OpenGL ES 2.0: Text from TextView isn't showing up

Started by
4 comments, last by frob 10 years, 1 month ago

I have adapted the code from Draw Text in OpenGL ES Android into my app, but the text isn't really showing up.

Here's what it currently looks like:

nKc5V.png

The green rectangle box is actually a Drawable bitmap.

pBVVs.png

I am expecting some sort of text, either white or black on top of the background, but nothing is ever showing up.

Here's the code for the Text class.


package gl.es;

import java.nio.*;

import android.content.Context;
import android.graphics.*;
import android.graphics.drawable.Drawable;
import android.opengl.*;
import android.opengl.Matrix;

public class Text {

    public int textTexture;
    public FloatBuffer textFloatBuffer;
    public FloatBuffer textureFloatBuffer;
    public int bufferSize;

    public int program;

    private final int textWidth = 112;
    private final int textHeight = 16;

    //private float posX;

    private int aTextPositionLocation;
    private int aTexturePositionLocation;
    private int uMatrixLocation;
    private int uTextureUnitLocation;

    public Text(Context context) {

        program = Shader.buildProgram(context, R.raw.text_vert, R.raw.text_frag);

        aTextPositionLocation = GLES20.glGetAttribLocation(program, "a_textPosition");
        aTexturePositionLocation = GLES20.glGetAttribLocation(program, "a_texturePosition");
        uMatrixLocation = GLES20.glGetUniformLocation(program, "u_matrix");
        uTextureUnitLocation = GLES20.glGetUniformLocation(program, "u_textureUnit");

        textTexture = createTexture(context);
        setBuffer();

        //posX = 0f;
    }

    public int createTexture(Context context) {
        //Create empty mutable bitmap.
        Bitmap bitmap = Bitmap.createBitmap(textWidth, textHeight, Bitmap.Config.ARGB_8888);
        //Use Canvas to paint over it.
        Canvas canvas = new Canvas(bitmap);
        bitmap.eraseColor(0);

        //Draw background
        Drawable background = context.getResources().getDrawable(R.drawable.text_bg);
        background.setBounds(0, 0, 112, 16);
        background.draw(canvas);

        //Draw text
        Paint textPaint = new Paint();
        textPaint.setTextSize(6f);
        textPaint.setAntiAlias(false);
        textPaint.setARGB(0xff, 0, 0, 0);
        //Draw text centered.
        canvas.drawText("Text.", 0, 0, textPaint);

        int[] texture = new int[1];
        GLES20.glGenTextures(1, texture, 0);
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture[0]);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT);
        GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);

        //Recycle.
        bitmap.recycle();
        return texture[0];
    }

    public void setBuffer() {
        final float[] vertexData = {
                0f, 0f,
                textWidth, 0f,
                0f, textHeight,
                0f, textHeight,
                textWidth, 0f,
                textWidth, textHeight
        };

        final float[] texData = {
                0f, 1f,
                1f, 1f,
                0f, 0f,
                0f, 0f,
                1f, 1f,
                1f, 0f
        };

        textFloatBuffer = ByteBuffer.allocateDirect(vertexData.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
        textFloatBuffer.put(vertexData);
        textureFloatBuffer = ByteBuffer.allocateDirect(texData.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
        textureFloatBuffer.put(texData);
        bufferSize = vertexData.length / 2;
    }

    public void transform(float[] model, float[] projection, float[] mvp) {
        Matrix.setIdentityM(model, 0);
        Matrix.translateM(model, 0, 0f, 0f, -60f);
        Matrix.translateM(model, 0, -60f, 0f, 0f);
        Matrix.multiplyMM(mvp, 0, projection, 0, model, 0);

        //posX = (posX - 0.3f) % 112f;
    }

    public void setVertexPointers() {
        textFloatBuffer.position(0);
        GLES20.glVertexAttribPointer(aTextPositionLocation, 2, GLES20.GL_FLOAT, false, 2 * 4, textFloatBuffer);
        GLES20.glEnableVertexAttribArray(aTextPositionLocation);
        textFloatBuffer.position(0);
        textureFloatBuffer.position(0);
        GLES20.glVertexAttribPointer(aTexturePositionLocation, 2, GLES20.GL_FLOAT, false, 2 * 4, textureFloatBuffer);
        GLES20.glEnableVertexAttribArray(aTexturePositionLocation);
        textureFloatBuffer.position(0);
    }

    public void draw() {
        GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, bufferSize);
    }

    public void useProgram() {
        GLES20.glUseProgram(program);
    }

    public void setUniforms(float[] matrix) {
        GLES20.glUniformMatrix4fv(uMatrixLocation, 1, false, matrix, 0);
        GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textTexture);
        GLES20.glUniform1i(uTextureUnitLocation, 1);
    }
}

Could someone tell me where I'm doing wrong? What should I do in order to fix this? Thanks in advance.

Advertisement

Could be:

You're painting the text outside of the box! The "Canvas.drawText" thing uses the y-parameter as the baseline for the text.

Please try using a different value, say "canvas.drawText("Text.", 50, 16, textPaint);"

Go on, feed your brain: http://poroba.com/flip/flipz.php

Did that help? Does the text now show up?

Go on, feed your brain: http://poroba.com/flip/flipz.php

Finally have time to get back to you.

No text.

But when I revert your suggestion and just add a Boolean value, true, to the method, view.getDrawingCache() as a parameter, I get text showing up.

Text has been cut from the middle, but there is Text!

I don't know why the same piece of code returns a black rectangle (void of any colors) on my Asus Transformer Pad though. It is like somebug in the TextView that were not compatible with something.

Attached are two photos of my Android phone and my tablet. Both are running the same Android app.
HTC Desire S:
[attachment=20083:2014-02-20_20-45-44.png]

Asus Transformer Pad TF701T:
[attachment=20084:Screenshot_2014-02-20-20-27-38.png]

Okay, for the Asus Transformer Pad, I have finally found the cause:

Stack Overflow Q&A tells me that because of the generated bitmap, on some devices, the bitmap size is a power of two, therefore the texture is drawn to the screen. On other devices, such as the tablet, due to its sheer resolution scale, the generated bitmap is not a power of two, therefore it shows up as nothing.

In order to combat this issue, I need to use GL_CLAMP_TO_EDGE or use a source texture from the /res/drawable-noapi folder. The latter prevents Android from density-based scaling from occurring.

Thank you for your time.

Thanks for replying back when you found the answer.

This topic is closed to new replies.

Advertisement