Question

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:

Green background without any text.

The green rectangle box is actually a Drawable bitmap.

Drawable file in Android assets folder.

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.


UPDATE 1: To answer deathember:

This is what happens when I changed the Matrix.transformM() to what you have suggested:

What happened afterwards...

And here's the code that shows where I put my view matrix at:

package gl.es;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.content.Context;
import android.opengl.*;

public class MyRenderer implements GLSurfaceView.Renderer
{

    Context context;
    Text text;

    float eyeX;
    float eyeY;
    float eyeZ;


    private float[] modelMatrix;
    private float[] viewMatrix;
    private float[] projectionMatrix;
    private float[] modelViewProjectionMatrix;

    public MyRenderer(Context context) {
        this.context = context;
        modelMatrix = new float[16];
        projectionMatrix = new float[16];
        viewMatrix = new float[16];
        modelViewProjectionMatrix = new float[16];
    }

    @Override
    public void onSurfaceCreated(GL10 p1, EGLConfig config)
    {
        // TODO: Implement this method
        GLES20.glClearColor(0.4f, 0.8f, 1.0f, 1.0f);
        this.text = new Text(this.context);
    }

    @Override
    public void onSurfaceChanged(GL10 p1, int width, int height)
    {
        // TODO: Implement this method
        GLES20.glViewport(0, 0, width, height);
        this.setPerspectiveM(45f, (float) (width) / (float) (height), 1f, 200f);
        // Did not use view matrix at all for transformations of Text textures.
        Matrix.setLookAtM(viewMatrix, 0, 0, 0, 0, 0, 0, 0, 0, 1f, 0); //Unused.

        Matrix.setIdentityM(modelMatrix, 0);
        projectionMatrix, 0, modelMatrix, 0);
    }

    @Override
    public void onDrawFrame(GL10 p1)
    {

        // TODO: Implement this method
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);

        text.transform(modelMatrix, projectionMatrix, modelViewProjectionMatrix);
        text.useProgram();
        text.setUniforms(modelViewProjectionMatrix);
        text.setVertexPointers();
        text.draw();
    }

    private void setPerspectiveM(float fov, float aspectRatio, float near, float far) {
        final float anglesInRadians = (float) (fov * Math.PI / 180f);
        final float angle = (float) (1f / Math.atan(anglesInRadians) / 2f);
        projectionMatrix[0] = angle / aspectRatio;
        projectionMatrix[1] = 0f;
        projectionMatrix[2] = 0f;
        projectionMatrix[3] = 0f;
        projectionMatrix[4] = 0f;
        projectionMatrix[5] = angle;
        projectionMatrix[6] = 0f;
        projectionMatrix[7] = 0f;
        projectionMatrix[8] = 0f;
        projectionMatrix[9] = 0f;
        projectionMatrix[10] = -((far + near) / (far - near));
        projectionMatrix[11] = -1f;
        projectionMatrix[12] = 0f;
        projectionMatrix[13] = 0f;
        projectionMatrix[14] = -((2f * far * near) / (far - near));
        projectionMatrix[15] = 0f;
    }
}

Hope that helps.

Was it helpful?

Solution 2

Add true inside view.getDrawingCache() as a parameter.

Note that on some devices and hardwares, this will never work. I found this out the hard way.

enter image description here

OTHER TIPS

Try to change

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;
}

into

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

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

And also set your view matrix look at center. May be you draw your text, but you can't see him. And where you set view matrix?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top