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

@@ -79,27 +79,27 @@ set(NEW_EDITOR_IMGUI_COMPAT_SOURCES
add_library(XCNewEditorImGuiCompat STATIC ${NEW_EDITOR_IMGUI_COMPAT_SOURCES})
add_executable(${PROJECT_NAME} WIN32 ${NEW_EDITOR_SOURCES})
target_include_directories(XCNewEditorImGuiCompat PRIVATE
set(NEW_EDITOR_COMMON_INCLUDE_DIRS
${CMAKE_CURRENT_SOURCE_DIR}/src
${XCENGINE_ROOT_DIR}/engine/include
${XCENGINE_ROOT_DIR}/editor/src
)
set(NEW_EDITOR_IMGUI_COMPAT_INCLUDE_DIRS
${NEW_EDITOR_COMMON_INCLUDE_DIRS}
${IMGUI_SOURCE_DIR}
${IMGUI_SOURCE_DIR}/backends
)
target_include_directories(${PROJECT_NAME} PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src
${XCENGINE_ROOT_DIR}/engine/include
${XCENGINE_ROOT_DIR}/editor/src
${IMGUI_SOURCE_DIR}
${IMGUI_SOURCE_DIR}/backends
)
target_include_directories(XCNewEditorImGuiCompat PRIVATE ${NEW_EDITOR_IMGUI_COMPAT_INCLUDE_DIRS})
target_include_directories(${PROJECT_NAME} PRIVATE ${NEW_EDITOR_COMMON_INCLUDE_DIRS})
file(TO_CMAKE_PATH "${XCENGINE_ROOT_DIR}" XCENGINE_ROOT_DIR_CMAKE)
target_compile_definitions(XCNewEditorImGuiCompat PRIVATE
UNICODE
_UNICODE
NOMINMAX
XCENGINE_NEW_EDITOR_REPO_ROOT="${XCENGINE_ROOT_DIR_CMAKE}"
)
target_compile_options(XCNewEditorImGuiCompat PRIVATE /utf-8)
@@ -107,6 +107,7 @@ target_compile_options(XCNewEditorImGuiCompat PRIVATE /utf-8)
target_compile_definitions(${PROJECT_NAME} PRIVATE
UNICODE
_UNICODE
NOMINMAX
XCENGINE_NEW_EDITOR_REPO_ROOT="${XCENGINE_ROOT_DIR_CMAKE}"
)
target_compile_options(${PROJECT_NAME} PRIVATE /utf-8)
@@ -123,7 +124,12 @@ if(MSVC)
COMPILE_PDB_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/new_editor/compile-pdb-compat/Debug"
COMPILE_PDB_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/new_editor/compile-pdb-compat/Release"
COMPILE_PDB_OUTPUT_DIRECTORY_MINSIZEREL "${CMAKE_BINARY_DIR}/new_editor/compile-pdb-compat/MinSizeRel"
COMPILE_PDB_OUTPUT_DIRECTORY_RELWITHDEBINFO "${CMAKE_BINARY_DIR}/new_editor/compile-pdb-compat/RelWithDebInfo")
COMPILE_PDB_OUTPUT_DIRECTORY_RELWITHDEBINFO "${CMAKE_BINARY_DIR}/new_editor/compile-pdb-compat/RelWithDebInfo"
PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/new_editor/pdb-compat"
PDB_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/new_editor/pdb-compat/Debug"
PDB_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/new_editor/pdb-compat/Release"
PDB_OUTPUT_DIRECTORY_MINSIZEREL "${CMAKE_BINARY_DIR}/new_editor/pdb-compat/MinSizeRel"
PDB_OUTPUT_DIRECTORY_RELWITHDEBINFO "${CMAKE_BINARY_DIR}/new_editor/pdb-compat/RelWithDebInfo")
target_link_options(${PROJECT_NAME} PRIVATE
$<$<CONFIG:Debug,RelWithDebInfo>:/INCREMENTAL:NO>)
set_property(TARGET ${PROJECT_NAME} PROPERTY

View File

@@ -1,5 +1,4 @@
#include "Application.h"
#include "XCUIBackend/LegacyImGuiHostInterop.h"
#include "XCUIBackend/NativeWindowUICompositor.h"
#include <XCEngine/Core/Asset/ResourceManager.h>
@@ -9,6 +8,10 @@
#include <cmath>
#include <sstream>
#ifdef DrawText
#undef DrawText
#endif
namespace XCEngine {
namespace NewEditor {
@@ -37,48 +40,6 @@ void ShutdownAndDelete(ResourceType*& resource) {
resource = nullptr;
}
const char* GetHostedPreviewPathLabel(bool nativeRequested, bool nativePresenterBound) {
if (nativeRequested && nativePresenterBound) {
return "native queued offscreen surface";
}
if (nativeRequested) {
return "native requested, hosted presenter bound";
}
if (nativePresenterBound) {
return "hosted presenter requested, native presenter still bound";
}
return "hosted presenter";
}
const char* GetHostedPreviewStateLabel(
bool hostedPreviewEnabled,
bool nativePresenterBound,
bool presentedThisFrame,
bool queuedToNativePassThisFrame,
bool surfaceImageAvailable,
bool surfaceAllocated,
bool surfaceReady,
bool descriptorAvailable) {
if (!hostedPreviewEnabled) {
return "disabled";
}
if (nativePresenterBound) {
if (surfaceImageAvailable && surfaceReady) {
return "live";
}
if (queuedToNativePassThisFrame || surfaceAllocated || descriptorAvailable) {
return "warming";
}
return "awaiting submit";
}
if (presentedThisFrame) {
return "live";
}
return "idle";
}
bool ContainsPoint(const UI::UIRect& rect, const UI::UIPoint& point) {
return point.x >= rect.x &&
point.y >= rect.y &&
@@ -174,42 +135,10 @@ NativeShellPanelLayout MakePanelLayout(
}
} // namespace
std::unique_ptr<::XCEngine::Editor::XCUIBackend::IXCUIHostedPreviewPresenter>
Application::CreateHostedPreviewPresenter(bool nativePreview) {
if (nativePreview) {
return ::XCEngine::Editor::XCUIBackend::CreateQueuedNativeXCUIHostedPreviewPresenter(
m_hostedPreviewQueue,
m_hostedPreviewSurfaceRegistry);
}
return ::XCEngine::Editor::XCUIBackend::CreateLegacyImGuiHostedPreviewPresenter();
}
bool Application::IsNativeWindowHostEnabled() const {
return m_windowHostMode == WindowHostMode::NativeXCUI;
}
void Application::InitializePanelsForActiveWindowHost() {
if (IsNativeWindowHostEnabled()) {
InitializeNativeShell();
return;
}
InitializeLegacyImGuiPanels();
ConfigureHostedPreviewPresenters();
}
void Application::InitializeLegacyImGuiPanels() {
m_demoPanel = std::make_unique<XCUIDemoPanel>(
&m_xcuiInputSource,
CreateHostedPreviewPresenter(IsNativeHostedPreviewEnabled(ShellPanelId::XCUIDemo)),
::XCEngine::Editor::XCUIBackend::CreateLegacyImGuiPanelCanvasHost());
m_layoutLabPanel = std::make_unique<XCUILayoutLabPanel>(
&m_xcuiInputSource,
CreateHostedPreviewPresenter(IsNativeHostedPreviewEnabled(ShellPanelId::XCUILayoutLab)),
::XCEngine::Editor::XCUIBackend::CreateLegacyImGuiPanelCanvasHost());
}
void Application::InitializeNativeShell() {
m_nativeActivePanel = m_shellChromeState.IsPanelVisible(ShellPanelId::XCUIDemo)
? ShellPanelId::XCUIDemo
@@ -238,115 +167,6 @@ bool Application::IsNativeHostedPreviewEnabled(ShellPanelId panelId) const {
return m_shellChromeState.IsNativeHostedPreviewActive(panelId);
}
void Application::ConfigureHostedPreviewPresenters() {
const ShellPanelChromeState* demoState = TryGetShellPanelState(ShellPanelId::XCUIDemo);
if (m_demoPanel != nullptr) {
m_demoPanel->SetVisible(demoState != nullptr && demoState->visible);
m_demoPanel->SetHostedPreviewEnabled(demoState == nullptr || demoState->hostedPreviewEnabled);
m_demoPanel->SetHostedPreviewPresenter(CreateHostedPreviewPresenter(IsNativeHostedPreviewEnabled(ShellPanelId::XCUIDemo)));
}
const ShellPanelChromeState* layoutLabState = TryGetShellPanelState(ShellPanelId::XCUILayoutLab);
if (m_layoutLabPanel != nullptr) {
m_layoutLabPanel->SetVisible(layoutLabState != nullptr && layoutLabState->visible);
m_layoutLabPanel->SetHostedPreviewEnabled(layoutLabState == nullptr || layoutLabState->hostedPreviewEnabled);
m_layoutLabPanel->SetHostedPreviewPresenter(
CreateHostedPreviewPresenter(IsNativeHostedPreviewEnabled(ShellPanelId::XCUILayoutLab)));
}
}
void Application::ConfigureShellCommandRouter() {
m_shellCommandRouter.Clear();
ShellCommandBindings bindings = {};
bindings.getXCUIDemoPanelVisible = [this]() {
return m_shellChromeState.IsPanelVisible(ShellPanelId::XCUIDemo);
};
bindings.setXCUIDemoPanelVisible = [this](bool visible) {
m_shellChromeState.SetPanelVisible(ShellPanelId::XCUIDemo, visible);
if (m_demoPanel != nullptr) {
m_demoPanel->SetVisible(visible);
}
};
bindings.getXCUILayoutLabPanelVisible = [this]() {
return m_shellChromeState.IsPanelVisible(ShellPanelId::XCUILayoutLab);
};
bindings.setXCUILayoutLabPanelVisible = [this](bool visible) {
m_shellChromeState.SetPanelVisible(ShellPanelId::XCUILayoutLab, visible);
if (m_layoutLabPanel != nullptr) {
m_layoutLabPanel->SetVisible(visible);
}
};
bindings.getImGuiDemoWindowVisible = [this]() {
return IsShellViewToggleEnabled(ShellViewToggleId::ImGuiDemoWindow);
};
bindings.setImGuiDemoWindowVisible = [this](bool visible) {
SetShellViewToggleEnabled(ShellViewToggleId::ImGuiDemoWindow, visible);
};
bindings.getNativeBackdropVisible = [this]() {
return IsShellViewToggleEnabled(ShellViewToggleId::NativeBackdrop);
};
bindings.setNativeBackdropVisible = [this](bool visible) {
SetShellViewToggleEnabled(ShellViewToggleId::NativeBackdrop, visible);
};
bindings.getPulseAccentEnabled = [this]() {
return IsShellViewToggleEnabled(ShellViewToggleId::PulseAccent);
};
bindings.setPulseAccentEnabled = [this](bool enabled) {
SetShellViewToggleEnabled(ShellViewToggleId::PulseAccent, enabled);
};
bindings.getNativeXCUIOverlayVisible = [this]() {
return IsShellViewToggleEnabled(ShellViewToggleId::NativeXCUIOverlay);
};
bindings.setNativeXCUIOverlayVisible = [this](bool visible) {
SetShellViewToggleEnabled(ShellViewToggleId::NativeXCUIOverlay, visible);
};
bindings.getHostedPreviewHudVisible = [this]() {
return IsShellViewToggleEnabled(ShellViewToggleId::HostedPreviewHud);
};
bindings.setHostedPreviewHudVisible = [this](bool visible) {
SetShellViewToggleEnabled(ShellViewToggleId::HostedPreviewHud, visible);
};
bindings.getNativeDemoPanelPreviewEnabled = [this]() {
return IsNativeHostedPreviewEnabled(ShellPanelId::XCUIDemo);
};
bindings.setNativeDemoPanelPreviewEnabled = [this](bool enabled) {
m_shellChromeState.SetHostedPreviewMode(
ShellPanelId::XCUIDemo,
enabled ? ShellHostedPreviewMode::NativeOffscreen : ShellHostedPreviewMode::HostedPresenter);
};
bindings.getNativeLayoutLabPreviewEnabled = [this]() {
return IsNativeHostedPreviewEnabled(ShellPanelId::XCUILayoutLab);
};
bindings.setNativeLayoutLabPreviewEnabled = [this](bool enabled) {
m_shellChromeState.SetHostedPreviewMode(
ShellPanelId::XCUILayoutLab,
enabled ? ShellHostedPreviewMode::NativeOffscreen : ShellHostedPreviewMode::HostedPresenter);
};
bindings.onHostedPreviewModeChanged = [this]() { ConfigureHostedPreviewPresenters(); };
Application::RegisterShellViewCommands(m_shellCommandRouter, bindings);
}
::XCEngine::Editor::XCUIBackend::XCUIInputBridgeFrameDelta
Application::DispatchShellShortcuts(
const ::XCEngine::Editor::XCUIBackend::XCUIInputBridgeFrameSnapshot& snapshot) {
::XCEngine::Editor::XCUIBackend::XCUIInputBridgeFrameSnapshot shellSnapshot = snapshot;
if (!IsNativeWindowHostEnabled()) {
::XCEngine::Editor::XCUIBackend::ApplyLegacyImGuiHostInputCapture(shellSnapshot);
}
if (!m_shellInputBridge.HasBaseline()) {
m_shellInputBridge.Prime(shellSnapshot);
}
const ::XCEngine::Editor::XCUIBackend::XCUIInputBridgeFrameDelta frameDelta =
m_shellInputBridge.Translate(shellSnapshot);
const ::XCEngine::Editor::XCUIBackend::XCUIEditorCommandInputSnapshot commandSnapshot =
Application::BuildShellShortcutSnapshot(frameDelta);
m_shellCommandRouter.InvokeMatchingShortcut({ &commandSnapshot });
return frameDelta;
}
Application::HostedPreviewPanelDiagnostics Application::BuildHostedPreviewPanelDiagnostics(
const char* debugName,
const char* fallbackDebugSource,
@@ -452,8 +272,7 @@ int Application::Run(HINSTANCE instance, int nCmdShow) {
Frame();
}
m_demoPanel.reset();
m_layoutLabPanel.reset();
ResetLegacyPanels();
ShutdownWindowCompositor();
ShutdownRenderer();
resourceManager.Shutdown();
@@ -558,18 +377,6 @@ bool Application::InitializeRenderer() {
return initialized;
}
void Application::InitializeWindowCompositor() {
m_windowCompositor = IsNativeWindowHostEnabled()
? ::XCEngine::Editor::XCUIBackend::CreateNativeWindowUICompositor()
: ::XCEngine::Editor::XCUIBackend::CreateLegacyImGuiWindowUICompositor();
if (m_windowCompositor != nullptr) {
m_windowCompositor->Initialize(
m_hwnd,
m_windowRenderer,
[]() { (void)::XCEngine::Editor::XCUIBackend::ConfigureLegacyImGuiHostFonts(); });
}
}
void Application::ShutdownWindowCompositor() {
DestroyHostedPreviewSurfaces();
if (m_windowCompositor != nullptr) {
@@ -599,15 +406,6 @@ void Application::DestroyHostedPreviewSurfaces() {
m_hostedPreviewSurfaces.clear();
}
void Application::SyncShellChromePanelStateFromPanels() {
m_shellChromeState.SetPanelVisible(
ShellPanelId::XCUIDemo,
m_demoPanel != nullptr && m_demoPanel->IsVisible());
m_shellChromeState.SetPanelVisible(
ShellPanelId::XCUILayoutLab,
m_layoutLabPanel != nullptr && m_layoutLabPanel->IsVisible());
}
void Application::SyncHostedPreviewSurfaces() {
const auto isNativePreviewEnabled = [this](const std::string& debugName) {
const ShellPanelChromeState* demoState = TryGetShellPanelState(ShellPanelId::XCUIDemo);

View File

@@ -3,12 +3,6 @@
#include <XCEngine/Input/InputTypes.h>
#include "XCUIBackend/XCUIEditorCommandRouter.h"
#include "panels/XCUIDemoPanel.h"
#include "panels/XCUILayoutLabPanel.h"
#include "Platform/D3D12WindowRenderer.h"
#include "Rendering/MainWindowNativeBackdropRenderer.h"
#include "XCUIBackend/IWindowUICompositor.h"
#include "XCUIBackend/NativeXCUIPanelCanvasHost.h"
#include "XCUIBackend/XCUIDemoRuntime.h"
#include "XCUIBackend/XCUIHostedPreviewPresenter.h"
@@ -17,6 +11,9 @@
#include "XCUIBackend/XCUIRHIRenderBackend.h"
#include "XCUIBackend/XCUIShellChromeState.h"
#include "XCUIBackend/XCUIStandaloneTextAtlasProvider.h"
#include "XCUIBackend/UITextureRegistration.h"
#include "Platform/D3D12WindowRenderer.h"
#include "Rendering/MainWindowNativeBackdropRenderer.h"
#include <chrono>
#include <cstdint>
@@ -29,10 +26,24 @@
#include <windows.h>
namespace XCEngine {
namespace Editor {
namespace XCUIBackend {
class IWindowUICompositor;
} // namespace XCUIBackend
} // namespace Editor
namespace NewEditor {
class XCUIDemoPanel;
class XCUILayoutLabPanel;
class Application {
public:
Application();
~Application();
using ShellChromeState = ::XCEngine::Editor::XCUIBackend::XCUIShellChromeState;
using ShellPanelId = ::XCEngine::Editor::XCUIBackend::XCUIShellPanelId;
using ShellViewToggleId = ::XCEngine::Editor::XCUIBackend::XCUIShellViewToggleId;
@@ -416,6 +427,7 @@ private:
HostedPreviewOffscreenSurface& previewSurface,
const ::XCEngine::Rendering::RenderContext& renderContext,
const ::XCEngine::UI::UIDrawData& drawData);
void ResetLegacyPanels();
void ConfigureShellCommandRouter();
::XCEngine::Editor::XCUIBackend::XCUIInputBridgeFrameDelta DispatchShellShortcuts(
const ::XCEngine::Editor::XCUIBackend::XCUIInputBridgeFrameSnapshot& snapshot);

View File

@@ -1,6 +1,8 @@
#include "Application.h"
#include "XCUIBackend/LegacyImGuiHostInterop.h"
#include "panels/XCUIDemoPanel.h"
#include "panels/XCUILayoutLabPanel.h"
#include <imgui.h>
@@ -65,6 +67,176 @@ const char* GetHostedPreviewStateLabel(
} // namespace
Application::Application() = default;
Application::~Application() = default;
std::unique_ptr<::XCEngine::Editor::XCUIBackend::IXCUIHostedPreviewPresenter>
Application::CreateHostedPreviewPresenter(bool nativePreview) {
if (nativePreview) {
return ::XCEngine::Editor::XCUIBackend::CreateQueuedNativeXCUIHostedPreviewPresenter(
m_hostedPreviewQueue,
m_hostedPreviewSurfaceRegistry);
}
return ::XCEngine::Editor::XCUIBackend::CreateLegacyImGuiHostedPreviewPresenter();
}
void Application::InitializePanelsForActiveWindowHost() {
if (IsNativeWindowHostEnabled()) {
InitializeNativeShell();
return;
}
InitializeLegacyImGuiPanels();
ConfigureHostedPreviewPresenters();
}
void Application::InitializeLegacyImGuiPanels() {
m_demoPanel = std::make_unique<XCUIDemoPanel>(
&m_xcuiInputSource,
CreateHostedPreviewPresenter(IsNativeHostedPreviewEnabled(ShellPanelId::XCUIDemo)),
::XCEngine::Editor::XCUIBackend::CreateLegacyImGuiPanelCanvasHost());
m_layoutLabPanel = std::make_unique<XCUILayoutLabPanel>(
&m_xcuiInputSource,
CreateHostedPreviewPresenter(IsNativeHostedPreviewEnabled(ShellPanelId::XCUILayoutLab)),
::XCEngine::Editor::XCUIBackend::CreateLegacyImGuiPanelCanvasHost());
}
void Application::ConfigureHostedPreviewPresenters() {
const ShellPanelChromeState* demoState = TryGetShellPanelState(ShellPanelId::XCUIDemo);
if (m_demoPanel != nullptr) {
m_demoPanel->SetVisible(demoState != nullptr && demoState->visible);
m_demoPanel->SetHostedPreviewEnabled(demoState == nullptr || demoState->hostedPreviewEnabled);
m_demoPanel->SetHostedPreviewPresenter(CreateHostedPreviewPresenter(IsNativeHostedPreviewEnabled(ShellPanelId::XCUIDemo)));
}
const ShellPanelChromeState* layoutLabState = TryGetShellPanelState(ShellPanelId::XCUILayoutLab);
if (m_layoutLabPanel != nullptr) {
m_layoutLabPanel->SetVisible(layoutLabState != nullptr && layoutLabState->visible);
m_layoutLabPanel->SetHostedPreviewEnabled(layoutLabState == nullptr || layoutLabState->hostedPreviewEnabled);
m_layoutLabPanel->SetHostedPreviewPresenter(
CreateHostedPreviewPresenter(IsNativeHostedPreviewEnabled(ShellPanelId::XCUILayoutLab)));
}
}
void Application::ResetLegacyPanels() {
m_demoPanel.reset();
m_layoutLabPanel.reset();
}
void Application::SyncShellChromePanelStateFromPanels() {
m_shellChromeState.SetPanelVisible(
ShellPanelId::XCUIDemo,
m_demoPanel != nullptr && m_demoPanel->IsVisible());
m_shellChromeState.SetPanelVisible(
ShellPanelId::XCUILayoutLab,
m_layoutLabPanel != nullptr && m_layoutLabPanel->IsVisible());
}
void Application::ConfigureShellCommandRouter() {
m_shellCommandRouter.Clear();
ShellCommandBindings bindings = {};
bindings.getXCUIDemoPanelVisible = [this]() {
return m_shellChromeState.IsPanelVisible(ShellPanelId::XCUIDemo);
};
bindings.setXCUIDemoPanelVisible = [this](bool visible) {
m_shellChromeState.SetPanelVisible(ShellPanelId::XCUIDemo, visible);
if (m_demoPanel != nullptr) {
m_demoPanel->SetVisible(visible);
}
};
bindings.getXCUILayoutLabPanelVisible = [this]() {
return m_shellChromeState.IsPanelVisible(ShellPanelId::XCUILayoutLab);
};
bindings.setXCUILayoutLabPanelVisible = [this](bool visible) {
m_shellChromeState.SetPanelVisible(ShellPanelId::XCUILayoutLab, visible);
if (m_layoutLabPanel != nullptr) {
m_layoutLabPanel->SetVisible(visible);
}
};
bindings.getImGuiDemoWindowVisible = [this]() {
return IsShellViewToggleEnabled(ShellViewToggleId::ImGuiDemoWindow);
};
bindings.setImGuiDemoWindowVisible = [this](bool visible) {
SetShellViewToggleEnabled(ShellViewToggleId::ImGuiDemoWindow, visible);
};
bindings.getNativeBackdropVisible = [this]() {
return IsShellViewToggleEnabled(ShellViewToggleId::NativeBackdrop);
};
bindings.setNativeBackdropVisible = [this](bool visible) {
SetShellViewToggleEnabled(ShellViewToggleId::NativeBackdrop, visible);
};
bindings.getPulseAccentEnabled = [this]() {
return IsShellViewToggleEnabled(ShellViewToggleId::PulseAccent);
};
bindings.setPulseAccentEnabled = [this](bool enabled) {
SetShellViewToggleEnabled(ShellViewToggleId::PulseAccent, enabled);
};
bindings.getNativeXCUIOverlayVisible = [this]() {
return IsShellViewToggleEnabled(ShellViewToggleId::NativeXCUIOverlay);
};
bindings.setNativeXCUIOverlayVisible = [this](bool visible) {
SetShellViewToggleEnabled(ShellViewToggleId::NativeXCUIOverlay, visible);
};
bindings.getHostedPreviewHudVisible = [this]() {
return IsShellViewToggleEnabled(ShellViewToggleId::HostedPreviewHud);
};
bindings.setHostedPreviewHudVisible = [this](bool visible) {
SetShellViewToggleEnabled(ShellViewToggleId::HostedPreviewHud, visible);
};
bindings.getNativeDemoPanelPreviewEnabled = [this]() {
return IsNativeHostedPreviewEnabled(ShellPanelId::XCUIDemo);
};
bindings.setNativeDemoPanelPreviewEnabled = [this](bool enabled) {
m_shellChromeState.SetHostedPreviewMode(
ShellPanelId::XCUIDemo,
enabled ? ShellHostedPreviewMode::NativeOffscreen : ShellHostedPreviewMode::HostedPresenter);
};
bindings.getNativeLayoutLabPreviewEnabled = [this]() {
return IsNativeHostedPreviewEnabled(ShellPanelId::XCUILayoutLab);
};
bindings.setNativeLayoutLabPreviewEnabled = [this](bool enabled) {
m_shellChromeState.SetHostedPreviewMode(
ShellPanelId::XCUILayoutLab,
enabled ? ShellHostedPreviewMode::NativeOffscreen : ShellHostedPreviewMode::HostedPresenter);
};
bindings.onHostedPreviewModeChanged = [this]() { ConfigureHostedPreviewPresenters(); };
Application::RegisterShellViewCommands(m_shellCommandRouter, bindings);
}
::XCEngine::Editor::XCUIBackend::XCUIInputBridgeFrameDelta
Application::DispatchShellShortcuts(
const ::XCEngine::Editor::XCUIBackend::XCUIInputBridgeFrameSnapshot& snapshot) {
::XCEngine::Editor::XCUIBackend::XCUIInputBridgeFrameSnapshot shellSnapshot = snapshot;
if (!IsNativeWindowHostEnabled()) {
::XCEngine::Editor::XCUIBackend::ApplyLegacyImGuiHostInputCapture(shellSnapshot);
}
if (!m_shellInputBridge.HasBaseline()) {
m_shellInputBridge.Prime(shellSnapshot);
}
const ::XCEngine::Editor::XCUIBackend::XCUIInputBridgeFrameDelta frameDelta =
m_shellInputBridge.Translate(shellSnapshot);
const ::XCEngine::Editor::XCUIBackend::XCUIEditorCommandInputSnapshot commandSnapshot =
Application::BuildShellShortcutSnapshot(frameDelta);
m_shellCommandRouter.InvokeMatchingShortcut({ &commandSnapshot });
return frameDelta;
}
void Application::InitializeWindowCompositor() {
m_windowCompositor = IsNativeWindowHostEnabled()
? ::XCEngine::Editor::XCUIBackend::CreateNativeWindowUICompositor()
: ::XCEngine::Editor::XCUIBackend::CreateLegacyImGuiWindowUICompositor();
if (m_windowCompositor != nullptr) {
m_windowCompositor->Initialize(
m_hwnd,
m_windowRenderer,
[]() { (void)::XCEngine::Editor::XCUIBackend::ConfigureLegacyImGuiHostFonts(); });
}
}
void Application::FrameLegacyImGuiHost() {
Application::BeginHostedPreviewFrameLifecycle(
m_hostedPreviewQueue,

View File

@@ -0,0 +1,7 @@
#pragma once
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include "../../../editor/src/Platform/D3D12WindowRenderer.h"

View File

@@ -0,0 +1,83 @@
#pragma once
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include "D3D12WindowRenderer.h"
#include "../UI/ImGuiBackendBridge.h"
#include <XCEngine/RHI/D3D12/D3D12CommandList.h>
#ifdef min
#undef min
#endif
#ifdef max
#undef max
#endif
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();
auto* d3d12CommandList = dynamic_cast<RHI::D3D12CommandList*>(renderContext.commandList);
if (!renderContext.IsValid() ||
d3d12CommandList == nullptr ||
renderContext.commandQueue == nullptr ||
windowRenderer.GetSwapChain() == nullptr ||
renderSurface == nullptr ||
windowRenderer.GetSrvHeap() == nullptr) {
return;
}
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);
if (beforeUiRender) {
beforeUiRender(renderContext, *renderSurface);
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

View File

@@ -1,23 +1,44 @@
#pragma once
#include "Platform/D3D12WindowRenderer.h"
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include "XCUIBackend/UITextureRegistration.h"
#include <XCEngine/Rendering/RenderContext.h>
#include <XCEngine/Rendering/RenderSurface.h>
#include <XCEngine/RHI/RHIDevice.h>
#include <XCEngine/RHI/RHITexture.h>
#include <functional>
#include <memory>
#include <windows.h>
#ifdef min
#undef min
#endif
#ifdef max
#undef max
#endif
namespace XCEngine {
namespace Editor {
namespace Platform {
class D3D12WindowRenderer;
} // namespace Platform
namespace XCUIBackend {
class IEditorHostCompositor {
public:
using ConfigureFontsCallback = std::function<void()>;
using RenderCallback = ::XCEngine::Editor::Platform::D3D12WindowRenderer::RenderCallback;
using RenderCallback =
std::function<void(const ::XCEngine::Rendering::RenderContext&, const ::XCEngine::Rendering::RenderSurface&)>;
virtual ~IEditorHostCompositor() = default;

View File

@@ -1,24 +1,45 @@
#pragma once
#include "Platform/D3D12WindowRenderer.h"
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include "XCUIBackend/UITextureRegistration.h"
#include <XCEngine/Rendering/RenderContext.h>
#include <XCEngine/Rendering/RenderSurface.h>
#include <XCEngine/RHI/RHIDevice.h>
#include <XCEngine/RHI/RHITexture.h>
#include <functional>
#include <memory>
#include <windows.h>
#ifdef min
#undef min
#endif
#ifdef max
#undef max
#endif
namespace XCEngine {
namespace Editor {
namespace Platform {
class D3D12WindowRenderer;
} // namespace Platform
namespace XCUIBackend {
class IWindowUICompositor {
public:
using ConfigureFontsCallback = std::function<void()>;
using UiRenderCallback = std::function<void()>;
using RenderCallback = ::XCEngine::Editor::Platform::D3D12WindowRenderer::RenderCallback;
using RenderCallback =
std::function<void(const ::XCEngine::Rendering::RenderContext&, const ::XCEngine::Rendering::RenderSurface&)>;
virtual ~IWindowUICompositor() = default;

View File

@@ -1,5 +1,6 @@
#include "XCUIBackend/IEditorHostCompositor.h"
#include "Platform/D3D12WindowRendererImGuiInterop.h"
#include "UI/ImGuiBackendBridge.h"
#include <imgui.h>
@@ -61,7 +62,12 @@ public:
const RenderCallback& beforeUiRender,
const RenderCallback& afterUiRender) override {
ImGui::Render();
windowRenderer.Render(m_backend, clearColor, beforeUiRender, afterUiRender);
::XCEngine::Editor::Platform::RenderImGuiFrame(
windowRenderer,
m_backend,
clearColor,
beforeUiRender,
afterUiRender);
}
bool CreateTextureDescriptor(

View File

@@ -1,5 +1,7 @@
#include "XCUIBackend/NativeWindowUICompositor.h"
#include "Platform/D3D12WindowRenderer.h"
#include <XCEngine/Rendering/RenderContext.h>
#include <XCEngine/Rendering/RenderSurface.h>
#include <XCEngine/RHI/RHICommandList.h>