2011年5月21日土曜日

[Android] OpenGL ESで文字を表示する

How to draw text on GLSurfaceView

AndroidのOpenGL ESには画面に文字を表示するAPIが無いようです。
いくつかのソースを調べたところ、文字を表示するために次のような2種類の方法がありました。

1.文字の形のポリゴンを表示する
2.文字を書いたビットマップ画像をテクスチャとして表示する

「1.文字の形のポリゴンを表示する」方法は、文字の種類や画数の多い日本語の表示には手間が多すぎます。
「2.文字を書いたビットマップ画像をテクスチャにする」のサンプルを作ってみます。
あらかじめ文字を書いたビットマップ画像を用意するのではなく、ビットマップ画像を動的に生成します。
注意するべき点はテクスチャに表示するビットマップ画像のサイズを2の累乗に設定することです。
例:128ピクセル×64ピクセル、512ピクセル×512ピクセル、など
このサイズを守らなくてもテクスチャ表示できる機種とできない機種があります。Android SDKのエミュレーターでは表示できてしまいますが、ほとんどの機種では表示できないと思います。
エミュレーターではテクスチャ表示できるのに実機では表示できない場合は画像のサイズが原因かもしれません。
テクスチャ表示するアプリは複数の機種で動作確認することをお勧めします。

GlSurfaceViewに現在時刻の文字を表示するサンプルソースです。
パーミッションは設定不要のためマニフェストは省略します。レイアウト用xmlも使いません。
(2011年5月30日訂正、20011年8月2日訂正)
ポリゴンらしく回転させてます。1分ごとに1回転します。
※画像や文字を回転させるだけならSurfaceViewでもできます。文字を回転させても読みにくいだけです。
ビットマップ画像の作成(動的ビットマップ画像)は負荷が高いらしく、あまり短い間隔でビットマップ画像を作成するとLow Memoryの警告がたくさん出たあげく強制終了することがありした。
対策として1秒に1回だけビットマップ画像を作成することにしました。

GLSurfaceView#onDrawFrameメソッド内でのメモリーの確保や解放は極力避けた方がいいようです。(StringではなくStringBufferを使っているのもそのため)
負荷軽減のためにはあらかじめ文字を描いた画像(静的ビットマップ画像)を表示する方がいいと思います。

OpenGLは機種ごとの動作の違いがはっきり現れるので実機テストが欠かせません。

以上、参考になれば幸いです。

キーワード
GLSurfaceView Renderer createBitmap Canvas Panit

5 件のコメント:

  1. プログラム参考にさせていただいています。

    背面除去で表が消えてしまいます。
    テキストの表裏が逆になっているようなのですが、どのようにすれば改善できるでしょうか。

    よろしくお願いします

    返信削除
  2. どんなコードを書きましたか?

    返信削除
  3. 大変参考になりました。ありがとうございます。

    返信削除
    返信
    1. コメントありがとうございます。

      削除