I started experimenting with OpenGL ES 2.0, and I'm trying to figure out a way to optimize/batch sprite drawing, where sprites only have the texture in common, but differ in the following properties:
- Texture coordinates
I tried two different approaches, which are "good enough" for most games, but I'm still curious on how I could optimize drawing sprites further. All the code is available here on GitHub, but I'll explain my approaches below.
(Both approaches use 4 vertices + 6 indices to draw a quad.)
One drawcall per sprite.
Position and texture coordinates are passed as a
vec4vertex attribute. The MVP matrix (that handles size and rotation) is passed as a
mat4uniform. Color is passed as a
vec4uniform and hue is passed as a
Since pretty much everything is being passed as an uniform, I have to set all uniforms and call
glDrawElementsonce per sprite.
I can draw 50000 sprites at 60FPS on my desktop (i7 2400k, GTX 970).
One drawcall per
The second idea I had and tried was dividing sprites in batches of
N. In this approach, everything is passed as a vertex attribute.
attribute mat4 a_projection_view_model; attribute vec4 a_pos_tex_coords; attribute vec4 a_color; attribute float a_hue;
From my tests it seems slightly faster than the previous approach, but it isn't a big improvement. Also, passing the same
mat4and the same
a_color) four times seems weird and unnecessarily expensive.
I couldn't figure out a different solution since every sprite has its own MVP matrix, color an hue.
How is sprite batching (when the texture is the same) usually done? Are my approaches "correct" in theory, or am I doing something which is considered bad practice?
How can I optimize my sprite drawing?