ホーム < ゲームつくろー! < DirectX技術編 < Xファイルのカスタムテンプレートを使ってみよう:サンプルプログラム
その32 Xファイルのカスタムテンプレートを使ってみよう:サンプルプログラム
DirectX技術編その32「Xファイルのカスタムテンプレートを使ってみよう」で説明した内容を踏まえたサンプルプログラムです。実行すると、PersonID.xというテンプレートを定義したファイルからテンプレート定義を読み込み、それを登録した後に、TestID.xという名前とID番号が入ったデータを読みに行き、Xファイルの仕様に従ってデータを格納して、画面に表示します。
サンプルスクリーンショット
以下のプログラムは指定のカスタムテンプレート(PersonID.x)及びデータファイル(TestID.x)をパスの通った場所に置き、空のプロジェクトにコピペすることで完全に動きます。PersonIDテンプレートは世界に一つしかない番号が振られておりますので、こちらからファイルをダウンロードしてください。上からデバッグしていくと、何をしているか良くわかるように1つのソースで完結させています。今回のポイントになりそうなところは太文字で示されています。
(もしうまく動かないようでしたら掲示板にてご連絡下さい)
/// XFileカスタムテンプレート読み込みテスト #pragma comment(lib, "dxguid.lib") #pragma comment(lib, "d3d9.lib") #pragma comment(lib, "d3dx9.lib") #pragma comment(lib, "d3dxof.lib") #include <windows.h> #include <tchar.h> #include <d3d9.h> #include <d3dx9.h> #include <dxfile.h> // Xファイル関連を使用するのに必要 #include <fstream> #include <vector> #include <string> using namespace std; #if _UNICODE typedef wstring gstring; #else typedef string gstring; #endif TCHAR gName[] = _T("XFileカスタムテンプレート読み込みテスト"); // 文字コード対応文字列代入関数 void COPYSTR_To_STL( gstring &stl, const char *str ) { #if _UNICODE TCHAR *Buf = _T(""); int num = MultiByteToWideChar(CP_ACP, 0, str, -1, Buf, 0); Buf = new TCHAR[num]; MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, str, -1, Buf, num); stl = Buf; delete Buf; #else stl = str; #endif } // テキストファイルをメモリにコピーする関数 char* GetFileText( char* filename ){ ifstream ifs; ifs.open( filename ); if( !ifs.is_open() ) return NULL; DWORD FileSize=0; while(!ifs.eof()){ ifs.ignore(); FileSize++;} // サイズ取得 ifs.clear(); ifs.seekg(0, ios_base::beg); // ファイルポインタを初期位置へ char* tmp = new char[FileSize]; ZeroMemory( tmp, FileSize ); ifs.read( tmp, FileSize-1); return tmp; } LRESULT CALLBACK WndProc(HWND hWnd, UINT mes, WPARAM wParam, LPARAM lParam){ if(mes == WM_DESTROY) {PostQuitMessage(0); return 0;} return DefWindowProc(hWnd, mes, wParam, lParam); } int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { // アプリケーションの初期化 MSG msg; HWND hWnd; WNDCLASSEX wcex ={sizeof(WNDCLASSEX), CS_HREDRAW | CS_VREDRAW, WndProc, 0, 0, hInstance, NULL, NULL, (HBRUSH)(COLOR_WINDOW+1), NULL, (TCHAR*)gName, NULL}; if(!RegisterClassEx(&wcex)) return 0; if(!(hWnd = CreateWindow(gName, gName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL))) return 0; // Direct3Dの初期化 LPDIRECT3D9 g_pD3D; LPDIRECT3DDEVICE9 g_pD3DDev; if( !(g_pD3D = Direct3DCreate9( D3D_SDK_VERSION )) ) return 0; D3DPRESENT_PARAMETERS d3dpp = {0,0,D3DFMT_UNKNOWN,0,D3DMULTISAMPLE_NONE,0, D3DSWAPEFFECT_DISCARD,NULL,TRUE,0,D3DFMT_UNKNOWN,0,0}; if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &g_pD3DDev ) ) ) if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pD3DDev ) ) ) { g_pD3D->Release(); return 0; } // カスタムテンプレートファイルからテンプレート定義を抽出 char* g_pTEMPLATE_PERSONID = GetFileText( "PersonID.x" ); if( !g_pTEMPLATE_PERSONID ){ g_pD3DDev->Release(); g_pD3D->Release(); return 0; } // テンプレートを登録 IDirectXFile *pDXFile; DirectXFileCreate( &pDXFile ); if(FAILED(pDXFile->RegisterTemplates( g_pTEMPLATE_PERSONID, strlen( g_pTEMPLATE_PERSONID ) ))){ g_pD3DDev->Release(); g_pD3D->Release(); return 0; } // ファイルからテンプレートデータを列挙するインターフェイスを取得 IDirectXFileEnumObject *pEnumObj; if(FAILED(pDXFile->CreateEnumObject( "TestID.x", DXFILELOAD_FROMFILE, &pEnumObj ))){ pDXFile->Release(); g_pD3DDev->Release(); g_pD3D->Release(); return 0; } // テンプレート内のデータを取得 IDirectXFileData *pDXData; DWORD Size; // 取得したデータサイズ char **pName; // 名前 DWORD *pIDCode; // ID vector< gstring > VctName; // 名前格納配列 vector< DWORD > VctID; // ID格納配列 const GUID PersonID_GUID ={ 0xB2B63407,0x6AA9,0x4618, 0x95, 0x63, 0x63, 0x1E, 0xDC, 0x20, 0x4C, 0xDE}; while( SUCCEEDED(pEnumObj->GetNextDataObject( &pDXData )) ){ const GUID *guid; pDXData->GetType( &guid ); if(*guid == PersonID_GUID) { // PersonIDテンプレートのデータなので、NameとIDCodeを取得 HRESULT hr; hr = pDXData->GetData("Name", &Size, (void**)&pName ); hr = pDXData->GetData("IDCode", &Size, (void**)&pIDCode ); //取得したデータをコピー gstring str; COPYSTR_To_STL( str, *pName ); VctName.push_back( str ); VctID.push_back( *pIDCode ); } pDXData->Release(); // データを取得したら解放が必要 } // Xファイル関連のインターフェイスを解放 pEnumObj->Release(); pDXFile->Release(); // フォントの生成 int fontsize = 24; D3DXFONT_DESC lf = {fontsize, 0, 500, 1, 0, SHIFTJIS_CHARSET, OUT_TT_ONLY_PRECIS, PROOF_QUALITY, DEFAULT_PITCH | FF_DONTCARE, _T("HG丸ゴシックM-PRO")}; // ID3DXFontコンポーネント生成 LPD3DXFONT pD3DFont; if(FAILED(D3DXCreateFontIndirect(g_pD3DDev, &lf, &pD3DFont))){ g_pD3DDev->Release(); g_pD3D->Release(); return 0; } ShowWindow(hWnd, nCmdShow); // メッセージ ループ DWORD DataNum = VctName.size(); DWORD i; RECT r = {0,0,0,0}; do{ Sleep(1); if( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) ){ DispatchMessage(&msg);} // Direct3Dの処理 g_pD3DDev->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0 ); g_pD3DDev->BeginScene(); for(i=0; i<DataNum; i++) { SetRect( &r, 0,0,0,0); // テキスト描画 // Name pD3DFont->DrawText(NULL, VctName[i].c_str(), -1, &r, DT_CALCRECT | DT_LEFT | DT_SINGLELINE, 0xffffffff); r.top = i*fontsize; r.bottom = (i+1)*fontsize; pD3DFont->DrawText(NULL, VctName[i].c_str(), -1, &r, DT_LEFT | DT_SINGLELINE, 0xffffff00); // ID _TCHAR localstr[10]; int a = _stprintf_s( localstr, 10, _T("%d"), VctID[i]); pD3DFont->DrawText(NULL, localstr, -1, &r, DT_CALCRECT | DT_LEFT | DT_SINGLELINE, 0xffffffff); r.left += fontsize*10; r.top = i*fontsize; r.right += fontsize*10; r.bottom = (i+1)*fontsize; pD3DFont->DrawText(NULL, localstr, -1, &r, DT_LEFT | DT_SINGLELINE, 0xffffff00); } g_pD3DDev->EndScene(); g_pD3DDev->Present( NULL, NULL, NULL, NULL ); }while(msg.message != WM_QUIT); pD3DFont->Release(); g_pD3DDev->Release(); g_pD3D->Release(); return 0; }