3,814 views
この記事は最終更新から 2329日 が経過しています。
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年から変わっていないようだ。