今回の記事ではテクスチャーを利用した描画をしていきます。
テクスチャーとは?
テクスチャーとは主に質感を表現するためのものです。
3Dのゲームなどでは光沢や凹凸の表現等の様々な用途で使用させています。
今回のように2Dの環境では基本的には事前に用意した画像を表示する単純なものです。
テクスチャーを使うことで画面に事前に準備した画像を表示できるようになります。
なのでテクスチャーを使うことが出来れば2Dのある程度のゲームは作れてしまいます。
たとえばこんな画像を表示したりとかですね。
テクスチャーの生成
DirectX9に同梱されているD3DXの機能を使えば簡単にテクスチャーを生成することができます。
D3DXとはDirectXに同梱されている開発のサポートキットのようなものです。
DirectX11では廃止されていますが、DirectX9の世代ではよく使用されていました。
では早速、テクスチャーの生成をしていきましょう。
とその前にD3DXの機能を使うには下記の対応が必要です。
DirectX9を使う際も同じ記述があったかと思いますが、インクルードとリンクの指定が必要になります。
// D3DXのヘッダーをインクルード #include <d3dx9.h> // D3DXの静的ライブラリをリンク #pragma comment(lib, "d3dx9.lib")
これでD3DXを使う準備が整いました。
では今度こそテクスチャーの生成です。
// テクスチャーデータ struct TextureData { UINT width; // テクスチャーの幅 UINT height; // テクスチャーの高さ UINT srcWidth; // 画像の幅 UINT srcHeight; // 画像の高さ IDirect3DTexture9* pTexture; // 生成したテクスチャーのポインタ };
今回は先ずテクスチャーを管理する構造体を準備しています。
内容はそれぞれコメントとして書いている通りですが、高さと幅が2つあるのは不思議だと感じる人が多いと思います。
これはテクスチャーの幅と高さが2の累乗でなければ対応していないデバイスがあることが主な理由です。
最近のデバイスは殆ど無いと思いますが、それでもハードウェアからの参照効率等から今でも2の累乗にした方がよいとされています。
今回は2の累乗になる画像を用意していますが、それ以外の場合でも正しいサイズに画像を表示するためにテクスチャーと画像の両方の高さと幅を保持しています。
// テクスチャーの読み込み bool LoadTexture(const WCHAR* pFileName, TextureData* pOut) { if( pOut == NULL ) return false; IDirect3DTexture9* pTexture; D3DXIMAGE_INFO info; // ファイルからテクスチャーを生成する HRESULT hr = D3DXCreateTextureFromFileEx( GetDirect3DDevice(), // Direct3DDevice pFileName, // ファイル名 D3DX_DEFAULT, // 横幅(D3DX_DEFAULTでファイルから判定) D3DX_DEFAULT, // 高さ(D3DX_DEFAULTでファイルから判定) 1, // ミップマップの数 0, // 使用用途 D3DFMT_A8R8G8B8, // フォーマット D3DPOOL_MANAGED, // メモリの管理設定 D3DX_FILTER_NONE, // フィルター設定 D3DX_DEFAULT, // ミップマップフィルターの設定 0x00000000, // カラーキー &info, // 画像情報 NULL, // パレットデータ &pTexture); // 生成したテクスチャーの格納先 if( FAILED(hr) ) { return false; } D3DSURFACE_DESC desc; // 生成したテクスチャーの情報を取得 pTexture->GetLevelDesc(0, &desc); // テクスチャー情報の設定 pOut->pTexture = pTexture; pOut->srcWidth = info.Width; pOut->srcHeight = info.Height; pOut->width = desc.Width; pOut->height = desc.Height; return true; } // テクスチャーの解放 void ReleaseTexture(TextureData* pTextureData) { if( pTextureData == NULL ) return; SAFE_RELEASE(pTextureData->pTexture); }
テクスチャーの生成と解放はたったこれだけです。
本来であればテクスチャーのフォーマット解析や必要メモリサイズの計算なども必要なのですが、D3DXが全て対応してくれています。
又、画像フォーマットにも複数対応していてbmp, jpg, png, tga, dds等が対応しています。
なのでD3DXCreateTextureFromFileExを呼び出すだけで基本は終わりです。
今回は実際に使う時のためにテクスチャーの幅や高さも取得しています。
D3DXCreateTextureFromFileExの引数をいくつか簡単に説明しておきます。
第二引数で指定されたファイルをHDDから読み込みテクスチャーとして生成してくれます。
第三引数と第四引数は幅と高さですが、D3DX_DEFAULTを指定した場合は2の累乗になるように調整した値になります。
第七引数は今回はRGBAを持ったフルカラーのテクスチャーを作るためにD3DFMT_A8R8G8B8を指定していますが、他のフォーマットのテクスチャーを作る際にはそれぞれ指定する必要があります。
第十一引数のカラーキーは透明にしたいカラーがあれば指定すると0xFF******と入れると指定されたカラーが透明になります。
第十二引数は読み込んだ画像の情報が入ります。必要のない場合はNULLで問題ありません。
第十四引数は生成したテクスチャーオブジェクトが返ってきます。
D3DSURFACE_DESC desc; // 生成したテクスチャーの情報を取得 pTexture->GetLevelDesc(0, &desc); // テクスチャー情報の設定 pOut->pTexture = pTexture; pOut->srcWidth = info.Width; pOut->srcHeight = info.Height; pOut->width = desc.Width; pOut->height = desc.Height;
最後に生成したテクスチャーの情報を設定しています。
内容は最初に記述したTextureDataの説明通りです。
今回はテクスチャーをファイルから生成する方法を紹介しましたが、空のテクスチャーやメモリ上からテクスチャーを生成する方法等もあります。
- 空のテクスチャーを生成
D3DXCreateTexture - メモリ上からテクスチャーを生成
D3DXCreateTextureFromFileInMemoryEx