Direct3D初始化

Direct3D初始化步骤(核心代码):

 1 // 描述交换链
 2     DXGI_SWAP_CHAIN_DESC sd;
 3     sd.BufferDesc.Width = mClientWidth;
 4     sd.BufferDesc.Height = mClientHeigth;
 5     sd.BufferDesc.RefreshRate.Numerator = 60;
 6     sd.BufferDesc.RefreshRate.Denominator = 1;
 7     sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
 8     sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
 9     sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
10     sd.SampleDesc.Count = 1;    // 多重采样数量和质量级别
11     sd.SampleDesc.Quality = 0;
12     sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;    // 将它用作渲染目标
13     sd.BufferCount = 1;
14     sd.OutputWindow = mhMainWnd;
15     sd.Windowed = true;
16     sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
17     sd.Flags = 0;
18 
19     UINT createDeviceFlags = 0;
20     // 创建设备和交换链
21     D3D10CreateDeviceAndSwapChain(0, md3dDriverType, 0, createDeviceFlags,
22         D3D10_SDK_VERSION, &sd, &mSwapChain, &md3dDevice);
23 
24     // 创建渲染目标视图
25     ID3D10Texture2D* backBuffer;
26     mSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), reinterpret_cast<void**>(&backBuffer));
27     md3dDevice->CreateRenderTargetView(backBuffer, 0, &mRenderTargetView);
28     backBuffer->Release();//每调用一次IDXGISwapChain::GetBuffer,后台缓冲区的COM引用计数向上递增一次,所以释放
29 
30     // 创建深度/模板缓冲区及其视图
31     D3D10_TEXTURE2D_DESC depthStencilDesc;
32     depthStencilDesc.Width = mClientWidth;
33     depthStencilDesc.Height = mClientHeigth;
34     depthStencilDesc.MipLevels = 1;
35     depthStencilDesc.ArraySize = 1;
36     depthStencilDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
37     depthStencilDesc.SampleDesc.Count = 1;
38     depthStencilDesc.SampleDesc.Quality = 0;
39     depthStencilDesc.Usage = D3D10_USAGE_DEFAULT;
40     depthStencilDesc.BindFlags = D3D10_BIND_DEPTH_STENCIL;
41     depthStencilDesc.CPUAccessFlags = 0;
42     depthStencilDesc.MiscFlags = 0;
43     md3dDevice->CreateTexture2D(&depthStencilDesc, 0, &mDepthStencilBuffer);
44     md3dDevice->CreateDepthStencilView(mDepthStencilBuffer, 0, &mDepthStencilView);
45 
46     // 将视图绑定到输出合并器阶段
47     md3dDevice->OMSetRenderTargets(1, &mRenderTargetView, mDepthStencilView);
48 
49     // 设置视口
50     // 通过修改视口,可以把3D场景渲染到后台缓冲区的一个子矩形区域中
51     D3D10_VIEWPORT vp;
52     vp.TopLeftX = 0;
53     vp.TopLeftY = 0;
54     vp.Width = mClientWidth;
55     vp.Height = mClientHeigth;
56     vp.MinDepth = 0.0f;
57     vp.MaxDepth = 1.0f;
58     md3dDevice->RSSetViewports(1, &vp);

本程序中,使用md3dDevice::ClearRenderTargetView清除渲染目标视图的颜色缓冲区,设为特定的颜色,然后调用mSwapChain->Present(0, 0)函数在屏幕上显示渲染缓冲区的内容(即设定的背景颜色)。

