glDrawArrays 和 glDrawElements 的作用都是从一个数据数组中提取数据渲染基本图元。( render primitives from array data )

注!如果要 glDrawArrays 和 glDrawElements 正确进行绘制的话,必须在之前 调用带有相应参数的 glEnableClientState 方法。 比如:

/* Enable vertex arrays. */
glEnableClientState( GL_VERTEX_ARRAY );
/* Enable texture arrays. */
glEnableClientState( GL_TEXTURE_COORD_ARRAY );

这两个方法的第一个形参都是代表 绘制模式(GLenum mode)。绘图模式有如下几种:
GL_POINTS
GL_LINES
GL_LINE_LOOP
GL_LINE_STRIP
GL_TRIANGLES
GL_TRIANGLE_STRIP
GL_TRIANGLE_FAN
我们还没有讨论点或线,所以我只介绍最后的三个 。
在我开始之前,我要提醒你,顶点数组可能包含不止一个三角形,以便当您只看到一个物体顶点数组,你要知道,不仅限于这一点。
假设我们有如下的顶点数据:

const GLfloat squareVertices[] = {
    -1.0,  1.0, -6.0, // Top left
    -1.0, -1.0, -6.0, // Bottom left
    1.0,  -1.0, -6.0, // Bottom right
    1.0,   1.0, -6.0  // Top right
};

GL_POINTS - 单独的将顶点画出来。
GL_LINES - 单独地将直线画出来。行为和 GL_TRIANGLES 类似。

GL_LINE_STRIP - 连贯地将直线画出来。行为和 GL_TRIANGLE_STRIP 类似。

GL_LINE_LOOP - 连贯地将直线画出来。行为和 GL_LINE_STRIP 类似,但是会自动将最后一个顶点和第一个顶点通过直线连接起来。
GL_TRIANGLES - 这个参数意味着OpenGL使用三个顶点来组成图形。所以,在开始的三个顶点,将用顶点1,顶点2,顶点3来组成一个三角形。完成后,在用下一组的三个顶点(顶点4,5,6)来组成三角形,直到数组结束。
GL_TRIANGLE_STRIP - OpenGL的使用将最开始的两个顶点出发,然后遍历每个顶点,这些顶点将使用前2个顶点一起组成一个三角形。
所以 squareVertices[6~8]{1.0, -1.0, 6.0} 将与 squareVerticies[0~2]{-1.0, 1.0, -6.0} 和 squareVerticies[3~5]{-1.0, -1.0, -6.0} 生成一个三角形。
squareVertices[9~11]{1.0, 1,0, -6.0} 将与  squareVertices[3~5]{-1.0, -1.0, -6.0} 和squareVertices[6~8]{1.0, -1.0, 6.0} 生成三角形。
也就是说,P0,P1,P2这三个点组成一个三角形,P1,P2,P3这三个点也组成一个三角形。
注意的是, squareVerticies[0~2]表示的意思是:
squareVerticies[0] x坐标
squareVerticies[1] y坐标
squareVerticies[2] z坐标
GL_TRIANGLE_FAN - 在跳过开始的2个顶点,然后遍历每个顶点,让OpenGL将这些顶点于它们前一个,以及数组的第一个顶点一起组成一个三角形。 squareVertices[6~8]{1.0, -1.0, 6.0} 将与 squareVerticies[3~5]{-1.0, -1.0, -6.0} (前一个)和 squareVerticies[0~2]{-1.0, 1.0, -6.0}(第一个).生成一个三角形。
也就是说,同样是P0,P1,P2,P3 这4个顶点。
1) 在 GL_TRIANGLE_STRIP 状态下是: P2、P1、P0 ; P3、P2、P1 这2个三角形。
2) 在 GL_TRIANGLE_FAN   状态下是: P2、P1、P0 ; P3、P2、P0 这2个三角形。
1.1 glDrawArrays 方法介绍
Description

glDrawArrays specifies multiple geometric primitives with very few subroutine calls. You can prespecify separate arrays of vertices, normals, colors, and texture coordinates and use them to construct a sequence of primitives with a single call to glDrawArrays.
When glDrawArrays is called, it uses count sequential elements from each enabled array to construct a sequence of geometric primitives, beginning with element first. mode specifies what kind of primitives are constructed, and how the array elements construct those primitives. If GL_VERTEX_ARRAY is not enabled, no geometric primitives are generated.
Vertex attributes that are modified by glDrawArrays have an unspecified value after glDrawArrays returns. For example, if GL_COLOR_ARRAY is enabled, the value of the current color is undefined after glDrawArrays executes. Attributes that aren’t modified remain well defined.

