Search code examples
c++openglopengl-4

With OpenGL 4.3, how do I correctly use glVertexAttribFormat/Binding?


I was trying to use this feature, here is what I did:

glGenBuffers(1, &m_vbo_id);
glGenVertexArrays(1, &m_vao_id);

glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id);
glBindVertexArray(m_vao_id);

glEnableVertexAttribArray(0);  // Vertices
glEnableVertexAttribArray(1);  // Color
glEnableVertexAttribArray(2);  // Texture coordinates

glVertexAttribFormat(0, 3, GL_FLOAT, GL_FALSE, 0);
glVertexAttribBinding(0, m_vbo_id);
glVertexAttribFormat(1, 4, GL_FLOAT, GL_FALSE, 24* sizeof(float));
glVertexAttribBinding(1, m_vbo_id);
glVertexAttribFormat(2, 2, GL_FLOAT, GL_FALSE, 42* sizeof(float));
glVertexAttribBinding(2, m_vbo_id);

glBindVertexBuffer(m_vbo_id, m_buffer_data[00], 54*sizeof(float), 0);
glBindVertexBuffer(m_vbo_id, m_buffer_data[18], 54*sizeof(float), 0);
glBindVertexBuffer(m_vbo_id, m_buffer_data[42], 54*sizeof(float), 0);

m_bufferdata is a std::array<float, 54>, containing all the floats, which is rebuilt every frame. This will generate a GL_INVALID_OPERATION. Can anyone tell me why or how I correctly order the calls?


Solution

  • The second argument of glVertexAttribBinding is not the buffer object, but the binding index.
    The arguments of glBindVertexBuffer are the binding index, the buffer object, the offset and the stride. Stride is (3+4+2)*sizeof(float) for a tightly packed buffer:

    int bindingindex = 0;
    
    glVertexAttribFormat(0, 3, GL_FLOAT, GL_FALSE, 0);
    glVertexAttribBinding(0, bindingindex);
    glVertexAttribFormat(1, 4, GL_FLOAT, GL_FALSE, 24* sizeof(float));
    glVertexAttribBinding(1, bindingindex);
    glVertexAttribFormat(2, 2, GL_FLOAT, GL_FALSE, 42* sizeof(float));
    glVertexAttribBinding(2, bindingindex);
    
    glBindVertexBuffer(bindingindex, m_vbo_id, 0, 9*sizeof(float));