今回、setCornMaerialのmaterial_amb、material_dif、material_spec三兄弟のα値を変更してみます。
α値って何?な人は「iPhoneアプリ開発、その(38)」を参照。
いっせいに変えたいので
てしました。
これだと、α値は0.5ということで、半透明の円錐表示を期待~。
変わらない。
どーせまたglEnableがらみだろう。
てなわけでglEnable(GL_TEXTURE_2D)のGL_TEXTURE_2Dを選んでからコンテキストメニュー「定義へジャンプ」だ!
コンテキストメニューについては「iPhoneアプリ開発、その(33)」を参照。
すると
ていう、それっぽい定義があるんで、リファレンスページでglEnableを見てみると
GL_BLEND
α値を使って書き込む先の画像と書き込む画像を合成する。glBlendFuncも見てね。
GL_ALPHA_TEST
α値をテストする。 glAlphaFuncも見てね。
ということで、さらに探ると
glBlendFunc
ブレンド方法を設定する。
sfactor
合成元の値をどのくらいの比率で利用するかの指定。初期値はGL_ONE
dfactor
合成先の値をどのくらいの比率で利用するかの指定。初期値はGL_ZERO
なんてのがあるわけですわ。
この初期値だと元画像で完全に置き換わるので、GL_BLENDをglEnableしても変化はしませんな。
じゃ、何を指定すればいいかというと
例えば合成元画像のα値の比率で合成元画像と合成先画像を合成するなら
てとこでしょう。
それぞれリファレンスページで、どう説明されているかというと
GL_SRC_ALPHA
浮動小数点指定ならα値そのまま。整数値指定ならα値をα値がとりうる最大値で割ったもの。もしα値が8ビットなら0~255の整数値をとりうるので、α値=10なら10/255となり0.039...という値に変換される。
といった内容の話が書かれてます。
ちなみにドキュメント読んだ人にだけ言うけどkc = 2mc - 1って、2^mc(2の階乗)の書き違いじゃね?8ビットなら0~255。普通そうだろ。気になってOpenGL ES 1.1.12 Full Specification調べてみたけど、そもそも整数での話省略してた。というか、こっちの説明の方がわかりやすいぞ。
GL_ONE_MINUS_SRC_ALPHA
1.0 - GL_SRC_ALPHAの値
最終的な値は、赤色要素で説明すると
で計算され、この値が
を越えるなら1.0に切り捨てる。そんな感じっす。
さっそくGL_BLENDを試してみましょう。
てやって、うりゃ!
おお、なんか半透明っぽい。
う、薄いっ。
でも、じっと見てると裏側の透け方が変なんだよね。
裏側が出ない場合が...
て、そうかZバッファで隠面消去してるからだわ。
glDrawArraysでGL_TRIANGLE_FANしてるんで順に平面が描かれていくんだけど、描き始めの平面が表に出てる場合、その裏で隠された平面は表示されてないとみなされて、合成作業までいってくれないわけだ。
描き始めの位置が重要。
んじゃ深度チェック
しなければいいんじゃね?
でも、深度チェックしないと、不透明物体との前後関係がわからなくならない?
試しにテクスチャ付き円錐の後側に不透明の灰色円錐を置いて描画してみた。
灰色の円錐の方は当然深度チェックしている。
やっぱ、微妙ですわ。
で、もうちょっと調べると
というのを発見。不透明物体と透明物体を描く場合は、こっちを使うべきか?
おお、めりこんでる。
ただし、灰色の円錐を描いてからでないと、どっちも効果ないっす。
あたりまえ。
ここらへんの描画順はアプリケーション側が面倒見ないと駄目みたい。
でもって、GL_ALPHA_TESTで紹介されたAPIはというと...
glAlphaFunc
α値を表示するかどうかのフラグに使う。
func
元画像のα値を使ってどう判断するかの指定。初期値はGL_ALWAYS。
ref
0.0~1.0の範囲で指定。初期値は0.0。
例えば、上のfuncでGL_GREATERと指定された場合、
の比較がおこなわれる。これが成り立つ場合、表示され、成り立たなければ表示されない。
ものは試しにし、αマスク付きPNG作って指定してみます。
こんなやつ。
で、以下のように設定して呼び出し。
うりゃ。
おお~、なんか面白い。
んじゃ、これは
うりゃ!
って、なんか予想してたのと違うのきた~。
以下次回。
------------
サンプルプロジェクト:es9.zip
α値って何?な人は「iPhoneアプリ開発、その(38)」を参照。
いっせいに変えたいので
#define TEXTURE_ALPHA 0.5f
・
・
GLfloat material_amb[4]={0.4f, 0.4f, 0.4f, TEXTURE_ALPHA};
GLfloat material_dif[4]={1.0f, 1.0f, 1.0f, TEXTURE_ALPHA};
GLfloat material_spec[4]={0.5f, 0.5f, 0.5f, TEXTURE_ALPHA};
てしました。
これだと、α値は0.5ということで、半透明の円錐表示を期待~。
変わらない。
どーせまたglEnableがらみだろう。
てなわけでglEnable(GL_TEXTURE_2D)のGL_TEXTURE_2Dを選んでからコンテキストメニュー「定義へジャンプ」だ!
コンテキストメニューについては「iPhoneアプリ開発、その(33)」を参照。
すると
GL_ALPHA_TEST
GL_BLEND
ていう、それっぽい定義があるんで、リファレンスページでglEnableを見てみると
GL_BLEND
α値を使って書き込む先の画像と書き込む画像を合成する。glBlendFuncも見てね。
GL_ALPHA_TEST
α値をテストする。 glAlphaFuncも見てね。
ということで、さらに探ると
glBlendFunc
ブレンド方法を設定する。
void glBlendFunc(
GLenum sfactor,
GLenum dfactor);
sfactor
合成元の値をどのくらいの比率で利用するかの指定。初期値はGL_ONE
dfactor
合成先の値をどのくらいの比率で利用するかの指定。初期値はGL_ZERO
なんてのがあるわけですわ。
この初期値だと元画像で完全に置き換わるので、GL_BLENDをglEnableしても変化はしませんな。
じゃ、何を指定すればいいかというと
例えば合成元画像のα値の比率で合成元画像と合成先画像を合成するなら
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
てとこでしょう。
それぞれリファレンスページで、どう説明されているかというと
GL_SRC_ALPHA
浮動小数点指定ならα値そのまま。整数値指定ならα値をα値がとりうる最大値で割ったもの。もしα値が8ビットなら0~255の整数値をとりうるので、α値=10なら10/255となり0.039...という値に変換される。
といった内容の話が書かれてます。
ちなみにドキュメント読んだ人にだけ言うけどkc = 2mc - 1って、2^mc(2の階乗)の書き違いじゃね?8ビットなら0~255。普通そうだろ。気になってOpenGL ES 1.1.12 Full Specification調べてみたけど、そもそも整数での話省略してた。というか、こっちの説明の方がわかりやすいぞ。
GL_ONE_MINUS_SRC_ALPHA
1.0 - GL_SRC_ALPHAの値
最終的な値は、赤色要素で説明すると
合成元R値 * GL_SRC_ALPHAの値 + 合成先R値 * GL_ONE_MINUS_SRC_ALPHAの値
R値が整数の場合、GL_SRC_ALPHAで説明した方法で0.0~1.0に変換されたものを使用する。
で計算され、この値が
1.0
を越えるなら1.0に切り捨てる。そんな感じっす。
さっそくGL_BLENDを試してみましょう。
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
てやって、うりゃ!
おお、なんか半透明っぽい。
#define TEXTURE_ALPHA 0.1
う、薄いっ。
でも、じっと見てると裏側の透け方が変なんだよね。
裏側が出ない場合が...
て、そうかZバッファで隠面消去してるからだわ。
glDrawArraysでGL_TRIANGLE_FANしてるんで順に平面が描かれていくんだけど、描き始めの平面が表に出てる場合、その裏で隠された平面は表示されてないとみなされて、合成作業までいってくれないわけだ。
描き始めの位置が重要。
んじゃ深度チェック
glEnable(GL_DEPTH_TEST);
しなければいいんじゃね?
でも、深度チェックしないと、不透明物体との前後関係がわからなくならない?
試しにテクスチャ付き円錐の後側に不透明の灰色円錐を置いて描画してみた。
灰色の円錐の方は当然深度チェックしている。
やっぱ、微妙ですわ。
で、もうちょっと調べると
glDepthMask
深度を書き込めないようにするだけで、深度チェックはする。
というのを発見。不透明物体と透明物体を描く場合は、こっちを使うべきか?
おお、めりこんでる。
ただし、灰色の円錐を描いてからでないと、どっちも効果ないっす。
あたりまえ。
ここらへんの描画順はアプリケーション側が面倒見ないと駄目みたい。
でもって、GL_ALPHA_TESTで紹介されたAPIはというと...
glAlphaFunc
α値を表示するかどうかのフラグに使う。
void glAlphaFunc(
GLenum func,
GLclampf ref);
func
元画像のα値を使ってどう判断するかの指定。初期値はGL_ALWAYS。
ref
0.0~1.0の範囲で指定。初期値は0.0。
例えば、上のfuncでGL_GREATERと指定された場合、
元画像のα値 > ref
の比較がおこなわれる。これが成り立つ場合、表示され、成り立たなければ表示されない。
ものは試しにし、αマスク付きPNG作って指定してみます。
こんなやつ。
で、以下のように設定して呼び出し。
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.5f);
うりゃ。
おお~、なんか面白い。
んじゃ、これは
glAlphaFunc(GL_LESS, 0.5f);
うりゃ!
って、なんか予想してたのと違うのきた~。
以下次回。
------------
サンプルプロジェクト:es9.zip