【Android】OpenGLの学習(1) 2Dをとにかく使ってみる

By | 2011年12月28日

AndroidでOpenGLを使って何か描画してみよう。
OpenGLと言えば3Dグラフィックスのライブラリという側面が強いのだが、まずは2Dから入っていくことにする。
始めに、画面の中心に四角形を描いてみる。プログラムは以下のようになった。

MainActivity.java

package com.lesson.gl;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.opengl.GLSurfaceView.Renderer;
import android.os.Bundle;

public class MainActivity extends Activity {
	
	private GLSurfaceView glSurfaceView;
	
	// ネイティブから直接参照可能なバッファを作成
	private static final FloatBuffer makeFloatBuffer(float[] arr){
		ByteBuffer bb = ByteBuffer.allocateDirect(arr.length * 4);
		bb.order(ByteOrder.nativeOrder());
		FloatBuffer fb = bb.asFloatBuffer();
		fb.put(arr);
		fb.position(0);
		
		return fb;
	}
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        glSurfaceView = new GLSurfaceView(this);
        glSurfaceView.setRenderer(new Renderer() {
			
			@Override
			public void onSurfaceCreated(GL10 gl, EGLConfig config) {
			}
			
			@Override
			public void onSurfaceChanged(GL10 gl, int width, int height) {
				
				// GLで利用する領域を設定
				gl.glViewport(0, 0, width, height);
				
				float ratio = (float) height / width;
				gl.glMatrixMode(GL10.GL_PROJECTION);
				gl.glLoadIdentity();
				
				// 正射影モードで座標系を設定
				// 左上(-1.0,-ratio) 右下(1.0f,ratio)
				gl.glOrthof(-1.0f, 1.0f, -ratio, ratio, 0.5f, -0.5f);
			}
			
			@Override
			public void onDrawFrame(GL10 gl) {
				
				// 画面を塗りつぶす
				gl.glClearColor(0.f, 0.f, 1.f, 1.f);
				gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
				
				
				gl.glMatrixMode(GL10.GL_MODELVIEW);
				gl.glLoadIdentity();
				
				// 四角形の座標
				float[] vertices ={
						-0.5f, -0.5f,
						 0.5f, -0.5f,
						-0.5f, 0.5f,
						 0.5f, 0.5f,
				};
				
				FloatBuffer fb = makeFloatBuffer(vertices);
				
				// 四角形の描画
				gl.glVertexPointer(2, GL10.GL_FLOAT, 0, fb);
				gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
				gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
			}
		});
        
        setContentView(glSurfaceView);
    }
    
    @Override
    protected void onPause() {
    	// TODO Auto-generated method stub
    	super.onPause();
    	glSurfaceView.onPause();
    }
    
    @Override
    protected void onResume() {
    	// TODO Auto-generated method stub
    	super.onResume();
    	glSurfaceView.onResume();
    }
}

AndroidでOpenGLを扱うにはGLSurfaceViewを使うと便利である。
GLSurfaceViewには、Rendererインターフェースの実装クラスをセットする必要がある。
37行目でGLSurfaceView#setRenderer()メソッドを使い、Rendererをセットしている。
44行目のonSurfaceChanged()メソッド内で画面領域の設定と座標系の設定を行う。
59行目のonDrawFrame()メソッドは繰り返し呼ばれるメソッドである。この中に描画処理を書く。
今回は、画面を青色に塗りつぶし、四角形を描いているだけである。
四角形の座標は配列にしてOpenGLに渡すのだが、Javaの配列をそのまま渡すことはできない。
そこで、Javaの配列を、ネイティブから直接参照可能な配列に変換する。21行目のmakeFloatBufferはそのためのメソッドである。

ここまでのプログラムを実行すると、以下のように表示される。


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です