OpenGL(六)使用 VAO 打包指令 优化代码结构
2017-03-29 12:16
489 查看
通常说来当创建好vbo的数据结构,还需要设置
glGenVertexArrays(1,&myVao);
glBindVertexArray(myVao);
//... some vbo operation
glBindVertexArray(0);
GLuint CreateVAOWithVBOSettings(std::function<void()> settings)
{
GLuint vaoTemp;
glGenVertexArrays(1,&vaoTemp);
glBindVertexArray(vaoTemp);
settings();
glBindVertexArray(0);
return vaoTemp;
}
调用时,将vbo过程作为参数传入:struct VertexData
{
float positon[3];
float texcoord[2];
float normal[3];
};
GLuint CreateBufferObject(GLenum bufferType,GLsizeiptr size,GLenum usage,void* data)
{
GLuint object;
glGenBuffers(1,&object);
glBindBuffer(bufferType,object);
glBufferData(bufferType,size,data,usage);
glBindBuffer(bufferType,0);
return object;
}
GLuint vao = CreateVAOWithVBOSettings([&]()->void
{
GLuint vbo = CreateBufferObject(GL_ARRAY_BUFFER, sizeof(VertexData) * vertexCount, GL_STATIC_DRAW, vertexes);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glEnableVertexAttribArray(posLocation);
glVertexAttribPointer(posLocation, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)0);
glEnableVertexAttribArray(texcoordLocation);
glVertexAttribPointer(texcoordLocation, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)(sizeof(float) * 3));
glEnableVertexAttribArray(normalLocation);
glVertexAttribPointer(normalLocation, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)(sizeof(float) * 5));
glBindBuffer(GL_ARRAY_BUFFER, 0);
});
//draw
glBindVertexArray(vao);
//...
glBindVertexArray(0);经过这样的改动,绘制部分变得非常简单。
关注我的微信公众号,获取更多优质内容
glVertexAttribPointer等一系列属性,在OpenGL中提供了 VAO (Vertex Array Object)它相当于同时记录了数据在哪里和数据是怎样分布。从实际应用的角度,它最重要的贡献就是简化了代码。
原理
通过接口函数生成一个VertexArray,然后在其中创建和设置VBO的相关参数,在最终绘制时,直接使用。GLuint myVao;glGenVertexArrays(1,&myVao);
glBindVertexArray(myVao);
//... some vbo operation
glBindVertexArray(0);
实现
通过C++的匿名函数,可以将vbo操作开放出去#include <functional>GLuint CreateVAOWithVBOSettings(std::function<void()> settings)
{
GLuint vaoTemp;
glGenVertexArrays(1,&vaoTemp);
glBindVertexArray(vaoTemp);
settings();
glBindVertexArray(0);
return vaoTemp;
}
调用时,将vbo过程作为参数传入:struct VertexData
{
float positon[3];
float texcoord[2];
float normal[3];
};
GLuint CreateBufferObject(GLenum bufferType,GLsizeiptr size,GLenum usage,void* data)
{
GLuint object;
glGenBuffers(1,&object);
glBindBuffer(bufferType,object);
glBufferData(bufferType,size,data,usage);
glBindBuffer(bufferType,0);
return object;
}
GLuint vao = CreateVAOWithVBOSettings([&]()->void
{
GLuint vbo = CreateBufferObject(GL_ARRAY_BUFFER, sizeof(VertexData) * vertexCount, GL_STATIC_DRAW, vertexes);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glEnableVertexAttribArray(posLocation);
glVertexAttribPointer(posLocation, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)0);
glEnableVertexAttribArray(texcoordLocation);
glVertexAttribPointer(texcoordLocation, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)(sizeof(float) * 3));
glEnableVertexAttribArray(normalLocation);
glVertexAttribPointer(normalLocation, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)(sizeof(float) * 5));
glBindBuffer(GL_ARRAY_BUFFER, 0);
});
//draw
glBindVertexArray(vao);
//...
glBindVertexArray(0);经过这样的改动,绘制部分变得非常简单。
总结
可以将 VAO 理解为一个存储指向VBO指针的数组,实际上数据还是储存在VBO中。它是将切分读取数据的过程打包在一起,避免了每次都编写繁琐的代码。关注我的微信公众号,获取更多优质内容
相关文章推荐
- 看opengl写代码(9)使用顶点数组(VAO)
- C#分析数据库结构,使用XSL模板自动生成代码
- 优化分支代码——避免跳转指令堵塞流水线
- 使用正则表达式优化网页代码
- C#分析数据库结构,使用XSL模板自动生成代码(二)
- 使用正则表达式优化网页代码
- 使用内部和匿名类优化Java代码
- 优化使用mysql存储session的php代码
- 使用正则表达式优化网页代码
- 使用SIMD指令高度优化Matrix类(in C++)
- C#分析数据库结构,使用XSL模板自动生成代码
- 优化分支代码——避免跳转指令堵塞流水线
- 使用FxCop做代码检查和优化
- 使用正则表达式优化网页代码
- 使用XPO过程中的代码优化
- 用VC写Assembly代码(6)--附录3[X86指令使用详解]
- luyikk Monster raid 一款使用C# 写的SYN 利器,完全代码共享,希望各位高手协助优化.
- C#分析数据库结构,使用XSL模板自动生成代码
- 使用正则表达式优化网页代码
- 优化使用mysql存储session的php代码