XFile描画

■必要知識

XFile描画について知っておいたほうがいいと思われる内容がいくつかあります。
以下の単語についてあいまいな場合はリンク先の内容を確認して下さい。

	・ポリゴン
	・メッシュ
	・頂点バッファ
	・インデックスバッファ
	・3Dモデル概要

	ポリゴン
	3Dモデル(基本)
	
●サンプル
	以下のリンクはXFile読み込みのサンプルプロジェクトです。

	描画サンプル
		DirectX.h、DirectX.cpp
			DirectX9に関する初期化、描画開始、終了処理
		XFile.h、XFile.cpp
			XFileの読み込み、描画を行うXFileクラス
		Drawer.h、Drawer.cpp
			描画クラス

■XFile読み込み

XFileの読み込みは、DirectX側が読み込むための関数やデータ型を
用意してくれているので、比較的簡単に読み込むことができます。
読み込みは以下の手順で行います。
※読み込みのサポートはDirectX9までです。

①.ファイル読み込み
	まずは「.x」拡張子のファイルを読み込むところから始まります。
	読み込みには「D3DXLoadMeshFromX」関数を使用します

	・関数情報
		関数名:
			D3DXLoadMeshFromX
	
		戻り値:
			読み込み結果
				S_OK:成功
				E_FAIL:失敗
	
		引数:
			LPCTSTR pFilename:
				ファイル名
	
			DWORD Options:
				メッシュ作成用のオプションを指定

			LPDIRECT3DDEVICE9 pDevice:
				Direct3DDevice
		
			LPD3DXBUFFER* ppAdjacency:
				基本未使用(NULL)
	
			LPD3DXBUFFER* ppMaterials:
				マテリアル情報

			LPD3DXBUFFER* ppEffectInstances:
				基本未使用(NULL)
		
			DWORD* pNumMaterials:
				XFileに使用されているマテリアルの数
		
			LPD3DXMESH* ppMesh:
				XFileのメッシュデータ
		
		内容:
			XFileを読み込みその結果を返す

	XFileの読み込みが無事完了すると「ppMaterials」「pNumMaterials」「ppMesh」の
	3つにXFileの必要な情報が格納されます。

②.マテリアル情報のコピー
	D3DXLoadMeshFromXの読み込みが完了した時点で、
	メッシュの読み込みは完了して「ppMesh」に格納されており、
	描画できるようになっています。
	ただ、メッシュの情報は頂点バッファやインデックスバッファなどで、
	マテリアルについては情報が入っていません。
	マテリアルは「ppMaterials」「pNumMaterials」に格納されているので、
	このデータをコピーしてマテリアルを描画時に使えるようにします。
	以下はサンプルプロジェクトのコードを抜粋した内容です。

	・例
		// バッファの先頭ポインタをD3DXMATERIALにキャストして取得
		D3DXMATERIAL *pmat_list = (D3DXMATERIAL*)p_material_buffer->GetBufferPointer();

		// 各メッシュのマテリアル情報を取得する
		for (DWORD i = 0; i < m_MaterialNum; i++)
		{
			// マテリアル取得
			m_pMeshMaterialList[i] = pmat_list[i].MatD3D;
			m_pTextureList[i] = NULL;

			// マテリアルで設定されているテクスチャ読み込み
			if (pmat_list[i].pTextureFilename != NULL)
			{
				std::string file_name = pmat_list[i].pTextureFilename;
				LPDIRECT3DTEXTURE9 texture = NULL;
				if (g_TextureList[file_name] == NULL)
				{
					D3DXCreateTextureFromFileA(g_pD3DDevice,
								file_name.c_str(),
								&g_TextureList[file_name]);
				}

				m_pTextureList[i] = g_TextureList[file_name];
			}
		}

		// マテリアルのコピーが終わったのでバッファを解放する
		p_material_buffer->Release();

	上記の手順を行うことでXFileを使用することができます。

■XFile描画

DirectX9で用意されているXFileの描画処理はフレームやメッシュ単位ではなく、
マテリアル単位で行います。
D3DXLoadMeshFromXで読み込まれたメッシュは「LPD3DXMESH* ppMesh」に格納されていますが、
メッシュのデータとしてサブセットというマテリアルを共有するポリゴンの集まりでまとめています。
そのサブセットを「DrawSubset」という関数で描画します。

●関数情報
	関数名:
		DrawSubset
	
	戻り値:
		描画結果:
			S_OK:成功
			E_FAIL:失敗
	
	引数:
		DWORD AttribId:
			サブセットの番号
	
	内容:
		引数で指定したサブセットのメッシュを描画する

●マテリアルの反映
	DrawSubSetはメッシュの描画を行いますが、マテリアルの反映は行いません。
	マテリアルの反映は「SetMaterial」や「SetTexture」を
	メッシュの描画前に指定してマテリアルの反映を行います。

	for (DWORD i = 0; i < マテリアルの数; i++)
	{
		SetMaterial(サブセットのマテリアル);
		SetTexture(0, マテリアルで使用しているテクスチャ);
		mesh->DrawSubSet(サブセット番号);
	}

■後処理

ゲーム上で不要になったXFileのデータは後処理を行わないと
メモリリークが発生しますのできちんと後処理を行います。

●解放の必要があるデータ
	XFileの後処理で最低でも解放する必要があるのは
	「D3DXLoadMeshFromX」関数の最後の引数に指定したメッシュデータです。
	これはデータ自体にRelease関数があるのでそちらを使用します。

		メッシュデータ->Release();

	次に読み込み後に動的に確保した配列などの解放を行います。
	サンプルプロジェクトでは「メッシュのマテリアル格納用の配列(m_pMeshMaterialList)」と
	「マテリアルで設定されているテクスチャ用の配列(m_pTextureList)」の
	二つをnewで確保しているので、この二つの配列を解放します。

		delete[] (m_pMeshMaterialList);
		delete[] (m_pTextureList);

	最後にXFileで使用しているテクスチャの解放も行いますが、
	こちらはゲーム中に使いまわしているテクスチャの可能性もありますので、
	解放するかどうかはリソース状況によります。

		テクスチャ->Release();
	
	上記の処理全てをサンプルプロジェクトのXFileクラスのデストラクタで行っています。