提问者:小点点

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


创建时,VAOs是只跟踪VBO索引(通过glBindVertexBuffer),还是还跟踪绑定到这些索引的VBO名称?如果我在VAO创建期间使用glVertexAttribBinding指定一个绑定索引,比如说,0,我能在一个draw调用之前将另一个VBO绑定到索引0,并让它使用那个VBO的内容吗,或者它将总是使用在VAO创建时VBO绑定到索引0的任何内容吗?

我这样问是因为我发现的许多示例都是在调用glVertexAttribBinding和glVertexAttribBinding之前先调用< code>glBindVertexBuffer,如果VAO只跟踪索引,这应该是不必要的(因为绑定索引是在< code > glVertexAttribBinding 中给出的)。


共2个答案

匿名用户

您可能知道,这是OpenGL 4.3中引入的相当新的功能。根据我阅读规范的方式,属性和缓冲区之间的映射现在具有间接级别:

  1. 每个属性都有一个属性,用于指定它使用的绑定索引。
  2. 缓冲区绑定到绑定索引。

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

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

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

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

在此基础上,解决您的具体问题:

创建时,vao是只跟踪VBO索引(通过< code>glBindVertexBuffer),还是还跟踪绑定到这些索引的VBO名称?

他们跟踪两者。

我可以在抽签调用之前将不同的VBO绑定到索引0并让它使用该VBO的内容吗?

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

我发现很多例子在调用glVertexAttribFormatglVertexAttribBinding之前调用glBindVertexBuffer,如果VAO只跟踪索引,这应该是不必要的。

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

匿名用户

答案是它们不存储顶点名称,只存储索引。如果将不同的 VBO 绑定到不同 VAO 中的同一索引,则必须在使用第一个 VAO 的任何 glDraw 调用之前再次重新绑定第一个 VCO。

至少在我的Macbook Pro上:

渲染器:NVidia GeForce GT 650M OpenGL引擎

版本: 4.1 英伟达-10.0.43 310.41.05f01