SAMPLE
投影マップ
画面に投影されるようなテクスチャ座標を計算するには
通常のオブジェクトの変換と同じ工程を使う。
モデルビュー、プロジェクション、w除算された頂点座標は
画面に対して [ -1 1 ] の範囲に収まる。
これをさらに [ 0 1 ] の範囲にずらせば画面に投影されるテクスチャ座標が求まる。
POINT
2次元テクスチャ座標は u, v の2つを指定するが、
投影マップの場合はw除算の処理が必要なため、w成分( GL_Q )も求めて置く必要がある。
Z成分( GL_T )の値は求める必要はない。
#define W 1024
#define H 512
App::onDraw() {
// UVの変換行列を合成する
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.5f, 0.5f, 0.5f);
glScalef(0.5f, 0.5f, 0.5f);
gluPerspective(60.0, (float)W/H, 1.0, 2000.0);
gluLookAt( n, n, n, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
// 合成された変換行列を取得する。
float m[16];
glGetFloatv(GL_MODELVIEW_MATRIX, m );
// UVの自動生成を有効化する。
glEnable( GL_TEXTURE_GEN_S );
glEnable( GL_TEXTURE_GEN_T );
glEnable( GL_TEXTURE_GEN_R ); // おまけ
glEnable( GL_TEXTURE_GEN_Q );
// 自動生成の計算式にオブジェクト空間の頂点座標を使う。
glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
// 線形結合する式の係数を並べておく。
float vs[] = { m[0], m[4], m[8], m[12] };
float vt[] = { m[1], m[5], m[9], m[13] };
float vr[] = { m[2], m[6], m[10], m[14] };
float vq[] = { m[3], m[7], m[11], m[15] };
// 合成した変換行列をオブジェクトの頂点に掛ければ画面を覆うようにUVが計算される。
glTexGenfv( GL_S, GL_OBJECT_PLANE, vs );
glTexGenfv( GL_T, GL_OBJECT_PLANE, vt );
glTexGenfv( GL_R, GL_OBJECT_PLANE, vr );
glTexGenfv( GL_Q, GL_OBJECT_PLANE, vq );
// 投影したいテクスチャをバインドする
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, id );
// モデルビュープロジェクション変換を設定する。
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluPerspective(60.0, (float)W/H, 1.0, 2000.0);
gluLookAt( n, n, n, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
// 平面を描画する。
// UVは自動で計算されるので座標は明示( glTexCoord() )しない。
drawPlane();
}