c++openglglfwgladdirect-state-access

Direct State Access (DSA) is Failing, but pre 4.3 OpenGL works


I currently have an OpenGL project in which I am using GLFW for the window and context creation, and GLAD for loading OpenGL functions. The GLAD version I am using is OpenGL 4.6, compatibility profile, with all extensions (including ARB_direct_state_access).

My current graphics card settings are

OpenGL Version: 4.6.0 NVIDIA 457.09
GLSL Version: 4.60 NVIDIA
Renderer: GeForce GTX 970/PCIe/SSE2
Vendor: NVIDIA Corporation

When I run the following non-DSA code, it works fine.

// Create vertex array object and bind it
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

// Create an index buffer object and use the data in the indices vector
GLuint ibo;
glGenBuffers(1, &ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicies.size()*sizeof(GLint), indicies.data(), GL_STATIC_DRAW);

// Create a array buffer object and use the positional data which has x,y,z components
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, positions.size()*sizeof(GLfloat), positions.data(), GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);

However when I try to translate this code to a DSA format and run it, the program opens a window and then terminates without and useful debug information.

GLuint vao;
glGenVertexArrays(1, &vao);

GLuint vbo;
glCreateBuffers(1, &vbo);
glNamedBufferStorage(vbo, positions.size()*sizeof(GLfloat), positions.data(), GL_DYNAMIC_STORAGE_BIT);
glVertexArrayVertexBuffer(vao, 0, vbo, 0, 0);
glEnableVertexArrayAttrib(vao, 0);
glVertexArrayAttribFormat(vao, 0, 3, GL_FLOAT, GL_FALSE, 0);
glVertexArrayAttribBinding(vao, 0, 0);

GLuint ibo;
glCreateBuffers(1, &ibo);
glNamedBufferStorage(ibo, sizeof(GLint)*indicies.size(), indicies.data(), GL_DYNAMIC_STORAGE_BIT);
glVertexArrayElementBuffer(vao, ibo);

In both cases I bind the Vertex Array Object before drawing like so

glBindVertexArray(vao);
glDrawElements(GL_TRIANGLES, indicies.size(), GL_UNSIGNED_INT, 0);

Why is my DSA like code not working?


Solution

  • When you use glVertexArrayVertexBuffer you must specify the stride argument. The special case in which the generic vertex attributes are understood as tightly packed when the stride is 0, as when using glVertexAttribPointer, does not apply when using glVertexArrayVertexBuffer.

    glVertexArrayVertexBuffer(vao, 0, vbo, 0, 0);

    glVertexArrayVertexBuffer(vao, 0, vbo, 0, 3*sizeof(float));
    

    It won't cause an error if stride is 0, but that doesn't mean it makes sense.