GLSurfaceViewを使ったOpenGL ES1.0の初期化が出来たので、続いてGLSurfaceViewに三角形を描いてみましょう。
OpenGL ES 1.0では、頂点のデータを設定した後OpenGLの図形を描く描画コマンドを実行すると、画面上に図形が描画されます。デフォルトの座標系では、描画領域全体を(-1.0, -1.0)~(1.0, 1.0)に対応させるXY平面上にZ軸が配置されているので、この範囲に入るよう頂点を置いて図形を描けば、画面上に表示されるわけです(Z座標は、カメラやデプスを設定しないと意味を持ちません)。
今回は、三角形を描くために(-0.5, -0.5, 0)(0, 0.5, 0)(0.5, 0.5, 0)というfloat型数値による三つの頂点を用意し、AndroidのOpenGL ESシステムに渡すことにします。
Androidアプリを動かすJava仮想マシンからOpenGL ESにデータを渡すには、Bufferオブジェクトの形にする必要があるので、まず頂点のデータをfloat型配列にしてからFloatBufferを作成します。
// 頂点をfloat配列に格納
float[] vlist = new float[]{-0.5f, -0.5f, 0.0f, 0.0f, 0.5f, 0.0f, 0.5f, -0.5f, 0.0f};
// 頂点データ格納用ByteBufferを作成
ByteBuffer bbuf = ByteBuffer.allocateDirect(vlist.length * 4);
// バイトオーダー設定
bbuf.order(ByteOrder.nativeOrder());
// ByteBufferからFloatBufferを作成
mVlist = bbuf.asFloatBuffer();
// 配列をバッファに転送
mVlist.put(vlist);
// 現在位置をバッファ先頭に設定
mVlist.position(0);
これで頂点を格納したバッファが用意できました。あとは頂点を設定できるようにglEnableClientState()で頂点配列を有効化すれば、準備完了です。
実際の描画時には、全体をクリアした後glVertexPointer()でOpenGL ESに頂点データを設定します。続いて、glDrawArrays()も図形の種類(今回は三角形を示すGL10.GL_TRIANGLES)、頂点データのオフセットと頂点の数を指定し(今回は最初から三つの頂点を使うので、0と3を指定)を渡すと画面上に描画されます。
今回は、描画時の色を指定するglColor4f()で背景の補色となる色を設定してみました。
import java.nio.*;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLSurfaceView;
import android.opengl.GLSurfaceView.Renderer;
import android.os.Bundle;
import android.app.Activity;
public class MainActivity extends Activity implements Renderer {
private GLSurfaceView mGLView;
private float mBGD, mBGDD;
FloatBuffer mVlist;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mBGD = 0;
mBGDD = 0;
mGLView = new GLSurfaceView(this);
mGLView.setRenderer(this);
setContentView(mGLView);
}
@Override
protected void onPause() {
super.onPause();
mGLView.onPause();
}
@Override
protected void onResume() {
super.onResume();
mGLView.onResume();
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// 頂点をfloat配列に格納
float[] vlist = new float[]{-0.5f, -0.5f, 0.0f, 0.0f, 0.5f, 0.0f, 0.5f, -0.5f, 0.0f};
// 頂点データ格納用ByteBufferを作成
ByteBuffer bbuf = ByteBuffer.allocateDirect(vlist.length * 4);
// バイトオーダー設定
bbuf.order(ByteOrder.nativeOrder());
// ByteBufferからFloatBufferを作成
mVlist = bbuf.asFloatBuffer();
// 配列をバッファに転送
mVlist.put(vlist);
// 現在位置をバッファ先頭に設定
mVlist.position(0);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
}
@Override
public void onDrawFrame(GL10 gl) {
gl.glClearColor(mBGD, mBGD * mBGD, 1.0f - mBGD, 1.0f);
mBGD += mBGDD;
if (mBGD >= 1.0f) {
mBGDD = -0.01f;
}
if (mBGD <= 0) {
mBGDD = 0.01f;
}
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
gl.glColor4f(1.0f - mBGD, 1.0f - (mBGD * mBGD), mBGD, 1.0f);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVlist);
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
}
}
このソースをAndroidアプリとしてビルドし起動すると、画面全体が塗りつぶされ中央に三角形が描かれます。