xfile.cpp
上传用户:zhwbfz
上传日期:2014-10-29
资源大小:8269k
文件大小:10k
源码类别:

DirextX编程

开发平台:

Visual C++

  1. //////////////////////////////////////////////////////////////////////////////////////////////////
  2. // 
  3. // File: xfile.cpp
  4. // 
  5. // Author: Frank Luna (C) All Rights Reserved
  6. //
  7. // System: AMD Athlon 1800+ XP, 512 DDR, Geforce 3, Windows XP, MSVC++ 7.0 
  8. //
  9. // Desc: Demonstrates how to load and render an XFile.
  10. //          
  11. //////////////////////////////////////////////////////////////////////////////////////////////////
  12. #include "d3dUtility.h"
  13. #include <vector>
  14. #include <math.h>
  15. //
  16. // Globals
  17. //
  18. IDirect3DDevice9* Device = 0; 
  19. const int Width  = 640;
  20. const int Height = 480;
  21. ID3DXMesh *                      house1 = 0,* house2=0,* people1=0;
  22. std::vector<D3DMATERIAL9>       Mtrls(0),Mtrls1(0),Mtrls2(0);
  23. std::vector<IDirect3DTexture9*> Textures(0),Textures1(0),Textures2(0);
  24. D3DXMATRIX V;
  25. D3DXVECTOR3 pos(-16.0f, -30.0f, -80.0f);
  26. D3DXVECTOR3 target(-0.0f, -30.0f, -120.0f);
  27. D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
  28. float startangle=atan2(6,40);
  29. // Framework functions
  30. //
  31. bool Setup()
  32. {
  33. HRESULT hr = 0;
  34. //target.x=pos.x+cos(startangle/D3DX_PI);
  35. //target.z=pos.z+sin(startangle/D3DX_PI);
  36. //
  37. // Load the XFile data.
  38. //
  39. ID3DXBuffer* adjBuffer  = 0,*adjBuffer1=0,* adjBuffer2  = 0;
  40. ID3DXBuffer* mtrlBuffer = 0,*mtrlBuffer1=0,* mtrlBuffer2 = 0;
  41. DWORD        numMtrls   = 0,numMtrls1=0,numMtrls2=0;
  42. hr = D3DXLoadMeshFromX(  
  43. "test.X",
  44. D3DXMESH_MANAGED,
  45. Device,
  46. &adjBuffer,
  47. &mtrlBuffer,
  48. 0,
  49. &numMtrls,
  50. &house1);
  51. D3DXLoadMeshFromX(  
  52. "仙剑道院.X",
  53. D3DXMESH_MANAGED,
  54. Device,
  55. &adjBuffer1,
  56. &mtrlBuffer1,
  57. 0,
  58. &numMtrls1,
  59. &house2);
  60. D3DXLoadMeshFromX(  
  61. "aaa.X",
  62. D3DXMESH_MANAGED,
  63. Device,
  64. &adjBuffer2,
  65. &mtrlBuffer2,
  66. 0,
  67. &numMtrls2,
  68. &people1);
  69. if(FAILED(hr))
  70. {
  71. ::MessageBox(0, "D3DXLoadMeshFromX() - FAILED", 0, 0);
  72. return false;
  73. }
  74. //
  75. // Extract the materials, and load textures.
  76. //
  77. if( mtrlBuffer != 0 && numMtrls != 0 )
  78. {
  79. D3DXMATERIAL* mtrls = (D3DXMATERIAL*)mtrlBuffer->GetBufferPointer();
  80. for(int i = 0; i < numMtrls; i++)
  81. {
  82. // the MatD3D property doesn't have an ambient value set
  83. // when its loaded, so set it now:
  84. mtrls[i].MatD3D.Ambient = D3DXCOLOR(1.8F,1.8F,1.8F,1.0F);
  85. //mtrls[i].MatD3D.Diffuse.a=0.5f;
  86. // save the ith material
  87. Mtrls.push_back( mtrls[i].MatD3D );
  88. // check if the ith material has an associative texture
  89. if( mtrls[i].pTextureFilename != 0 )
  90. {
  91. // yes, load the texture for the ith subset
  92. IDirect3DTexture9* tex = 0;
  93. D3DXCreateTextureFromFile(
  94. Device,
  95. mtrls[i].pTextureFilename,
  96. &tex);
  97. // save the loaded texture
  98. Textures.push_back( tex );
  99. }
  100. else
  101. {
  102. // no texture for the ith subset
  103. Textures.push_back( 0 );
  104. }
  105. }
  106. }
  107. d3d::Release<ID3DXBuffer*>(mtrlBuffer); // done w/ buffer
  108. if( mtrlBuffer1 != 0 && numMtrls1 != 0 )
  109. {
  110. D3DXMATERIAL* mtrls1 = (D3DXMATERIAL*)mtrlBuffer1->GetBufferPointer();
  111. for(int i = 0; i < numMtrls1; i++)
  112. {
  113. // the MatD3D property doesn't have an ambient value set
  114. // when its loaded, so set it now:
  115. mtrls1[i].MatD3D.Ambient = D3DXCOLOR(1.8F,1.8F,1.8F,1.0F);
  116. //mtrls[i].MatD3D.Diffuse.a=0.5f;
  117. // save the ith material
  118. Mtrls1.push_back( mtrls1[i].MatD3D );
  119. // check if the ith material has an associative texture
  120. if( mtrls1[i].pTextureFilename != 0 )
  121. {
  122. // yes, load the texture for the ith subset
  123. IDirect3DTexture9* tex = 0;
  124. D3DXCreateTextureFromFile(
  125. Device,
  126. mtrls1[i].pTextureFilename,
  127. &tex);
  128. // save the loaded texture
  129. Textures1.push_back( tex );
  130. }
  131. else
  132. {
  133. // no texture for the ith subset
  134. Textures1.push_back( 0 );
  135. }
  136. }
  137. }
  138. d3d::Release<ID3DXBuffer*>(mtrlBuffer1); // done w/ buffer
  139. if( mtrlBuffer2 != 0 && numMtrls2 != 0 )
  140. {
  141. D3DXMATERIAL* mtrls2 = (D3DXMATERIAL*)mtrlBuffer2->GetBufferPointer();
  142. for(int i = 0; i < numMtrls2; i++)
  143. {
  144. // the MatD3D property doesn't have an ambient value set
  145. // when its loaded, so set it now:
  146. mtrls2[i].MatD3D.Ambient = D3DXCOLOR(1.8F,1.8F,1.8F,1.0F);
  147. //mtrls[i].MatD3D.Diffuse.a=0.5f;
  148. // save the ith material
  149. Mtrls2.push_back( mtrls2[i].MatD3D );
  150. // check if the ith material has an associative texture
  151. if( mtrls2[i].pTextureFilename != 0 )
  152. {
  153. // yes, load the texture for the ith subset
  154. IDirect3DTexture9* tex = 0;
  155. D3DXCreateTextureFromFile(
  156. Device,
  157. mtrls2[i].pTextureFilename,
  158. &tex);
  159. // save the loaded texture
  160. Textures2.push_back( tex );
  161. }
  162. else
  163. {
  164. // no texture for the ith subset
  165. Textures2.push_back( 0 );
  166. }
  167. }
  168. }
  169. d3d::Release<ID3DXBuffer*>(mtrlBuffer2); // done w/ buffer
  170. //
  171. // Optimize the mesh.
  172. //
  173. hr = house1->OptimizeInplace(
  174. D3DXMESHOPT_ATTRSORT |
  175. D3DXMESHOPT_COMPACT  |
  176. D3DXMESHOPT_VERTEXCACHE,
  177. (DWORD*)adjBuffer->GetBufferPointer(),
  178. 0, 0, 0);
  179. d3d::Release<ID3DXBuffer*>(adjBuffer); // done w/ buffer
  180. if(FAILED(hr))
  181. {
  182. ::MessageBox(0, "OptimizeInplace() - FAILED", 0, 0);
  183. return false;
  184. }
  185. //
  186. // Set texture filters.
  187. //
  188. Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
  189. Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
  190. Device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
  191. // 
  192. // Set Lights.
  193. //
  194. D3DXVECTOR3 dir(1.0f, -1.0f, 1.0f);
  195. D3DXCOLOR col(1.0f, 1.0f, 1.0f, 1.0f);
  196. D3DLIGHT9 light = d3d::InitDirectionalLight(&dir, &col);
  197. Device->SetLight(0, &light);
  198. Device->LightEnable(0, true);
  199. Device->SetRenderState(D3DRS_NORMALIZENORMALS, true);
  200. Device->SetRenderState(D3DRS_SPECULARENABLE, true);
  201. //
  202. // Set camera.
  203. //
  204. D3DXMatrixLookAtLH(
  205. &V,
  206. &pos,
  207. &target,
  208. &up);
  209. Device->SetTransform(D3DTS_VIEW, &V);
  210. //
  211. // Set projection matrix.
  212. //
  213. D3DXMATRIX proj;
  214. D3DXMatrixPerspectiveFovLH(
  215. &proj,
  216. D3DX_PI * 0.5f, // 90 - degree
  217. (float)Width / (float)Height,
  218. 1.0f,
  219. 1000.0f);
  220. Device->SetTransform(D3DTS_PROJECTION, &proj);
  221. /*Device->SetRenderState(D3DRS_ALPHABLENDENABLE,true);
  222. Device->SetTextureStageState(0,D3DTSS_ALPHAARG1,D3DTA_TEXTURE);
  223. Device->SetTextureStageState(0,D3DTSS_ALPHAOP,D3DTOP_SELECTARG1);
  224. Device->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA);
  225. Device->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);*/
  226. Device->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE);
  227. Device->SetRenderState(D3DRS_ALPHATESTENABLE,true);
  228. Device->SetRenderState(D3DRS_ALPHAFUNC,D3DCMP_GREATER); Device->SetRenderState(D3DRS_ALPHAREF,100);
  229. return true;
  230. }
  231. void Cleanup()
  232. {
  233. d3d::Release<ID3DXMesh*>(house1);
  234. for(int i = 0; i < Textures.size(); i++)
  235. d3d::Release<IDirect3DTexture9*>( Textures[i] );
  236. }
  237. bool Display(float timeDelta)
  238. {
  239. if( Device )
  240. {
  241. //
  242. // Update: Rotate the mesh.
  243. //
  244. static float angle = startangle;
  245. //target.x=pos.x;target.z=pos.z;
  246. bool b_key=false;
  247. if(::GetAsyncKeyState(VK_LEFT)&0x8000f){angle+=0.3f;b_key=true;}
  248. if(::GetAsyncKeyState(VK_RIGHT)&0X800f){angle-=0.3f;b_key=true;}
  249. if(::GetAsyncKeyState(VK_UP)&0X8000F){
  250. pos.x+=0.08*cos(angle/180.0f*D3DX_PI);
  251. pos.z+=0.08*sin(angle/180.0f*D3DX_PI);b_key=true;
  252. }
  253. if(::GetAsyncKeyState(VK_DOWN)&0X8000F)
  254. {
  255. pos.x-=0.08*cos(angle/180.0f*D3DX_PI);
  256. pos.z-=0.08*sin(angle/180.0f*D3DX_PI);b_key=true;
  257. }
  258. if(b_key){
  259. target.x=pos.x+0.005*cos(angle/180.0f*D3DX_PI);
  260. target.z=pos.z+0.005*sin(angle/180.0f*D3DX_PI);
  261. D3DXMatrixLookAtLH(&V,&pos,&target,&up);
  262. Device->SetTransform(D3DTS_VIEW,&V);
  263. }
  264. if( angle >= 360.0f||angle<=-360.0f)
  265. angle = 0.0f;
  266. //
  267. // Render
  268. //
  269. Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x608000, 1.0f, 0);
  270. Device->BeginScene();
  271. D3DXMATRIX housemat;
  272. D3DXMATRIX roty;
  273. D3DXMatrixRotationY(&roty,D3DX_PI);
  274. D3DXMatrixIdentity(&housemat);
  275. Device->SetTransform(D3DTS_WORLD,&(roty*housemat));
  276. for(int i = 0; i < Mtrls.size(); i++)
  277. {
  278. Device->SetMaterial( &Mtrls[i] );
  279. Device->SetTexture(0, Textures[i]);
  280. house1->DrawSubset(i);
  281. }
  282. D3DXMatrixTranslation(&housemat,0.0f,-46.0f,-150.0f);
  283. Device->SetTransform(D3DTS_WORLD,&(roty*housemat));
  284. for( i = 0; i < Mtrls1.size(); i++)
  285. {
  286. Device->SetMaterial( &Mtrls1[i] );
  287. Device->SetTexture(0, Textures1[i]);
  288. house2->DrawSubset(i);
  289. }
  290. D3DXMatrixRotationY(&roty,D3DX_PI*0.5f);
  291. D3DXMatrixTranslation(&housemat,240.0f,-46.0f,-50.0f);
  292. D3DXMATRIX scal;
  293. D3DXMatrixScaling(&scal,0,2,1.5);
  294. Device->SetTransform(D3DTS_WORLD,&(roty*housemat));
  295. for( i = 0; i < Mtrls1.size(); i++)
  296. {
  297. Device->SetMaterial( &Mtrls1[i] );
  298. Device->SetTexture(0, Textures1[i]);
  299. house2->DrawSubset(i);
  300. }
  301. D3DXMatrixRotationY(&roty,D3DX_PI*0.5f);
  302. D3DXMatrixTranslation(&housemat,80.0f,-46.0f,-100.0f);
  303. Device->SetTransform(D3DTS_WORLD,&(roty*housemat));
  304. for( i = 0; i < Mtrls1.size(); i++)
  305. {
  306. Device->SetMaterial( &Mtrls1[i] );
  307. Device->SetTexture(0, Textures1[i]);
  308. house2->DrawSubset(i);
  309. }
  310. static float autorot=0.0f;
  311. D3DXMatrixRotationY(&roty,autorot);
  312. autorot+=0.023f;
  313. if(autorot>=6.28f)autorot=0.0f;
  314. D3DXMatrixTranslation(&housemat,-10.0f, -40.0f, -110.0f);
  315. D3DXMatrixScaling(&scal,0.2f,0.2f,0.2f);
  316. Device->SetTransform(D3DTS_WORLD,&(scal*roty*housemat));
  317. for( i = 0; i < Mtrls2.size(); i++)
  318. {
  319. Device->SetMaterial( &Mtrls2[i] );
  320. Device->SetTexture(0, Textures2[i]);
  321. people1->DrawSubset(i);
  322. }
  323. Device->EndScene();
  324. Device->Present(0, 0, 0, 0);
  325. }
  326. return true;
  327. }
  328. //
  329. // WndProc
  330. //
  331. LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  332. {
  333. switch( msg )
  334. {
  335. case WM_DESTROY:
  336. ::PostQuitMessage(0);
  337. break;
  338. case WM_KEYDOWN:
  339. if( wParam == VK_ESCAPE )
  340. ::DestroyWindow(hwnd);
  341. break;
  342. }
  343. return ::DefWindowProc(hwnd, msg, wParam, lParam);
  344. }
  345. //
  346. // WinMain
  347. //
  348. int WINAPI WinMain(HINSTANCE hinstance,
  349.    HINSTANCE prevInstance, 
  350.    PSTR cmdLine,
  351.    int showCmd)
  352. {
  353. if(!d3d::InitD3D(hinstance,
  354. 1024, 768, true, D3DDEVTYPE_HAL, &Device))
  355. {
  356. ::MessageBox(0, "InitD3D() - FAILED", 0, 0);
  357. return 0;
  358. }
  359. if(!Setup())
  360. {
  361. ::MessageBox(0, "Setup() - FAILED", 0, 0);
  362. return 0;
  363. }
  364. d3d::EnterMsgLoop( Display );
  365. Cleanup();
  366. Device->Release();
  367. return 0;
  368. }