I'm trying to put together a very basic OpenGL 3.2 (core profile) application. In the following code, which is supposed to create a VBO containing the vertex positions for a triangle, the call to glVertexAttribPointer
fails and raises the OpenGL error GL_INVALID_OPERATION
. What does this mean, and how might I go about fixing it?
GLuint vbo, attribLocation = glGetAttribLocation(...);
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
GLfloat vertices[] = { 0, 1, 0, 1, 0, 0, -1, 0, 0 };
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(attribLocation);
// At this point, glGetError() returns GL_NO_ERROR.
glVertexAttribPointer(attribLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
// At this point, glGetError() returns GL_INVALID_OPERATION.
glEnableVertexAttribArray(program.getAttrib("in_Position"));
// A call to getGLError() at this point prints nothing.
glVertexAttribPointer(program.getAttrib("in_Position"), 3, GL_FLOAT, GL_FALSE, 0, 0);
// A call to getGLError() at this point prints "OpenGL error 1282".
First, there's an obvious driver bug here, because glEnableVertexAttribArray
should also have issued a GL_INVALID_OPERATION
error. Or you made a mistake when you checked it.
Why should both functions error? Because you didn't use a Vertex Array Object. glEnableVertexAttribArray
sets state in the current VAO. There is no current VAO, so... error. Same goes for glVertexAttribPointer
. It's even in the list of errors for both on those pages.
You don't need a VAO in a compatibility context, but you do in a core context. Which you asked for. So... you need one:
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
Put that somewhere in your setup and your program will work.
As an aside, this:
glfwOpenWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
is only necessary if you intend your code to run on MacOS's GL 3.2+ implementation. Unless you have that as a goal, it is unneeded and can be disruptive, as a small number of features are available in a core context that are not part of forward compatibility (wide lines, for example).