Refactor editor rendering contracts

This commit is contained in:
2026-04-28 02:57:49 +08:00
parent 3bc0cfcf08
commit b1ae6c462d
47 changed files with 798 additions and 377 deletions

View File

@@ -35,8 +35,12 @@ change.
contracts under `app/Core` and `app/Host/Interfaces`.
- `XCEditorCore` also does not consume the whole `editor/app` root privately.
Its implementation include paths enumerate concrete app module roots such as
`app/Composition`, `app/Features`, `app/Windowing`, `app/Rendering`,
`app/Scene`, `app/Services`, and `app/Support`.
`app/Composition`, `app/Features`, `app/Windowing`, `app/Scene`,
`app/Services`, and `app/Support`.
- Concrete `app/Rendering/**` implementation builds as the
`XCEditorCoreRendering` object library. `XCEditorCore` consumes those object
files, but it does not publish or privately widen its include surface back to
`app/Rendering`.
- `XCEditorCore` and `XCEditor` require
`XCENGINE_ENABLE_RENDERING_EDITOR_SUPPORT=ON`; the root build defaults that
support on when either the core library or app executable is enabled.
@@ -71,8 +75,9 @@ change.
state contracts, panel IDs, shared window type contracts, host window
geometry/metrics, frame transfer requests, the panel-facing service view,
the windowing-facing frame-services/shell-runtime contracts,
scene-viewport request contracts, workspace-panel runtime interface, and
utility-window runtime/descriptors.
scene-viewport request contracts, icon-service and viewport-runtime
contracts, workspace-panel runtime interface, and utility-window
runtime/descriptors.
- `app/Host/Interfaces/` contains neutral host-facing contracts used across
editor core and executable host code: editor window host interfaces,
render-runtime factories, UI texture hosts, viewport render hosts, host
@@ -86,7 +91,9 @@ change.
- `app/Windowing/` owns window instances, content controllers, lifecycle,
workspace synchronization, and utility-window creation.
- `app/Rendering/` owns built-in icons, viewport render targets, object
picking, scene viewport passes, and viewport render services.
picking, scene viewport passes, and viewport render services. It is the
concrete implementation side of Core-owned editor icon and viewport runtime
contracts.
- `app/Features/` contains user-facing panels and editor tools: Hierarchy,
Scene viewport, Inspector, Project, Console, Color Picker, and component UI.
- `app/Features/EditorWorkspacePanelRegistry.*` is the concrete workspace
@@ -115,6 +122,11 @@ change.
shared value contracts in `app/Core`. Do not add new public app contracts
under concrete `app/Windowing`, `app/Rendering`, `app/Host/Win32`,
`app/Host/D3D12`, or legacy `app/Platform` paths.
- `app/Composition/**` and `app/Features/**` may depend on
`app/Core/Assets/EditorIconService.h` and `app/Core/Viewport/**`, but they
must not include concrete `app/Rendering/**` headers such as
`Assets/BuiltInIcons.h`, `Viewport/ViewportHostService.h`, or
`Viewport/SceneViewportRenderService.h`.
- `app/Windowing/**` may depend on `app/Core/Windowing` contracts such as
`EditorFrameServices` and `EditorWorkspaceShellRuntime`, but it must not
include concrete `app/Composition/EditorContext.h` or
@@ -166,17 +178,20 @@ change.
`UIEditorWorkspaceController` every frame. A live controller writes mutations
through to the authoritative window workspace state; a copied controller is
only a preview.
- `EditorShellRuntime` owns per-window interactive runtime state: viewport host
service, built-in icons, the workspace panel runtime set, shell interaction
state/frame, splitter correction state, trace entries, draw composer,
interaction engine, hosted panel coordinator, and session coordinator.
- `EditorShellRuntime` owns per-window interactive runtime state: injected
editor icon and viewport-runtime services, the workspace panel runtime set,
shell interaction state/frame, splitter correction state, trace entries,
draw composer, interaction engine, hosted panel coordinator, and session
coordinator.
- `EditorWorkspaceShellRuntime` is the windowing-facing shell runtime contract.
`EditorShellRuntime` is the current concrete implementation, and
`Application` injects it through the content factory instead of letting
`app/Windowing/**` construct or name the concrete type directly.
- The workspace shell runtime factory passed into windowing is intentionally
zero-argument. `Application` composes the concrete workspace-panel runtime
set with `EditorShellRuntime`; `app/Windowing/**` must not accept or call
set, `CreateEditorIconService()`, and
`CreateEditorViewportRuntimeServices()` with `EditorShellRuntime`;
`app/Windowing/**` must not accept or call
`EditorWorkspacePanelRuntimeSetFactory`.
- `EditorWindowRuntimeController` owns the content controller, render runtime,
screenshot controller, title-bar logo texture, text measurer access, DPI
@@ -288,18 +303,27 @@ inside pure shell/widget code.
- Scene and Game are `ViewportShell` presentations. The Scene panel is the
active editor viewport implementation; Game is registered as a viewport panel
but is not equivalent to the runtime game view yet.
- `SceneViewportFeature` owns `SceneViewportController` and
`SceneViewportRenderService`.
- `ViewportHostService` is the per-window manager for viewport requests,
render-target allocation, retirement, fallback clearing, and dispatch to the
attached `ViewportRenderHost`.
- `SceneViewportRenderService` renders scene content through the engine
renderer and owns object-id picking state. Keep editor picking/render support
behind `XCENGINE_ENABLE_RENDERING_EDITOR_SUPPORT`.
- Core viewport contracts now live under `app/Core/Viewport/**`: shared
viewport frame/resource types, object-picking contracts, and the editor
scene/runtime service abstractions.
- `SceneViewportFeature` owns `SceneViewportController` and consumes the
injected `EditorSceneViewportRuntime` contract instead of constructing or
naming concrete rendering services.
- `ViewportHostService` is the concrete per-window implementation of
`EditorViewportRuntimeServices`. It manages viewport requests, render-target
allocation, retirement, fallback clearing, and dispatch to the attached
`ViewportRenderHost`.
- `SceneViewportRenderService` is the concrete `EditorSceneViewportRuntime`
implementation. It renders scene content through the engine renderer and
owns object-id picking state. Keep editor picking/render support behind
`XCENGINE_ENABLE_RENDERING_EDITOR_SUPPORT`.
- Core icon contracts now live under `app/Core/Assets/EditorIconService.h`.
`BuiltInIcons` is the concrete implementation, and scene/tool overlays must
resolve editor icons through that contract rather than probing
`editor/resources/Icons` directly.
- Scene viewport shader/resource paths are runtime data. Build them from the
startup/runtime repo root in `SceneViewportFeature`, pass them into
`SceneViewportRenderService`, and keep render passes free of compile-time
source-tree path discovery.
startup/runtime repo root inside the rendering runtime service and keep
render passes free of compile-time source-tree path discovery.
- D3D12 window rendering is behind the abstract
`Rendering::Host::EditorWindowRenderRuntime`; native startup surface data is
passed through the neutral
@@ -317,6 +341,10 @@ inside pure shell/widget code.
`EditorWorkspacePanel` adapter interface; do not include concrete feature
panel headers from `EditorShellRuntime`, `EditorShellHostedPanelCoordinator`,
`EditorShellDrawComposer`, or `EditorShellSessionCoordinator`.
- Add new icon/viewport cross-layer contracts under `app/Core/Assets` or
`app/Core/Viewport`. Keep concrete texture loading, render-target ownership,
viewport host wiring, and scene viewport rendering in `app/Rendering/**`,
then inject those implementations from `Application`.
- Add new workspace panels by updating the panel ID constants, panel registry,
default workspace model, shell presentation, workspace panel runtime adapter,
and command/menu entries together.
@@ -352,6 +380,10 @@ inside pure shell/widget code.
`app/Host/Interfaces`, `include`, and engine headers;
implementation files use explicit module roots instead of the app-wide
compatibility root.
- Concrete rendering stays behind the `XCEditorCoreRendering` object library.
`XCEditorCore` consumes the object files, while Composition/Features/Core
continue to see only `app/Core` contracts and never gain an `app/Rendering`
include root.
- App-facing unit tests follow the same rule. `editor_app_core_tests` uses
explicit module include roots and must not regain the whole `editor/app`
root to make stale tests compile.
@@ -362,6 +394,11 @@ inside pure shell/widget code.
- `XCEditor` is the thin executable host that wires `XCEditorCore` to concrete
Win32 and D3D12 implementations. Do not move concrete platform/render host
code into `XCEditorCore` without first introducing neutral host contracts.
- `Application` is also the composition root for concrete editor icon and
viewport runtime services. It wires `CreateEditorIconService()` and
`CreateEditorViewportRuntimeServices()` into
`CreateEditorWorkspaceShellRuntime(...)` so `app/Composition/**` and
`app/Features/**` do not take concrete `app/Rendering/**` dependencies.
- `app/Core/Windowing/EditorFrameServices.h` and
`app/Core/Windowing/EditorWorkspaceShellRuntime.h` are the current
composition-to-windowing contract boundary. `EditorContext` and
@@ -436,7 +473,11 @@ inside pure shell/widget code.
- `editor/app/Host/Win32/Windowing/EditorWindowMessageDispatcher.cpp`
- `editor/app/Host/Interfaces/EditorWindowRenderRuntime.h`
- `editor/app/Host/Interfaces/EditorWindowHostInterfaces.h`
- `editor/app/Core/Assets/EditorIconService.h`
- `editor/app/Core/Viewport/EditorViewportRuntimeServices.h`
- `editor/app/Core/Windowing/EditorWindowTransferRequests.h`
- `editor/app/Rendering/Assets/EditorIconServiceFactory.h`
- `editor/app/Rendering/Viewport/EditorViewportRuntimeServicesFactory.h`
- `editor/app/Rendering/Viewport/ViewportHostService.h`
- `tests/UI/Editor/unit/CMakeLists.txt`
- `tests/UI/Editor/smoke/CMakeLists.txt`
@@ -529,8 +570,18 @@ ownership rule.
`app/Host/Win32/Resources`, so `XCEditorCore` no longer consumes
`app/Bootstrap` or Win32 resource helpers to initialize built-in icons,
title-bar branding, or screenshot output roots.
- Scene viewport shader paths are now injected at runtime from
`SceneViewportFeature` into `SceneViewportRenderService` and its pass bundle.
- Concrete editor icons and scene viewport runtime services are now hidden
behind `Core/Assets/EditorIconService.h` and `Core/Viewport/**` contracts.
`Application` injects `CreateEditorIconService()` and
`CreateEditorViewportRuntimeServices()` into `EditorShellRuntime`, so
`app/Composition/**` and `app/Features/**` no longer include concrete
`app/Rendering/**` headers.
- `XCEditorCoreRendering` now builds `app/Rendering/**` as a dedicated object
library. That keeps concrete rendering implementation in the core product
build without reopening `app/Rendering` as an include root for
Composition/Features/Core.
- Scene viewport shader paths are now injected at runtime by the viewport
runtime service into `SceneViewportRenderService` and its pass bundle.
Grid/selection passes no longer infer source-tree shader paths through
`XCUIEDITOR_REPO_ROOT` or `__FILE__`.
- `Application` no longer resolves the editor repo root from a compile-time

