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

MFCベースのプログラムでOpenGLを使用するときのサンプルです。今回はglBindTexture()を利用したテクスチャマッピングを行ってみます。

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

サンプルプログラム
sk00c-06.lzh

前回のと同様、テクスチャマッピングをされた箱とティーポットがぐるぐる回るだけのサンプルです。

箱とティーポットぐるぐる
箱とティーポットがぐるぐる回る図

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

○テクスチャマッピング(glBindTexture)

基本的な手順は前回のサンプルプログラムと大きく変わっていません。ただ、前回はHBITMAPのデータを毎回、直接転送していた部分が事前に登録する形になっただけです。

テクスチャを読み込む部分は以下の通り。

UINT            CSk00View::LoadTexture( const char* fn )
{
    //      指定されたファイルをテクスチャとして読み込む

    //      とりあえず画像を読み込み

    HBITMAP bmp = skLoadImage( fn );
    if( bmp == NULL )
        return  NULL;

    BITMAP  inf;
    GetObject( bmp,sizeof(BITMAP),&inf );

    //      今回は24ビットカラーのデータのみを採用

    if( inf.bmBitsPixel != 24 ) {
        DeleteObject( bmp );
        return  NULL;
    }

    //      テクスチャを作成

    UINT    id  = 0;

    glGenTextures( 1,&id );
    glBindTexture( GL_TEXTURE_2D,id );

    //      データを転送

    glTexImage2D( GL_TEXTURE_2D,0,3,
                  inf.bmWidth,inf.bmHeight,0,
                  GL_BGR_EXT,GL_UNSIGNED_BYTE,inf.bmBits );

    //      使い終わったので画像を破棄

    DeleteObject( bmp );

    return  id;
}

上半分は前回のサンプルプログラムとほとんど変わってません。まず、テクスチャとして使える画像データを読み込んでいます。

画像データが準備できたところでテクスチャの登録に入ります。まず、glGenTextures()で新しいテクスチャのためのIDを取得します。複数のIDをまとめて取得する事もできますが、ここではIDを1個取得しているだけです。

その後、glBindTexture()でどのテクスチャIDを使用するか宣言し、glTexImage2D()で画像データをテクスチャに転送します。これで、あとはテクスチャIDを指定するだけでテクスチャの中身はOpenGL側が管理してくれるようになりました。

必要のなくなった画像データを破棄してテクスチャの作成作業は終了です。

テクスチャマッピング関係の設定を行う部分は以下のようになります。

    //      テクスチャの設定

    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,      GL_REPEAT );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,      GL_REPEAT );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,  GL_LINEAR );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,  GL_LINEAR );
    glTexEnvf( GL_TEXTURE_ENV,      GL_TEXTURE_ENV_MODE,    GL_MODULATE );
    glEnable( GL_TEXTURE_2D );

前回のサンプルからの変更点はGL_TEXTURE_2Dを有効にしているところだけです。テクスチャIDに0を指定する事でテクスチャのON・OFFを切り替える事ができるので、テクスチャマッピングは常に有効にしてしまいます。

実際にテクスチャを貼り付ける処理は以下のようになります。

void            CSk00View::SetTexture( UINT id )
{
    //      テクスチャを貼り付ける

    glBindTexture( GL_TEXTURE_2D,id );
}

テクスチャIDを指定してglBindTexture()を呼び出すだけです。簡単ですね。

○テクスチャマッピングの課題

とりあえず、テクスチャデータを毎回転送する旧形式と、OpenGLに登録するglBindTexture形式の二通りのやり方でテクスチャマッピングが使えるようになりました。

これで、OpenGLにおけるテクスチャマッピングは完璧・・・ と思ったら大間違い。実際にテクスチャマッピングを使っていると、いろいろ、もっと凝ったことがやりたくなることでしょう。

32ビットテクスチャ
RGBの他にα情報もビットごとに持たせたテクスチャデータです。そもそも、データを用意のが面倒だったりしますが、ときどき、これが必要になったりします。
透明色指定
α情報を持たないテクスチャデータに対して、特定の色だけを透明に置き換える事ができれば便利な事がよくあるんです。
8ビットテクスチャ対応
今時、必要ないようにも見えますが、テクスチャの容量を減らすためにも8ビットカラー、つまり256色でパレットを使う形式のテクスチャも使えると便利です。パレットアニメもできるとさらに便利かも。
動的テクスチャ
状況に応じて、データの内容が変化するテクスチャです。テクスチャデータを毎回転送する事で簡単にできたりします。

次回は、このあたりを総まとめしたクラスを作る予定です。


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