7d_3d_class::d_3d_class()
12 render_target_view_ = 0;
13 depth_stencil_buffer_ = 0;
14 depth_stencil_state_ = 0;
15 depth_stencil_view_ = 0;
17 depth_disabled_stencil_state_ = 0;
18 alpha_enable_blending_state_ = 0;
19 alpha_disable_blending_state_ = 0;
28d_3d_class::~d_3d_class()
33bool d_3d_class::initialize(
int screenWidth,
int screenHeight,
bool vsync, HWND hwnd,
bool fullscreen,
float screenDepth,
float screenNear)
35 Logger::Get().Log(
"Initializing D3Dclass", __FILE__, __LINE__, Logger::LogLevel::Initialize);
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;
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;
58 vsync_enabled_ = vsync;
61 result = CreateDXGIFactory(__uuidof(IDXGIFactory), (
void**)&factory);
64 Logger::Get().Log(
"Failed to create DXGIFactory", __FILE__, __LINE__, Logger::LogLevel::Error);
69 result = factory->EnumAdapters(0, &adapter);
72 Logger::Get().Log(
"Failed to create adapter", __FILE__, __LINE__, Logger::LogLevel::Error);
77 result = adapter->EnumOutputs(0, &adapterOutput);
80 Logger::Get().Log(
"Failed to create adapter output", __FILE__, __LINE__, Logger::LogLevel::Error);
85 result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, NULL);
88 Logger::Get().Log(
"Failed to get display mode list", __FILE__, __LINE__, Logger::LogLevel::Error);
93 displayModeList =
new DXGI_MODE_DESC[numModes];
96 Logger::Get().Log(
"Failed to create display mode list", __FILE__, __LINE__, Logger::LogLevel::Error);
101 result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList);
104 Logger::Get().Log(
"Failed to fill display mode list", __FILE__, __LINE__, Logger::LogLevel::Error);
110 for (i = 0; i < numModes; i++)
112 if (displayModeList[i].Width == (
unsigned int)screenWidth)
114 if (displayModeList[i].Height == (
unsigned int)screenHeight)
116 numerator = displayModeList[i].RefreshRate.Numerator;
117 denominator = displayModeList[i].RefreshRate.Denominator;
123 result = adapter->GetDesc(&adapterDesc);
126 Logger::Get().Log(
"Failed to get adapter description", __FILE__, __LINE__, Logger::LogLevel::Error);
131 video_card_memory_ = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024);
134 error = wcstombs_s(&stringLength, video_card_description_, 128, adapterDesc.Description, 128);
137 Logger::Get().Log(
"Failed to convert video card name to character array", __FILE__, __LINE__, Logger::LogLevel::Error);
142 delete[] displayModeList;
146 adapterOutput->Release();
158 ZeroMemory(&swapChainDesc,
sizeof(swapChainDesc));
161 swapChainDesc.BufferCount = 1;
164 swapChainDesc.BufferDesc.Width = screenWidth;
165 swapChainDesc.BufferDesc.Height = screenHeight;
168 swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
173 swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator;
174 swapChainDesc.BufferDesc.RefreshRate.Denominator = denominator;
178 swapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
179 swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
183 swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
186 swapChainDesc.OutputWindow = hwnd;
189 swapChainDesc.SampleDesc.Count = 1;
190 swapChainDesc.SampleDesc.Quality = 0;
195 swapChainDesc.Windowed =
false;
199 swapChainDesc.Windowed =
true;
203 swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
204 swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
207 swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
210 swapChainDesc.Flags = 0;
213 featureLevel = D3D_FEATURE_LEVEL_11_0;
216 result = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, &featureLevel, 1,
217 D3D11_SDK_VERSION, &swapChainDesc, &swap_chain, &device_, NULL, &device_context_);
220 Logger::Get().Log(
"Failed to create swap chain, device and device context", __FILE__, __LINE__, Logger::LogLevel::Error);
225 result = swap_chain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr);
228 Logger::Get().Log(
"Failed to get pointer to back buffer", __FILE__, __LINE__, Logger::LogLevel::Error);
233 result = device_->CreateRenderTargetView(backBufferPtr, NULL, &render_target_view_);
236 Logger::Get().Log(
"Failed to create render target view", __FILE__, __LINE__, Logger::LogLevel::Error);
241 backBufferPtr->Release();
245 ZeroMemory(&depthBufferDesc,
sizeof(depthBufferDesc));
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;
261 result = device_->CreateTexture2D(&depthBufferDesc, NULL, &depth_stencil_buffer_);
264 Logger::Get().Log(
"Failed to create texture for depth buffer", __FILE__, __LINE__, Logger::LogLevel::Error);
269 ZeroMemory(&depthStencilDesc,
sizeof(depthStencilDesc));
272 depthStencilDesc.DepthEnable =
true;
273 depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
274 depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS;
276 depthStencilDesc.StencilEnable =
true;
277 depthStencilDesc.StencilReadMask = 0xFF;
278 depthStencilDesc.StencilWriteMask = 0xFF;
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;
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;
293 result = device_->CreateDepthStencilState(&depthStencilDesc, &depth_stencil_state_);
296 Logger::Get().Log(
"Failed to create depth stencil state", __FILE__, __LINE__, Logger::LogLevel::Error);
301 device_context_->OMSetDepthStencilState(depth_stencil_state_, 1);
304 ZeroMemory(&depthStencilViewDesc,
sizeof(depthStencilViewDesc));
307 depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
308 depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
309 depthStencilViewDesc.Texture2D.MipSlice = 0;
312 result = device_->CreateDepthStencilView(depth_stencil_buffer_, &depthStencilViewDesc, &depth_stencil_view_);
315 Logger::Get().Log(
"Failed to create depth stencil view", __FILE__, __LINE__, Logger::LogLevel::Error);
320 device_context_->OMSetRenderTargets(1, &render_target_view_, depth_stencil_view_);
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;
335 result = device_->CreateRasterizerState(&rasterDesc, &raster_state_);
338 Logger::Get().Log(
"Failed to create rasterizer state", __FILE__, __LINE__, Logger::LogLevel::Error);
343 device_context_->RSSetState(raster_state_);
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;
354 device_context_->RSSetViewports(1, &viewport_);
357 fieldOfView = 3.141592654f / 4.0f;
358 screenAspect = (float)screenWidth / (
float)screenHeight;
361 projection_matrix_ = XMMatrixPerspectiveFovLH(fieldOfView, screenAspect, screenNear, screenDepth);
364 world_matrix_ = XMMatrixIdentity();
367 ortho_matrix_ = XMMatrixOrthographicLH((
float)screenWidth, (
float)screenHeight, screenNear, screenDepth);
370 ZeroMemory(&depthDisabledStencilDesc,
sizeof(depthDisabledStencilDesc));
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;
390 result = device_->CreateDepthStencilState(&depthDisabledStencilDesc, &depth_disabled_stencil_state_);
393 Logger::Get().Log(
"Failed to create depth disabled stencil state", __FILE__, __LINE__, Logger::LogLevel::Error);
398 ZeroMemory(&blendStateDescription,
sizeof(D3D11_BLEND_DESC));
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;
411 result = device_->CreateBlendState(&blendStateDescription, &alpha_enable_blending_state_);
414 Logger::Get().Log(
"Failed to create alpha enabled blend state", __FILE__, __LINE__, Logger::LogLevel::Error);
419 blendStateDescription.RenderTarget[0].BlendEnable = FALSE;
422 result = device_->CreateBlendState(&blendStateDescription, &alpha_disable_blending_state_);
425 Logger::Get().Log(
"Failed to create alpha disabled blend state", __FILE__, __LINE__, Logger::LogLevel::Error);
433void d_3d_class::shutdown()
436 Logger::Get().Log(
"Shutting down D3Dclass", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
441 swap_chain->SetFullscreenState(
false, NULL);
444 if (alpha_enable_blending_state_)
446 alpha_enable_blending_state_->Release();
447 alpha_enable_blending_state_ = 0;
450 if (alpha_disable_blending_state_)
452 alpha_disable_blending_state_->Release();
453 alpha_disable_blending_state_ = 0;
456 if (depth_disabled_stencil_state_)
458 depth_disabled_stencil_state_->Release();
459 depth_disabled_stencil_state_ = 0;
464 raster_state_->Release();
468 if (depth_stencil_view_)
470 depth_stencil_view_->Release();
471 depth_stencil_view_ = 0;
474 if (depth_stencil_state_)
476 depth_stencil_state_->Release();
477 depth_stencil_state_ = 0;
480 if (depth_stencil_buffer_)
482 depth_stencil_buffer_->Release();
483 depth_stencil_buffer_ = 0;
486 if (render_target_view_)
488 render_target_view_->Release();
489 render_target_view_ = 0;
494 device_context_->Release();
506 swap_chain->Release();
510 Logger::Get().Log(
"D3Dclass shutdown", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
516void d_3d_class::begin_scene(
float red,
float green,
float blue,
float alpha)
528 device_context_->ClearRenderTargetView(render_target_view_, color);
533 device_context_->ClearDepthStencilView(depth_stencil_view_, D3D11_CLEAR_DEPTH, 1.0f, 0);
539void d_3d_class::end_scene()
545 swap_chain->Present(1, 0);
550 swap_chain->Present(0, 0);
557ID3D11Device* d_3d_class::get_device()
563ID3D11DeviceContext* d_3d_class::get_device_context()
565 return device_context_;
568void d_3d_class::get_video_card_info(
char* cardName,
int& memory)
570 strcpy_s(cardName, 128, video_card_description_);
571 memory = video_card_memory_;
576void d_3d_class::set_back_buffer_render_target()
579 device_context_->OMSetRenderTargets(1, &render_target_view_, depth_stencil_view_);
585void d_3d_class::reset_viewport()
588 device_context_->RSSetViewports(1, &viewport_);
593void d_3d_class::release_resources()
595 Logger::Get().Log(
"Releasing D3D resources", __FILE__, __LINE__);
598 if (render_target_view_)
600 render_target_view_->Release();
601 render_target_view_ = 0;
605 if (depth_stencil_buffer_)
607 depth_stencil_buffer_->Release();
608 depth_stencil_buffer_ = 0;
612 if (depth_stencil_view_)
614 depth_stencil_view_->Release();
615 depth_stencil_view_ = 0;
618 Logger::Get().Log(
"D3D resources released", __FILE__, __LINE__);
622void d_3d_class::reset_resources(
int newWidth,
int newHeight)
624 Logger::Get().Log(
"Resetting D3D resources", __FILE__, __LINE__);
628 ID3D11Texture2D* backBuffer;
629 result = swap_chain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBuffer);
632 Logger::Get().Log(
"Failed to get back buffer", __FILE__, __LINE__, Logger::LogLevel::Error);
636 result = device_->CreateRenderTargetView(backBuffer, NULL, &render_target_view_);
639 Logger::Get().Log(
"Failed to create render target view", __FILE__, __LINE__, Logger::LogLevel::Error);
643 result = backBuffer->Release();
646 Logger::Get().Log(
"Failed to release back buffer", __FILE__, __LINE__, Logger::LogLevel::Error);
651 D3D11_TEXTURE2D_DESC depthBufferDesc;
652 ZeroMemory(&depthBufferDesc,
sizeof(depthBufferDesc));
653 depthBufferDesc.Width = newWidth;
654 depthBufferDesc.Height = newHeight;
655 depthBufferDesc.MipLevels = 1;
656 depthBufferDesc.ArraySize = 1;
657 depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
658 depthBufferDesc.SampleDesc.Count = 1;
659 depthBufferDesc.SampleDesc.Quality = 0;
660 depthBufferDesc.Usage = D3D11_USAGE_DEFAULT;
661 depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
662 depthBufferDesc.CPUAccessFlags = 0;
663 depthBufferDesc.MiscFlags = 0;
665 D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc;
666 ZeroMemory(&depthStencilViewDesc,
sizeof(depthStencilViewDesc));
667 depthStencilViewDesc.Format = depthBufferDesc.Format;
668 depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
669 depthStencilViewDesc.Texture2D.MipSlice = 0;
672 result = device_->CreateTexture2D(&depthBufferDesc, NULL, &depth_stencil_buffer_);
675 Logger::Get().Log(
"Failed to create depth stencil buffer", __FILE__, __LINE__, Logger::LogLevel::Error);
679 result = device_->CreateDepthStencilView(depth_stencil_buffer_, &depthStencilViewDesc, &depth_stencil_view_);
682 Logger::Get().Log(
"Failed to create depth stencil view", __FILE__, __LINE__, Logger::LogLevel::Error);
687 device_context_->OMSetRenderTargets(1, &render_target_view_, depth_stencil_view_);
690IDXGISwapChain* d_3d_class::get_swap_chain()
695void d_3d_class::resize_swap_chain(
int newWidth,
int newHeight)
699 Logger::Get().Log(
"Resizing swap chain to " + std::to_string(newWidth) +
"x" + std::to_string(newHeight), __FILE__, __LINE__);
705 device_context_->Flush();
708 result = swap_chain->ResizeBuffers(0, newWidth, newHeight, DXGI_FORMAT_UNKNOWN, 0);
711 Logger::Get().Log(
"Failed to resize swap chain", __FILE__, __LINE__, Logger::LogLevel::Error);
716 reset_resources(newWidth, newHeight);
719 viewport_.Width =
static_cast<float>(newWidth);
720 viewport_.Height =
static_cast<float>(newHeight);
721 device_context_->RSSetViewports(1, &viewport_);
724void d_3d_class::turn_z_buffer_on()
726 device_context_->OMSetDepthStencilState(depth_stencil_state_, 1);
731void d_3d_class::turn_z_buffer_off()
733 device_context_->OMSetDepthStencilState(depth_disabled_stencil_state_, 1);
737void d_3d_class::enable_alpha_blending()
739 float blendFactor[4];
743 blendFactor[0] = 0.0f;
744 blendFactor[1] = 0.0f;
745 blendFactor[2] = 0.0f;
746 blendFactor[3] = 0.0f;
749 device_context_->OMSetBlendState(alpha_enable_blending_state_, blendFactor, 0xffffffff);
754void d_3d_class::disable_alpha_blending()
756 float blendFactor[4];
760 blendFactor[0] = 0.0f;
761 blendFactor[1] = 0.0f;
762 blendFactor[2] = 0.0f;
763 blendFactor[3] = 0.0f;
766 device_context_->OMSetBlendState(alpha_disable_blending_state_, blendFactor, 0xffffffff);
771void d_3d_class::set_vsync(
bool vsync)
773 vsync_enabled_ = vsync;