■ 2005年07月04日 [OpenGL][テクスチャ] 第23回 放物面マッピングと他のテクスチャとの合成
環境のテクスチャを最下層に置いたとき
放物面マッピングでは映り込みのテクスチャを不透明にする必要があったので,そのテクスチャを最下層に置きました.今回は,そのテクスチャと,その上に重ねたテクスチャとの合成を行ってみます.
テクスチャユニットを指定したテクスチャ座標の設定
前回作成したプログラムでは,もともとあったテクスチャを,テクスチャユニット2 (GL_TEXTURE2) に割り当てています.ただし,このテクスチャは,実際には使用していませんでした.
また,box.cpp で定義している立方体を描く関数 box() では,glTexCoord2dv() を使って各面に貼るテクスチャのテクスチャ座標を設定しています.この関数はデフォルトのテクスチャユニット,すなわちテクスチャユニット0 (GL_TEXTURE0) に対してテクスチャ座標を設定することができますが,テクスチャユニット2に割り当てたテクスチャに対してテクスチャ座標を設定することはできません.
glMultiTexCoord2dv()
特定のテクスチャユニットに対してテクスチャ座標を設定するには,glMultiTexCoord*() という関数群を使います.この関数も Windows の gl.h では宣言されていないので,Windows でこの関数を使用する場合は,glMultiTexCoord2dv() の関数ポインタ変数の宣言を main.cpp に追加する必要があります.
#include <stdio.h> #include <stdlib.h> #include <math.h> #if defined(WIN32) //# pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"") # include "glut.h" # include "glext.h" PFNGLACTIVETEXTUREPROC glActiveTexture; PFNGLMULTITEXCOORD2DVPROC glMultiTexCoord2dv; #elif defined(__APPLE__) || defined(MACOSX) # include <GLUT/glut.h> #else # include <GL/glut.h> #endif ・・・
そしてプログラムの初期化時に,この関数ポインタ変数に関数の実体のエントリポイントを格納しておきます.
・・・ /* 各テクスチャユニット用にテクスチャオブジェクトを作る */ GLuint texname[3]; glGenTextures(3, texname); #if defined(WIN32) glActiveTexture = (PFNGLACTIVETEXTUREPROC)wglGetProcAddress("glActiveTexture"); glMultiTexCoord2dv = (PFNGLMULTITEXCOORD2DVPROC)wglGetProcAddress("glMultiTexCoord2dv"); #endif /* 裏面の放物面テクスチャのマッピングに使うテクスチャユニット */ glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texname[0]); ・・・
このほか,シーンを描画する際はテクスチャユニット2によるテクスチャマッピングを有効にしておきます.
・・・ /* ** シーンの描画 */ static void scene(void) { ・・・ #if 1 /* テクスチャマッピング開始 */ glActiveTexture(GL_TEXTURE2); glEnable(GL_TEXTURE_2D); #endif /* トラックボール処理による回転 */ glMultMatrixd(trackballRotation()); /* 箱を描く */ box(1.0, 1.0, 1.0); #if 1 /* テクスチャマッピング終了 */ glDisable(GL_TEXTURE_2D); #endif ・・・
一方 box.cpp も,テクスチャ座標を glTexCoord2dv() を使って設定している部分を glMultiTexCoord2dv() に置き換えます.Windows の場合は関数ポインタ変数 glTexCoord2dv を外部変数として宣言しておいてください.
#if defined(WIN32) # include "glut.h" # include "glext.h" extern PFNGLMULTITEXCOORD2DVPROC glMultiTexCoord2dv; #elif defined(__APPLE__) || defined(MACOSX) # include <GLUT/glut.h> #else # include <GL/glut.h> #endif ・・・ /* 四角形6枚で箱を描く */ glBegin(GL_QUADS); for (j = 0; j < 6; ++j) { glNormal3dv(normal[j]); for (i = 0; i < 4; ++i) { /* テクスチャ座標の指定 */ glMultiTexCoord2dv(GL_TEXTURE2, texcoord[j][i]); /* 対応する頂点座標の指定 */ glVertex3dv(vertex[j][i]); } } glEnd(); }
もちろん,テクスチャ環境の GL_MODULATE を GL_COMBINE に置き換えて,線形補間によるテクスチャの合成を行うこともできます.
・・・ /* テクスチャ環境 */ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE); static const GLfloat blend[] = { 1.0, 1.0, 1.0, 0.5 }; glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, blend); /* 初期設定 */ glClearColor(0.3, 0.3, 1.0, 0.0); glEnable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); ・・・