▽OpenGLでテクスチャマッピング(その3)

MFCベースのプログラムでOpenGLを使用するときのサンプルです。OpenGLでテクスチャを便利に取り扱うためのskGLTextureクラスを作成したので、これを使っていろいろなテクスチャを貼ってみます。

まずはサンプルプログラムをどうぞ。

サンプルプログラム
sk00d-18.lzh

今回は、微妙に種類の違うテクスチャマッピングをされた8個の箱がぐるぐる回るサンプルです。

8個の箱がぐるぐる
8個の箱がぐるぐる回る図

念のために解説しておくと、それぞれ、貼ってある画像にその種類が書き込んであります。

8bpp / 24bpp
『8bpp』は8ビットカラーのテクスチャ。ただし、減色は“ディザあり”で行われている点が要注意。『24bpp』は元になったフルカラーのデータ。
本当は32ビットカラーのデータも貼りたかったんだけど、データを用意するのが面倒なので、また、次の機会に(´∀`;)
直接 / 登録
『直接』は毎回データを転送するOpenGL 1.0までの形式でのテクスチャマッピング。『登録』はglBindTexture()を使用するOpenGL 1.1以降の形式のテクスチャマッピング。
透明 / 不透明
『透明』は真っ白の部分が透明になるように指定してテクスチャを作成。この作業の結果、24bppのデータは、実質、32bppのデータのテクスチャになっている事に注意。『不透明』はα情報を付け加える作業を行っていないデータ。

以下、サンプルプログラムのピンポイント解説です。

○skGLTextureについて

skGLTextureはHBITMAPからテクスチャを作成、管理してくれるクラスです。以下のような特徴を持っています。

skGLTextureの簡単な使い方は以下の通りです。それぞれの手順において、OpenGLの関数を使えるようにしておく必要があることに注意してください。

1.skGLTexture::Create()で作成
skGLTexture::Create()でテクスチャを作成します。テクスチャに使える画像データは幅・高さともに2の累乗で8/24/32ビットカラーのデータだけです。

透明色が指定されていた場合、必要に応じてα情報が追加されます。8ビットカラーのデータの場合、パレットもこの時点で作成されます。
2.skGLSetTexture()で貼り付け
テクスチャの貼り付けを簡単に行えるようにするため、グローバル関数が用意してあります。skGLSetTexture()にskGLTextureのポインタを渡す事で、対応するテクスチャが貼り付けられます。テクスチャを貼らないときはポインタにNULLを渡します。
3.skGLTexture::Release()で破棄
テクスチャを使い終えるとskGLTexture::Release()で破棄します。この中でテクスチャに使っていたHBITMAPも一緒に破棄されます。

○skGLTextureの注意点

skGLTextureを使うときは、以下のような点に注意する必要があります。

対応している形式は8/24/32ビットカラーのデータのみ
16ビットカラーのデータは論外です。まぁ、そもそも、16ビットカラーのデータをテクスチャに使う必要もないでしょうが・・・
32ビットカラーのデータではα情報を事前に用意する事
skGLTextureには8/24ビットカラーのデータにαをセットする機能がありますが、32ビットカラーのデータは、あえて、何もいじらないようにプログラムしてあります。32ビットカラーのデータを使うときは、事前に、自分でα情報をセットしておきましょう。
毎回転送の場合はデータの変更に注意
毎回転送の形式を使う場合、HBITMAPの中身を変更する事でアニメーションテクスチャが簡単に再現できますが、skGLTextureが管理するいくつかの要素は変更できません。具体的に言うと、テクスチャのサイズの変更・色数の変更・HBITMAPでのパレット変更はできません。詳細は・・・ ソースを見てください。
テクスチャに関するフラグは作成前に設定
skGLTextureは標準で使いやすそうな設定をするようにしてありますが、これを変えたいときは、Create()を呼び出す前に変更しておいてください。プログラム全体で、特定の設定を使いたい場合は、skGLTextureを継承したクラスを作って、そのコンストラクタでまとめて設定変更してしまいましょう。
HBITMAPはskGLTextureが管理
基本的にテクスチャ作成時に使ったHBITMAPは、その後、skGLTextureが管理する事になります。どうしても自分で管理したい場合は・・・ まぁ、気合いで。ウソです、何とかできるようにします(´∀`;)

他にもいろいろとこまかい注意点はありますが・・・ すべてはソース参照という事で(´∀`;)

○OpenGLの注意点

skGLTextureと関係なく、OpenGLでテクスチャマッピングを使用するとき全般の注意点です。

昔の記憶だけで書いている部分があります。実際のところは自分で確認してください。

GL_DECALだとαがうまく反映されない事がある
これは、環境によるのかな? なぜか、うまくいかなかった経験があります。
GL_REPEATでUV座標にマイナスの値を指定するとはまる事がある
これも、環境によるのかな? まぁ、こういう使い方をしなければすむ事なんですけど。
テクスチャマッピングを使うとスペキュラーが効かない
OpenGLの巨大な問題点のうちの一つです。どうしてもスペキュラーを効かせたいなら・・・ DirectXに逃げるのが正解かなぁ。スペキュラーのためだけにマルチテクスチャをやるのはものすごく切ない。

以下、特に未確認情報なので要注意。気が向いたら検証用のテストプログラムを書くかもしれません。

8ビットカラーのテクスチャはかなり重い?
データのサイズは一番小さいけど、処理は重い? 経験上、24ビットカラーのテクスチャが一番速いような気がします。
32ビットカラーのデータは汚い?
これも、環境次第なのかなぁ。今回のサンプルでも24bpp・透明のテクスチャと、24bpp・不透明のデータだと、透明の方はマッハバンドが見える事があるかと思います。

あと、α情報を使うときのオブジェクトの描画順の話とかもありますが・・・ もう、このあたりはOpenGLもすっ飛ばして3Dレンダリング全般の話になるので省略で。


[skLib] Presented by See.Ku [2005/1/18]