ホーム < ゲームつくろー! < DirectX技術編 < テクスチャ作成あれこれ


その3 テクスチャ作成あれこれ


 昨今のゲームではポリゴンの表面にテクスチャを張る事が当たり前となりました。2Dゲームの場合も、板ポリゴンにテクスチャを張らなければなりません。つまり、テクスチャを作成して貼り付けられなければ見栄えの良い大規模本格ゲームは難しいのです。
 ここではDirect3Dでテクスチャを作成する方法をざざっと羅列してみたいと思います。

@ IDirect3DDevice9::CreateTexture関数

 空のテクスチャを作成する基本の関数です。最終的にIDirect3DTexture9オブジェクトへのポインタを取得できます。絵を貼り付けるのは多少面倒ですが、この空テクスチャを駆使すると色々面白いことが出来ます。

HRESULT CreateTexure(
UINT Width,
UINT Height,
UINT Levels,
DWORD Usage,
D3DFORMAT Format,
D3DPOOL Pool,
IDirect3DTexture9** ppTexture
HANDLE* pHandle
);


WidthHrightは作成するテクスチャのサイズを指定します。
Levelsは「ミップマップレベル」を設定します。ミップマップとは連続したテクスチャで、同じ画像を徐々に低解像度にしたものです。具体的には、100×80という画像を用意した(Level 1)とすると、次のレベル2は50×40と縦横とも半分の大きさになります。Level3は25×20、Level4は12×10、Level5は6×5、Level7は3×2、Level8は1×1となります。つまり、この大きさの画像を用意した場合、Levelは0〜8まで設定できます。0を設定すると1×1になるまでミップマップを全部生成してくれます。
Usageはテクスチャの性質や確保するメモリの場所を指定するオプションです。マニュアルの「D3DUSAGE」に設定できるフラグの一覧があります。D3DUSAGE_DYNAMICを指定すると動的テクスチャが作成されますが、Pool=D3DPOOL_MANAGEDと一緒には使えません。「動的」というのは作成後にテクスチャの大きさを変更できると言う事です。D3DUSAGE_AUTOGENMIPMAPを指定すると、ミップマップが自動生成されます。ただし、Levelsを0か1にしなければなりません。D3DUSAGE_RENDERTARGETを指定すると、テクスチャを描画対象(レンダリングターゲット)にする事が出来ます。通常テクスチャは外部のテクスチャファイルを読み込ませますが、この場合はバックバッファの代わりにテクスチャに描画できるようになります。ただし、Pool=D3DPOOL_DEFAULTにする必要があります。レンダリングターゲットにすることにより、美しい効果を作り出せるので、あなどれない設定です。D3DUSAGE_DEPTHSTENCILを指定すると、テクスチャサーフェイスをZバッファとステンシルバッファとして利用できるようになります。ステンシルバッファは「マスク」として使用できるので、一部分だけを描画するなどの効果が期待できます。ただしこれもPool=D3DPOOL_DEFAULTにする必要があります。
Formatはテクスチャのピクセルフォーマットを指定します。マニュアルの「D3DFORMAT」に設定できるフォーマットの全てが記載されています。物凄い沢山あるのでとてもここでは紹介し切れません。現在の画面と同じにするか、用意してある絵ファイルのフォーマットにあわせるのが普通です。テクスチャを深度バッファとして使用する場合は、専用の設定値(例:D3DFMT_D15S1、D3DFMT_D16など)にする必要があります。
Poolはテクスチャを格納するメモリの位置と管理に関するフラグを設定します。静的なテクスチャの場合D3DPOOL_MANAGEDを設定すると良いパフォーマンスが得られます。Usageで特別なフラグを立てた時には、D3DPOOL_DEFAULTにする必要があります。あとシステムメモリに格納するD3DPOOL_SYSTEMもありますが、VRAMに格納された方が描画は速くなります。
ppTextureへは作成されたテクスチャインターフェイスへのポインタが返ります。これを得る事が目的です。
pHandleは現在使われていません。NULLを設定します。

すっかり長い説明になってしまいました。関数が成功すると指定された空テクスチャが作成されます。


A D3DXCreateTexture関数

D3Dエクステンションで用意されているテクスチャ作成のヘルパー関数です。@のCreateTextureと同様に空のテクスチャを作成してくれますが、@よりも少し簡単になっています。

HRESULT D3DXCreateTexure(
LPDIRECT3DDEVICE9 pDevice,
UINT Width,
UINT Height,
UINT Levels,
DWORD Usage,
D3DFORMAT Format,
D3DPOOL Pool,
IDirect3DTexture9** ppTexture
);


