Search code examples
openglvertex-buffervertex-array-object

Binding multiple buffer object with a single vertex array object is not working


I'm trying to understand the mapping between OpenGL vertex buffer binding points and vertex array indices. I have a 2D rectangle and a 2D triangle

const GLfloat rect[] = {
       -0.5f,  0.5f,
        0.5f,  0.5f, 
        0.5f, -0.5f,
       -0.5f, -0.5f};

const GLfloat tri[] = { 
        0.0f,  1.0f,
        0.5f,  0.5f,
       -0.5f,  0.5f};

I put them in different vertex buffer objects and try to map them to vertex array object's indices so that first 3 attributes are from triangle and next 2 attributes are from the rectangle's last 2 points. Then I draw them as triangle strips.

GLuint vbo[2];
glGenBuffers(2, vbo);
GLuint varr;
glGenVertexArrays(1, &varr);
glBindVertexArray(varr);
// draw triangle
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
glBufferStorage(GL_ARRAY_BUFFER, sizeof(tri), tri, 0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
// draw rectangle
glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
glBufferStorage(GL_ARRAY_BUFFER, sizeof(rect), rect, 0);
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), 0);
glEnableVertexAttribArray(3);

glDrawArrays(GL_TRIANGLE_STRIP, 0, 5);

glDeleteVertexArrays(1, &varr);
glDeleteBuffers(2, vbo);

As you can see from the coordinates, the intended shape is like a hut, adjacent triangle over rectangle. However, what I get is this

display

Am I misunderstanding the binding or the indices of the vertex array object? Full compilable code is here, I use GtkGlExt but the OpenGL part is generic.


Solution

  • I think your are making a conceptual error about what an attribute is.

    As far as I understand what you try to do is to draw a triangle strip using 5 vertices, 3 of which come from the triangle and 2 of which come from the rectangle.

    However, attributes are parts of a vertex, i.e. the position and the color etc. . Vertex attribute buffer bindings are used for a set of attributes of all vertices. I.e. you can put the positions of all vertices in buffer 1 and the colors of all vertices in buffer 2.

    You can't put both the position and the color of the first few vertices in one buffer and the position and color of the other vertices in another buffer and still draw them in a single call.

    The solution is to concatenate the buffers (or more accurately the triangle buffer and the last part of the rectangle buffer) into a single buffer or split the draw call into multiple draw calls.