[OpenGL] 射影変換
概念
Viewing,ここで説明することは投視変換とViewport処理です.ちょっとややこしく感じるかもしれませんが,知っておくと細かくOpenGLを処理することが可能です.
射影変換とViewportの概念は下のようになります.

簡単に説明すると,プログラム上では,3次元上でものを書き,それをカメラで写し(射影変換),それをウィンドウに貼り付ける(Viewport変換),といった手続きになります.
これらの処理は描画コードが実行されるまでに処理しておきます.当然,初期化時以外にも変更することは可能です.
これらの一連の処理は知らなくても大体のプログラミングは可能ですが,どこかで必要になります.
それでは説明していきます.
射影変換
簡単には2種類の射影変換が存在します.

正射影
この射影変換にすると,遠くのものも近くのものも同じ大きさになります.この方法では完全に遠近感が消えてしまいます.3DCGモデリングや,CADなどのアプリケーションのウィンドウなどによく使われます.なぜならどこまで,奥にあったとしても手前の座標と大きさが変わらないからです.
投視射影
これはよくあるカメラや,人間の目の役割とよく似ています.我々の視覚と同じく,遠近感があり遠くにあるものは小さく,近くにあるものは大きく見えます.通常の3Dゲームなどはこの形式で描画されます.人が見たような情景を再現したいのですから当然です.
図にあるように水色で示した部分を”視体積”と呼びます.視体積に含まれる部分だけが見える,つまり描画されるわけです.つまり,射影変換をOpenGL上で設定するということはこの視体積を設定することに他なりません.
その設定方法ですが,OpenGLのAPIで一発で指定できます.OpenGLではすべての射影変換,オブジェクトなどの位置,姿勢は行列計算で行います.そして,その行列計算にはふたつのモードがあります.Model Viewモード,Projectionモードです.
かなり強引に説明すると,ModelViewモードが射影変換を行う前の3次元上でオブジェクトを描画するときに平行移動,回転などを行うときの行列計算モードで,Projectionモードが射影変換を行うときの行列計算モードとなります.
行列計算というと,高等数学のイメージがつきまといますが,実際には良く知らなくても使うことはできます.当然,よく知らなければ,OpenGLを使いこなすことはできませんし,より高度な処理などは不可能です.しかし,平行移動,回転などの行列計算はOpenGLのAPIで一発でできます.
この行列計算については他のセクションで言及します.
射影変換のコーディング
先に結論を書いてしまいましょう.
// プロジェクションモードへ移行 glMatrixMode( GL_PROJECTION ); glLoadIdentity(); gluPerspective( 60.0, 4.0f/3.0f, 1.0, 10.0 ); // モデルビューモードへ移行 glMatrixMode( GL_MODELVIEW );
これで視野角60度,アスペクト比4:3,視体積の手前の平面までの距離が1,奥の平面までの距離が10という設定になります.アスペクト比とは横:縦の値のことです.
これらの値は下の図のようになります.

この他に,glFrsutum()というAPIもあります.こちらのAPIは細かく設定する必要がある分,かなり強力なAPIです.ここでは簡単にということでこのAPIの説明はしません.リファレンスなどを参考にしてください.
Viewport
Viewportはもっと簡単です.射影変換後の描画結果をウィンドウに貼り付けるときにどう貼り付けるかを設定します.実際にはこんなコーディングになります.
// ビューポートを設定 glViewport( x, y, h, w);
イメージはこんな感じです.どうでしょうか?つまり,射影変換後の描画結果のアスペクト比とウィンドウに貼り付けるときのアスペクト比をうまく調節してやらないと,歪んだ結果となってしまいます.Viewportを設定するタイミングはまず,初期化時,つづいてウィンドウのサイズを変更したときには必ず再設定する必要があります.なぜなら再設定しないと前のウィンドウサイズのままViewportを使用してしまう結果になるからです.

ここでは設定の意味などに重点を絞りました.実際のコーディングについてはOSによる初期化のセクションで言及したいと思います.