创建时,VAO 是否仅跟踪 VBO 索引(通过 glBindVertexBuffer ),或者哪些 VBO 名称绑定(bind)到这些索引?如果我使用 glVertexAttribBinding 指定绑定(bind)索引,例如 0在创建 VAO 期间,我可以在绘制调用之前将不同的 VBO 绑定(bind)到索引 0 并让它使用该 VBO 的内容,还是始终使用在创建 VAO 时绑定(bind)到索引 0 的任何 VBO?
我问是因为我发现很多例子先于调用 glVertexAttribFormat和 glVertexAttribBinding调用 glBindVertexBuffer
,如果 VAO 只跟踪索引则不需要调用(因为绑定索引在 glVertexAttribBinding
中给出)。
最佳答案
您可能已经知道,这是 OpenGL 4.3 中引入的相当新的功能。按照我阅读规范的方式,属性和缓冲区之间的映射现在具有一定程度的间接性:
- 每个属性都有一个指定它使用哪个绑定(bind)索引的特性。
- 缓冲区绑定(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
andglVertexAttribBinding
with a call toglBindVertexBuffer
, 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/