So I was looking at another SO question regarding the command glVertexAttribPointer and I ran into a slight confusion. The accepted answer to this question explains,
But there's an additional implied piece of state that is also stored away for attribute 0 when you make the call: the data is read from the buffer currently bound to GL_ARRAY_BUFFER
This makes sense to me, but what if I have multiple buffers that are bound as GL_ARRAY_BUFFER
? How does the glVertexAttribPointer()
method know which one to set the attributes of?
For example, in my code, I'm drawing a gradient triangle. To do this, I've created 2 VBOs, one with color data in an array and another with vertex locations.
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
static const GLfloat points[] = {
//data here
};
static const GLfloat colors[] = {
//data here
};
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
vs = glCreateShader(GL_VERTEX_SHADER);
fs = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(vs, 1, &vertexShaderData, NULL);
glShaderSource(fs, 1, &fragShaderData, NULL);
glCompileShader(vs);
glCompileShader(fs);
sp=glCreateProgram();
glBindFragDataLocation(sp, 0, "outColor");
glAttachShader(sp, vs);
glAttachShader(sp, fs);
glLinkProgram(sp);
glUseProgram(sp);
glGenBuffers(1, &colorBuffer);
glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(1);
glDrawArrays(GL_TRIANGLES, 0, 9);
When I call the command, where do I specify which buffer to use?
This makes sense to me, but what if I have multiple buffers that are bound as GL_ARRAY_BUFFER?
That's not possible. When you bind a buffer (or any OpenGL object) to a target, it automatically unbinds whatever was there before.
OpenGL object targets are like global variables. What happens when you set a global integer to 3? It's old value is gone.
glVertexAttribPointer
will always use whatever buffer is currently bound to GL_ARRAY_BUFFER
. So in your first call, it will use buffer
. In your second call, it will use colorBuffer
.
This is why it is important to remember that glVertexAttribPointer
operates on what is currently bound. Because even after you bind colorBuffer
, and set it to be used by attribute 1, attribute 0 still receives its vertex data from buffer
.
So while you cannot have multiple buffers bound to GL_ARRAY_BUFFER
, you can use multiple buffers as sources for your vertex data.