whn*_*whn 5 opengl vertex-buffer vertex opengl-4 vertex-attributes
我一直在寻找将属性与任意组的顶点相关联的方法,起初,实例化似乎是实现此目的的唯一方法,但是后来我迷迷糊糊地问了这个问题,这个答案指出:
但是,使用较新版本的OpenGL可能会设置某个顶点属性的缓冲区偏移增加的速率。有效地,这意味着给定顶点数组的数据在属性的缓冲区偏移量增加之前被复制到n个顶点。设置该除数的函数是glVertexBindingDivisor。
(强调我的)
在我看来,这似乎是答案在断言,我可以划分顶点数而不是实例数。但是,当我查看glVertexBindingDivisor的文档并将其与进行比较时,glVertexAttribDivisor它们似乎都指发生在实例而非顶点上的划分。例如,在glVertexBindingDivisor的文档中指出:
glVertexBindingDivisor和glVertexArrayBindingDivisor修改在单个draw命令中渲染图元的多个实例时通用顶点属性前进的速率。如果除数为零,则使用绑定到bindingindex的缓冲区的属性每个顶点前进一次。如果除数不为零,则属性在每个要渲染的顶点集的除数实例中前进一次。如果相应的除数值不为零,则将该属性称为实例。
(强调我的)
那么这两个功能之间的实际区别是什么?
好吧,首先讲一点背景故事。
从OpenGL 4.3 / ARB_vertex_attrib_binding(又名:glVertexBindingDivisor来源,因此很重要)开始,VAO在概念上分为两部分:描述单个属性值的顶点格式数组,以及描述单个属性的缓冲区绑定点数组如何获取数据数组(缓冲区对象,偏移量,跨距和除数)。顶点格式指定其数据来自哪个缓冲区绑定点,以便多个属性可以从同一数组获取数据(即:交织)。
当VAO分为这两部分时,较旧的API就根据新系统进行了重新定义。因此,如果您glVertexAttribPointer使用属性索引进行调用,则此函数将为给定格式设置顶点格式数据index,并将为它设置缓冲区绑定状态(缓冲区对象,字节偏移量等)index。现在,这是两个独立的VAO状态数据数组(顶点格式和缓冲区绑定);此函数只是在两个数组中使用相同的索引。
但是由于顶点格式和缓冲区绑定现在是分开的,所以glVertexAttribPointer也相当于说index处的顶点格式从index index处的缓冲区绑定获取数据index。这很重要,因为这不是自动的。vertex_attrib_binding的全部要点是,一个索引处的顶点格式可以使用来自其他索引的缓冲区绑定。因此,当您使用旧的API时,它通过将format链接index到binding 来将自己重置为旧的行为index。
现在,与除数有什么关系?好吧,因为我刚才说的那句话实际上是它们之间的唯一区别。
glVertexAttribDivisor是用于设置除数的旧式API。它具有属性索引,但是它作用于作为缓冲区绑定点一部分的状态(实例化是每个数组的构造,而不是现在的每个属性的构造)。这意味着该函数假定(在新系统中)at处的属性index从处的缓冲区绑定点获取其数据index。
我刚才说的是一个谎言。它通过直接设置顶点格式以使用该缓冲区绑定点来强制执行此“假设” 。也就是说,它执行与最后相同的步骤。glVertexAttribPointer
glVertexBindingDivisor是现代功能。它没有传递属性索引。它传递了缓冲区绑定索引。因此,它不会更改属性的缓冲区绑定索引。
因此glVertexAttribDivisor完全等同于:
void glVertexAttribDivisor(GLuint index, GLuint divisor)
{
glVertexBindingDivisor(index, divisor);
glVertexAttribBinding(index, index);
}
Run Code Online (Sandbox Code Playgroud)
显然,glVertexBindingDivisor不做最后一部分。
那么这两个函数的实际区别是什么呢?
现代 OpenGL 有两个不同的 API 用于指定顶点属性数组及其属性。传统的glVertexAttribArray和朋友在一起,哪里glVertexAttribDivisor也是一部分。
(自ARB_vertex_attrib_bindingGL 4.3 起的核心)引入了一个新的 API,它将顶点格式与指针分开。预计切换数据指针很快,而切换顶点格式可能会更昂贵。新 API 允许分别显式控制这两个方面,而旧 API 总是同时设置这两个方面。
对于新的 API,引入了一个新的引入层:缓冲区绑定点。(有关更多详细信息,请参阅OpenGL wikiglVertexBindingDivisor 。)为此类绑定点指定属性实例除数,因此它在概念上等同于glVertexAttribDivisor新 API 的函数。