Programs / 最終更新時間:2003年10月20日 00時38分30秒

概要

以下DirectX 7時代の話です。

目次

スフィア環境マップを簡単に

ある物体(すでにテクスチャが貼ってある)に、スフィア環境マップなどを重ね合わせるように描画したいときがあります。

そんなとき、頂点にマルチテクスチャ用のもうひとつのuv領域を作ったりするのは、面倒だし、プログラムが荒れてしまいがちです。しかし、DirectX7にはテクスチャ座標自動生成機能があります。

これを使えば、uvのない頂点で作ってあるプリミティブにテクスチャを貼ったり、すでにあるuvに加えて、さらに別のテクスチャのuvを自動生成して重ね合わせたりすることができるわけです。

いきなりですが、以下のよーなコードでいけます(ただし、勘違いしている可能性アリ)。

// スフィア環境マッピングを有効にする
// (シングルパスのみサポート)
m_pd3dDevice->SetTextureStageState( 1, D3DTSS_TEXTURETRANSFORMFLAGS,  D3DTTFF_COUNT2);
m_pd3dDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACENORMAL|1);

// このへんは任意
m_pd3dDevice->SetTextureStageState( 1, D3DTSS_MAGFILTER, D3DTFG_LINEAR );
m_pd3dDevice->SetTextureStageState( 1, D3DTSS_MINFILTER, D3DTFN_LINEAR );

m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE );
m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_CURRENT );
m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_ADDSMOOTH );
m_pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );

m_pd3dDevice->SetTexture( 1, m_pddsSphereMap );

このあと、DrawPrimitiveなどで描画してやればOK。いままでのソースに変更を加えなくても、これを追加するだけでたぶん大丈夫。もちろん、テクスチャの読み込みとか、環境マップしたくないやつの前では無効にしてやるとか、細かいことは必要ですが。

あ、忘れてました。↑のままだと、テクスチャ座標が望みのものより大きいし、中心位置がずれてるので、テクスチャ座標変換行列も設定してやりましょう。

以下、その部分のソース。

static float mat[4][4] =
{
   { 0.5f, 0.0f, 0.0f, 0.0f },
   { 0.0f, 0.5f, 0.0f, 0.0f },
   { 0.0f, 0.0f, 0.5f, 0.0f },
   { 0.5f, 0.5f, 0.5f, 1.0f }
};

m_pd3dDevice->SetTransform( (D3DTRANSFORMSTATETYPE)(D3DTRANSFORMSTATE_TEXTURE1), (const LPD3DMATRIX)mat );

簡単だという証拠として、SDKサンプルのClipMirrorがベースにしたサンプルソース&実行ファイルを用意してみました。

DirectX7SDKのIMサンプルソース群と同じフォルダにコピーしてコンパイル/実行してください。
ClipMirrorに追加したコードは「//---/」で囲っているのですぐわかると思います。

画面

ティーポット自体に基本のテクスチャが貼ってないのでアレですが、貼ってあってもうまくいきます。

ダウンロード

ClipMirrorEnvTex.lzhのダウンロード(114KB)