Welcome 微信登录
编程资源 图片资源库 蚂蚁家优选 PDF转换器

首页 / 操作系统 / Linux / OpenGL超级宝典学习笔记——顶点缓冲区对象

显示列表可以快速简单地优化立即模式(glBegin/glEnd)的代码。在最坏的情况下,显示列表的命令被预编译存到命令缓冲区中,然后发送给图形硬件。在最好的情况下,是编译后放在图形硬件中以减少传输的带宽。显示列表的优化根据实现的不同而有所不同,而且显示列表一旦被创建就不可以修改,灵活性差。顶点数组提供了我们想要的灵活性,最坏的结果不过是把数据块复制给硬件而已(比立即模式快的多)。而索引顶点数组可以减少向硬件传输的顶点数据的数量,减少变换的开销。OpenGL还提供了一个特性对图形的吞吐量进行终极的控制。当我们使用顶点数组时,可以把单个数组从客户内存(CPU可以访问)传输到图形硬件。这个特性称为顶点缓冲区对象,允许我们按照类似于管理纹理的方式来管理顶点数组数据,而且顶点缓冲区对象要更灵活。 

管理和使用缓冲区对象

首先要使用缓冲区对象得有顶点数组。第二步创建顶点缓冲区对象,使用函数:void glGenBuffers(GLsizei n, GLuint *buffers);这个函数工作方式像glGenTextures一样。其对应的删除缓冲区对象的函数是glDeleteBuffers。然后绑定顶点缓冲区对象:void glBindBuffer(GLenum target, GLuint buffer);这里的target参数指定了要绑定什么样的数组。类型有很多,可以是顶点数组GL_ARRAY_BUFFER,顶点索引数组GL_ELEMENT_ARRAY_BUFFER(用于glDrawElements和其他基于索引的渲染函数)等。 

加载缓冲区对象

在绑定了缓冲区对象之后,我们就可以往图形硬件拷贝顶点数组了。void glBufferData(GLenum target, GLsizeptr size, GLvoid *data, GLenum usage);target可以是GL_ARRAY_BUFFER或者GL_ELEMENT_ARRAY_BUFFER等。size指定了顶点数组的大小(以字节为单位)。最后一个参数是用法提示。如下表:
用法提示描述
GL_DYNAMIC_DRAW存储在缓冲区对象中的顶点数组经常要更新,并且可能多次作为绘图的来源。这个提示告诉OpenGL实现把数据放置在更新开销不大的地方。
GL_STATIC_DRAW数组很少更新,但可能多次作为绘图的来源。这个提示告诉OpenGL实现把数据放置在能够快速渲染但不需要快速更新的地方。
GL_STREAM_DRAW数据极少变化,并且最多只有几次作为绘图的源数据。这个提示告诉OpenGL实现有一些时间敏感的数据(例如动画)将只使用一次,然后被替换。
 

从顶点缓冲区对象渲染

从顶点缓冲区对象渲染有两个地方需要改动。首先,需要在调用glVertexPointer之前绑定缓冲区对象,然后把真实的数组指针改成顶点缓冲区对象的偏移值。例如:glVertexPointer(3, GL_FLOAT, 0, pVerts);现在变成了:glBindBuffer(GL_ARRAY_BUFFER, bufferObjects[0]);glVertexPointer(3, GL_FLOAT, 0, 0);渲染 就变成了:glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferObjects[3]);glDrawElements(GL_TRIANGLES, nNumIdexes, GL_UNSIGNED_SHORT, 0);最后一个参数会偏移量。从技术上说,缓冲区对象的这个偏移量基于本地体系结构的NULL指针。在大多数系统中,可设置为0. 

总体步骤

  1. 生成缓冲区对象标识符glGenBuffers(可选步骤)
  2. 绑定一个缓冲区对象,确定它是用于存储顶点数组还是索引(GL_ARRAY_BUFFER,还是GL_ELEMENT_BUFFER)
  3. 请求数据的存储空间,并且对这些数据元素进行初始化
  4. 指定相对于缓冲区起始位置的偏移量。
  5. 绑定适当的缓冲区对象,用于渲染。
  6. 使用适当的顶点数组渲染函数进行渲染如glDrawArrays glDrawElements
