2011年2月16日水曜日

OpenGL勉強会まとめ(2) OpenGLアプリの最小構成

OpenGLはプラットフォーム非依存
コノルさんの勉強会ではiPhoneでのOpenGL ESアプリを作ることを目標に、基本的な描画、テクスチャ、バンプマッピング、マルチテクスチャまでを勉強しました。

このブログはおさらいという意味で、勉強会のソースをアリの目でもう一度追学習してみようと考えています。

OpenGL自体はプラットフォーム非依存で、実際に画面に表示するウィンドウを作るなどという部分は含まれていません。そのあたりを扱う有名なライブラリに、glutなどがありますし、本家でもEGLという、プラットフォーム依存部分のインターフェースを規定しているものもあるようです(iOSでのEAGLViewはEGLのApple実装らしい)。

iOSではglutは使えませんから、私も参考書などにあるソースがそのまま動かなかったりして戸惑いました。逆にEAGLViewは当然他の環境にはありませんので、この記事はiOSでのOpenGL ES1.1をターゲットにしていますが、iPhone独自部分についてはあまり深く追わず、OpenGL ES1.1として一般的な内容になるように心がけてみます。

テンプレートを見てみる
XCodeでOpenGL ES Application新規プロジェクトを作成すると、そのままグラデーションがかかった四角形が上下に運動するデモアプリになります。勉強会でもここからスタートしました。これがiOSでのOpenGLアプリ最小構成だといえますので、まずこれを追ってみましょう。

素のOpenGL ES Application

iOSでの OpenGL ESアプリ起動までの流れ
テンプレートには、主に下記のクラスが含まれます。環境依存部分ではありますが、軽く見てきます。
xxxAppDelegate
EAGLView
xxxViewController

アプリ起動→xxxAppDelegate→xxxViewControllerという流れは通常のアプリと同じです。
xxxViewControllerでは、OpenGL ES1.1 APIの使用開始(contextを作る)、EAGLViewのインスタンスを作成、フレームバッファ(後述)の作成が行われます。
その直後、iOSにより画面表示開始される直前に(viewWillAppearメソッドからstartAnimationメソッドが呼ばれ)フレームレートの設定などが行われます。ここで画面表示のタイミング(1/60秒)で 毎回drawFrameメソッドが呼ばれるように設定されます。

ここまでお膳立てしてもらえるので、開発者は drawFrameメソッドの中のみ実装すればよいわけです。勉強会では実装を簡単にするために初期化もdrawFrameの初回呼び出し時に行っていましたが、startAnimationメソッドにて初期化を行うのもありだと思います。

OpenGLの最小構成
テンプレートのdrawFrameメソッドの中身は、下記のようになっています。(動きの部分は割愛)
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);  //色を指定して
glClear(GL_COLOR_BUFFER_BIT); //色バッファをクリア
glMatrixMode(GL_PROJECTION); //射影行列を
glLoadIdentity(); //単位行列に初期化
glMatrixMode(GL_MODELVIEW); //モデルビュー行列を
glLoadIdentity(); //単位行列に初期化して
glTranslatef(0.0f, (GLfloat)(sinf(transY)/2.0f), 0.0f); //上下の動き分平行移動
glVertexPointer(2, GL_FLOAT, 0, squareVertices); //頂点配列の設定
glEnableClientState(GL_VERTEX_ARRAY); //頂点配列を有効に
glColorPointer(4, GL_UNSIGNED_BYTE, 0, squareColors); //カラー配列の設定
glEnableClientState(GL_COLOR_ARRAY);  //カラー配列を有効に
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); //描画
[(EAGLView *)self.view presentFramebuffer]; //フレームバッファを表示
コメントを付けておきましたのでなんとなくわかるかと思いますが、私が最初とまどったのはそれぞれの概念がよくわからないことです。というわけで登場人物を整理します。(これはいずれするかもしれないOpenGLクラス化の候補にもなります)

フレームバッファ
最終的に画面上に表示するピクセルを保持するバッファです。色を保持する色バッファと、深度(奥行き)をピクセルごとに保持する深度バッファ(Zバッファとも呼ばれる)からなります。深度バッファは奥に隠れた物体を隠す隠面消去のために使われますが、テンプレートの状態では生成されていません。これらフレームバッファはiOSではEAGLViewにて管理されています。

頂点配列
頂点はバーテックスとも言います(複数形はVertices)線やポリゴン(OpenGL ES1.1では3角形)の頂点の座標(2次元及び3次元)を列挙する配列です。物の外形はこの配列で決まります。


カラー配列
頂点ごとの色が列挙されている配列です。頂点配列と要素数が同じで、各頂点と1:1で対応します。

射影変換行列
3次元座標世界のポリゴンを2次元にどのように投影するかを決める4x4の行列です。

モデルビュー変換行列
3次元座標内でモデルをどのように移動・回転・拡大縮小するかを決める4x4の行列です。


次回は引き続きこのテンプレートをもう少し詳しく見ていきます。

0 件のコメント:

コメントを投稿