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

时间:2014-11-05 21:59:22

标签: opengl vbo opengl-4 vao

创建时,VAO是否仅跟踪VBO索引(通过glBindVertexBuffer),或者哪些VBO名称与这些索引绑定?如果我在VAO创建过程中使用glVertexAttribBinding指定了一个绑定索引,比如0,我可以在绘制调用之前将不同的VBO绑定到索引0并让它使用该VBO的内容,或者它是否总是在创建VAO时使用VBO绑定为0的任何东西?

我问,因为我找到的很多示例都先调用glVertexAttribFormatglVertexAttribBinding来调用glBindVertexBuffer,如果VAO只跟踪索引,则不应该这样做(因为绑定索引在glVertexAttribBinding)中给出。

2 个答案:

答案 0 :(得分:4)

您可能已经意识到,这是OpenGL 4.3中引入的相当新功能。我读取规范的方式,属性和缓冲区之间的映射现在有一个间接级别:

  1. 每个属性都有一个属性,用于指定它使用的绑定索引。
  2. 缓冲区必然会绑定索引。
  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的内容。

      

    我发现的很多示例都在调用glVertexAttribFormatglVertexAttribBinding之前调用glBindVertexBuffer,如果VAO仅跟踪索引,则不应该这样做

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

答案 1 :(得分:-1)

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

至少在我的Macbook Pro上:

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

版本:4.1 NVIDIA-10.0.43 310.41.05f01