ビューポート
印刷作業
さて、モデルビュー、射影に続く最後の変換作業はビューポートです
ビューポートは、例えるならば撮影した映像の印刷作業と言えるでしょう
これまで、モデルビューは被写体、射影はカメラの設定のようなものでした
これらで決定された映像をどのように印刷するかがビューポートなのです
映像を証明写真とするか、巨大なポスターにするかは自由なのです
ただし、私たちが扱うのは印刷用紙ではなくコンピュータ グラフィックスです
そのため、ビューポートはウィンドウのサイズに合わせて描画されています
しかし、特定のサイズに固定したり、サイズを変更してスケーリングすることも自由です
ビューポートの設定は glViewport() 関数を使います
void glViewport(GLint x , GLint y , GLsizei width , GLsizei height);
x と y には、ビューポート方形の左下隅の座標を
width と height には幅と高さをそれぞれ指定します
デフォルトでは、X 座標、Y 座標共に 0、ウィンドウの幅と高さで描画されます
とくに、Windows 系の2次元グラフィックに慣れ親しんでいるユーザーは
方形の原点がウィンドウの左下隅であることに注意してください
しかし、ウィンドウを満たさないビューポートを描画した場合
再描画時に有効化されないウィンドウ領域が存在することになります
この問題は、どうやって解決することができるのでしょうか?
答えは簡単で、もう一度変換作業を行ってビューポートを設定すればよいのです
モデルビューからビューポートまでの一連の変換作業を1つのサイクルと考えてください
ビューポートを設定すれば、再び頂点の設定や変換を行って「撮影」することができるのです
すなわち、ひとつのウィンドウ領域に複数のビューポートを使って画面分割するのです
#include <windows.h>
#include <GL/gl.h>
#include <GL/glut.h>
const GLfloat vertex[] = {
-0.9 , 0.9 , 0.9 , 0.9 , 0 , -0.9 ,
-0.9 , -0.9 , 0.9 , -0.9 , 0 , 0.9
};
int width , height;
void disp( void ) {
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_POLYGON , 0 , 3);
glViewport(0 , height / 2 , width , height / 2);
glDrawArrays(GL_POLYGON , 3 , 3);
glViewport(0 , 0 , width , height / 2);
glFlush();
}
void reshape(int w , int h) {
width = w; height = h;
disp();
}
int main(int argc , char ** argv) {
glutInit(&argc , argv);
glutInitWindowPosition(100 , 50);
glutInitWindowSize(400 , 300);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
glutCreateWindow("Kitty on your lap");
glutDisplayFunc(disp);
glutReshapeFunc(reshape);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2 , GL_FLOAT , 0 , vertex);
glutMainLoop();
return 0;
}
このプログラムは、6つの頂点を三角形として表示するのではなく
異なる2つの画面として、ビューポートを分割して描画しています
最初の glViewport() 関数では、ウィンドウの中央より上に画面を描画し
その後に、もう一度設定を行い glViewport() で中央より下に異なる画面を描画しています
こうすれば、まったく異なる変換のオブジェクトを複数のビューポートを使って描画できるのです