Search code examples
c++openglvbovao

In OpenGL is it possible to select from multiple indices with the same vao? Or share a vbo across vaos?


Suppose we are drawing a cube in 3 ways: points, wireframe and shaded. The same 8 points are used for both drawing commands, but the points can just be drawn from the vbo, the wireframe is connecting pairs of points, and the shaded version needs triangles.

This can be achieved using two index arrays. For wireframe:

uint32_t lineIndices[] = {
  0,1,     1,2,     2,3,     3,0,
  4,5,     5,6,     6,7,     7,4,
  0,4,     1,5,     2,6,     3,7
};

suppose these numbers are bound into an index array lbo. To draw the lines would be:

drawElements(GL_LINES, 24, GL_UNSIGNED_INT, BUFFER_OFFSET(0));

If instead I want to draw triangles, I need a different index.

If I have two indices, lbo and sbo, can both be in the same vao? Can I just bind the one that I want currently so it is used? If not, is it possible to share the same vbo across multiple vaos and have each index in a different vao?


Solution

  • Yes, you can put multiple sequences of indices within one index buffer.

    The last argument of glDrawElements() (void* indices) is actually not a pointer to memory but rather a starting byte offset into your index buffer. You can draw a subset of your indices by simply specifying the byte offset of the first index you want to draw, and specifying the number of indices to draw with the count argument as usual.

    For example, your index buffer could contain the 8 indices required to draw the cube as points, then the 24 indices required to draw the cube as lines, then the 36 indices required to draw the cube as triangles. If you want to draw the cube as lines, you could compute the byte offset of the first index (8 * sizeof(uint32_t)), and then simply call glDrawElements() as you have already, but passing this offset as the last argument.

    Side note: the index buffer is usually abbreviated as EBO for "element buffer object," rather than IBO.