ちょっと正しい透過処理を試みてみた。半透明なブロックを置けるようにしたいと思ったからだ。 OpenGLで半透明な面を描画するにはアルファブレンディングの機能を使う。 アルファブレンディングによる透過処理を正常に行うためには以下の手順を踏む必要があると考えられる。
- すべての面の描画を試みる。
- 不透明な面はそのまま描画する。
- 半透明な面はボディ座標からワールド座標値を求め、この時点では描画しない。
- ワールド座標上でのZ値が奥から手前の順になるように半透明な面をソートする。
- 半透明な面を奥からすべて描画する。
なぜこのような処理手順を踏む必要があるのか、 Zバッファとの兼ね合いから半透明な面は、手前のものより先に奥のものから順番に書いていかないと描画されないからだ。 今回は、この手前か奥かという判定に面の中心座標のZ値を使用した。 「ちょっと正しい」とはそういう意味だ。ソートも何もしないよりは正しくなる。
3Dブロック崩しの場合だけを考えるなら、面を単位とするよりはブロックを単位とした方が早くなりそうだが、 後で他にも使えるかもしれないのでより一般的な方法として上の方法を試してみることにした。 しかし、思った以上に透過処理の処理コストが高いかもしれない。 一定数以上の面を透過処理すると動作がすごく重くなる。
Visual Studioから実行したときと、実行ファイルを直接実行したときではなぜか速度が違う。 Visual Studioからプログラムを実行するとすごく遅い。なぜだろうか?

今回初めて影付け *1 に挑戦した! 上の図は、壁にボールの影が映っているところ。 ボールに影があるのは当たり前だって?いやいや、OpenGLで影を付けるためには色々と苦労がいるんだよ。 影付けをするためには、影に相当する面を計算して求めなくちゃいけないんだ。 そして、ステンシルバッファを利用して影を付ける。 ここで一つつまづいたのは、 SDLでOpenGLを利用するときはステンシルバッファのサイズを事前に指定しなくちゃいけないってこと。
SDLを利用したものと利用しなかったもの、同じプログラムなのにSDLを使ったものだと失敗して、 SDLを使わなかったものだと成功する? この一行を書かなかったばっかりに、なぜできないんだって悩む羽目になったよ(笑)
そうそう開発自体には関係ないんだけど、CG検定2級をGETした! 資格を取るだけじゃなくて、資格に見合うだけの実装能力を身に着けたい! ってなわけで、3Dブロック崩しの開発がんばるぞ!