OpenGL(六)使用 VAO 打包指令 优化代码结构

本文介绍OpenGL中VAO(VertexArrayObject)与VBO(VertexBufferObject)的概念及其实现方式。VAO简化了VBO的使用流程,通过一次性设置顶点缓冲区对象的属性,减少了绘制时的代码复杂度。

通常说来当创建好vbo的数据结构,还需要设置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中。它是将切分读取数据的过程打包在一起,避免了每次都编写繁琐的代码。

松阳论道

关注我的微信公众号,获取更多优质内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值