本文参考 https://www.jianshu.com/p/dfe29d697a62
我们通过顶点缓冲对象(Vertex Buffer Objects, VBO)管理内存,它会在GPU内存(通常被称为显存)中储存大批顶点。使用这些缓冲对象的好处是我们可以一次性的发送一大批数据到显卡上,而不是每个顶点发送一次。
声明
//顶点缓冲对象
GLuint VBO;
生成顶点缓冲对象
//1 使用glGenBuffers函数生成一个缓冲ID
glGenBuffers(1, &VBO);
绑定
//2 使用glBindBuffer函数把新创建的缓冲绑定到GL_ARRAY_BUFFER缓冲类型上
glBindBuffer(GL_ARRAY_BUFFER, VBO);
构造顶点
struct VertexData
{
QVector3D position;
QVector3D color;
};
//vbo数据,顶点与颜色
VertexData vc[] = {
//正面
{QVector3D(-0.5f, 0.0f, 0.5f), QVector3D(1.0f, 0.0f, 0.0f)}, //1
{QVector3D(0.5f, 0.0f, 0.5f), QVector3D(0.0f, 1.0f, 0.0f)}, //2
{QVector3D(0.5f, 1.0f, 0.5f), QVector3D(0.0f, 0.0f, 1.0f)}, //3
{QVector3D(-0.5f, 1.0f, 0.5f), QVector3D(1.0f, 1.0f, 1.0f)}, //4
//右面
{QVector3D(0.5f, 0.0f, 0.5f), QVector3D(0.0f, 1.0f, 0.0f)}, //2
{QVector3D(0.5f, 0.0f, -0.5f), QVector3D(1.0f, 1.0f, 0.0f)}, //5
{QVector3D(0.5f, 1.0f, -0.5f), QVector3D(0.0f, 1.0f, 1.0f)}, //6
{QVector3D(0.5f, 1.0f, 0.5f), QVector3D(0.0f, 0.0f, 1.0f)}, //3
//左面
{QVector3D(-0.5f, 0.0f, 0.5f), QVector3D(1.0f, 0.0f, 0.0f)}, //1
{QVector3D(-0.5f, 0.0f, -0.5f),QVector3D(1.0f, 0.0f, 1.0f)}, //8
{QVector3D(-0.5f, 1.0f, -0.5f),QVector3D(1.0f, 0.6f, 0.0f)}, //7
{QVector3D(-0.5f, 1.0f, 0.5f), QVector3D(1.0f, 1.0f, 1.0f)}, //4
//背面
{QVector3D(0.5f, 0.0f, -0.5f), QVector3D(1.0f, 1.0f, 0.0f)}, //5
{QVector3D(0.5f, 1.0f, -0.5f), QVector3D(0.0f, 1.0f, 1.0f)}, //6
{QVector3D(-0.5f, 1.0f, -0.5f), QVector3D(1.0f, 0.6f, 0.0f)}, //7
{QVector3D(-0.5f, 0.0f, -0.5f), QVector3D(1.0f, 0.0f, 1.0f)}, //8
//顶面
{QVector3D(0.5f, 1.0f, 0.5f), QVector3D(0.0f, 0.0f, 1.0f)}, //3
{QVector3D(0.5f, 1.0f, -0.5f), QVector3D(0.0f, 1.0f, 1.0f)}, //6
{QVector3D(-0.5f, 1.0f, -0.5f), QVector3D(1.0f, 0.6f, 0.0f)}, //7
{QVector3D(-0.5f, 1.0f, 0.5f), QVector3D(1.0f, 1.0f, 1.0f)}, //4
//底面
{QVector3D(0.5f, 0.0f, 0.5f), QVector3D(0.0f, 1.0f, 0.0f)}, //2
{QVector3D(0.5f, 0.0f, -0.5f), QVector3D(1.0f, 1.0f, 0.0f)}, //5
{QVector3D(-0.5f, 0.0f, -0.5f), QVector3D(1.0f, 0.0f, 1.0f)}, //8
{QVector3D(-0.5f, 0.0f, 0.5f), QVector3D(1.0f, 0.0f, 0.0f)}, //1
};
复制数据
//3 把用户定的义数据复制到当前绑定缓冲的函数
glBufferData(GL_ARRAY_BUFFER, sizeof(vc), vc, GL_STATIC_DRAW);
链接属性
在渲染前指定OpenGL如何解释顶点数据。
//4 链接顶点属性
//indx: 属性名
//size: 顶点大小
//type: 数据类型
//normalized:数据被标准化
//stride: 步长
//ptr: 数据在缓冲中起始位置的偏移量
glVertexAttribPointer(m_posAttr, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (GLvoid*)0);
glVertexAttribPointer(m_colAttr, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (GLvoid*)sizeof(QVector3D));
开启属性
//5 开启顶点属性
glEnableVertexAttribArray(0);
//颜色值
glEnableVertexAttribArray(1);
绘制四边形
//6 绘制四边形
glDrawArrays(GL_QUADS, 0, 24);
停用属性
//7 停用对应的顶点属性数组
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(0);
源代码
https://gitee.com/chen227/opengl_OpenGLFunctions3
问题
opengl下原来是一个个点绘制,所以使用VBO后能批量使用数据,区别明显。
qt下我们本来就是使用数组数据,换成VBO并没有方便多少,那么
//qt原技术
glVertexAttribPointer(m_posAttr, 3, GL_FLOAT, GL_FALSE, 0, vertices);
是不是就是VBO技术呢???
//VBO
glVertexAttribPointer(m_posAttr, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (GLvoid*)0);