我正在调查OpenGL Android deqp测试套装,并与其中一个案例混淆。测试是 dEQP-GLES31.functional.vertex_attribute_binding.usage.mixed_usage.mixed_api_change_binding_point 。 可以找到来源here,感兴趣的行是1197-1213。我不知道,使用了一个技巧。
const int maxUsedLocation = de::max(positionLoc, colorLoc);
const int bindingPoint1 = maxUsedLocation + 1;
const int bindingPoint2 = maxUsedLocation + 2;
// bind data using old api
gl.glBindBuffer(GL_ARRAY_BUFFER, m_buffer);
gl.glVertexAttribPointer(bindingPoint1, 4, GL_FLOAT, GL_FALSE, (glw::GLsizei)(2 * sizeof(tcu::Vec4)), (const deUint8*)DE_NULL);
gl.glVertexAttribPointer(bindingPoint2, 4, GL_FLOAT, GL_FALSE, (glw::GLsizei)(2 * sizeof(tcu::Vec4)), (const deUint8*)DE_NULL + sizeof(tcu::Vec4));
// change buffer binding point with vertex_attrib_binding
gl.glVertexAttribFormat(positionLoc, 4, GL_FLOAT, GL_FALSE, 0);
gl.glVertexAttribFormat(colorLoc, 4, GL_FLOAT, GL_FALSE, 0);
gl.glVertexAttribBinding(positionLoc, bindingPoint1);
gl.glVertexAttribBinding(colorLoc, bindingPoint2);
首先,bindingPoint1
和bindingPoint2
以奇怪的方式初始化(着色器中最大数量顶点位置的增量)。然后它被用作glVertexAttribPointer
中的顶点属性位置(?)。之后,它用作glVertexAttribBinding
中的顶点缓冲区绑定点。最后,没有glBindVertexBuffer
调用,缓冲区bindingPoint1
和bindingPoint2
被绑定了?我尝试了解 ARB_vertex_attrib_binding扩展程序,但我仍然不了解此代码。
对我来说,glVertexAttribPointer
似乎不正确,因为顶点属性位置不正确,glVertexAttribBinding
也不正确,因为没有顶点绑定点绑定到顶点缓冲区。
有人可以解释一下,这是怎么回事?
答案 0 :(得分:2)
您正在阅读的内容是一项测试,用于验证OpenGL驱动程序是否正确实现了该功能。 并不意味着是合理代码的一个例子。它基本上是测试一个角落案例,一个理智的代码通常永远不会触发。
Vertex attrib绑定有效地重新定义了glVertexAttribPointer
,specifying that it now works by using glVertexAttribFormat
/etc internally的含义。此测试旨在验证驱动程序是否正确实现了重新定义的glVertexAttribPointer
。
同样,你不应该编写像这样混合两者的代码。但规范允许它,因此一个好的测试人员应该验证实现是否正在发挥作用。
因此对glVertexAttribPointer
的两次调用有效地执行了以下操作:
glVertexAttribFormat(bindingPoint1, ..., 0);
glBindVertexBuffer(bindingPoint1, m_buffer, 0, (glw::GLsizei)(2 * sizeof(tcu::Vec4)));
glVertexAttribBinding(bindingPoint1, bindingPoint1);
glVertexAttribFormat(bindingPoint2, ..., 0);
glBindVertexBuffer(bindingPoint2, m_buffer, sizeof(tcu::Vec4), (glw::GLsizei)(2 * sizeof(tcu::Vec4)));
glVertexAttribBinding(bindingPoint2, bindingPoint2);
因此,这会设置两个属性以及两个缓冲区绑定。但是着色器实际上从未使用过这些属性。
后面的代码设置了另外两个属性,但是:
gl.glVertexAttribBinding(positionLoc, bindingPoint1);
gl.glVertexAttribBinding(colorLoc, bindingPoint2);
意味着他们获取属性从先前建立的绑定点获取其顶点数据。因此VS实际使用的两个属性从缓冲区绑定点bindingPoint1
和bindingPoint2
获取缓冲区数据。另外两个属性也从相同的绑定点获取数据,VS不使用它们,因此无关紧要。
现在让我再次强调,在实际代码中,您应该永远不会这样做。选择一种API风格并坚持下去。或者如果没有,请在同一个VAO中选择API样式。