How to draw text clearly in OpenGL ES (Android?

Draw text in OpenGL ES (Android)

  • I'm currently developing a small OpenGL game for the Android platform and I wonder if there's an easy way to render text on top of the rendered frame (like a HUD with the player´s score etc). The text would need to use a custom font also. I've seen an example using a View as an overlay, but I don't know if I want to do that since I might want to port the game to other platforms later. Any ideas? Regards/Per

  • Answer:

    The Android SDK doesn't come with any easy way to draw text on OpenGL views. Leaving you with the following options. Place a TextView over your SurfaceView. This is slow and bad, but the most direct approach. Render common strings to textures, and simply draw those textures. This is by far the simplest and fastest, but the least flexible. Roll-your-own text rendering code based on a sprite. Probably second best choice if 2 isn't an option. A good way to get your feet wet but note that while it seems simple (and basic features are), it get's harder and more challenging as you add more features (texture-alignment, dealing with line-breaks, variable-width fonts etc.) - if you take this route, make it as simple as you can get away with! Use an off-the-shelf/open-source library. There are a few around if you hunt on Google, the tricky bit is getting them integrated and running. But at least, once you do that, you'll have all the flexibility and maturity they provide.

shakazed at Stack Overflow Visit the source

Was this solution helpful to you?

Other answers

Rendering text to a texture is simpler than what the Sprite Text demo make it looks like, the basic idea is to use the Canvas class to render to a Bitmap and then pass the Bitmap to an OpenGL texture: // Create an empty, mutable bitmap Bitmap bitmap = Bitmap.createBitmap(256, 256, Bitmap.Config.ARGB_4444); // get a canvas to paint over the bitmap Canvas canvas = new Canvas(bitmap); bitmap.eraseColor(0); // get a background image from resources // note the image format must match the bitmap format Drawable background = context.getResources().getDrawable(R.drawable.background); background.setBounds(0, 0, 256, 256); background.draw(canvas); // draw the background to our bitmap // Draw the text Paint textPaint = new Paint(); textPaint.setTextSize(32); textPaint.setAntiAlias(true); textPaint.setARGB(0xff, 0x00, 0x00, 0x00); // draw the text centered canvas.drawText("Hello World", 16,112, textPaint); //Generate one texture pointer... gl.glGenTextures(1, textures, 0); //...and bind it to our array gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]); //Create Nearest Filtered Texture gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR); //Different possible texture parameters, e.g. GL10.GL_CLAMP_TO_EDGE gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT); //Use the Android GLUtils to specify a two-dimensional texture image from our bitmap GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0); //Clean up bitmap.recycle();

JVitela

I looked at the sprite text example and it looks awfully complicated for such a task, I considered rendering to a texture too, but I'm worried about the performance hit that might cause. I might just have to go with a view instead and worry about porting when it's time to cross that bridge :)

shakazed

Take a look at CBFG and the Android port of the loading/rendering code. You should be able to drop the code into your project and use it straight away. CBFG - http://www.codehead.co.uk/cbfg Android loader - http://www.codehead.co.uk/cbfg/TexFont.java

Codehead

Look at the "Sprite Text" sample in the http://www.go-android.de/externe-news/introducing-glsurfaceview.

weichsel

According to this link: http://code.neenbedankt.com/how-to-render-an-android-view-to-a-bitmap You can render any View to a bitmap. It's probably worth assuming that you can layout a view as you require (including text, images etc.) and then render it to a Bitmap. Using JVitela's code http://stackoverflow.com/questions/1339136/draw-text-in-opengl-es-android/4336679#4336679 you should be able to use that Bitmap as an OpenGL texture.

user379806

If you insist on using GL, you could render the text on to textures. Assuming that most of the HUD is relatively static, you shouldn't have to load the textures to texture memory too often.

Tal Pressman

How exactly did you overlay the textview? I have been following http://blog.jayway.com/2009/12/03/opengl-es-tutorial-for-android-part-i/ and cannot find any examples on how to overlay text continuing from these tutorials.

user560571

I have been looking for this for a few hours, this was the first article i came accross and although it has the best answer, the most popular answers i think are off the mark. Certainly for what i needed. weichsel's and shakazed's answers were right on the button but a bit obscured in the articles. To put you right to the project. Here: Just create a new Android project based on existing sample. Choose ApiDemos: Look under the source folder ApiDemos/src/com/example/android/apis/graphics/spritetext And you will find everything you need.

Justin

Just Added Q & A:

Find solution

For every problem there is a solution! Proved by Solucija.

  • Got an issue and looking for advice?

  • Ask Solucija to search every corner of the Web for help.

  • Get workable solutions and helpful tips in a moment.

Just ask Solucija about an issue you face and immediately get a list of ready solutions, answers and tips from other Internet users. We always provide the most suitable and complete answer to your question at the top, along with a few good alternatives below.