【问题标题】:Android: Displaying text with OpenGL ESAndroid:使用 OpenGL ES 显示文本
【发布时间】:2016-10-11 15:25:38
【问题描述】:

我想编写一个在设备上显示文本正好 1/60 秒(帧速率 = 60 Hz)的应用。

管理此任务的最佳方法是什么?

我第一次尝试不使用 OpenGL,使用 ImageView,但时间管理并不容易,因为我没有访问渲染器。或者有没有办法访问渲染器?

我的以下代码在 OpenGL 中不显示“T E S T I N G”,我不知道为什么。

public class MainActivity extends AppCompatActivity implements GLSurfaceView.Renderer {

// The texture pointer
private int[] textures = new int[1];

private Bitmap bitmap;
private Canvas canvas;
private Drawable background;
private Paint textPaint;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);


    GLSurfaceView glSurfaceView = new GLSurfaceView(this);

    // OpenGL Version 2
    glSurfaceView.setEGLContextClientVersion(2);
    // bits for the channels of output image (red, green, blue, alpha, depth, stencil)
    glSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
    // Activity acts as the Renderer
    glSurfaceView.setRenderer(this);
    // update on demand
    glSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);


    // our bitmap
    bitmap = Bitmap.createBitmap(256, 256, Bitmap.Config.ARGB_4444);
    // get a canvas to paint over the bitmap
    canvas = new Canvas(bitmap);
    bitmap.eraseColor(0);

    // get a background image from resources
    // note the image format must match the bitmap format
    background = this.getApplicationContext().getResources().getDrawable(R.drawable.background);
    background.setBounds(0, 0, 256, 256);
    // draw the background to our bitmap
    background.draw(canvas);

    // draw the text
    textPaint = new Paint();
    textPaint.setTextSize(32);
    textPaint.setAntiAlias(true);
    textPaint.setARGB(0xff, 0x00, 0x00, 0x00);
    // draw the text centered
    canvas.drawText("T E S T I N G", 16, 112, textPaint);
}

// when OpenGL starts up
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {

    // default state to background color light grey state
    GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}

// called as often as possible => high frame rate
@Override
public void onDrawFrame(GL10 gl) {

    // clear the color buffer (bitmaps)
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);

    // 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();
}

// for resizing purposes
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {

    // when size of the GLSurfaceView changes we also want to change the size of the rendering view port to be the same
    GLES20.glViewport(0, 0, width, height);
}}

【问题讨论】:

标签: java android opengl-es


【解决方案1】:

您会在此处找到从 GLSurfaceView 开始的好地方:

https://developer.android.com/training/graphics/opengl/environment.html

但是,对于文本,只需将文本绘制到纹理并渲染纹理即可。请参阅此答案以了解如何做到这一点:https://stackoverflow.com/a/4336679/2979092

为确保使用 GLES 2.0,请将其添加到您的清单中

<uses-feature android:glEsVersion="0x00020000" android:required="true" />

扩展 GLSurfaceView

class MyGLSurfaceView extends GLSurfaceView {

    private final MyGLRenderer mRenderer;

    public MyGLSurfaceView(Context context){
        super(context);
        setEGLContextClientVersion(2);
        mRenderer = new MyGLRenderer(); // extended GLSurfaceView.Renderer
        setRenderer(mRenderer);
    }
}

你的渲染器骨架

public class MyGLRenderer implements GLSurfaceView.Renderer {

    public void onSurfaceCreated(GL10 unused, EGLConfig config) {
        GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    }

    public void onDrawFrame(GL10 unused) {
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
    }

    public void onSurfaceChanged(GL10 unused, int width, int height) {
        GLES20.glViewport(0, 0, width, height);
    }
}

按需更新

setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);

使用位图将文本渲染到纹理(从链接的答案复制)

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();

如果您使用 GLES 2.0,您还需要在渲染之前绑定着色器程序。

【讨论】:

  • 感谢 WLGfx 非常详细的回答。这对我帮助很大。不过我还有几个问题。
  • 链接答案中的代码在哪里?在构造函数 MyGLSurfaceView 中?在 onDrawFrame 方法中?我必须自己在 R.drawable 中创建一个 .png 背景文件吗?
  • 纹理数组来自哪里?如何在渲染前绑定着色器程序?
  • 您可以在代码中的任何位置准备位图,但在使用它时,您通常会在 onDraw 方法中上传纹理。 GLES 2.0 着色器是另一个主题,首先学习 2D 着色器通常是一个好的开始。同样对于背景渲染,您可以将任何加载的位图上传到 GPU 并使用纹理渲染四边形。着色器由一个顶点着色器和一个片段着色器组成。
  • 谢谢。我在上面编辑了我的问题以显示我的代码。不幸的是,它仍然没有显示任何文字。
猜你喜欢
  • 2018-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-08
  • 2012-05-24
相关资源
最近更新 更多