示例代码:

glEnableClientState(GL_VERTEX_ARRAY);
    
const GLfixed vers[] = {
        F2X(0.25), F2X(0.25), F2X(0.0), 
        F2X(0.75), F2X(0.25), F2X(0.0), 
        F2X(0.25), F2X(0.75), F2X(0.0), 
        F2X(0.75), F2X(0.75), F2X(0.0), 
};

glVertexPointer(3, GL_FIXED, 0, vers);
    
glDrawArrays(GL_LINE_STRIP, 0, 4);
    
eglSwapBuffers(iGlDisp, iGlSurface);

结果:

1.2 glDrawElements 是一个OPENGL的图元绘制函数,从数组中获得数据并渲染图元。
函数原型为:
void glDrawElements( 
        GLenum mode, 
        GLsizei count,
        GLenum type, 
        const GLvoid *indices
        );
其中:
    mode 指定绘制图元的类型,但是如果GL_VERTEX_ARRAY 没有被激活的话,不能生成任何图元。它应该是下列值之一:
        GL_POINTS, GL_LINE_STRIP, 
        GL_LINE_LOOP, GL_LINES, 
        GL_TRIANGLE_STRIP, 
        GL_TRIANGLE_FAN, 
        GL_TRIANGLES, 
        GL_QUAD_STRIP, 
        GL_QUADS, 
        GL_POLYGON
         
    count 为绘制图元的数量。
type 为索引数组(indices)中元素的类型,只能是下列值之一: 
        GL_UNSIGNED_BYTE, 
        GL_UNSIGNED_SHORT, 
        GL_UNSIGNED_INT
        
    indices:指向索引数组的指针。

glDrawElements函数能够通过较少的函数调用绘制多个几何图元,而不是通过OPENGL函数调用来传递每一个顶点,法线,颜色信息。
你可以事先准备一系列分离的顶点、法线、颜色数组,并且调用一次glDrawElements把这些数组定义成一个图元序列。
当调用glDrawElements函数的时候,它将通过索引使用count个成序列的元素来创建一系列的几何图元。
glDrawElements修改的顶点属性在glDrawElements调用返回后的值具有不确定性。

例如,在 GL_COLOR_ARRAY 被激活后,当glDrawElements执行完成时,当前的颜色值是没有指定的。没有被修改的属性值保持不变。
可以在显示列表中包含 glDrawElements,当glDrawElements被包含进显示列表时,相应的顶点、法线、颜色数组数据也得进入显示列表的,因为那些数组指针是ClientSideState的变量,在显示列表创建的时候而不是在显示列表执行的时候,这些数组指针的值影响显示列表。
glDrawElements 只能用在 OPENGL1.1 或者更高的版本。

示例代码如下:

// The vertex array is enabled for writing and used during rendering.
glEnableClientState(GL_VERTEX_ARRAY);

// 顶点坐标数组
const GLfixed vers[] = {
        F2X(0.25), F2X(0.25), F2X(0.0), // 第1个顶点坐标
        F2X(0.75), F2X(0.25), F2X(0.0), // 第2个顶点坐标
        F2X(0.25), F2X(0.75), F2X(0.0), // 第3个顶点坐标
        F2X(0.75), F2X(0.75), F2X(0.0)  // 第4个顶点坐标
};

glVertexPointer(
        3,        // 表示每一个顶点由3维坐标构成
        GL_FIXED, // 顶点坐标数组中的元素是 GL_FIXED 类型
        0,        // 从顶点坐标数组的第0个元素开始读取数据
        vers      // 指向顶点坐标数组的指针
        );

// 等效替换 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4) ++

/* 索引数组. 此索引数组表示依次是
第0个顶点{F2X(0.25), F2X(0.25), F2X(0.0)},
第1个顶点{F2X(0.75), F2X(0.25), F2X(0.0)},
第2个顶点{F2X(0.25), F2X(0.75), F2X(0.0)},
第3个顶点{F2X(0.75), F2X(0.75), F2X(0.0)} */
const GLubyte indices[] = {0, 1, 2, 3};

glDrawElements(
        GL_TRIANGLE_STRIP, // 绘图模式
        4,                 // 依次从索引数组中读取4个顶点来进行绘制
        GL_UNSIGNED_BYTE,  // 索引数组中存放的元素的类型
        indices            // 指向索引数组的指针
        );

