Refactor scene viewport render planning

This commit is contained in:
2026-04-03 14:17:50 +08:00
parent c04dbb07e0
commit 608e0bc9d8
4 changed files with 1004 additions and 31 deletions

View File

@@ -0,0 +1,96 @@
#pragma once
#include "Passes/SceneViewportEditorOverlayPass.h"
#include "SceneViewportEditorOverlayData.h"
#include "ViewportHostRenderFlowUtils.h"
#include <XCEngine/Core/Math/Color.h>
#include <XCEngine/Rendering/RenderPass.h>
#include <functional>
#include <memory>
#include <utility>
#include <vector>
namespace XCEngine {
namespace Editor {
struct SceneViewportRenderPlan {
Rendering::BuiltinPostProcessRequest builtinPostProcess = {};
Rendering::RenderPassSequence postScenePasses = {};
Rendering::RenderPassSequence overlayPasses = {};
bool hasClearColorOverride = true;
Math::Color clearColorOverride = Math::Color(0.27f, 0.27f, 0.27f, 1.0f);
bool HasPostScenePasses() const {
return postScenePasses.GetPassCount() > 0;
}
bool HasOverlayPasses() const {
return overlayPasses.GetPassCount() > 0;
}
};
using SceneViewportOverlayPassFactory =
std::function<std::unique_ptr<Rendering::RenderPass>(const SceneViewportOverlayFrameData&)>;
struct SceneViewportRenderPlanBuildResult {
SceneViewportRenderPlan plan = {};
const char* warningStatusText = nullptr;
};
inline SceneViewportRenderPlanBuildResult BuildSceneViewportRenderPlan(
const ViewportRenderTargets& targets,
const SceneViewportOverlayData& overlay,
const std::vector<uint64_t>& selectedObjectIds,
const SceneViewportOverlayFrameData& editorOverlayFrameData,
const SceneViewportOverlayFrameData& transientOverlayFrameData,
const SceneViewportOverlayPassFactory& overlayPassFactory,
bool debugSelectionMask = false) {
SceneViewportRenderPlanBuildResult result = {};
if (!overlay.valid) {
return result;
}
const SceneViewportBuiltinPostProcessBuildResult builtinPostProcess =
BuildSceneViewportBuiltinPostProcess(
overlay,
selectedObjectIds,
targets.objectIdShaderView != nullptr,
debugSelectionMask);
result.plan.builtinPostProcess = builtinPostProcess.request;
result.warningStatusText = builtinPostProcess.warningStatusText;
SceneViewportOverlayFrameData renderOverlayFrameData = editorOverlayFrameData;
AppendSceneViewportOverlayFrameData(renderOverlayFrameData, transientOverlayFrameData);
if (renderOverlayFrameData.HasOverlayPrimitives() &&
overlayPassFactory != nullptr) {
std::unique_ptr<Rendering::RenderPass> overlayPass = overlayPassFactory(renderOverlayFrameData);
if (overlayPass != nullptr) {
result.plan.overlayPasses.AddPass(std::move(overlayPass));
}
}
return result;
}
inline void ApplySceneViewportRenderPlan(
const ViewportRenderTargets& targets,
SceneViewportRenderPlan& plan,
Rendering::CameraRenderRequest& request) {
ApplySceneViewportRenderRequestSetup(
targets,
&plan.builtinPostProcess,
&plan.postScenePasses,
request);
if (plan.HasOverlayPasses()) {
request.overlayPasses = &plan.overlayPasses;
}
request.hasClearColorOverride = plan.hasClearColorOverride;
request.clearColorOverride = plan.clearColorOverride;
}
} // namespace Editor
} // namespace XCEngine

View File

@@ -9,6 +9,7 @@
#include "SceneViewportEditorOverlayData.h"
#include "SceneViewportOverlayHandleBuilder.h"
#include "SceneViewportOverlayBuilder.h"
#include "SceneViewportRenderPlan.h"
#include "ViewportHostRenderFlowUtils.h"
#include "ViewportHostRenderTargets.h"
#include "ViewportObjectIdPicker.h"
@@ -417,9 +418,7 @@ private:
struct SceneViewportRenderState {
SceneViewportOverlayData overlay = {};
Rendering::BuiltinPostProcessRequest builtinPostProcess = {};
SceneViewportOverlayFrameData editorOverlayFrameData = {};
std::vector<uint64_t> selectedObjectIds;
SceneViewportRenderPlan renderPlan = {};
};
ViewportEntry& GetEntry(EditorViewportKind kind) {
@@ -641,17 +640,25 @@ private:
return;
}
outState.selectedObjectIds = context.GetSelectionManager().GetSelectedEntities();
outState.editorOverlayFrameData = GetSceneViewEditorOverlayFrameData(context);
const SceneViewportBuiltinPostProcessBuildResult builtinPostProcess =
BuildSceneViewportBuiltinPostProcess(
const std::vector<uint64_t> selectedObjectIds = context.GetSelectionManager().GetSelectedEntities();
const SceneViewportOverlayFrameData& editorOverlayFrameData =
GetSceneViewEditorOverlayFrameData(context);
SceneViewportRenderPlanBuildResult renderPlan =
BuildSceneViewportRenderPlan(
entry.renderTargets,
outState.overlay,
outState.selectedObjectIds,
entry.renderTargets.objectIdShaderView != nullptr,
selectedObjectIds,
editorOverlayFrameData,
BuildSceneViewTransientTransformGizmoOverlayFrameData(),
[this](const SceneViewportOverlayFrameData& frameData) {
return CreateSceneViewportEditorOverlayPass(
m_sceneViewportEditorOverlayRenderer,
frameData);
},
kDebugSceneSelectionMask);
outState.builtinPostProcess = builtinPostProcess.request;
if (builtinPostProcess.warningStatusText != nullptr) {
SetViewportStatusIfEmpty(entry.statusText, builtinPostProcess.warningStatusText);
outState.renderPlan = std::move(renderPlan.plan);
if (renderPlan.warningStatusText != nullptr) {
SetViewportStatusIfEmpty(entry.statusText, renderPlan.warningStatusText);
}
}
@@ -695,25 +702,7 @@ private:
return false;
}
ApplySceneViewportRenderRequestSetup(
entry.renderTargets,
&sceneState.builtinPostProcess,
nullptr,
requests[0]);
SceneViewportOverlayFrameData renderOverlayFrameData = sceneState.editorOverlayFrameData;
AppendSceneViewportOverlayFrameData(
renderOverlayFrameData,
BuildSceneViewTransientTransformGizmoOverlayFrameData());
Rendering::RenderPassSequence overlayPassSequence = {};
if (renderOverlayFrameData.HasOverlayPrimitives()) {
overlayPassSequence.AddPass(
CreateSceneViewportEditorOverlayPass(
m_sceneViewportEditorOverlayRenderer,
renderOverlayFrameData));
requests[0].overlayPasses = &overlayPassSequence;
}
requests[0].hasClearColorOverride = true;
requests[0].clearColorOverride = Math::Color(0.27f, 0.27f, 0.27f, 1.0f);
ApplySceneViewportRenderPlan(entry.renderTargets, sceneState.renderPlan, requests[0]);
if (!m_sceneRenderer->Render(requests)) {
ApplyViewportRenderFailure(