2

The Description

I'm currently learning OpenGL and want to try out the the direct state access extension from OpenGL 4.5. Thus I setup a simple triangle render example (in 3D) which should render my triangle. The code below is executed each frame and draws a triangle in 3D space.

    void Geometry::draw(glm::vec3 pos, glm::vec3 pos1, glm::vec3 pos2) {
        float vertices[9] = {
            pos.x, pos.y, pos.z,
            pos1.x, pos1.y, pos1.z,
            pos2.x, pos2.y, pos2.z
        };

        unsigned int m_VaoID;
        glGenVertexArrays(1, &m_VaoID);
        glBindVertexArray(m_VaoID);

        unsigned int m_VboID;
        glGenBuffers(1, &m_VboID);
        glBindBuffer(GL_ARRAY_BUFFER, m_VboID);
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 3, 0);

        Shader shader = Shader("../../shader.glsl");
        shader.compileShader();
        shader.useShader();

        glDrawArrays(GL_TRIANGLES, 0, 3);

        glBindVertexArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glDeleteVertexArrays(1, &m_VaoID);
        glDeleteBuffers(1, &m_VboID);
    }

However, as soon as I change the code to make use of the direct state access extension, it no longer renders a triangle and instead produces error messages.

    void Geometry::drawDSA(glm::vec3 pos, glm::vec3 pos1, glm::vec3 pos2) {
        float vertices[9] = {
            pos.x, pos.y, pos.z,
            pos1.x, pos1.y, pos1.z,
            pos2.x, pos2.y, pos2.z
        };

        unsigned int m_VaoID;
        glCreateVertexArrays(1, &m_VaoID);
        glVertexArrayAttribFormat(m_VaoID, 0, 3, GL_FLOAT, GL_FALSE, 0);

        unsigned int m_VboID;
        glCreateBuffers(1, &m_VboID);
        glNamedBufferData(m_VboID, sizeof(vertices), vertices, GL_STATIC_DRAW);

        glVertexArrayAttribBinding(m_VaoID, 0, m_VboID);

        Shader shader = Shader("../../shader.glsl");
        shader.compileShader();
        shader.useShader();

        glBindVertexArray(m_VaoID);
        glBindBuffer(GL_ARRAY_BUFFER, m_VboID);

        glDrawArrays(GL_TRIANGLES, 0, 3);

        glBindVertexArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glDeleteVertexArrays(1, &m_VaoID);
        glDeleteBuffers(1, &m_VboID);
    }

Both methods get called in my update loop with the same values (between -1.f and 0.f).

The error output:

Here is the console output of the error I'm getting:

[OpenGL Debug HIGH] GL_INVALID_VALUE in glVertexArrayAttribBinding(bindingindex=16 >= GL_MAX_VERTEX_ATTRIB_BINDINGS)
[OpenGL Debug HIGH] GL_INVALID_VALUE in glVertexArrayAttribBinding(bindingindex=17 >= GL_MAX_VERTEX_ATTRIB_BINDINGS)
[OpenGL Debug HIGH] GL_INVALID_VALUE in glVertexArrayAttribBinding(bindingindex=18 >= GL_MAX_VERTEX_ATTRIB_BINDINGS)
[OpenGL Debug HIGH] GL_INVALID_VALUE in glVertexArrayAttribBinding(bindingindex=19 >= GL_MAX_VERTEX_ATTRIB_BINDINGS)

What I tried so far

I looked through the Khronos Wiki and through the docs.gl documentation, but I could not find out why my code produces the above error instead of rendering my triangle.

ShadowDragon
  • 2,238
  • 5
  • 20
  • 32
  • 1
    The third parameter of `glVertexArrayAttribBinding` should not be a VBO. You are also missing calls to `glVertexArrayAttribFormat` and `glVertexArrayVertexBuffer`. I guess you confused completely how DSA works. Check out [Direct State access with vertex buffers](https://stackoverflow.com/questions/32739297/direct-state-access-with-vertex-buffers/32739484#32739484) for a step-by-step explanation on how to translate from old code to DSA. Also note, that you shouldn't call `glBindBuffer` when drawing. – BDL May 15 '20 at 19:58

1 Answers1

1

The 3d parameter of glVertexArrayAttribBinding is not the vertex buffer object, it is a binding index. It is an arbitrary id which you have to choose.
The following instruction associates a binding index to an attribute index (0) of the specified VAO.

glVertexArrayAttribBinding(m_VaoID, 0, m_VboID);

glVertexArrayAttribBinding(m_VaoID, 0, binding_index);

Furthermore you have to useglVertexArrayVertexBuffer to associate a buffer object to a binding index of a specified VAO:

glVertexArrayVertexBuffer(m_VaoID, binding_index, m_VboID, 0, sizeof(float) * 3);
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • Thx for the answer. Could you please specify what the binding index is for? Can I just choose any random number? Interesting to know that I still have to call `glBindVertexBuffer` despite using DSA. I thought this would no longer be necessary. – ShadowDragon May 15 '20 at 20:03
  • @ShadowDragon 1. Yes random. 2. I've changed the answer. – Rabbid76 May 15 '20 at 20:08
  • 2
    @ShadowDragon: You shouldn't be using glBindVertexBuffer but glVertexArrayVertexBuffer. – BDL May 15 '20 at 20:11