完整程序(使用类):

  1 /*
  2 2015.4
  3 DirectX10 Init
  4 
  5 对 Direct3D 进行初始化
  6 1. 填充一个DXGI_SWAP_CHAIN_DESC结构体,该结构体描述了所要创建的交换链的特性。
  7 2. 使用D3D10CreateDeviceAndSwapChain 函数创建ID3D10Device接口和IDXGISwapChain接口。
  8 3. 为交换链的后台缓冲区创建一个渲染目标视图。
  9 4. 创建深度/模板缓冲区以及相关的深度/模板视图。
 10 5. 将渲染目标视图和深度/模板视图绑定到渲染管线的输出合并阶段,使它们可以被Direct3D使用。
 11 6. 设置视口。
 12 */
 13 
 14 #include <iostream>
 15 #include <string>
 16 #include <d3d10.h>
 17 #include <d3dx10.h>
 18 
 19 #pragma comment(lib, "d3d10.lib")
 20 #pragma comment(lib, "d3dx10.lib")
 21 
 22 LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
 23 
 24 class D3DApp
 25 {
 26 public:
 27     D3DApp(HINSTANCE hInstance);
 28     ~D3DApp();
 29 
 30     HINSTANCE getAppInstance();
 31     HWND getMainWnd();
 32     int run();
 33 
 34     void initApp();
 35     void onResize();
 36     void updateScene();
 37     void drawScene();
 38     LRESULT msgProc(UINT msg, WPARAM wParam, LPARAM lParam);
 39 
 40 protected:
 41     void initMainWindow();
 42     void initDirect3D();
 43 
 44     HINSTANCE mhAppInstance;
 45     HWND mhMainWnd;
 46     bool mAppPaused;
 47     bool mMinimized;
 48     bool mMaximized;
 49     bool mResizing;
 50 
 51     std::wstring mFrameStatus;
 52     std::wstring mMainWndCaption;
 53 
 54     ID3D10Device* md3dDevice;
 55     IDXGISwapChain* mSwapChain;
 56     D3D10_DRIVER_TYPE md3dDriverType;
 57     D3DXCOLOR mClearColor;
 58     ID3D10Texture2D* mDepthStencilBuffer;
 59     ID3D10RenderTargetView* mRenderTargetView; 
 60     ID3D10DepthStencilView* mDepthStencilView;
 61     ID3DX10Font* mFont;
 62 
 63     int mClientWidth;
 64     int mClientHeigth;
 65 };
 66 
 67 D3DApp::D3DApp(HINSTANCE hInstance)
 68 {
 69     mhAppInstance = hInstance;
 70     mhMainWnd = 0;
 71     mAppPaused = false;
 72     mMinimized = false;
 73     mMaximized = false;
 74     mResizing = false;
 75 
 76     mFrameStatus = L"";
 77     mMainWndCaption = L"D3D10 Application";
 78 
 79     md3dDevice = 0;
 80     mSwapChain = 0;
 81     md3dDriverType = D3D10_DRIVER_TYPE_HARDWARE;
 82     mClearColor = D3DXCOLOR(0.0f, 0.0f, 0.0f, 1.0f);
 83     mFont = 0;
 84     mClientWidth = 800;
 85     mClientHeigth = 600;
 86 }
 87 
 88 D3DApp::~D3DApp()
 89 {
 90     mSwapChain->Release();
 91     mFont->Release();
 92     md3dDevice->Release();
 93 }
 94 
 95 HINSTANCE D3DApp::getAppInstance()
 96 {
 97     return mhAppInstance;
 98 }
 99 
