Can VAO 0 be used as the default vertex array object in OpenGL core profile?
0 reputation · 17 Jun 2021, 11:32 UTC
0 reputation · 17 Jun 2021, 11:32 UTC
Goal: determine whether VAO 0 can be treated as a portable default vertex array object for vertex attribute and draw calls in OpenGL core profile contexts, compared with compatibility profile contexts.
OpenGL 3.1 and later core profiles require a non-zero VAO to be bound before glVertexAttribPointer or glDrawArrays; VAO 0 is not specified as a usable default object. Compatibility profiles retain VAO 0 as the default vertex array object. Driver behavior differs when VAO 0 is bound in a core profile: some implementations accept it silently, while others generate GL_INVALID_OPERATION. The specification leaves the outcome implementation-dependent, so results may vary by GPU vendor, driver version, and context creation flags.
Does binding VAO 0 in a core profile context satisfy the VAO binding requirement for glVertexAttribPointer and glDrawArrays? Is VAO 0 guaranteed to act as a valid default vertex array object across core-profile drivers? Can the same vertex-state code rely on VAO 0 when a windowing system exposes both core and compatibility contexts?
35275 reputation · 17 Jun 2021, 13:59 UTC
In an OpenGL core‑profile context (≥ 3.1), binding vertex‑array object zero is not a valid default. The specification requires a non‑zero VAO to be bound before any glVertexAttribPointer or draw call. Using VAO 0 will generate GL_INVALID_OPERATION on compliant drivers.
“The name zero is reserved for the default vertex array object. Binding vertex array object zero effectively unbinds any vertex array object. It is an error to specify vertex array state when no vertex array object is bound.”
VAO 0 as the default, so legacy code that omits glGenVertexArrays continues to work.VAO 0 and emit GL_INVALID_OPERATION (often visible via a debug callback).VAO 0 in core profile, but this is non‑conforming and can change with updates.#include <GL/glew.h>
#include <GLFW/glfw3.h>
int main() {
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* win = glfwCreateWindow(800, 600, "core", NULL, NULL);
glfwMakeContextCurrent(win);
glewExperimental = GL_TRUE; // required for core profile
glewInit();
GLuint vao; glGenVertexArrays(1, &vao);
glBindVertexArray(vao); // bind a real VAO
GLuint vbo; glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
// upload vertex data …
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glEnableVertexAttribArray(0);
// draw
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 3);
// cleanup
glDeleteBuffers(1, &vbo);
glDeleteVertexArrays(1, &vao);
glfwTerminate();
return 0;
}
glBindVertexArray(0); and then glVertexAttribPointer(...);.glGetError() or a debug callback. It should report GL_INVALID_OPERATION.For portable, core‑profile‑only applications, always create and bind a non‑zero VAO. Relying on VAO 0 is not guaranteed and will break on compliant drivers.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.