您可能知道,这是 OpenGL 4.3 中引入的相当新的功能。按照我阅读规范的方式,属性和缓冲区之间的映射现在具有一定程度的间接性:
- 每个属性都有一个属性,指定它使用哪个绑定索引。
- 缓冲区绑定到绑定索引。
您可以将其视为两张表,一张定义从属性索引到绑定索引的映射,另一张定义从绑定索引到缓冲区名称的映射。这两个表都是 VAO 状态的一部分。
我相信这些可以完全独立地以任何顺序指定。glVertexAttribBinding()
在属性索引和绑定索引之间建立第一个关联。glBindVertexBuffer()
建立绑定索引和缓冲区名称之间的关联。
规范中的状态表证实了这种理解。GL 4.4 规范中的表 23.4,标题为“顶点数组对象状态”,列出:
VERTEX_ATTRIB_BINDING
,可以用 查询glGetVertexAttribiv()
,是给定属性索引的绑定索引的值。
VERTEX_BINDING_BUFFER
,可以用 查询glGetIntegeri_v()
,是给定绑定索引的缓冲区名称的值。
基于此,解决您的具体问题:
创建时,VAO 是否仅跟踪 VBO 索引(通过glBindVertexBuffer
),或者哪些 VBO 名称绑定到这些索引?
他们跟踪两者。
我可以在绘图调用之前将不同的 VBO 绑定到索引 0 并让它使用该 VBO 的内容吗
是的,如果您将不同的 VBO 绑定到绑定索引 0,则所有绑定索引为 0 的属性都将使用该 VBO 的内容。
我发现很多例子在调用之前glVertexAttribFormat
和glVertexAttribBinding
调用之前glBindVertexBuffer
,如果 VAO 只跟踪索引,这应该是不必要的
VAO 跟踪所有这些调用设置的状态,因此将所有这些调用用作设置 VAO 的一部分是有意义的。跟踪 VAO 中的整个顶点设置状态是首先拥有 VAO 的主要目的。它允许您在初始化期间设置一次状态,然后glBindVertexArray()
在您的绘图调用之前只需要一次调用即可再次设置整个状态。