# When does it make sense to use drawRangeElements

I am trying to understand when it makes sense to use the glDrawRangeElements function.

The OpenGL wiki says:

for optimization purposes, it is useful for implementations to know the range of indexed rendering data

So, as I interpret it, if I had one large buffer (containing say, multiple meshes' data) and I was planning to call glDrawRangeElements if I instead specify the minimum and maximum index values that this call will use, I could achieve a speedup.

Is this a correct use case for glDrawRangeElements?

It seems like I would almost always know the minimum and maximum index values (because I would know ahead of time what I am going to draw) so it seems like glDrawRangeElements should be just a drop in replacement for glDrawElements.

However, this answer implies that glDrawRangeElements might actually be slower.

So, what are the pros and cons of using glDrawRangeElements?

• Really interesting question. I long wondered about what the practical relevance of this function actually is nowadays, especially since there are no ranged calls for any of the more advanced drawcalls that arose later on, like instanced rendering for example. It seems like a relic of the past (maybe from the times before VBOs). Feb 1 '18 at 10:53

The problem glDrawRangeElements was invented to fix was effectively removed by the advent of vertex buffers.

What glDrawRangeElements allows the implementation to do is to know exactly what range of values will be used as indices for the vertex arrays. Given that knowledge, they can read that range of values into a separate buffer, and then render from that buffer. Without knowing the range of indices, that wouldn't be possible, since an index list could pick from any index.

But that's only useful if you're reading from client memory. Copying that range out of client memory allows you to render asynchronously. You copy out the values you know you need, issue a rendering command with that, and then return to the caller.

If you're reading from buffer objects, this isn't a useful thing to do. And since core OpenGL doesn't even allow you the option of using client memory, the Range commands are no longer useful.

• "You copy out the values you know you need, issue a rendering command with that, and then return to the caller" - here is specifying the the indices in an EBO what you mean when you "copy out the values", and what do you mean by "return to the caller" - the caller being your application here? Feb 1 '18 at 17:40
• "what you mean when you "copy out the values"" Vertex arrays contain the vertex data that you're going to render with. Copying out the values would be copying out the data that will be rendered. "what do you mean by "return to the caller"" The caller of glDrawRangeElements. Feb 1 '18 at 17:43

From the OpenGL 4.5 spec, glDrawRangeElements:

Implementations denote recommended maximum amounts of vertex and index data, which may be queried by calling GetIntegerv with pnames MAX_ELEMENTS_VERTICES and MAX_ELEMENTS_INDICES.

If end − start + 1 is greater than the value of MAX_ELEMENTS_VERTICES, or if count is greater than the value of MAX_ELEMENTS_INDICES, then the call may operate at reduced performance.

My interpretation of this is glDrawElements may perform worse than glDrawRangeElements if the index count or implicit range exceed that of the implementation dependent GL_MAX_ELEMENTS_{INDICES|VERTICES}. For platforms where glDrawElements is always superior I would expect glDrawRangeElements to ignore start and end all together, and the value of GL_MAX_ELEMENTS_{INDICES|VERTICES} to be "infinite".

Correct usage according to spec is therefore whenever glDrawElements exceeds GL_MAX_ELEMENTS_{INDICES|VERTICES} and glDrawRangeElements does not.

For reference, on my GTX 970 the value is 1048576 for both.