#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(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