强烈推荐http://www.zwqxin.com/archives/opengl/vao-and-vbo-stuff.html
一.vbo使用
1.初始化阶段
glGenBuffers(1, &g_ArrayBuffer);
glBindBuffer(GL_ARRAY_BUFFER, g_ArrayBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(MyVertex) * 3, NULL, GL_STREAM_DRAW);//确定array大小
/******/
VBO允许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
"Static”意味着VBO中的数据不会被改变(一次修改,多次使用)
"dynamic”意味着数据可以被频繁修改(多次修改,多次使用)
"stream”意味着数据每帧都不同(一次修改,一次使用)。"Draw”意味着数据将会被送往GPU进行绘制,"read”意味着数据会被用户的应用读取,"copy”意味着数据会被用于绘制和读取。注意在使用VBO时,只有draw是有效的,而copy和read主要将会在像素缓冲区(PBO)和帧缓冲区(FBO)中发挥作用。
2.rendering阶段
glGenVertexArrays(1,&g_VertexArray);
glBindVertexArray(g_VertexArray);
glBindBuffer(GL_ARRAY_BUFFER, g_ArrayBuffer);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(MyVertex) * 3, &verts[0].x);
glEnableVertexAttribArray(ATTRIB_POSITION);
glVertexAttribPointer(ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, sizeof(MyVertex),BUFFER_OFFSET(0));
glEnableVertexAttribArray(ATTRIB_COLOR);
glVertexAttribPointer(ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(MyVertex),BUFFER_OFFSET(sizeof(float) * 3));
glDrawArrays(GL_TRIANGLES, 0, 3);
代码如上:
1.先绑定vao,就是glGenVertexArrays,glBindVertexArray
2. 绑定对应的vbo,对应的是glBindBuffer。其中glBufferSubData是更新部分buffer data
3.设置数据格式、内容。对应glEnableVertexAttribArray、glVertexAttribPointer.
4.绘制。对应的是glDrawArrays,如果有索引,就是glDrawElements。
5.ps.如果存在不同缓冲区,则写成下面形式:
- glGenBuffers(1, &m_nQuadPositionVBO);
- glBindBuffer(GL_ARRAY_BUFFER, m_nQuadPositionVBO);
- glBufferData(GL_ARRAY_BUFFER, sizeof(fQuadPos), fQuadPos, GL_STREAM_DRAW);
- glEnableVertexAttribArray(VAT_POSITION);
- glVertexAttribPointer(VAT_POSITION, 2, GL_INT, GL_FALSE, 0, NULL);
- //上面为顶点信息,下面为纹理信息
- glGenBuffers(1, &m_nQuadTexcoordVBO);
- glBindBuffer(GL_ARRAY_BUFFER, m_nQuadTexcoordVBO);
- glBufferData(GL_ARRAY_BUFFER, sizeof(fQuadTexcoord), fQuadTexcoord, GL_STREAM_DRAW);
- glEnableVertexAttribArray(VAT_TEXCOORD);
- glVertexAttribPointer(VAT_TEXCOORD, 2, GL_INT, GL_FALSE, 0, NULL);