#include "D3D.hpp" #include "../Utils.hpp" #include #include #include #include #include #include #include #include namespace Li::Gui { void D3D::createRenderTarget() { ID3D11Texture2D* backBuffer; this->swapChain->GetBuffer(0, IID_PPV_ARGS(&backBuffer)); this->d3dDevice->CreateRenderTargetView(backBuffer, NULL, &this->mainRenderTargetView); backBuffer->Release(); } bool D3D::createDeviceD3D() { // Setup swap chain DXGI_SWAP_CHAIN_DESC sd; memset(&sd, 0, sizeof(sd)); sd.BufferCount = 2; sd.BufferDesc.Width = this->windowWidth; sd.BufferDesc.Height = this->windowHeight; sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; sd.BufferDesc.RefreshRate.Numerator = 60; sd.BufferDesc.RefreshRate.Denominator = 1; sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.OutputWindow = this->hwnd; sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; sd.Windowed = TRUE; sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; UINT createDeviceFlags = 0; #ifdef DEBUG createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_FEATURE_LEVEL featureLevel; const D3D_FEATURE_LEVEL featureLevelArray[2] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_0, }; if (D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, featureLevelArray, 2, D3D11_SDK_VERSION, &sd, &this->swapChain, &this->d3dDevice, &featureLevel, &this->d3dDeviceContext) != S_OK) return false; return true; } void D3D::cleanupDeviceD3D() { if (this->swapChain) { this->swapChain->Release(); this->swapChain = NULL; } if (this->d3dDeviceContext) { this->d3dDeviceContext->Release(); this->d3dDeviceContext = NULL; } if (this->d3dDevice) { this->d3dDevice->Release(); this->d3dDevice = NULL; } } void D3D::cleanupRenderTarget() { if (this->mainRenderTargetView) { this->mainRenderTargetView->Release(); this->mainRenderTargetView = NULL; } } ID3D11Device* D3D::D3dDevice() { return this->d3dDevice; } ID3D11DeviceContext* D3D::D3dDeviceContext() { return this->d3dDeviceContext; } void D3D::InitImgui() { ImGui_ImplDX11_Init(this->d3dDevice, this->d3dDeviceContext); } void D3D::ImGuiNewFrame() { DirectX::XMFLOAT4 clearColor(0.0f, 0.0f, 0.0f, 1.0f); const float clearColorWithAlpha[4] = { clearColor.x * clearColor.w, clearColor.y * clearColor.w, clearColor.z * clearColor.w, clearColor.w }; this->d3dDeviceContext->ClearRenderTargetView(this->mainRenderTargetView, clearColorWithAlpha); ImGui_ImplDX11_NewFrame(); } void D3D::Resize(int newWidth, int newHeight) { this->cleanupRenderTarget(); this->windowWidth = newWidth; this->windowHeight = newHeight; this->swapChain->ResizeBuffers(0, newWidth, newHeight, DXGI_FORMAT_UNKNOWN, 0); this->createRenderTarget(); this->setupRenderTarget(); } int D3D::CompileShader(std::string shaderSrc, std::string entryPoint, std::string shaderModel, void** shaderObjectOut) { DWORD shaderFlags = D3DCOMPILE_ENABLE_STRICTNESS; #ifdef _DEBUG shaderFlags |= D3DCOMPILE_DEBUG; shaderFlags |= D3DCOMPILE_SKIP_OPTIMIZATION; #endif ID3DBlob* errorObj = nullptr; HRESULT res = D3DCompile(shaderSrc.c_str(), shaderSrc.size(), nullptr, nullptr, nullptr, entryPoint.c_str(), shaderModel.c_str(), shaderFlags, 0, (ID3DBlob**)shaderObjectOut, &errorObj); if (res < 0) { if (errorObj) { std::string error = std::string((const char*)(errorObj->GetBufferPointer())); Utils::ShowErrorMessage("Failed to compile shader: " + error); errorObj->Release(); } return res; } if (errorObj) errorObj->Release(); return S_OK; } void D3D::setupRenderTarget() { this->d3dDeviceContext->OMSetRenderTargets(1, &this->mainRenderTargetView, NULL); D3D11_VIEWPORT vp; vp.Width = (FLOAT)this->windowWidth; vp.Height = (FLOAT)this->windowHeight; vp.MinDepth = 0.0f; vp.MaxDepth = 1.0f; vp.TopLeftX = 0; vp.TopLeftY = 0; this->d3dDeviceContext->RSSetViewports(1, &vp); this->d3dDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); } void D3D::Render() { ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData()); this->swapChain->Present(1, 0); } int D3D::WindowHeight() { return this->windowHeight; } int D3D::WindowWidth() { return this->windowWidth; } D3D::D3D(HWND hwnd, int windowWidth, int windowHeight) { this->hwnd = hwnd; this->windowWidth = windowWidth; this->windowHeight = windowHeight; this->createDeviceD3D(); this->createRenderTarget(); this->setupRenderTarget(); }; D3D::~D3D() { this->cleanupRenderTarget(); this->cleanupDeviceD3D(); } }