1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346
| //============================================================================= // Desc: 绘制茶壶模型 //============================================================================= #include <d3dx9.h> //该头文件中又包含了d3d9.h头文件 #include <tchar.h> #include <d3dx9core.h> #include "UtilMacro.h"
//----------------------------------------------------------------------------- // Desc: 全局变量 //----------------------------------------------------------------------------- LPDIRECT3D9 g_pD3D = NULL; //Direct3D对象 LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; //Direct3D设备对象 LPD3DXFONT g_pFont = 0; //字体对象 LPD3DXMESH g_pTeapotMesh = NULL; //茶壶网格模型
RECT g_ClientRect; //窗口客户区 float g_FPS = 0; //帧速率 WCHAR g_strFPS[20]; //包含帧速率的字符数组
//----------------------------------------------------------------------------- // Desc: 顶点结构和顶点格式 //----------------------------------------------------------------------------- struct CUSTOMVERTEX { D3DXVECTOR3 position; DWORD color; }; #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE)
//----------------------------------------------------------------------------- // Desc: 设置世界矩阵 //----------------------------------------------------------------------------- void SetWorldMatrix() { //创建并设置世界矩阵 D3DXMATRIXA16 matWorld; float time = timeGetTime() * 0.001f; float fAngle = time * D3DX_PI / 2; //fAngle = 0; D3DXMatrixRotationY(&matWorld, fAngle); //旋转 g_pd3dDevice->SetTransform(D3DTS_WORLD, &matWorld); }
//----------------------------------------------------------------------------- // Desc: 设置观察矩阵和投影矩阵 //----------------------------------------------------------------------------- void SetViewandProjMatrices() { //建立并设置观察矩阵 D3DXVECTOR3 vEyePt(0.0f, 0.0f, -5.0f); D3DXVECTOR3 vLookatPt(0.0f, 0.0f, 0.0f); D3DXVECTOR3 vUpVec(0.0f, 1.0f, 0.0f); D3DXMATRIXA16 matView; D3DXMatrixLookAtLH(&matView, &vEyePt, &vLookatPt, &vUpVec); g_pd3dDevice->SetTransform(D3DTS_VIEW, &matView);
//建立并设置投影矩阵 D3DXMATRIXA16 matProj; float aspect = (float)(g_ClientRect.right - g_ClientRect.left) / (g_ClientRect.bottom - g_ClientRect.top); D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI / 4, aspect, 1.0f, 100.0f); g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj); }
//----------------------------------------------------------------------------- // Desc: 设置灯光 //----------------------------------------------------------------------------- void SetLights() { //方向光 D3DXVECTOR3 vecDir; D3DLIGHT9 light; ZeroMemory(&light, sizeof(D3DLIGHT9)); light.Type = D3DLIGHT_DIRECTIONAL; light.Diffuse.r = 1.0f; light.Diffuse.g = 1.0f; light.Diffuse.b = 1.0f; vecDir = D3DXVECTOR3(1, -1, 1); D3DXVec3Normalize((D3DXVECTOR3*)&light.Direction, &vecDir); light.Range = 1000.0f; g_pd3dDevice->SetLight(0, &light); g_pd3dDevice->LightEnable(0, TRUE); g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, true);
//全局环境光 g_pd3dDevice->SetRenderState(D3DRS_AMBIENT, 0xff505050); }
//----------------------------------------------------------------------------- // Desc: 设置材质 //----------------------------------------------------------------------------- void SetMaterial() { D3DMATERIAL9 mtrl; ZeroMemory(&mtrl, sizeof(D3DMATERIAL9)); mtrl.Diffuse.r = mtrl.Ambient.r = 1.0f; mtrl.Diffuse.g = mtrl.Ambient.g = 0.0f; mtrl.Diffuse.b = mtrl.Ambient.b = 0.0f; mtrl.Diffuse.a = mtrl.Ambient.a = 1.0f; g_pd3dDevice->SetMaterial(&mtrl); }
//----------------------------------------------------------------------------- // Desc: 初始化Direct3D //----------------------------------------------------------------------------- HRESULT InitD3D(HWND hWnd) { HRESULT hr;
//创建Direct3D对象, 该对象用来创建Direct3D设备对象 g_pD3D = Direct3DCreate9(D3D_SDK_VERSION); if (g_pD3D == NULL) return E_FAIL;
//检查设备性能 D3DCAPS9 caps; g_pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps);
//检查设备是否支持硬件顶点处理 int vp = 0; if (caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) { vp = D3DCREATE_HARDWARE_VERTEXPROCESSING; } else { vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING; }
//设置D3DPRESENT_PARAMETERS结构 D3DPRESENT_PARAMETERS d3dpp; ZeroMemory(&d3dpp, sizeof(d3dpp)); d3dpp.Windowed = TRUE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; d3dpp.EnableAutoDepthStencil = TRUE; d3dpp.AutoDepthStencilFormat = D3DFMT_D16; d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
//创建Direct3D设备对象 V_RETURN(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, vp, &d3dpp, &g_pd3dDevice));
//创建字体对象 V_RETURN(D3DXCreateFont(g_pd3dDevice, 0, 0, 0, 0, 0, 0, 0, 0, 0, L"Arial", &g_pFont));
//获取窗口客户区 GetClientRect(hWnd, &g_ClientRect);
//设置观察和投影矩阵 SetViewandProjMatrices();
return S_OK; }
//----------------------------------------------------------------------------- // Desc: 创建场景图形 //----------------------------------------------------------------------------- HRESULT InitGeometry() { HRESULT hr; V_RETURN(D3DXCreateTeapot(g_pd3dDevice, &g_pTeapotMesh, NULL)); return S_OK; }
//----------------------------------------------------------------------------- // Desc: 计算帧速率 //----------------------------------------------------------------------------- float GetFPS() { static float fps = 0; static int frameCount = 0; static float currentTime = 0.0f; static float lastTime = 0.0f;
frameCount++; currentTime = timeGetTime()*0.001f;
if (currentTime - lastTime > 1.0f) { fps = (float)frameCount / (currentTime - lastTime); lastTime = currentTime; frameCount = 0; }
return fps; }
//----------------------------------------------------------------------------- // Desc: 渲染图形 //----------------------------------------------------------------------------- void Render() { //清空后台缓存 g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(45, 50, 170), 1.0f, 0);
//开始在后台缓存绘制图形 if (SUCCEEDED(g_pd3dDevice->BeginScene())) { //设置灯光和材质 SetLights(); SetMaterial();
//设置世界矩阵 SetWorldMatrix();
//绘制茶壶 g_pTeapotMesh->DrawSubset(0);
//在窗口左上角绘制文本 int charCount = swprintf_s(g_strFPS, 20, L"FPS: %0.2f", GetFPS()); g_pFont->DrawText(NULL, g_strFPS, charCount, &g_ClientRect, DT_TOP | DT_LEFT, 0xffffffff);
//结束在后台缓存渲染图形 g_pd3dDevice->EndScene(); }
//将在后台缓存绘制的图形提交到前台缓存显示 g_pd3dDevice->Present(NULL, NULL, NULL, NULL); }
//----------------------------------------------------------------------------- // Desc: 释放创建的对象 //----------------------------------------------------------------------------- void Cleanup() { SAFE_RELEASE(g_pTeapotMesh); SAFE_RELEASE(g_pFont); SAFE_RELEASE(g_pd3dDevice); SAFE_RELEASE(g_pD3D); }
//----------------------------------------------------------------------------- // Desc: 消息处理 //----------------------------------------------------------------------------- LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_KEYDOWN: if (wParam == VK_ESCAPE) PostQuitMessage(0); break;
case WM_DESTROY: PostQuitMessage(0); break; }
return DefWindowProc(hWnd, msg, wParam, lParam); }
//----------------------------------------------------------------------------- // Desc: 程序入口 //----------------------------------------------------------------------------- int _stdcall _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PTSTR szCmdLine, int iCmdShow) { //定义窗口类 WNDCLASSEX wndClassEx; wndClassEx.cbSize = sizeof(WNDCLASSEX); wndClassEx.style = CS_CLASSDC; wndClassEx.lpfnWndProc = WndProc; wndClassEx.cbClsExtra = 0; wndClassEx.cbWndExtra = 0; wndClassEx.hInstance = hInstance; wndClassEx.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndClassEx.hCursor = LoadCursor(NULL, IDC_ARROW); wndClassEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndClassEx.lpszMenuName = NULL; wndClassEx.lpszClassName = L"ClassName"; wndClassEx.hIconSm = NULL;
//注册窗口类 if (!RegisterClassEx(&wndClassEx)) { MessageBox(NULL, L"注册窗口类失败!", L"Teapot", 0); return 0; }
//创建窗口 HWND hWnd = NULL; hWnd = CreateWindowEx(NULL, //窗口扩展风格 L"ClassName", //窗口类名称 L"Teapot", //窗口标题 WS_OVERLAPPEDWINDOW, //窗口风格 CW_USEDEFAULT, //窗口初始X位置 CW_USEDEFAULT, //窗口初始Y位置 600, //窗口初始宽度 480, //窗口初始高度 NULL, //父窗口句柄 NULL, //窗口菜单句柄 hInstance, //程序实例句柄 NULL); // 创建参数
if (hWnd == NULL) { MessageBox(NULL, L"创建窗口失败!", L"Teapot", 0); return 0; }
//初始化Direct3D if (SUCCEEDED(InitD3D(hWnd))) { //创建并填充顶点缓存 if (SUCCEEDED(InitGeometry())) { //显示窗口 ShowWindow(hWnd, SW_SHOWDEFAULT); UpdateWindow(hWnd);
//进入消息循环 MSG msg; ZeroMemory(&msg, sizeof(msg)); while (msg.message != WM_QUIT) { if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } else { Render(); //渲染图形 } } } }
//释放创建的相关对象 Cleanup();
return 0; }
|