OpenGL Vertex Buffer Objects(VBOs)

原创 2010年05月20日 12:53:00

[教学视频]计算机图形学基础 -在线学习教程


*原创文章转载请注明出处*

 

OpenGL Vertex Buffer Objects(VBOs)

 

Vertex Buffer Objects(VBOs)是一组保存在显存中的数据,这些数据可以是顶点,顶点颜色,顶点法线,顶点索引或贴图坐标等等。由于这些数据都是保存在显存中的,而且可以随时修改数据或整块替换数据,这样就极大的提高了显卡的工作效率和渲染的速度。VBO的概念类似于D3D中的顶点缓冲和索引缓冲的概念。这篇文章将通过实际的例子来说明在openGL中如何使用VBOs,并且和使用传统的glVertex()函数定义顶点和使用glCallList()函数进行比较。

 

现在要渲染一个模型,首先定义该模型的顶点数组。

 

struct myVertex

{

      GLfloat x,y,z;      // vertex

      GLfloat nx,ny,nz;   // noraml

};

 

这里定义了一个结构体数据,包括顶点和法线,它们都是浮点型的,所以该结构体一共占用4*6=24字节的空间。有了顶点结构体后,为了提供顶点间连接的信息,我们还需要定义索引数组。

 

myVertex *vertexData;

GLuint *indexData;

 

这里使用无符号的整型定义了一个定点数组的指针,myVertex *vertexData是用我们定义的顶点结构体定义了一个顶点数据指针。在使用VBO之前,我们先将数据初始化到顶点数组和索引数组中。假设现在顶点数据和索引数组都有数据,现在就可以使用VBO了。使用VBO和使用其他openGL的一些对象差不多,使用前都要先申请和创建。使用VBO也要先创建对象。

 

GLuint BufferName[2];

glGenBuffers(2, BufferName);

 

为了将顶点数据和索引数据能放到对应的缓存中,这里定义了一个保存两个缓存idBufferName数组。然后使用glGenBuffers()函数申请2个缓存id。申请到id后立即为要使用的缓存分配空间和初始化。

 

glBindBuffer(GL_ARRAY_BUFFER, BufferName[0]);

glBufferData(GL_ARRAY_BUFFER, vertexSize, vertexData, GL_STATIC_DRAW);

 

glVertexPointer(3, GL_FLOAT,24,0);

glNormalPointer(GL_FLOAT, 24, (GLvoid*)12);

 

上面的代码中,glBindBuffer表示绑定一个要使用的buffer对象,该函数有2个参数,该函数的原型为

 

void glBindBuffer(GLenum target, GLuint buffer);

 

 

参数target表示buffer的类型,参数buffer表示id。第一个buffer里要保存顶点数据,所以指定为GL_ARRAY_BUFFER为即可。绑定完一个buffer对象后,然后让这个buffer关联到数据上。这里使用函数glBufferData该函数为绑定的buffer指定要放入的数据,它的原型为

 

void glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage);

 

同样参数target表示使用的buffer的类型, size的类型是GLsizeiptr,该类型表示一个指向size的一个指针,在使用之前,先要求得放入buffer中数据的大小。

 

GLsizeiptr vertexSize = number_of_vertex * sizeof(myVertex);

 

可以通过上面的代码简单的求出顶点数据共占用的显存空间。data表示要放到该buffer中的顶点数组的指针,usage表示用法,这里指定为GL_STATIC_DRAW表示该buffer只能修改一次,但可多次读取。

 

现在已经在顶点缓存中放入了顶点数据,但是显卡是不知道这些数据中哪些是顶点,哪些是法线等等。于是我们还要告诉显卡哪些数据是用来干什么的。同样openGL中提供了glVertexPointerglNormalPointer分别来管理不同的数据。于是我们看了上面这样的代码。

 

glVertexPointer(3, GL_FLOAT,24,0);

glNormalPointer(GL_FLOAT, 24, (GLvoid*)12);

 

函数glVertexPointer中,第一个参数表示顶点的维数,比如2维,3维或4维。第二个参数表示顶点的类型,第三个参数表示每隔多少字节顶点数据开始重复,最后一个参数表示顶点开始位置的偏移。由于我们顶点每个是24字节,并且连续保存在显存中,于是每隔24字节就开始重复。函数glNormalPointer中,第一个参数表示法线的数据类型,第二参数还是表示每隔多少字节开始重复,最后一个参数表示法线开始位置的偏移量。由于在顶点数据中前12字节是顶点坐标,后12个字节才是法线,于是法线数据开发的偏移量就是12个字节。我们可以通过下面的图清楚的看到这些数据之间的关系。

 

 

Fig1 顶点数据在显存中的存储

 

顶点数据处理完后,接下来就是顶点索引数据了。和顶点数据一样,要使用索引缓存,也要先绑定索引到buffer中。

 

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, BufferName[1]);

glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexSize, indexData, GL_STATIC_DRAW);

 

