变换反馈对象的缓冲区绑定

Posted

技术标签:

【中文标题】变换反馈对象的缓冲区绑定【英文标题】:Buffer bindings of transform feedback objects 【发布时间】:2016-09-14 23:55:38 【问题描述】:

使用 OpenGL 4.5 和 NVidia 卡,我注意到当通过glBindTransformFeedback() 切换变换反馈对象时,与glBindBufferBase() 建立的关联数组缓冲区绑定不会改变。

看看下面的sn-ps:

假设有一对变换反馈和顶点缓冲对象:

GLuint tfo1, vbo1;
glGenTransformFeedbacks(1, &tfo1);
glGenBuffers(1, &vbo1);
glBindBuffer(GL_ARRAY_BUFFER, vbo1);
glBufferData(GL_ARRAY_BUFFER, 123 * sizeof(float), nullptr, GL_DYNAMIC_DRAW);

glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfo1);
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, vbo1);

使用glGetIntegerv()查询结果:

GL_TRANSFORM_FEEDBACK_BINDING: 1
GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: 1

假设有另一对这样的对象:

GLuint tfo2, vbo2;
glGenTransformFeedbacks(1, &tfo2);
glGenBuffers(1, &vbo2);
glBindBuffer(GL_ARRAY_BUFFER, vbo2);
glBufferData(GL_ARRAY_BUFFER, 123 * sizeof(float), nullptr, GL_DYNAMIC_DRAW);

glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfo2);
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, vbo2);

使用glGetIntegerv()查询结果:

GL_TRANSFORM_FEEDBACK_BINDING: 2
GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: 2

现在问题来了:在创建第二对之后,绑定之前的转换缓冲区对象tfo1...

glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfo1);

...导致以下查询结果:

GL_TRANSFORM_FEEDBACK_BINDING: 1
GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: 2   <--- WHY NOT 1?

绑定的 TFO 现在是 tfo1,但数组缓冲区绑定尚未更改。 看起来缓冲区绑定不是 TFO 状态的一部分,但可以吗? 管理缓冲区绑定不是 TFO 存在的主要原因吗?

【问题讨论】:

"管理缓冲区绑定不是 TFO 存在的主要原因吗?" 不;反馈对象存在的主要原因是能够暂停和恢复反馈操作。当然,它们确实包含缓冲区对象绑定。但是您应该向我们展示您查询这些内容的实际代码。因为我强烈怀疑您没有正确查询缓冲区。 变换反馈源/目标缓冲区选择的测试用例link 【参考方案1】:

根据OpenGL 4.5 core profile specification,通用GL_TRANSFORM_FEEDBACK_BUFFER_BINDING(使用glGetIntegerv 查询以及索引绑定(使用glGetIntegeri_v 查询)都是变换反馈对象状态的一部分。第 13.2.1 节“转换反馈对象”状态(强调我的)

通过将GenTransformFeedbacks 返回的名称与命令绑定来创建转换反馈对象 void BindTransformFeedback( enum target, uint id ); 生成的变换反馈对象是一个新的状态向量,包含所有状态并且具有表 23.48 中列出的相同初始值。

表 23.48 包含两者:

TRANSFORM_FEEDBACK_BUFFER_BINDING | Z+   | GetIntegerv   | 0 | Buffer object bound to generic bind point for transform feedback 
TRANSFORM_FEEDBACK_BUFFER_BINDING |n x Z+| GetIntegeri_v | 0 | Buffer object bound to each transform feedback attribute stream
[...]

因此,在您的示例中,切换回tfo1 也应该将通用转换缓冲区反馈绑定恢复回vbo1。我试过你的例子。在 AMD 实施(Windows 7、Firepro 15.201.2401 驱动程序)上,它的行为与规范所述相同。但是,使用 NVidia(Linux,370.28),我得到了与您描述的相同的结果。有趣的是,即使是 Nvidia 自己的来自GL_NV_transform_feedback2 的转换反馈对象版本也使用了类似的语言,并且明确地将泛型绑定定义为转换反馈对象状态的一部分。所以我会说你只是遇到了一些 Nvidia 错误。

【讨论】:

以上是关于变换反馈对象的缓冲区绑定的主要内容,如果未能解决你的问题,请参考以下文章

带偏移的变换反馈

webGL2统一缓冲区对象和布局的使用(std140)

绑定到“顶点数组对象”后,我应该删除“顶点缓冲区对象”吗?

OpenGL顶点数组对象不记录VBO和IBO绑定

如何使用直接状态访问将元素缓冲区数组“绑定”到顶点数组对象?

为啥 OpenGL 缓冲区解除绑定顺序很重要? [复制]