# Why does OpenGL >= 3 only allow VBOs?

I see that OpenGL versions 3 and up eliminate the use of client-side rendering. Immediate mode has been eliminated, and vertex arrays seem to be deprecated. Instead, if I understand correctly, VBOs are the main way of rendering vertices.

While I see the logic behind having a uniform way of rendering everything, is it the case that VBOs have no major downsides over vertex arrays? I thought VBOs were supposed to be large buffers containing > 1MB of data, generally. What if I have a scene that has a lot of smaller geometry? I have a scene graph with a large number of nodes, each of which needs its own transform, etc. Each node should also be able to be deleted separately, added to separately, etc. I was using vertex arrays before. So my first question is whether, if I switch to VBOs, there will be a greater overhead to my scene graph objects now because a VBO needs to be allocated for each object.

Another concern is that the geometry I'm rendering can be highly dynamic. In the worst case, there may be times when all geometry needs to be resent every frame for some period of time. Will VBOs have worse performance than vertex arrays in this use case, or do VBOs at worst do just as much work as vertex arrays but no more?

So, in more concise format, my questions are:

1) Is there a substantial overhead to allocating / deallocating VBOs (I mean the mere act of setting up a buffer)?

2) If I'm updating the data from the CPU every frame, can this be substantially worse than if I had used vertex arrays?

And finally, I'd like to know:

3) If the answer to either of the above questions is "yes", why deprecate other modes of rendering that could have advantages over VBOs? Is there something I'm missing here, like techniques I'm supposed to use to mitigate some of these potential allocation costs, etc.?

4) Do the answers to any of these questions change substantially depending on what OpenGL version I'm using? If I refactor my code to be OpenGL 3 or 4 forward-compatible by using VBOs in a way that is performant, will the same techniques be likely to perform well with OpenGL 2, or is it likely that certain techniques are much faster with OpenGL 3+ and others with OpenGL 2?

I asked this question on stack overflow, but I am re-posting here because I realized this site may be more appropriate for my question.

• Why a vote to close? Is it a dup? If so, can I see a link so that I can benefit from it? Jan 1, 2012 at 1:16

Is there a substantial overhead to allocating / deallocating VBOs (I mean the mere act of setting up a buffer)?

Define "substantial." It is generally wise not to create them in the middle of frames; they should be set up during initialization or wherever. But this is true of most OpenGL objects, like textures, renderbuffers, or shaders.

If I'm updating the data from the CPU every frame, can this be substantially worse than if I had used vertex arrays?

Can it? Yes. OpenGL defines functionality, not performance. You can indeed make things much slower. Or you can make things faster. It all depends on how you use it.

The OpenGL Wiki has a good article on how to properly stream data.

If the answer to either of the above questions is "yes", why deprecate other modes of rendering that could have advantages over VBOs? Is there something I'm missing here, like techniques I'm supposed to use to mitigate some of these potential allocation costs, etc.?

First, they weren't just deprecated. Deprecation means marking something as "to be removed" in future versions. They were deprecated in 3.0, and removed in 3.1 core and above.

Second, the ARB has generally explained the reason they removed stuff from OpenGL. It makes the spec smaller and simpler. It makes the API smaller and more streamlined. It makes it easier to know what APIs you ought to be using; 2.1 had 4 ways to provide vertex data; 3.1+ has 1. It gets rid of a lot of cruft. Etc.

Do the answers to any of these questions change substantially depending on what OpenGL version I'm using? If I refactor my code to be OpenGL 3 or 4 forward-compatible by using VBOs in a way that is performant, will the same techniques be likely to perform well with OpenGL 2, or is it likely that certain techniques are much faster with OpenGL 3+ and others with OpenGL 2?

More or less no. Only on MacOSX is the difference between 3.1+core and pre-3.0 versions really apparently. The compatibility profile is implemented by all drivers for Linux and Windows, so you can assume that the core profile from these drivers is really just adding checks to prevent you from calling compatibility functions.

Under Mac OSX 10.7, GL 3.2 core is available, but not the compatibility profile. That doesn't necessarily mean anything for performance techniques on one versus the other. But it does mean that if there are differences, that is the platform you will see them on.

