0

I have two buffers I created like this:

    GLuint vao;
    GLuint vbo[2];

    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);
    glGenBuffers(2, vbo);

    // 1
    glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(triangle), triangle, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GL_FLOAT), (void*)0);
    glEnableVertexAttribArray(0);

    // 2
    glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(rectangle), rectangle, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GL_FLOAT), (void*)0);
    glEnableVertexAttribArray(0);

The first one has to create a triangle and the second one a rectangle. So I am calling glDrawArrays() in the rendering loop like this:

        glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
        glDrawArrays(GL_POLYGON, 0, 3);         // Triangle

        glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
        glDrawArrays(GL_POLYGON, 0, 4);         // Rectangle

So why doesn't this work? (PS: I know GL_TRIANGLES is used nowdays, but for this project I have to use GL_POLYGON)

leech
  • 367
  • 1
  • 4
  • 16

1 Answers1

2

I case of a VBO and vertex attribute pointers, it's not that important which VBO is bound but which VBO is attached to the attribute. The VBO-attribute binding is established with the glVertexAttribPointer call, which means that calling it a second time with the same attribute index will unbind the first one.

You either have to establish the binding before each draw call, like:

glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GL_FLOAT), (void*)0);
glDrawArrays(GL_POLYGON, 0, 3);         // Triangle

glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GL_FLOAT), (void*)0);
glDrawArrays(GL_POLYGON, 0, 4);         // Rectangle

Or you could use two VAO, setup each on their own and switch VAO during rendering.

If your geometry is fixed and you always have to render these two geometries, I would think about combining the two geometries in one VBO and use the first parameter of the glDrawArrays command to draw the geometries. This should lead to better performance since you need less state changes. The code for this would be something like:

glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glGenBuffers(1, vbo);

// Allocate memory for both geometries
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(triangle) + sizeof(rectangle), NULL, GL_STATIC_DRAW);
//Copy geometries one after the other to the VBO
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(triangle), triangle);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(triangle), sizeof(rectangle), rectangle);

//Attribute binding
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GL_FLOAT), (void*)0);
glEnableVertexAttribArray(0);

Rendering:

glBindVertexArray(vao);
glDrawArrays(GL_POLYGON, 0, 3);         // Triangle
glDrawArrays(GL_POLYGON, 3, 4);         // Rectangle
BDL
  • 21,052
  • 22
  • 49
  • 55