3

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

我问是因为我发现很多示例在调用glVertexAttribFormatglVertexAttribBinding之前调用,glBindVertexBuffer如果 VAO 仅跟踪索引(因为绑定索引在 中给出glVertexAttribBinding),则不需要这样做。

4

2 回答 2

5

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

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

您可以将其视为两张表,一张定义从属性索引到绑定索引的映射,另一张定义从绑定索引到缓冲区名称的映射。这两个表都是 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()在您的绘图调用之前只需要一次调用即可再次设置整个状态。

于 2014-11-06T04:25:24.490 回答
-1

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

至少在我的 Macbook Pro 上:

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

版本:4.1 NVIDIA-10.0.43 310.41.05f01

于 2014-12-19T19:02:01.733 回答