• Since you just cross-posted this question, I'll just cross-post my answer. Jan 1, 2012 at 1:26
• Another advantage of keeping the API concise is that it makes the OpenGL API easier to implement. This was a big consideration in the original OpenGL ES spec. Jan 1, 2012 at 1:41
• @stephelton: Makes sense. My "why deprecate everything but VBOs" question was based on the thinking that while it makes perfect sense to keep the API lean, it doesn't make sense to deprecate features that could be better than VBOs for many use cases. From what I'm hearing, it seems there are no disadvantages to using VBOs, though, so then it makes perfect sense to deprecate everything else. Jan 2, 2012 at 4:30
• @gravity You don't have to use VBO's. You can use an array of vertices as well. Jan 2, 2012 at 5:30

The way OpenGL works, whenever you use non-VBO data, the driver has to make a copy of it - in practice creating a temporary VBO - since nothing stps you from modifying your user-space naked arrays between calls to OpenGL.

There may be some driver-side trickery to make the temp allocation faster, but there's nothing you can do to avoid the copying.

So yeah, as long as you - and the driver developers - do everything right, VBOs should(tm) always just speed things up.

• I like this answer better. It's shorter and more down to the point, imo. Jan 1, 2012 at 8:41
• @JariKomppa: That sounds like a very reasonable explanation. I still have one concern: VBOs are supposed to be reasonably large objects, often allocated as 1MB - 4MB buffers last time I checked. What if my geometry objects aren't that large, but I'm still concerned about performance because I have lots of objects? I'm worried VBOs might just be for a different use case than what I have. Should I pool multiple objects together in a single VBO and then use glDrawRangeElements to draw each individual object, or is that inefficient just like vertex arrays? Jan 2, 2012 at 4:25
• I doubt that will make any difference, but if you feel it's a concern, benchmark it. Jan 2, 2012 at 4:45
• @JariKomppa: What do you doubt will make a difference? Using glDrawRangeElements multiple times on each VBO with a few VBOs rather than giving each object its own VBO? Jan 2, 2012 at 6:31
• Exactly. I doubt you'll see much of a difference there, but profiling some test cases should give you more info. I also wouldn't worry about it now, as a change like that could be applied later on if need be. Jan 2, 2012 at 15:29

and vertex arrays seem to be deprecated. Instead, if I understand correctly,

Not quite. Vertex arrays are the foundation for vertex buffer objects. Only the storage moved from client to server side.

What if I have a scene that has a lot of smaller geometry?

Merge smaller geometry sets into larger VBOs. There's no need to have one VBO per geometry batch. You can perfectly address subsets of a VBO for rendering. Use a nonzereo offset for the gl…Pointer data parameter.

2) If I'm updating the data from the CPU every frame, can this be substantially worse than if I had used vertex arrays?

For this there are the GL_DYNAMIC_DRAW and GL_STREAM_DRAW buffer usage flags.

If the answer to either of the above questions is "yes", why deprecate other modes of rendering that could have advantages over VBOs?

Because there are no advantages. The geometry data has to be transferred to the GPU in any case. Using a regular client side vertex array will still cause a DMA transfer to GPU, and immediate mode will build a batch to transfer first as well.

There's absolutely no benefit in not using VBOs.

• So my performance should generally not be worse with VBOs than with vertex arrays, but only if I correctly set the mode to GL_STREAM_DRAW? Dec 31, 2011 at 23:55
• @Gravity: Indeed. However the buffer mode is merely a hint on the to be expected usage, but of course that hint should be true to what you're going to do. Also don't forget that you can map buffers into your process address space for updates (glMapBuffer, glUnmapBuffer). Jan 1, 2012 at 0:13
• but then the buffer couldn't be in VRAM, right? Or would it still be in VRAM but just addressable via process-space addresses? Would random access be cheap with this technique, or should I still try to update only a small number of contiguous ranges? Jan 1, 2012 at 0:21
• @Gravity: a buffer can be mapped read only, write only or read write. For updates you'd choose write only. Now it gets important to know how modern OS manage virtual address space, namely through paged memory. In the case of a write only map you're mapped a piece of DMA transfer memory and your writes to that mapped range will go to GPU memory more or less directly (contents are written to CPU RAM first, but then transferred to GPU by DMA transfer). It's important that this is a more direct path than if the data goes through a client side vertex array: Regular process memory is not fit for DMA Jan 1, 2012 at 0:28