4,164 views
この記事は最終更新から 2622日 が経過しています。
1. やりたいこと
Androidアプリの画面描画に OpenGL ES を使用してみる。
OpenGLとは、言わずと知れたグラフィックアクセラレータを駆使した高速描画ライブラリのことだ。
これを使用することにより、ゲーム上のキャラクターの描画処理が高速になり、見た目がスムーズになるはず。
2. やってみる!
(1) 方針
今回は OpenGL ESを使う第 1回目なので、余計な物を一切取っ払ったミニマム実装をしてみる。
すなわち…
OpenGLの Surface Viewを作り、Rendererを割り付け、直線を引くだけのシンプルな処理を書いてみる。
土台さえ作ってしまえば、後はその土台の上で動く物を凝ればよいだけだ。
(2) 実装
実行環境: Android Studio 3.2
Android Studioで自動生成した Empty Activityプロジェクトに以下のようにコードを付け足した。
18行目 : OpenGLの Viewを生成する。
19行目 : Renderer(描画制御オブジェクト)を生成し、OpenGLの Viewに割り付ける。
20行目 : Activityに Viewを割り付ける。
24行目 : Rendererクラス(描画制御クラス)を実装する。
29行目 : 画面いっぱいをキャンバスとする。
30行目 : 描画は 2Dの平面投影とする。 こちらを参照
31行目 : 頂点配列の使用を宣言する。 こちらを参照
34行目 : int型の座標指定は 1 = 0x10000 とのこと。
35行目 : 直線の点座標を定義する。OpenGLの座標系は画面の左下が原点、右向き、上向きが正方向
41行目 : OpenGL描画用バッファをクリアする。
44行目 : 描画データ用バッファを作成する。
48行目 : 作成したバッファに頂点座標データを格納する。
51行目 : 頂点座標データを格納したバッファを OpenGLに渡す。
52行目 : Rendererによる描画を実行する。
import android.opengl.GLSurfaceView;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLU;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
public class MainActivity extends AppCompatActivity {
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// OpenGL View, Rendererを生成&アタッチ
GLSurfaceView surfaceView = new GLSurfaceView(this);
surfaceView.setRenderer(new MyRenderer());
setContentView(surfaceView);
}
// 画面描画用のRendererクラス
public class MyRenderer implements Renderer {
@Override public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// 今回は特になし。
}
@Override public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height); // 画面いっぱいをキャンバスとする。
GLU.gluOrtho2D( gl, 0.0f, width, 0.0f, height );
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); // 頂点配列の使用を宣言する。
}
@Override public void onDrawFrame(GL10 gl) {
int one = 0x10000; // 上位16bitは整数部、下位16bitは小数部
int vertex[] = {
100 * one, 100 * one,
200 * one, 200 * one,
300 * one, 250 * one,
600 * one, 600 * one,
};
// 描画用バッファをクリア
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// 描画データ用バッファを作成する。
ByteBuffer bytebuffer = ByteBuffer.allocateDirect( vertex.length * 4 );
bytebuffer.order(ByteOrder.nativeOrder());
IntBuffer intbuffer = bytebuffer.asIntBuffer();
// 描画データ用バッファにデータを格納する。
intbuffer.put(vertex);
intbuffer.position(0);
// 描画実行!
gl.glVertexPointer(2, GL10.GL_FIXED, 0, intbuffer);
gl.glDrawArrays(GL10.GL_LINE_STRIP, 0, vertex.length / 2);
}
}
}
できた!

3. 応用
(1) 応用その1
以下の 2点を変えてみる。
1) 背景色を黒からグレーに変えてみる。
2) 線の描画色を白から黄色に変えてみる。
※各色の輝度指定は 0 ~ 255 ではなく 0.0 ~ 1.0 であることに注意。
1) onSurfaceCreated で背景色を指定する。
@Override public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glClearColor(0.5f,0.5f,0.5f,1.0f); //背景色 50%グレー
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
}
2) onDrawFrame で線の描画色を指定する。
// 描画実行!
gl.glColor4f(1.0f,1.0f,0.0f, 1.0f); // 線の描画色を黄色にする。
gl.glVertexPointer(2, GL10.GL_FIXED, 0, intbuffer);
gl.glDrawArrays(GL10.GL_LINE_STRIP, 0, vertex.length / 2);
できた!

4. 所感
・Androidでの OpenGLの基本的な使い方は、自分が前にアプリを作った 2010年から変わっていないようだ。