SSブログ

Androidアプリ開発 OpenGLを使う GLSurfaceView [Android OpenGL]

Androidには標準でOpenGLが入っている。OpenGLは2D/3DでのCGを作成するためのグラフィックスライブラリ。Androidに搭載されているOpenGLはモバイル端末向けに機能が限定された「OpenGL ES」といったパッケージになる。

androidでの2Dでの描画は(OpenGLを使わなくても)、Canvasを使って行うこともできる。
OpenGLを使うとGPUでのハードウェア・アクセラレーションが可能になり、高速に描画できる。また、3DCGはCanvasではできない。

androidアプリでは、アクティビティにビューを乗っけることでビューを表示することができる。ビューにはテキストとか、エディットといった種類のビューが用意されているので、アクティビティにテキストビューを追加すれば、テキストが表示される。

ビューは、入れ子にすることができ、レイアウトでどこに配置するかを決定できる。細かい話はOpenGLと離れていってしまうので、またの機会にしよう。

さて、androidアプリでOpenGLでなにか表示しようと思ったら、GLSurfaceViewの派生クラスを作ってやる必要がある。サーフェースビューは、普通のビューとは異なり、専用の描画スレッドを持っていて、高速に描画できるらしい。OpenGL版のサーフェースビューがGLSurfaceViewということになる。

じゃあ、早速作ってみるべし。

public class SampleGLSurfaceView extends GLSurfaceView {
}


クラスの定義はこんな感じでいいでしょう。名前はSampleGLSurfaceViewとしたが、ここは適当に好きな名前にしてもよい。
Eclipseのウイザードでクラスを作成すると、importが自動的に行われるが、パスまではめんどうみてくれないので、android.opengl.GLSurfaceViewをインポートする。

import android.opengl.GLSurfaceView;

public class SampleGLSurfaceView extends GLSurfaceView {
}


GLSurfaceViewのエラー赤線は消えるが、クラス名のところにエラーの赤線が出る。
「コンストラクタが必要」となるので、コンストラクタを作成する。このとき、Contextを引数に持つやつを作っておく。ContextっていうのはメインのActivityのこと。少し意味が違うかも知れないが、アプリケーションの「プロセスを特定するためのもの」、と思っておけばよい。
引数でもらったContextは、そのままスーパークラスのコンストラクタに渡してやる。そうしないと「引数が必要」といった感じのエラーになる。
Eclipseのクイックフィックス機能を使って、「コンストラクタを作成」をクリックしてやれば、自動的にこんな感じに作成してくれる。

import android.content.Context;
import android.opengl.GLSurfaceView;

public class SampleGLSurfaceView extends GLSurfaceView {

	public SampleGLSurfaceView(Context context) {
		super(context);
		// TODO 自動生成されたコンストラクター・スタブ
	}

}


Eclipse、超便利。

TODOのところにコードを書いていく。

import android.content.Context;
import android.opengl.GLSurfaceView;

public class SampleGLSurfaceView extends GLSurfaceView {

	public SampleGLSurfaceView(Context context) {
		super(context);
		renderer = new OpenGLRenderer();
		setRenderer(renderer);
	}

}


コンストラクタでは、「レンダラー」を作ってセットしている。
OpenGLで何か描画しようと思ったら、レンダラーでやらないといけない。

「えー、ビューだけじゃだめぇ...」

そうなんです。なんと、めんどくさいことにOpenGLでは「ビュー」と「レンダラー」を作ってやる必要がある。レンダラーは、android.opengl.GLSurfaceView.Rendererを実装したクラスで、これでレンダリングをする。
レンダリングっていうのは3DCGでの用語で、「バーチャル空間に配置されている3次元データを2次元のスクリーン上に描画する」っていうことかな。

GLSurfaceViewの方は、androidのSurfaceViewのOpenGL版、と捉えればよいと思う。
Rendererの方は、OpenGLライブラリ関数のラッパークラス、と捉えればOKでしょう。

なので、OpenGLでの描画のメインはRendererに作成していく。GLSurfaceViewには、ビューが作成されたときや、大きさが変更されたときなど、画面上のウイジットやコントロールといった感じの機能を受け持つことになる。

前置きはこれくらいにして、Rendererを作成しよう。Rendererは、別のソースファイルに作成してもいいが、何かとViewと連携することも多いと思うので、クラス内のクラスで作成することにした。

public class SampleGLSurfaceView extends GLSurfaceView {

	// レンダラークラス
	class OpenGLRenderer implements Renderer {
	}
	private OpenGLRenderer renderer;

	// サーフェースビューのコンストラクタ
	public SampleGLSurfaceView(Context context) {
		super(context);
		renderer = new OpenGLRenderer();
		setRenderer(renderer);
	}
}


