opengl es VBO IBO VAO
VBO Vertex Buffer Object
其实就是显卡中的显存,可以将要绘制的顶点数据缓存在显存中,从而免去将要绘制的顶点数据重复从CPU发送到GPU, 提高渲染速度。
IBO Indices Buffer Object
索引缓冲对象,和VBO一样,只是存储的是索引数组。
VAO Vertex Array Object
是一个容器,可以绑定VBO和IBO的一个包装对象,把有关联的VBO和IBO一起绑定到一个VAO上,然后使用VAO就可以进行绘制了,绘制效率更高,VAO可以使开发更加灵活。
1、
// 0,1,2代表着色器的input的location,分别代表顶点位置,顶点颜色,顶点纹理坐标
glEnableVertexAttribArray(0);
// 固定管线使用glEnableClientState(GL_VERTEX_ARRAY)
glEnableVertexAttribArray(1);
// 固定管线使用glEnableClientState(GL_COLOR_ARRAY)
glEnableVertexAttribArray(2);
// 固定管线使用glEnableClientState(GL_TEXTURE_COORD_ARRAY)
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, vertexes);
// 固定管线使用glVertexPointer(4, GL_FLOAT, 0, vertexes);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, colores);
// 固定管线使用glColorPointer(4, GL_FLOAT, 0, colores);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, texCoordes);
// 固定管线使用glTexCoordPointer(2, GL_FLOAT, 0, texCoordes);
2、
// 绘制一个四边形
glDrawArrays(GL_QUADS, 0, 4);
3、
// 指定顶点数据,注意渲染顺序的迎风面是逆时针还是顺时针,绘制4个顶点,分别对应顶点数组中的前4个顶点
GLuint indexes = {0, 1, 2, 3};
// 用顶点索引进行绘制的绘制调用
glDrawElements(GL_QUADS, 4, GL_UNSIGNED_INT, indexes);
4、// 生成VBO,并为VBO绑定顶点数据
size_t dataSize = sizeof(GLfloat) * vertexCount * 4; // 在图像显卡中需要分配的内存大小
GLuint vbos[1] = { 0 }; // VBO名字
glGenBuffers(1, vbos); // 生成一个可用的VBO名字
GLuint vertexVBO = vbos[0];
glBindBuffer(GL_ARRAY_BUFFER, vertexVBO); // 绑定当前的VBO,GL_ARRAY_BUFFER是VBO使用的固定参数
glBufferData(GL_ARRAY_BUFFER, dataSize, vertexes, GL_STATIC_DRAW);
//将位置数据绑定到当前的VBO上,dataSize是需要的内存大小,vertexes是顶点的位置数据
/*
GL_STATIC_DRAW 是一个性能提示参数,这个参数指示了当前VBO的用途,该参数必须是GL_STREAM_DRAW, GL_STATIC_DRAW, or GL_DYNAMIC_DRAW之一。openGL会根据该指示,尽可能将数据放置在性能最优的内存中,可能是显存,AGP内存,或者cpu内存中.
GL_STATIC_DRAW:数据指定一次,并多次被用于绘制。
GL_STREAM_DRAW:数据指定一次,最多几次用于绘制。
GL_DYNAMIC_DRAW:数组多次指定,多次用于绘制。
*/
//使用VBO进行绘制,和使用顶点数组类似
//数据在缓冲区中的偏移位置,和顶点数组指针位置效果类似
#define BUFFER_OFFSET(offset) ((GLvoid*)(NULL + offset))
glBindBuffer(GL_ARRAY_BUFFER, vertexVBO); // 绑定位置VBO
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0)); // 指定位置数据
glBindBuffer(GL_ARRAY_BUFFER, colorVBO); // 绑定颜色VBO
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0)); // 指定颜色数据
glBindBuffer(GL_ARRAY_BUFFER, textureVBO); // 绑定纹理VBO
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0)); // 指定纹理数据
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDrawArrays(GL_QUADS, 0, m_vertexCount); // 绘制
5、IBO: 索引缓冲对象,和VBO一样,只是存储的是索引数组。
GLuint ibos[1] = { 0 }; // IBO名字
GLuint IBO;
glGenBuffers(1, &IBO); // 生成可用的IBO名字
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
//参数必须使用GL_ELEMENT_ARRAY_BUFFER
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * indexCount, indexes, GL_STATIC_DRAW);
//将索引数据绑定到当前的IBO上,GL_STATIC_DRAW同上面的VBO中第使用
//绘制
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
glDrawElements(GL_QUADS, indexCount, GL_UNSIGNED_INT, BUFFER_OFFSET(0));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
6、生成VAO
GLuint VAO;; // VAO名字
glGenVertexArrays(1, &VAO); // 生成一个VAO
glBindVertexArray(VAO); // 绑定到当前的VAO
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO); // 绑定一个IBO到当前的VAO上
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, vertexVBO); // 绑定位置VBO到当前的VAO上
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0)); // 指定位置数据
glBindBuffer(GL_ARRAY_BUFFER, colorVBO); // 绑定颜色VBO到当前的VAO上
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0)); // 指定颜色数据
glBindBuffer(GL_ARRAY_BUFFER, textureVBO); // 绑定纹理VBO到当前的VAO上
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0)); // 指定纹理数据
// 绘制
glBindVertexArray(VAO);
glDrawElements(GL_QUADS, indexCount, GL_UNSIGNED_INT, BUFFER_OFFSET(0));
glBindVertexArray(0);