今回はXファイルの読み込みから描画までをザラッと行きます。 途中ライトの設定なんかも出てきますが、今は気にせず・・・。後々解説しようと思います。
//---------------------------------------------------------------------------//
//メッシュ構造体
//---------------------------------------------------------------------------//
struct THING
{
LPD3DXMESH pMesh; //メッシュオブジェクト
D3DMATERIAL9 *pMeshMaterials; //マテリアルオブジェクト
LPDIRECT3DTEXTURE9 *pMeshTextures; //テクスチャ
DWORD dwNumMaterials; //マテリアル数
THING()
{
ZeroMemory(this, sizeof(THING)); //初期化
}
};
//---------------------------------------------------------------------------//
//物体初期化関数
//---------------------------------------------------------------------------//
HRESULT InitThing(THING *pThing, LPSTR szXFileName)
{
//Xファイルからメッシュをロードする
LPD3DXBUFFER pD3DXMtrlBuffer = NULL;
if(FAILED(D3DXLoadMeshFromX(szXFileName,
D3DXMESH_SYSTEMMEM, //システムメモリを使う
pDevice, NULL,
&pD3DXMtrlBuffer, //マテリアルを読み込むバッファ
NULL,
&pThing->dwNumMaterials, //読み込んだテクスチャ数
&pThing->pMesh))) //読み込んだメッシュ
{
MessageBox(NULL, "Xファイルの読み込みに失敗",
NULL, MB_OK);
}
D3DXMATERIAL *d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();
pThing->pMeshMaterials = new D3DMATERIAL9[pThing->dwNumMaterials];
pThing->pMeshTextures = new LPDIRECT3DTEXTURE9[pThing->dwNumMaterials];
//マテリアルとテクスチャの設定
for(DWORD i = 0 ; i < pThing->dwNumMaterials ; i++)
{
pThing->pMeshMaterials[i] = d3dxMaterials[i].MatD3D;
pThing->pMeshMaterials[i].Ambient = pThing->pMeshMaterials[i].Diffuse;
pThing->pMeshTextures[i] = NULL;
if(d3dxMaterials[i].pTextureFilename != NULL &&
lstrlen(d3dxMaterials[i].pTextureFilename) > 0)
{
//テクスチャの読み込み
if(FAILED(D3DXCreateTextureFromFile(
pDevice,
d3dxMaterials[i].pTextureFilename, //テクスチャファイル名
&pThing->pMeshTextures[i]))) //テクスチャオブジェクト
{
MessageBox(NULL, "テクスチャの読み込みに失敗しました", NULL, MB_OK);
}
}
}
pD3DXMtrlBuffer->Release();
return S_OK;
}
InitThingの使い方
InitThing(&Thing, "モデル名.x");
また、今回はライトを使用するので
pDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
ライトをオンにしておきます。
//---------------------------------------------------------------------------//
//レンダリング関数
//---------------------------------------------------------------------------//
VOID Render()
{
//ワールドトランスフォーム(絶対座標変換)
D3DXMATRIXA16 matWorld;
D3DXMATRIXA16 matPosition;
D3DXMatrixIdentity(&matWorld);
//移動行列の作成
D3DXMatrixTranslation(&matPosition, 0.0f, 0.0f, 0.0f);
//ワールド行列に移動行列をかける(matWorld *= matPosition)
D3DXMatrixMultiply(&matWorld, &matWorld, &matPosition);
//ワールド座標に変換
pDevice->SetTransform(D3DTS_WORLD, &matWorld);
//ビュートランスフォーム(視点座標変換)
D3DXVECTOR3 vecEyePt(0.0f, 0.0f, 0.0f); //カメラ位置
D3DXVECTOR3 vecLookatPt(0.0f, 0.0f, 0.0f); //注視位置
D3DXVECTOR3 vecUpVec(0.0f, 1.0f, 0.0f); //上方位置
D3DXMATRIXA16 matView;
//カメラ位置、注視位置、上方位置の合成
D3DXMatrixLookAtLH(&matView, &vecEyePt, &vecLookatPt, &vecUpVec);
pDevice->SetTransform(D3DTS_VIEW, &matView);
//プロジェクショントランスフォーム(射影変換)
D3DXMATRIXA16 matProj;
D3DXMatrixPerspectiveFovLH(&matProj,
D3DX_PI/4,
1.0f,
1.0f,
100.0f);
pDevice->SetTransform(D3DTS_PROJECTION, &matProj);
//ライトをあてる(白色で鏡面反射あり)
D3DXVECTOR3 vecDirection(0, -1, 1); //ライトを向ける方向
D3DLIGHT9 light; //ライト構造体
ZeroMemory(&light, sizeof(D3DLIGHT9)); //初期化
light.Type = D3DLIGHT_DIRECTIONAL; //普通の光源
//ディフューズ色
light.Diffuse.r = 1.0f;
light.Diffuse.g = 1.0f;
light.Diffuse.b = 1.0f;
//スペキュラ色
light.Specular.r = 1.0f;
light.Specular.g = 1.0f;
light.Specular.b = 1.0f;
//ライトの方向を構造体に割り当て
D3DXVec3Normalize((D3DXVECTOR3*)&light.Direction, &vecDirection);
light.Range = 200.0f;
pDevice->SetLight(0, &light); //ライトを設置
pDevice->LightEnable(0, TRUE); //ライトを当てる
//画面の初期化
pDevice->Clear(0, NULL,
D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
D3DCOLOR_XRGB(100, 100, 100),
1.0f,0);
//描画開始
if(SUCCEEDED(pDevice->BeginScene()))
{
//マテリアル数分繰り返し
for(DWORD i = 0 ; i< Thing.dwNumMaterials ; i++)
{
pDevice->SetMaterial(&Thing.pMeshMaterials[i]);
pDevice->SetTexture(0, Thing.pMeshTextures[i]);
Thing.pMesh->DrawSubset(i);
}
pDevice->EndScene();
}
//フリップ(バックバッファを表に出す)
pDevice->Present(NULL, NULL, NULL, NULL);
}
これで描画(表示)は出来ました。次はモデルを移動させたいと思います。