ARB_vertex_attrib_binding测试用例理解

时间:2017-03-17 15:19:58

标签: opengl opengl-es

我正在调查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);

首先,bindingPoint1bindingPoint2以奇怪的方式初始化(​​着色器中最大数量顶点位置的增量)。然后它被用作glVertexAttribPointer中的顶点属性位置(?)。之后,它用作glVertexAttribBinding中的顶点缓冲区绑定点。最后,没有glBindVertexBuffer调用,缓冲区bindingPoint1bindingPoint2被绑定了?我尝试了解 ARB_vertex_attrib_binding扩展程序,但我仍然不了解此代码。

对我来说,glVertexAttribPointer似乎不正确,因为顶点属性位置不正确,glVertexAttribBinding也不正确,因为没有顶点绑定点绑定到顶点缓冲区。 有人可以解释一下,这是怎么回事?

1 个答案:

答案 0 :(得分:2)

您正在阅读的内容是一项测试,用于验证OpenGL驱动程序是否正确实现了该功能。 并不意味着是合理代码的一个例子。它基本上是测试一个角落案例,一个理智的代码通常永远不会触发。

Vertex attrib绑定有效地重新定义了glVertexAttribPointerspecifying 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实际使用的两个属性从缓冲区绑定点bindingPoint1bindingPoint2获取缓冲区数据。另外两个属性也从相同的绑定点获取数据,VS不使用它们,因此无关紧要。

现在让我再次强调,在实际代码中,您应该永远不会这样做。选择一种API风格并坚持下去。或者如果没有,请在同一个VAO中选择API样式。