2011年8月6日土曜日

[Android] Android-NDKでテクスチャを表示するには

How to draw textures in Android-NDK

Havaは大きいソースが扱えないので、[Android] 頂点の多いポリゴンを扱うには では頂点数の多いポリゴンをAndroid-NDKを使ってJNIからJavaに大きい配列を渡す方法でバナナを表示しました。この方法はFloatBufferの作成に時間がかかるという問題がありました。
今回は、頂点とテクスチャの機能もJNIで書いてみます。

JNIで画像を扱うには?
テクスチャを表示するためglTexImage2Dを使います。
glTexImage2Dで表示できるテクスチャ画像はunsigned char型配列のビットマップデータです。配列の内容は1ピクセルごとにRGBAの順に1バイトずつです。
このブログを作成している時点ではJNIからres/drawableフォルダーやassetsフォルダーのファイルを扱う方法が見当たりませんでした。
そこで、JNIで画像データを扱うために次のようにしました。
  1. Javaでres/drawableフォルダーの画像をint型配列に変換してJNIに渡す
  2. JNIでJavaから渡されたint型配列をunsigned char型配列に変換しテクスチャ表示する
以下ソースです。
ndk.cpp
glu.h (Android-NDKのsampleの com.example.SanAngeles から抜粋しました)
Android.mk
これら ndk.cpp、glu.h、Android.mk と、HBehrens-obj2opengl-a0f123e.zipのbanana.h をプロジェクトのjniフォルダーにインポートし、カレントフォルダーをjniに移してndk-buildを実行します。
HBehrens-obj2opengl-a0f123e.zipののbanana.jpgをres/drawableフォルダーにインポートします。

Activityのソース(Main.java)
画面をフリックするとバナナが回転するようにしました。
これをエミュレーターで実行したら一瞬でバナナが表示されました。JavaでFloatBufferを作成する方法(エミュレーターで2分くらい)とは大違いの速さです。
テスト環境では、Heapを見比べたらJavaでFloatBufferを作成する方法に比べて1MBほどメモリーの節約になりました。
Android-NDKでビルドしたアプリケーションはARMの端末でしか動作しないのが玉に瑕です。

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

0 件のコメント:

コメントを投稿