0

I've been doing some game development on Android and have been able to accomplish the majority of my drawing simply by using the glDrawTexfOES method from the GL extensions library. Using this for drawing my sprites seemed to yield good performance and I didn't have any complaints until I started trying to use it for bitmap fonts.

With the way I have my bitmap fonts set up right now, I read in the character definitions, texture, and character properties from an XML file in order to initialize my font class. Using these properties, a call is made to glDrawTexfOES and is formatted so that the requested character is drawn and scaled to the desired size. This works fine for smaller strings, but unfortunately requires a separate call to glDrawTexfOES for every single character drawn. As you can imagine, this causes noticeable lag and performance issues for larger strings.

Does anyone have advice for how I could render this more intelligently? I've heard about using VBOs for large groups of static objects, but I'm not sure if these are appropriate for the use case of having text that needs to be dynamic as well. Advice from someone who's implemented something similar with OpenGL ES would be much appreciated.

4

1 回答 1

0

There are several ways to improve the redering speed of your code. The documentation of glDrawTexfOES doesn't offer many details and only mentions a direct mapping of texels to fragments, so I my best guess is that the implementation you are using is not very optimized and is the main cause of your speed problems (I'm assuming your are using OpenGL ES 1.1).

My suggestion is to get rid of glDrawTexfOES and replace it with a custom rendering function using triangle strips and degenerate triangles to connect different strips.

It works like this:

1) Create a buffer to store the vertex position, texture coordinates and indices to draw the triangles in a single batch. Each letter will be draw using two triangles and an additional degenerate triangle will be used (or ignored) to connect it to another letter.

2) Create degenerate triangles by using the following algorithm:

for (int k = 0; k < MAX_NUMBER_OF_LETTERS ; k++)
{
    indices[k*6] = k*4;

    for (int p=0; p<4; p++)
        indices[k*6+p+1] = k*4+p;

    indices[k*6+5] = k*4+3;
}

3) Batch all your draw calls into the buffer you created in step 1. You can send the triangles to the rendering pipeline using glDrawArrays. You can batch as many triangles as you want, the trick to speed up the rendering is to hold the call to glDrawArrays until there's going to be a change in the state of OpenGL (like changing the binded texture).

4) You obviously need to use a texture atlas.

I also suggest not doing VBOs if your are doing some basic 2D stuff. Going that route means changing your code to OpenGL ES 2.0 instead of 1.1 and they are completely different.

于 2013-04-29T00:40:04.097 回答