OpenGL缓冲区对象之VBO
来源:互联网 发布:java小游戏设计 编辑:程序博客网 时间:2024/05/17 19:21
VBO是OpenGL提供的一种特性,主要是用于在非立即模式下(使用glBegin/glEnd这种方式)用来保存顶点数据(包括位置、纹理、颜色等),同时提供了更新这些数据的方法。 VBO相比较立即模式的渲染来说效率更高,这主要是因为VBO的数据一般会放在显存中而不是内存中。通俗点说VBO就好像是显卡中开辟的一块存储区域,用来把以前放在内存中的数据放在了显存中,便于更加方便的传输处理。 VBO特性是在OpenGL1.5版本引入的。
- VBO相关函数
OpenGL提供了几个对其进行操作的函数:
- 创建VBO
创建一个VBO需要3个步骤:
1. 新建一个新的缓冲区对象(调用 glGenBuffers)
2. 绑定缓冲区对象 (调用glBindBuffer)
3. 拷贝顶点数据到缓冲区对象中(调用glBufferData)
------------------------
glGenBuffer的函数原型如下:
- void glGenBuffers (GLsizei n, GLuint * buffers);
glBindBuffer的函数原型如下:
- void glBindBuffer (GLenum target,GLuint buffer);
这里需要注意: 所有顶点属性(如顶点坐标值、顶点纹理坐标、顶点法线和颜色)都必须使用GL_ARRAY_BUFFER。索引数组GL_ELEMENT_ARRAY_BUFFER是配合glDraw[Range]Elements()来使用的。
这个函数调用之后,VBO就被初始化完成。
glBufferData的函数原型如下:
- void glBufferData(
- GLenum target,
- GLsizeiptr size,
- const GLvoid * data,
- GLenum usage);
target:取值是GL_ARRAY_BUFFER或者是GL_ELEMENT_ARRAY,含义与上文中所述的一致。
size:需要写入的数据大小(以字节为单位)
data:写入数据的指针,如果data是空,那么VBO仅仅保留size大小的空间
usage:是一种优化的参数,根据实际使用情况来选定,可以有9种取值(仅仅是建议,其实可以随便选,但是按照使用的特点选取特定的模式可以获得更好的表现)
- GL_STATIC_DRAW_ARB
- GL_STATIC_READ_ARB
- GL_STATIC_COPY_ARB
- GL_DYNAMIC_DRAW_ARB
- GL_DYNAMIC_READ_ARB
- GL_DYNAMIC_COPY_ARB
- GL_STREAM_DRAW_ARB
- GL_STREAM_READ_ARB
- GL_STREAM_COPY_ARB
”DYNAMIC“开头的单词意味着VBO中的数据会经常变化。
”STREAM“开头的单词意味着VBO中的数据每一帧都会变化
”DRAW“表示数据传输到GPU中进行绘制(从Application到GL)
”READ“表示数据是客户端程序来读取(从GL到Application)
”COPY“则表示数据的流向既有DRAW同时也有READ
需要注意的是:基本上VBO都只会用到DRAW,COPY和READ一般是在FBO和PBO(稍后介绍)中使用。
glBufferSubData函数原型如下:
- void glBufferSubData(
- GLenum target,
- GLintptr offset,
- GLsizeiptr size,
- const GLvoid * data);
这个函数和glBufferData的作用有点类似,主要是向VBO中写入数据,但是它只是替换VBO中的一部分数据,另外在使用它之前的缓冲区对象必须先使用过glBufferData写入过全部的数据。(也就是说glBufferSubData不能更新一个全新的缓冲区对象[仅仅使用glBindBuffer,还未使用glBufferData写入的缓冲区])
参数含义与glBufferData基本类似,只不过它有一个offset偏移量,通过offset和size就能算出一个子区间,用来更新。
glDeleteBudffer函数原型如下:
- void glDeleteBuffers( GLsizei n,
- const GLuint * buffers);
- 使用方式
上文已经介绍了所有相关的API,那么看看如何使用。下面就是一个使用简单的代码:
- GLuint vboId; // 声明一个VBO的ID值
- GLfloat* vertices = new GLfloat[vCount*3]; // 存放VBO数据的数组(内存中)
- // 新建缓冲区对象,并使用vboId来保存这个缓冲区的ID
- glGenBuffers(1, &vboId);
- // 绑定缓冲区对象,作为数据数组使用
- glBindBuffer(GL_ARRAY_BUFFER_ARB, vboId);
- // 写入内存中的数据到缓冲区对象中
- glBufferData(GL_ARRAY_BUFFER_ARB, dataSize, vertices, GL_STATIC_DRAW_ARB);
- // 当拷贝数据到缓冲区对象中之后,内存中的数组对象可以安全的被释放
- delete [] vertices;
- // 程序结束后删除缓冲区对象(回收缓冲区以备之后使用)
- glDeleteBuffers(1, &vboId);
- 示例
关于VBO的示例可以参考《VA AVO VBO 备忘》一文,里面有详细的参数和使用介绍。
- 更新VBO
VBO的一个特点是它可以在客户端被修改(相比显示列表)。最简单的更新VBO数据的方式是将新的数据通过glBufferData或者glBufferSubData拷贝到VBO中,这种情况下总是有关于顶点数据的两份拷贝,一份在应用程序中一份在VBO中。
OpenGL提供了另一种修改缓冲区对象的方式,将缓冲区对象映射到客户端内存中。客户端可以使用这个映射的指针来修改缓冲区中的数据,相关的API包括:
- void * glMapBuffer( GLenum target,
- GLenum access);
target参数的取值和glBindBuffer中target一样,access的取值包括以下几种
- GL_READ_ONLY
- GL_WRITE_ONLY
- GL_READ_WRITE
- GLboolean glUnmapBuffer( GLenum target);
0 0
- OpenGL缓冲区对象之VBO
- OpenGL缓冲区对象之VBO
- OpenGL系列教程之八:OpenGL顶点缓冲区对象(VBO)
- OpenGL系列教程之八:OpenGL顶点缓冲区对象(VBO)
- OpenGL顶点缓冲区对象(VBO)
- OpenGL顶点缓冲区对象(VBO)
- 缓冲区对象VBO
- GLES 顶点缓冲区对象(VBO)
- OpenGL缓冲区对象之UBO
- OpenGL缓冲区对象之FBO
- OpenGL缓冲区对象之EBO
- OpenGL缓冲区对象之VAO
- OpenGL缓冲区对象之VAO
- OpenGL缓冲区对象之EBO
- OpenGL缓冲区对象之FBO
- OpenGL缓冲区对象之UBO
- OpenGL缓冲区对象之VAO
- OpenGL缓冲区对象之UBO
- mysql_fetch_array与mysql_fetch_assoc区别
- referrer返回当前文档的来源URL
- 网络爬虫-爬取广州当天天气预报
- navicat 导出数据库 存储过程 函数
- Nginx关于Rewrite执行顺序详解.docx
- OpenGL缓冲区对象之VBO
- MVC 解决JSON日期格式化/JSON及匿名对象
- [JQ权威指南]使用$.extend()扩展函数
- Android 自定义View总结 —— LayoutParams
- 背景
- android 动态的显示时间
- Android 并发二三事之 IntentService Handler 机制再次来袭
- java HashSet学习
- MVC+RDLC报表+PrintPreviewDialog(winform控件)打印、打印预览?!