Search code examples
c++openglvertex-buffervertex-attributesvertex-array-object

Can I have multiple GL_ARRAY_BUFFER buffers?


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?


Solution

  • 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.