Efficient drawing of primitives in openGL ES 2.0

I am writing a game on Android and it is running well. I try to keep everything as efficient as possible, so I store as much as I can in Vertex Buffer Objects to avoid unnecessary CPU overhead. However, the simple act of drawing a lot of unbound primitives or even variable length sprites efficiently (like drawing text on the screen) eludes me.

The purpose of these primitives is menus and buttons, as well as text.

For drawing the menu, I could just create an array of vertices for each item (menu background, buttons, etc.), but since they are all just squares, this seems very inefficient. I could also create a drawQuad () function that lets you just transparently load one saved vertex array with data for xy / height & width / color / texture / whatever. However, reloading each element of the array with new coordinates and different data every time to copy it to the Float Buffer (for the C ++ guys this is a special step you have to take in Java to transfer data to GL), so I can send it to the GPU also feels a lack of efficiency, although I don't know how else I could have done it. (One efficiency improvement I could see is to set square coordinates as a unit square,and then use Uniforms to scale it, but that seems immodest).

For text, this is even worse, since I don't know how long the text will be and I don't want to create large buffers for larger text (forcing the GC to randomly start later). An alternative option is to draw each letter with an independent draw command, but this also seems very inefficient even for a hundred letters on the screen (since I read that you should try to have as few draw commands as possible).

It is also possible that I was looking too deeply for the necessary openGL optimizations, but don't want me to get into a corner early with some awful design.


source to share

1 answer

You should try to learn the idea of ​​data interleaving for glDrawArrays calls. This link provided is for the iphone, but there is a nice graphic at the bottom of the page that goes into detail about this concept. http://iphonedevelopment.blogspot.com/2009/06/opengl-es-from-ground-up-part-8.html

I'm going to assume for drawing your characters that you point some vertex and some texture coordinates to some kind of bitmap font in order to pick the correct character. So you could imagine your FloatBuffer looking like

[vertex 1] [texcoord 1] [vertex 2] [texcoord 2] [vertex 3] [texcoord 3]

[vertex 2] [texcoord 2] [vertex 3] [texcoord 3] [vertex 4] [texcoord 4]

The above will represent one character in your sentence if you are using GL_TRIANGLES, and you could extend that idea to have vertices 5-8 to represent the second character, etc. etc. Now you can draw all the text on the screen with a single call to glDrawArrays. Now you may be concerned about having redundant data in your FloatBuffer, but the savings will be huge. For example, when rendering a teapot with 1200 vertices and having redundant data in my buffer, I was able to get a very noticeable speed boost by calling glDrawArrays for each individual triangle, perhaps about 10 times better.

I have a small demo at sourceforge where I am using data striping to render the teapot I mentioned earlier. Its ShaderProgramTutorial.rar. https://sourceforge.net/projects/androidopengles/files/ShaderProgram/ Look in teapot.java in the onDrawFrame function to see it.

On a side note, you can find some other things on this sourceforge page that will be useful in your future Android OpenGL ES 2.0!



All Articles