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

DirextX编程

开发平台:

Visual C++

  1. // cylinder.cpp : 定义应用程序的入口点。
  2. //
  3. #include "stdafx.h"
  4. #include "cylinder.h"
  5. #include "D3DEnvClass.h"
  6. #define MAX_LOADSTRING 100
  7. // 自定义顶点结构体
  8. typedef struct tagCUSTOMVERTEX{
  9. D3DXVECTOR3 position; // The position of the vertex.
  10. D3DCOLOR    color;    // The color
  11. }CUSTOMVERTEX;
  12. // 自定义顶点格式
  13. #define D3DFVF_CUSTOMVERTEX  D3DFVF_XYZ|D3DFVF_DIFFUSE
  14. // 全局变量:
  15. HINSTANCE hInst; // 当前实例
  16. TCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本
  17. TCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名
  18. // 全局变量,D3D环境对象
  19. CZFXD3DEnv g_d3dEnv;
  20. IDirect3DVertexBuffer9* g_pVB1;          //Vertex Buffer, 圆柱体的侧面
  21. IDirect3DVertexBuffer9* g_pVB2;          //Vertex Buffer, 圆柱体的上表面
  22. IDirect3DVertexBuffer9* g_pVB3;          //Vertex Buffer, 圆柱体的上表面
  23. BOOL CreateVertexBuf1( IDirect3DVertexBuffer9* & g_pVB);
  24. BOOL CreateVertexBuf2( IDirect3DVertexBuffer9* & g_pVB);
  25. BOOL CreateVertexBuf3( IDirect3DVertexBuffer9* & g_pVB);
  26. void SetupMatrices();
  27. // 此代码模块中包含的函数的前向声明:
  28. ATOM MyRegisterClass(HINSTANCE hInstance);
  29. BOOL InitInstance(HINSTANCE, int);
  30. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
  31. LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
  32. int APIENTRY _tWinMain(HINSTANCE hInstance,
  33.    HINSTANCE prevInstance, 
  34.    PSTR cmdLine,
  35.    int nCmdShow)
  36. {
  37.   // TODO: 在此放置代码。
  38. MSG msg;
  39. HACCEL hAccelTable;
  40. // 初始化全局字符串
  41. LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
  42. LoadString(hInstance, IDC_CYLINDER, szWindowClass, MAX_LOADSTRING);
  43. MyRegisterClass(hInstance);
  44. // 执行应用程序初始化:
  45. if (!InitInstance (hInstance, nCmdShow)) 
  46. {
  47. return FALSE;
  48. }
  49. hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_CYLINDER);
  50. // 主消息循环:
  51. while (GetMessage(&msg, NULL, 0, 0)) 
  52. {
  53. if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
  54. {
  55. TranslateMessage(&msg);
  56. DispatchMessage(&msg);
  57. }
  58. }
  59. return (int) msg.wParam;
  60. }
  61. //
  62. //  函数: MyRegisterClass()
  63. //
  64. //  目的: 注册窗口类。
  65. //
  66. //  注释: 
  67. //
  68. //    仅当希望在已添加到 Windows 95 的
  69. //    “RegisterClassEx”函数之前此代码与 Win32 系统兼容时,
  70. //    才需要此函数及其用法。调用此函数
  71. //    十分重要,这样应用程序就可以获得关联的
  72. //   “格式正确的”小图标。
  73. //
  74. ATOM MyRegisterClass(HINSTANCE hInstance)
  75. {
  76. WNDCLASSEX wcex;
  77. wcex.cbSize = sizeof(WNDCLASSEX); 
  78. wcex.style = CS_HREDRAW | CS_VREDRAW;
  79. wcex.lpfnWndProc = (WNDPROC)WndProc;
  80. wcex.cbClsExtra = 0;
  81. wcex.cbWndExtra = 0;
  82. wcex.hInstance = hInstance;
  83. wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_CYLINDER);
  84. wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
  85. wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  86. wcex.lpszMenuName = (LPCTSTR)IDC_CYLINDER;
  87. wcex.lpszClassName = szWindowClass;
  88. wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
  89. return RegisterClassEx(&wcex);
  90. }
  91. //
  92. //   函数: InitInstance(HANDLE, int)
  93. //
  94. //   目的: 保存实例句柄并创建主窗口
  95. //
  96. //   注释: 
  97. //
  98. //        在此函数中,我们在全局变量中保存实例句柄并
  99. //        创建和显示主程序窗口。
  100. //
  101. BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
  102. {
  103.    HWND hWnd;
  104.    hInst = hInstance; // 将实例句柄存储在全局变量中
  105.    hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
  106.       CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
  107.    if (!hWnd)
  108.    {
  109.       return FALSE;
  110.    }
  111.    if(FAILED(g_d3dEnv.InitD3D(TRUE, hWnd)))
  112.    return FALSE;
  113.    if( !CreateVertexBuf1(g_pVB1))
  114. {
  115. MessageBox(NULL, "Create Vertex Buffer Failed", "Textures.exe", MB_OK);
  116. return FALSE;
  117. }
  118. if( !CreateVertexBuf2(g_pVB2))
  119. {
  120. MessageBox(NULL, "Create Vertex Buffer Failed", "Textures.exe", MB_OK);
  121. return FALSE;
  122. }
  123. if( !CreateVertexBuf3(g_pVB3))
  124. {
  125. MessageBox(NULL, "Create Vertex Buffer Failed", "Textures.exe", MB_OK);
  126. return FALSE;
  127. }
  128.    ShowWindow(hWnd, nCmdShow);
  129.    UpdateWindow(hWnd);
  130.    return TRUE;
  131. }
  132. //
  133. //  函数: WndProc(HWND, unsigned, WORD, LONG)
  134. //
  135. //  目的: 处理主窗口的消息。
  136. //
  137. //  WM_COMMAND - 处理应用程序菜单
  138. //  WM_PAINT - 绘制主窗口
  139. //  WM_DESTROY - 发送退出消息并返回
  140. //
  141. //
  142. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  143. {
  144. int wmId, wmEvent;
  145. // PAINTSTRUCT ps;
  146. // HDC hdc;
  147. switch (message) 
  148. {
  149. case WM_COMMAND:
  150. wmId    = LOWORD(wParam); 
  151. wmEvent = HIWORD(wParam); 
  152. // 分析菜单选择:
  153. switch (wmId)
  154. {
  155. case IDM_ABOUT:
  156. DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
  157. break;
  158. case IDM_EXIT:
  159. DestroyWindow(hWnd);
  160. break;
  161. default:
  162. return DefWindowProc(hWnd, message, wParam, lParam);
  163. }
  164. break;
  165. case WM_PAINT:
  166. //hdc = BeginPaint(hWnd, &ps);
  167. // TODO: 在此添加任意绘图代码...
  168. //EndPaint(hWnd, &ps);
  169. // 确信设备未丢失,如果丢失,函数会完成重置设备功能
  170. g_d3dEnv.MakeSureNotLost();
  171. // 清除屏幕
  172. g_d3dEnv.m_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0,0,0,0), 1.0f, 0 );
  173. // 开始渲染
  174. g_d3dEnv.m_pd3dDevice->BeginScene();
  175. // 在此渲染你要呈现的场景
  176. // .....
  177. // 设置变换矩阵
  178. SetupMatrices();
  179. // 设置渲染状态
  180. g_d3dEnv.m_pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
  181. g_d3dEnv.m_pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
  182. g_d3dEnv.m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
  183. g_d3dEnv.m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
  184. // 输出顶点流
  185. g_d3dEnv.m_pd3dDevice->SetStreamSource(0, g_pVB1, 0, sizeof(CUSTOMVERTEX));
  186. g_d3dEnv.m_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
  187. g_d3dEnv.m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 98);
  188. g_d3dEnv.m_pd3dDevice->SetStreamSource(0, g_pVB2, 0, sizeof(CUSTOMVERTEX));
  189. g_d3dEnv.m_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
  190. g_d3dEnv.m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 49);
  191. g_d3dEnv.m_pd3dDevice->SetStreamSource(0, g_pVB3, 0, sizeof(CUSTOMVERTEX));
  192. g_d3dEnv.m_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
  193. g_d3dEnv.m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 49);
  194. g_d3dEnv.m_pd3dDevice->EndScene();
  195. // 将后台缓冲的数据搬到屏幕
  196. g_d3dEnv.m_pd3dDevice->Present( NULL, NULL, NULL, NULL );
  197. break;
  198. case WM_DESTROY:
  199. PostQuitMessage(0);
  200. g_pVB1->Release();
  201. g_pVB2->Release();
  202. g_pVB3->Release();
  203. g_d3dEnv.Release();
  204. break;
  205. default:
  206. return DefWindowProc(hWnd, message, wParam, lParam);
  207. }
  208. return 0;
  209. }
  210. // “关于”框的消息处理程序。
  211. LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  212. {
  213. switch (message)
  214. {
  215. case WM_INITDIALOG:
  216. return TRUE;
  217. case WM_COMMAND:
  218. if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) 
  219. {
  220. EndDialog(hDlg, LOWORD(wParam));
  221. return TRUE;
  222. }
  223. break;
  224. }
  225. return FALSE;
  226. }
  227. //100 Vertices created.........
  228. BOOL CreateVertexBuf1(IDirect3DVertexBuffer9* & g_pVB)
  229. {
  230. CUSTOMVERTEX pVertices[100];
  231. ZeroMemory( pVertices, 100*sizeof( CUSTOMVERTEX ) );
  232. for(int i=0;i<50;i++)
  233. {
  234. FLOAT alpha = (2*D3DX_PI*i)/49;
  235. pVertices[2*i].position   =  D3DXVECTOR3( sinf(alpha), 1.0f, cosf(alpha));
  236. pVertices[2*i].color      =  0x88ffffff;
  237. pVertices[2*i+1].position =  D3DXVECTOR3( sinf(alpha),-1.0f, cosf(alpha));
  238. pVertices[2*i+1].color      =  0x88ffffff;
  239. }
  240. if( FAILED(g_d3dEnv.m_pd3dDevice->CreateVertexBuffer( 100*sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX
  241. , D3DPOOL_DEFAULT, &g_pVB, NULL)))
  242. return FALSE;
  243. void* pData;
  244. g_pVB->Lock(0, 100*sizeof(CUSTOMVERTEX), (void**)&pData, 0);
  245. memcpy(pData, pVertices, 100*sizeof(CUSTOMVERTEX));
  246. g_pVB->Unlock();
  247. return TRUE;
  248. }
  249. BOOL CreateVertexBuf2(IDirect3DVertexBuffer9* & g_pVB)
  250. {
  251. CUSTOMVERTEX pVertices[51];
  252. ZeroMemory( pVertices, 51*sizeof( CUSTOMVERTEX ) );
  253. pVertices[0].position = D3DXVECTOR3( 0.0f, 1.0f, 0.0f);
  254. pVertices[0].color    = 0x88ffffff;
  255. for(int i=0;i<50;i++)
  256. {
  257. FLOAT alpha = (2*D3DX_PI*i)/49;
  258. pVertices[i+1].position   =  D3DXVECTOR3( sinf(alpha), 1.0f, cosf(alpha));
  259. pVertices[i+1].color      =  0x88ffffff;
  260. }
  261. if( FAILED(g_d3dEnv.m_pd3dDevice->CreateVertexBuffer( 51*sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX
  262. , D3DPOOL_DEFAULT, &g_pVB, NULL)))
  263. return FALSE;
  264. void* pData;
  265. g_pVB->Lock(0, 51*sizeof(CUSTOMVERTEX), (void**)&pData, 0);
  266. memcpy(pData, pVertices, 51*sizeof(CUSTOMVERTEX));
  267. g_pVB->Unlock();
  268. return TRUE;
  269. }
  270. BOOL CreateVertexBuf3(IDirect3DVertexBuffer9* & g_pVB)
  271. {
  272. CUSTOMVERTEX pVertices[51];
  273. ZeroMemory( pVertices, 51*sizeof( CUSTOMVERTEX ) );
  274. pVertices[0].position = D3DXVECTOR3( 0.0f, -1.0f, 0.0f);
  275. pVertices[0].color    = 0x88ffffff;
  276. for(int i=0;i<50;i++)
  277. {
  278. FLOAT alpha = (2*D3DX_PI*i)/49;
  279. pVertices[i+1].position   =  D3DXVECTOR3( sinf(alpha), -1.0f, cosf(alpha));
  280. pVertices[i+1].color      =  0x88ffffff;
  281. }
  282. if( FAILED(g_d3dEnv.m_pd3dDevice->CreateVertexBuffer( 51*sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX
  283. , D3DPOOL_DEFAULT, &g_pVB, NULL)))
  284. return FALSE;
  285. void* pData;
  286. g_pVB->Lock(0, 51*sizeof(CUSTOMVERTEX), (void**)&pData, 0);
  287. memcpy(pData, pVertices, 51*sizeof(CUSTOMVERTEX));
  288. g_pVB->Unlock();
  289. return TRUE;
  290. }
  291. void SetupMatrices()
  292. {
  293. // Set up world matrix
  294. D3DXMATRIX matWorld;
  295. D3DXMatrixIdentity( &matWorld );
  296. g_d3dEnv.m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
  297. // Set up our view matrix. A view matrix can be defined given an eye point,
  298. // a point to lookat, and a direction for which way is up. Here, we set the
  299. // eye five units back along the z-axis and up three units, look at the
  300. // origin, and define "up" to be in the y-direction.
  301. D3DXVECTOR3 vEyePt( 0.0f, 2.0f,-4.0f );
  302. D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
  303. D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
  304. D3DXMATRIX matView;
  305. D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
  306. g_d3dEnv.m_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
  307. // For the projection matrix, we set up a perspective transform (which
  308. // transforms geometry from 3D view space to 2D viewport space, with
  309. // a perspective divide making objects smaller in the distance). To build
  310. // a perpsective transform, we need the field of view (1/4 pi is common),
  311. // the aspect ratio, and the near and far clipping planes (which define at
  312. // what distances geometry should be no longer be rendered).
  313. D3DXMATRIX matProj;
  314. D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 20.0f );
  315. g_d3dEnv.m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
  316. }