結果だけでなく過程も見てください

たい焼きさんの日々の奮闘を綴る日記です。

DirectXのテクスチャをファイルからではなくオンメモリからロードする

DirectXでは、以下の方法でテクスチャをファイルからロードできます。

static const char* TEXFILE = "C:\\temp\\tex.dds";
IDirect3DDevice9*   pDevice;   // 各自作成しておいてね
IDirect3DTexture9*  pTexture = NULL;

  :

D3DXCreateTextureFromFileEx(			
	pDevice,                ←pDevice デバイス
	TEXFILE,                ←pSrcFile ソースファイル
	0,                      ←Width 幅。イメージから自動的に取得するなら00,                      ←Height 高さ。イメージから自動的に取得するなら00,                      ←MipLevels ミップマップレベル。使わない場合は0
	0,                      ←Usage テクスチャの使い方。D3DUSAGE_RENDERTARGETや、D3DUSAGE_DYNAMICなどを指定
	D3DFMT_A8R8G8B8,        ←Format
	D3DPOOL_MANAGED,        ←Pool D3DPOOL列挙型メンバ。
	D3DX_FILTER_NONE,       ←Filter フィルタリング方法を制御するD3DX_FILTERの組み合わせ
	D3DX_DEFAULT,           ←MipFilter
	0,                      ←ColorKey
	NULL,                   ←pSrcInfo ソースイメージファイル内のデータの記述を格納するD3DXIMAGE_INFO
	NULL,                   ←pPalette 256色パレットを表すPALETTEENTRY構造体へのポインタ
	&pTexture );		←テクスチャ格納先

D3DXCreateTextureFromFileExヘルパー関数は、bmp,dds,jpg,pngなどファイルの形式を
自動的に判別して読み込み、IDirect3DTexture9*へ画像情報を格納
してくれます。

しかし、ユーザーが画像ファイルを見られないように
独自の暗号化などをかけた場合は、この関数を使うことはできません。
そこで登場するのがD3DXCreateTextureFromFileInMemoryExという関数です。

めんどくさいので、サンプルコードと一緒に使い方を説明します。
CreateFileでファイルをオープンし、ファイルの中身を全部読み込み、
D3DXCreateTextureFromFileInMemoryExでロードします。

static const char* TEXFILE = "C:\\temp\\tex.dds";
IDirect3DDevice9*   pDevice;   // 各自作成しておいてね
IDirect3DTexture9*  pTexture = NULL;
HRESULT hr = S_OK;
char*  pTempBuf = NULL;	       // テクスチャロード用			

// ファイルの読み込み						
HANDLE hFile = ::CreateFile( TEXFILE, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL );	
if ( hFile == INVALID_HANDLE_VALUE )	
{	
	fprintf( stderr, "テクスチャファイルの読み込み失敗(file=%s code=%d)", TEXFILE, GetLastError() );
	hr = E_FAIL;
	goto Cleanup;
}	
	
DWORD dwFileSize = ::GetFileSize( hFile, NULL );	
if ( dwFileSize == -1 )	
{	
	fprintf( stderr, "テクスチャファイルの読み込み失敗(file=%s code=%d)", TEXFILE, GetLastError() );
	hr = E_FAIL;
	goto Cleanup;
}

pTempBuf = new char[dwFileSize+1];

DWORD dwActualRead;	
int rc = ::ReadFile( hFile, pTempBuf, dwFileSize, &dwActualRead, NULL );	
if ( rc == 0 ||	
     dwFileSize != dwActualRead )
{	
	 fprintf( stderr, "テクスチャファイルの読み込み失敗(file=%s code=%d)", TEXFILE, GetLastError() );
	 hr = E_FAIL;
	 goto Cleanup;
}	


// TODO:ここにデコード等の処理を記載する	


if ( FAILED( hr = D3DXCreateTextureFromFileInMemoryEx(					
					pDevice,
					pTempBuf,
					dwFileSize,
					0, 
					0, 
					0, 
					0, 
					D3DFMT_A8R8G8B8, 
					D3DPOOL_MANAGED, 
					D3DX_FILTER_NONE, 
					D3DX_DEFAULT, 
					0, 
 					NULL, 
 					NULL, 
					&pTexture ) ) )
{	
	fprintf( stderr, "テクスチャファイルの読み込み失敗(file=%s code=%d)", TEXFILE, GetLastError() );
	goto Cleanup;
}	

:	

Cleanup:	

if ( hFile != NULL &&	
     hFile != INVALID_HANDLE_VALUE )	
{	
	::CloseHandle( hFile );
	hFile = NULL;
}

if ( pTempBuf!= NULL )
{
        delete [] pTempBuf;
        pTempBuf= NULL;
}

要は、以下だけの違いです!

  • ファイルのフルパスを指定して、ファイルから直接テクスチャを読み込む
  • ファイルを読み込んだメモリ領域の先頭アドレス(と、そのサイズ)を指定して、メモリからテクスチャを読み込む

参考サイト

D3DXCreateTextureFromFileEx 関数
http://msdn.microsoft.com/ja-jp/library/cc372753.aspx

D3DXCreateTextureFromFileInMemoryEx 関数
http://msdn.microsoft.com/ja-jp/library/cc372744.aspx