Directx11学习笔记【八】 龙书D3DApp的实现

directx11龙书中的初始化程序D3DApp跟我们上次写的初始化程序大体一致,只是包含了计时器的内容,而且使用了深度模板缓冲。

 

D3DUtil类,定义了一些工具和宏,目前只定义了两个宏,以后还会添加

#ifndef D3DUTIL_H
#define D3DUTIL_H

#include <d3dx11.h>
#include <xnamath.h>
#include <dxerr.h>
#include <cassert>

//-------------------------------
//方便检测d3d errors
//-------------------------------
#if defined(DEBUG) | defined(_DEBUG)
#ifndef HR
#define HR(x)                                              \
    {                                                          \
    HRESULT hr = (x);                                      \
if (FAILED(hr))                                         \
        {                                                      \
        DXTrace(__FILE__, (DWORD)__LINE__, hr, L#x, true); \
        }                                                      \
    }
#endif

#else
#ifndef HR
#define HR(x) (x)
#endif
#endif 

//------------------------------
//方便删除COM objects
//------------------------------
#define ReleaseCOM(x) { if(x){ x->Release(); x = 0; } }


#endif//D3DUTIL_H

 

基类D3DApp的实现

.h文件

 1 #ifndef D3DAPP_H
 2 #define D3DAPP_H
 3 
 4 #include <windows.h>
 5 #include <string>
 6 #include "D3DUtil.h"
 7 #include "GameTimer.h"
 8 
 9 class D3DApp
10 {
11 public:
12     D3DApp(HINSTANCE hInstance);
13     virtual ~D3DApp();
14 
15     HINSTANCE AppInst() const;
16     HWND MainWnd() const;
17     float AspectRatio() const;
18 
19     int Run();
20 
21     virtual bool Init();
22     virtual void OnResize();
23     virtual void UpdateScene(float dt) = 0;
24     virtual void DrawScene();
25     virtual LRESULT MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
26     
27     //鼠标事件
28     virtual void OnMouseDown(WPARAM btnState, int x, int y){}
29     virtual void OnMouseUp(WPARAM btnState, int x, int y){}
30     virtual void OnMouseMove(WPARAM btnState, int x, int y){}
31 
32 protected:
33     bool InitMainWindow();
34     bool InitDirect3D();
35     //计算FPS
36     void CalculateFrameStats();
37 
38 protected:
39     HINSTANCE m_hAppInst;                            //实例句柄
40     HWND m_hMainWnd;                                //主窗口句柄
41     bool m_isAppPaused;
42     bool m_isMinimized;
43     bool m_isMaximized;
44     bool m_isResizing;
45     UINT m_4xMsaaQuality;                            //4重采样质量
46 
47     GameTimer m_timer;                                //计时器
48     D3D_DRIVER_TYPE m_d3dDriverType;                //驱动类型
49     ID3D11Device *m_pD3dDevice;                        //设备
50     ID3D11DeviceContext *m_pImmediateContext;        //设备上下文
51     IDXGISwapChain *m_pSwapChain;                    //交换链
52     ID3D11Texture2D *m_pDepthStencilBuffer;            //深度模板缓冲
53     ID3D11RenderTargetView *m_pRenderTargetView;    //渲染目标视图
54     ID3D11DepthStencilView *m_pDepthStencilView;    //深度模板缓冲视图
55     D3D11_VIEWPORT m_screenViewPort;                //视口
56 
57     std::wstring m_mainWndCaption;                    //窗口标题
58     int m_clientWidth;
59     int m_clientHeight;
60     bool m_isEnable4xMsaa;                            //是否支持4重采样
61 };
62 #endif    //D3DAPP_H

 

.cpp

  1 #include <windowsx.h>//包含大量可用的宏和各种方便的工具
  2 #include <sstream>
  3 #include "D3DApp.h"
  4 
  5 namespace
  6 {
  7     D3DApp *g_d3dApp = NULL;
  8 }
  9 
 10 LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
 11 {
 12     return g_d3dApp->MsgProc(hWnd,msg,wParam,lParam);
 13 }
 14 
 15 
 16 D3DApp::D3DApp(HINSTANCE hInstance) :
 17 m_hAppInst(hInstance),
 18 m_mainWndCaption(L"D3D11 Application"),
 19 m_d3dDriverType(D3D_DRIVER_TYPE_HARDWARE),
 20 m_clientHeight(600),
 21 m_clientWidth(800),
 22 m_isEnable4xMsaa(false),
 23 m_hMainWnd(NULL),
 24 m_isAppPaused(false),
 25 m_isMaximized(false),
 26 m_isMinimized(false),
 27 m_isResizing(false),
 28 m_4xMsaaQuality(0),
 29 
 30 m_pD3dDevice(NULL),
 31 m_pImmediateContext(NULL),
 32 m_pSwapChain(NULL),
 33 m_pRenderTargetView(NULL),
 34 m_pDepthStencilBuffer(NULL)
 35 {
 36     ZeroMemory(&m_screenViewPort, sizeof(D3D11_VIEWPORT));
 37     g_d3dApp = this;
 38 }
 39 
 40 D3DApp::~D3DApp()
 41 {
 42     ReleaseCOM(m_pRenderTargetView);
 43     ReleaseCOM(m_pDepthStencilBuffer);
 44     ReleaseCOM(m_pSwapChain);
 45     ReleaseCOM(m_pDepthStencilView);
 46 
 47     if (m_pImmediateContext)
 48         m_pImmediateContext->ClearState();
 49 
 50     ReleaseCOM(m_pImmediateContext);
 51     ReleaseCOM(m_pD3dDevice);
 52 }
 53 
 54 HINSTANCE D3DApp::AppInst() const
 55 {
 56     return m_hAppInst;
 57 }
 58 
 59 HWND D3DApp::MainWnd() const
 60 {
 61     return m_hMainWnd;
 62 }
 63 
 64 float D3DApp::AspectRatio() const
 65 {
 66     return static_cast<float>(m_clientWidth / m_clientHeight);
 67 }
 68 
 69 int D3DApp::Run()
 70 {
 71     MSG msg;
 72     ZeroMemory(&msg, sizeof(MSG));
 73     m_timer.Reset();
 74 
 75     while (msg.message != WM_QUIT)
 76     {
 77         if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
 78         {
 79             TranslateMessage(&msg);
 80             DispatchMessage(&msg);
 81         }
 82         else
 83         {
 84             m_timer.Tick();
 85             if (!m_isAppPaused)
 86             {
 87                 CalculateFrameStats();
 88                 UpdateScene(m_timer.DeltaTime());
 89                 DrawScene();
 90             }
 91             else
 92             {
 93                 Sleep(100);
 94             }
 95         }
 96     }
 97     return static_cast<int>(msg.wParam);
 98 }
 99 
100 bool D3DApp::Init()
101 {
102     if (!InitMainWindow())
103         return false;
104     if (!InitDirect3D())
105         return false;
106     return true;
107 }
108 
109 void D3DApp::OnResize()
110 {
111     assert(m_pImmediateContext);
112     assert(m_pD3dDevice);
113     assert(m_pSwapChain);
114 
115     //release old views
116     ReleaseCOM(m_pRenderTargetView);
117     ReleaseCOM(m_pDepthStencilView);
118     ReleaseCOM(m_pDepthStencilBuffer);
119 
120     HR(m_pSwapChain->ResizeBuffers(1, m_clientWidth, m_clientHeight, DXGI_FORMAT_R8G8B8A8_UNORM, 0));
121     ID3D11Texture2D *backBuffer;
122     HR(m_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&backBuffer)));
123     HR(m_pD3dDevice->CreateRenderTargetView(backBuffer, 0, &m_pRenderTargetView));
124     ReleaseCOM(backBuffer);
125 
126     //create depth/stencil buffer and view
127     D3D11_TEXTURE2D_DESC depthStencilDecs;
128     depthStencilDecs.Width = m_clientWidth;
129     depthStencilDecs.Height = m_clientHeight;
130     depthStencilDecs.MipLevels = 1;
131     depthStencilDecs.ArraySize = 1;
132     depthStencilDecs.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
133     
134     //是否使用4重采样
135     if (m_isEnable4xMsaa)
136     {
137         depthStencilDecs.SampleDesc.Count = 4;
138         depthStencilDecs.SampleDesc.Quality = m_4xMsaaQuality - 1;
139     }
140     else
141     {
142         depthStencilDecs.SampleDesc.Count = 1;
143         depthStencilDecs.SampleDesc.Quality = 0;
144     }
145     
146     depthStencilDecs.Usage = D3D11_USAGE_DEFAULT;
147     depthStencilDecs.BindFlags = D3D11_BIND_DEPTH_STENCIL;
148     depthStencilDecs.CPUAccessFlags = 0;
149     depthStencilDecs.MiscFlags = 0;
150 
151     HR(m_pD3dDevice->CreateTexture2D(&depthStencilDecs, 0, &m_pDepthStencilBuffer));
152     HR(m_pD3dDevice->CreateDepthStencilView(m_pDepthStencilBuffer, 0, &m_pDepthStencilView));
153 
154     //绑定新的render target view 和 depth/stencil view到管线
155     m_pImmediateContext->OMSetRenderTargets(1, &m_pRenderTargetView, m_pDepthStencilView);
156 
157     //设置viewport
158     m_screenViewPort.TopLeftX = 0;
159     m_screenViewPort.TopLeftY = 0;
160     m_screenViewPort.Width = m_clientWidth;
161     m_screenViewPort.Height = m_clientHeight;
162     m_screenViewPort.MaxDepth = 1.0f;
163     m_screenViewPort.MinDepth = 0.0f;
164 
165     m_pImmediateContext->RSSetViewports(1, &m_screenViewPort);
166 }
167 
168 LRESULT D3DApp::MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
169 {
170     switch (msg)
171     {
172         //当一个窗口被激活或失去激活状态
173     case WM_ACTIVATE:
174         if (LOWORD(wParam) == WA_INACTIVE)
175         {
176             m_isAppPaused = true;
177             m_timer.Stop();
178         }
179         else
180         {
181             m_isAppPaused = false;
182             m_timer.Start();
183         }
184         return 0;
185 
186         //当用户重绘窗口时
187     case WM_SIZE:
188         m_clientWidth = LOWORD(lParam);
189         m_clientHeight = HIWORD(lParam);
190         if (m_pD3dDevice)
191         {
192             if (wParam == SIZE_MINIMIZED)//窗口最小化
193             {
194                 m_isAppPaused = true;
195                 m_isMinimized = true;
196                 m_isMaximized = true;
197             }
198             else if (wParam == SIZE_MAXIMIZED)//窗口最大化
199             {
200                 m_isAppPaused = false;
201                 m_isMinimized = false;
202                 m_isMaximized = true;
203                 OnResize();
204             }
205             else if (wParam == SIZE_RESTORED)//窗口大小改变既不是最大化也不是最小化
206             {
207                 if (m_isMinimized)
208                 {
209                     m_isAppPaused = false;
210                     m_isMinimized = false;
211                     OnResize();
212                 }
213                 else if (m_isMaximized)
214                 {
215                     m_isAppPaused = false;
216                     m_isMaximized = false;
217                     OnResize();
218                 }
219                 //当用户正在改变窗口大小时不调用OnResize(),当改变完成后再
220                 //调用
221                 else if (m_isResizing)
222                 {
223 
224                 }
225                 else
226                 {
227                     OnResize();
228                 }
229             }
230         }
231         return 0;
232 
233     //用户开始拖拽改变窗口大小
234     case WM_ENTERSIZEMOVE:
235         m_isAppPaused = true;
236         m_isResizing = true;
237         m_timer.Stop();
238         return 0;
239 
240     //用户改变窗口大小完毕
241     case WM_EXITSIZEMOVE:
242         m_isAppPaused = false;
243         m_isResizing = false;
244         m_timer.Start();
245         OnResize();
246         return  0;
247     //窗口销毁
248     case WM_DESTROY:
249         PostQuitMessage(0);
250         return 0;
251 
252     //The WM_MENUCHAR message is sent when a menu is active and the user presses 
253     // a key that does not correspond to any mnemonic or accelerator key.
254     case WM_MENUCHAR:
255         return MAKELRESULT(0, MNC_CLOSE);
256 
257     //防止窗口变得太小
258     case WM_GETMINMAXINFO:
259         ((MINMAXINFO*)lParam)->ptMinTrackSize.x = 200;
260         ((MINMAXINFO*)lParam)->ptMinTrackSize.y = 200;
261         return 0;
262 
263     case WM_LBUTTONDOWN:
264     case WM_MBUTTONDOWN:
265     case WM_RBUTTONDOWN:
266         OnMouseDown(wParam, GET_X_LPARAM(lParam),GET_Y_LPARAM(lParam));
267         return 0;
268     case WM_LBUTTONUP:
269     case WM_MBUTTONUP:
270     case WM_RBUTTONUP:
271         OnMouseUp(wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
272         return 0;
273     case WM_MOUSEMOVE:
274         OnMouseMove(wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
275         return 0;
276     }
277     return DefWindowProc(hWnd, msg, wParam, lParam);
278 }
279 
280 bool D3DApp::InitMainWindow()
281 {
282     WNDCLASS wc;
283     wc.cbClsExtra = 0;
284     wc.cbWndExtra = 0;
285     wc.hbrBackground = static_cast<HBRUSH>(GetStockObject(NULL_BRUSH));
286     wc.hCursor = LoadCursor(0, IDC_ARROW);
287     wc.hIcon = LoadIcon(0, IDI_APPLICATION);
288     wc.hInstance = m_hAppInst;
289     wc.lpfnWndProc = MainWndProc;
290     wc.lpszClassName = L"D3DWndClassName";
291     wc.lpszMenuName = NULL;
292     wc.style = CS_HREDRAW | CS_VREDRAW;
293     if (!RegisterClass(&wc))
294     {
295         MessageBox(0, L"RegisterClass Failed", 0, 0);
296         return false;
297     }
298 
299     RECT rect{ 0, 0, m_clientWidth, m_clientHeight };
300     AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, false);
301     int width = rect.right - rect.left;
302     int height = rect.bottom - rect.top;
303 
304     m_hMainWnd = CreateWindow(L"D3DWndClassName", m_mainWndCaption.c_str(), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
305         width, height, NULL, NULL, m_hAppInst, 0);
306     if (!m_hMainWnd)
307     {
308         MessageBox(0, L"CreateWindow Failed", 0, 0);
309         return 0;
310     }
311 
312     ShowWindow(m_hMainWnd,SW_SHOW);
313     UpdateWindow(m_hMainWnd);
314 
315     return true;
316 }
317 
318 bool D3DApp::InitDirect3D()
319 {
320     UINT createDeviceFlags = 0;
321 #if defined(DEBUG) || defined(_DEBUG)
322     createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
323 #endif
324 
325     D3D_FEATURE_LEVEL featureLevel;
326     HRESULT hr = D3D11CreateDevice(
327         0,//默认的adapter
328         m_d3dDriverType,
329         0,
330         createDeviceFlags,
331         0, 0,
332         D3D11_SDK_VERSION,
333         &m_pD3dDevice,
334         &featureLevel,
335         &m_pImmediateContext
336         );
337     if (FAILED(hr))
338     {
339         MessageBox(0, L"D3D11CreateDevice Failed", 0, 0);
340         return hr;
341     }
342 
343     if (featureLevel != D3D_FEATURE_LEVEL_11_0)
344     {
345         MessageBox(0, L"Direct3D Feature Level 11 unsupported!", 0, 0);
346         return false;
347     }
348 
349     //check 4x msaa quality support
350     HR(m_pD3dDevice->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, 4, &m_4xMsaaQuality));
351     assert(m_4xMsaaQuality > 0);
352 
353     //填充交换链描述
354     DXGI_SWAP_CHAIN_DESC sd;
355     sd.BufferDesc.Width = m_clientWidth;
356     sd.BufferDesc.Height = m_clientHeight;
357     sd.BufferDesc.RefreshRate.Numerator = 60;
358     sd.BufferDesc.RefreshRate.Denominator = 1;
359     sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
360     sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
361     sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
362     //是否用4重采样
363     if (m_isEnable4xMsaa)
364     {
365         sd.SampleDesc.Count = 4;
366         sd.SampleDesc.Quality = m_4xMsaaQuality - 1;
367     }
368     else
369     {
370         sd.SampleDesc.Count = 1;
371         sd.SampleDesc.Quality = 0;
372     }
373 
374     sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
375     sd.BufferCount = 1;
376     sd.OutputWindow = m_hMainWnd;
377     sd.Windowed = true;
378     sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
379     sd.Flags = 0;
380 
381     //要创建交换链必须得到IDXGIFactory
382     IDXGIDevice *pDxgiDevice = 0;
383     HR(m_pD3dDevice->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&pDxgiDevice)));
384     
385     IDXGIAdapter *pDxgiAdapter = 0;
386     HR(pDxgiDevice->GetParent(__uuidof(IDXGIAdapter), reinterpret_cast<void**>(&pDxgiAdapter)));
387 
388     IDXGIFactory *pDxgiFactory = 0;
389     HR(pDxgiAdapter->GetParent(__uuidof(IDXGIFactory), reinterpret_cast<void**>(&pDxgiFactory)));
390 
391     HR(pDxgiFactory->CreateSwapChain(m_pD3dDevice, &sd, &m_pSwapChain));
392 
393     ReleaseCOM(pDxgiDevice);
394     ReleaseCOM(pDxgiAdapter);
395     ReleaseCOM(pDxgiFactory);
396 
397     OnResize();
398 
399     return true;
400 }
401 
402 void D3DApp::CalculateFrameStats()
403 {
404     //计算fps,每一帧调用
405     static int frameCnt = 0;
406     static float timeElapsed = 0.0f;
407 
408     frameCnt++;
409 
410     if ((m_timer.TotalTime() - timeElapsed) >= 1.0f)
411     {
412         float fps = static_cast<float>(frameCnt);
413         float mspf = 1000.f / fps;
414 
415         std::wostringstream outs;
416         outs.precision(6);//浮点数显示6位
417         outs << m_mainWndCaption << L"    " << L"FPS:" << fps << L"    "
418             << L"Frame Time:" << mspf << L" (ms) ";
419         SetWindowText(m_hMainWnd, outs.str().c_str());
420 
421         frameCnt = 0;
422         timeElapsed += 1.0f;
423     }
424 }
425 
426 void D3DApp::DrawScene()
427 {
428 
429 }

 

