13#include <imgui_internal.h>
16#include <d3dcompiler.h>
24DirectX11Renderer::DirectX11Renderer(
Window* window)
27 deviceContext(nullptr),
29 renderTargetView(nullptr) {
30 this->Type = RendererType::DirectX11;
31 this->cull = D3D11_CULL_FRONT;
33 ResourceManager::RegisterCreateBuffer(
this,&DirectX11Renderer::CreateBuffer);
34 ResourceManager::RegisterCreateShader(
this,&DirectX11Renderer::CreateShader);
35 ResourceManager::RegisterCreateTexture(
this,&DirectX11Renderer::CreateTexture);
36 ResourceManager::RegisterCreateCubemapTexture(
this,&DirectX11Renderer::CreateCubemapTexture);
37 ResourceManager::RegisterCreateCubemapTextureFromPanorama(
this,&DirectX11Renderer::CreateCubemapTextureFromPanorama);
38 ResourceManager::RegisterCreateTextureFromMemory(
39 [
this](
const void* data, uint32_t w, uint32_t h, TextureFormat fmt, uint32_t) -> Texture* {
40 auto* tex =
new DirectX11Texture(device);
41 if (tex->LoadFromMemory(data, w, h, fmt))
return tex;
48DirectX11Renderer::~DirectX11Renderer() {
52bool DirectX11Renderer::Initialize() {
53 HWND hwnd = (HWND)SDL_GetPointerProperty(SDL_GetWindowProperties(window->GetSDLWindow()),
54 SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL);
56 DXGI_SWAP_CHAIN_DESC swapChainDesc = {};
57 swapChainDesc.BufferCount = 2;
58 swapChainDesc.BufferDesc.Width = Window::GetWidth();
59 swapChainDesc.BufferDesc.Height = Window::GetHeight();
60 swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
61 swapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
62 swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
63 swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
64 swapChainDesc.OutputWindow = hwnd;
65 swapChainDesc.SampleDesc.Count = 1;
66 swapChainDesc.SampleDesc.Quality = 0;
67 swapChainDesc.Windowed = TRUE;
68 swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
70 UINT createDeviceFlags = 0;
72 createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
75 D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_0 };
76 HRESULT hr = D3D11CreateDeviceAndSwapChain(
78 D3D_DRIVER_TYPE_HARDWARE,
97 if (!CreateRenderTargetView() ||
98 !CreateDepthStencilBuffer(window->GetWidth(), window->GetHeight())) {
102 SetViewport(0, 0, window->GetWidth(), window->GetHeight());
104 SLEAK_INFO(
"DirectX 11 has successfully created!");
107 ID3D11InfoQueue* infoQueue;
108 if (SUCCEEDED(device->QueryInterface(__uuidof(ID3D11InfoQueue), (
void**)&infoQueue))) {
111 infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION,
true);
113 D3D11_MESSAGE_SEVERITY severities[] = {
114 D3D11_MESSAGE_SEVERITY_INFO
117 D3D11_INFO_QUEUE_FILTER filter = {};
118 filter.DenyList.NumSeverities = _countof(severities);
119 filter.DenyList.pSeverityList = severities;
121 infoQueue->AddStorageFilterEntries(&filter);
122 infoQueue->Release();
126 SetPerformanceCounter(
true);
127 SetRenderMode(RenderMode::Fill);
128 SetRenderFace(RenderFace::Front);
130 ConfigureRenderMode();
136 D3D11_QUERY_DESC queryDesc;
137 queryDesc.Query = D3D11_QUERY::D3D11_QUERY_PIPELINE_STATISTICS;
138 queryDesc.MiscFlags = 0;
139 if(FAILED(device->CreateQuery(&queryDesc,&query)))
140 SLEAK_WARN(
"Could not create pipeline statics object!");
143 if(bEnabledPerformanceCounter){
145 while (deviceContext->GetData(query,
nullptr, 0, 0) == S_FALSE);
146 deviceContext->Begin(query);
149 if (!CreateBlendState())
155void DirectX11Renderer::BeginRender() {
156 if (m_msaaChangeRequested)
160 if (m_hasPendingLightVP) {
161 std::memcpy(m_lightVP, m_pendingLightVP,
sizeof(m_lightVP));
165 if (m_tonemapEnabled && !m_tonemapResourcesCreated)
166 CreateTonemapResources();
169 if (m_tonemapEnabled && m_tonemapResourcesCreated && msaaSampleCount <= 1) {
170 deviceContext->OMSetRenderTargets(1, &m_hdrRTV, depthStencilView);
171 }
else if (msaaSampleCount > 1 && msaaRenderTargetView && msaaDepthStencilView) {
172 deviceContext->OMSetRenderTargets(1, &msaaRenderTargetView, msaaDepthStencilView);
174 deviceContext->OMSetRenderTargets(1, &renderTargetView, depthStencilView);
178 ClearDepthStencil(
true,
false, 1.0, 0);
181 if (m_shadowPassEnabled) {
188 if (m_shadowMapCreated && m_shadowSRV && m_shadowSampler) {
189 deviceContext->PSSetShaderResources(3, 1, &m_shadowSRV);
190 deviceContext->PSSetSamplers(3, 1, &m_shadowSampler);
193 if (bIsLayoutCreated)
194 deviceContext->IASetInputLayout(layout);
197 ImGui_ImplDX11_NewFrame();
198 ImGui_ImplSDL3_NewFrame();
203void DirectX11Renderer::EndRender() {
205 if (msaaSampleCount > 1) {
207 deviceContext->OMSetRenderTargets(1, &renderTargetView, depthStencilView);
212 if (m_tonemapEnabled && m_tonemapResourcesCreated && msaaSampleCount <= 1) {
213 ExecuteTonemapPass();
215 if (bIsLayoutCreated)
216 deviceContext->IASetInputLayout(layout);
220 if (bImInitialized) {
222 deviceContext->OMSetRenderTargets(1, &renderTargetView,
nullptr);
224 ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
227 swapChain->Present(m_vsync ? 1 : 0, 0);
229 UpdateFrameMetrics();
232void DirectX11Renderer::Cleanup() {
233 bImInitialized =
false;
236 CleanupTonemapResources();
237 CleanupShadowResources();
240 if (msaaRenderTarget) { msaaRenderTarget->Release(); msaaRenderTarget =
nullptr; }
241 if (msaaRenderTargetView) { msaaRenderTargetView->Release(); msaaRenderTargetView =
nullptr; }
242 if (msaaDepthStencilBuffer) { msaaDepthStencilBuffer->Release(); msaaDepthStencilBuffer =
nullptr; }
243 if (msaaDepthStencilView) { msaaDepthStencilView->Release(); msaaDepthStencilView =
nullptr; }
245 if (renderTargetView) {
246 renderTargetView->Release();
247 renderTargetView =
nullptr;
250 swapChain->Release();
254 deviceContext->Release();
255 deviceContext =
nullptr;
258 if (depthStencilView) {
259 depthStencilView->Release();
260 depthStencilView =
nullptr;
262 if (depthStencilBuffer) {
263 depthStencilBuffer->Release();
264 depthStencilBuffer =
nullptr;
266 if (depthStencilState) {
267 depthStencilState->Release();
268 depthStencilState =
nullptr;
272 blendState->Release();
273 blendState =
nullptr;
282 if (bImInitialized) {
283 ImGui_ImplDX11_Shutdown();
284 ImGui_ImplSDL3_Shutdown();
285 ImGui::DestroyContext();
286 bImInitialized =
false;
291 ID3D11Debug* debugDevice;
292 device->QueryInterface(__uuidof(ID3D11Debug), (
void**)&debugDevice);
294 debugDevice->ReportLiveDeviceObjects(D3D11_RLDO_DETAIL);
295 debugDevice->Release();
306bool DirectX11Renderer::CreateDepthStencilBuffer(uint32_t
width,uint32_t
height) {
308 D3D11_TEXTURE2D_DESC depthDesc = {};
309 depthDesc.Width =
width;
310 depthDesc.Height =
height;
311 depthDesc.MipLevels = 1;
312 depthDesc.ArraySize = 1;
313 depthDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
314 depthDesc.SampleDesc.Count = 1;
315 depthDesc.SampleDesc.Quality = 0;
316 depthDesc.Usage = D3D11_USAGE_DEFAULT;
317 depthDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
320 device->CreateTexture2D(&depthDesc,
nullptr, &depthStencilBuffer);
322 SLEAK_ERROR(
"Failed to create depth stencil buffer!");
326 hr = device->CreateDepthStencilView(depthStencilBuffer,
nullptr,
329 SLEAK_ERROR(
"Failed to create depth stencil view!");
333 deviceContext->OMSetRenderTargets(1, &renderTargetView, depthStencilView);
337void DirectX11Renderer::SetDepthStencilState(
bool enableDepth,
338 bool enableStencil) {
339 D3D11_DEPTH_STENCIL_DESC depthStencilDesc = {};
340 depthStencilDesc.DepthEnable = enableDepth;
341 depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
342 depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS;
343 depthStencilDesc.StencilEnable = enableStencil;
344 depthStencilDesc.StencilReadMask = 0xFF;
345 depthStencilDesc.StencilWriteMask = 0xFF;
348 depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
349 depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;
350 depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
351 depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
354 depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
355 depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR;
356 depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
357 depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
359 HRESULT hr = device->CreateDepthStencilState(&depthStencilDesc, &depthStencilState);
361 SLEAK_ERROR(
"Failed to create depth stencil state!");
365 deviceContext->OMSetDepthStencilState(depthStencilState, 1);
368void DirectX11Renderer::Resize(uint32_t
width, uint32_t
height) {
369 if (swapChain ==
nullptr || device ==
nullptr || deviceContext ==
nullptr) {
375 deviceContext->OMSetRenderTargets(0,
nullptr,
nullptr);
376 deviceContext->ClearState();
377 deviceContext->Flush();
380 if (renderTargetView) {
381 renderTargetView->Release();
382 renderTargetView =
nullptr;
385 if (depthStencilView) {
386 depthStencilView->Release();
387 depthStencilView =
nullptr;
389 if (depthStencilBuffer) {
390 depthStencilBuffer->Release();
391 depthStencilBuffer =
nullptr;
393 if (depthStencilState) {
394 depthStencilState->Release();
395 depthStencilState =
nullptr;
400 HRESULT hr = swapChain->ResizeBuffers(0,
406 SLEAK_ERROR(
"Failed to resize swap chain buffers! HRESULT: 0x{:X}", (
unsigned)hr);
411 if (!CreateRenderTargetView() || !CreateDepthStencilBuffer(
width,
height)) {
416 if (msaaSampleCount > 1) {
417 CreateMSAARenderTarget();
418 CreateMSAADepthStencil();
422 if (m_tonemapResourcesCreated) {
423 CleanupTonemapResources();
424 CreateTonemapResources();
435void DirectX11Renderer::Draw(uint32_t vertexCount) {
Draw(vertexCount, 0); }
437void DirectX11Renderer::Draw(uint32_t vertexCount, uint32_t firstVertex) {
438 deviceContext->Draw(vertexCount, firstVertex);
441void DirectX11Renderer::DrawIndexed(uint32_t indexCount) {
445void DirectX11Renderer::DrawIndexed(uint32_t indexCount, uint32_t firstIndex,
446 int32_t baseVertex) {
447 deviceContext->DrawIndexed(indexCount, firstIndex, baseVertex);
448 DrawnVertices += indexCount;
451void DirectX11Renderer::DrawInstance(uint32_t instanceCount,
452 uint32_t vertexPerInstance) {
453 deviceContext->DrawInstanced(vertexPerInstance, instanceCount, 0, 0);
456void DirectX11Renderer::DrawIndexedInstance(uint32_t instanceCount,
457 uint32_t indexPerInstance) {
458 DrawIndexedInstance(instanceCount, indexPerInstance, 0, 0);
461void DirectX11Renderer::DrawIndexedInstance(uint32_t instanceCount,
462 uint32_t indexPerInstance,
464 int32_t baseVertex) {
465 deviceContext->DrawIndexedInstanced(indexPerInstance, instanceCount,
466 firstIndex, baseVertex, 0);
469void DirectX11Renderer::ClearRenderTarget(
float r,
float g,
float b,
float a) {
470 const float clearColor[4] = {r, g, b, a};
472 ID3D11RenderTargetView* target;
473 if (m_tonemapEnabled && m_tonemapResourcesCreated && msaaSampleCount <= 1)
475 else if (msaaSampleCount > 1)
476 target = msaaRenderTargetView;
478 target = renderTargetView;
481 deviceContext->ClearRenderTargetView(target, clearColor);
484void DirectX11Renderer::ClearDepthStencil(
bool clearDepth,
bool clearStencil,
485 float depth, uint8_t stencil) {
487 if (clearDepth) clearFlags |= D3D11_CLEAR_DEPTH;
488 if (clearStencil) clearFlags |= D3D11_CLEAR_STENCIL;
490 ID3D11DepthStencilView* target = (msaaSampleCount > 1 && msaaDepthStencilView)
491 ? msaaDepthStencilView : depthStencilView;
493 deviceContext->ClearDepthStencilView(target, clearFlags, depth, stencil);
498void DirectX11Renderer::BindVertexBuffer(RefPtr<BufferBase> buffer, uint32_t slot) {
507 auto d3d11Buffer =
dynamic_cast<DirectX11Buffer*
>
511 deviceContext->IASetVertexBuffers(slot, 1, &d3d11Buffer, &stride, &offset);
514 catch (std::exception& e)
516 SLEAK_ERROR(
"Failed to cast Vertex Buffer! {}", e.what());
520void DirectX11Renderer::BindIndexBuffer(RefPtr<BufferBase> buffer,
528 dynamic_cast<DirectX11Buffer*
>(buffer.get())->GetD3DBuffer();
530 deviceContext->IASetIndexBuffer(d3d11Buffer, DXGI_FORMAT_R32_UINT, 0);
532 }
catch (std::exception& e) {
533 SLEAK_ERROR(
"Failed to cast Index Buffer! {}", e.what());
537void DirectX11Renderer::BindConstantBuffer(RefPtr<BufferBase> buffer,
540 auto* dx11Buf =
dynamic_cast<DirectX11Buffer*
>(buffer.get());
541 if (!dx11Buf)
return;
544 if (m_inShadowPass && slot == 0 && dx11Buf->GetCPUShadowCopySize() >= 128) {
545 const float* srcWorld =
reinterpret_cast<const float*
>(
546 static_cast<const char*
>(dx11Buf->GetCPUShadowCopy()) + 64);
549 for (
int r = 0; r < 4; ++r) {
550 for (
int c = 0; c < 4; ++c) {
552 for (
int k = 0; k < 4; ++k) {
553 sum += srcWorld[r * 4 + k] * m_lightVP[k * 4 + c];
555 shadowPC[r * 4 + c] = sum;
558 std::memcpy(&shadowPC[16], srcWorld,
sizeof(
float) * 16);
561 if (!m_shadowTransformCB) {
562 D3D11_BUFFER_DESC desc{};
563 desc.ByteWidth = 128;
564 desc.Usage = D3D11_USAGE_DYNAMIC;
565 desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
566 desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
567 device->CreateBuffer(&desc,
nullptr, &m_shadowTransformCB);
571 D3D11_MAPPED_SUBRESOURCE mapped{};
572 if (SUCCEEDED(deviceContext->Map(m_shadowTransformCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped))) {
573 std::memcpy(mapped.pData, shadowPC,
sizeof(shadowPC));
574 deviceContext->Unmap(m_shadowTransformCB, 0);
576 deviceContext->VSSetConstantBuffers(slot, 1, &m_shadowTransformCB);
577 deviceContext->PSSetConstantBuffers(slot, 1, &m_shadowTransformCB);
581 auto d3d11Buffer = dx11Buf->GetD3DBuffer();
582 deviceContext->VSSetConstantBuffers(slot, 1, &d3d11Buffer);
583 deviceContext->PSSetConstantBuffers(slot, 1, &d3d11Buffer);
585 }
catch (std::exception& e) {
586 SLEAK_ERROR(
"Failed to cast Constant Buffer! {}", e.what());
590void DirectX11Renderer::ConfigureRenderMode() {
593 case RenderMode::Fill:
594 topology = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
595 fillMode = D3D11_FILL_MODE::D3D11_FILL_SOLID;
597 case RenderMode::Points:
598 topology = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST;
599 fillMode = D3D11_FILL_MODE::D3D11_FILL_SOLID;
601 case RenderMode::Wireframe :
602 topology = D3D11_PRIMITIVE_TOPOLOGY_LINELIST;
603 fillMode = D3D11_FILL_MODE::D3D11_FILL_WIREFRAME;
611 deviceContext->IASetPrimitiveTopology(topology);
616void DirectX11Renderer::ConfigureRenderFace() {
618 case RenderFace::None : cull = D3D11_CULL_MODE::D3D11_CULL_NONE;
break;
619 case RenderFace::Front : cull = D3D11_CULL_MODE::D3D11_CULL_FRONT;
break;
620 case RenderFace::Back : cull = D3D11_CULL_MODE::D3D11_CULL_BACK;
break;
621 default: cull = D3D11_CULL_MODE::D3D11_CULL_FRONT;
625bool DirectX11Renderer::SetRasterState() {
626 ID3D11RasterizerState* rasterState;
627 D3D11_RASTERIZER_DESC RasterDesc = {};
628 RasterDesc.AntialiasedLineEnable =
true;
629 RasterDesc.MultisampleEnable =
true;
630 RasterDesc.CullMode = cull;
631 RasterDesc.DepthBias = 0;
632 RasterDesc.DepthBiasClamp = 0.0f;
633 RasterDesc.SlopeScaledDepthBias = 0.0f;
634 RasterDesc.DepthClipEnable =
true;
635 RasterDesc.ScissorEnable =
false;
636 RasterDesc.FillMode = fillMode;
637 RasterDesc.FrontCounterClockwise =
false;
639 if (FAILED(device->CreateRasterizerState(&RasterDesc, &rasterState))) {
642 deviceContext->RSSetState(rasterState);
643 rasterState->Release();
649void DirectX11Renderer::SetRenderMode(RenderMode mode) {
651 ConfigureRenderMode();
654void DirectX11Renderer::SetRenderFace(RenderFace face) {
656 ConfigureRenderFace();
659void DirectX11Renderer::SetViewport(
float x,
float y,
float width,
float height,
662 D3D11_VIEWPORT viewport = {};
663 viewport.Width =
static_cast<float>(
width);
664 viewport.Height =
static_cast<float>(
height);
665 viewport.MinDepth = minDepth;
666 viewport.MaxDepth = maxDepth;
667 viewport.TopLeftX = x;
668 viewport.TopLeftY = y;
669 deviceContext->RSSetViewports(1, &viewport);
673bool DirectX11Renderer::CreateRenderTargetView() {
675 if (renderTargetView) {
676 renderTargetView->Release();
677 renderTargetView =
nullptr;
681 ID3D11Texture2D* backBuffer =
nullptr;
682 HRESULT hr = swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D),
683 reinterpret_cast<void**
>(&backBuffer));
690 hr = device->CreateRenderTargetView(backBuffer,
nullptr, &renderTargetView);
691 backBuffer->Release();
693 SLEAK_ERROR(
"Failed to create render target view!");
698 deviceContext->OMSetRenderTargets(1, &renderTargetView,
nullptr);
700 SLEAK_INFO(
"Render target view created successfully.");
704Texture* DirectX11Renderer::CreateTextureFromData(uint32_t
width, uint32_t
height,
void* data) {
705 DirectX11Texture* texture =
new DirectX11Texture(device);
706 if (texture->LoadFromMemory(data,
width,
height,TextureFormat::RGBA8)) {
712Texture* DirectX11Renderer::CreateTexture(
const std::string& TexturePath) {
713 DirectX11Texture* texture =
new DirectX11Texture(device);
714 if (texture->LoadFromFile(TexturePath)) {
720Texture* DirectX11Renderer::CreateCubemapTexture(
721 const std::array<std::string, 6>& facePaths) {
722 auto* texture =
new DirectX11CubemapTexture(device);
723 if (texture->LoadCubemap(facePaths)) {
730Texture* DirectX11Renderer::CreateCubemapTextureFromPanorama(
731 const std::string& panoramaPath) {
732 auto* texture =
new DirectX11CubemapTexture(device);
733 if (texture->LoadEquirectangular(panoramaPath)) {
740void DirectX11Renderer::SetDepthWrite(
bool enabled) {
741 m_depthWriteEnabled = enabled;
743 D3D11_DEPTH_STENCIL_DESC desc = {};
744 desc.DepthEnable = TRUE;
745 desc.DepthWriteMask = enabled ? D3D11_DEPTH_WRITE_MASK_ALL
746 : D3D11_DEPTH_WRITE_MASK_ZERO;
747 desc.DepthFunc = m_depthFunc;
748 desc.StencilEnable = FALSE;
750 ID3D11DepthStencilState* state =
nullptr;
751 if (SUCCEEDED(device->CreateDepthStencilState(&desc, &state))) {
752 deviceContext->OMSetDepthStencilState(state, 1);
757void DirectX11Renderer::SetDepthCompare(DepthCompare compare) {
759 case DepthCompare::Less: m_depthFunc = D3D11_COMPARISON_LESS;
break;
760 case DepthCompare::LessEqual: m_depthFunc = D3D11_COMPARISON_LESS_EQUAL;
break;
761 case DepthCompare::Greater: m_depthFunc = D3D11_COMPARISON_GREATER;
break;
762 case DepthCompare::GreaterEqual: m_depthFunc = D3D11_COMPARISON_GREATER_EQUAL;
break;
763 case DepthCompare::Equal: m_depthFunc = D3D11_COMPARISON_EQUAL;
break;
764 case DepthCompare::NotEqual: m_depthFunc = D3D11_COMPARISON_NOT_EQUAL;
break;
765 case DepthCompare::Always: m_depthFunc = D3D11_COMPARISON_ALWAYS;
break;
766 case DepthCompare::Never: m_depthFunc = D3D11_COMPARISON_NEVER;
break;
769 D3D11_DEPTH_STENCIL_DESC desc = {};
770 desc.DepthEnable = TRUE;
771 desc.DepthWriteMask = m_depthWriteEnabled ? D3D11_DEPTH_WRITE_MASK_ALL
772 : D3D11_DEPTH_WRITE_MASK_ZERO;
773 desc.DepthFunc = m_depthFunc;
774 desc.StencilEnable = FALSE;
776 ID3D11DepthStencilState* state =
nullptr;
777 if (SUCCEEDED(device->CreateDepthStencilState(&desc, &state))) {
778 deviceContext->OMSetDepthStencilState(state, 1);
783void DirectX11Renderer::SetCullEnabled(
bool enabled) {
785 cull = D3D11_CULL_FRONT;
787 cull = D3D11_CULL_NONE;
792void DirectX11Renderer::BindTexture(RefPtr<Sleak::Texture> texture,
794 if (texture.IsValid()) {
799void DirectX11Renderer::BeginSkyboxPass() {
801 m_savedCullMode = cull;
802 m_savedDepthStencilState = depthStencilState;
803 if (m_savedDepthStencilState) {
804 m_savedDepthStencilState->AddRef();
808void DirectX11Renderer::EndSkyboxPass() {
810 if (m_savedDepthStencilState) {
811 deviceContext->OMSetDepthStencilState(m_savedDepthStencilState, 1);
812 m_savedDepthStencilState->Release();
813 m_savedDepthStencilState =
nullptr;
817 cull = m_savedCullMode;
821 m_depthWriteEnabled =
true;
822 m_depthFunc = D3D11_COMPARISON_LESS;
825void DirectX11Renderer::BeginDebugLinePass() {
826 m_savedTopology = topology;
827 topology = D3D11_PRIMITIVE_TOPOLOGY_LINELIST;
828 deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST);
831void DirectX11Renderer::EndDebugLinePass() {
832 topology = m_savedTopology;
833 deviceContext->IASetPrimitiveTopology(topology);
836BufferBase* DirectX11Renderer::CreateBuffer(BufferType Type, uint32_t size,
void* data) {
839 DirectX11Buffer* buffer =
new DirectX11Buffer(device, size, Type);
840 if (!buffer->Initialize(data)) {
844 return static_cast<BufferBase*
>(buffer);
847Shader* DirectX11Renderer::CreateShader(
const std::string& shaderSource) {
848 DirectX11Shader* shader =
new DirectX11Shader(device);
849 if (shader->compile(shaderSource)) {
852 auto* il = shader->createInputLayout();
853 if (!bIsLayoutCreated && il) {
855 bIsLayoutCreated =
true;
857 return static_cast<Shader*
>(shader);
862bool DirectX11Renderer::CreateBlendState() {
867 D3D11_BLEND_DESC desc;
868 desc.AlphaToCoverageEnable =
false;
869 desc.IndependentBlendEnable =
false;
871 desc.RenderTarget[0].BlendEnable =
true;
873 desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
874 desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
876 desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
877 desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
879 desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
880 desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
882 desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
884 if (FAILED(device->CreateBlendState(&desc, &blendState)))
890void DirectX11Renderer::SetBlendState(
float r,
float g,
float b,
float a, UINT Mask) {
891 float BlendFactor[4] = {r,g,b,a};
892 deviceContext->OMSetBlendState(blendState, BlendFactor, Mask);
895void DirectX11Renderer::CheckMSAASupport() {
896 m_maxMsaaSampleCount = 1;
897 for (UINT sampleCount = 1;
898 sampleCount <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT;
902 HRESULT hr = device->CheckMultisampleQualityLevels(
903 DXGI_FORMAT_R8G8B8A8_UNORM, sampleCount, &quality);
904 if (SUCCEEDED(hr) && quality > 0) {
905 SLEAK_INFO(
"MSAA {}x supported with {} quality levels.",
906 sampleCount, quality);
907 if (sampleCount <= 8)
908 m_maxMsaaSampleCount = sampleCount;
913bool DirectX11Renderer::CreateMSAARenderTarget() {
915 if (msaaRenderTarget) msaaRenderTarget->Release();
916 if (msaaRenderTargetView) msaaRenderTargetView->Release();
918 D3D11_TEXTURE2D_DESC texDesc;
919 texDesc.Width = window->GetWidth();
920 texDesc.Height = window->GetHeight();
921 texDesc.MipLevels = 1;
922 texDesc.ArraySize = 1;
923 texDesc.SampleDesc.Count = msaaSampleCount;
924 texDesc.SampleDesc.Quality = msaaQualityLevel;
925 texDesc.BindFlags = D3D11_BIND_RENDER_TARGET;
926 texDesc.CPUAccessFlags = 0;
927 texDesc.MiscFlags = 0;
928 texDesc.Usage = D3D11_USAGE_DEFAULT;
929 texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
931 if (FAILED(device->CreateTexture2D(&texDesc,
nullptr, &msaaRenderTarget)))
934 if (FAILED(device->CreateRenderTargetView(msaaRenderTarget,
nullptr,&msaaRenderTargetView)))
940bool DirectX11Renderer::CreateMSAADepthStencil() {
941 if (msaaDepthStencilBuffer) msaaDepthStencilBuffer->Release();
942 if (msaaDepthStencilView) msaaDepthStencilView->Release();
944 D3D11_TEXTURE2D_DESC texDesc;
945 texDesc.Width = window->GetWidth();
946 texDesc.Height = window->GetHeight();
947 texDesc.MipLevels = 1;
948 texDesc.ArraySize = 1;
949 texDesc.SampleDesc.Count = msaaSampleCount;
950 texDesc.SampleDesc.Quality = msaaQualityLevel;
951 texDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
952 texDesc.CPUAccessFlags = 0;
953 texDesc.MiscFlags = 0;
954 texDesc.Usage = D3D11_USAGE_DEFAULT;
955 texDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
957 if (FAILED(device->CreateTexture2D(&texDesc,
nullptr,&msaaDepthStencilBuffer)))
return false;
959 if (FAILED(device->CreateDepthStencilView(msaaDepthStencilBuffer,
nullptr,&msaaDepthStencilView)))
return false;
965void DirectX11Renderer::ResolveMSAA() {
966 if (msaaSampleCount <= 1 || msaaSampleCount % 2 != 0)
969 ID3D11Texture2D* back;
970 if (FAILED(swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (
void**)&back))) {
971 SLEAK_ERROR(
"Failed to get back buffer for MSAA!");
974 deviceContext->ResolveSubresource(back,0,msaaRenderTarget,0,DXGI_FORMAT_R8G8B8A8_UNORM);
979void DirectX11Renderer::ApplyMSAAChange() {
980 if (!m_msaaChangeRequested)
982 m_msaaChangeRequested =
false;
984 m_msaaSampleCount = m_pendingMsaaSampleCount;
985 msaaSampleCount = m_pendingMsaaSampleCount;
989 device->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM,
990 msaaSampleCount, &quality);
991 msaaQualityLevel = (quality > 0) ? quality - 1 : 0;
994 if (msaaRenderTarget) { msaaRenderTarget->Release(); msaaRenderTarget =
nullptr; }
995 if (msaaRenderTargetView) { msaaRenderTargetView->Release(); msaaRenderTargetView =
nullptr; }
996 if (msaaDepthStencilBuffer) { msaaDepthStencilBuffer->Release(); msaaDepthStencilBuffer =
nullptr; }
997 if (msaaDepthStencilView) { msaaDepthStencilView->Release(); msaaDepthStencilView =
nullptr; }
999 if (msaaSampleCount > 1) {
1000 CreateMSAARenderTarget();
1001 CreateMSAADepthStencil();
1004 deviceContext->OMSetRenderTargets(1, &renderTargetView, depthStencilView);
1007 SLEAK_INFO(
"DX11 MSAA changed to {}x", msaaSampleCount);
1010bool DirectX11Renderer::CreateImGUI()
1012 IMGUI_CHECKVERSION();
1013 ImCon = ImGui::CreateContext();
1014 ImCon->IO.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
1016 ImGui::StyleColorsDark();
1018 if(!ImGui_ImplSDL3_InitForD3D(window->GetSDLWindow()))
1021 if(!ImGui_ImplDX11_Init(device, deviceContext))
1024 if(!ImGui_ImplDX11_CreateDeviceObjects())
1028 bImInitialized =
true;
1036bool DirectX11Renderer::CreateShadowConstantBuffer() {
1037 if (m_shadowCBCreated)
return true;
1039 D3D11_BUFFER_DESC desc{};
1040 desc.ByteWidth =
sizeof(PCSSShadowGPUData);
1041 desc.Usage = D3D11_USAGE_DYNAMIC;
1042 desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
1043 desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
1045 HRESULT hr = device->CreateBuffer(&desc,
nullptr, &m_shadowCB);
1047 SLEAK_ERROR(
"Failed to create shadow constant buffer!");
1051 m_shadowCBCreated =
true;
1055void DirectX11Renderer::CleanupShadowResources() {
1056 if (m_shadowCB) { m_shadowCB->Release(); m_shadowCB =
nullptr; }
1057 m_shadowCBCreated =
false;
1058 if (m_shadowTransformCB) { m_shadowTransformCB->Release(); m_shadowTransformCB =
nullptr; }
1059 if (m_shadowRasterState) { m_shadowRasterState->Release(); m_shadowRasterState =
nullptr; }
1060 if (m_shadowSampler) { m_shadowSampler->Release(); m_shadowSampler =
nullptr; }
1061 if (m_shadowSRV) { m_shadowSRV->Release(); m_shadowSRV =
nullptr; }
1062 if (m_shadowDSV) { m_shadowDSV->Release(); m_shadowDSV =
nullptr; }
1063 if (m_shadowDepthTex) { m_shadowDepthTex->Release(); m_shadowDepthTex =
nullptr; }
1064 m_shadowMapCreated =
false;
1067void DirectX11Renderer::SetLightVP(
const float* mat) {
1069 std::memcpy(m_pendingLightVP, mat,
sizeof(m_pendingLightVP));
1070 m_hasPendingLightVP =
true;
1074bool DirectX11Renderer::CreateShadowMapResources() {
1075 if (m_shadowMapCreated)
return true;
1078 D3D11_TEXTURE2D_DESC texDesc{};
1079 texDesc.Width = m_shadowMapResolution;
1080 texDesc.Height = m_shadowMapResolution;
1081 texDesc.MipLevels = 1;
1082 texDesc.ArraySize = 1;
1083 texDesc.Format = DXGI_FORMAT_R32_TYPELESS;
1084 texDesc.SampleDesc.Count = 1;
1085 texDesc.SampleDesc.Quality = 0;
1086 texDesc.Usage = D3D11_USAGE_DEFAULT;
1087 texDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE;
1089 HRESULT hr = device->CreateTexture2D(&texDesc,
nullptr, &m_shadowDepthTex);
1091 SLEAK_ERROR(
"Failed to create shadow depth texture!");
1096 D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc{};
1097 dsvDesc.Format = DXGI_FORMAT_D32_FLOAT;
1098 dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
1099 hr = device->CreateDepthStencilView(m_shadowDepthTex, &dsvDesc, &m_shadowDSV);
1106 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc{};
1107 srvDesc.Format = DXGI_FORMAT_R32_FLOAT;
1108 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
1109 srvDesc.Texture2D.MipLevels = 1;
1110 hr = device->CreateShaderResourceView(m_shadowDepthTex, &srvDesc, &m_shadowSRV);
1117 D3D11_SAMPLER_DESC sampDesc{};
1118 sampDesc.Filter = D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT;
1119 sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_BORDER;
1120 sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_BORDER;
1121 sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_BORDER;
1122 sampDesc.BorderColor[0] = 1.0f;
1123 sampDesc.BorderColor[1] = 1.0f;
1124 sampDesc.BorderColor[2] = 1.0f;
1125 sampDesc.BorderColor[3] = 1.0f;
1126 sampDesc.ComparisonFunc = D3D11_COMPARISON_LESS_EQUAL;
1127 sampDesc.MinLOD = 0;
1128 sampDesc.MaxLOD = 0;
1129 hr = device->CreateSamplerState(&sampDesc, &m_shadowSampler);
1136 D3D11_RASTERIZER_DESC rasterDesc{};
1137 rasterDesc.FillMode = D3D11_FILL_SOLID;
1138 rasterDesc.CullMode = D3D11_CULL_NONE;
1139 rasterDesc.FrontCounterClockwise = FALSE;
1140 rasterDesc.DepthBias = 100;
1141 rasterDesc.SlopeScaledDepthBias = 2.0f;
1142 rasterDesc.DepthBiasClamp = 0.01f;
1143 rasterDesc.DepthClipEnable = TRUE;
1144 hr = device->CreateRasterizerState(&rasterDesc, &m_shadowRasterState);
1146 SLEAK_ERROR(
"Failed to create shadow rasterizer state!");
1150 m_shadowMapCreated =
true;
1151 m_shadowResourcesCreated =
true;
1152 SLEAK_INFO(
"D3D11 shadow map resources created ({}x{})", m_shadowMapResolution, m_shadowMapResolution);
1156void DirectX11Renderer::RenderShadowPass() {
1158 auto* queue = RenderCommandQueue::GetInstance();
1159 if (!queue || !queue->HasCachedShadowDraws())
return;
1161 if (!m_shadowMapCreated) {
1162 if (!CreateShadowMapResources())
return;
1166 ID3D11RenderTargetView* savedRTV =
nullptr;
1167 ID3D11DepthStencilView* savedDSV =
nullptr;
1168 deviceContext->OMGetRenderTargets(1, &savedRTV, &savedDSV);
1170 D3D11_VIEWPORT savedViewport;
1171 UINT numViewports = 1;
1172 deviceContext->RSGetViewports(&numViewports, &savedViewport);
1175 ID3D11ShaderResourceView* nullSRV =
nullptr;
1176 deviceContext->PSSetShaderResources(3, 1, &nullSRV);
1179 ID3D11RenderTargetView* nullRTV =
nullptr;
1180 deviceContext->OMSetRenderTargets(1, &nullRTV, m_shadowDSV);
1183 D3D11_VIEWPORT shadowViewport{};
1184 shadowViewport.Width =
static_cast<float>(m_shadowMapResolution);
1185 shadowViewport.Height =
static_cast<float>(m_shadowMapResolution);
1186 shadowViewport.MinDepth = 0.0f;
1187 shadowViewport.MaxDepth = 1.0f;
1188 deviceContext->RSSetViewports(1, &shadowViewport);
1191 deviceContext->ClearDepthStencilView(m_shadowDSV, D3D11_CLEAR_DEPTH, 1.0f, 0);
1194 deviceContext->RSSetState(m_shadowRasterState);
1197 deviceContext->IASetPrimitiveTopology(topology);
1198 if (bIsLayoutCreated)
1199 deviceContext->IASetInputLayout(layout);
1202 m_inShadowPass =
true;
1204 queue->ExecuteShadowPass(
this);
1206 m_inShadowPass =
false;
1212 deviceContext->OMSetRenderTargets(1, &savedRTV, savedDSV);
1213 deviceContext->RSSetViewports(1, &savedViewport);
1214 if (savedRTV) savedRTV->Release();
1215 if (savedDSV) savedDSV->Release();
1218 deviceContext->PSSetShaderResources(3, 1, &m_shadowSRV);
1219 deviceContext->PSSetSamplers(3, 1, &m_shadowSampler);
1222void DirectX11Renderer::UpdateShadowLightUBO(
const void* data, uint32_t size) {
1223 if (!device || !deviceContext)
return;
1226 if (!m_shadowCBCreated) {
1227 if (!CreateShadowConstantBuffer())
return;
1231 const auto* ubo =
static_cast<const ShadowLightUBO*
>(data);
1233 PCSSShadowGPUData shadowData{};
1234 std::memcpy(shadowData.LightVP, ubo->LightVP,
sizeof(
float) * 16);
1235 shadowData.ShadowBias = ubo->ShadowBias;
1236 shadowData.ShadowStrength = ubo->ShadowStrength;
1237 shadowData.ShadowTexelSize = ubo->ShadowTexelSize;
1238 shadowData.ShadowLightSize = ubo->LightSize;
1239 shadowData.PCSSEnabled = m_pcssEnabled ? 1 : 0;
1240 shadowData.ShadowMapEnabled = m_shadowPassEnabled ? 1 : 0;
1242 D3D11_MAPPED_SUBRESOURCE mapped{};
1243 HRESULT hr = deviceContext->Map(m_shadowCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped);
1244 if (SUCCEEDED(hr)) {
1245 std::memcpy(mapped.pData, &shadowData,
sizeof(shadowData));
1246 deviceContext->Unmap(m_shadowCB, 0);
1250 deviceContext->VSSetConstantBuffers(5, 1, &m_shadowCB);
1251 deviceContext->PSSetConstantBuffers(5, 1, &m_shadowCB);
1256bool DirectX11Renderer::CreateTonemapResources() {
1257 if (m_tonemapResourcesCreated)
return true;
1258 if (!device)
return false;
1261 ID3D11Texture2D* backBuffer =
nullptr;
1262 swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (
void**)&backBuffer);
1263 if (!backBuffer)
return false;
1265 D3D11_TEXTURE2D_DESC bbDesc{};
1266 backBuffer->GetDesc(&bbDesc);
1267 backBuffer->Release();
1270 D3D11_TEXTURE2D_DESC texDesc{};
1271 texDesc.Width = bbDesc.Width;
1272 texDesc.Height = bbDesc.Height;
1273 texDesc.MipLevels = 1;
1274 texDesc.ArraySize = 1;
1275 texDesc.Format = DXGI_FORMAT_R16G16B16A16_FLOAT;
1276 texDesc.SampleDesc.Count = 1;
1277 texDesc.SampleDesc.Quality = 0;
1278 texDesc.Usage = D3D11_USAGE_DEFAULT;
1279 texDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
1281 HRESULT hr = device->CreateTexture2D(&texDesc,
nullptr, &m_hdrTexture);
1283 SLEAK_ERROR(
"Failed to create HDR texture for tonemapping!");
1287 hr = device->CreateRenderTargetView(m_hdrTexture,
nullptr, &m_hdrRTV);
1288 if (FAILED(hr))
return false;
1290 hr = device->CreateShaderResourceView(m_hdrTexture,
nullptr, &m_hdrSRV);
1291 if (FAILED(hr))
return false;
1294 D3D11_SAMPLER_DESC sampDesc{};
1295 sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
1296 sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
1297 sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
1298 sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
1299 hr = device->CreateSamplerState(&sampDesc, &m_pointSampler);
1300 if (FAILED(hr))
return false;
1303 D3D11_BUFFER_DESC cbDesc{};
1304 cbDesc.ByteWidth =
sizeof(PostProcessGPUData);
1305 cbDesc.Usage = D3D11_USAGE_DYNAMIC;
1306 cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
1307 cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
1308 hr = device->CreateBuffer(&cbDesc,
nullptr, &m_postProcessCB);
1309 if (FAILED(hr))
return false;
1312 ID3DBlob* vsBlob =
nullptr;
1313 ID3DBlob* psBlob =
nullptr;
1314 ID3DBlob* errorBlob =
nullptr;
1317 std::string narrowPath =
"assets/shaders/tonemap.hlsl";
1318 std::wstring shaderPath(narrowPath.begin(), narrowPath.end());
1320 hr = D3DCompileFromFile(shaderPath.c_str(),
nullptr, D3D_COMPILE_STANDARD_FILE_INCLUDE,
1321 "VS_Main",
"vs_5_0", D3DCOMPILE_DEBUG, 0, &vsBlob, &errorBlob);
1325 (
const char*)errorBlob->GetBufferPointer());
1326 errorBlob->Release();
1331 hr = D3DCompileFromFile(shaderPath.c_str(),
nullptr, D3D_COMPILE_STANDARD_FILE_INCLUDE,
1332 "PS_Main",
"ps_5_0", D3DCOMPILE_DEBUG, 0, &psBlob, &errorBlob);
1336 (
const char*)errorBlob->GetBufferPointer());
1337 errorBlob->Release();
1343 hr = device->CreateVertexShader(vsBlob->GetBufferPointer(),
1344 vsBlob->GetBufferSize(),
nullptr, &m_tonemapVS);
1346 if (FAILED(hr)) { psBlob->Release();
return false; }
1348 hr = device->CreatePixelShader(psBlob->GetBufferPointer(),
1349 psBlob->GetBufferSize(),
nullptr, &m_tonemapPS);
1351 if (FAILED(hr))
return false;
1353 m_tonemapResourcesCreated =
true;
1354 SLEAK_INFO(
"Tonemapping post-process resources created successfully");
1358void DirectX11Renderer::CleanupTonemapResources() {
1359 if (m_tonemapVS) { m_tonemapVS->Release(); m_tonemapVS =
nullptr; }
1360 if (m_tonemapPS) { m_tonemapPS->Release(); m_tonemapPS =
nullptr; }
1361 if (m_postProcessCB) { m_postProcessCB->Release(); m_postProcessCB =
nullptr; }
1362 if (m_hdrSRV) { m_hdrSRV->Release(); m_hdrSRV =
nullptr; }
1363 if (m_hdrRTV) { m_hdrRTV->Release(); m_hdrRTV =
nullptr; }
1364 if (m_hdrTexture) { m_hdrTexture->Release(); m_hdrTexture =
nullptr; }
1365 if (m_pointSampler) { m_pointSampler->Release(); m_pointSampler =
nullptr; }
1366 m_tonemapResourcesCreated =
false;
1369void DirectX11Renderer::ExecuteTonemapPass() {
1370 if (!m_tonemapResourcesCreated || !m_tonemapVS || !m_tonemapPS)
1374 PostProcessGPUData ppData{};
1375 ppData.Exposure = m_exposure;
1376 ppData.Gamma = m_gamma;
1377 ppData.TonemapEnabled = m_tonemapEnabled ? 1 : 0;
1379 D3D11_MAPPED_SUBRESOURCE mapped{};
1380 HRESULT hr = deviceContext->Map(m_postProcessCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped);
1381 if (SUCCEEDED(hr)) {
1382 std::memcpy(mapped.pData, &ppData,
sizeof(ppData));
1383 deviceContext->Unmap(m_postProcessCB, 0);
1387 deviceContext->OMSetRenderTargets(1, &renderTargetView,
nullptr);
1390 deviceContext->PSSetShaderResources(0, 1, &m_hdrSRV);
1391 deviceContext->PSSetSamplers(0, 1, &m_pointSampler);
1392 deviceContext->PSSetConstantBuffers(0, 1, &m_postProcessCB);
1395 deviceContext->VSSetShader(m_tonemapVS,
nullptr, 0);
1396 deviceContext->PSSetShader(m_tonemapPS,
nullptr, 0);
1399 deviceContext->IASetInputLayout(
nullptr);
1400 deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
1401 deviceContext->Draw(3, 0);
1404 ID3D11ShaderResourceView* nullSRV =
nullptr;
1405 deviceContext->PSSetShaderResources(0, 1, &nullSRV);
Backend-facing rendering layer shared by the four graphics backends.
Root namespace for everything the engine exposes.