クラスOpenGLRendererはRendererインターフェースを実装したクラス。継承ではなく、インターフェースの実装でレンダラーを作成する。OpenGLRendererは私が考えた名前。ここは好きな名前に変更してよい。
レンダラーのインスタンスを作成したら、setRendererでレンダラーとビューをつなげる。直接、setRenderereでnewしたインスタンスを設定してもよいが、後から使用するかも知れないので、クラスのフィールドrendererで記憶しておく。

Rendererはインターフェースなので、実装すべきメソッドがいくつか存在する。
OpenGLRendereにエラーの赤線が表示されており、「実装すべきメソッドがないよ」と教えてくれている。面倒なのでEclipseでクイックフィックスしてしまおう。
「実装されていないメソッドの追加」をクリックすると、自動的に3つのメソッドが作成される。

	// レンダラークラス
	class OpenGLRenderer implements Renderer {

		@Override
		public void onDrawFrame(GL10 gl) {
			// TODO 自動生成されたメソッド・スタブ
			
		}

		@Override
		public void onSurfaceChanged(GL10 gl, int width, int height) {
			// TODO 自動生成されたメソッド・スタブ
			
		}

		@Override
		public void onSurfaceCreated(GL10 gl, EGLConfig config) {
			// TODO 自動生成されたメソッド・スタブ
			
		}
	}


作成されたメソッドは全部で3つ。そのひとつが、onDrawFrameである。ここで描画を行う。
その他に、onSurfaceCreated、onSurfaceChangedがあるが、こいつらはとりあえず使わない。

Frameは「フレーム」なので、映画や、ビデオのアニメーションのようにフレーム毎に描画が行われることを意味している。つまり、onDrawFrameは「連続して呼び出し続けられる」。
これに比べ、onSurfaceCreated、onSurfaceChangedの呼び出される頻度は少ない。

描画する際に、方向を少しづつ変えていけば、表示される像が移動してみえることになり、まさにアニメーションのように物が動いてみえる。
さっそくやってみたいところだが、まず、ファーストステップとしては、「単に黒く塗り潰すだけ」にする。「急がば回れ」である。

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

import android.content.Context;
import android.opengl.GLSurfaceView;

public class SampleGLSurfaceView extends GLSurfaceView {
	// レンダラークラス
	class OpenGLRenderer implements Renderer {

		@Override
		public void onDrawFrame(GL10 gl) {
			gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
		}

		@Override
		public void onSurfaceChanged(GL10 gl, int width, int height) {
		}

		@Override
		public void onSurfaceCreated(GL10 gl, EGLConfig config) {
			gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
		}
	}
	private OpenGLRenderer renderer;

	// サーフェースビューのコンストラクタ
	public SampleGLSurfaceView(Context context) {
		super(context);
		renderer = new OpenGLRenderer();
		setRenderer(renderer);
	}

}


これで、レンダラーが完成。
onSurfaceCreatedにもコードを書いてしまったが、まぁ、御愛嬌っていうことで。へへ。

後は、アクティビティで「表示すべきビュー」をSampleGLSurfaceViewにすれば、そのように表示される。
アクティビティは以下のように作成してみた。

public class TestOpenGLActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.main);
        // OpenGL用のビューを作る
        SampleGLSurfaceView view = new SampleGLSurfaceView(this);
        // アクティビティにビューを設定
        setContentView(view);
    }
}


これで完成。真黒なアクティビティが表示できたら「成功」。



関連記事
AREarthWebGL AREarthroidの地球表示部分をWebGL化




サイト内を検索

タグ:OpenGL Android
nice!(0)  コメント(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。



Copyright Atsushi Asai Google+朝井淳
[改訂第4版]SQLポケットリファレンス

[改訂第4版]SQLポケットリファレンス

  • 作者: 朝井 淳
  • 出版社/メーカー: 技術評論社
  • 発売日: 2017/02/18
  • メディア: 単行本(ソフトカバー)

イラストで理解 SQL はじめて入門

イラストで理解 SQL はじめて入門

  • 作者: 朝井 淳
  • 出版社/メーカー: 技術評論社
  • 発売日: 2019/05/16
  • メディア: 単行本(ソフトカバー)

[データベースの気持ちがわかる]SQLはじめの一歩 (WEB+DB PRESS plus)

[データベースの気持ちがわかる]SQLはじめの一歩 (WEB+DB PRESS plus)

  • 作者: 朝井 淳
  • 出版社/メーカー: 技術評論社
  • 発売日: 2015/03/03
  • メディア: 単行本(ソフトカバー)

Access クエリ 徹底活用ガイド ~仕事の現場で即使える

Access クエリ 徹底活用ガイド ~仕事の現場で即使える

  • 作者: 朝井 淳
  • 出版社/メーカー: 技術評論社
  • 発売日: 2018/05/25
  • メディア: 大型本

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。