分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow
也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!
Win32 OpenGL编程(5) 顶点数组详细介绍
write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie
提要
本文主要讲解了OpenGL中使用顶点数组来绘制图形的需求及方法,
需求
按照前面已经讲过的内容来说,简单的2D图形绘制已经没有问题了,并且,很多东西其实已经涉及到3D,但是会发现,复杂图形的绘制时,glBegin和glEnd对中指定顶点的函数调用会非常多,glVertex函数调用的开销会过大。(虽然在C/C++中函数调用开销其实已经比较小)在3D图形绘制时,此问题更加严重,想想,一个四边形,4个顶点,一个四方体,就有8个顶点了,但是按照我们目前描述平面的方式来描述就是需要指定6 * 4 = 24个顶点。这正是OpenGL作为高性能图像接口应该极力避免的事情,事实上,OpenGL当然不会一直要求我们用如此低效的方式来完成任务,我们有新的高效的工具——顶点数组。事实上,在强调高效和尽量减少API的OpenGL ES中,甚至根本就没有glBegin,glEnd和glVertex*等API。
顶点数组相对来说是OpenGL中用于提高效率的手段,不是核心概念。(虽然OpenGL ES中完全以顶点数组绘制图元,但是事实上OpenGL 1.1版中才加入了定点数组)顶点数组不能使我们绘制出以前以前绘制不了的图元,但是却实实在在的提高了我们绘制图形的效率,但是事实上,对于高性能图像处理来说,提高效率是如此的重要,因为效率的提升从本质上来说没有增加我们绘制更多图形的能力(即不用提高效率手段也能绘制出相同图形),但是,随着效率的提高,我们却能在同样的机器上绘制更多的图元,那么,意味着我们可以更加丰富和逼真地表现图像,这不正是图形绘制所追求的目标吗?
概念
有的东西说简单就简单,说复杂就复杂,顶点数组的概念如此的简单,如其名,就是将原来由一系列的glVertex*指定的顶点放在一个数组中,(其意思就是顶点数据组成的数组)由顶点数组处理函数一次性指定。事实上,不仅如此,其一次性指定的不仅仅是数组,还可以是其他系列的东西,比如表面发现,RGBA颜色,辅助颜色等。
使用方式初步
使用方式,编程手段的使用方式最佳讲解手段肯定是程序,我们以一个例子来讲解使用方式。
glVertexArray:
1: //OpenGL初始化开始
2: void SceneInit(int w,int h)
3: {
4: glClearColor(0.0, 0.0, 0.0, 0.0);
5: // 启用顶点数组
6: glEnableClientState(GL_VERTEX_ARRAY);
7:
8: // 顶点数组数据
9: static GLfloat fVertices[] = { -0.5, -0.5,
10: 0.5, -0.5,
11: 0.5, 0.5,
12: -0.5, 0.5};
13:
14: glVertexPointer(2, GL_FLOAT, 0, fVertices);
15: }
16:
17: //这里进行所有的绘图工作
18: void SceneShow(GLvoid)
19: {
20: glClear(GL_COLOR_BUFFER_BIT); // 清空颜色缓冲区
21: glColor4f(1.0, 1.0, 1.0, 1.0);
22:
23: glBegin(GL_QUADS);
24: glArrayElement(0);
25: glArrayElement(1);
26: glArrayElement(2);
27: glArrayElement(3);
28: glEnd();
29:
30: // 上述函数调用与下面的效果一样
31: //glBegin(GL_QUADS);
32: //glVertex3f(-0.5, -0.5, 0.0);
33: //glVertex3f(0.5, -0.5, 0.0);
34: //glVertex3f(0.5, 0.5, 0.0);
35: //glVertex3f(-0.5, 0.5, 0.0);
36: //glEnd();
37:
38: glFlush();
39: }
为节省篇幅仅贴出关键片段,完整源代码见我博客源代码的2009-10-18/glVertexArray/ 目录,获取方式见文章最后关于获取博客完整源代码的说明。
上述例子的效果与以前SimpleRectangle的效果完全一样,请参考本OpenGL系列文章3,4,(以下简称XO3,XO4^^),截图如以前一样。
分步骤说明一下上述源代码的含义:
glEnableClientState(GL_VERTEX_ARRAY);
用于表示启用顶点数组,此函数还可以搭配其他参数用于指定其他数组
glEnableClientState — enable or disable client-side capability
void glEnableClientState( GLenum cap);
Parameters:Specifies the capability to enable.
Symbolic constants
GL_COLOR_ARRAY,
GL_EDGE_FLAG_ARRAY,
GL_FOG_COORD_ARRAY,
GL_INDEX_ARRAY,
GL_NORMAL_ARRAY,
GL_SECONDARY_COLOR_ARRAY,
GL_TEXTURE_COORD_ARRAY, and
GL_VERTEX_ARRAY
are accepted.
此例中仅仅使用了GL_VERTEX_ARRAY一种用法。
glVertexPointer也是关键函数,用于指定顶点数组的数据。
glVertexPointer — define an array of vertex data
C Specification
void glVertexPointer( GLint size,
GLenum type,
GLsizei stride,
const GLvoid * pointer);
Parameters
size
Specifies the number of coordinates per vertex. Must be 2, 3, or
4. The initial value is 4.
typeSpecifies the data type of each coordinate in the array.
Symbolic constants
GL_SHORT,
GL_INT,
GL_FLOAT,
or GL_DOUBLE
are accepted. The initial value is GL_FLOAT.
strideSpecifies the byte offset between consecutive
vertices. If stride is 0, the vertices are understood to be tightly packed in
the array. The initial value
is 0.
pointerSpecifies a pointer to the first coordinate of the first vertex in the
array. The initial value is 0.
此例中,数据以2个位一组,类型都是GL_FLOAT,跨度为0表示数据紧密排列,指针自然指向刚才分配的顶点数组数据。
glArrayElement用于指定顶点数组函数具体的顶点,放在glBegin与glEnd之间,产生glVertex*一样的效果,即一次指定一个顶点。
glArrayElement — ren