このプログラムは、OpenGL における「テクスチャマッピング (Texture Mapping)」の基礎を学ぶための、学生向けのサンプルプログラムです。本プログラムは、以下のブログ記事の解説に沿って学習を進めるための雛形として提供されています。
今回は通常のテクスチャマッピングとは少し異なり、スライドプロジェクターやスポットライトで物体に画像を投影するようにマッピングする、テクスチャ投影 (Projective Texture Mapping) という手法を実装します。プログラムを実行すると、テクスチャが立方体に投影されながらアニメーションする様子を観察できます。
このプログラムは CMake を用いてビルドを構成しています。各プラットフォームごとの手順は以下の通りです。なお、プログラムをビルドするためのバイナリディレクトリは、バージョン管理ファイル(.gitignore)の設定に合わせて build という名前にします。
-
コマンドプロンプトまたは PowerShell を開き、このプロジェクトのディレクトリに移動します。
-
以下のコマンドを実行してビルドディレクトリを作成し、CMake で構成を行います。
mkdir build cd build cmake .. -G "Visual Studio 17 2022"
-
生成された build フォルダ内の texture2.sln を Visual Studio で開きます。
-
ソリューションエクスプローラーで texture2 プロジェクトを右クリックし、「スタートアップ プロジェクトに設定」を選択します。
-
「ローカル Windows デバッガー」をクリックするか、F5 キーを押してビルドおよび実行します。
-
ターミナルを開き、このプロジェクトのディレクトリに移動します。
-
以下のコマンドを実行してビルドディレクトリを作成し、Xcode 用のプロジェクトを生成します。
mkdir build cd build cmake .. -G Xcode -
生成された build/texture2.xcodeproj を Xcode で開きます。
-
左上のスキーム選択(再生ボタンの横)が texture2 になっていることを確認します。
-
「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 texture2.exe -
macOS
Xcode 上で左上の「Run(再生ボタン)」をクリックするのが楽です。これにより texture2.app アプリケーションバンドルとして自動的に実行されます。アプリケーションバンドルを直接起動するなら、Finder から build/Debug/texture2.app をダブルクリックするか、ターミナルから open build/Debug/texture2.app を実行します (この場合はエラーメッセージ等が表示されません)。
-
Ubuntu Linux
ターミナルから以下のコマンドで実行ファイル(バイナリ)を直接起動します。
cd build ./texture2
-
マウスの左ボタンでドラッグ
投影されるテクスチャの向き(仮想的なプロジェクターの方向)を3次元的に回転させることができます。(以前は物体自体を回転させていましたが、今回はテクスチャを回転させるように変更されています)
-
キーボードの q, Q または ESC キー
プログラムを終了します。
このプログラムは、画像を 3D 空間の物体に投影して貼り付ける処理を行っています。プログラムの主要な処理手順とアルゴリズムは以下の通りです。
- プログラム起動時、
init()関数内で RAW 形式の画像ファイル(tire.raw)を読み込み、配列に格納します。 - 読み込んだ画像データを
glTexImage2D()関数を使って OpenGL のシステム(GPU)に転送します。 glTexParameteri()を使って、画像を引き伸ばしたときの補間方法(滑らかにする処理)や、画像の端の扱い方(GL_CLAMP_TO_EDGE:端の色を延長する)を設定します。
- 通常のテクスチャマッピングでは、画像の縦横を
0.0から1.0までの 2D 座標(U, V 座標)で指定します。 - しかし、このプログラムの
box()関数では、glTexCoord3dv()という関数を使い、物体の頂点の 3D 座標(X, Y, Z)をそのままテクスチャ座標として割り当てています。 - この段階ではまだ画像は正しく貼り付けられず、3D 空間の座標系とテクスチャの座標系が直接結びついた状態になります。
display()関数の前半でglMatrixMode(GL_MODELVIEW)を呼び出し、通常の空間(カメラや物体)の設定を行います。gluLookAt()を用いて、箱を斜め上(1.5, 2.0, 2.5)の位置から原点に向かって見下ろすようにカメラ(視点)を配置しています。- 今回のプログラムでは、モデルビュー行列に対するトラックボール(マウス)の回転処理はコメントアウトされており、物体(箱)自体は空間内に固定された状態になっています。
- 次に、
glMatrixMode(GL_TEXTURE)を呼び出して「テクスチャ行列」を操作するモードに切り替えます。テクスチャ行列を使うと、指定したテクスチャ座標に対して移動や回転などの変換をかけることができます。 - ここで、カメラの位置を決める
gluLookAt()と、遠近感を計算する透視投影のgluPerspective()を呼び出します。これにより、「仮想的なプロジェクター」を 3D 空間に配置し、そこから画像を投影する計算が行われます。 - さらに、マウス操作による
trackballRotation()をテクスチャ行列に適用することで、マウスのドラッグ操作で「プロジェクターから投影されるテクスチャの向き」を回転させることができるようになっています。 - 投影計算の結果として得られる座標は -1.0 から 1.0 の範囲になりますが、テクスチャ画像は 0.0 から 1.0 の範囲で扱う必要があるため、
glScaled(0.5, 0.5, 1.0)とglTranslated(0.5, 0.5, 0.0)を使って座標の範囲を半分に縮小し、ずらす処理を行っています。 - また、時間経過 (
t) に応じたglRotated()による回転も加わっており、投影される画像が回転アニメーションする様子も観察できます。 - これらの設定が終わった後、
scene()関数を呼び出して物体(箱)を描画します。この結果、設定された「テクスチャプロジェクター」から投影された模様が、箱の表面に浮かび上がって画面に表示されます。
