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

DirextX编程

开发平台:

Visual C++

  1. //--------------------------------------------------------------------------------------
  2. // 主程序: Alpha_blend.cpp , 作者:曾凡喜
  3. //
  4. // 本程序示例演示如何渲染半透明物体
  5. //
  6. // 场景由两个物体组成,一个小房子和一个半透明的玻璃球
  7. //
  8. // 完成时间:2008-05-11
  9. //--------------------------------------------------------------------------------------
  10. #include "zfxd3dUtility.h"
  11. #include "zfxMesh.h"
  12. #include <stdio.h>
  13. // D3D对象接口
  14. IDirect3D9* g_pd3d;
  15. // D3D设备接口
  16. IDirect3DDevice9* g_pd3dDevice;
  17. // Cell模型
  18. CZFXMesh g_cell;
  19. // 球体模型
  20. ID3DXMesh* g_sphere;
  21. // 半透明材质
  22. D3DMATERIAL9* g_transMtrl;
  23. // 灯光
  24. D3DLIGHT9 g_dirLight;
  25. // 字体
  26. ID3DXFont* g_pFont = NULL;
  27. // 建立渲染环境
  28. bool Setup()
  29. {
  30. // 装载模型
  31. if(FAILED(g_cell.LoadMeshFromFile(g_pd3dDevice, L"cell.x")))
  32. return false;
  33. // 创建球体模型
  34. D3DXCreateSphere(g_pd3dDevice, 1.0f, 20, 20, &g_sphere, 0);
  35. // 创建透明材质
  36. g_transMtrl = new D3DMATERIAL9(GREEN_MTRL);
  37. g_transMtrl->Ambient.a = 0.5f;
  38. g_transMtrl->Diffuse.a = 0.5f;
  39. g_transMtrl->Specular.a = 0.5f;
  40. // 设定渲染状态
  41. // 设置灯光
  42. g_dirLight = InitDirectionalLight(&D3DXVECTOR3(1, -1, 1), &D3DXCOLOR(0xff88bb88));
  43. // g_pd3dDevice->SetRenderState(D3DRS_AMBIENT, 0xffffffff);
  44. g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
  45. g_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE);
  46. g_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
  47. g_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
  48. g_pd3dDevice->SetRenderState( D3DRS_BLENDOP, D3DBLENDOP_ADD);
  49. g_pd3dDevice->SetRenderState( D3DRS_SPECULARENABLE, TRUE);
  50. // 设置投影矩阵
  51. D3DXMATRIX proj;
  52. D3DXMatrixPerspectiveFovLH(
  53. &proj,
  54. D3DX_PI * 0.25f, // 45 - degree
  55. 1024.0f/768.0f,
  56. 1.0f,
  57. 1000.0f);
  58. g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &proj);
  59. return true;
  60. }
  61. bool DrawTextX()
  62. {
  63. //用于渲染侦FPS
  64. static int tmLastTime = GetTickCount();
  65. int tmNow = GetTickCount();
  66. //用于计算渲染FPS
  67. static int nFrameCount = 0;
  68. static int nFPS = 0;
  69. if(tmNow - tmLastTime > 1000)
  70. {
  71. //计算FPS
  72. tmLastTime = tmNow;
  73. nFPS = nFrameCount;
  74. nFrameCount = 0;
  75. }
  76. nFrameCount ++;
  77. char str[500];
  78. RECT rect;
  79. rect.left = rect.top = 10;
  80. rect.bottom = rect.top + 30;
  81. rect.right = rect.left + 260;
  82. sprintf_s(str, 500, "Current FPS:%d, ", nFPS);
  83. g_pFont->DrawTextA(NULL, str, (int)strlen(str), &rect, DT_LEFT|DT_NOCLIP|DT_WORDBREAK, 0xffffff00);
  84. return true;
  85. }
  86. bool Display()
  87. {
  88. // 获取两次进入函数入口的时间间隔
  89. static float lastTime = (float)timeGetTime();
  90. float curTime  = (float)timeGetTime();
  91. float timeDelta = (curTime - lastTime)*0.001f;
  92. lastTime = curTime;
  93. // 设定视口矩阵,你可以通过按下上下左右键改变视角
  94. static float angle  = (3.0f * D3DX_PI) / 2.0f;
  95. static float height = 1.0f;
  96. if( ::GetAsyncKeyState(VK_LEFT) & 0x8000f )
  97. angle -= 0.5f * timeDelta;
  98. if( ::GetAsyncKeyState(VK_RIGHT) & 0x8000f )
  99. angle += 0.5f * timeDelta;
  100. if( ::GetAsyncKeyState(VK_UP) & 0x8000f )
  101. height += 1.5f * timeDelta;
  102. if( ::GetAsyncKeyState(VK_DOWN) & 0x8000f )
  103. height -= 1.5f * timeDelta;
  104. D3DXVECTOR3 eyept( cosf(angle) * 5.0f, height, sinf(angle) * 5.0f );
  105. D3DXVECTOR3 lookAt(0.0f, 0.5f, 0.0f);
  106. D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
  107. D3DXMATRIX view_mat;
  108. D3DXMatrixLookAtLH(&view_mat, &eyept, &lookAt, &up);
  109. g_pd3dDevice->SetTransform(D3DTS_VIEW, &view_mat);
  110. // 绘制场景
  111. g_pd3dDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
  112. g_pd3dDevice->BeginScene();
  113. g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, false);
  114. g_cell.Render(g_pd3dDevice);
  115. g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, true);
  116. g_pd3dDevice->SetLight(0, &g_dirLight);
  117. g_pd3dDevice->LightEnable(0, true);
  118. g_pd3dDevice->SetMaterial(g_transMtrl);
  119. g_pd3dDevice->SetTexture(0, 0);
  120. g_sphere->DrawSubset(0);
  121. // 在屏幕上写字
  122. if(g_pFont)
  123. DrawTextX(); 
  124. g_pd3dDevice->EndScene();
  125. g_pd3dDevice->Present(0, 0, 0, 0);
  126. return true;
  127. }
  128. bool CleanUp()
  129. {
  130. g_sphere->Release();
  131. g_cell.Release();
  132. SAFE_DELETE(g_transMtrl);
  133. SAFE_RELEASE(g_pd3dDevice);
  134. SAFE_RELEASE(g_pd3d);
  135. return true;
  136. }
  137. int WINAPI WinMain(HINSTANCE hInstance,
  138.    HINSTANCE prevInstance, 
  139.    PSTR cmdLine,
  140.    int showCmd)
  141. {
  142. // 应用程序初始化
  143. if(!InitD3DApp(hInstance, false/*true代表窗口模式*/, 
  144. D3DDEVTYPE_HAL, &g_pd3d, &g_pd3dDevice, L"Alpha_blend"/*窗口标题*/, 1024, 768))
  145. {
  146. MessageBoxW(0, L"应用程序初始化失败", 0, 0);
  147. return 0;
  148. }
  149. // 创建字体
  150. if(!InitDXFont(g_pd3dDevice, &g_pFont, L"Times New Roman"))
  151. g_pFont = NULL;
  152. Setup();
  153. // 进入消息循环
  154. MSG msg;
  155. ZeroMemory(&msg, sizeof(msg));
  156. while(msg.message != WM_QUIT)
  157. {
  158. if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
  159. {
  160. TranslateMessage(&msg);
  161. DispatchMessage(&msg);
  162. }
  163. else
  164. {
  165. Display();
  166. }
  167. }
  168. CleanUp();
  169. return 0;
  170. }
  171. // 消息循环函数
  172. LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  173. {
  174. static bool bWireFrame = false;
  175. switch( msg )
  176. {
  177. case WM_DESTROY:
  178. ::PostQuitMessage(0);
  179. break;
  180. case WM_KEYDOWN:
  181. if( wParam == VK_ESCAPE )
  182. ::DestroyWindow(hwnd);
  183. break;
  184. case WM_CHAR:
  185. if(wParam == 'q'|| wParam == 'Q')
  186. bWireFrame = !bWireFrame;
  187. if(bWireFrame)
  188. g_pd3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_WIREFRAME );
  189. else
  190. g_pd3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
  191. break;
  192. }
  193. return ::DefWindowProc(hwnd, msg, wParam, lParam);
  194. }