Files
XCEngine/editor/src/Platform/D3D12WindowRendererImGuiInterop.h

83 lines
2.9 KiB
C++

#pragma once
#include "D3D12WindowRenderer.h"
#ifdef min
#undef min
#endif
#ifdef max
#undef max
#endif
#include "../UI/ImGuiBackendBridge.h"
namespace XCEngine {
namespace Editor {
namespace Platform {
inline void RenderImGuiFrame(
D3D12WindowRenderer& windowRenderer,
UI::ImGuiBackendBridge& imguiBackend,
const float clearColor[4],
const D3D12WindowRenderer::RenderCallback& beforeUiRender = {},
const D3D12WindowRenderer::RenderCallback& afterUiRender = {}) {
const Rendering::RenderSurface* renderSurface = windowRenderer.GetCurrentRenderSurface();
Rendering::RenderContext renderContext = windowRenderer.GetRenderContext();
if (!renderContext.IsValid() ||
renderContext.commandList == nullptr ||
renderContext.commandQueue == nullptr ||
windowRenderer.GetSwapChain() == nullptr ||
renderSurface == nullptr ||
windowRenderer.GetSrvHeap() == nullptr) {
return;
}
auto* d3d12CommandList = static_cast<RHI::D3D12CommandList*>(renderContext.commandList);
const auto& colorAttachments = renderSurface->GetColorAttachments();
if (colorAttachments.empty() || colorAttachments[0] == nullptr) {
return;
}
RHI::RHIResourceView* renderTargetView = colorAttachments[0];
renderContext.commandList->TransitionBarrier(
renderTargetView,
RHI::ResourceStates::Present,
RHI::ResourceStates::RenderTarget);
renderContext.commandList->SetRenderTargets(1, &renderTargetView, nullptr);
renderContext.commandList->ClearRenderTarget(renderTargetView, clearColor);
// Host-owned swapchain surfaces are handed to the callback already bound and ready for rendering.
// The callback must leave the color attachment in RenderTarget state so ImGui can render after it.
if (beforeUiRender) {
beforeUiRender(renderContext, *renderSurface);
// Viewport rendering can bind offscreen render targets on the shared command list.
// Rebind the swapchain backbuffer so the subsequent ImGui draw data lands on the main window.
renderContext.commandList->SetRenderTargets(1, &renderTargetView, nullptr);
}
ID3D12DescriptorHeap* descriptorHeaps[] = { windowRenderer.GetSrvHeap() };
d3d12CommandList->SetDescriptorHeaps(1, descriptorHeaps);
imguiBackend.RenderDrawData(d3d12CommandList->GetCommandList());
if (afterUiRender) {
renderContext.commandList->SetRenderTargets(1, &renderTargetView, nullptr);
afterUiRender(renderContext, *renderSurface);
}
renderContext.commandList->TransitionBarrier(
renderTargetView,
RHI::ResourceStates::RenderTarget,
RHI::ResourceStates::Present);
renderContext.commandList->Close();
void* commandLists[] = { renderContext.commandList };
renderContext.commandQueue->ExecuteCommandLists(1, commandLists);
windowRenderer.GetSwapChain()->Present(1, 0);
}
} // namespace Platform
} // namespace Editor
} // namespace XCEngine