01.ベースOpenGLレンダラクラスを作る
(開発環境として「Eclipse」を使用した、古い情報です。
開発環境として「Android Studio」を使用した、新しい情報は、
「ホーム > プログラミング > モデルビューアを作る ( Android + OpenGL ES 1.0/1.1 ) ( Android Studio 2.3.3 版 )」)
OpenGLの初期化処理と終了処理を行い、OpenGLを用いた描画処理の骨格を担う、ベースOpenGLレンダラクラスを作成します。
使用開発環境は、Eclipse 3.7.2 ベースの Pleiades です。
解説
Androidで、OpenGLを使用して描画をするためにすべきことは、以下です。
- GLSurfaceView.Rendererインターフェースを実装したクラスのオブジェクトを生成する。
- GLSurfaceViewクラス(もしくは、その派生クラス)のオブジェクトを生成する。
- 1.で作成したGLSurfaceView.Rendererオブジェクトを、2.で作成したGLSurfaceViewオブジェクトに、setRenderer関数でセットする。
- 2.で作成したGLSurfaceViewオブジェクトを、メインアクティビティの、onCreate関数内で、setContentView関数でセットする。
- GLSurfaceView.Rendererインターフェースを実装したクラスの、サーフェースが作成された時およびサーフェースが再作成された時に呼び出される onSurfaceCreated関数で、クリアカラーの設定や、クリア深度設定、およびOpenGLの有効、無効の設定をする。
- GLSurfaceView.Rendererインターフェースを実装したクラスの、サーフェースが変更された時に呼び出される onSurfaceChanged関数で、ビューポートの設定、視野角錐台の設定、視点座標変換の設定をする。
- GLSurfaceView.Rendererインターフェースを実装したクラスの、フレームを描画する時に呼び出されるonDrawFrame関数で、モデル描画の処理をする。
Androidで、OpenGLを使用して描画をするときに、した方がよいことは、以下です。
- メインアクティビティクラスの、他のアクティビティが起動したことでバックグラウンドに追いやられた時に呼び出される onPause関数で、GLSurfaceViewオブジェクトのonPause関数呼び出しを行う。
- メインアクティビティクラスの、ポーズから復帰する時に呼び出される onResume関数で、GLSurfaceViewオブジェクトのonResume関数呼び出しを行う。
Androidで、OpenGLを使用して描画をするときに、しなくても良いが、今回やっていることは、以下です。
- GLSurfaceViewの描画モードは、既定では、RENDERMODE_CONTINUOUSLYという、絶え間なく描画するというモードになっていますが、RENDERMODE_WHEN_DIRTYという、描画要求があったときだけ描画するというモードに変更しています。描画要求は、requestRenderという関数で行います。
実装
プロジェクトの作成
メニュー 「ファイル > 新規 > プロジェクト」 を選択します。
Android プロジェクトを選択し、「次へ」ボタンを押します。
Project Name に「ModelViewerEtude」と入力し、「次へ」ボタンを押します。
ビルドターゲットを一つチェックし(たとえば、「Android 2.1」をチェックし)、「次へ」ボタンを押します。
Package Name にパッケージ名(たとえば、「com.hiramine.modelvieweretude」)を入力し、「完了」ボタンを押します。
ベースOpenGLレンダラクラスの作成
OpenGLを用いた描画処理の骨格を担う、ベースOpenGLレンダラクラスを作成します。
GLSurfaceView.Rendererインターフェースを実装したクラスとして作成します。
パッケージエクスプローラで、作成したプロジェクトの下の「src」の下の作成したパッケージを右クリックし、 右クリックメニューの「新規 >
クラス」 を選択します。
名前 にクラス名「OpenGLBaseRenderer」、
インターフェースに、「android.opengl.GLSurfaceView.Renderer」、
を入力し、「完了」ボタンを押します。
サーフェースが作成された時、再作成された時の処理の実装
GLSurfaceView.Rendererインターフェースを実装したクラスの、サーフェースが作成された時およびサーフェースが再作成された時に呼び出される
onSurfaceCreated関数に、OpenGLオブジェクトに関するメンバ変数への設定、クリア処理の設定、クリア処理の設定、ポリゴン処理の設定、ライティング処理の設定、ブレンド処理の設定を追加します。
OpenGLオブジェクトに関するメンバ変数およびアクセサを追加します。
サーフェースが変更された時の処理の実装
GLSurfaceView.Rendererインターフェースを実装したクラスの、サーフェースが変更された時に呼び出される onSurfaceChanged関数に、サーフェースのサイズに関するメンバ変数への設定、ビューポートの設定、視野角錐台の無効化、視点座標変換の無効化、の処理を追加します。
サーフェースのサイズに関するメンバ変数およびアクセサ関数、ビューポート設定関数を追加します。
視野角錐台設定、視点座標変換設定は、OpenGLの変換行列を変更するとき以外は設定する必要はありません。必要なときのみ設定することで、描画処理の負担を軽減するようにします。設定を実施する必要があるかを判断するための設定の有効性メンバ変数、アクセサを追加します。
フレーム描画処理の実装
GLSurfaceView.Rendererインターフェースを実装したクラスの、フレームを描画する時に呼び出されるonDrawFrame関数に、モデル描画の処理を追加します。
視野角錐台設定、視点座標変換は、設定の有効性メンバ変数に応じて実施するようにします。
視野角錐台設定、視点座標変換設定、シーン描画前の処理、シーン描画後の処理、ストックシーンの描画、シーン描画、軸の描画、byteバッファーの作成、shortバッファーの作成、floatバッファーの作成の関数を追加します。
また、byte型のバイト数、short型のバイト数、float型のバイト数の定数変数を追加します。
また、軸描画用の頂点バッファーメンバ変数、色バッファーメンバ変数を追加します。
また、コンストラクタを追加し、コンストラクタに、軸描画用の頂点バッファーメンバ変数、色バッファーメンバ変数の構築処理を追加します。
メインアクティビティクラスの実装
メインアクティビティの、onCreate関数内で、以下を行います。
- GLSurfaceView.Rendererインターフェースを実装したクラスのオブジェクトを生成します。
- GLSurfaceViewクラスのオブジェクトを生成します。
- 1.で作成したGLSurfaceView.Rendererオブジェクトを、2.で作成したGLSurfaceViewオブジェクトに、setRenderer関数でセットします。
- 2.で作成したGLSurfaceViewオブジェクトを、メインアクティビティに、setContentView関数でセットします。
また、GLSurfaceViewクラスのオブジェクトメンバ変数を追加します。
また、GLSurfaceViewの描画モードは、既定では、RENDERMODE_CONTINUOUSLYという、絶え間なく描画するというモードになっていますが、RENDERMODE_WHEN_DIRTYという、描画要求があったときだけ描画するというモードに変更します。(描画要求は、requestRenderという関数で行います。)
また、その他、フルスクリーン設定、タイトルなし設定の処理を追加します。
他のアクティビティが起動した場合等には、OpenGLの処理を一時中断するようにします。
メインアクティビティクラスの、他のアクティビティが起動したことでバックグラウンドに追いやられた時に呼び出される onPause関数をオーバーライドし、GLSurfaceViewオブジェクトのonPause関数呼び出しを追加します。
メインアクティビティクラスの、ポーズから復帰する時に呼び出される onResume関数をオーバーライドし、GLSurfaceViewオブジェクトのonResume関数呼び出しを追加します。
import宣言は、eclipseの「エラーの即時修正」機能を使用して、追加します。
実行
Android Virtual Deviceの作成
動作確認用のAndroid Virtual Deviceを作成します。
OpenGL ES 1.0 の機能のみを利用したアプリケーションの動作確認用の Android Virtual Device の作成においては、特に気にすることはありません。
しかし、OpenGL ES 1.0 の機能に加えて、1.1 の機能を利用したアプリケーションの動作確認の Android Virtual Device
においては、私の環境においては、Android Virtual Deviceを
・ターゲットとして、「Android 4.0.3 - API Level 15」
・ハードウェアとして、「GPU emulation」をyes
の設定で作成しなければ、「GPU内で関数が定義されていない」旨のエラーが発生し、動作確認ができませんでした。(エラーの具体的なメッセージとしては、「called
unimplemented OpenGL ES API」。エラーが発生する具体的な関数としては、「glGetFloatv」。)
この章では、OpenGL ES 1.0の機能のみを利用していますが、続く章で、OpenGL ES 1.1の機能も利用するので、Android
Virtual Device を
・ターゲットとして、「Android 4.0.3 - API Level 15」
・ハードウェアとして、「GPU emulation」をyes
の設定で作成します。
メニュー 「ウィンドウ > AVD マネージャー」 を選択します。
「新規」ボタンを押します。
名前:適当な名前を入力
ターゲット:「Android 4.0.3 - API Level 15」を選択
CPU/ABI:「ARM (armeabi-v7a)」を選択
SDカードサイズ:64[MiB]を入力
ハードウェア:「GPU emulation」の項目を追加し、値を「yes」に設定
「AVD の作成」ボタンを押します。
作成したAVDの項目を選択し、「開始」ボタンを押します。
「起動」ボタンを押します。
しばらくすると、AVDが起動し、しばらくすると、AVD内に、Android OSが起動します。
Android OSの起動が完了するのを待ちます。
スライドロックを解除します。