投影マップ(ProjectionMap)

SAMPLE https://www.dropbox.com/s/wd1848kxtx6fb6a/projectionmap.exe( 投影マップ ) 画面に投影されるようなテクスチャ座標を計算するには 通常のオブジェクトの変換と同じ工程を使う。 モデルビュー、プロジェクション、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(); }