Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/371.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 显示每帧上更改的文本(如分数)_Java_Android_Opengl Es - Fatal编程技术网

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

Java 显示每帧上更改的文本(如分数),java,android,opengl-es,Java,Android,Opengl Es,在onDrawFrame方法中,在实现渲染器的类的每个帧上,是否有任何简单的方法可以显示简单的白色文本,而在右上角没有任何纹理,这些纹理会发生变化?它是二维的,所以我相信没有必要进行任何转换。我找到了很多教程,但它们似乎都太复杂,代码太多。也许只需要几行代码就可以完成?如果不可能,那么在不修改太多现有代码的情况下,最简单的方法是什么?请显示完整的代码,因为我是新手。我使用了位图画布drawText,但我仍然必须将其用作纹理,可能使用较小的位图和字体大小 bitmap = Bitmap.creat

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

我使用了位图画布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章中看到src/com.badlogic.androidgames.framework.gl.Font.java是我用于位图字体的,我使用代码头生成位图字体位图字体生成器

渲染器是一种OpenGL方法。OpenGL ES本身并不支持文本。这将留下以下选项:

  • 使用纹理,使用Android的Canvas类绘制纹理
  • 使用图书馆。这很可能也会绘制到纹理
  • 使用多边形创建文本
  • 因为你的问题是要求一个不绘制纹理的解决方案,所以1和2都是错误的。既然你想要一些简单的东西,那么3也不行。没有留下好的解决方案

    考虑的另一种选择是在你正在使用的GLASTURVIEW之上分层另一个视图。您可以使用RelativeLayout轻松堆叠两个视图,其中一个是文本视图,您可以将其定位到屏幕的右上角。伪代码如下:

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

    这种方法的好处是将您从OpenGL需求中拉出来,以完成文本。我已经在我的几个应用程序上成功地做到了这一点。

    文本应该位于与OpenGL不同的层中

    <FrameLayout>
        <GLSurfaceView/>
        <LinearLayout android:layout_gravity="top|right" >
            <TextView android:id="@+id/score" ... />
        </LinearLayout>
    </FrameLayout>
    
    您可能需要在每次渲染GLSURFACHEVIEW后强制重新绘制分数布局,以避免openGL在文本顶部绘制。(对此不确定)


    为了性能起见,将文本区域尽可能小(换行内容表示线性布局的宽度和高度)

    在我看来,您可以使用RelativeLayout来换行GLSurfaceView,也可以使用另一个TextView将其放在任意位置。然后在渲染器构造函数中,传递TextView引用 Gles20三角渲染器(上下文,TextView tv) 在onDrawFrame方法中,调用

     ((Activity)mContext).runOnUiThread(new Runnable(){
    
            @Override
            public void run() {
                // TODO Auto-generated method stub
                tv.setText(Math.random() + " random");
    
            }
    
        });
    

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

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

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

    您可能想看看Android SDK示例附带的API演示项目。有一个OpenGL Sprite文本示例,它完全满足您的需要

    您可以通过在emulator(或设备)上安装API演示并导航到以下位置来查看演示: API演示>图形>OpenGL ES>精灵文本

    以下是一个屏幕截图:

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

    您可以在Android SDK示例目录中找到源代码: ApiDemos\src\com\example\android\api\graphics\spritetext

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

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

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

    下面是分数不断更新时的情况

    基本上,呈现分数的过程如下所示:

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

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


    您只需将
    文本视图
    附加到
    活动
    窗口管理器
    上,然后从那里显示。如下所示

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

    使用好的位图字体库,可能只需要几行。如果你找不到一个图书馆,那还需要很多。@Geobits关于我可以选择哪一个图书馆的任何建议?上次我找的时候,我找不到一个完全符合我要求的图书馆。然而,这不仅仅是“显示一些数字”,所以可能会有一些东西给你,我只是不知道马上。你在问一些矛盾的问题。您说您已经看过教程,但“代码太多”,但您想要一个完整的代码示例。你已经得到了答案,但不会接受你必须为此做些工作。作为一个新手并不是不想弄明白的借口。我们不是来为你写代码的,这似乎正是你想要的。我更新了一些代码,我不确定它是否能按照你想要的方式“每一帧”工作,但值得一试。我猜Geobits可能是对的,不过关于位图字体库,我有一个定制的,尽管它与一系列类相关联,我可以给你指代码吗?我是从一本书中学到的。你是运行API演示还是我的示例应用程序?我的应用程序是Sprite文本API演示的精简版本,因为我已经删除了三角形Sprite。这样就很容易理解只需要渲染分数的代码行。当然,你可以在屏幕上针对你的应用程序绘制更多内容。+1感谢你的指导,为这项工作提取了必要的代码。对我来说很好:)
    activity.runOnUiThread(new Runnable(){
    
        @Override
        public void run() {
            tv.setText("FPS: " + fps);
        }
    
    });