テクスチャマッピング
概要
テクスチャマッピングは、3D物体(ポリゴン)の表面の質感を表現するために、にテクスチャ(画像)を貼付けること。
貼り付ける物体形状とテクスチャの形状は一致している必要はありません。
貼り付ける物体形状とテクスチャの形状は一致している必要はありません。
大まかな手順は次のとおりです。
- テクスチャとなる画像配列の準備
- テクスチャ作成:画像配列をテクスチャバッファへ格納
- ポリゴンへテクスチャを貼付け
画像配列は、RGBRGBRGB…とならんだデータのことです。
data[0] = Rデータ0
data[1] = Gデータ0
data[2] = Bデータ0
data[3] = Rデータ1
data[4] = Gデータ1
data[5] = Bデータ1
…
OpenGLではBMPやJPEGなどから画像配列を取り出す機能は持ち合わせていませんので、変換処理する機構はユーザが任意に用意する必要があります。
data[0] = Rデータ0
data[1] = Gデータ0
data[2] = Bデータ0
data[3] = Rデータ1
data[4] = Gデータ1
data[5] = Bデータ1
…
OpenGLではBMPやJPEGなどから画像配列を取り出す機能は持ち合わせていませんので、変換処理する機構はユーザが任意に用意する必要があります。
テクスチャバッファへの格納は次の手順で行います。
glGenTextures // テクスチャオブジェクト生成 ↓ glBindTexture // テクスチャオブジェクト(アプリケーション側)とテクスチャバッファ(サーバー側)との対応付け ↓ glTexImage2D // 対応付けたテクスチャバッファへ画像配列を転送
ここでは設定もろもろ説明を省いています。
テクスチャの貼付けは、2種類の座標、テクスチャ座標と頂点座標とを関連付けることで行ないます。
たとえば、次のようになります。
たとえば、次のようになります。
glBegin(GL_QUADS);
glTexCoord2d(0.0, 1.0); glVertex2d(-1,1,0);
glTexCoord2d(0.0, 0.0); glVertex2d(-1,-1,0);
glTexCoord2d(1.0, 0.0); glVertex2d(1,-1,0);
glTexCoord2d(1.0, 1.0); glVertex2d(1,1,0);
glEnd();
詳細
サンプルコードの一部を抜粋します。
GLuint texture;
void initializeGL()
{
GLubyte pixels[Width*Height*3];
// 画像データ読み込み
…
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
// テクスチャオブジェクト作成
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D,texture);
// 拡大縮小について設定
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// テクスチャの繰り返し設定
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// テクスチャバッファへ画像配列を転送
glTexImage2D(
GL_TEXTURE_2D, // target
0, // level
3, // internalFormat
Width, // 画像横サイズ
Height, // 画像縦サイズ
0, // border
GL_RGB, // 画像の形式
GL_UNSIGNED_BYTE, // データ型
pixels // 画像配列へのポインタ
);
glBindTexture(GL_TEXTURE_2D,0);
}
void paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//モデル・ビュー・マトリックス設定
glMatrixMode (GL_MODELVIEW);
glLoadIdentity();
//カメラ設定
gluLookAt(3.0, 4.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glPushMatrix();
{ // 平面表示
GLfloat color[] = { 1.0, 1.0, 1.0, 1.0 };
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
glBegin(GL_QUADS);
glNormal3f(0.0, 1.0, 0.0);
glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, 0.0, -1.0);
glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, 0.0, 1.0);
glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, 0.0, 1.0);
glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, 0.0, -1.0);
glEnd();
glDisable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
}
glPopMatrix();
}
まとめ
テクスチャマッピング自体は、それほど難しくありません。
少しハードルを高くしている原因は画像の読み込みではないでしょうか。
C言語(GLUT)では、標準で画像を読み込む機構がないので画像を配列に変換する作業が面倒です。
OpenGLのユーティリティツールとしてあればよいのですが。。。
少しハードルを高くしている原因は画像の読み込みではないでしょうか。
C言語(GLUT)では、標準で画像を読み込む機構がないので画像を配列に変換する作業が面倒です。
OpenGLのユーティリティツールとしてあればよいのですが。。。
テクスチャに関するその他の技術
- ミップマップ
- テクスチャ座標自動生成
- キューブマッピング
- 環境マッピング
- マルチテクスチャ