切り抜き
アルファ値には、画像の合成の他にも使い道があります。前回、Photshop Elements の選択範囲を保存してアルファチャンネルを持った画像(RGBA 形式の画像)を作成しましたが、選択範囲を使って画像を切り抜けるのと同様に、アルファ値を使ってポリゴンを切り抜くことができます。
その前に
雛形のプログラムは、前回のままではとんでもない色使いになってしまっているので、一旦元に戻します。まず、GL_TEXTURE_ENV_MODE を GL_MODULATE に設定します。また、GL_MODULATE では GL_TEXTURE_ENV_COLOR で指定した色は参照されません。したがって次の変数 blend の宣言と、それを GL_TEXTURE_ENV_COLOR に設定している glTexEnvf() 関数を、#if 0 〜 #endif ではさんで1無効にしておきます。
/*
** 初期化
*/
static void init()
{
...
/* テクスチャ環境 */
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()
{
static const GLfloat color[] = { 1.0f, 1.0f, 1.0f, 1.0f }; /* 材質 (色) */
/* 材質の設定 */
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color);
アルファ値の比較関数
アルファテストは、画素のアルファ値をある値と比較し、その結果をもとにその画素を表示するか否かを決定します。アルファ値は 0〜1 の間の値を持ち、0 で透明、1 で不透明を表しますから、ここでは glAlphaFunc() を使って、アルファ値が 0.5 を超えていればその画素を表示し、超えていなければ非表示にすることにします。
/*
** 初期化
*/
static void init()
{
...
/* テクスチャ環境 */
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_GREATER,EQUAL,GL_GREATER, およびGL_ALWAYSがあります。
これは 2004 年の記事です。OpenGL (3.1以降 Core Profile) および OpenGL ES 2.0/3.0 以降では、
glAlphaFunc()関数は廃止されています。
複雑な外形のポリゴンが描ける
そして、図形を描画する前に、アルファテストを有効にしておきます。
/*
** シーンの描画
*/
static void scene()
{
static const GLfloat color[] = { 1.0f, 1.0f, 1.0f, 1.0f }; /* 材質 (色) */
/* 材質の設定 */
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枚のポリゴンで円盤を描くことができます。もちろん、円盤に限らず複雑な形状を描くことができるので、ポリゴン数を減らしたいゲームなどでは多用されています。ただし、これにはテクスチャマッピングやアルファテストが十分高速なハードウェアを使用するという条件が付きますが。
-
こういう方法は良くないと言われます。ちゃんとコメントにしましょう。 ↩