Initializes the Direct3D device and related resources.
34{
35 Logger::Get().
Log(
"Initializing D3Dclass", __FILE__, __LINE__, Logger::LogLevel::Initialize);
36
37 HRESULT result;
38 IDXGIFactory* factory;
39 IDXGIAdapter* adapter;
40 IDXGIOutput* adapterOutput;
41 unsigned int numModes, i, numerator, denominator;
42 unsigned long long stringLength;
43 DXGI_MODE_DESC* displayModeList;
44 DXGI_ADAPTER_DESC adapterDesc;
45 int error;
46 DXGI_SWAP_CHAIN_DESC swapChainDesc;
47 D3D_FEATURE_LEVEL featureLevel;
48 ID3D11Texture2D* backBufferPtr;
49 D3D11_TEXTURE2D_DESC depthBufferDesc;
50 D3D11_DEPTH_STENCIL_DESC depthStencilDesc;
51 D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc;
52 D3D11_RASTERIZER_DESC rasterDesc;
53 float fieldOfView, screenAspect;
54 D3D11_DEPTH_STENCIL_DESC depthDisabledStencilDesc;
55 D3D11_BLEND_DESC blendStateDescription;
56
57
58 vsync_enabled_ = vsync;
59
60
61 result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory);
62 if (FAILED(result))
63 {
64 Logger::Get().
Log(
"Failed to create DXGIFactory", __FILE__, __LINE__, Logger::LogLevel::Error);
65 return false;
66 }
67
68
69 result = factory->EnumAdapters(0, &adapter);
70 if (FAILED(result))
71 {
72 Logger::Get().
Log(
"Failed to create adapter", __FILE__, __LINE__, Logger::LogLevel::Error);
73 return false;
74 }
75
76
77 result = adapter->EnumOutputs(0, &adapterOutput);
78 if (FAILED(result))
79 {
80 Logger::Get().
Log(
"Failed to create adapter output", __FILE__, __LINE__, Logger::LogLevel::Error);
81 return false;
82 }
83
84
85 result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, NULL);
86 if (FAILED(result))
87 {
88 Logger::Get().
Log(
"Failed to get display mode list", __FILE__, __LINE__, Logger::LogLevel::Error);
89 return false;
90 }
91
92
93 displayModeList = new DXGI_MODE_DESC[numModes];
94 if (!displayModeList)
95 {
96 Logger::Get().
Log(
"Failed to create display mode list", __FILE__, __LINE__, Logger::LogLevel::Error);
97 return false;
98 }
99
100
101 result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList);
102 if (FAILED(result))
103 {
104 Logger::Get().
Log(
"Failed to fill display mode list", __FILE__, __LINE__, Logger::LogLevel::Error);
105 return false;
106 }
107
108
109
110 for (i = 0; i < numModes; i++)
111 {
112 if (displayModeList[i].Width == (unsigned int)screenWidth)
113 {
114 if (displayModeList[i].Height == (unsigned int)screenHeight)
115 {
116 numerator = displayModeList[i].RefreshRate.Numerator;
117 denominator = displayModeList[i].RefreshRate.Denominator;
118 }
119 }
120 }
121
122
123 result = adapter->GetDesc(&adapterDesc);
124 if (FAILED(result))
125 {
126 Logger::Get().
Log(
"Failed to get adapter description", __FILE__, __LINE__, Logger::LogLevel::Error);
127 return false;
128 }
129
130
131 video_card_memory_ = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024);
132
133
134 error = wcstombs_s(&stringLength, video_card_description_, 128, adapterDesc.Description, 128);
135 if (error != 0)
136 {
137 Logger::Get().
Log(
"Failed to convert video card name to character array", __FILE__, __LINE__, Logger::LogLevel::Error);
138 return false;
139 }
140
141
142 delete[] displayModeList;
143 displayModeList = 0;
144
145
146 adapterOutput->Release();
147 adapterOutput = 0;
148
149
150 adapter->Release();
151 adapter = 0;
152
153
154 factory->Release();
155 factory = 0;
156
157
158 ZeroMemory(&swapChainDesc, sizeof(swapChainDesc));
159
160
161 swapChainDesc.BufferCount = 1;
162
163
164 swapChainDesc.BufferDesc.Width = screenWidth;
165 swapChainDesc.BufferDesc.Height = screenHeight;
166
167
168 swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
169
170
171 if (vsync_enabled_)
172 {
173 swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator;
174 swapChainDesc.BufferDesc.RefreshRate.Denominator = denominator;
175 }
176 else
177 {
178 swapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
179 swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
180 }
181
182
183 swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
184
185
186 swapChainDesc.OutputWindow = hwnd;
187
188
189 swapChainDesc.SampleDesc.Count = 1;
190 swapChainDesc.SampleDesc.Quality = 0;
191
192
193 if (fullscreen)
194 {
195 swapChainDesc.Windowed = false;
196 }
197 else
198 {
199 swapChainDesc.Windowed = true;
200 }
201
202
203 swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
204 swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
205
206
207 swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
208
209
210 swapChainDesc.Flags = 0;
211
212
213 featureLevel = D3D_FEATURE_LEVEL_11_0;
214
215
216 result = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, &featureLevel, 1,
217 D3D11_SDK_VERSION, &swapChainDesc, &swap_chain, &device_, NULL, &device_context_);
218 if (FAILED(result))
219 {
220 Logger::Get().
Log(
"Failed to create swap chain, device and device context", __FILE__, __LINE__, Logger::LogLevel::Error);
221 return false;
222 }
223
224
225 result = swap_chain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr);
226 if (FAILED(result))
227 {
228 Logger::Get().
Log(
"Failed to get pointer to back buffer", __FILE__, __LINE__, Logger::LogLevel::Error);
229 return false;
230 }
231
232
233 result = device_->CreateRenderTargetView(backBufferPtr, NULL, &render_target_view_);
234 if (FAILED(result))
235 {
236 Logger::Get().
Log(
"Failed to create render target view", __FILE__, __LINE__, Logger::LogLevel::Error);
237 return false;
238 }
239
240
241 backBufferPtr->Release();
242 backBufferPtr = 0;
243
244
245 ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc));
246
247
248 depthBufferDesc.Width = screenWidth;
249 depthBufferDesc.Height = screenHeight;
250 depthBufferDesc.MipLevels = 1;
251 depthBufferDesc.ArraySize = 1;
252 depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
253 depthBufferDesc.SampleDesc.Count = 1;
254 depthBufferDesc.SampleDesc.Quality = 0;
255 depthBufferDesc.Usage = D3D11_USAGE_DEFAULT;
256 depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
257 depthBufferDesc.CPUAccessFlags = 0;
258 depthBufferDesc.MiscFlags = 0;
259
260
261 result = device_->CreateTexture2D(&depthBufferDesc, NULL, &depth_stencil_buffer_);
262 if (FAILED(result))
263 {
264 Logger::Get().
Log(
"Failed to create texture for depth buffer", __FILE__, __LINE__, Logger::LogLevel::Error);
265 return false;
266 }
267
268
269 ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc));
270
271
272 depthStencilDesc.DepthEnable = true;
273 depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
274 depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS;
275
276 depthStencilDesc.StencilEnable = true;
277 depthStencilDesc.StencilReadMask = 0xFF;
278 depthStencilDesc.StencilWriteMask = 0xFF;
279
280
281 depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
282 depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;
283 depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
284 depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
285
286
287 depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
288 depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR;
289 depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
290 depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
291
292
293 result = device_->CreateDepthStencilState(&depthStencilDesc, &depth_stencil_state_);
294 if (FAILED(result))
295 {
296 Logger::Get().
Log(
"Failed to create depth stencil state", __FILE__, __LINE__, Logger::LogLevel::Error);
297 return false;
298 }
299
300
301 device_context_->OMSetDepthStencilState(depth_stencil_state_, 1);
302
303
304 ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc));
305
306
307 depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
308 depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
309 depthStencilViewDesc.Texture2D.MipSlice = 0;
310
311
312 result = device_->CreateDepthStencilView(depth_stencil_buffer_, &depthStencilViewDesc, &depth_stencil_view_);
313 if (FAILED(result))
314 {
315 Logger::Get().
Log(
"Failed to create depth stencil view", __FILE__, __LINE__, Logger::LogLevel::Error);
316 return false;
317 }
318
319
320 device_context_->OMSetRenderTargets(1, &render_target_view_, depth_stencil_view_);
321
322
323 rasterDesc.AntialiasedLineEnable = false;
324 rasterDesc.CullMode = D3D11_CULL_BACK;
325 rasterDesc.DepthBias = 0;
326 rasterDesc.DepthBiasClamp = 0.0f;
327 rasterDesc.DepthClipEnable = true;
328 rasterDesc.FillMode = D3D11_FILL_SOLID;
329 rasterDesc.FrontCounterClockwise = false;
330 rasterDesc.MultisampleEnable = false;
331 rasterDesc.ScissorEnable = false;
332 rasterDesc.SlopeScaledDepthBias = 0.0f;
333
334
335 result = device_->CreateRasterizerState(&rasterDesc, &raster_state_);
336 if (FAILED(result))
337 {
338 Logger::Get().
Log(
"Failed to create rasterizer state", __FILE__, __LINE__, Logger::LogLevel::Error);
339 return false;
340 }
341
342
343 device_context_->RSSetState(raster_state_);
344
345
346 viewport_.Width = (float)screenWidth;
347 viewport_.Height = (float)screenHeight;
348 viewport_.MinDepth = 0.0f;
349 viewport_.MaxDepth = 1.0f;
350 viewport_.TopLeftX = 0.0f;
351 viewport_.TopLeftY = 0.0f;
352
353
354 device_context_->RSSetViewports(1, &viewport_);
355
356
357 fieldOfView = 3.141592654f / 4.0f;
358 screenAspect = (float)screenWidth / (float)screenHeight;
359
360
361 projection_matrix_ = XMMatrixPerspectiveFovLH(fieldOfView, screenAspect, screenNear, screenDepth);
362
363
364 world_matrix_ = XMMatrixIdentity();
365
366
367 ortho_matrix_ = XMMatrixOrthographicLH((float)screenWidth, (float)screenHeight, screenNear, screenDepth);
368
369
370 ZeroMemory(&depthDisabledStencilDesc, sizeof(depthDisabledStencilDesc));
371
372
373
374 depthDisabledStencilDesc.DepthEnable = false;
375 depthDisabledStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
376 depthDisabledStencilDesc.DepthFunc = D3D11_COMPARISON_LESS;
377 depthDisabledStencilDesc.StencilEnable = true;
378 depthDisabledStencilDesc.StencilReadMask = 0xFF;
379 depthDisabledStencilDesc.StencilWriteMask = 0xFF;
380 depthDisabledStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
381 depthDisabledStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;
382 depthDisabledStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
383 depthDisabledStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
384 depthDisabledStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
385 depthDisabledStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR;
386 depthDisabledStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
387 depthDisabledStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
388
389
390 result = device_->CreateDepthStencilState(&depthDisabledStencilDesc, &depth_disabled_stencil_state_);
391 if (FAILED(result))
392 {
393 Logger::Get().
Log(
"Failed to create depth disabled stencil state", __FILE__, __LINE__, Logger::LogLevel::Error);
394 return false;
395 }
396
397
398 ZeroMemory(&blendStateDescription, sizeof(D3D11_BLEND_DESC));
399
400
401 blendStateDescription.RenderTarget[0].BlendEnable = TRUE;
402 blendStateDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE;
403 blendStateDescription.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
404 blendStateDescription.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
405 blendStateDescription.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
406 blendStateDescription.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
407 blendStateDescription.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
408 blendStateDescription.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
409
410
411 result = device_->CreateBlendState(&blendStateDescription, &alpha_enable_blending_state_);
412 if (FAILED(result))
413 {
414 Logger::Get().
Log(
"Failed to create alpha enabled blend state", __FILE__, __LINE__, Logger::LogLevel::Error);
415 return false;
416 }
417
418
419 blendStateDescription.RenderTarget[0].BlendEnable = FALSE;
420
421
422 result = device_->CreateBlendState(&blendStateDescription, &alpha_disable_blending_state_);
423 if (FAILED(result))
424 {
425 Logger::Get().
Log(
"Failed to create alpha disabled blend state", __FILE__, __LINE__, Logger::LogLevel::Error);
426 return false;
427 }
428
429 return true;
430}
void Log(const std::string &message, const std::string &fileName, int lineNumber, LogLevel level=LogLevel::Info)