pDeviceはIDirect3DDevice9オブジェクトへのポインタを渡します。
WidthHeightは@と同じですが、D3DX_DEFAULTを指定すると256ピクセルのテクスチャとなります。
Levelsは@と同じです。
Usageも@と同じですが、指定できるフラグがD3DUSAGE_RENDERTARGET、D3DUSAGE_DYNAMIC及び0に限定されています。
Formatも@と同様です。ただし、指定したFormatをデバイスがサポートしない場合、指定した物と異なるフォーマットになる事があります。これは多分なるべくテクスチャの作成を成功させるためだと思います。
Poolは@と同じです。
ppTextureに作成されたテクスチャオブジェクトが返されます。

IDirect3DDevice9::CreateTexture関数をより簡略にして使いやすくした感じですね。


B D3DXCreateTextureFromFile関数

 画像ファイルを読み込んでテクスチャを作成してくれるヘルパー関数です。引数が少なく非常に便利で簡単に使えるので、ポリゴンに貼り付けるテクスチャはこれで作成する事が多いです。

HRESULT D3DXCreateTextureFromFile(
LPDIRECT3DDEVICE9 pDevice,
 LPCTSTR pSrcFile,
 LPDIRECT3DTEXTURE9* ppTexture
);


pDeviceはIDirect3DDevice9オブジェクトへのポインタです。
pSrcFileは画像ファイルへの絶対パス及び相対パスを表す文字列です。扱える画像ファイルのフォーマットは、bmp、.dds、.dib、.jpg、.png、および .tga です。これはDirectX8よりも随分と増えました。特にpngやtgaなどのα情報が格納されている画像ファイルを扱えるのが嬉しいところです。dds(Direct Draw Surface)はDirect3DX独自のフォーマットで、親和性が高くミップマップも保存できるフォーマットで、α情報も持っています。
ppTextureに生成されたテクスチャオブジェクトへのポインタが返ります。

マニュアルにもあるのですが、この関数は次に紹介しているD3DXCreateTextureFromFileExの限定版で、D3DXCreateTextureFromFileEx(pDevice, pSrcFile, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, ppTexture) と同じです。


C D3DXCreateTextureFromFileEx関数

 B同様に画像ファイルからテクスチャを作成してくれますが、Bより細かな制御が可能になっています。引数がめちゃくちゃ沢山あるので大変でもあります。

HRESULT D3DXCreateTextureFromFileEx(
LPDIRECT3DDEVICE9 pDevice,
LPCTSTR pSrcFile,
UINT Width,
UINT Height,
UINT MipLevels,
DWORD Usage,
D3DFORMAT Format,
D3DPOOL Pool,
DWORD Filter,
DWORD MipFilter,
D3DCOLOR ColorKey,
D3DXIMAGE_INFO* pSrcInfo,
PALETTEENTRY* pPalette,
LPDIRECT3DTEXTURE9* ppTexture
);


AやBと同じ物は簡略していきます。
pDevice, pSrcFileはBと同じです。
Width, HeightはAと同様ですがここに0及びD3DX_DEFAULTを指定すると、画像ファイルから幅と高さを取得してくれます。
MipLevelsUsageFormatPoolはAとまったく同じです。
Filterはイメージのフィルタリング方法を指定します。フィルタリングとは拡大縮小されたイメージのピクセルの補間計算法の事です。D3DX_FILTER列挙型に補間方法が沢山定義されていますが、D3DX_FILTER_POINTD3DX_FILTER_LINEAR及びD3DX_FILTER_TRIANGLEのどれかにするのが普通です。D3DX_FILTER_POINTは一番近い点の色がそのまま使われます。D3DX_FILTER_LINEARはいわゆる線形補間で、中間色が指定されます。D3DX_FILTER_TRIANGLEは変換後の点に対して元の画像の点が等しく反映されます。大変綺麗なのですが、処理時間が多少掛かります。D3DX_DEFAULTにするとD3DX_FILTER_TRIANGLE | D3DX_FILTER_DITHER(ディザ)となります。
MipFilterはミップマップに対して行われるフィルタリング法を指定します。設定内容はFilterと同じです。D3DX_DEFAULTにするとD3DX_FILTER_BOX(4点平均)になります。
ColorKeyは「カラーキー」という完全に透明にする色を指定します。画像ファイル内でこの色と同じ色のピクセルはすべて透明と扱われます。指定したくない場合は0を設定します。一昔前に切り抜き貼り付けを再現するときにしようしましたが、ジャギがどうしても目立ってしまうので、昨今はあまり使われなくなった気もします。
pSrcInfoは元の画像の情報を格納するD3DXIMAGE_INFO構造体へのポインタを渡します。格納しなくても良い場合はNULLを指定します。
pPaletteは256フォーマットの場合にのみ使われ、画像に使われているパレットへのポインタがここに格納されます。最近は256色に減色しなくても十分な速さを得られるようになったので、使用頻度は下がりました。
ppTextureに生成したテクスチャオブジェクトへのポインタが返ります。