100 HWND D3DApp::getMainWnd()
101 {
102     return mhMainWnd;
103 }
104 
105 int D3DApp::run()
106 {
107     MSG msg = { 0 };
108 
109     while (msg.message != WM_QUIT)
110     {
111         if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
112         {
113             TranslateMessage(&msg);
114             DispatchMessage(&msg);
115         }
116         else
117         {
118             drawScene();
119         }
120     }
121     return (int)msg.wParam;
122 }
123 
124 void D3DApp::initApp()
125 {
126     initMainWindow();
127     initDirect3D();
128 
129     D3DX10_FONT_DESC fontDesc;
130     fontDesc.Height = 24;
131     fontDesc.Width = 0;
132     fontDesc.Weight = 0;
133     fontDesc.MipLevels = 1;
134     fontDesc.Italic = false;    //非斜体
135     fontDesc.CharSet = DEFAULT_CHARSET;
136     fontDesc.OutputPrecision = OUT_DEFAULT_PRECIS;
137     fontDesc.Quality = DEFAULT_QUALITY;
138     fontDesc.PitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
139     wcscpy_s(fontDesc.FaceName, L"Times New Roman");
140 
141     D3DX10CreateFontIndirect(md3dDevice, &fontDesc, &mFont);
142 }
143 
144 void D3DApp::onResize()
145 {
146     // Release the old views, as they hold references to the buffers we
147     // will be destroying.  Also release the old depth/stencil buffer.
148     mRenderTargetView->Release();
149     mDepthStencilBuffer->Release();
150     mDepthStencilView->Release();
151 
152     // Resize the swap chain and recreate the render target view.
153     mSwapChain->ResizeBuffers(1, mClientWidth, mClientHeigth, DXGI_FORMAT_R8G8B8A8_UNORM, 0); //[0, 1]区间
154     
155     // 创建渲染目标视图
156     ID3D10Texture2D* backBuffer;
157     mSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), reinterpret_cast<void**>(&backBuffer));
158     md3dDevice->CreateRenderTargetView(backBuffer, 0, &mRenderTargetView);
159     backBuffer->Release();
160 
161     // 创建深度/模板缓冲区及其视图
162     D3D10_TEXTURE2D_DESC depthStencilDesc;
163     depthStencilDesc.Width = mClientWidth;
164     depthStencilDesc.Height = mClientHeigth;
165     depthStencilDesc.MipLevels = 1;
166     depthStencilDesc.ArraySize = 1;
167     depthStencilDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
168     depthStencilDesc.SampleDesc.Count = 1;
169     depthStencilDesc.SampleDesc.Quality = 0;
170     depthStencilDesc.Usage = D3D10_USAGE_DEFAULT;
171     depthStencilDesc.BindFlags = D3D10_BIND_DEPTH_STENCIL;
172     depthStencilDesc.CPUAccessFlags = 0;
173     depthStencilDesc.MiscFlags = 0;
174     md3dDevice->CreateTexture2D(&depthStencilDesc, 0, &mDepthStencilBuffer);
175     md3dDevice->CreateDepthStencilView(mDepthStencilBuffer, 0, &mDepthStencilView);
176 
177     // 将视图绑定到输出合并器阶段,使它们可以被Direct3D使用
178     md3dDevice->OMSetRenderTargets(1, &mRenderTargetView, mDepthStencilView);
179 
180     // 设置视口
181     D3D10_VIEWPORT vp;
182     vp.TopLeftX = 0;
183     vp.TopLeftY = 0;
184     vp.Width = mClientWidth;
185     vp.Height = mClientHeigth;
186     vp.MinDepth = 0.0f;
187     vp.MaxDepth = 1.0f;
188     md3dDevice->RSSetViewports(1, &vp);
189 }
190 
191 void D3DApp::updateScene()
192 {
193 
194 }
195 
196 void D3DApp::drawScene()
197 {
198     mClearColor = D3DXCOLOR(0.0f, 0.5f, 0.0f, 1.0f);
199 
200     // 清除渲染目标视图的颜色缓冲区,设为特定的颜色
201     md3dDevice->ClearRenderTargetView(mRenderTargetView, mClearColor);
202 
203     // 调用交换链的Present函数在屏幕上显示渲染缓冲区的内容
204     mSwapChain->Present(0, 0);
205 }
206 
207 LRESULT D3DApp::msgProc(UINT msg, WPARAM wParam, LPARAM lParam)
208 {
209     switch (msg)
210     {
211     case WM_DESTROY:
212         PostQuitMessage(0);
213         return 0;
214     }
215     return DefWindowProc(mhMainWnd, msg, wParam, lParam);
216 }
217 
218 void D3DApp::initMainWindow()
219 {
220     WNDCLASS wc;
221     wc.style = CS_HREDRAW | CS_VREDRAW;
222     wc.lpfnWndProc = MainWndProc;
223     wc.cbClsExtra = 0;
224     wc.cbWndExtra = 0;
225     wc.hInstance = mhAppInstance;
226     wc.hIcon = LoadIcon(0, IDI_APPLICATION);
227     wc.hCursor = LoadCursor(0, IDC_ARROW);
228     wc.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
229     wc.lpszMenuName = 0;
230     wc.lpszClassName = L"D3DWndClassName";
231 
232     if (!RegisterClass(&wc))
233     {
234         MessageBox(0, L"RegisterClass FAILED", 0, 0);
235         PostQuitMessage(0);
236     }
237     RECT R = { 0, 0, mClientWidth, mClientHeigth };
238     AdjustWindowRect(&R, WS_OVERLAPPEDWINDOW, false);
239     int width = R.right - R.left;
240     int height = R.bottom - R.top;
241 
242     mhMainWnd = CreateWindow(L"D3DWndClassName", mMainWndCaption.c_str(),
243         WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, width, height, 0, 0, mhAppInstance, this);
244     if (!mhMainWnd)
245     {
246         MessageBox(0, L"CreateWindow FAILED", 0, 0);
247         PostQuitMessage(0);
248     }
249 
250     ShowWindow(mhMainWnd, SW_SHOW);
251     UpdateWindow(mhMainWnd);
252 }
253 
254 void D3DApp::initDirect3D()
255 {
256     // 描述交换链
257     DXGI_SWAP_CHAIN_DESC sd;
258     sd.BufferDesc.Width = mClientWidth;
259     sd.BufferDesc.Height = mClientHeigth;
260     sd.BufferDesc.RefreshRate.Numerator = 60;
261     sd.BufferDesc.RefreshRate.Denominator = 1;
262     sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
263     sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
264     sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
265     sd.SampleDesc.Count = 1;    // 多重采样数量和质量级别
266     sd.SampleDesc.Quality = 0;
267     sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;    // 将它用作渲染目标
268     sd.BufferCount = 1;
269     sd.OutputWindow = mhMainWnd;
270     sd.Windowed = true;
271     sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
272     sd.Flags = 0;
273 
274     UINT createDeviceFlags = 0;
275     // 创建设备和交换链
276     D3D10CreateDeviceAndSwapChain(0, md3dDriverType, 0, createDeviceFlags,
277         D3D10_SDK_VERSION, &sd, &mSwapChain, &md3dDevice);
278 
279     //onResize();    //在该程序中可以使用此句代替下面语句
280 
281     // 创建渲染目标视图
282     ID3D10Texture2D* backBuffer;
283     mSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), reinterpret_cast<void**>(&backBuffer));
284     md3dDevice->CreateRenderTargetView(backBuffer, 0, &mRenderTargetView);
285     backBuffer->Release();//每调用一次IDXGISwapChain::GetBuffer,后台缓冲区的COM引用计数向上递增一次,所以释放
286 
287     // 创建深度/模板缓冲区及其视图
288     D3D10_TEXTURE2D_DESC depthStencilDesc;
289     depthStencilDesc.Width = mClientWidth;
290     depthStencilDesc.Height = mClientHeigth;
291     depthStencilDesc.MipLevels = 1;
292     depthStencilDesc.ArraySize = 1;
293     depthStencilDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
294     depthStencilDesc.SampleDesc.Count = 1;
295     depthStencilDesc.SampleDesc.Quality = 0;
296     depthStencilDesc.Usage = D3D10_USAGE_DEFAULT;
297     depthStencilDesc.BindFlags = D3D10_BIND_DEPTH_STENCIL;
298     depthStencilDesc.CPUAccessFlags = 0;
299     depthStencilDesc.MiscFlags = 0;
300     md3dDevice->CreateTexture2D(&depthStencilDesc, 0, &mDepthStencilBuffer);
301     md3dDevice->CreateDepthStencilView(mDepthStencilBuffer, 0, &mDepthStencilView);
302 
303     // 将视图绑定到输出合并器阶段
304     md3dDevice->OMSetRenderTargets(1, &mRenderTargetView, mDepthStencilView);
305 
306     // 设置视口
307     // 通过修改视口,可以把3D场景渲染到后台缓冲区的一个子矩形区域中
308     D3D10_VIEWPORT vp;
309     vp.TopLeftX = 0;
310     vp.TopLeftY = 0;
311     vp.Width = mClientWidth;
312     vp.Height = mClientHeigth;
313     vp.MinDepth = 0.0f;
314     vp.MaxDepth = 1.0f;
315     md3dDevice->RSSetViewports(1, &vp);
316 
317 }
318 
319 LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
320 {
321     static D3DApp* app = 0;
322     switch (msg)
323     {
324     case WM_CREATE:
325     {
326                       // CREATESTRUCT结构定义了应用程序中窗口过程的初始化参数
327                       CREATESTRUCT* cs = (CREATESTRUCT*)lParam;
328                       app = (D3DApp*)cs->lpCreateParams;
329                       return 0;
330     }
331     }
332 
333     if (app)
334         return app->msgProc(msg, wParam, lParam);
335     else
336         return DefWindowProc(hwnd, msg, wParam, lParam);
337 }
338 
339 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR cmdLine, int showCmd)
340 {
341     D3DApp theApp(hInstance);
342 
343     theApp.initApp();
344     theApp.run();
345 
346     return 0;
347 }
原文地址:https://www.cnblogs.com/ht-beyond/p/4453392.html