绘制一个立方体的时候,需要6个正方形,普通的画法,需要指定6 × 4 = 24个顶点
进一步优化:指定8个顶点,存在数组中,再创建另外一个数组,保存每个面使用的顶点序号。就是一个比较合理的程序结构。但程序依然要循环24次,分别指定每个正方形的顶点。
进一步优化,使用顶点数组:
1. 顶点数组和前面的优化方法一样,一个数组保存顶点,一个数组保存顶点序号
2. 优点:不需要用普通的算法循环逐个循环指定顶点,而是把这两个数组传个OpenGL,OpenGL自动的查找顶点并绘制。减少了函数运行次数,提高运行效率
顶点数组是保存在客户端的,该机制也是在客户端生效。服务器端并不知道是否启用定点数组,也不关注
使用顶点数组的方法:
glEnableClientState(GL_VERTEX_ARRAY); //启动顶点数组功能
glVertexPointer(3, GL_FLOAT, 0, vertex_list);//指定保存顶点的数组
glDrawElements(GL_QUADS, 24, GL_UNSIGNED_INT, index_list); //指定保存顶点序号的数组,并开始绘制
顶点数组还可以保存配套的与顶点相关的信息:
1. 纹理坐标
2. 法线向量
3. 颜色
顶点的每一个属性都可以指定一个数组,然后用统一的序号来进行访问。比如序号3,就表示取得颜色数组的第3个元素作为颜色、取得纹理坐标数组的第3个元素作为纹理坐标、取得法线向量数组的第3个元素作为法线向量、取得顶点坐标数组的第3个元素作为顶点坐标。把所有的数据综合起来,最终得到一个顶点。
可以用glEnableClientState/glDisableClientState单独的开启和关闭每一种数组。
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
用以下的函数来指定数组的位置:
glVertexPointer
glColorPointer
glNormalPointer
glTexCoordPointer
glInterleavedArrays:
把所有的顶点数据(法线,颜色等)都混合起来,指定到同一个数组中。这就是混合数组
顶点数组和显示列表不同,显示列表保存在服务器端,顶点数组保存在客户端, 优缺点:
1. 顶点数组保存在本地,可以随时修改,而显示列表在服务器端,无法修改
2. 每次绘制时,顶点数组需要传送到服务器端,效率稍低。显示列表在服务器端,每次绘制无需传送
顶点缓冲区对象的出现:
1. 顶点数据保存在服务器端
2. 可以随时修改
顶点缓冲区对象跟纹理对象有很多相似之处。首先,分配一个缓冲区对象编号,然后,为对应编号的缓冲区对象指定数据,以后可以随时修改其中的数据。
下面的表格可以帮助类比理解。
纹理对像 | 顶点缓冲区对象 | |
分配编号 | glGenTextures | glGenBuffersARB |
绑定(指定为当前所使用的对象) | glBindTexture | glBindBufferARB |
指定数据 | glTexImage* | glBufferDataARB |
修改数据 | glTexSubImage* | glBufferSubDataARB |
顶点数据和序号各自使用不同的缓冲区。具体的说,就是顶点数据放在GL_ARRAY_BUFFER_ARB类型的缓冲区中,序号数据放在GL_ELEMENT_ARRAY_BUFFER_ARB类型的缓冲区中。
可以分配多个缓冲区对象,顶点坐标、颜色、纹理坐标等数据,可以各自单独使用一个缓冲区
每个缓冲区可以有不同的性能提示,比如在绘制一个运动的人物时,顶点坐标数据经常变化,但法线向量、纹理坐标等则不会变化,可以给予不同的性能提示,以提高性能。