light.cpp
上传用户:junlon
上传日期:2022-01-05
资源大小:39075k
文件大小:6k
源码类别:

DirextX编程

开发平台:

Visual C++

  1. #include "zfxd3dUtility.h"
  2. #include <stdio.h>
  3. // D3D对象接口
  4. IDirect3D9* g_pd3d;
  5. // D3D设备接口
  6. IDirect3DDevice9* g_pd3dDevice;
  7. // 字体
  8. ID3DXFont* g_pFont = NULL;
  9. // 光源定义
  10. D3DLIGHT9 g_pointLight;
  11. D3DLIGHT9 g_directionalLight;
  12. D3DLIGHT9 g_spotLight;
  13. // 表明开启第几个灯
  14. int g_nlight_Enabled = 0;
  15. // 物体定义
  16. ID3DXMesh* g_object[4] = {0, 0, 0, 0};
  17. // 世界矩阵定义,每个物体对应一个世界矩阵
  18. D3DXMATRIX  g_world_mat[4];
  19. // 材质定义
  20. D3DMATERIAL9 g_mtrl[4];
  21. // 建立渲染环境
  22. bool Setup()
  23. {
  24. // 点光源初始化
  25. D3DXVECTOR3 pos(0, 0, 0);
  26. D3DXCOLOR yellow_color = YELLOW;
  27. g_pointLight = InitPointLight(&pos, &yellow_color);
  28. // 方向光源初始化
  29. D3DXVECTOR3 direction(1, -1, 0);
  30. D3DXCOLOR white_color = WHITE;
  31. g_directionalLight = InitDirectionalLight(&direction, &white_color);
  32. // 聚光灯初始化
  33. D3DXVECTOR3 spot_pos(4, 4, 0);
  34. D3DXVECTOR3 spot_direction(-1, -1, 0);
  35. D3DXCOLOR red_color = WHITE;
  36. g_spotLight = InitSpotLight(&spot_pos, &spot_direction, &red_color);
  37. // 材质初始化
  38. g_mtrl[0] = RED_MTRL;
  39. g_mtrl[1] = BLUE_MTRL;
  40. g_mtrl[2] = GREEN_MTRL;
  41. g_mtrl[3] = YELLOW_MTRL;
  42. // 世界矩阵初始化
  43. D3DXMatrixTranslation(&g_world_mat[0],  0.0f,  2.0f, 0.0f);
  44. D3DXMatrixTranslation(&g_world_mat[1],  0.0f, -3.0f, 0.0f);
  45. D3DXMatrixTranslation(&g_world_mat[2], -3.0f,  0.0f, 0.0f);
  46. D3DXMatrixTranslation(&g_world_mat[3],  3.0f,  0.0f, 0.0f);
  47. // 创建物体
  48. D3DXCreateTeapot(g_pd3dDevice, &g_object[0], 0);
  49. D3DXCreateSphere(g_pd3dDevice, 1.0f, 20, 20, &g_object[1], 0);
  50. D3DXCreateTorus(g_pd3dDevice, 0.5f, 1.0f, 20, 20, &g_object[2], 0);
  51. D3DXCreateCylinder(g_pd3dDevice, 0.5f, 0.5f, 2.0f, 20, 20, &g_object[3], 0);
  52. // 设定光源
  53. g_pd3dDevice->SetLight(0, &g_pointLight);
  54. g_pd3dDevice->SetLight(1, &g_directionalLight);
  55. g_pd3dDevice->SetLight(2, &g_spotLight);
  56. // 设定渲染状态
  57. g_pd3dDevice->SetRenderState(D3DRS_NORMALIZENORMALS, true);
  58. g_pd3dDevice->SetRenderState(D3DRS_SPECULARENABLE, true);
  59. g_pd3dDevice->SetRenderState(D3DRS_AMBIENT, 0xff333333);
  60. // 设置投影矩阵
  61. D3DXMATRIX proj;
  62. D3DXMatrixPerspectiveFovLH(
  63. &proj,
  64. D3DX_PI * 0.25f, // 45 - degree
  65. 1,
  66. 1.0f,
  67. 100.0f);
  68. g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &proj);
  69. return true;
  70. }
  71. bool DrawTextX()
  72. {
  73. //用于渲染侦FPS
  74. static int tmLastTime = GetTickCount();
  75. int tmNow = GetTickCount();
  76. //用于计算渲染FPS
  77. static int nFrameCount = 0;
  78. static int nFPS = 0;
  79. if(tmNow - tmLastTime > 1000)
  80. {
  81. //计算FPS
  82. tmLastTime = tmNow;
  83. nFPS = nFrameCount;
  84. nFrameCount = 0;
  85. }
  86. nFrameCount ++;
  87. char str[500];
  88. RECT rect;
  89. rect.left = rect.top = 10;
  90. rect.bottom = rect.top + 30;
  91. rect.right = rect.left + 260;
  92. sprintf(str, "Current FPS:%d, please press Q to toggle WireFrame mode, 
  93. and press LButton to enable a different Light source", nFPS);
  94. g_pFont->DrawTextA(NULL, str, (int)strlen(str), &rect, DT_LEFT|DT_NOCLIP|DT_WORDBREAK, 0xffffff00);
  95. return true;
  96. }
  97. bool Display()
  98. {
  99. // 获取两次进入函数入口的时间间隔
  100. static float lastTime = (float)timeGetTime();
  101. float curTime  = (float)timeGetTime();
  102. float timeDelta = (curTime - lastTime)*0.001f;
  103. lastTime = curTime;
  104. // 设定视口矩阵,你可以通过按下上下左右键改变视角
  105. static float angle  = (3.0f * D3DX_PI) / 2.0f;
  106. static float height = 5.0f;
  107. if( ::GetAsyncKeyState(VK_LEFT) & 0x8000f )
  108. angle -= 0.5f * timeDelta;
  109. if( ::GetAsyncKeyState(VK_RIGHT) & 0x8000f )
  110. angle += 0.5f * timeDelta;
  111. if( ::GetAsyncKeyState(VK_UP) & 0x8000f )
  112. height += 1.5f * timeDelta;
  113. if( ::GetAsyncKeyState(VK_DOWN) & 0x8000f )
  114. height -= 1.5f * timeDelta;
  115. D3DXVECTOR3 eyept( cosf(angle) * 10.0f, height, sinf(angle) * 10.0f );
  116. D3DXVECTOR3 lookAt(0.0f, 0.0f, 0.0f);
  117. D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
  118. D3DXMATRIX view_mat;
  119. D3DXMatrixLookAtLH(&view_mat, &eyept, &lookAt, &up);
  120. g_pd3dDevice->SetTransform(D3DTS_VIEW, &view_mat);
  121. // 设定灯光
  122. g_pd3dDevice->LightEnable( g_nlight_Enabled % 3, true);
  123. g_pd3dDevice->LightEnable( (g_nlight_Enabled + 1)%3, false);
  124. g_pd3dDevice->LightEnable( (g_nlight_Enabled + 2)%3, false);
  125. // 绘制场景
  126. g_pd3dDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
  127. g_pd3dDevice->BeginScene();
  128. for(int i = 0; i < 4; i++)
  129. {
  130. // 设置相关的材质和世界矩阵,然后绘制物体
  131. g_pd3dDevice->SetMaterial(&g_mtrl[i]);
  132. g_pd3dDevice->SetTransform(D3DTS_WORLD, &g_world_mat[i]);
  133. g_object[i]->DrawSubset(0);
  134. }
  135. // 在屏幕上写字
  136. if(g_pFont)
  137. DrawTextX();
  138. g_pd3dDevice->EndScene();
  139. g_pd3dDevice->Present(0, 0, 0, 0);
  140. return true;
  141. }
  142. bool CleanUp()
  143. {
  144. SAFE_RELEASE(g_pd3dDevice);
  145. SAFE_RELEASE(g_pd3d);
  146. for(int i = 0; i < 4; i++)
  147. SAFE_RELEASE(g_object[i]);
  148. return true;
  149. }
  150. int WINAPI WinMain(HINSTANCE hInstance,
  151.    HINSTANCE prevInstance, 
  152.    PSTR cmdLine,
  153.    int showCmd)
  154. {
  155. // 应用程序初始化
  156. if(!InitD3DApp(hInstance, false/*true代表窗口模式*/, 
  157. D3DDEVTYPE_HAL, &g_pd3d, &g_pd3dDevice, "light"/*窗口标题*/, 1024, 768))
  158. {
  159. MessageBoxW(0, L"应用程序初始化失败", 0, 0);
  160. return 0;
  161. }
  162. // 创建字体
  163. if(!InitDXFont(g_pd3dDevice, &g_pFont, "Times New Roman"))
  164. g_pFont = NULL;
  165. Setup();
  166. // 进入消息循环
  167. MSG msg;
  168. ZeroMemory(&msg, sizeof(msg));
  169. while(msg.message != WM_QUIT)
  170. {
  171. if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
  172. {
  173. TranslateMessage(&msg);
  174. DispatchMessage(&msg);
  175. }
  176. else
  177. {
  178. Display();
  179. }
  180. }
  181. CleanUp();
  182. return 0;
  183. }
  184. // 消息循环函数
  185. LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  186. {
  187. static bool bWireFrame = false;
  188. switch( msg )
  189. {
  190. case WM_DESTROY:
  191. ::PostQuitMessage(0);
  192. break;
  193. case WM_LBUTTONDOWN:
  194. g_nlight_Enabled++;
  195. break;
  196. case WM_KEYDOWN:
  197. if( wParam == VK_ESCAPE )
  198. ::DestroyWindow(hwnd);
  199. break;
  200. case WM_CHAR:
  201. if(wParam == 'q')
  202. bWireFrame = !bWireFrame;
  203. if(bWireFrame)
  204. g_pd3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_WIREFRAME );
  205. else
  206. g_pd3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
  207. break;
  208. }
  209. return ::DefWindowProc(hwnd, msg, wParam, lParam);
  210. }