導入.x文件生成漸進網格

 以先前文章中的 DirectX 框架爲基礎,寫了一個導入.x文件生成漸進網格的例子。按下'A'鍵增加網格頂點數(不超過最大值)  按下  'S'  鍵減小頂點數 (不小於最小值) 

代碼清單:

  1. //////////////////////////////////////////////////////////////////////////////////////////////////
  2. //xfile.cpp 
  3. //by tianzhihen
  4. //2008.10.19
  5. //VC8.0          
  6. //////////////////////////////////////////////////////////////////////////////////////////////////
  7. #include "d3dUtility.h"
  8. #include <vector>
  9. IDirect3DDevice9* Device = 0 ;
  10. const int Width = 640;
  11. const int Height = 480;
  12. ID3DXMesh*                      SourceMesh = 0; //網格
  13. ID3DXPMesh*                     PMesh = 0;      //漸進網格
  14. std::vector<D3DMATERIAL9>       Mtrl(0);        //材質
  15. std::vector<IDirect3DTexture9*> Textures(0);    //紋理
  16. bool Setup()
  17. {
  18.     HRESULT hr = 0;
  19.     ID3DXBuffer* adjBuffer = 0;   // 鄰接緩存
  20.     ID3DXBuffer* mtrlBuffer = 0;  // 材質緩存
  21.     DWORD numMtrls = 0;           // 材質數量
  22.     //
  23.     // 從 .X 文件中加載數據到網格
  24.     //
  25.     hr = D3DXLoadMeshFromX(
  26.         "bigship1.x",
  27.         D3DXMESH_MANAGED,//託管內存池
  28.         Device,
  29.         &adjBuffer,
  30.         &mtrlBuffer,
  31.         0,
  32.         &numMtrls,
  33.         &SourceMesh //目的網格地址
  34.         );
  35.     if(FAILED(hr))
  36.     {
  37.         ::MessageBox(0, "D3DXLoadMeshFromX() - FAILED", 0, 0);
  38.         return false;
  39.     }
  40.     if (mtrlBuffer!=0&&numMtrls!=0)
  41.     {
  42.         //材質存在
  43.         /*
  44.          typedef struct D3DXMATERIAL {
  45.                 D3DMATERIAL9 MatD3D;    //材質
  46.                 LPSTR pTextureFilename; //紋理地址
  47.             } D3DXMATERIAL, *LPD3DXMATERIAL;
  48.         */
  49.         D3DXMATERIAL* mtrls =(D3DXMATERIAL*)mtrlBuffer->GetBufferPointer();
  50.         for (int i=0;i<numMtrls;i++)
  51.         {
  52.             mtrls[i].MatD3D.Ambient = mtrls[i].MatD3D.Diffuse;  // .X 文件中沒有定義材質的環境光分量
  53.             Mtrl.push_back(mtrls[i].MatD3D);
  54.             if (mtrls[i].pTextureFilename!=0)
  55.             {
  56.                 IDirect3DTexture9* tex = 0;
  57.                 D3DXCreateTextureFromFile(Device,mtrls[i].pTextureFilename,&tex);   //加載紋理
  58.                 Textures.push_back(tex);
  59.             }
  60.             else
  61.             {
  62.                 Textures.push_back(0);
  63.             }
  64.         }
  65.     }
  66.     d3d::Release<ID3DXBuffer*>(mtrlBuffer);
  67.     //
  68.     // 優化網格數據
  69.     //
  70.     hr = SourceMesh->OptimizeInplace(
  71.             D3DXMESHOPT_ATTRSORT|
  72.             D3DXMESHOPT_COMPACT|
  73.             D3DXMESHOPT_VERTEXCACHE,
  74.             (DWORD*)adjBuffer->GetBufferPointer(),
  75.             (DWORD*)adjBuffer->GetBufferPointer(),
  76.             0,0
  77.         );
  78.     if (FAILED(hr))
  79.     {
  80.         ::MessageBox(0,"OptimizeInplace() - FAILED",0,0);
  81.         d3d::Release<ID3DXBuffer*>(adjBuffer);
  82.         return E_FAIL;
  83.     }
  84.     //
  85.     // 生成漸進網格
  86.     //
  87.     hr = D3DXGeneratePMesh(
  88.             SourceMesh,
  89.             (DWORD*)adjBuffer->GetBufferPointer(),
  90.             0,
  91.             0,
  92.             1,
  93.             D3DXMESHSIMP_FACE,
  94.             
  95.         );
  96.     d3d::Release<ID3DXMesh*>(SourceMesh);
  97.     d3d::Release<ID3DXBuffer*>(adjBuffer);
  98.     if(FAILED(hr))
  99.     {
  100.         ::MessageBox(0, "D3DXGeneratePMesh() - FAILED", 0, 0);
  101.         return E_FAIL;
  102.     }
  103.     // 設置漸進網格初始面片值爲最大
  104.     DWORD maxFaces = PMesh->GetMaxFaces();
  105.     PMesh->SetNumFaces(maxFaces);
  106.     //紋理採樣模式
  107.     Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
  108.     Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
  109.     Device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
  110.     //
  111.     // 設置光照
  112.     //
  113.     D3DXVECTOR3 dir(1.0f,-1.0f,1.0f);
  114.     D3DXCOLOR col(1.0f,1.0f,1.0f,1.0f);
  115.     D3DLIGHT9 light = d3d::InitDirectionalLight(&dir,&col);
  116.     Device->SetLight(0,&light);
  117.     Device->LightEnable(0,true);
  118.     Device->SetRenderState(D3DRS_NORMALIZENORMALS, true);
  119.     Device->SetRenderState(D3DRS_SPECULARENABLE, true);
  120.     //
  121.     // 設置取景變換矩陣
  122.     //
  123.     D3DXVECTOR3 pos(-8.0f, 4.0f, -12.0f);
  124.     D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);
  125.     D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
  126.     D3DXMATRIX V;
  127.     D3DXMatrixLookAtLH(
  128.         &V,
  129.         &pos,
  130.         &target,
  131.         &up);
  132.     Device->SetTransform(D3DTS_VIEW, &V);
  133.     //
  134.     // 設置投影矩陣
  135.     //
  136.     D3DXMATRIX proj;
  137.     D3DXMatrixPerspectiveFovLH(
  138.         &proj,
  139.         D3DX_PI * 0.5f, // 90 - degree
  140.         (float)Width / (float)Height,
  141.         1.0f,
  142.         1000.0f);
  143.     Device->SetTransform(D3DTS_PROJECTION, &proj);
  144.     return true;
  145. }
  146. void Cleanup()
  147. {
  148.     d3d::Release<ID3DXPMesh*>(PMesh);
  149.     for (int i=0;i<Textures.size();i++)
  150.     {
  151.         d3d::Release<IDirect3DTexture9*>(Textures[i]);
  152.     }
  153. }
  154. bool Display(float timeDelta)
  155. {
  156.     if (Device)
  157.     {
  158.         int numFaces = PMesh->GetNumFaces();
  159.         if (::GetAsyncKeyState('A')&0x8000f)
  160.         {
  161.             //按下'A'鍵則增加面片數
  162.             PMesh->SetNumFaces(numFaces+1);
  163.             if(PMesh->GetNumFaces()==numFaces)
  164.                 PMesh->SetNumFaces(numFaces+2);
  165.         }
  166.         if(::GetAsyncKeyState('S')&0x8000f)
  167.         {
  168.             //按下'S'鍵則減少面片數
  169.             PMesh->SetNumFaces(numFaces-1);
  170.         }
  171.         //
  172.         // 繪製場景
  173.         //
  174.         Device->Clear(0,0,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,0xffffffff,1.0f,0);
  175.         Device->BeginScene();
  176.         for (int i=0;i<Mtrl.size();i++)
  177.         {
  178.             //繪製模型
  179.             Device->SetMaterial(&Mtrl[i]);
  180.             Device->SetTexture(0,Textures[i]);
  181.             PMesh->DrawSubset(i);
  182.             // 繪製面片線框
  183.             Device->SetMaterial(&d3d::YELLOW_MTRL);
  184.             Device->SetRenderState(D3DRS_FILLMODE,D3DFILL_WIREFRAME);
  185.             PMesh->DrawSubset(i);
  186.             Device->SetRenderState(D3DRS_FILLMODE,D3DFILL_SOLID);
  187.         }
  188.         Device->EndScene();
  189.         Device->Present(0,0,0,0);
  190.         
  191.     }
  192.     return true;
  193. }
  194. //
  195. // WndProc
  196. //
  197. LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  198. {
  199.     switch( msg )
  200.     {
  201.     case WM_DESTROY:
  202.         ::PostQuitMessage(0);
  203.         break;
  204.     case WM_KEYDOWN:
  205.         if( wParam == VK_ESCAPE )
  206.             ::DestroyWindow(hwnd);
  207.         break;
  208.     }
  209.     return ::DefWindowProc(hwnd, msg, wParam, lParam);
  210. }
  211. //
  212. // WinMain
  213. //
  214. int WINAPI WinMain(HINSTANCE hinstance,
  215.                    HINSTANCE prevInstance, 
  216.                    PSTR cmdLine,
  217.                    int showCmd)
  218. {
  219.     if(!d3d::InitD3D(hinstance,
  220.         Width, Height, true, D3DDEVTYPE_HAL, &Device))
  221.     {
  222.         ::MessageBox(0, "InitD3D() - FAILED", 0, 0);
  223.         return 0;
  224.     }
  225.     if(!Setup())
  226.     {
  227.         ::MessageBox(0, "Setup() - FAILED", 0, 0);
  228.         return 0;
  229.     }
  230.     d3d::EnterMsgLoop( Display );
  231.     Cleanup();
  232.     Device->Release();
  233.     return 0;
  234. }

 

發佈了126 篇原創文章 · 獲贊 10 · 訪問量 25萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章