176 lines
5.4 KiB
C++
176 lines
5.4 KiB
C++
#include "D3D.hpp"
|
|
#include "../Utils.hpp"
|
|
|
|
#include <string>
|
|
#include <iostream>
|
|
#include <SDL.h>
|
|
#include <imgui.h>
|
|
#include <imgui_impl_dx11.h>
|
|
#include <DirectXMath.h>
|
|
#include <d3dcompiler.h>
|
|
#include <d3d11.h>
|
|
|
|
|
|
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();
|
|
}
|
|
|
|
|
|
} |