OpenGL顶点缓冲区绑定点可以在不同的VAO之间重用吗? [英] Can OpenGL vertex buffer binding points be reused across different VAOs?

查看:106
本文介绍了OpenGL顶点缓冲区绑定点可以在不同的VAO之间重用吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我使用新的(自OpenGL 4.3起)glBindVertexBuffer机制设置了两个VAO:

Suppose I set up two VAOs, using the new (as of OpenGL 4.3) glBindVertexBuffer mechanism:

glGenVertexArrays(1, &vaoIndex0);
glGenVertexArrays(1, &vaoIndex1);

...

glBindVertexArray(vaoIndex0)
glBindVertexBuffer(bindingIndex0, ...)
glEnableVertexAttribArray(0)
glVertexAttribFormat(0, ...)
glVertexAttribBinding(0, bindingIndex0)
...
glBindVertexArray(0)

...

glBindVertexArray(vaoIndex1)
glBindVertexBuffer(bindingIndex1, ...)
glEnableVertexAttribArray(0)
glVertexAttribFormat(0, ...)
glVertexAttribBinding(0, bindingIndex1)
...
glBindVertexArray(0)

并假定两者是独立的,除非它们存在于同一OpenGL上下文中.它们绑定不同的缓冲区,并将用于绘制不同的内容.

And suppose the two are independent, except insofar as they exist in the same OpenGL context; they bind different buffers and will be used to draw different things.

bindingIndex0是否需要与bindingIndex1不同?这两个指数的均等(或不平等)有什么意义吗?

Does bindingIndex0 need to be different from bindingIndex1? Is there any significance at all in the equality (or inequality) of the two indices?

...

收到答案后,我开始对实际上知道顶点缓冲区绑定点"(特别是其范围是什么)的某人了解,我的问题似乎是在问与我的意图不同的东西.也许会有一个更好的表述:是否需要竭尽全力以防止OpenGL顶点缓冲区绑定点 indices 甚至在多个VAO上重复使用,以防止冲突?"但是无论如何,似乎两个问题都已经得到了回答:不,您不能重用绑定点",也不需要以这种方式避免索引冲突.

After receiving an answer I began to understand that to someone who actually knows what a "vertex buffer binding point" is, and particularly, what its scope is, my question might seem to be asking something different than what I intended. Maybe a better phrasing would have been "Does one need to go out of one's way to prevent OpenGL vertex buffer binding point indices from being reused, even across multiple VAOs, in order to prevent conflicts?" But anyway, it seems that both questions have now been answered: No you can't reuse the "binding points", and no you don't need to avoid index conflicts in that way.

推荐答案

所有这些调用都会修改VAO状态.因此,不能,您不能在VAO之间重用这些设置.您当然可以在多个VAO中将它们设置为相同,但是在设置每个VAO时必须进行一次必要的状态设置调用.

All of these calls modify VAO state. So no, you cannot reuse these settings across VAOs. You can of course set them the same in multiple VAOs, but you have to make the necessary state setup calls once when you set up each VAO.

您在代码片段中使用的bindingIndex0bindingIndex1值没有任何特殊含义.它们只是在您使用glBindVertexBuffer()绑定到绑定索引的缓冲区与您指定使用该绑定索引的属性之间建立连接.

The bindingIndex0 and bindingIndex1 values you use in your code fragment don't have any special meaning. They just establish the connection between the buffer you bind to the binding index with glBindVertexBuffer(), and the attributes you specify as using that binding index.

唯一的条件是绑定索引必须小于您可以查询为MAX_VERTEX_ATTRIB_BINDINGS的值,该值必须至少为16.由于这些调用会修改每个VAO状态,因此您绝对可以使用相同的值.多个VAO的绑定索引.

The only condition is that the binding index has to be smaller than the value you can query as MAX_VERTEX_ATTRIB_BINDINGS, which is guaranteed to be at least 16. Since these calls modify per-VAO state, you absolutely can use the same binding indices for multiple VAOs.

查看这些较新的状态设置调用的一种方法是,它们引入了以前不可用的间接级别:

One way of looking at these newer state setup calls is that they introduce a level of indirection that was not previously available:

  • 无需这些调用,即可在绑定所需缓冲区的同时调用glVertexAttribPointer(),在顶点属性和缓冲区之间建立直接连接.
  • 通过这些新的调用,顶点属性现在具有到绑定索引的连接,该绑定索引由glVertexAttribBinding()建立.然后,将绑定索引连接到使用glBindVertexBuffer()建立的缓冲区.
  • Without these calls, you establish a direct connection between vertex attribute and buffer, by calling glVertexAttribPointer() while the desired buffer is bound.
  • With these newer calls, a vertex attribute now has a connection to a binding index, which is established with glVertexAttribBinding(). The binding index is then connected to a buffer, which is established with glBindVertexBuffer().

换句话说,旧式的连接是:

In other words, in old style the connection is:

attribute index --> buffer

具有这些4.3+调用的新样式:

new style with these 4.3+ calls:

attribute index --> buffer index --> buffer

此新灵活性的一个优点是,您可以通过一个调用将新缓冲区绑定到多个属性.只要所有这些属性都具有相同的缓冲区索引,您只需调用一次glBindVertexBuffer()即可为所有属性指定新的缓冲区.

One advantage of this new flexibility is that you can bind a new buffer to multiple attributes with a single call. As long as all these attributes have the same buffer index, you need just one call to glBindVertexBuffer() to specify a new buffer for all the attributes.

以下内容根本不是官方符号.我只是编造的.但是我认为通过写下一些伪数据结构来更正式地定义这些关系可能很有用.

The following is not official notation at all. I just made it up. But I thought it might be useful to define the relationships more formally, by writing down some pseudo data structures.

比方说,每个VAO都包含两个数组来捕获上面说明的连接:

Let's say each VAO contains two arrays to capture the connections explained above:

struct VAO {
    ...
    uint bufferIndexBindings[MAX_VERTEX_ATTRIB_BINDINGS];
    uint attribBufferIndices[MAX_VERTEX_ATTRIBS];
}

这里讨论的两个调用将修改此结构,如下所示:

The two calls discussed here would then modify this structure like this:

glBindVertexBuffer(uint bindingIndex, uint buffer, ...) {
    CurrentVAO.bufferIndexBindings[bindingIndex] = buffer;
}

glVertexAttribBinding(uint attribIndex, uint bindingIndex) {
    CurrentVAO.attribBufferIndices[attribIndex] = bindingIndex;
}

然后使用此状态获取索引为attribIndex的给定属性的缓冲区:

This state is then used to obtain the buffer for a given attribute with index attribIndex as:

CurrentVAO.bufferIndexBindings[CurrentVAO.attribBufferIndices[attribIndex]]

这也说明了我上面解释的间接性,这里显示为对状态表的两级查找.

This also illustrates the indirection I explained above, which shows up here as two levels of lookup into the state tables.

这篇关于OpenGL顶点缓冲区绑定点可以在不同的VAO之间重用吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