导入.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. }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值