134

私は現在、Android プラットフォーム用の小さな OpenGL ゲームを開発しています。レンダリングされたフレームの上にテキストをレンダリングする簡単な方法があるかどうか疑問に思います (プレーヤーのスコアなどを含む HUD など)。テキストには、カスタム フォントも使用する必要があります。

ビューをオーバーレイとして使用する例を見たことがありますが、後でゲームを他のプラットフォームに移植する可能性があるため、それを行うかどうかはわかりません。

何か案は?

4

13 に答える 13

169

テクスチャへのテキストのレンダリングは、Sprite Textデモのように見えるよりも簡単です。基本的な考え方は、Canvasクラスを使用してビットマップにレンダリングしてから、ビットマップをOpenGLテクスチャに渡すことです。

// Create an empty, mutable bitmap
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();
于 2010-12-02T15:35:44.640 に答える
107

Android SDK には、OpenGL ビューにテキストを描画する簡単な方法はありません。次のオプションを残します。

  1. SurfaceView の上に TextView を配置します。これは遅くて悪い方法ですが、最も直接的な方法です。
  2. 一般的な文字列をテクスチャにレンダリングし、それらのテクスチャを単純に描画します。これは最も単純で高速ですが、柔軟性が最も低くなります。
  3. スプライトに基づいた独自のテキスト レンダリング コード。2 がオプションでない場合、おそらく 2 番目に良い選択肢です。足を濡らす良い方法ですが、単純に見えますが (基本的な機能はそうです)、機能を追加するにつれて (テクスチャの配置、改行の処理、可変幅フォントなど)、より難しく、より困難になることに注意してください。 ) - このルートを使用する場合は、できるだけ簡単に回避してください。
  4. 既製/オープンソースのライブラリを使用します。Google で探してみるといくつかありますが、難しいのはそれらを統合して実行することです。しかし、少なくとも、一度それを行うと、それらが提供するすべての柔軟性と成熟度が得られます.
于 2009-08-27T18:35:54.010 に答える
38

JVitelaが投稿した回答を拡張するチュートリアルを作成しました。基本的には同じ考え方を使用しますが、各文字列をテクスチャにレンダリングする代わりに、フォント ファイルからすべての文字をテクスチャにレンダリングし、それを使用して、それ以上速度を落とさずに完全な動的テキスト レンダリングを可能にします (初期化が完了すると)。 .

さまざまなフォント アトラス ジェネレーターと比較した場合の私の方法の主な利点は、フォントのバリエーションやサイズごとに大きなビットマップを出荷する代わりに、プロジェクトに小さなフォント ファイル (.ttf .otf) を出荷できることです。フォントファイルのみを使用して、任意の解像度で完璧な品質のフォントを生成できます:)

チュートリアルには、どのプロジェクトでも使用できる完全なコードが含まれています :)

于 2012-05-25T08:40:35.697 に答える
8

このリンクによると:

http://code.neenbedankt.com/how-to-render-an-android-view-to-a-bitmap

任意のビューをビットマップにレンダリングできます。必要に応じて (テキスト、画像などを含めて) ビューをレイアウトし、それをビットマップにレンダリングできると想定することはおそらく価値があります。

上記の JVitela のコードを使用すると、そのビットマップを OpenGL テクスチャとして使用できるはずです。

于 2011-03-09T14:14:56.157 に答える
7

CBFG と、ロード/レンダリング コードの Android ポートを見てください。コードをプロジェクトにドロップして、すぐに使用できるはずです。

CBFG - http://www.codehead.co.uk/cbfg

Android ローダー - http://www.codehead.co.uk/cbfg/TexFont.java

于 2011-02-18T22:20:14.353 に答える
6

スプライトテキストの例を見ると、そのようなタスクでは非常に複雑に見えます。テクスチャへのレンダリングも検討しましたが、パフォーマンスの低下が発生する可能性があるのではないかと心配しています。代わりにビューを使用して、その橋を渡るときに移植することを心配する必要があるかもしれません:)

于 2009-08-27T14:46:50.483 に答える
5

ゲームで OpenGL ES を使用する理由は 3 つあります。

  1. オープン スタンダードを使用して、モバイル プラットフォーム間の違いを回避します。
  2. レンダリング プロセスをより詳細に制御するため。
  3. GPU 並列処理の恩恵を受けるため。

ゲーム デザインでは、テキストの描画は常に問題になります。オブジェクトを描画しているため、ウィジェットなどを使用した一般的なアクティビティのルック アンド フィールを実現することはできません。

フレームワークを使用して、TrueType フォントからビットマップ フォントを生成し、レンダリングすることができます。私が見たすべてのフレームワークは同じように動作します: 描画時にテキストの頂点とテクスチャ座標を生成します。これは、OpenGL の最も効率的な使用法ではありません。

最適な方法は、コードの早い段階で頂点とテクスチャにリモート バッファー (頂点バッファー オブジェクト - VBO) を割り当て、描画時の遅延メモリ転送操作を回避することです。

ゲーム プレイヤーはテキストを読むのを好まないので、動的に生成された長いテキストを記述しないことに注意してください。ラベルには、静的なテクスチャを使用して、時間とスコアの動的テキストを残すことができます。どちらも、数文字の長さの数値です。

だから、私の解決策は簡単です:

  1. 一般的なラベルと警告のテクスチャを作成します。
  2. 数字 0 ~ 9、「:」、「+」、「-」のテクスチャを作成します。キャラクターごとに 1 つのテクスチャ。
  3. 画面内のすべての位置に対してリモート VBO を生成します。その位置に静的テキストまたは動的テキストをレンダリングできますが、VBO は静的です。
  4. テキストは常に一方向にレンダリングされるため、Texture VBO を 1 つだけ生成します。
  5. 描画時には、静的テキストをレンダリングします。
  6. 動的テキストの場合、VBO の位置を見て、文字テクスチャを取得し、一度に 1 文字ずつ描画できます。

リモート静的バッファを使用すると、描画操作が高速になります。

画面の位置 (画面の対角線のパーセンテージに基づく) とテクスチャ (静的および文字) を含む XML ファイルを作成し、レンダリングする前にこの XML を読み込みます。

高い FPS レートを得るには、描画時に VBO を生成しないようにする必要があります。

于 2013-01-18T16:56:29.000 に答える
4

GLSurfaceViewサンプルの「SpriteText」サンプルを見てください。

于 2009-08-27T06:18:12.810 に答える
3

どうしても GL を使用する場合は、テキストをテクスチャにレンダリングできます。HUD の大部分が比較的静的であると仮定すると、テクスチャをテクスチャ メモリに頻繁にロードする必要はありません。

于 2009-08-27T06:15:30.583 に答える
3

CBFG読み込み/レンダリング コードの Android ポートを見てください。コードをプロジェクトにドロップして、すぐに使用できるはずです。

  1. CBFG

  2. Android ローダー

この実装には問題があります。フォントのビットマップのサイズを変更しようとすると(特殊文字が必要です)、描画全体が失敗します:(

于 2012-07-09T11:30:34.560 に答える