Isolate XCNewEditor default build from ImGui headers

This commit is contained in:
2026-04-05 16:11:08 +08:00
parent 18f53bd920
commit 9db0d82082
17 changed files with 546 additions and 308 deletions

View File

@@ -1,4 +1,5 @@
#include "Application.h"
#include "Platform/D3D12WindowRendererImGuiInterop.h"
#include "Core/EditorLoggingSetup.h"
#include "Core/ProjectRootResolver.h"
#include "Core/EditorWindowTitle.h"
@@ -264,7 +265,8 @@ void Application::RenderEditorFrame() {
m_layerStack.onUIRender();
UpdateWindowTitle();
ImGui::Render();
m_windowRenderer.Render(
Platform::RenderImGuiFrame(
m_windowRenderer,
m_imguiBackend,
kClearColor,
[this](const Rendering::RenderContext& renderContext, const Rendering::RenderSurface&) {

View File

@@ -1,7 +1,5 @@
#pragma once
#include "UI/ImGuiBackendBridge.h"
#include <XCEngine/Rendering/RenderContext.h>
#include <XCEngine/Rendering/RenderSurface.h>
#include <XCEngine/RHI/RHICommandList.h>
@@ -16,6 +14,10 @@
#include <XCEngine/RHI/D3D12/D3D12Device.h>
#include <XCEngine/RHI/D3D12/D3D12SwapChain.h>
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <d3d12.h>
#include <functional>
#include <vector>
@@ -179,66 +181,6 @@ public:
return true;
}
void Render(
UI::ImGuiBackendBridge& imguiBackend,
const float clearColor[4],
const RenderCallback& beforeUiRender = {},
const RenderCallback& afterUiRender = {}) {
auto* d3d12Queue = GetD3D12CommandQueue();
auto* d3d12CommandList = GetD3D12CommandList();
if (m_swapChain == nullptr ||
d3d12Queue == nullptr ||
d3d12CommandList == nullptr ||
m_srvHeap == nullptr) {
return;
}
const uint32_t backBufferIndex = m_swapChain->GetCurrentBackBufferIndex();
if (backBufferIndex >= m_backBufferViews.size() ||
backBufferIndex >= m_backBufferSurfaces.size() ||
m_backBufferViews[backBufferIndex] == nullptr) {
return;
}
RHI::RHIResourceView* renderTargetView = m_backBufferViews[backBufferIndex];
Rendering::RenderSurface& renderSurface = m_backBufferSurfaces[backBufferIndex];
d3d12CommandList->TransitionBarrier(
renderTargetView,
RHI::ResourceStates::Present,
RHI::ResourceStates::RenderTarget);
d3d12CommandList->SetRenderTargets(1, &renderTargetView, nullptr);
d3d12CommandList->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(GetRenderContext(), 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.
d3d12CommandList->SetRenderTargets(1, &renderTargetView, nullptr);
}
ID3D12DescriptorHeap* descriptorHeaps[] = { m_srvHeap->GetDescriptorHeap() };
d3d12CommandList->SetDescriptorHeaps(1, descriptorHeaps);
imguiBackend.RenderDrawData(d3d12CommandList->GetCommandList());
if (afterUiRender) {
d3d12CommandList->SetRenderTargets(1, &renderTargetView, nullptr);
afterUiRender(GetRenderContext(), renderSurface);
}
d3d12CommandList->TransitionBarrier(
renderTargetView,
RHI::ResourceStates::RenderTarget,
RHI::ResourceStates::Present);
m_commandList->Close();
void* commandLists[] = { m_commandList };
m_commandQueue->ExecuteCommandLists(1, commandLists);
m_swapChain->Present(1, 0);
}
ID3D12Device* GetDevice() const {
const auto* device = GetD3D12Device();
return device ? device->GetDevice() : nullptr;

View File

@@ -0,0 +1,82 @@
#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