# Changing the sprite position: Modify VBO data or translate it?

I am beginning with VBO and I want to know if it's better use GL_STATIC_DRAW to make a quad and them translate it, or use DYNAMIC_DRAW and modify the vertex position data directly.

Also when I modify the data of a static VBO the rendering really change! Why does this happen? It is supposed to make STATIC object right?

• Obviously when you modify the buffer data, the rendered image is different. You modified the data. I think you misunderstand the point of GL_STATIC_DRAW. It doesn't mean the "object is static," it means you the programmer intend to modify the data once and then use it to draw many times (as opposed to GL_DYNAMIC_DRAW, which indicates to the API you intend to modify the data often). This helps the implementation choose where and how to allocate the buffer data. – Josh Jul 19 '13 at 15:02

Don't change the vertex buffer to translate, rotate or scale the object. For 3d graphics, this is typically done by multiplying every vertex with a transformation matrix in the vertex shader.

So if you don't want to modify the shape of the mesh, you should use GL_STATIC_DRAW. The other option DYNAMIC_DRAW is used to stream meshes changing other time.

• but how I can use vertex shader?, how I said before I beginning with VBO so I don't(for the moment) how to use it, I was thinking to use simple geometry transformations like glTranslatef to move it but if shaders are faster... then I think I have to learn about them, do you know some book or page about shaders? – user33283 Jul 19 '13 at 16:02
• Even though a transformation matrix, containing position, rotation and scale, is supported by the fixed function pipeline, I strongly advice you to learn shaders nowadays. There are so many good tutorial on the internet. For example http://open.gl. – danijar Jul 19 '13 at 16:18
• This implies you have a single vertex buffer per sprite, which is not terribly efficient. – Josh Jul 19 '13 at 19:08

In contrast to danijar's advice, I'm going to suggest modifying the buffer. For sprites, you can be much better off writing all your sprites into a single buffer. You then can't as easily apply a transformation matrix to them on the GPU (especially if you're targetting the Web or mobile platforms stuck with GLES 2, which does not having instancing support). It can be more efficient to stuff all the sprites' quads/tris, with pre-transformed vertices, into a single buffer you update each frame.

This of course also requires texture atlasing and can only be done for sprites using the same atlas and the same material/shaders, but in general this is a pretty safe requirement for most 2D sprite games.

Pre-transforming the vertices is super expensive when you have 3D meshes with thousands of vertices each (that may have much more than just a position to calculate) so in 3D you absolutely want to do as much as possible on the GPU, but doing it on the CPU for a couple hundred 2D rectangles is entirely reasonable, even on a cell phone.

If you do want to do it all the GPU, you really want to use instancing. In such a case you have just a single VBO for a quad. You then, each frame, fill in a dynamic VBO or texture with all the transformation matrices and UV coordinates and such for every sprite (which not much cheaper than just filling in the regular VBO for each sprite), and then let the GPU draw that same quad X times, once for each transformation matrix and other data.

Drawing each sprite individually, with its own transformation, is really bad. Your GPU has hundreds or even thousands of cores meant to process large volumes of data at once but you end up asking it to do a whole 4 vertices at a time. Not the best utilization. Batching your draws together can scale your performance by a very very large factor on modern hardware, again, even phones. It can be the difference between getting 40 FPS with two dozen sprites or 400 FPS with a thousand sprites. (Of course, profile your specific app and hardware to get an accurate measure of the speedup).

Instancing has historically been poorly supported by desktop GL drivers, so you might find it's faster overall to just pre-transform everything even if, in theory, it shouldn't be. Again, though, either method is much more efficient than drawing each sprite individually.

There are a number of articles on this site about instancing if you're interested in looking up more information on that.

• Good advice but one needs to be very careful about accidentally introducing synchronization when modifying a VBO, especially as GL's APIs for this are not great. Even if only a single sprite needs modifying it may be more efficient to throw away and respecify all of the vertex data for every sprite rather than just modifying the VBO range for that single sprite. – Maximus Minimus Jul 19 '13 at 19:30
• It's easy enough to solve. Either use glBufferData with a NULL pointer value, as an unofficial but common way to handle this, or use the new glInvalidateBufferData. – Sean Middleditch Jul 19 '13 at 20:51
• But yes, just rebuild the whole buffer every frame, don't try to update individual entries "intelligently". – Sean Middleditch Jul 19 '13 at 20:52
• I haven't heard of this technique and it sounds quite hacky. But I am sure there are good reason for using this in some cases. However, for a very beginner, it is no good advice. He should learn the basic approach first, which holds efficient for 3d models he might want to use some day. – danijar Jul 19 '13 at 23:45
• Nothing hacky about it. It's how one does high-speed 2D graphics on modern GPUs, period. – Sean Middleditch Jul 19 '13 at 23:46