このプログラムは、OpenGL における「テクスチャマッピング (Texture Mapping)」の基礎を学ぶための、学生向けのサンプルプログラムです。本プログラムは、以下のブログ記事の解説に沿って学習を進めるための雛形として提供されています。
今回はテクスチャマッピングにおいて、物体の表面に周囲の情景が映りこむようにマッピングする方法について学びます。このようなテクスチャマッピングを環境マッピングといい、キューブマッピングはその手法の一つです。
プログラムを実行すると、周囲の情景が映り込んだティーポットが表示されます。スフィアマッピングでは、周囲の情景の画像を1枚のテクスチャとして扱い、それをティーポットにマッピングしていました。キューブマッピングでは、周囲の情景の画像を6方向の面(正六面体)にそれぞれマッピングすることで、キューブマッピングを実現します。マウスのドラッグでティーポットを回転することができます。
このプログラムは CMake を用いてビルドを構成しています。各プラットフォームごとの手順は以下の通りです。なお、プログラムをビルドするためのバイナリディレクトリは、バージョン管理ファイル(.gitignore)の設定に合わせて build という名前にします。
-
コマンドプロンプトまたは PowerShell を開き、このプロジェクトのディレクトリに移動します。
-
以下のコマンドを実行してビルドディレクトリを作成し、CMake で構成を行います。
mkdir build
cd build
cmake .. -G "Visual Studio 17 2022"-
生成された build フォルダ内の texture7.sln を Visual Studio で開きます。
-
ソリューションエクスプローラーで texture7 プロジェクトを右クリックし、「スタートアップ プロジェクトに設定」を選択します。
-
「ローカル Windows デバッガー」をクリックするか、F5 キーを押してビルドおよび実行します。
-
ターミナルを開き、このプロジェクトのディレクトリに移動します。
-
以下のコマンドを実行してビルドディレクトリを作成し、Xcode 用のプロジェクトを生成します。
mkdir build
cd build
cmake .. -G Xcode-
生成された build/texture7.xcodeproj を Xcode で開きます。
-
左上のスキーム選択(再生ボタンの横)が texture7 になっていることを確認します。
-
「Run」ボタン(再生ボタン)をクリックするか、Command + R を押してビルドおよび実行します。
-
ターミナルを開き、このプロジェクトのディレクトリに移動します。
-
必要なパッケージ(freeglut3-dev や pkg-config など)がインストールされていることを確認し、以下のコマンドでビルドします。
mkdir build
cd build
cmake ..
make各OSとも、ビルド後に生成されるバイナリディレクトリ (build) やそのサブフォルダから起動します。(※ CMake の設定により、Windows や Xcode では Debug などのフォルダ下に実行ファイルが置かれることがあります)
- Windows
Visual Studio 上で「ローカル Windows デバッガー」をクリックして実行するか、またはコマンドプロンプトから以下のコマンドで起動します。
cd build\Debug
texture7.exe- macOS
Xcode 上で左上の「Run(再生ボタン)」をクリックするのが楽です。これにより texture7.app アプリケーションバンドルとして自動的に実行されます。アプリケーションバンドルを直接起動するなら、Finder から build/Debug/texture7.app をダブルクリックするか、ターミナルから open build/Debug/texture7.app を実行します (この場合はエラーメッセージ等が表示されません)。
- Ubuntu Linux
ターミナルから以下のコマンドで実行ファイル(バイナリ)を直接起動します。
cd build
./texture7-
マウスの左ボタンでドラッグ: 表示されている**オブジェクト(ティーポット)**を3次元的に回転させることができます。回転に伴い、ティーポット表面に映り込んだ周囲の情景(環境マップ)も変化します。
-
キーボードの q, Q または ESC キー: プログラムを終了します。
このプログラムでは、テクスチャ座標の自動生成機能 (GL_REFLECTION_MAP) を用いることで、**物体の表面に周囲の情景が映り込んでいるように見えるキューブマッピング(環境マッピング)**を実現しています。
環境マッピングを行うためには、視点ベクトルと物体表面の法線ベクトルから反射ベクトルを計算し、その反射ベクトルに基づいて環境マップ(テクスチャ)上の座標を決定する必要があります。
OpenGL では、テクスチャ座標の自動生成モードとして GL_REFLECTION_MAP を指定することで、この計算を自動的に行い、3次元のテクスチャ座標
/* キューブマッピング用のテクスチャ座標を生成する */
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);オブジェクト(今回はティーポット)を描画する前に、キューブマップテクスチャを有効にし、3つのテクスチャ座標の自動生成を有効にします。
/* テクスチャマッピング開始 */
glEnable(GL_TEXTURE_CUBE_MAP);
/* テクスチャ座標の自動生成を有効にする */
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_TEXTURE_GEN_R);
/* ティーポットを描く */
glutSolidTeapot(1.0);
/* テクスチャ座標の自動生成を無効にする */
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glDisable(GL_TEXTURE_GEN_R);
/* テクスチャマッピング終了 */
glDisable(GL_TEXTURE_CUBE_MAP);これにより、ティーポットの各頂点に対してキューブマッピング用のテクスチャ座標
キューブマッピング GL_REFLECTION_MAP で生成した3次元のテクスチャ座標に対しても座標変換を行うことができます。スフィアマッピングでは視線を軸とした回転以外は正常にマッピングされませんでしたが、キューブマッピングでは任意の方向への回転が可能です。試しに /* トラックボール処理で図形を回転 */ のところの glMultMatrixd() をコメントアウトし、 /* トラックボール処理でテクスチャを回転 */ のところの glMultMatrixd() のコメントアウトを外して実行してみてください。ティーポット自体は回転せずに、周囲の映り込み(環境マップ)だけが回転するようになります。
/* トラックボール処理で図形を回転 */
glMultMatrixd(trackballRotation());
/* テクスチャ行列の設定 */
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
/* トラックボール処理でテクスチャを回転 */
//glMultMatrixd(trackballRotation());