一个 VBO 可以绑定多个 VAO 吗?

Posted

技术标签:

【中文标题】一个 VBO 可以绑定多个 VAO 吗?【英文标题】:Can a VBO be bound to multiple VAOs? 【发布时间】:2013-03-15 17:28:08 【问题描述】:

我正在尝试通过将模型的纹理坐标视为顶点位置数组来渲染模型的 UV 贴图。我为模型设置了一个完美渲染的 VAO,然后尝试添加第二个 VAO 并将纹理坐标缓冲区绑定到它。不幸的是它没有渲染任何东西。

我已经为 UV 贴图编写了第二组顶点和片段着色器,它们编译得很好。缓冲区的绑定方式与模型 VAO 和顶点属性集的绑定方式相同。我能看到的唯一区别是我没有重新指定缓冲区数据。

这是我设置模型 VAO 的代码:

// Create model VAO

glGenVertexArrays( 1, &modelVAO );
glBindVertexArray( modelVAO );

// Create position buffer

glGenBuffers( 1, &positionBuffer );
glBindBuffer( GL_ARRAY_BUFFER, positionBuffer );
glBufferData( GL_ARRAY_BUFFER, sizeof( GLfloat ) * vertexCount * 4, positions, GL_STATIC_DRAW );
glVertexAttribPointer( 0, 4, GL_FLOAT, GL_FALSE, 0, 0 );
glEnableVertexAttribArray( 0 );

// Create normal buffer

glGenBuffers( 1, &normalBuffer );
glBindBuffer( GL_ARRAY_BUFFER, normalBuffer );
glBufferData( GL_ARRAY_BUFFER, sizeof( GLfloat ) * vertexCount * 3, normals, GL_STATIC_DRAW );
glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, 0, 0 );
glEnableVertexAttribArray( 1 );

// Create texture coordinate buffer

glGenBuffers( 1, &textureCoordinateBuffer );
glBindBuffer( GL_ARRAY_BUFFER, textureCoordinateBuffer );
glBufferData( GL_ARRAY_BUFFER, sizeof( GLfloat ) * vertexCount * 2, textureCoordinates, GL_DYNAMIC_DRAW );
glVertexAttribPointer( 2, 2, GL_FLOAT, GL_FALSE, 0, 0 );
glEnableVertexAttribArray( 2 );

// Unbind model VAO

glBindVertexArray( 0 );

然后我像这样设置UV贴图VAO:

// Create new UV map VAO

glGenVertexArrays( 1, &uvMapVAO );
glBindVertexArray( uvMapVAO );

// Bind texture coordinate buffer

glBindBuffer( GL_ARRAY_BUFFER, textureCoordinateBuffer );
glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 0, 0 );
glEnableVertexAttribArray( 0 );

// Unbind UV map VAO

glBindVertexArray( 0 );

是否可以将同一个 VBO 与多个这样的 VAO 一起使用?

【问题讨论】:

【参考方案1】:

Yes。 VAO 仅存储对 VBO 的引用,以及 glVertexAttribPointer 指定的格式、偏移量等相关数据。 Index VBOs 的语义略有不同。

【讨论】:

这也是我的想法。 glGetError 也没有返回错误,所以它一定是其他地方的问题。

以上是关于一个 VBO 可以绑定多个 VAO 吗?的主要内容,如果未能解决你的问题,请参考以下文章

VAO 与 VBO 和 IBO 的手动绑定

多个缓冲器和 VAO 性能

VBO必须在VAO之后绑定

VAO 是不是同时记住 EBO/IBO(元素或索引)和 VBO?

绑定到“顶点数组对象”后,我应该删除“顶点缓冲区对象”吗?

如何在 Qt 5 中使用带有实例化的 VAO