初始化程序

InitDirect3DApp.h

 1 #ifndef INITDIRECT3DAPP_H
 2 #define INITDIRECT3DAPP_H
 3 
 4 #include "D3DApp.h"
 5 
 6 class InitDirect3DApp : public D3DApp
 7 {
 8 public:
 9     InitDirect3DApp(HINSTANCE hInstance);
10     ~InitDirect3DApp();
11 
12     bool Init();
13     void OnResize();
14     void UpdateScene(float dt);
15     void DrawScene();
16 };
17 
18 #endif//INITDIRECT3DAPP_H

 

InitDirect3DApp.cpp

 1 #include "InitDirect3DApp.h"
 2 
 3 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
 4 {
 5 #if defined(DEBUG) | defined(_DEBUG)
 6     _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
 7 #endif
 8 
 9     InitDirect3DApp theApp(hInstance);
10 
11     if (!theApp.Init())
12         return  0;
13     return theApp.Run();
14 }
15 
16 
17 
18 InitDirect3DApp::InitDirect3DApp(HINSTANCE hInstance) : D3DApp(hInstance)
19 {
20 }
21 
22 InitDirect3DApp::~InitDirect3DApp()
23 {
24 }
25 
26 bool InitDirect3DApp::Init()
27 {
28     if (!D3DApp::Init())
29         return false;
30     return true;
31 }
32 
33 void InitDirect3DApp::OnResize()
34 {
35     D3DApp::OnResize();
36 }
37 
38 void InitDirect3DApp::UpdateScene(float dt)
39 {
40 
41 }
42 
43 void InitDirect3DApp::DrawScene()
44 {
45     assert(m_pImmediateContext);
46     assert(m_pSwapChain);
47 
48     float ClearColor[4] = { 0.0f, 0.0f, 1.0f, 1.0f };
49     m_pImmediateContext->ClearRenderTargetView(m_pRenderTargetView, ClearColor);
50     m_pImmediateContext->ClearDepthStencilView(m_pDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
51     HR(m_pSwapChain->Present(0, 0));
52 }

 

posted @ 2016-03-20 20:00  zhangbaochong  阅读(2619)  评论(0编辑  收藏  举报