<p>From the OpenGL 4.5 spec, <code>glDrawRangeElements</code>:</p>

<blockquote>
  <p>Implementations denote <strong>recommended maximum</strong> amounts of vertex and index
  data, which may be queried by calling GetIntegerv with pnames
  <strong>MAX_ELEMENTS_VERTICES</strong> and <strong>MAX_ELEMENTS_INDICES</strong>. </p>
  
  <p>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, <strong>then
  the call may operate at reduced performance</strong>.</p>
</blockquote>

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

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

<p>For reference, on my GTX 970 the value is 1048576 for both.</p>

CC BY-SA 3.0
2018-02-03T13:57:40.853Z
2018-02-03T13:57:40.853Z
Andreas
<p>The problem <code>glDrawRangeElements</code> was invented to fix was effectively removed by the advent of vertex buffers.</p>

<p>What <code>glDrawRangeElements</code> 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.</p>

<p>But that's only useful if you're reading from <em>client memory</em>. 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.</p>

<p>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 <code>Range</code> commands are no longer useful.</p>

CC BY-SA 3.0
2018-02-01T17:40:37.500Z
"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?
Startec
CC BY-SA 3.0
2018-02-01T17:43:06.120Z
"*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`.
Nicol Bolas
CC BY-SA 3.0
2018-02-01T15:34:50.167Z
2018-02-02T13:40:46.433Z
2018-02-02T13:40:46.433Z
Nicol Bolas
<p>I am trying to understand when it makes sense to use the <code>glDrawRangeElements</code> function.</p>

<p>The OpenGL wiki says:</p>

<blockquote>
  <p>for optimization purposes, it is useful for implementations to know the range of indexed rendering data</p>
</blockquote>

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

<p><strong>Is this a correct use case for <code>glDrawRangeElements</code>?</strong></p>

<p>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 <code>glDrawRangeElements</code> should be just a drop in replacement for <code>glDrawElements</code>.</p>

<p>However, <a href="https://gamedev.stackexchange.com/a/116838/77716">this answer</a> implies that <code>glDrawRangeElements</code> might actually be slower.</p>

<p>So, <strong>what are the pros and cons of using glDrawRangeElements?</strong></p>

CC BY-SA 3.0
2018-02-01T10:53:23.370Z
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).
Christian Rau
<opengl>
When does it make sense to use drawRangeElements
Startec
# When does it make sense to use drawRangeElements

(Asked by: username_0 on 2018-02-01)

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](https://gamedev.stackexchange.com/a/116838/77716) implies that `glDrawRangeElements` might actually be slower.

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

**Tags:** opengl

> **Comments:**
> **username_1**: 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).  

---

## 2 answers

### Answer by username_3 on 2018-02-01. Score: 6 | Accepted answer

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.

> **Comments:**
> **username_0**: "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?  
> **username_3**: "*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`.  

---

### Answer by username_2 on 2018-02-03. Score: 0

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.


---

