■ 2004年09月16日 [OpenGL][テクスチャ] 第4回 アルファテスト
切り抜き
アルファ値には,画像の合成の他にも使い道があります.前回,Photshop Elements の選択範囲を保存してアルファチャンネルを持った画像(RGBA 形式の画像)を作成しましたが,選択範囲を使って画像を切り抜けるのと同様に,アルファ値を使ってポリゴンを切り抜くことができます.
その前に
雛形のプログラムは,前回のままではとんでもない色使いになってしまっているので,一旦元に戻します.まず,GL_TEXTURE_ENV_MODE を GL_MODULATE に設定します.また,GL_MODULATE では GL_TEXTURE_ENV_COLOR で指定した色は参照されません.したがって次の変数 blend の宣言と,それを GL_TEXTURE_ENV_COLOR に設定している glTexEnvf() 関数を,#if 0 〜 #endif ではさんで無効にしておきます.
・・・ /* ** 初期化 */ static void init(void) { ・・・ /* テクスチャ環境 */ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); #if 0 /* 混合する色の設定 */ static const GLfloat blend[] = { 0.0, 1.0, 0.0, 1.0 }; glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, blend); #endif ・・・
次に,下地のポリゴンの材質も,もとの白色に戻しておきましょう.
・・・ /* ** シーンの描画 */ static void scene(void) { static const GLfloat color[] = { 1.0, 1.0, 1.0, 1.0 }; /* 材質 (色) */ /* 材質の設定 */ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color); ・・・
アルファ値の比較関数
アルファテストは,画素のアルファ値をある値と比較し,その結果をもとにその画素を表示するか否かを決定します.アルファ値は 0〜1 の間の値を持ち,0 で透明,1 で不透明を表しますから,ここではアルファ値が 0.5 を超えていればその画素を表示し,超えていなければ非表示にすることにします.
・・・ /* テクスチャ環境 */ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); #if 0 /* 混合する色の設定 */ static const GLfloat blend[] = { 0.0, 1.0, 0.0, 1.0 }; glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, blend); #endif /* アルファテストの比較関数 */ glAlphaFunc(GL_GREATER, 0.5); ・・・
- void glAlphaFunc(GLenum func, GLclampf ref)
- アルファ値の比較関数を設定します.引数 func には比較関数を示す定数値,ref には比較の対象となる値(しきい値)を 0〜1 の値で設定します.func に指定できる値には GL_NEVER, GL_LESS, GL_LEQUAL, GL_EQUAL, GL_NOTEQUAL, GL_GEQUAL, GL_GREATER, および GL_ALWAYS があります.
複雑な外形のポリゴンが描ける
そして,図形を描画する前に,アルファテストを有効にしておきます.
・・・ /* ** シーンの描画 */ static void scene(void) { static const GLfloat color[] = { 1.0, 1.0, 1.0, 1.0 }; /* 材質 (色) */ /* 材質の設定 */ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color); /* アルファテスト開始 */ glEnable(GL_ALPHA_TEST); /* テクスチャマッピング開始 */ glEnable(GL_TEXTURE_2D); /* 1枚の4角形を描く */ glNormal3d(0.0, 0.0, 1.0); glBegin(GL_QUADS); glTexCoord2d(0.0, 1.0); glVertex3d(-1.0, -1.0, 0.0); glTexCoord2d(1.0, 1.0); glVertex3d( 1.0, -1.0, 0.0); glTexCoord2d(1.0, 0.0); glVertex3d( 1.0, 1.0, 0.0); glTexCoord2d(0.0, 0.0); glVertex3d(-1.0, 1.0, 0.0); glEnd(); /* テクスチャマッピング終了 */ glDisable(GL_TEXTURE_2D); /* アルファテスト終了 */ glDisable(GL_ALPHA_TEST); } ・・・
すると,こんな具合にポリゴンが抜けます.
ということで,複数のポリゴンを組み合わせなくても,1枚のポリゴンで円盤を描くことができます.もちろん,円盤に限らず複雑な形状を描くことができるので,ポリゴン数を減らしたいゲームなどでは多用されています.ただし,これにはテクスチャマッピングやアルファテストが十分高速なハードウェアを使用するという条件が付きますが.