简单示例:#include "gltools.h"//宏定义#define VERTICES 0#define INDICES 1#define NUM_BUFFERS 2//缓冲区标示符GLuint buffers[NUM_BUFFERS];static GLfloat cube[]={-1.0f, -1.0f, -5.0f, //前面的正方形1.0f, -1.0f,-5.0f,1.0f, 1.0f, -5.0f, -1.0f, 1.0f, -5.0f,-1.0f, -1.0f, -10.0f,//背面的正方形1.0f, -1.0f, -10.0f,1.0f, 1.0f, -10.0f,-1.0f, 1.0f, -10.0f};static GLubyte index[]={0, 1, 2, 3, //前面0, 3, 7, 4, //左面5, 6, 2, 1, //右面7, 6, 5, 4, //后面3, 2, 6, 7, //上面1, 0, 4, 5 //地面};void SetupRC(){  glClearColor(1.0f, 1.0f, 1.0f, 1.0f);  glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);  //生成缓冲区标示符  glGenBuffers(NUM_BUFFERS, buffers);  //绑定缓冲区对象,并设置顶点数组  glBindBuffer(GL_ARRAY_BUFFER, buffers[VERTICES]);  glBufferData(GL_ARRAY_BUFFER, sizeof(cube), cube, GL_STATIC_DRAW);  glVertexPointer(3, GL_FLOAT, 0, 0);}void RenderScene(){  glClear(GL_COLOR_BUFFER_BIT);  glColor3f(0.0f, 0.0f, 1.0f);  glPushMatrix();  glEnableClientState(GL_VERTEX_ARRAY);  //绑定缓冲区对象,并进行渲染  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[INDICES]);  glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(index), index, GL_STATIC_DRAW);  glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, 0);  glDisableClientState(GL_VERTEX_ARRAY);  glPopMatrix();  glutSwapBuffers();}void ChangeSize(GLsizei w, GLsizei h){  if(h == 0)    h = 1;  glViewport(0, 0, w, h);  GLfloat fAspect = (GLfloat)w / (GLfloat)h;  glMatrixMode(GL_PROJECTION);  glLoadIdentity();  gluPerspective(35.0f, fAspect, 1.0f, 100.0f);  glMatrixMode(GL_MODELVIEW);  glLoadIdentity();}int main(int args, char* argv[]){  glutInit(&args, argv);  glutInitWindowPosition(200, 200);  glutInitWindowSize(800, 600);  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);  glutCreateWindow("VBO");  glutDisplayFunc(RenderScene);  glutReshapeFunc(ChangeSize);  SetupRC();  glutMainLoop();  return 0;} OpenGL超级宝典 第4版 中文版PDF+英文版+源代码 见  http://www.linuxidc.com/Linux/2013-10/91413.htmOpenGL编程指南(原书第7版)中文扫描版PDF 下载 http://www.linuxidc.com/Linux/2012-08/67925.htmOpenGL 渲染篇 http://www.linuxidc.com/Linux/2011-10/45756.htmUbuntu 13.04 安装 OpenGL http://www.linuxidc.com/Linux/2013-05/84815.htmOpenGL三维球体数据生成与绘制【附源码】 http://www.linuxidc.com/Linux/2013-04/83235.htmUbuntu下OpenGL编程基础解析 http://www.linuxidc.com/Linux/2013-03/81675.htm如何在Ubuntu使用eclipse for c++配置OpenGL http://www.linuxidc.com/Linux/2012-11/74191.htm 更多《OpenGL超级宝典学习笔记》相关知识 见 http://www.linuxidc.com/search.aspx?where=nkey&keyword=34581本文永久更新链接地址:http://www.linuxidc.com/Linux/2015-02/114033.htm