View File

@@ -265,7 +265,9 @@ if(XCENGINE_BUILD_XCUI_EDITOR_CORE)
)
set(XCUI_EDITOR_APP_RENDERING_SOURCES
app/Rendering/Assets/EditorIconServiceFactory.cpp
app/Rendering/Assets/BuiltInIcons.cpp
app/Rendering/Viewport/EditorViewportRuntimeServicesFactory.cpp
app/Rendering/Viewport/Passes/SceneViewportGridPass.cpp
app/Rendering/Viewport/Passes/SceneViewportSelectionOutlinePass.cpp
app/Rendering/Viewport/Passes/SceneViewportSelectedHelpersPass.cpp
@@ -289,13 +291,35 @@ if(XCENGINE_BUILD_XCUI_EDITOR_CORE)
${XCUI_EDITOR_APP_COMMAND_SOURCES}
${XCUI_EDITOR_APP_COMPOSITION_SOURCES}
${XCUI_EDITOR_APP_FEATURE_SOURCES}
${XCUI_EDITOR_APP_RENDERING_SOURCES}
${XCUI_EDITOR_APP_SUPPORT_SOURCES}
)
add_library(XCEditorCoreRendering OBJECT
${XCUI_EDITOR_APP_RENDERING_SOURCES}
)
target_include_directories(XCEditorCoreRendering
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/app/Core
${CMAKE_CURRENT_SOURCE_DIR}/app/Host/Interfaces
${CMAKE_CURRENT_SOURCE_DIR}/app/Rendering
${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_SOURCE_DIR}/engine/include
${CMAKE_SOURCE_DIR}/engine/third_party/stb
)
xcui_editor_apply_common_target_settings(XCEditorCoreRendering PRIVATE)
target_link_libraries(XCEditorCoreRendering PRIVATE
XCEngine
XCUIEditor
XCEngineRenderingEditorSupport
)
set(XCUI_EDITOR_CORE_SOURCES
${XCUI_EDITOR_APP_WINDOWING_SOURCES}
${XCUI_EDITOR_APP_CORE_SOURCES}
$<TARGET_OBJECTS:XCEditorCoreRendering>
)
add_library(XCEditorCore STATIC
@@ -312,7 +336,6 @@ if(XCENGINE_BUILD_XCUI_EDITOR_CORE)
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/app/Composition
${CMAKE_CURRENT_SOURCE_DIR}/app/Features
${CMAKE_CURRENT_SOURCE_DIR}/app/Rendering
${CMAKE_CURRENT_SOURCE_DIR}/app/Scene
${CMAKE_CURRENT_SOURCE_DIR}/app/Services
${CMAKE_CURRENT_SOURCE_DIR}/app/Support

View File

@@ -6,7 +6,9 @@
#include "EditorUtilityWindowRegistry.h"
#include "EditorWorkspacePanelRegistry.h"
#include "EditorWindowManager.h"
#include "Assets/EditorIconServiceFactory.h"
#include "Diagnostics/Win32CrashTrace.h"
#include "Viewport/EditorViewportRuntimeServicesFactory.h"
#include "System/Win32SystemInteractionHost.h"
#include "Resources/Win32EditorResourceService.h"
#include "Windowing/EditorWindow.h"
@@ -153,7 +155,9 @@ bool Application::Initialize(HINSTANCE hInstance, int nCmdShow) {
std::make_unique<Host::D3D12EditorWindowRenderRuntimeFactory>();
App::EditorWorkspaceShellRuntimeFactory workspaceShellRuntimeFactory = []() {
return App::CreateEditorWorkspaceShellRuntime(
App::CreateEditorWorkspacePanelRuntimeSet());
App::CreateEditorWorkspacePanelRuntimeSet(),
App::CreateEditorIconService(),
App::CreateEditorViewportRuntimeServices());
};
m_windowManager = std::make_unique<App::EditorWindowManager>(
*m_editorContext,

View File

@@ -14,3 +14,13 @@ IDR_PNG_LOGO_ICON PNG "../resources/Icons/logo_icon.png"
IDR_PNG_PLAY_BUTTON_ICON PNG "../resources/Icons/play_button.png"
IDR_PNG_PAUSE_BUTTON_ICON PNG "../resources/Icons/pause_button.png"
IDR_PNG_STEP_BUTTON_ICON PNG "../resources/Icons/step_button.png"
IDR_PNG_VIEW_MOVE_TOOL_ICON PNG "../resources/Icons/view_move_tool.png"
IDR_PNG_VIEW_MOVE_TOOL_ACTIVE_ICON PNG "../resources/Icons/view_move_tool_on.png"
IDR_PNG_MOVE_TOOL_ICON PNG "../resources/Icons/move_tool.png"
IDR_PNG_MOVE_TOOL_ACTIVE_ICON PNG "../resources/Icons/move_tool_on.png"
IDR_PNG_ROTATE_TOOL_ICON PNG "../resources/Icons/rotate_tool.png"
IDR_PNG_ROTATE_TOOL_ACTIVE_ICON PNG "../resources/Icons/rotate_tool_on.png"
IDR_PNG_SCALE_TOOL_ICON PNG "../resources/Icons/scale_tool.png"
IDR_PNG_SCALE_TOOL_ACTIVE_ICON PNG "../resources/Icons/scale_tool_on.png"
IDR_PNG_TRANSFORM_TOOL_ICON PNG "../resources/Icons/transform_tool.png"
IDR_PNG_TRANSFORM_TOOL_ACTIVE_ICON PNG "../resources/Icons/transform_tool_on.png"

View File

@@ -14,3 +14,13 @@
#define IDR_PNG_PLAY_BUTTON_ICON 210
#define IDR_PNG_PAUSE_BUTTON_ICON 211
#define IDR_PNG_STEP_BUTTON_ICON 212
#define IDR_PNG_VIEW_MOVE_TOOL_ICON 213
#define IDR_PNG_VIEW_MOVE_TOOL_ACTIVE_ICON 214
#define IDR_PNG_MOVE_TOOL_ICON 215
#define IDR_PNG_MOVE_TOOL_ACTIVE_ICON 216
#define IDR_PNG_ROTATE_TOOL_ICON 217
#define IDR_PNG_ROTATE_TOOL_ACTIVE_ICON 218
#define IDR_PNG_SCALE_TOOL_ICON 219
#define IDR_PNG_SCALE_TOOL_ACTIVE_ICON 220
#define IDR_PNG_TRANSFORM_TOOL_ICON 221
#define IDR_PNG_TRANSFORM_TOOL_ACTIVE_ICON 222

View File

@@ -6,7 +6,7 @@
#include <utility>
#include "Panels/EditorPanelIds.h"
#include <XCEngine/Input/InputTypes.h>
#include "Assets/BuiltInIcons.h"
#include "Assets/EditorIconService.h"
namespace XCEngine::UI::Editor::App {

View File

@@ -1,7 +1,7 @@
#include "EditorShellDrawComposer.h"
#include "WorkspacePanels/EditorWorkspacePanelRuntime.h"
#include "Assets/BuiltInIcons.h"
#include "Assets/EditorIconService.h"
#include <XCEditor/Foundation/UIEditorTheme.h>
#include <XCEditor/Shell/UIEditorShellInteraction.h>
@@ -18,16 +18,16 @@ using ::XCEngine::UI::UIDrawList;
class BuiltInIconResolver final : public UIEditorShellIconResolver {
public:
explicit BuiltInIconResolver(const BuiltInIcons& icons)
: m_icons(icons) {}
explicit BuiltInIconResolver(const EditorIconService& iconService)
: m_iconService(iconService) {}
const ::XCEngine::UI::UITextureHandle* TryResolveIcon(
std::uint8_t iconKind) const override {
return &m_icons.Resolve(static_cast<BuiltInIconKind>(iconKind));
return &m_iconService.Resolve(static_cast<BuiltInIconKind>(iconKind));
}
private:
const BuiltInIcons& m_icons;
const EditorIconService& m_iconService;
};
UIEditorShellComposeModel BuildShellComposeModelFromFrame(
@@ -90,7 +90,7 @@ void EditorShellDrawComposer::Append(
const auto& palette = ResolveUIEditorShellInteractionPalette();
const UIEditorShellComposeModel shellComposeModel =
BuildShellComposeModelFromFrame(context.shellFrame);
const BuiltInIconResolver iconResolver(context.builtInIcons);
const BuiltInIconResolver iconResolver(context.iconService);
AppendDrawPacket(
drawData,

View File

@@ -11,13 +11,13 @@ struct UIEditorShellInteractionState;
namespace XCEngine::UI::Editor::App {
class BuiltInIcons;
class EditorIconService;
class EditorWorkspacePanelRuntimeSet;
struct EditorShellDrawComposerContext {
const UIEditorShellInteractionFrame& shellFrame;
const UIEditorShellInteractionState& shellInteractionState;
const BuiltInIcons& builtInIcons;
const EditorIconService& iconService;
const EditorWorkspacePanelRuntimeSet& workspacePanels;
};

View File

@@ -18,7 +18,7 @@ bool IsViewportPanel(std::string_view panelId) {
}
void ApplyViewportFrameToPresentation(
const ViewportFrame& viewportFrame,
const EditorViewportFrame& viewportFrame,
UIEditorWorkspacePanelPresentationModel& presentation) {
presentation.viewportShellModel.frame.texture = viewportFrame.texture;
presentation.viewportShellModel.frame.requestedSize = viewportFrame.requestedSize;
@@ -28,7 +28,7 @@ void ApplyViewportFrameToPresentation(
}
void ApplyViewportFrameToShellModel(
const ViewportFrame& viewportFrame,
const EditorViewportFrame& viewportFrame,
UIEditorViewportShellModel& shellModel) {
shellModel.frame.texture = viewportFrame.texture;
shellModel.frame.requestedSize = viewportFrame.requestedSize;
@@ -51,7 +51,7 @@ UIEditorWorkspacePanelPresentationModel* FindMutableWorkspacePresentation(
void ApplyViewportFramesToShellFrame(
UIEditorShellInteractionFrame& shellFrame,
ViewportHostService& viewportHostService) {
EditorViewportRuntimeServices& viewportRuntimeServices) {
auto applyToViewportFrames =
[&](std::vector<UIEditorWorkspaceViewportComposeFrame>& viewportFrames) {
for (UIEditorWorkspaceViewportComposeFrame& viewportComposeFrame : viewportFrames) {
@@ -59,8 +59,8 @@ void ApplyViewportFramesToShellFrame(
continue;
}
const ViewportFrame viewportFrame =
viewportHostService.RequestViewport(
const EditorViewportFrame viewportFrame =
viewportRuntimeServices.RequestViewport(
viewportComposeFrame.panelId,
viewportComposeFrame.viewportShellFrame.requestedViewportSize);
ApplyViewportFrameToShellModel(
@@ -128,7 +128,7 @@ void EditorShellInteractionEngine::Update(
const Widgets::UIEditorDockHostLayout preUpdateDockLayout =
context.shellFrame.workspaceInteractionFrame.dockHostFrame.layout;
context.viewportHostService.BeginFrame();
context.viewportRuntimeServices.BeginFrame();
const std::vector<UIInputEvent> shellEvents =
context.hostedContentCaptureActive
? FilterShellInputEventsForHostedContentCapture(context.inputEvents)
@@ -160,7 +160,7 @@ void EditorShellInteractionEngine::Update(
metrics);
}
ApplyViewportFramesToShellFrame(context.shellFrame, context.viewportHostService);
ApplyViewportFramesToShellFrame(context.shellFrame, context.viewportRuntimeServices);
}
} // namespace XCEngine::UI::Editor::App

View File

@@ -1,6 +1,6 @@
#pragma once
#include "Viewport/ViewportHostService.h"
#include "Viewport/EditorViewportRuntimeServices.h"
#include <XCEditor/Shell/UIEditorShellInteraction.h>
#include <XCEditor/Workspace/UIEditorWorkspaceController.h>
@@ -33,7 +33,7 @@ struct EditorShellInteractionEngineContext {
bool useDetachedTitleBarTabStrip = false;
float detachedTitleBarTabHeight = 0.0f;
float detachedWindowChromeHeight = 0.0f;
ViewportHostService& viewportHostService;
EditorViewportRuntimeServices& viewportRuntimeServices;
};
class EditorShellInteractionEngine final {

View File

@@ -4,40 +4,57 @@
#include <XCEditor/Shell/UIEditorShellCapturePolicy.h>
#include <XCEngine/Rendering/RenderContext.h>
#include <cassert>
#include <utility>
namespace XCEngine::UI::Editor::App {
EditorShellRuntime::EditorShellRuntime(EditorWorkspacePanelRuntimeSet workspacePanels)
: m_workspacePanels(std::move(workspacePanels)) {}
EditorShellRuntime::EditorShellRuntime(
EditorWorkspacePanelRuntimeSet workspacePanels,
std::unique_ptr<EditorIconService> iconService,
std::unique_ptr<EditorViewportRuntimeServices> viewportRuntimeServices)
: m_iconService(std::move(iconService))
, m_viewportRuntimeServices(std::move(viewportRuntimeServices))
, m_workspacePanels(std::move(workspacePanels)) {}
void EditorShellRuntime::Initialize(
const std::filesystem::path& repoRoot,
Rendering::Host::UiTextureHost& textureHost,
Host::EditorHostResourceService& resourceService,
UIEditorTextMeasurer& textMeasurer) {
m_textureHost = &textureHost;
m_builtInIcons.Initialize(textureHost, resourceService);
assert(m_iconService != nullptr);
assert(m_viewportRuntimeServices != nullptr);
if (m_iconService == nullptr || m_viewportRuntimeServices == nullptr) {
return;
}
m_iconService->Initialize(textureHost, resourceService);
m_viewportRuntimeServices->Initialize(repoRoot);
m_workspacePanels.Initialize(
EditorWorkspacePanelInitializationContext{
.repoRoot = repoRoot,
.textureHost = textureHost,
.textMeasurer = textMeasurer,
.builtInIcons = m_builtInIcons,
.viewportHostService = m_viewportHostService,
.iconService = *m_iconService,
.sceneViewportRuntime = &m_viewportRuntimeServices->GetSceneViewportRuntime(),
});
}
void EditorShellRuntime::AttachViewportWindowRenderer(Rendering::Host::ViewportRenderHost& renderer) {
m_viewportHostService.AttachWindowRenderer(renderer);
if (m_viewportRuntimeServices != nullptr) {
m_viewportRuntimeServices->AttachWindowRenderer(renderer);
}
}
void EditorShellRuntime::DetachViewportWindowRenderer() {
m_viewportHostService.DetachWindowRenderer();
if (m_viewportRuntimeServices != nullptr) {
m_viewportRuntimeServices->DetachWindowRenderer();
}
}
void EditorShellRuntime::SetViewportSurfacePresentationEnabled(bool enabled) {
m_viewportHostService.SetSurfacePresentationEnabled(enabled);
if (m_viewportRuntimeServices != nullptr) {
m_viewportRuntimeServices->SetSurfacePresentationEnabled(enabled);
}
}
void EditorShellRuntime::Shutdown() {
@@ -45,20 +62,14 @@ void EditorShellRuntime::Shutdown() {
m_shellInteractionState = {};
m_splitterDragCorrectionState = {};
m_traceEntries.clear();
if (m_textureHost != nullptr) {
m_workspacePanels.Shutdown(
EditorWorkspacePanelShutdownContext{
.textureHost = *m_textureHost,
.viewportHostService = m_viewportHostService,
});
m_workspacePanels = {};
m_builtInIcons.Shutdown();
m_textureHost = nullptr;
} else {
m_workspacePanels = {};
m_builtInIcons.Shutdown();
m_workspacePanels.Shutdown(EditorWorkspacePanelShutdownContext{});
m_workspacePanels = {};
if (m_iconService != nullptr) {
m_iconService->Shutdown();
}
if (m_viewportRuntimeServices != nullptr) {
m_viewportRuntimeServices->Shutdown();
}
m_viewportHostService.Shutdown();
}
void EditorShellRuntime::ResetInteractionState() {
@@ -82,7 +93,8 @@ const std::vector<WorkspaceTraceEntry>& EditorShellRuntime::GetTraceEntries() co
}
const std::string& EditorShellRuntime::GetBuiltInIconError() const {
return m_builtInIcons.GetLastError();
static const std::string kEmptyError = {};
return m_iconService != nullptr ? m_iconService->GetLastError() : kEmptyError;
}
void EditorShellRuntime::SetExternalDockHostDropPreview(
@@ -144,8 +156,13 @@ bool EditorShellRuntime::HasInteractiveCapture() const {
}
std::unique_ptr<EditorWorkspaceShellRuntime> CreateEditorWorkspaceShellRuntime(
EditorWorkspacePanelRuntimeSet workspacePanels) {
return std::make_unique<EditorShellRuntime>(std::move(workspacePanels));
EditorWorkspacePanelRuntimeSet workspacePanels,
std::unique_ptr<EditorIconService> iconService,
std::unique_ptr<EditorViewportRuntimeServices> viewportRuntimeServices) {
return std::make_unique<EditorShellRuntime>(
std::move(workspacePanels),
std::move(iconService),
std::move(viewportRuntimeServices));
}
} // namespace XCEngine::UI::Editor::App
@@ -154,15 +171,21 @@ namespace XCEngine::UI::Editor::App {
void EditorShellRuntime::RenderRequestedViewports(
const ::XCEngine::Rendering::RenderContext& renderContext) {
m_viewportHostService.RenderRequestedViewports(renderContext);
if (m_viewportRuntimeServices != nullptr) {
m_viewportRuntimeServices->RenderRequestedViewports(renderContext);
}
}
void EditorShellRuntime::Append(::XCEngine::UI::UIDrawData& drawData) const {
if (m_iconService == nullptr) {
return;
}
m_drawComposer.Append(
EditorShellDrawComposerContext{
.shellFrame = m_shellFrame,
.shellInteractionState = m_shellInteractionState,
.builtInIcons = m_builtInIcons,
.iconService = *m_iconService,
.workspacePanels = m_workspacePanels,
},
drawData);
@@ -182,6 +205,10 @@ void EditorShellRuntime::Update(
bool useDetachedTitleBarTabStrip,
float detachedTitleBarTabHeight,
float detachedWindowChromeHeight) {
if (m_viewportRuntimeServices == nullptr) {
return;
}
const auto buildDefinition = [&]() {
return m_sessionCoordinator.PrepareShellDefinition(
EditorShellSessionCoordinatorContext{
@@ -206,7 +233,7 @@ void EditorShellRuntime::Update(
.useDetachedTitleBarTabStrip = useDetachedTitleBarTabStrip,
.detachedTitleBarTabHeight = detachedTitleBarTabHeight,
.detachedWindowChromeHeight = detachedWindowChromeHeight,
.viewportHostService = m_viewportHostService,
.viewportRuntimeServices = *m_viewportRuntimeServices,
});
m_sessionCoordinator.FinalizeFrame(frameServices, workspaceController, m_shellFrame.result);

View File

@@ -4,10 +4,10 @@
#include "EditorShellHostedPanelCoordinator.h"
#include "EditorShellInteractionEngine.h"
#include "EditorShellSessionCoordinator.h"
#include "Assets/EditorIconService.h"
#include "Viewport/EditorViewportRuntimeServices.h"
#include "Windowing/EditorWorkspaceShellRuntime.h"
#include "WorkspacePanels/EditorWorkspacePanelRuntime.h"
#include "Assets/BuiltInIcons.h"
#include "Viewport/ViewportHostService.h"
#include <XCEditor/Shell/UIEditorShellInteraction.h>
#include <XCEditor/Docking/UIEditorDockHostTransfer.h>
@@ -45,8 +45,10 @@ namespace XCEngine::UI::Editor::App {
class EditorShellRuntime final : public EditorWorkspaceShellRuntime {
public:
EditorShellRuntime() = default;
explicit EditorShellRuntime(EditorWorkspacePanelRuntimeSet workspacePanels);
EditorShellRuntime(
EditorWorkspacePanelRuntimeSet workspacePanels,
std::unique_ptr<EditorIconService> iconService,
std::unique_ptr<EditorViewportRuntimeServices> viewportRuntimeServices);
void Initialize(
const std::filesystem::path& repoRoot,
@@ -95,9 +97,8 @@ public:
bool HasInteractiveCapture() const override;
private:
ViewportHostService m_viewportHostService = {};
BuiltInIcons m_builtInIcons = {};
Rendering::Host::UiTextureHost* m_textureHost = nullptr;
std::unique_ptr<EditorIconService> m_iconService = {};
std::unique_ptr<EditorViewportRuntimeServices> m_viewportRuntimeServices = {};
EditorWorkspacePanelRuntimeSet m_workspacePanels = {};
UIEditorShellInteractionState m_shellInteractionState = {};
UIEditorShellInteractionFrame m_shellFrame = {};
@@ -110,7 +111,9 @@ private:
};
std::unique_ptr<EditorWorkspaceShellRuntime> CreateEditorWorkspaceShellRuntime(
EditorWorkspacePanelRuntimeSet workspacePanels);
EditorWorkspacePanelRuntimeSet workspacePanels,
std::unique_ptr<EditorIconService> iconService,
std::unique_ptr<EditorViewportRuntimeServices> viewportRuntimeServices);
} // namespace XCEngine::UI::Editor::App

View File

@@ -0,0 +1,60 @@
#pragma once
#include "HostFwd.h"
#include <XCEngine/UI/Types.h>
#include <cstdint>
#include <filesystem>
#include <string>
namespace XCEngine::UI::Editor::Rendering::Host {
class UiTextureHost;
} // namespace XCEngine::UI::Editor::Rendering::Host
namespace XCEngine::UI::Editor::App {
enum class BuiltInIconKind : std::uint8_t {
Folder = 0,
GameObject,
Scene,
CameraGizmo,
DirectionalLightGizmo,
PointLightGizmo,
SpotLightGizmo,
PlayButton,
PauseButton,
StepButton,
ViewMoveTool,
ViewMoveToolActive,
MoveTool,
MoveToolActive,
RotateTool,
RotateToolActive,
ScaleTool,
ScaleToolActive,
TransformTool,
TransformToolActive
};
class EditorIconService {
public:
virtual ~EditorIconService() = default;
virtual void Initialize(
Rendering::Host::UiTextureHost& renderer,
Host::EditorHostResourceService& resourceService) = 0;
virtual void Shutdown() = 0;
virtual void BeginFrame() = 0;
[[nodiscard]] virtual const ::XCEngine::UI::UITextureHandle& Resolve(
BuiltInIconKind kind) const = 0;
[[nodiscard]] virtual const ::XCEngine::UI::UITextureHandle* ResolveAssetPreview(
const std::filesystem::path& assetPath,
const std::filesystem::path& projectRoot) = 0;
[[nodiscard]] virtual const std::string& GetLastError() const = 0;
};
} // namespace XCEngine::UI::Editor::App

View File

@@ -0,0 +1,41 @@
#pragma once
#include <XCEngine/Rendering/Picking/ObjectIdCodec.h>
#include <XCEngine/UI/Types.h>
#include <cstdint>
namespace XCEngine::UI::Editor::App {
enum class ViewportObjectIdPickStatus : std::uint8_t {
Unavailable = 0,
Success,
ReadbackFailed
};
struct ViewportObjectIdPickResult {
ViewportObjectIdPickStatus status = ViewportObjectIdPickStatus::Unavailable;
std::uint64_t frameSerial = 0u;
::XCEngine::Rendering::RenderObjectId renderObjectId =
::XCEngine::Rendering::kInvalidRenderObjectId;
std::uint64_t resolvedEntityId = 0u;
bool HasResolvedSample() const {
return status == ViewportObjectIdPickStatus::Success;
}
bool HasResolvedEntity() const {
return HasResolvedSample() && resolvedEntityId != 0u;
}
};
class IViewportObjectPickerService {
public:
virtual ~IViewportObjectPickerService() = default;
virtual ViewportObjectIdPickResult PickObject(
const ::XCEngine::UI::UISize& viewportSize,
const ::XCEngine::UI::UIPoint& viewportMousePosition) const = 0;
};
} // namespace XCEngine::UI::Editor::App

View File

@@ -0,0 +1,50 @@
#pragma once
#include "Scene/SceneViewportRenderRequest.h"
#include "Viewport/EditorViewportPicking.h"
#include "Viewport/EditorViewportTypes.h"
#include <filesystem>
#include <string_view>
namespace XCEngine::Rendering {
class RenderContext;
} // namespace XCEngine::Rendering
namespace XCEngine::UI::Editor::Rendering::Host {
class ViewportRenderHost;
} // namespace XCEngine::UI::Editor::Rendering::Host
namespace XCEngine::UI::Editor::App {
class EditorSceneViewportRuntime {
public:
virtual ~EditorSceneViewportRuntime() = default;
virtual void SetRenderRequest(SceneViewportRenderRequest request) = 0;
[[nodiscard]] virtual const IViewportObjectPickerService& GetObjectPicker() const = 0;
};
class EditorViewportRuntimeServices {
public:
virtual ~EditorViewportRuntimeServices() = default;
virtual void Initialize(const std::filesystem::path& repoRoot) = 0;
virtual void Shutdown() = 0;
virtual void AttachWindowRenderer(Rendering::Host::ViewportRenderHost& windowRenderer) = 0;
virtual void DetachWindowRenderer() = 0;
virtual void SetSurfacePresentationEnabled(bool enabled) = 0;
virtual void BeginFrame() = 0;
[[nodiscard]] virtual EditorViewportFrame RequestViewport(
std::string_view viewportId,
const ::XCEngine::UI::UISize& requestedSize) = 0;
virtual void RenderRequestedViewports(
const ::XCEngine::Rendering::RenderContext& renderContext) = 0;
[[nodiscard]] virtual EditorSceneViewportRuntime& GetSceneViewportRuntime() = 0;
};
} // namespace XCEngine::UI::Editor::App

View File

@@ -0,0 +1,24 @@
#pragma once
#include <XCEngine/UI/Types.h>
#include <string>
namespace XCEngine::UI::Editor::App {
struct EditorViewportResourceRequirements {
bool requiresDepthSampling = false;
bool requiresObjectIdSurface = false;
bool requiresSelectionMaskSurface = false;
};
struct EditorViewportFrame {
::XCEngine::UI::UITextureHandle texture = {};
::XCEngine::UI::UISize requestedSize = {};
::XCEngine::UI::UISize renderSize = {};
bool hasTexture = false;
bool wasRequested = false;
std::string statusText = {};
};
} // namespace XCEngine::UI::Editor::App

View File

@@ -1,8 +1,10 @@
#pragma once
#include "Assets/EditorIconService.h"
#include "Commands/EditorEditCommandRoute.h"
#include "State/EditorSession.h"
#include "Panels/EditorPanelServices.h"
#include "Viewport/EditorViewportRuntimeServices.h"
#include <XCEditor/Foundation/UIEditorTextMeasurement.h>
#include <XCEditor/Panels/UIEditorHostedPanelDispatch.h>
@@ -25,17 +27,8 @@ struct UIInputEvent;
} // namespace XCEngine::UI
namespace XCEngine::UI::Editor::Rendering::Host {
class UiTextureHost;
} // namespace XCEngine::UI::Editor::Rendering::Host
namespace XCEngine::UI::Editor::App {
class BuiltInIcons;
class ViewportHostService;
enum class EditorWorkspacePanelCursorKind : std::uint8_t {
Arrow = 0,
ResizeEW
@@ -54,16 +47,12 @@ struct EditorWorkspacePanelFrameEvent {
struct EditorWorkspacePanelInitializationContext {
const std::filesystem::path& repoRoot;
Rendering::Host::UiTextureHost& textureHost;
UIEditorTextMeasurer& textMeasurer;
BuiltInIcons& builtInIcons;
ViewportHostService& viewportHostService;
EditorIconService& iconService;
EditorSceneViewportRuntime* sceneViewportRuntime = nullptr;
};
struct EditorWorkspacePanelShutdownContext {
Rendering::Host::UiTextureHost& textureHost;
ViewportHostService& viewportHostService;
};
struct EditorWorkspacePanelShutdownContext {};
struct EditorWorkspacePanelUpdateContext {
EditorPanelServices& services;

View File

@@ -7,8 +7,6 @@
#include "Project/ProjectPanel.h"
#include "Scene/SceneEditCommandRoute.h"
#include "Scene/SceneViewportFeature.h"
#include "Assets/BuiltInIcons.h"
#include "Viewport/ViewportHostService.h"
#include <XCEditor/Panels/UIEditorHostedPanelDispatch.h>
@@ -219,7 +217,7 @@ public:
}
void Initialize(const EditorWorkspacePanelInitializationContext& context) override {
m_panel.SetBuiltInIcons(&context.builtInIcons);
m_panel.SetIconService(&context.iconService);
m_panel.SetTextMeasurer(&context.textMeasurer);
m_panel.Initialize();
}
@@ -330,7 +328,7 @@ public:
}
void Initialize(const EditorWorkspacePanelInitializationContext& context) override {
m_panel.SetBuiltInIcons(&context.builtInIcons);
m_panel.SetIconService(&context.iconService);
m_panel.SetTextMeasurer(&context.textMeasurer);
}
@@ -406,15 +404,16 @@ public:
}
void Initialize(const EditorWorkspacePanelInitializationContext& context) override {
m_feature.Initialize(
context.repoRoot,
context.textureHost,
&context.builtInIcons,
context.viewportHostService);
if (context.sceneViewportRuntime != nullptr) {
m_feature.Initialize(
&context.iconService,
*context.sceneViewportRuntime);
}
}
void Shutdown(const EditorWorkspacePanelShutdownContext& context) override {
m_feature.Shutdown(context.textureHost, context.viewportHostService);
(void)context;
m_feature.Shutdown();
m_commandRoute.BindSceneRuntime(nullptr);
}

View File

@@ -1,5 +1,5 @@
#include "HierarchyPanel.h"
#include "Assets/BuiltInIcons.h"
#include "Assets/EditorIconService.h"
#include <XCEditor/Foundation/UIEditorPanelInputFilter.h>
#include <XCEditor/Foundation/UIEditorTheme.h>
#include "EditorSceneRuntime.h"
@@ -15,13 +15,13 @@ using ::XCEngine::UI::UIColor;
inline constexpr float kDragThreshold = 4.0f;
inline constexpr UIColor kDragPreviewColor(0.92f, 0.92f, 0.92f, 0.42f);
::XCEngine::UI::UITextureHandle ResolveGameObjectIcon(const BuiltInIcons* icons);
::XCEngine::UI::UITextureHandle ResolveGameObjectIcon(const EditorIconService* icons);
} // namespace XCEngine::UI::Editor::App
namespace XCEngine::UI::Editor::App {
::XCEngine::UI::UITextureHandle ResolveGameObjectIcon(const BuiltInIcons* icons) {
::XCEngine::UI::UITextureHandle ResolveGameObjectIcon(const EditorIconService* icons) {
return icons != nullptr
? icons->Resolve(BuiltInIconKind::GameObject)
: ::XCEngine::UI::UITextureHandle {};
@@ -80,7 +80,7 @@ void HierarchyPanel::SetCommandFocusService(
m_commandFocusService = commandFocusService;
}
void HierarchyPanel::SetBuiltInIcons(const BuiltInIcons* icons) {
void HierarchyPanel::SetIconService(const EditorIconService* icons) {
m_icons = icons;
RebuildItems();
}

View File

@@ -20,8 +20,8 @@
namespace XCEngine::UI::Editor::App {
class BuiltInIcons;
class EditorCommandFocusService;
class EditorIconService;
class EditorSceneRuntime;
class HierarchyPanel final : public EditorEditCommandRoute {
@@ -44,7 +44,7 @@ public:
void Initialize();
void SetSceneRuntime(EditorSceneRuntime* sceneRuntime);
void SetCommandFocusService(EditorCommandFocusService* commandFocusService);
void SetBuiltInIcons(const BuiltInIcons* icons);
void SetIconService(const EditorIconService* icons);
void SetTextMeasurer(const ::XCEngine::UI::Editor::UIEditorTextMeasurer* textMeasurer);
void ResetInteractionState();
void Update(
@@ -90,7 +90,7 @@ private:
const std::vector<Widgets::UIEditorTreeViewItem>& GetPresentedTreeItems() const;
const ::XCEngine::UI::Widgets::UIExpansionModel& GetPresentedExpansionModel() const;
const BuiltInIcons* m_icons = nullptr;
const EditorIconService* m_icons = nullptr;
EditorCommandFocusService* m_commandFocusService = nullptr;
EditorSceneRuntime* m_sceneRuntime = nullptr;
HierarchyModel m_model = {};

View File

@@ -1,5 +1,5 @@
#include "ProjectPanel.h"
#include "Assets/BuiltInIcons.h"
#include "Assets/EditorIconService.h"
#include <XCEditor/Collections/UIEditorScrollView.h>
#include <XCEditor/Collections/UIEditorTreeView.h>
#include <XCEditor/Foundation/UIEditorTheme.h>
@@ -71,7 +71,7 @@ float MeasureTextWidth(
const UIEditorTextMeasurer* textMeasurer,
std::string_view text,
float fontSize);
::XCEngine::UI::UITextureHandle ResolveFolderIcon(const BuiltInIcons* icons);
::XCEngine::UI::UITextureHandle ResolveFolderIcon(const EditorIconService* icons);
float ClampNavigationWidth(float value, float totalWidth);
UIRect ComputeFittedTextureRect(
const UIRect& bounds,
@@ -129,7 +129,7 @@ float MeasureTextWidth(
return static_cast<float>(text.size()) * fontSize * 0.56f;
}
::XCEngine::UI::UITextureHandle ResolveFolderIcon(const BuiltInIcons* icons) {
::XCEngine::UI::UITextureHandle ResolveFolderIcon(const EditorIconService* icons) {
return icons != nullptr
? icons->Resolve(BuiltInIconKind::Folder)
: ::XCEngine::UI::UITextureHandle {};
@@ -425,7 +425,7 @@ void ProjectPanel::SetSystemInteractionHost(
m_systemInteractionHost = systemInteractionHost;
}
void ProjectPanel::SetBuiltInIcons(BuiltInIcons* icons) {
void ProjectPanel::SetIconService(EditorIconService* icons) {
m_icons = icons;
RebuildWindowTreeItems();
}

View File

@@ -29,8 +29,8 @@
namespace XCEngine::UI::Editor::App {
class BuiltInIcons;
class EditorCommandFocusService;
class EditorIconService;
} // namespace XCEngine::UI::Editor::App
@@ -86,7 +86,7 @@ public:
void SetProjectRuntime(EditorProjectRuntime* projectRuntime);
void SetCommandFocusService(EditorCommandFocusService* commandFocusService);
void SetSystemInteractionHost(System::SystemInteractionService* systemInteractionHost);
void SetBuiltInIcons(BuiltInIcons* icons);
void SetIconService(EditorIconService* icons);
void SetTextMeasurer(const ::XCEngine::UI::Editor::UIEditorTextMeasurer* textMeasurer);
void ResetInteractionState();
void Update(
@@ -254,7 +254,7 @@ private:
EditorProjectRuntime* m_projectRuntime = nullptr;
EditorCommandFocusService* m_commandFocusService = nullptr;
System::SystemInteractionService* m_systemInteractionHost = nullptr;
BuiltInIcons* m_icons = nullptr;
EditorIconService* m_icons = nullptr;
const ::XCEngine::UI::Editor::UIEditorTextMeasurer* m_textMeasurer = nullptr;
std::vector<Widgets::UIEditorTreeViewItem> m_windowTreeItems = {};
::XCEngine::UI::Widgets::UISelectionModel m_folderSelection = {};

View File

@@ -1,6 +1,6 @@
#include "Scene/SceneViewportController.h"
#include "Viewport/ViewportObjectPickerService.h"
#include "Viewport/EditorViewportPicking.h"
#include "EditorSceneRuntime.h"
#include "State/EditorCommandFocusService.h"
@@ -136,17 +136,15 @@ void ApplySceneViewportToggleButton(
} // namespace
void SceneViewportController::Initialize(
const std::filesystem::path& repoRoot,
Rendering::Host::UiTextureHost& renderer,
const BuiltInIcons* builtInIcons) {
m_toolOverlay.Initialize(repoRoot, renderer);
m_sceneOverlay.SetBuiltInIcons(builtInIcons);
void SceneViewportController::Initialize(const EditorIconService* iconService) {
m_toolOverlay.SetIconService(iconService);
m_sceneOverlay.SetIconService(iconService);
ResetInteractionState();
}
void SceneViewportController::Shutdown(Rendering::Host::UiTextureHost& renderer) {
m_toolOverlay.Shutdown(renderer);
void SceneViewportController::Shutdown() {
m_toolOverlay.SetIconService(nullptr);
m_sceneOverlay.SetIconService(nullptr);
ResetInteractionState();
}

View File

@@ -10,32 +10,18 @@
#include <XCEngine/UI/Types.h>
#include <chrono>
#include <filesystem>
namespace XCEngine::UI::Editor::App {
class EditorCommandFocusService;
class BuiltInIcons;
class EditorIconService;
class EditorSceneRuntime;
class IViewportObjectPickerService;
} // namespace XCEngine::UI::Editor::App
namespace XCEngine::UI::Editor::Rendering::Host {
class UiTextureHost;
} // namespace XCEngine::UI::Editor::Rendering::Host
namespace XCEngine::UI::Editor::App {
class SceneViewportController {
public:
void Initialize(
const std::filesystem::path& repoRoot,
Rendering::Host::UiTextureHost& renderer,
const BuiltInIcons* builtInIcons);
void Shutdown(Rendering::Host::UiTextureHost& renderer);
void Initialize(const EditorIconService* iconService);
void Shutdown();
void ResetInteractionState();
void SetCommandFocusService(EditorCommandFocusService* commandFocusService);

View File

@@ -1,33 +1,20 @@
#include "Scene/SceneViewportFeature.h"
#include "Panels/EditorPanelIds.h"
#include "UiTextureHost.h"
#include "Viewport/SceneViewportResourcePaths.h"
#include "Viewport/ViewportHostService.h"
#include "EditorSceneRuntime.h"
#include "State/EditorCommandFocusService.h"
namespace XCEngine::UI::Editor::App {
void SceneViewportFeature::Initialize(
const std::filesystem::path& repoRoot,
Rendering::Host::UiTextureHost& textureHost,
const BuiltInIcons* builtInIcons,
ViewportHostService& viewportHostService) {
m_renderService.Initialize(BuildSceneViewportShaderPaths(repoRoot));
viewportHostService.SetContentRenderer(
kScenePanelId,
&m_renderService,
SceneViewportRenderService::GetViewportResourceRequirements());
m_controller.Initialize(repoRoot, textureHost, builtInIcons);
const EditorIconService* iconService,
EditorSceneViewportRuntime& sceneViewportRuntime) {
m_sceneViewportRuntime = &sceneViewportRuntime;
m_controller.Initialize(iconService);
}
void SceneViewportFeature::Shutdown(
Rendering::Host::UiTextureHost& textureHost,
ViewportHostService& viewportHostService) {
viewportHostService.SetContentRenderer(kScenePanelId, nullptr, {});
m_controller.Shutdown(textureHost);
m_renderService.Shutdown();
void SceneViewportFeature::Shutdown() {
m_controller.Shutdown();
m_sceneViewportRuntime = nullptr;
}
void SceneViewportFeature::ResetInteractionState() {
@@ -40,17 +27,23 @@ void SceneViewportFeature::SetCommandFocusService(
}
void SceneViewportFeature::SyncRenderRequest(EditorSceneRuntime& sceneRuntime) {
m_renderService.SetRenderRequest(
sceneRuntime.BuildSceneViewportRenderRequest());
if (m_sceneViewportRuntime != nullptr) {
m_sceneViewportRuntime->SetRenderRequest(
sceneRuntime.BuildSceneViewportRenderRequest());
}
}
void SceneViewportFeature::Update(
EditorSceneRuntime& sceneRuntime,
const UIEditorWorkspaceComposeState& composeState,
const UIEditorWorkspaceComposeFrame& composeFrame) {
if (m_sceneViewportRuntime == nullptr) {
return;
}
m_controller.Update(
sceneRuntime,
m_renderService,
m_sceneViewportRuntime->GetObjectPicker(),
composeState,
composeFrame);
SyncRenderRequest(sceneRuntime);

View File

@@ -1,42 +1,24 @@
#pragma once
#include "Assets/EditorIconService.h"
#include "Scene/SceneViewportController.h"
#include "Viewport/SceneViewportRenderService.h"
#include "Viewport/EditorViewportRuntimeServices.h"
#include <XCEditor/Workspace/UIEditorWorkspaceCompose.h>
#include <XCEngine/UI/DrawData.h>
#include <filesystem>
namespace XCEngine::UI::Editor::App {
class EditorCommandFocusService;
class BuiltInIcons;
class EditorSceneRuntime;
} // namespace XCEngine::UI::Editor::App
namespace XCEngine::UI::Editor::Rendering::Host {
class UiTextureHost;
} // namespace XCEngine::UI::Editor::Rendering::Host
namespace XCEngine::UI::Editor::App {
class ViewportHostService;
class SceneViewportFeature {
public:
void Initialize(
const std::filesystem::path& repoRoot,
Rendering::Host::UiTextureHost& textureHost,
const BuiltInIcons* builtInIcons,
ViewportHostService& viewportHostService);
void Shutdown(
Rendering::Host::UiTextureHost& textureHost,
ViewportHostService& viewportHostService);
const EditorIconService* iconService,
EditorSceneViewportRuntime& sceneViewportRuntime);
void Shutdown();
void ResetInteractionState();
void SetCommandFocusService(EditorCommandFocusService* commandFocusService);
void SyncRenderRequest(EditorSceneRuntime& sceneRuntime);
@@ -47,7 +29,7 @@ public:
void Append(::XCEngine::UI::UIDrawList& drawList) const;
private:
SceneViewportRenderService m_renderService = {};
EditorSceneViewportRuntime* m_sceneViewportRuntime = nullptr;
SceneViewportController m_controller = {};
};

View File

@@ -1,7 +1,7 @@
#include "Scene/SceneViewportSceneOverlay.h"
#include "Scene/SceneViewportTransformGizmoSupport.h"
#include "Assets/BuiltInIcons.h"
#include "Assets/EditorIconService.h"
#include "EditorSceneRuntime.h"
#include <XCEngine/Components/CameraComponent.h>
@@ -68,14 +68,14 @@ SceneViewportGizmoSupport::SceneViewportOverlayData BuildOverlayData(
return overlay;
}
::XCEngine::UI::UITextureHandle ResolveCameraIcon(const BuiltInIcons* icons) {
::XCEngine::UI::UITextureHandle ResolveCameraIcon(const EditorIconService* icons) {
return icons != nullptr
? icons->Resolve(BuiltInIconKind::CameraGizmo)
: ::XCEngine::UI::UITextureHandle();
}
::XCEngine::UI::UITextureHandle ResolveLightIcon(
const BuiltInIcons* icons,
const EditorIconService* icons,
const LightComponent& light) {
if (icons == nullptr) {
return {};
@@ -95,7 +95,7 @@ SceneViewportGizmoSupport::SceneViewportOverlayData BuildOverlayData(
} // namespace
void SceneViewportSceneOverlay::SetBuiltInIcons(const BuiltInIcons* icons) {
void SceneViewportSceneOverlay::SetIconService(const EditorIconService* icons) {
m_icons = icons;
if (m_icons == nullptr) {
ResetFrame();

View File

@@ -7,8 +7,8 @@
namespace XCEngine::UI::Editor::App {
class BuiltInIcons;
class EditorSceneRuntime;
class EditorIconService;
class SceneViewportSceneOverlay {
public:
@@ -21,7 +21,7 @@ public:
}
};
void SetBuiltInIcons(const BuiltInIcons* icons);
void SetIconService(const EditorIconService* icons);
void ResetFrame();
void Refresh(
EditorSceneRuntime& sceneRuntime,
@@ -42,7 +42,7 @@ public:
};
private:
const BuiltInIcons* m_icons = nullptr;
const EditorIconService* m_icons = nullptr;
Frame m_frame = {};
};

View File

@@ -1,7 +1,5 @@
#include "Scene/SceneViewportToolOverlay.h"
#include "UiTextureHost.h"
#include <XCEditor/Widgets/UIEditorTextLayout.h>
#include <algorithm>
@@ -39,16 +37,16 @@ constexpr float kToggleMinWidth = 60.0f;
struct ToolButtonSpec {
SceneToolMode mode = SceneToolMode::View;
const char* label = "";
const char* inactiveFile = "";
const char* activeFile = "";
BuiltInIconKind inactiveIcon = BuiltInIconKind::ViewMoveTool;
BuiltInIconKind activeIcon = BuiltInIconKind::ViewMoveToolActive;
};
constexpr std::array<ToolButtonSpec, 5> kToolButtonSpecs = {{
{ SceneToolMode::View, "View", "view_move_tool.png", "view_move_tool_on.png" },
{ SceneToolMode::Translate, "Move", "move_tool.png", "move_tool_on.png" },
{ SceneToolMode::Rotate, "Rotate", "rotate_tool.png", "rotate_tool_on.png" },
{ SceneToolMode::Scale, "Scale", "scale_tool.png", "scale_tool_on.png" },
{ SceneToolMode::Transform, "Transform", "transform_tool.png", "transform_tool_on.png" }
{ SceneToolMode::View, "View", BuiltInIconKind::ViewMoveTool, BuiltInIconKind::ViewMoveToolActive },
{ SceneToolMode::Translate, "Move", BuiltInIconKind::MoveTool, BuiltInIconKind::MoveToolActive },
{ SceneToolMode::Rotate, "Rotate", BuiltInIconKind::RotateTool, BuiltInIconKind::RotateToolActive },
{ SceneToolMode::Scale, "Scale", BuiltInIconKind::ScaleTool, BuiltInIconKind::ScaleToolActive },
{ SceneToolMode::Transform, "Transform", BuiltInIconKind::TransformTool, BuiltInIconKind::TransformToolActive }
}};
bool ContainsPoint(const UIRect& rect, const UIPoint& point) {
@@ -198,47 +196,10 @@ UIRect BuildToggleButtonRect(
return kToggleIdle;
}
} // namespace
bool SceneViewportToolOverlay::Initialize(
const std::filesystem::path& repoRoot,
Rendering::Host::UiTextureHost& renderer) {
Shutdown(renderer);
const std::filesystem::path iconRoot =
(repoRoot / "editor" / "resources" / "Icons").lexically_normal();
bool loadedAnyTexture = false;
for (std::size_t index = 0; index < kToolButtonSpecs.size(); ++index) {
const ToolButtonSpec& path = kToolButtonSpecs[index];
ToolTextureSet& textureSet = m_toolTextures[index];
textureSet = {};
textureSet.mode = path.mode;
textureSet.label = path.label;
std::string error = {};
loadedAnyTexture =
renderer.LoadTextureFromFile(
iconRoot / path.inactiveFile,
textureSet.inactiveTexture,
error) || loadedAnyTexture;
error.clear();
loadedAnyTexture =
renderer.LoadTextureFromFile(
iconRoot / path.activeFile,
textureSet.activeTexture,
error) || loadedAnyTexture;
}
return loadedAnyTexture;
}
void SceneViewportToolOverlay::Shutdown(Rendering::Host::UiTextureHost& renderer) {
for (ToolTextureSet& textureSet : m_toolTextures) {
renderer.ReleaseTexture(textureSet.inactiveTexture);
renderer.ReleaseTexture(textureSet.activeTexture);
textureSet = {};
}
void SceneViewportToolOverlay::SetIconService(const EditorIconService* iconService) {
m_iconService = iconService;
ResetFrame();
}
@@ -305,7 +266,6 @@ void SceneViewportToolOverlay::BuildFrame(
for (std::size_t index = 0; index < m_frame.buttons.size(); ++index) {
const ToolButtonSpec& spec = kToolButtonSpecs[index];
const ToolTextureSet& textureSet = m_toolTextures[index];
SceneViewportToolOverlayButtonFrame& button = m_frame.buttons[index];
button = {};
button.mode = spec.mode;
@@ -314,9 +274,10 @@ void SceneViewportToolOverlay::BuildFrame(
button.active = spec.mode == activeMode;
button.hovered = index == hoveredIndex;
button.pressed = index == pressedIndex;
button.texture = spec.mode == activeMode
? textureSet.activeTexture
: textureSet.inactiveTexture;
if (m_iconService != nullptr) {
button.texture = m_iconService->Resolve(
spec.mode == activeMode ? spec.activeIcon : spec.inactiveIcon);
}
}
}

View File

@@ -1,7 +1,7 @@
#pragma once
#include "SceneToolState.h"
#include "HostFwd.h"
#include "Assets/EditorIconService.h"
#include <XCEngine/UI/DrawData.h>
#include <XCEngine/UI/Types.h>
@@ -9,7 +9,6 @@
#include <array>
#include <cstddef>
#include <cstdint>
#include <filesystem>
#include <string>
namespace XCEngine::UI::Editor::App {
@@ -57,10 +56,7 @@ struct SceneViewportToolOverlayFrame {
class SceneViewportToolOverlay {
public:
bool Initialize(
const std::filesystem::path& repoRoot,
Rendering::Host::UiTextureHost& renderer);
void Shutdown(Rendering::Host::UiTextureHost& renderer);
void SetIconService(const EditorIconService* iconService);
void ResetFrame();
void BuildFrame(
@@ -82,15 +78,8 @@ public:
const SceneViewportToolOverlayFrame& GetFrame() const;
private:
struct ToolTextureSet {
SceneToolMode mode = SceneToolMode::View;
const char* label = "";
::XCEngine::UI::UITextureHandle inactiveTexture = {};
::XCEngine::UI::UITextureHandle activeTexture = {};
};
std::array<ToolTextureSet, 5> m_toolTextures = {};
SceneViewportToolOverlayFrame m_frame = {};
const EditorIconService* m_iconService = nullptr;
};
void AppendSceneViewportToolOverlay(

View File

@@ -20,6 +20,16 @@ enum class EditorHostPngResourceKind : std::uint8_t {
PlayButtonIcon,
PauseButtonIcon,
StepButtonIcon,
ViewMoveToolIcon,
ViewMoveToolActiveIcon,
MoveToolIcon,
MoveToolActiveIcon,
RotateToolIcon,
RotateToolActiveIcon,
ScaleToolIcon,
ScaleToolActiveIcon,
TransformToolIcon,
TransformToolActiveIcon,
};
struct EditorHostResourceBytes {

View File

@@ -34,6 +34,26 @@ int ResolvePngResourceId(EditorHostPngResourceKind kind) {
return IDR_PNG_PAUSE_BUTTON_ICON;
case EditorHostPngResourceKind::StepButtonIcon:
return IDR_PNG_STEP_BUTTON_ICON;
case EditorHostPngResourceKind::ViewMoveToolIcon:
return IDR_PNG_VIEW_MOVE_TOOL_ICON;
case EditorHostPngResourceKind::ViewMoveToolActiveIcon:
return IDR_PNG_VIEW_MOVE_TOOL_ACTIVE_ICON;
case EditorHostPngResourceKind::MoveToolIcon:
return IDR_PNG_MOVE_TOOL_ICON;
case EditorHostPngResourceKind::MoveToolActiveIcon:
return IDR_PNG_MOVE_TOOL_ACTIVE_ICON;
case EditorHostPngResourceKind::RotateToolIcon:
return IDR_PNG_ROTATE_TOOL_ICON;
case EditorHostPngResourceKind::RotateToolActiveIcon:
return IDR_PNG_ROTATE_TOOL_ACTIVE_ICON;
case EditorHostPngResourceKind::ScaleToolIcon:
return IDR_PNG_SCALE_TOOL_ICON;
case EditorHostPngResourceKind::ScaleToolActiveIcon:
return IDR_PNG_SCALE_TOOL_ACTIVE_ICON;
case EditorHostPngResourceKind::TransformToolIcon:
return IDR_PNG_TRANSFORM_TOOL_ICON;
case EditorHostPngResourceKind::TransformToolActiveIcon:
return IDR_PNG_TRANSFORM_TOOL_ACTIVE_ICON;
default:
return 0;
}

View File

@@ -584,6 +584,76 @@ void BuiltInIcons::Initialize(
"step_button.png",
m_stepButtonIcon,
errorStream);
LoadEmbeddedIconTexture(
renderer,
resourceService,
Host::EditorHostPngResourceKind::ViewMoveToolIcon,
"view_move_tool.png",
m_viewMoveToolIcon,
errorStream);
LoadEmbeddedIconTexture(
renderer,
resourceService,
Host::EditorHostPngResourceKind::ViewMoveToolActiveIcon,
"view_move_tool_on.png",
m_viewMoveToolActiveIcon,
errorStream);
LoadEmbeddedIconTexture(
renderer,
resourceService,
Host::EditorHostPngResourceKind::MoveToolIcon,
"move_tool.png",
m_moveToolIcon,
errorStream);
LoadEmbeddedIconTexture(
renderer,
resourceService,
Host::EditorHostPngResourceKind::MoveToolActiveIcon,
"move_tool_on.png",
m_moveToolActiveIcon,
errorStream);
LoadEmbeddedIconTexture(
renderer,
resourceService,
Host::EditorHostPngResourceKind::RotateToolIcon,
"rotate_tool.png",
m_rotateToolIcon,
errorStream);
LoadEmbeddedIconTexture(
renderer,
resourceService,
Host::EditorHostPngResourceKind::RotateToolActiveIcon,
"rotate_tool_on.png",
m_rotateToolActiveIcon,
errorStream);
LoadEmbeddedIconTexture(
renderer,
resourceService,
Host::EditorHostPngResourceKind::ScaleToolIcon,
"scale_tool.png",
m_scaleToolIcon,
errorStream);
LoadEmbeddedIconTexture(
renderer,
resourceService,
Host::EditorHostPngResourceKind::ScaleToolActiveIcon,
"scale_tool_on.png",
m_scaleToolActiveIcon,
errorStream);
LoadEmbeddedIconTexture(
renderer,
resourceService,
Host::EditorHostPngResourceKind::TransformToolIcon,
"transform_tool.png",
m_transformToolIcon,
errorStream);
LoadEmbeddedIconTexture(
renderer,
resourceService,
Host::EditorHostPngResourceKind::TransformToolActiveIcon,
"transform_tool_on.png",
m_transformToolActiveIcon,
errorStream);
m_frameIndex = 0;
m_previewLoadsThisFrame = 0;
@@ -605,6 +675,16 @@ void BuiltInIcons::Shutdown() {
m_renderer->ReleaseTexture(m_playButtonIcon);
m_renderer->ReleaseTexture(m_pauseButtonIcon);
m_renderer->ReleaseTexture(m_stepButtonIcon);
m_renderer->ReleaseTexture(m_viewMoveToolIcon);
m_renderer->ReleaseTexture(m_viewMoveToolActiveIcon);
m_renderer->ReleaseTexture(m_moveToolIcon);
m_renderer->ReleaseTexture(m_moveToolActiveIcon);
m_renderer->ReleaseTexture(m_rotateToolIcon);
m_renderer->ReleaseTexture(m_rotateToolActiveIcon);
m_renderer->ReleaseTexture(m_scaleToolIcon);
m_renderer->ReleaseTexture(m_scaleToolActiveIcon);
m_renderer->ReleaseTexture(m_transformToolIcon);
m_renderer->ReleaseTexture(m_transformToolActiveIcon);
}
m_renderer = nullptr;
@@ -944,6 +1024,26 @@ const ::XCEngine::UI::UITextureHandle& BuiltInIcons::Resolve(
return m_pauseButtonIcon;
case BuiltInIconKind::StepButton:
return m_stepButtonIcon;
case BuiltInIconKind::ViewMoveTool:
return m_viewMoveToolIcon;
case BuiltInIconKind::ViewMoveToolActive:
return m_viewMoveToolActiveIcon;
case BuiltInIconKind::MoveTool:
return m_moveToolIcon;
case BuiltInIconKind::MoveToolActive:
return m_moveToolActiveIcon;
case BuiltInIconKind::RotateTool:
return m_rotateToolIcon;
case BuiltInIconKind::RotateToolActive:
return m_rotateToolActiveIcon;
case BuiltInIconKind::ScaleTool:
return m_scaleToolIcon;
case BuiltInIconKind::ScaleToolActive:
return m_scaleToolActiveIcon;
case BuiltInIconKind::TransformTool:
return m_transformToolIcon;
case BuiltInIconKind::TransformToolActive:
return m_transformToolActiveIcon;
default:
return m_folderIcon;
}

View File

@@ -1,8 +1,6 @@
#pragma once
#include "HostFwd.h"
#include <XCEngine/UI/Types.h>
#include "Assets/EditorIconService.h"
#include <condition_variable>
#include <cstdint>
@@ -17,32 +15,19 @@
namespace XCEngine::UI::Editor::App {
enum class BuiltInIconKind : std::uint8_t {
Folder = 0,
GameObject,
Scene,
CameraGizmo,
DirectionalLightGizmo,
PointLightGizmo,
SpotLightGizmo,
PlayButton,
PauseButton,
StepButton
};
class BuiltInIcons {
class BuiltInIcons final : public EditorIconService {
public:
void Initialize(
Rendering::Host::UiTextureHost& renderer,
Host::EditorHostResourceService& resourceService);
void Shutdown();
void BeginFrame();
Host::EditorHostResourceService& resourceService) override;
void Shutdown() override;
void BeginFrame() override;
const ::XCEngine::UI::UITextureHandle& Resolve(BuiltInIconKind kind) const;
const ::XCEngine::UI::UITextureHandle& Resolve(BuiltInIconKind kind) const override;
const ::XCEngine::UI::UITextureHandle* ResolveAssetPreview(
const std::filesystem::path& assetPath,
const std::filesystem::path& projectRoot);
const std::string& GetLastError() const;
const std::filesystem::path& projectRoot) override;
const std::string& GetLastError() const override;
struct LoadedTexturePixels {
std::vector<std::uint8_t> rgbaPixels = {};
@@ -121,6 +106,16 @@ private:
::XCEngine::UI::UITextureHandle m_playButtonIcon = {};
::XCEngine::UI::UITextureHandle m_pauseButtonIcon = {};
::XCEngine::UI::UITextureHandle m_stepButtonIcon = {};
::XCEngine::UI::UITextureHandle m_viewMoveToolIcon = {};
::XCEngine::UI::UITextureHandle m_viewMoveToolActiveIcon = {};
::XCEngine::UI::UITextureHandle m_moveToolIcon = {};
::XCEngine::UI::UITextureHandle m_moveToolActiveIcon = {};
::XCEngine::UI::UITextureHandle m_rotateToolIcon = {};
::XCEngine::UI::UITextureHandle m_rotateToolActiveIcon = {};
::XCEngine::UI::UITextureHandle m_scaleToolIcon = {};
::XCEngine::UI::UITextureHandle m_scaleToolActiveIcon = {};
::XCEngine::UI::UITextureHandle m_transformToolIcon = {};
::XCEngine::UI::UITextureHandle m_transformToolActiveIcon = {};
std::unordered_map<std::string, CachedAssetPreview> m_assetPreviews = {};
std::vector<std::thread> m_previewWorkers = {};
std::deque<PreviewDecodeJob> m_previewDecodeQueue = {};

View File

@@ -0,0 +1,11 @@
#include "Assets/EditorIconServiceFactory.h"
#include "Assets/BuiltInIcons.h"
namespace XCEngine::UI::Editor::App {
std::unique_ptr<EditorIconService> CreateEditorIconService() {
return std::make_unique<BuiltInIcons>();
}
} // namespace XCEngine::UI::Editor::App

View File

@@ -0,0 +1,11 @@
#pragma once
#include "Assets/EditorIconService.h"
#include <memory>
namespace XCEngine::UI::Editor::App {
std::unique_ptr<EditorIconService> CreateEditorIconService();
} // namespace XCEngine::UI::Editor::App

View File

@@ -0,0 +1,11 @@
#include "Viewport/EditorViewportRuntimeServicesFactory.h"
#include "Viewport/ViewportHostService.h"
namespace XCEngine::UI::Editor::App {
std::unique_ptr<EditorViewportRuntimeServices> CreateEditorViewportRuntimeServices() {
return std::make_unique<ViewportHostService>();
}
} // namespace XCEngine::UI::Editor::App

View File

@@ -0,0 +1,11 @@
#pragma once
#include "Viewport/EditorViewportRuntimeServices.h"
#include <memory>
namespace XCEngine::UI::Editor::App {
std::unique_ptr<EditorViewportRuntimeServices> CreateEditorViewportRuntimeServices();
} // namespace XCEngine::UI::Editor::App

View File

@@ -1,5 +1,7 @@
#include "Viewport/SceneViewportRenderService.h"
#include "Viewport/ViewportObjectIdPicker.h"
#include <XCEngine/Rendering/Picking/RenderObjectIdRegistry.h>
#include <XCEngine/Rendering/Execution/SceneRenderer.h>
#include <XCEngine/Scene/Scene.h>
@@ -41,9 +43,9 @@ SceneViewportRenderService::SceneViewportRenderService() = default;
SceneViewportRenderService::~SceneViewportRenderService() = default;
ViewportResourceRequirements
EditorViewportResourceRequirements
SceneViewportRenderService::GetViewportResourceRequirements() {
ViewportResourceRequirements requirements = {};
EditorViewportResourceRequirements requirements = {};
requirements.requiresDepthSampling = true;
requirements.requiresObjectIdSurface = true;
requirements.requiresSelectionMaskSurface = true;
@@ -79,6 +81,10 @@ void SceneViewportRenderService::SetRenderRequest(
m_renderRequest = std::move(request);
}
const IViewportObjectPickerService& SceneViewportRenderService::GetObjectPicker() const {
return *this;
}
ViewportRenderResult SceneViewportRenderService::Render(
ViewportRenderTargets& targets,
::XCEngine::RHI::RHIDevice& device,

View File

@@ -1,9 +1,8 @@
#pragma once
#include "Viewport/EditorViewportRuntimeServices.h"
#include "Viewport/ViewportContentRenderer.h"
#include "Viewport/ViewportObjectPickerService.h"
#include "Viewport/SceneViewportRenderPassBundle.h"
#include "Scene/SceneViewportRenderRequest.h"
#include <memory>
#include <string>
@@ -28,16 +27,18 @@ namespace XCEngine::UI::Editor::App {
class SceneViewportRenderService
: public IViewportContentRenderer
, public EditorSceneViewportRuntime
, public IViewportObjectPickerService {
public:
SceneViewportRenderService();
~SceneViewportRenderService();
static ViewportResourceRequirements GetViewportResourceRequirements();
static EditorViewportResourceRequirements GetViewportResourceRequirements();
void Initialize(const SceneViewportShaderPaths& shaderPaths);
void Shutdown();
void SetRenderRequest(SceneViewportRenderRequest request);
void SetRenderRequest(SceneViewportRenderRequest request) override;
const IViewportObjectPickerService& GetObjectPicker() const override;
ViewportRenderResult Render(
ViewportRenderTargets& targets,

View File

@@ -1,5 +1,7 @@
#include "ViewportHostService.h"
#include "Panels/EditorPanelIds.h"
#include "Viewport/SceneViewportResourcePaths.h"
#include "ViewportRenderHost.h"
#include <XCEngine/RHI/RHICommandList.h>
@@ -18,6 +20,14 @@ ViewportHostService::ViewportHostService() = default;
ViewportHostService::~ViewportHostService() = default;
void ViewportHostService::Initialize(const std::filesystem::path& repoRoot) {
m_sceneViewportRuntime.Initialize(BuildSceneViewportShaderPaths(repoRoot));
SetContentRenderer(
kScenePanelId,
&m_sceneViewportRuntime,
SceneViewportRenderService::GetViewportResourceRequirements());
}
void ViewportHostService::AttachWindowRenderer(
Rendering::Host::ViewportRenderHost& windowRenderer) {
if (m_windowRenderer == &windowRenderer) {
@@ -43,13 +53,15 @@ void ViewportHostService::SetSurfacePresentationEnabled(bool enabled) {
void ViewportHostService::SetContentRenderer(
std::string_view viewportId,
IViewportContentRenderer* renderer,
const ViewportResourceRequirements& requirements) {
const EditorViewportResourceRequirements& requirements) {
ViewportEntry& entry = GetOrCreateEntry(viewportId);
entry.renderer = renderer;
entry.requirements = requirements;
}
void ViewportHostService::Shutdown() {
SetContentRenderer(kScenePanelId, nullptr, {});
m_sceneViewportRuntime.Shutdown();
for (auto& [viewportId, entry] : m_entries) {
DestroyViewportEntry(entry);
}
@@ -155,7 +167,7 @@ void ViewportHostService::RetireViewportTargets(ViewportRenderTargets& targets)
std::swap(m_retiredTargetsBySlot[activeSlot].back(), targets);
}
ViewportFrame ViewportHostService::RequestViewport(
EditorViewportFrame ViewportHostService::RequestViewport(
std::string_view viewportId,
const ::XCEngine::UI::UISize& requestedSize) {
ViewportEntry& entry = GetOrCreateEntry(viewportId);
@@ -302,10 +314,10 @@ void ViewportHostService::ClearViewport(
entry.renderTargets.objectIdFrameSerial = 0u;
}
ViewportFrame ViewportHostService::BuildFrame(
EditorViewportFrame ViewportHostService::BuildFrame(
const ViewportEntry& entry,
const ::XCEngine::UI::UISize& requestedSize) const {
ViewportFrame frame = {};
EditorViewportFrame frame = {};
frame.requestedSize = requestedSize;
frame.renderSize = ::XCEngine::UI::UISize(
static_cast<float>(entry.renderTargets.width),
@@ -322,4 +334,8 @@ ViewportFrame ViewportHostService::BuildFrame(
return frame;
}
EditorSceneViewportRuntime& ViewportHostService::GetSceneViewportRuntime() {
return m_sceneViewportRuntime;
}
} // namespace XCEngine::UI::Editor::App

View File

@@ -1,6 +1,8 @@
#pragma once
#include "Viewport/EditorViewportRuntimeServices.h"
#include "HostFwd.h"
#include "Viewport/SceneViewportRenderService.h"
#include "Viewport/ViewportContentRenderer.h"
#include "ViewportRenderTargets.h"
@@ -15,33 +17,35 @@
namespace XCEngine::UI::Editor::App {
class ViewportHostService {
class ViewportHostService final : public EditorViewportRuntimeServices {
public:
ViewportHostService();
~ViewportHostService();
void AttachWindowRenderer(Rendering::Host::ViewportRenderHost& windowRenderer);
void DetachWindowRenderer();
void SetSurfacePresentationEnabled(bool enabled);
void Initialize(const std::filesystem::path& repoRoot) override;
void Shutdown() override;
void AttachWindowRenderer(Rendering::Host::ViewportRenderHost& windowRenderer) override;
void DetachWindowRenderer() override;
void SetSurfacePresentationEnabled(bool enabled) override;
void SetContentRenderer(
std::string_view viewportId,
IViewportContentRenderer* renderer,
const ViewportResourceRequirements& requirements = {});
const EditorViewportResourceRequirements& requirements = {});
void Shutdown();
void BeginFrame();
void BeginFrame() override;
ViewportFrame RequestViewport(
EditorViewportFrame RequestViewport(
std::string_view viewportId,
const ::XCEngine::UI::UISize& requestedSize);
const ::XCEngine::UI::UISize& requestedSize) override;
void RenderRequestedViewports(
const ::XCEngine::Rendering::RenderContext& renderContext);
const ::XCEngine::Rendering::RenderContext& renderContext) override;
EditorSceneViewportRuntime& GetSceneViewportRuntime() override;
private:
struct ViewportEntry {
IViewportContentRenderer* renderer = nullptr;
ViewportResourceRequirements requirements = {};
EditorViewportResourceRequirements requirements = {};
std::uint32_t requestedWidth = 0;
std::uint32_t requestedHeight = 0;
bool requestedThisFrame = false;
@@ -68,7 +72,7 @@ private:
float g,
float b,
float a);
ViewportFrame BuildFrame(
EditorViewportFrame BuildFrame(
const ViewportEntry& entry,
const ::XCEngine::UI::UISize& requestedSize) const;
@@ -78,6 +82,7 @@ private:
bool m_surfacePresentationEnabled = false;
std::unordered_map<std::string, ViewportEntry> m_entries = {};
std::vector<std::vector<ViewportRenderTargets>> m_retiredTargetsBySlot = {};
SceneViewportRenderService m_sceneViewportRuntime = {};
};
} // namespace XCEngine::UI::Editor::App

View File

@@ -1,10 +1,11 @@
#pragma once
#include "Viewport/EditorViewportPicking.h"
#include <XCEngine/RHI/RHICommandQueue.h>
#include <XCEngine/RHI/RHIEnums.h>
#include <XCEngine/RHI/RHITexture.h>
#include <XCEngine/Rendering/Picking/ObjectIdCodec.h>
#include <XCEngine/UI/Types.h>
#include <algorithm>
#include <array>
@@ -36,28 +37,6 @@ struct ViewportObjectIdReadbackRequest {
std::uint32_t pixelY = 0;
};
enum class ViewportObjectIdPickStatus : std::uint8_t {
Unavailable = 0,
Success,
ReadbackFailed
};
struct ViewportObjectIdPickResult {
ViewportObjectIdPickStatus status = ViewportObjectIdPickStatus::Unavailable;
std::uint64_t frameSerial = 0u;
::XCEngine::Rendering::RenderObjectId renderObjectId =
::XCEngine::Rendering::kInvalidRenderObjectId;
std::uint64_t resolvedEntityId = 0u;
bool HasResolvedSample() const {
return status == ViewportObjectIdPickStatus::Success;
}
bool HasResolvedEntity() const {
return HasResolvedSample() && resolvedEntityId != 0u;
}
};
inline bool CanPickViewportObjectId(const ViewportObjectIdPickContext& context) {
return context.commandQueue != nullptr &&
context.texture != nullptr &&

View File

@@ -1,16 +1,3 @@
#pragma once
#include "Viewport/ViewportObjectIdPicker.h"
namespace XCEngine::UI::Editor::App {
class IViewportObjectPickerService {
public:
virtual ~IViewportObjectPickerService() = default;
virtual ViewportObjectIdPickResult PickObject(
const ::XCEngine::UI::UISize& viewportSize,
const ::XCEngine::UI::UIPoint& viewportMousePosition) const = 0;
};
} // namespace XCEngine::UI::Editor::App
#include "Viewport/EditorViewportPicking.h"

View File

@@ -1,25 +1,11 @@
#pragma once
#include <XCEngine/UI/Types.h>
#include <string>
#include "Viewport/EditorViewportTypes.h"
namespace XCEngine::UI::Editor::App {
struct ViewportResourceRequirements {
bool requiresDepthSampling = false;
bool requiresObjectIdSurface = false;
bool requiresSelectionMaskSurface = false;
};
struct ViewportFrame {
::XCEngine::UI::UITextureHandle texture = {};
::XCEngine::UI::UISize requestedSize = {};
::XCEngine::UI::UISize renderSize = {};
bool hasTexture = false;
bool wasRequested = false;
std::string statusText = {};
};
using ViewportResourceRequirements = EditorViewportResourceRequirements;
using ViewportFrame = EditorViewportFrame;
} // namespace XCEngine::UI::Editor::App