显示在每个帧上更改的文本(如分数)

时间:2013-03-12 19:48:17

标签: java android opengl-es

在onDrawFrame方法中,有没有简单的方法来显示右上角没有任何纹理的简单白色文本,这些纹理会在实现渲染器的类中的每个帧上发生变化?它是二维的,所以没有必要进行任何转换,我相信。我发现了很多教程,但是它们看起来太复杂了,代码太多了。也许只需几行代码即可完成?如果那是不可能的,那么在不修改过多现有代码的情况下,最简单的方法是什么?因为我是新手,请出示完整的代码。

8 个答案:

答案 0 :(得分:11)

Renderer是一种OpenGL方法。 OpenGL ES本身并不支持文本。这留下了以下选项:

  1. 使用纹理,使用Android的Canvas类绘制到它。
  2. 使用库。这很可能也会吸引纹理。
  3. 使用多边形创建文本。
  4. 由于你的问题是要求一个没有绘制到纹理的解决方案,所以1和2都是out。既然你想要简单的东西,那么3也是出类拔萃的。没有好的解决方案。

    另一种考虑方法是在您正在使用的GLSurfaceView上叠加另一个视图。您可以使用RelativeLayout轻松堆叠两个视图,一个是可以锚定到屏幕右上角的文本视图。下面的伪代码:

    <RelativeLayout ... />
        <GLSurfaceView ... />
        <TextView ... />
    </RelativeLayout>
    

    这种方法的好处是可以帮助您摆脱OpenGL的要求来完成您的文本。我在几个应用程序上成功完成了这项工作。

答案 1 :(得分:7)

您可能需要查看Android SDK示例附带的API Demos项目。有一个OpenGL Sprite Text示例,可以完全满足您的需求。

您可以通过在模拟器(或设备)上安装API演示并导航到以下内容来查看演示: API演示&gt;图形&gt; OpenGL ES&gt;精灵文字

以下是截图:

enter image description here

在渲染器的onDrawFrame方法中,每个帧上的屏幕右下角的文本都会更改。

您可以在Android SDK示例目录中找到源代码: ApiDemos \ SRC \ COM \示例\机器人\的API \图形\ spritetext

您需要将少量文件复制到项目中,只需很少的代码就可以实现相同的功能。

示例应用: 我已经创建了一个示例应用程序,通过重用API Demos项目中的代码来演示相同的应用程序。你可以从这里得到它 - OpenGLText_eclipse_project.zip

简而言之,您可以完全重用Grid.java,LabelMaker.java,NumericSprite.java。然后在渲染器中添加几行代码以使用上面的类,如我的TextRenderer.java中所示

以下是连续更新分数的效果。

enter image description here

基本上,渲染分数就像这样简单:

LabelMaker mLabels = new LabelMaker();

mLabels.initialize(gl);
mLabels.beginAdding(gl);
int mLabelMsPF = mLabels.add(gl, "Score:", mLabelPaint);
mLabels.endAdding(gl);

mLabels.beginDrawing(gl, mWidth, mHeight);
mLabels.draw(gl, 0, 0, mLabelMsPF);
mLabels.endDrawing(gl);

NumericSprite mNumericSprite = new NumericSprite();
mNumericSprite.setValue(16);
mNumericSprite.draw(gl, 0, 0, mWidth, mHeight);

答案 2 :(得分:3)

尝试查看CodeHead的Bitmap字体生成器和Android Loader,并尝试使用此代码。

CBFG

Android Loader

答案 3 :(得分:2)

我使用了一个位图画布drawText,但我仍然不得不将它用作纹理,可能是一个较小的位图和字体大小

bitmap = Bitmap.createBitmap(256, 256, Bitmap.Config.ARGB_8888);
canvas = new Canvas(bitmap);
h = (int)((((System.currentTimeMillis()/1000)/60)/60)%60);
    m = (int)(((System.currentTimeMillis()/1000)/60)%60);
    s = (int)((System.currentTimeMillis()/1000)%60);
    paint = new Paint();
    paint.setColor(Color.MAGENTA);
    paint.setTextAlign(Align.CENTER);
    paint.setTypeface(Typeface.DEFAULT_BOLD);
    paint.setTextSize(55);
time = String.valueOf(h) + "h" + String.valueOf(m) + "m" + String.valueOf(s) + "s";
canvas.drawText(time, bitmap.getWidth()/2, 100, paint);
int[] textureIds = new int[1];
    gl.glGenTextures(1, textureIds, 0);
    textureId = textureIds[0];
gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);
         GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);

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_NEAREST);            
         gl.glBindTexture(GL10.GL_TEXTURE_2D, 0);

如果你去第9章中的here src / com.badlogic.androidgames.framework.gl.Font.java是我用于位图字体的东西,我使用Codeheads位图字体生成器生成位图字体

答案 4 :(得分:2)

文本应与OpenGL不同。

<FrameLayout>
    <GLSurfaceView/>
    <LinearLayout android:layout_gravity="top|right" >
        <TextView android:id="@+id/score" ... />
    </LinearLayout>
</FrameLayout>

FrameLayout允许视图堆叠在另一个的顶部。 然后用以下内容设置文本:

( (TextView) findViewById(R.id.score) ).setText( "Your Score" );

您可能需要在每次渲染GLSurfaceView后强制重绘分数布局,以避免openGL在文本之上绘制。 (不确定这个)

为了性能,请使文本区域尽可能小(Linear_ayout的宽度和高度的wrap_content)

答案 5 :(得分:1)

在我看来,你可以使用RelativeLayout来包装GLSurfaceView,还可以使用另一个TextView来放置你想要的任何地方。然后在Renderer构造函数中,传递TextView引用     GLES20TriangleRenderer(Context context,TextView tv) 在onDrawFrame方法中,调用

 ((Activity)mContext).runOnUiThread(new Runnable(){

        @Override
        public void run() {
            // TODO Auto-generated method stub
            tv.setText(Math.random() + " random");

        }

    });

答案 6 :(得分:1)

您需要将得分文本绘制到位图,然后将此位图用作纹理。

要在位图上绘制文本,您可以使用以下代码:

// Create and draw a texto to your bitmap.
Bitmap bm = Bitmap.createBitmap(300, 100, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bm);
Paint p = new Paint();
p.setColor(Color.RED);
c.drawText("YOUR SCORE", 0, 0, new Paint());

答案 7 :(得分:0)

您只需将TextView附加到Activity WindowManager并从那里显示即可。如下。

TextView tv = new TextView(this);
tv.setText("FPS: 0");

//get WindowManager from Activity
WindowManager w = this.getWindowManager();

//setup view LayoutParams
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
    ViewGroup.LayoutParams.WRAP_CONTENT,
    ViewGroup.LayoutParams.WRAP_CONTENT,
    0,
    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
            | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
    PixelFormat.TRANSPARENT);

//position
lp.gravity = Gravity.RIGHT | Gravity.TOP;

//attach view
w.addView(tv,lp);

然后通过

更新
activity.runOnUiThread(new Runnable(){

    @Override
    public void run() {
        tv.setText("FPS: " + fps);
    }

});

enter image description here