今回は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); }
これで描画(表示)は出来ました。次はモデルを移動させたいと思います。