直接状态访问 (DSA) 失败,但 4.3 之前的 OpenGL 工作

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

我目前有一个 OpenGL 项目,我在其中使用 GLFW 进行 window 和上下文创建,并使用 GLAD 加载 OpenGL 函数。我使用的 GLAD 版本是 OpenGL 4.6,兼容性配置文件,具有所有扩展(包括 ARB_direct_state_access)。

我目前的显卡设置是

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

当我 运行 以下非 DSA 代码时,它工作正常。

// 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);

但是,当我尝试将此代码转换为 DSA 格式并 运行 时,程序会打开一个 window,然后在没有有用的调试信息的情况下终止。

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);

在这两种情况下,我都在绘制之前绑定了顶点数组对象

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

为什么我的 DSA 类代码不起作用?

当您使用 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 时,在使用 glVertexArrayVertexBuffer 时不适用。

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

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

如果stride为0不会报错,但不代表有意义