BのCreateTextureFromFile関数に対してFilter及びMipFilterを細かく設定したい場合に使う場合が多そうです。ColorKeyも最近はαブレンドが普通になってしまったので、使う頻度はぐっと減ってしまいました。


D D3DXCreateTextureFromFileInMemory関数


 メモリ内のファイルからテクスチャを作成します。メモリ内のファイルとはファイル情報がメモリにそっくり格納されている状態のファイルです。これは多分ファイルマッピング(メモリマップドファイル)を指しているのだと思います。例えばBitmapの情報をメモリに全部読み込ませると言う事は結構あります。使用頻度として高いのが、画像ファイルの情報を1つのデータファイルとして全部格納してしまい、それをファイルマッピングして扱う場合です。ゲームを配布する時に、画像ファイルをそのままの形式にしておくと、あっさりと転用されたりします。データファイルとしてまとめてしまうと、一般ユーザでは絵を見られにくくなり、ちょっとだけ改ざん防止になります。

HRESULT D3DXCreateTextureFromFileInMemory(
LPDIRECT3DDEVICE9 pDevice,
LPCVOID pSrcData,
UINT SrcData,
LPDIRECT3DTEXTURE9* ppTexture
);


pDeviceppTextureはもういいですね。
pSrcDataにはメモリ内にあるファイルへのポインタを渡します。もちろん、メモリ内に画像ファイルがなければエラーになります。
SrcDataはメモリ内ファイルのサイズです。

この関数はファイルマッピングとの併用で威力を発揮すると思われます。ファイルマッピングとはメモリマップドファイルとも呼ばれ、HDDに格納されているファイルをメモリと同様の扱いにしてくれる方法で、ポインタのような操作やランダムアクセスなどとっても便利にファイルを扱う事が出来ます。MSDNライブラリのプラットフォームSDKでプロセス間通信の所にAPIの説明があります。


E D3DXCreateTextureFromFileInMemoryEx関数


 Dの拡張版で、ちょうどBとCの関係と同じです。

HRESULT D3DXCreateTextureFromFileInMemoryEx(
LPDIRECT3DDEVICE9 pDevice,
LPCVOID pSrcData,
UINT SrcDataSize,
UINT Width,
UINT Height,
UINT MipLevels,
DWORD Usage,
D3DFORMAT Format,
D3DPOOL Pool,
DWORD Filter,
DWORD MipFilter,
D3DCOLOR ColorKey,
D3DXIMAGE_INFO* pSrcInfo,
PALETTEENTRY* pPalette,
LPDIRECT3DTEXTURE9* ppTexture
);


変数の構成はCと殆ど同じですし、pSrcDataSrcDataSizeはDと同じなので、ここでは省略します。

F D3DXCreateTextureFromResource関数


 リソースからテクスチャを作成します。リソースはモジュールに組み込まれた物なので、画像をデータファイル化するよりもユーザによって絵を見られたり抽出されたりする危険がより少なくなります。

HRESULT D3DXCreateTextureFromResource(
LPDIRECT3DDEVICE9 pDevice,
HMODULE hSrcModule,
LPCTSTR pSrcResource
LPDIRECT3DTEXTURE9* ppTexture
);


hSrcModuleはリソースが格納されているモジュールハンドルを指定します。もし、今のプロセスにリソースがある場合はNULLにします。
pSrcResourceはリソース名を文字列で指定します。

 VC++では画像ファイルをリソースエディタで作成できますし、インポートも簡単です。


G D3DXCreateTextureFromResourceEx関数


疲れてきました(笑)。Fの上位関数でBとC、DとEとまったく同じ関係です。

HRESULT D3DXCreateTextureFromResourceEx(
LPDIRECT3DDEVICE9 pDevice,
HMODULE hSrcModule,
LPCTSTR pSrcResource,
UINT Width,
UINT Height,
UINT MipLevels,
DWORD Usage,
D3DFORMAT Format,
D3DPOOL Pool,
DWORD Filter,
DWORD MipFilter,
D3DCOLOR ColorKey,
D3DXIMAGE_INFO* pSrcInfo,
PALETTEENTRY* pPalette,
LPDIRECT3DTEXTURE9* ppTexture
);


変数はCとFのミックスです。

これで多分テクスチャを作成する関数は全部説明したと思います。テクスチャ自体にも色々種類があり、ここでは単純な2Dテクスチャの作成方法を挙げました。大規模なゲームになるとリソース化するのも大変なので、画像ファイルをデータファイルとしてアーカイブする事が多いと思います。そういう意味ではDD3DXCreateTextureFromFileInMemory及びとED3DXCreateTextureFromFileInMemoryEx関数を使うのがベターかもしれません。ただ、その為にはファイルアーカイバの作成と、ファイルマッピングを扱わなければなりません。開発段階では通常のファイルからテクスチャを作成し、本番でアーカイブ化してクラスを差し替えるというのも1つの手段ですね。