// 等效替换 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4) --

eglSwapBuffers(iGlDisp, iGlSurface);


转自:http://hwcrazy.com/7d354b48702f11e187c2000d601c5586/

glDrawArrays,glDrawElements用法相关推荐

  1. OpenGL Vertex Array

    原文地址 http://www.songho.ca/opengl/gl_vertexarray.html<-------这博客不错!貌似博主是个棒子. OpenGL Vertex Array R ...

  2. OpenGL 渲染管线理论

    这几天稍微看了一些关于GLSL的顶点着色以及片元着色的一些相关知识.目前来讲还有一个着色器则是Geometry_shader..我的显卡用不了这个功能..当然有点遗憾>_<..       ...

  3. OpenGL: 渲染管线理论

    学习着色器,并理解着色器的工作机制,就要对OpenGL的固定功能管线有深入的了解. 零.首先要知道几个OpenGL的术语 渲染(rendering):计算机根据模型(model)创建图像的过程. 模型 ...

  4. OpenGL 渲染管线理论

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 学习着色 ...

  5. 动态合批和静态合批的区别

    参考文章: 图形渲染及优化-Unity合批技术实践 图形渲染及优化-Batch 批是啥? 对某对象进行批量处理叫批处理 Batch是啥? 引擎每帧提交的Batch数量就是衡量渲染压力的指标 Batch ...

  6. Android OpenGL ES 画球体

    最近因为兴趣所向,开始学习OpenGL绘图.本文以"画球体"为点,小结一下最近所学. > 初识OpenGL ES 接触OpenGL是从Android开始的.众所周知,Andr ...

  7. OpenGL2.0 和 OpenGL3.0 的不同与共同点

    OpenGL2.0 和 OpenGL3.0 的不同与共同点 在OpenGL2.0中vertex shader 中 可以不指定 version 如果不指定 version 对于iOS来说 默认认为是Op ...

  8. 图形学的入门课--shader

    引言   shader到底是干什么用的?shader的工作原理是什么?  其实当我们对这个问题还很懵懂的时候,就已经开始急不可耐的要四处搜寻有关shader的资料,恨不得立刻上手写一个出来.但看了一些 ...

  9. OpenGL Shading Language 汇总

    overview 用glCreateShader创建一个shader,可以指定shader的类型等信息. 通过glShaderSource导入shader的源文件. 通过glCompileShader ...

最新文章

  1. 基于TF-IDF编码进行文本聚类分析:文档成对相似性计算、层次聚类(链接矩阵、树形图dendrogram绘制、聚类标签)
  2. VTK:几何对象之Arrow
  3. mock模拟接口测试 vue_vue+mock.js实现前后端分离
  4. IDEA 启动、编译、clean、安装maven等、报错Process terminated
  5. linux 设备驱动之8250串口驱动分析
  6. 学校校园无盘教学系统
  7. M3U8下载,直播源下载,FLASH下载(三)-直播源下载
  8. spring-boot集成elastic-job 并实现http类型作业
  9. 【VISIO绘图】VISIO绘图 学习笔记
  10. 2019新版《网易云课堂 C++收银系统项目实战教程》
  11. 面向车路协同的路侧感知仿真系统
  12. Python+Django实现智慧校园考试比赛系统
  13. 高性能PC机与服务器的真正区别
  14. 华为路由三层交互:单臂路由实验
  15. 'BMap' is not defined 解决方案,亲测有效
  16. 【热血足球联盟】补丁记录
  17. 腾讯云服务器无法通过密钥登录
  18. 第2次实验——算法基本功 与 综合思考
  19. 恒大kk服务器信息端口,恒大kk手机客户端服务器
  20. 时间序列分析-预测Apple股票价格

热门文章

  1. Windows下编写的脚本文件无法在Linux上运行的问题
  2. java语言复制数组的四种方法
  3. 计算机的编程发源地,计算机编程: C典型上机试题
  4. == 和 equals方法的区别
  5. 数组小案例(求数组最大最小值、反转数组中元素、指定元素第一次出现的索引)
  6. ROS中阶笔记(一):机器人系统设计—ROS系统下连接外部传感器
  7. mysql dba环境验收_面对一个全新的环境,作为一个Mysql DBA,应该了解
  8. 为什么nodejs是单进程的_Nodejs探秘:深入理解单线程实现高并发原理
  9. win2003无法进入桌面_电脑桌面怎么建立便签,可以在电脑桌面显示的便签
  10. JAVA中用于处理字符串的 三兄弟