(10) OpenGL ESのミニマム実装

投稿者: | 2018年10月1日

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年から変わっていないようだ。


コメントを残す

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


日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)