How to draw many vertrics on GLSurfaceView
前回のブログ
obj2opengl.plをJava用に改造する では
obj2opengl: convert obj 3D models to arrays compatible with iPhone OpenGL ES « Heiko Behrens (Blog):
http://heikobehrens.net/2009/08/27/obj2opengl/
で公開されているバナナのオブジェクトは頂点が多くてJavaでは扱えないことがわかりました。
原因は
定数プールは65536エントリー以内
コンストラクターやメソッドのソースは65536バイト以内
というJavaの仕様によるものでした。
Javaは大きいソースをビルドできないので、外部ファイルに持たせる方法をいくつか試してみましたがどれも無理でした。
1.assetsフォルダーに頂点データをテキストファイルに保存する
→AssetManagerは256行以上のテキストファイルを読み込めない(IOException例外が発生)
2.頂点データをvalues/strings.xmlに保存する
→strings.xmlは65536行以上のデータを扱えない
試行錯誤の結果、
obj2opengl.plが出力したbanana.hをAndroid-NDKで使うことでバナナを表示できました。
HBehrens-obj2opengl-a0f123e.zipに含まれるbanana.jpgとbanana.hをAndroidプロジェクトに取り込みます。
jniフォルダーを作ってbanana.hを保存します。
drawableフォルダーを作ってbanana.jpgを保存します。
jniフォルダーにはさらにAndroid.mkとbanan.cppを保存します。
Android.mk
banana.cpp
Activityのソースです。
Main.java(Activity)
これでカレントフォルダーをプロジェクトのjniフォルダーに移動し、ndk-buildを実行します。
起動するとこうなります。
画面をドラッグすると視点が動くようにしました。
バナナとバナナの中心点がかなり離れてるようで(気のせいでした)、大きく動かすと画面から消えてしまいます。
今回は頂点の配列をAndroid-NDK、それ以外をJavaで書いたので
エミュレーターで実行するとすごく遅いです。
FloatBufferの作成にすごく時間がかかります。バナナが表示されるまで2分くらいかかりました。
FloatBufferをシリアライズできればもっとスマートになるんですが。
Blenderモンキーの頂点+法線ベクトルの組み合わせもソースが大きくてJavaではビルドできませんでした。objファイルをobj2opengl.plでhファイルに変換し、バナナと同じようにAndroid-NDKでビルドしました。光源で照らしてます。こちらはテクスチャがないのでエミュレーターに表示されるまで30秒くらいでした。
Android-NDKを使うデメリットはARMプラットフォームの端末しかサポートきなくなることです。x86版Android端末にはインストールすらできなくなります。
ただし、今のところ国内のAndroid端末はほとんどがARMベース(Qualcomm、Tegraなど)なので大きなデメリットではないと思います。
以上、参考になれば幸いです。