glVertexAttribDivisor和glVertexBindingDivisor有什么区别



我一直在寻找将属性与任意顶点分组相关联的方法,起初实例化似乎是我完成此操作的唯一方法,但后来我偶然发现了这个问题,这个答案指出:

但是,较新版本的 OpenGL 可能设置某个顶点属性的缓冲区偏移量前进的速率。实际上,这意味着在属性的缓冲区偏移量前进之前,给定顶点数组的数据将复制到 n 个顶点。设置此除数的函数是glVertexBindingDivisor

(强调我的)

在我看来,答案似乎是声称我可以除以顶点数而不是实例数。 然而,当我查看glVertexBindingDivisor的文档并将其与glVertexAttribDivisor的进行比较时,它们似乎都是指发生在实例而不是顶点上的划分。例如,在glVertexBindingDivisor的文档中,它指出:

glVertexBindingDivisor 和 glVertexArrayBindingDivisor 修改在单个绘制命令中呈现基元的多个实例时,通用顶点属性的前进速率。如果除数为零,则使用绑定到 bindingindex 的缓冲区的属性每个顶点前进一次。如果除数不为零,则属性将按要渲染的顶点集的每个除数实例前进一次。如果相应的除数值不为零,则属性称为实例化

(强调我的)

那么这两个功能之间的实际区别是什么?

好的,先说一点背景故事。

从OpenGL 4.3/ARB_vertex_attrib_binding(AKA:glVertexBindingDivisor来自哪里,所以这是相关的)开始,VAO在概念上分为两部分:描述单个属性数据价值的顶点格式数组,以及描述如何获取数据数组的缓冲区绑定点数组(缓冲区对象, 偏移量、步幅和除数)。顶点格式指定其数据来自哪个缓冲区绑定点,以便多个属性可以从同一数组获取数据(即:交错)。

当VAO被拆分为这两个部分时,旧的API根据新系统重新定义。因此,如果使用属性索引调用glVertexAttribPointer,此函数将为给定index的格式设置顶点格式数据,并且它将为同一index设置缓冲区绑定状态(缓冲区对象、字节偏移量等)。现在,这是两个独立的 VAO 状态数据数组(顶点格式和缓冲区绑定);此函数只是在两个数组中使用相同的索引。

但是由于顶点格式和缓冲区绑定现在是分开的,glVertexAttribPointer也相当于说索引index处的顶点格式从索引index处的缓冲区绑定获取其数据。这很重要,因为这不是自动的;vertex_attrib_binding的全部要点是,一个索引处的顶点格式可以使用来自不同索引的缓冲区绑定。因此,当您使用旧 API 时,它会通过将格式index链接到绑定index来将自身重置为旧行为。

现在,这一切与除数有什么关系?好吧,因为我刚才说的那件事实际上是它们之间的唯一区别。

glVertexAttribDivisor是用于设置除数的旧式 API。它采用属性索引,但它作用于作为缓冲区绑定点一部分的状态(实例化是每个数组的构造,而不是现在的每属性构造)。这意味着该函数假定(在新系统中)index的属性从index处的缓冲区绑定点获取其数据。

我刚才说的有点谎言。它通过直接设置顶点格式以使用该缓冲区绑定点来强制执行此"假设"。也就是说,它执行与glVertexAttribPointer相同的最后一步。

glVertexBindingDivisor是现代功能。它没有传递属性索引;它传递缓冲区绑定索引。因此,它不会更改属性的缓冲区绑定索引。

所以glVertexAttribDivisor完全等同于这个:

void glVertexAttribDivisor(GLuint index, GLuint divisor)
{
glVertexBindingDivisor(index, divisor);
glVertexAttribBinding(index, index);
}

显然,glVertexBindingDivisor没有做最后一部分。

那么这两个函数之间的实际区别是什么?

现代 OpenGL 有两个不同的API 用于指定顶点属性数组及其属性。传统的glVertexAttribArray和朋友,glVertexAttribDivisor也是其中的一部分。

随着ARB_vertex_attrib_binding(从GL 4.3开始的核心),引入了一个新的API,它将顶点格式与指针分开。预计切换数据指针的速度很快,而切换顶点格式的成本可能更高。新 API 允许分别明确控制这两个方面,而旧 API 总是同时设置这两个方面。

对于新的 API,引入了一个新的引入层:缓冲区绑定点。(有关更多详细信息,请参阅 OpenGL wiki。glVertexBindingDivisor指定此类绑定点的属性实例化除数,因此它在概念上等效于新 API 的glVertexAttribDivisor函数。

相关内容

  • 没有找到相关文章

最新更新