■ 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枚のポリゴンで円盤を描くことができます.もちろん,円盤に限らず複雑な形状を描くことができるので,ポリゴン数を減らしたいゲームなどでは多用されています.ただし,これにはテクスチャマッピングやアルファテストが十分高速なハードウェアを使用するという条件が付きますが.