[转载] glDrawArrays, glDrawElements

[转载] glDrawArrays, glDrawElements 2010-09-21 15:13:50
楼主
  • 用户名:admin

    名爵:扶正大臣

    发帖:178 回帖:128

    积分:103151 金币:0

    注册:2010-01-23

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 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);

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);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值