glDrawArrays = DrawPrimitive
glDrawElements = DrawIndexPrimitive
比如画一个由2个3角形组成的正方形,左上角坐标是l,t,右下角坐标是r,b
使用glDrawArrays绘制时,画2个三角形,需要这样传:
(l,t),(r,t),(l,b)
(r,t),(r,b),(l,b)
而用glDrawElements画的话可以这样
float coord[4][2]={{l,t},{r,t},{r,b},{l,b}};
绘制时:
0,1,3
1,2,3
也就是说glDrawArrays传输或指定的数据是最终的真实数据,在绘制时效能更好
而glDrawElements指定的是真实数据的调用索引,在内存/显存占用上更节省
from:http://bbs.gameres.com/showthread.asp?threadid=71647
前两天接触OpenGL ES的时候发现里面没有了熟悉的glBegin(), glEnd(),glVertex3f()函数,取而代之的是glDrawArrays()。有问题问google,终于找到答案:因为OpenGL ES是针对嵌入式设备这些对性能要求比较高的平台,因此把很多影响性能的函数都去掉了,上述的几个函数都被移除了。接下来看看这些函数是如何使用的。
1.glEnableClientState(GL_VERTEX_ARRAY); 使能顶点数组功能。
2.将准备好的数组告知程序,使用glVertexPointer(),原型如下:
void glVertexPointer(
GLint size, //每个顶点占用的数组元素数量
GLenum type, //数组元素的数据类型
GLsizei stride, //元素之间的间隔,一般系统为0
const GLvoid *pointer //指向数组的指针
);
3.进行绘图:glDrawArrays()或者 glDrawElements(),glDrawElements()主要用于索引数组。函数原型如下:
void glDrawArrays(
GLenum mode, //绘图方式 GL_POINTS、GL_QUADS etc
GLint first, //第一个元素的下标
GLsizei count //绘制元素的数量
);
void glDrawElements(
GLenum mode, //绘图方式 GL_POINTS、GL_QUADS etc
GLsizei count, //顶点数组当中元素的个数
GLenum type, //索引数组当中元素数据类型
const GLvoid *indices //指向索引数组的指针
);
对应于顶点数组,OpenGL当中还提供了法向量数组、纹理坐标数组等等的支持,这些数组与顶点数组的使用方式相同,只是在相关参数和函数名称上将Vertex改为对应的名字即可。
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer();
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
我们还没有讨论点或线,所以我只介绍最后的三个 。
在我开始之前,我要提醒你,顶点数组可能包含不止一个三角形,以便当您只看到一个物体顶点数组,你要知道,不仅限于这一点。
假设我们有如下的顶点数据:
constGLfloat 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 countsequential elements from each enabled array to construct a sequenceof geometric primitives, beginning with element first. modespecifies what kind of primitives are constructed, and how thearray
elements construct those primitives. If GL_VERTEX_ARRAY isnot enabled, no geometric primitives are generated.
Vertex attributes that are modified by glDrawArrayshave an unspecified value after glDrawArrays returns. For example,if GL_COLOR_ARRAY is enabled, the value of the current color isundefined after glDrawArrays executes. Attributes
that aren'tmodified remain well defined.
示例代码:
glEnableClientState(GL_VERTEX_ARRAY);
constGLfixed 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);
// 顶点坐标数组
constGLfixed 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)} */
constGLubyte indices[]={0,1,2,3};
glDrawElements(
GL_TRIANGLE_STRIP,// 绘图模式
4,// 依次从索引数组中读取4个顶点来进行绘制
GL_UNSIGNED_BYTE,// 索引数组中存放的元素的类型
indices// 指向索引数组的指针
);
// 等效替换glDrawArrays(GL_TRIANGLE_STRIP, 0, 4) --
eglSwapBuffers(iGlDisp,iGlSurface);
分享到:
相关推荐
#### glDrawArrays与glDrawElements:渲染图元 `glDrawArrays`和`glDrawElements`用于渲染图元,前者基于顶点数组直接绘制,后者则根据索引数组来确定绘制的顶点。 #### glEvalCoord与glEvalMesh:计算网格和曲线 `...
一次绘制100个矩形,是一种只调用一次渲染函数却能绘制出很多物体的技术,它节省渲染物体 时从CPU到GPU的通信时间,...将 glDrawArrays 和 glDrawElements 各自改 为 glDrawArraysInstanced 和 glDrawElementsInstanced
此数据必须从客户端内存复制到图形内存时 绘制调用,如glDrawArrays或glDrawElements。 和光栅化。” 然而,如果我们不这样做会好得多 在每个绘制调用上复制顶点数据,但可以缓存 图形存储器中的数据。 这种方法...
随后,通过调用相应的OpenGL函数激活着色器程序,将顶点缓冲区和着色器程序绑定,就可以使用glDrawArrays或glDrawElements函数来命令OpenGL绘制三角形了。 渲染两个三角形的两种常见方法是:第一种是使用两个VBO和...
4. 使用glDrawArrays或glDrawElements函数绘制直线段。如果使用glDrawArrays,你需要为每对相邻的顶点创建一个线段;如果使用glDrawElements,你可以指定索引来创建线段。 5. 最后,调用glFlush或glFinish来确保所有...
为了绘制3D图形,源码会使用glDrawArrays或glDrawElements函数。这些函数告诉OpenGL如何从内存中的数据绘制图形。同时,还会涉及视口设置、投影矩阵和模型视图矩阵的变换,以控制图形在屏幕上的位置和大小。 最后,...
此外,还会介绍基本的绘制命令,如glDrawArrays和glDrawElements,以及如何实现模型的旋转、平移和缩放。 第12章:3D模型加载与动画 3D游戏中的角色和环境通常由复杂的3D模型构成,这一章将深入探讨3D模型的格式...
正方体的绘制通常涉及顶点数组和索引数组,通过定义每个顶点的位置、颜色等属性,然后使用OpenGL的几何绘制命令(如glDrawArrays或glDrawElements)来呈现。 接着,我们要了解的是着色器。在OpenGL中,着色器是运行...
在OpenGL中,颜色可以通过glColor函数指定,而绘制几何形状(如球体)则使用glDrawArrays或glDrawElements函数。在本例中,可能使用了三角面片(triangle strips或triangle fan)来近似球体表面,因为球体无法用简单...
4. 渲染模型:调用glDrawArrays或glDrawElements等函数绘制几何形状。 此外,为了实现平滑的旋转效果,可能需要用到时间戳和帧率控制,通过每帧更新旋转角度来实现连续动画。这通常涉及计时器函数,如glutTimerFunc...
在这个太阳系模拟中,每个行星都是由多个顶点定义的多边形组成,通过OpenGL的绘制命令(如glDrawArrays或glDrawElements)将这些几何数据转化为屏幕上的像素。同时,为了实现动态效果,需要应用变换矩阵,包括平移、...
在OnPaint事件中,调用glClear清除颜色和深度缓冲,设置矩阵,加载纹理,然后调用glDrawArrays或glDrawElements进行几何体绘制。 在Delphi中结合OpenGL,你可以实现高级的3D图形渲染,如光照、阴影、粒子系统、纹理...
例如,glDrawArrays和glDrawElements用于绘制顶点数组,glGenBuffers和glBindBuffer用于管理缓冲区,以及glTexImage2D和glTexParameteri用于处理纹理。这些API的高效使用是优化图形性能的关键。 最后,"opengl参考...
在OnPaint函数中,我们需要清除颜色和深度缓冲区,然后调用glDrawArrays或glDrawElements等函数来绘制几何形状。 4. **消息处理**:为了响应用户的输入,如鼠标和键盘事件,我们需要在对话框的消息映射中处理相应的...
5. 绘制:调用glDrawArrays或glDrawElements等函数绘制几何体。 6. 检查并处理错误:确保程序无误。 7. 交换缓冲区:使用glSwapBuffers将渲染结果从后台缓冲区显示到前台。 在压缩包中的“www.pudn.com.txt”可能是...
此外,OpenGL ES中的绘图调用(如glDrawArrays或glDrawElements)用于实际的渲染过程。在这个例子中,我们可能使用glDrawArrays来绘制一个四边形,其顶点数据来自于预先定义的缓冲区。 在Android应用中,我们还需要...
在OpenGL中,可以使用glDrawArrays或glDrawElements等函数来绘制多边形,通过指定顶点数组来形成几何形状。 "2 菜单响应"子文件则可能是实现菜单事件处理的部分。当用户在MFC菜单上点击一个项时,相应的消息会被...
在OpenGL中,可以使用库如Assimp或自定义解析器来读取OBJ文件,将其转换为OpenGL可理解的顶点数组,然后使用glDrawArrays或glDrawElements等函数进行绘制。 在处理OBJ文件时,需要注意以下几点: 1. 顶点:OBJ文件...
为了流畅地更新图形,需要在SurfaceView的onDrawFrame方法中执行这些操作,并调用glDrawArrays或glDrawElements来重新绘制场景。 此外,Android的硬件加速特性对于提高图形性能至关重要。开启硬件加速可以使OpenGL ...