OpenGL ES 2.0で波紋を作る#6 カメラをつける
前の章で作成した板ポリゴンへのカメラの使い方を解説します。
ポイント
・カメラの使い方
カメラの概念
板ポリゴンにカメラをつけるには、OpenGL上でのカメラの使い方を理解しなければなりません。
以下、カメラの使い方を解説します。
・プロジェクションの設定
・カメラ視点の設定
・モデルビューの設定
・描画
プロジェクションの設定
□ プロジェクションの概念
プロジェクションは、画角、ニアクリップ、ファークリップを利用します。
以下の図の青色がカメラから見える範囲です。
項目 | 内容 |
---|---|
画角 | Y軸に対する視野領域の角度。 radianを設定します。 |
ニアクリップ | カメラ視点から最初に見える距離。 nearを設定します。 |
ファークリップ | カメラ視点から最後に見える距離。 farを設定します。 |
□ プロジェクションの設定
カメラのプロジェクションの設定は、「GLKMatrix4MakePerspective」を利用します。
GLKMatrix4MakePerspectiveの引数は、下記の通りです。
第1引数:ラジアン。GLKMathDegreesToRadiansを利用することで、度数からラジアンに変換できます。
第2引数:画面のアスペクト比
第3引数:ニアクリップ
第4引数:ファークリップ
1 |
GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(degree), aspect, near, far); |
□ カメラ視点の概念
カメラの視点の概念
カメラ視点には、カメラのベクトル、カメラの位置、ターゲットの位置を設定します。
項目 | 内容 |
---|---|
カメラの位置 | カメラの位置座標。 eyeX、eyeY、eyeZを設定します。 |
ターゲットの位置 | カメラから見るターゲットの位置座標。 targetX、targetY、targetZを設定します。 |
カメラのベクトル | カメラの方向。 upX、upY、upZを設定します。 |
カメラ視点の設定
カメラ視点の設定は、「GLKMatrix4MakeLookAt」を利用します。
GLKMatrix4MakeLookAtの引数は、先頭から順にカメラの位置座標、ターゲットの位置座標、カメラのベクトルの座標を設定します。
1 |
GLKMatrix4 modelViewMatrix = GLKMatrix4MakeLookAt(eyeX, eyeY, eyeZ, targetX, targetY, targetZ, upX, upY, upZ); |
□ モデルビュー
頂点シェーダへ連携するためのモデルビューを算出します。
モデルビューは、カメラのプロジェクションとカメラの視点の情報を掛けあわせた情報です。
モデルビューの設定 p>
モデルビューの設定は、「GLKMatrix4Multiply」を利用します。
GLKMatrix4Multiplyは、行列の掛け算を行います。カメラのプロジェクション情報とカメラの視点情報を引数に渡します。
その後、頂点シェーダ側で頂点情報と掛け合わすことでカメラの視点になります。
1 |
GLKMatrix4 projection_modelview = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); |
□ 描画
頂点シェーダ内のデータアクセス
頂点シェーダ内のデータへアクセスするには、「glUniformMatrix4fv」を利用します。
これで、頂点シェーダが保持する「unif_pm」変数に外部からアクセスできるようになります。
1 2 3 4 5 6 7 |
attribute vec4 attr_pos; uniform mat4 unif_pm; void main() { gl_Position = unif_pm * attr_pos; } |
1 |
GLint unif_pm = glGetUniformLocation(_program, "unif_pm"); |
1 |
glUniformMatrix4fv(unif_pm, 1, GL_FALSE, projection_modelview.m); |
カメラの作成
□ カメラの作成
前の章で作成したrepercussionsプロジェクトに対して、以下のファイルを修正します。
・Shader.vsh
・GameViewController.m
変更箇所について解説します。
変更箇所は、背景を反転させています。
Shader.fsh
1 2 3 4 5 6 7 8 9 10 11 |
attribute vec4 attr_pos; attribute vec4 attr_color; uniform mat4 unif_pm; varying lowp vec4 vary_color; void main() { gl_Position = unif_pm * attr_pos; vary_color = attr_color; } |
カメラ情報は uniform で宣言した変数を利用します。uniform を宣言した unif_pm は、外部からカメラ情報を設定することができます。
※uniform は、attribute とは異なり宣言する数に制限があります。ご注意ください。
gl_Position は、頂点情報とカメラ情報を掛けあわせた情報を受け取ります。
GameViewController.m
1 2 3 4 5 6 7 8 9 10 11 12 |
@interface GameViewController () { // レンダリング用プログラムシェーダー GLuint _program; // 頂点バッファ GLuint vertices_buffer; // 頂点インデックス GLuint indices_buffer; // 視点 GLKMatrix4 projection_modelview; } |
描画時にOpenGLへ連携するモデルビューを宣言します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
- (void)setupGL { [EAGLContext setCurrentContext:self.context]; [self loadShaders]; // 板ポリゴン作成 { { // 頂点バッファ { …省略… } // 頂点インデックスバッファ { …省略… } } // カメラ初期化 { //カメラ範囲 float near = 0.0f; float far = 10.0f; // カメラ角度 float radian = 60.0f; // カメラ位置 float eyeX = 0.0f; float eyeY = 3.0f; float eyeZ = 3.0f; // ターゲット位置 float targetX = 0.0f; float targetY = 0.5f; float targetZ = 0.0f; // カメラベクトル float upX = 0.0f; float upY = -1.0f; float upZ = 0.0f; // カメラ初期値設定 float aspect = (GLfloat) self.view.bounds.size.width / (GLfloat) self.view.bounds.size.height; GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective( GLKMathDegreesToRadians(radian), aspect, near, far); GLKMatrix4 modelViewMatrix = GLKMatrix4MakeLookAt( eyeX, eyeY, eyeZ, targetX, targetY, targetZ, upX, upY, upZ); projection_modelview = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); } } } |
setupGLメソッドでは、カメラの初期化処理を追加します。
カメラの初期化は、カメラのプロジェクション、カメラ視点を設定し、そこからモデルビューを算出します。
カメラのプロジェクション、カメラ視点、モデルビューは、上記で説明した内容と同じです。
ここでの注意点は、カメラの設定には微調整が必要になることです。
カメラの向き、視点の範囲、距離などが適切に設定されないと対象物を見失うことになります。
例えるならば、カメラのファインダーと同じイメージです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect { glClearColor(0.2f, 0.2f, 0.2f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // シェーダー利用開始 glUseProgram(_program); assert(glGetError() == GL_NO_ERROR); // バッファバインド glBindBuffer(GL_ARRAY_BUFFER, vertices_buffer); // カメラ設定 { // シェーダのuniform変数取得 GLint unif_pm = glGetUniformLocation(_program, "unif_pm"); // カメラ指定 glUniformMatrix4fv(unif_pm, 1, GL_FALSE, projection_modelview.m); } // 頂点データ読み込み設定 { …省略… } // フラグメントデータ読み込み設定 { …省略… } // インデックスバッファバインド …省略… // シェーダー描画 …省略… } |
glkViewメソッドでは、頂点シェーダにカメラ情報を連携するための処理を追加します。
カメラの実行
シミュレータを起動すると、カメラ視点から眺めた板ポリゴンが画面に描画されます。
次回は、最終章です。
このカメラつき板ポリゴンに対して、時間に応じて高さを設定すると波紋が完成します。
バックナンバー
OpenGL ES2.0で波紋を作る#4 OpenGL ES を組み込むベースを作成
OpenGL ES2.0で波紋を作る#5 格子状の板ポリゴンを作る
OpenGL ES2.0で波紋を作る#6 カメラをつける