Dan Dan Dan Dan - 2 months ago 11
C++ Question

glDrawRangeElements doesn't draw the chosen range

I want to draw two cubes with a rectangle between them, so I stored vertices data into a vbo,then i created an ebo(Element Buffer Object) to avoid extra vertices(42 vs 12).
I need to draw them separately, because I want the rectangle to reflect the up cube, doing stencil test and disabling the depth mask while drawing the rectangle.
I thought I could draw the first cube with a glDrawElements call

glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);


then, to draw the ractangle I'm trying to use glDrawRangeElements

glDrawRangeElements(GL_TRIANGLES, 36, 41, 6, GL_UNSIGNED_INT, 0);


but it is just drawing the base of the cube.

For the last cube I am using the same draw call of the first, just inverting it in the z axis.

I think i did something wrong with glDrawRangeElements parameters, because i tried doing just one call for the first cube and then the rectangle

glDrawElements(GL_TRIANGLES, 42, GL_UNSIGNED_INT, 0);


and it works.

What's wrong with that glDrawRangeElements call?

EDIT: I solved by not using a glDrawRangeElements call but a simple glDrawArrays call, rearranging the rectangle's vertices to draw two triangles;

Answer

glDrawRangeElements doesn't do what you think it does. The functionality of glDrawRangeElements is identical to glDrawElements. The only difference is that glDrawRangeElements takes a range that acts as a hint to the implementation as to which vertices you'll be using.

See, because your indices are in an array, the driver doesn't automatically know what section of the vertex data you're using. You use glDrawRangeElements as a potential performance enhancer; it lets you tell the driver what range of vertices your draw call uses.

Nowadays, glDrawRangeElements is pointless. See, the range used to matter, because implementations used to read vertex arrays from CPU memory. So when you did a regular glDrawElements, the driver had to read your index buffer, figure out what the range of vertex data was, and then copy that data from your vertex buffers into GPU memory and then issue the draw call. The Range version allows it to skip the expensive index reading step.

That doesn't matter much anymore, since now we store vertex data in buffer objects on the GPU. So you shouldn't be using glDrawRangeElements at all.