一、VBO
VBO是顶点缓冲对象,顶点缓冲对象在GPU中存储数据,加速渲染过程。
1、1 VBO优点
- 减少数据从CPU到GPU的传输,提升渲染效率。在鸿蒙OpenGL入门,绘制三角形中介绍了绘制三角形,其实当时绘制的三角形性能并不高。三角形的顶点数据和颜色数据都是从CPU获取,如果图形复杂,数据每次都从CPU拷贝到GPU,性能就太低。更好的方式是一次性将全部数据从CPU拷贝到GPU,之后需要数据的时候,直接从GPU中获取数据。在GPU中设置一个对象,这个对象就是VBO,一次性将全部数据拷贝到VBO中。VBO在GPU中,从VBO中获取数据就是从GPU中获取数据,大大的提升了渲染性能。
- 数据保存在GPU,可重复使用。
- 可以在GPU中转换数据,减少CPU负载。
1、2 使用VBO基本步骤
需要注意的是,下面的操作需要在链接完程序后调用,也就是在调用完glLinkProgram函数后。
- 调用glGenBuffers函数生成VBO对象。
void GL_APIENTRY glGenBuffers (GLsizei n, // 一次生成多少个VBO
GLuint *buffers); // VBO对象的索引值
- 调用glBindBuffer进行绑定。
void GL_APIENTRY glBindBuffer (GLenum target, // 目标数据类型,它是个常量,GL_ARRAY_BUFFER表示用于存储顶点数据
GLuint buffer); // VBO对象的id,解绑时需要将该参数设置为0
- 调用glBufferData将顶点数据复制到VBO对象中。
void GL_APIENTRY glBufferData (GLenum target, // 目标数据类型,它是个常量,GL_ARRAY_BUFFER表示用于存储顶点数据
GLsizeiptr size, // 拷贝数据的大小
const void *data, // 从哪拷贝数据
GLenum usage); // 常量,指定拷贝数据的方式,一般设置为GL_STATIC_DRAW,表明是一次性拷贝
- 调用glVertexAttribPointer从VBO中读取数据,glVertexAttribPointer函数之前文章介绍过,当使用VBO的时候,需要将glVertexAttribPointer函数最后一个参数设置为0。
- 解绑VBO对象,VBO是在GPU分配空间,当不需要时,主动释放空间。
glDeleteBuffers(VBO_COUNT, vboIds);
如下代码是使用VBO的流程。
bool VBOTriangleExample::init() {
if (TriangleExample::init()) {
// 生成vbo对象
glGenBuffers(1, vboIds);
// 绑定vbo
glBindBuffer(GL_ARRAY_BUFFER, vboIds[0]);
// 将顶点数据复制到VBO对象
glBufferData(GL_ARRAY_BUFFER, sizeof(triangleVertices), triangleVertices, GL_STATIC_DRAW);
// 解绑vbo
glBindBuffer(GL_ARRAY_BUFFER, 0);
return true;
}
return false;
}
1、3修改绘制代码
有三处改动
- 调用glBindBuffer函数告知着色器从哪个vbo中读取数据。
- 调用glVertexAttribPointer的时候,需要将最后一个参数设置为0,表示从GPU读取数据。
- 调用glBindBuffer函数,最后一个参数设置为0,表示解绑vbo。
void VBOTriangleExample::draw() {
glUseProgram(program);
// 告知着色器从哪个vbo中读