Rendering Text in OpenGL 2.0 ES on Android

Hello all,

I have just finished porting fractious’s Rendering Text in OpenGL on Android to OpenGL ES 2.0 (this is the mobile version of OpenGL 3.0 and the main difference with the older versions OpenGL is having acces to the shaders, which allow us to run code on the GPU).

I had to do this because my project TheHunt uses, you guessed it, the newer version. Reason is that it would allow me to do some nifty shader tricks… some day :-)

So here is my code - https://github.com/d3kod/Texample2. Feel free to use it for whatever you want as it is licensed under the CC0 1.0 public domain license.

Texample2

The example application, Texample2

Some implementation details:

  • I firstly started by simply converting the OpenGL ES 1 commands to the newer version. The Model, View and Projection matrices were passed using a uniform variable to the shaders, i.e. all the letters used the same matrices. This was good enough to produce horizontal text
  • In TheHunt I use text to label events (fishbone flops, net snatches), and I need this text to be tilted (it would be somewhat boring otherwise). For this I needed to be able to assign individual model matrices to each word. A bit tricky, but using Sprite Batching in OpenGL ES 2.0 | Anton Holmquist as inspiration I managed to do it. In short, instead of an uniform Model-View-Projection matrix, the vertex shader has an uniform array of matrices. I fill this array with an individual matrix for each letter and also pass a matrix index attribute for each vertex (the exact same method suggested by Anton Holmquist.) The result is that each GLText::draw call can tilt the string drawn with a certain angle (it can now receive an angle argument, in degrees).
  • The last catch was drawing color text – at first, all text was coming out black for me. The reason turns out to be that the texture is defined as grayscale, so in the fragment shader we need to multiply the color we want for the text (passed as uniform u_Color) with the grayscale value (called W in OpenGL) of the texture (not with the whole texture color, because it is something like [0, 0, 0, grayscale] which was resulting in the all black text):

gl_FragColor = texture2D(u_Texture, v_TexCoordinate).w * u_Color

— from BatchTextProgram.java

That’s all I can think of, and the result is efficient text drawing in OpenGL ES 2.0, and more importantly in TheHunt, where you can expect a nice GUI to appear soon!

About these ads

27 responses to “Rendering Text in OpenGL 2.0 ES on Android

    • I’m happy to hear this is useful for you, mike! Indeed, GUI will be a major leap for TheHunt, I will try to come up with something in a week or two =)

  1. I found this really useful and implemented it in to my project but only the first letter of each line renders properly. Any ideas?

    • Hey Simon. I will be happy to help you pinpoint the problem – who knows you might have stumbled in a bug =D

      Have you tried using the setSpace() method on your GLText instance before drawing? This controls the spacing between the characters, maybe yours is too big or too small for some reason?

      If not, please tell me more details of the configuration you’re using – font file and size you’re using in GLText.load() and the viewProjection matrix you’re using in GLText.begin and I will try to reproduce the behavior.

    • You’re welcome! Glad it works.

      BTW, what font size do you use? I’d like to look into it, the default calculated spacing must be off.

      • glText.load( “Roboto-Regular.ttf”, 16, 2, 2 ); // Create Font (Height: 14 Pixels / X+Y Padding 2 Pixels)
        glText.setSpace(10.0f);
        glText.setScale(0.035f);

        Another suggestion, I basically have added Z position to the project so that a piece of text can follow a user in my game. What I found is that even using glText.DrawC, rotation did not happen to the center of the text but rotated around the first letter.

        I had to make some changes but not happy with them

        // create a model matrix based on x, y and angleDeg
        float[] modelMatrix = new float[16];
        Matrix.setIdentityM(modelMatrix, 0);
        Matrix.translateM(modelMatrix, 0, x – 1.0f, y, z + 2.0f);
        Matrix.rotateM(modelMatrix, 0, angleDeg, 0, 1, 0);
        // added by me lol
        Matrix.translateM(modelMatrix, 0, -2, 0, 0);

      • Simon, I’m sorry for the delay =)
        It will be nice to have it working in 3D. I will try to implement it in the next couple of days and let you know!

      • Sadly you have hit the same issues as I have if you rotate on the Y access
        Matrix.rotateM(modelMatrix, 0, angleDeg, 0, 1, 0);

        It does not rotate around the center of the word for the y access, thanks for trying though

      • You are right – have been trying all day to fix it, I give up for now, It rotates around the center of the word for y axis now when at (0, 0), but translating it around alters the rotation (only around x and y axis, z always works), which should not be happening. Any ideas?

  2. Thank you for your code! I really preciate it.
    Actually, I saw nothing on the sreen at first, but than with this lines
    glText.setSpace(1.0f);
    glText.setScale(0.0035f);
    it works just fine.
    I have been searching for about a 10 minutes to find such a way to render text in OpenGL ES 2.0.
    Again, thank you for porting fractious’s Rendering Text in OpenGL on Android to OpenGL ES 2.0! :)

  3. Hi!
    Thank you so much for the code!
    I’m trying to use this version, and although it works on device, it always crashes the emulator. Even running the example project provided, without modifications, the emulator still crash.
    Any idea?

      • Simon,

        This anyone should be me I suppose heh. I will work on it a little bit the next couple of days and let you know if I get anywhere.

      • Hi d3kod!

        I’m using Host GPU Emulation in the AVD, but it does crash the emulator. I have tried with differents Devices, Targets and CPU/ABI but to no avail.
        Can you run the example project on the emulator? Could you please show me your emulator configuration?

        Thank you!

      • I’m sorry it didn’t work out – I was supposed to try doing it today but I forgot… I will try it tomorrow and let you know ^_^

      • Hey fredluciano, it works!
        CPU: ARM
        Target: 4.0.3 (but should work with any 4+)
        Skin: Nexus 4
        hw.gpu.enabled = yes

        Everything else is the default values. Let me know if it works out for you, if not it will be very helpful if you can give me the logcat output (the exception that occurs would be nice)

  4. Hi, yes i’ve tried it too on various configs including the one you recommend above, but still crashes badly. badly as in no useful logcat output. Commenting out the glText.begin, …draw, …end statements does allow it to run (but no text shows obviously ). I guess logging various parts in the process as one form of initial debugging may help you pin point the location of the problem.

  5. First of all, thank you for this code. It is very handy.
    The code runs fine on my Samsung GS3. When I try to run the same code on my Droid X, I get a 1281 error on the line:
    GLES20.glEnableVertexAttribArray(mColorHandle);
    I’ve determined that this is because the GL_MAX_VERTEX_ATTRIBS on my Droid X is only 8, and mColorHandle is set to 26. Any idea how to work around this for older devices?
    Thanks!

    • More information:
      When I run my app on my Samsung GS3 (android 4.1.2), GL_MAX_VERTEX_ATTRIBS is 16, but mColorHandle is set to 0.
      When I run my app on my Motorola Droid X (android 2.3.4), GL_MAX_VERTEX_ATTRIBS is 8, but mColorHandle is set to 26.
      So since 26>8, the 1281 error gets thrown. I don’t understand why the Droid gets a handle value of 26 and the GS3 gets 8.
      Thanks.

  6. Thanks for the GLES 2.0 port. BTW, I’m also getting a 1281 error for GLES20.glEnableVertexAttribArray(mColorHandle) on an Android 4.0.4 Onepad 940 tablet whereas it works flawlessly on a Samsung Galaxy Y with Gingerbread. Couldn’t find out what’s going wrong so far.

Chit-chat

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s