Android で OpenGL を利用する方法
ここでは Android で OpenGL を利用するための基本的な方法について記載します。
ただし OpenGL を利用したプログラミング自体がはじめて、という人も少なくないと思いますから、 アクティビティなどの Android 特有の話題と OpenGL 固有の話題をあまり明確に分けずに順序立てて解説していこうと思います。
OpenGL のエキスパートの方で、 Android の開発をこれからはじめる、、、という方には少々冗長な話になってしまうかもしれませんが、そこはご勘弁ください。
OpenGL を利用する Android アプリケーション基本構成
OpenGL を利用する基本的な Android アプリケーションで登場する要素は主に次の図のようなものになります。
まず Activity は、 ご存知のとおり OpenGL を利用してもしなくても Android アプリケーションを構成する基本要素です。
OpenGL を利用する場合、 View として GLSurfaceView クラスの派生クラスを用います。 GLSurfaceView は Android 1.5 から導入されたクラスで、 OpenGLのレンダリングが可能なビューを提供します。
アクティビティの onResume、onPause のそれぞれのイベントで、ビューの onResume、onPause をそれぞれ呼び出します。これでアクティビティのライフサイクルに、 OpenGLも参加できるようになります。
ということで、 Activity と View を接続する箇所はこんな風になります。 ここで MyGLView は android.opengl.GLSurfaceView の派生クラスです。
package com.keicode.android.test;
import android.app.Activity;
import android.os.Bundle;
public class OpenGL0 extends Activity {
MyGLView myGLView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myGLView = new MyGLView(this);
setContentView(myGLView);
}
@Override
protected void onResume(){
super.onResume();
myGLView.onResume();
}
@Override
protected void onPause(){
super.onPause();
myGLView.onPause();
}
}
レンダリング (描画) を受け持つのは Renderer インターフェイスを実装した Renderer オブジェクトです。 Renderer オブジェクトは View にセットすることで、 イベントを受け取れるようになります。
Renderer クラスをここでは MyRenderer という名前で実装すると、次のような形になります。
package com.keicode.android.test;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLSurfaceView.Renderer;
public class MyRenderer implements Renderer {
@Override
public void onDrawFrame(GL10 gl) {
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
}
}
Renderer インターフェイスは上にみられるように、onSurfaceCreated、onSurfaceChanged、onDrawFrame の三つのメソッドです。
ひとことで言うと、 onSurfaceCreated は初期化時に呼ばれ、 onSurfaceChanged は主に landscape と portraid の切り替え (縦向き、横向き切り替え) のときに呼ばれる、 onDrawFrame は描画のため繰り返し呼ばれる、ということになってます。
onSurfaceCreated は描画コンテキスト (Drawing context) がなくなって再作成されるときに呼ばれます。 通常コンテキストは Activity のライフサイクルの中では onPause、onResume で再作成されます。
onDrawFrame は1フレーム毎に呼び出されます。デフォルトで連続描画モード (Continuous Rendering) です。 もし何かあったときにだけ再描画したいということなら、 GLSurfaceView.setRenderMode(RENDERMODE_WHEN_DIRTY) でダーティになったときだけ再描画するというモードにしておき、 描画したいときに GLSurfaceView.requestRender() を呼ぶということも可能です。
メインの描画ロジックはこの、 onDrawFrame に記述することになります。
さて、 Renderer が定義できたので、 最初に出てきた View クラスの MyGLView に戻りましょう。
もったいぶるほどではなかったのですが、 次のコードのように setRenderer メソッドでレンダラをセットするところがポイントです。
package com.keicode.android.test;
import android.content.Context;
import android.opengl.GLSurfaceView;
public class MyGLView extends GLSurfaceView {
MyRenderer myRenderer;
public MyGLView(Context context) {
super(context);
myRenderer = new MyRenderer();
setRenderer(myRenderer);
}
}
さぁ、これで主な登場人物は登場し終わりました。 それでは OpenGL 固有の描画ロジックなどをここに加えていきましょう。