使用索引缓存的话,在glBindBuffer函数中,target就要选择GL_ELEMENT_ARRAY_BUFFER,然后绑定到第二个buffer。之后同样用函数glBufferData将索引数据放到buffer中。这里的indexSize也是Glsizeiptr类型。

 

GLsizeiptr indexSize = number_of_face*3*sizeof(GLuint);

 

上面的代码可以求出索引缓存的大小,由于mesh的一个三角形使用3个顶点索引,所以索引缓存的大小是三角形的个数乘以3再乘以索引数据类型所占的字节数。

有了所有这些数据后,最后在渲染的时候,我们就可以使用函数glDrawElements绘制对象了。

 

glEnableClientState(GL_VERTEX_ARRAY);

     

glDrawElements(GL_TRIANGLES, number_of_face*3, GL_UNSIGNED_INT,  0);

 

glDisableClientState(GL_VERTEX_ARRAY);

 

绘制前开开启客户端处理功能。函数glDrawElements中,第一个参数表示索引那种图元来连接。第二个参数表示要渲染多少个这种图元,第三个参数表示索引的数据类型,最后一个参数表示开始索引开始位置的偏移量。

 

Fig2 渲染的模型

 

Fig2中可以看到渲染的一个模型,该模型的顶点数为219483个,三角形数为435667个。要渲染这样一个顶点数有20万,三角形数有40万的模型来说,如果用传统的glVertex函数来设置顶点的话,渲染一帧的画面就要大约调用该函数3*40=120万次,如果要达到30FPS的话,那么每秒要调用函数大约3*40*30 =3600万次,这样多的函数调用次数相当耗时。

 

Fig3 各种渲染方法帧数对比

 

现在为了对比进行试验,试验用电脑配置采用Inter Core2 6600处理器,2G内存和NVIDIA GeForce8600GT显卡。 试验的结果可以从Fig3中看到,纵轴表示帧数。 实际试验中发现,使用glVertex函数渲染方法,平均只能达到1FPS,这远远低于实时渲染的要求。为了提高性能,也可以使用Display List,在openGL中可以使用glGenListglNewListglCallList函数,在同样环境下运行程序,渲染帧数有了明显改善,达到平均16FPS的水平,虽然和采用glVertex的方法比性能提高了16倍,但是仍然达不到实时渲染的要求。最后采用VBO的方法,在相同环境下运行程序,这次帧数到达了60FPS,约为采用Display List方法的4倍,完全可以达到实时渲染的要求。从试验中可以看到,采用VBO能够明显提高性能。

 

 

*原创文章转载请注明出处*

使用Vertex Buffer绘制基本几何形状

使用Vertex Buffer绘制基本几何形状在前面的文章有稍微介绍了XNA的XNA Rendering Pipeline现在,让我们开始从头了解吧!!(也许有人会好奇,怎么会要讲这个...因为这个部...

计算机图形学-OpenGL-绘制五角星

计算机图形学-OpenGL-绘制五角星本次实验我们将利用OpenGL绘制五角星图案,集成开发环境采用VS2013。预备知识五角星五个顶点的计算方法:五个顶点均匀分布在圆周上,可以用如下公式计算: Xi...

用刚学的OpenGL画五角星

这学期开了门《计算机图形学》,学了三周了,学会一些绘图的方法。 实验要求绘制一个六边形,我想绘制一个五角星。      算出每个顶点的坐标就可以了,然后用GL_PLOYGON模式将几个顶点连接就可以了...

Android Lesson Seven: An Introduction to Vertex Buffer Objects (VBOs)

原文链接地址:http://www.learnopengles.com/android-lesson-seven-an-introduction-to-vertex-buffer-objects-vb...
  • incanus
  • incanus
  • 2012年06月02日 13:23
  • 1728

android opengles 3.0 学习(一):顶点绘制法 VBOs(Vertex Buffer Objects)

本文主要介绍android中opengl es 3.0的开发,通过一个例子介绍VBO顶点缓存法绘制图形,适合入门的同学。目前只有android系统中只有android 4.3或以上支持opengles...
  • lvjing2
  • lvjing2
  • 2013年09月21日 19:33
  • 2855

OZone3D OpenGL Vertex Buffer Objects 2/3

2 - Practice For each sub-part of the practice part, there is an associated class in the sample...

OZone3D OpenGL Vertex Buffer Objects 3/3

3 - References 3.1. Buffers Usage   STREAM1 DYNAMIC1 STATIC1 DRAW1 GL_STREAM_...

OZone3D OpenGL Vertex Buffer Objects 1/3

原文地址http://www.ozone3d.net/tutorials/opengl_vbo.php OpenGL Vertex Buffer Objects By Christ...

OpenGL ES2.0 Programming Guide - chapter 6:Vertex attributes, vertex array and buffer objects

chapter 6:Vertex attributes, vertex array and buffer objects

[转]OpenGL Vertex Buffer Object (VBO)

Related Topics:Vertex Array , Display List , Pixel Buffer ObjectDownload:vbo.zip , vboSimple.zipC...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:OpenGL Vertex Buffer Objects(VBOs)
举报原因:
原因补充:

(最多只允许输入30个字)