opengl - OpenGL 顶点数组对象存储顶点缓冲区名称和索引,还是仅存储索引?

标签 opengl vbo opengl-4 vao

创建时,VAO 是否仅跟踪 VBO 索引(通过 glBindVertexBuffer ),或者哪些 VBO 名称绑定(bind)到这些索引?如果我使用 glVertexAttribBinding 指定绑定(bind)索引,例如 0在创建 VAO 期间,我可以在绘制调用之前将不同的 VBO 绑定(bind)到索引 0 并让它使用该 VBO 的内容,还是始终使用在创建 VAO 时绑定(bind)到索引 0 的任何 VBO?

我问是因为我发现很多例子先于调用 glVertexAttribFormatglVertexAttribBinding调用 glBindVertexBuffer,如果 VAO 只跟踪索引则不需要调用(因为绑​​定索引在 glVertexAttribBinding 中给出)。

最佳答案

您可能已经知道,这是 OpenGL 4.3 中引入的相当新的功能。按照我阅读规范的方式,属性和缓冲区之间的映射现在具有一定程度的间接性:

  1. 每个属性都有一个指定它使用哪个绑定(bind)索引的特性。
  2. 缓冲区绑定(bind)到绑定(bind)索引。

您可以将其视为两个表,一个定义从属性索引到绑定(bind)索引的映射,另一个定义从绑定(bind)索引到缓冲区名称的映射。这两个表都是 VAO 状态的一部分。

我相信这些可以完全独立地以任何顺序指定。 glVertexAttribBinding() 在属性索引和绑定(bind)索引之间建立第一个关联。 glBindVertexBuffer() 建立绑定(bind)索引和缓冲区名称之间的关联。

规范中的状态表证实了这种理解。 GL 4.4 规范中的表 23.4,标题为“顶点数组对象状态”,列出:

  • VERTEX_ATTRIB_BINDING,可以用glGetVertexAttribiv()查询,是给定属性索引的绑定(bind)索引的值。
  • VERTEX_BINDING_BUFFER,可以用 glGetIntegeri_v() 查询,是给定绑定(bind)索引的缓冲区名称的值。

据此,解决您的具体问题:

When created, do VAOs track just VBO indices (via glBindVertexBuffer), or also which VBO names are bound to those indices?

他们跟踪两者。

can I bind a different VBO to index 0 just prior to a draw call and have it use the contents of that VBO

是的,如果您将不同的 VBO 绑定(bind)到绑定(bind)索引 0,则绑定(bind)索引为 0 的所有属性都将使用该 VBO 的内容。

a lot of examples I find precede calls to glVertexAttribFormat and glVertexAttribBinding with a call to glBindVertexBuffer, which should not be necessary if the VAO tracks only indices

VAO 跟踪所有这些调用设置的状态,因此将所有这些调用用作设置 VAO 的一部分确实有意义。跟踪 VAO 中的整个顶点设置状态是首先拥有 VAO 的主要目的。它允许您在初始化期间设置一次状态,然后在绘制调用之前只需调用一次 glBindVertexArray() 即可再次设置整个状态。

关于opengl - OpenGL 顶点数组对象存储顶点缓冲区名称和索引,还是仅存储索引?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26767939/

相关文章:

c++ - OpenGL 文本渲染方法和权衡

c++ - SwapBuffers 使我的程序崩溃!

opengl - 将顶点缓冲区对象用于基于图 block 的游戏和纹理图集

c++ - 在 OpenGL4.0 中使用交错属性数组提高性能

c++ - 在 OpenGL 中存储模型矩阵的最佳位置?

c++ - opengl 3d 空间平面上的程序网格

OpenGL 交错索引数组

c++ - 每个网格多个顶点缓冲区

c++ - 为什么 VERTEX 着色器中的矩阵乘法无法正常工作?

OpenGL 4.x 学习资源