2026-04-03 14:17:50 +08:00
|
|
|
#pragma once
|
|
|
|
|
|
2026-04-03 14:26:36 +08:00
|
|
|
#include "Passes/SceneViewportGridPass.h"
|
|
|
|
|
#include "Passes/SceneViewportSelectionOutlinePass.h"
|
2026-04-03 14:17:50 +08:00
|
|
|
#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::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&)>;
|
2026-04-03 14:26:36 +08:00
|
|
|
using SceneViewportGridPassFactory =
|
2026-04-04 16:29:06 +08:00
|
|
|
std::function<std::unique_ptr<Rendering::RenderPass>(const SceneViewportGridPassData&)>;
|
2026-04-03 14:26:36 +08:00
|
|
|
using SceneViewportSelectionOutlinePassFactory = std::function<std::unique_ptr<Rendering::RenderPass>(
|
2026-04-09 05:16:04 +08:00
|
|
|
ViewportRenderTargets*,
|
2026-04-03 14:26:36 +08:00
|
|
|
const std::vector<uint64_t>&,
|
2026-04-04 16:29:06 +08:00
|
|
|
const SceneViewportSelectionOutlineStyle&)>;
|
2026-04-03 14:17:50 +08:00
|
|
|
|
|
|
|
|
struct SceneViewportRenderPlanBuildResult {
|
|
|
|
|
SceneViewportRenderPlan plan = {};
|
|
|
|
|
const char* warningStatusText = nullptr;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
inline SceneViewportRenderPlanBuildResult BuildSceneViewportRenderPlan(
|
2026-04-09 05:16:04 +08:00
|
|
|
ViewportRenderTargets& targets,
|
2026-04-03 14:17:50 +08:00
|
|
|
const SceneViewportOverlayData& overlay,
|
|
|
|
|
const std::vector<uint64_t>& selectedObjectIds,
|
|
|
|
|
const SceneViewportOverlayFrameData& editorOverlayFrameData,
|
2026-04-03 14:26:36 +08:00
|
|
|
const SceneViewportGridPassFactory& gridPassFactory,
|
|
|
|
|
const SceneViewportSelectionOutlinePassFactory& selectionOutlinePassFactory,
|
2026-04-03 14:17:50 +08:00
|
|
|
const SceneViewportOverlayPassFactory& overlayPassFactory,
|
|
|
|
|
bool debugSelectionMask = false) {
|
|
|
|
|
SceneViewportRenderPlanBuildResult result = {};
|
|
|
|
|
if (!overlay.valid) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-04 16:29:06 +08:00
|
|
|
const SceneViewportGridPassData gridPassData = BuildSceneViewportGridPassData(overlay);
|
2026-04-03 14:26:36 +08:00
|
|
|
if (gridPassData.valid && gridPassFactory != nullptr) {
|
|
|
|
|
std::unique_ptr<Rendering::RenderPass> gridPass = gridPassFactory(gridPassData);
|
|
|
|
|
if (gridPass != nullptr) {
|
|
|
|
|
result.plan.postScenePasses.AddPass(std::move(gridPass));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!selectedObjectIds.empty()) {
|
2026-04-09 05:16:04 +08:00
|
|
|
if (targets.selectionMaskView != nullptr &&
|
|
|
|
|
targets.selectionMaskShaderView != nullptr &&
|
|
|
|
|
targets.depthView != nullptr &&
|
|
|
|
|
targets.depthShaderView != nullptr &&
|
2026-04-03 14:26:36 +08:00
|
|
|
selectionOutlinePassFactory != nullptr) {
|
|
|
|
|
std::unique_ptr<Rendering::RenderPass> selectionOutlinePass =
|
|
|
|
|
selectionOutlinePassFactory(
|
2026-04-09 05:16:04 +08:00
|
|
|
&targets,
|
2026-04-03 14:26:36 +08:00
|
|
|
selectedObjectIds,
|
|
|
|
|
BuildSceneViewportSelectionOutlineStyle(debugSelectionMask));
|
|
|
|
|
if (selectionOutlinePass != nullptr) {
|
|
|
|
|
result.plan.postScenePasses.AddPass(std::move(selectionOutlinePass));
|
|
|
|
|
}
|
|
|
|
|
} else if (!debugSelectionMask) {
|
2026-04-09 05:16:04 +08:00
|
|
|
result.warningStatusText = "Scene selection outline resources are unavailable";
|
2026-04-03 14:26:36 +08:00
|
|
|
}
|
|
|
|
|
}
|
2026-04-03 14:17:50 +08:00
|
|
|
|
2026-04-06 03:28:20 +08:00
|
|
|
if (editorOverlayFrameData.HasRenderPassPrimitives() &&
|
2026-04-03 14:17:50 +08:00
|
|
|
overlayPassFactory != nullptr) {
|
2026-04-03 16:50:46 +08:00
|
|
|
std::unique_ptr<Rendering::RenderPass> overlayPass = overlayPassFactory(editorOverlayFrameData);
|
2026-04-03 14:17:50 +08:00
|
|
|
if (overlayPass != nullptr) {
|
|
|
|
|
result.plan.overlayPasses.AddPass(std::move(overlayPass));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline void ApplySceneViewportRenderPlan(
|
|
|
|
|
const ViewportRenderTargets& targets,
|
|
|
|
|
SceneViewportRenderPlan& plan,
|
2026-04-14 00:40:11 +08:00
|
|
|
Rendering::CameraFramePlan& framePlan) {
|
2026-04-03 14:17:50 +08:00
|
|
|
ApplySceneViewportRenderRequestSetup(
|
|
|
|
|
targets,
|
|
|
|
|
&plan.postScenePasses,
|
2026-04-14 00:40:11 +08:00
|
|
|
framePlan);
|
2026-04-03 14:17:50 +08:00
|
|
|
|
|
|
|
|
if (plan.HasOverlayPasses()) {
|
2026-04-14 00:40:11 +08:00
|
|
|
framePlan.overlayPasses = &plan.overlayPasses;
|
2026-04-03 14:17:50 +08:00
|
|
|
}
|
|
|
|
|
|
2026-04-14 00:40:11 +08:00
|
|
|
framePlan.request.hasClearColorOverride = plan.hasClearColorOverride;
|
|
|
|
|
framePlan.request.clearColorOverride = plan.clearColorOverride;
|
2026-04-03 14:17:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace Editor
|
|
|
|
|
} // namespace XCEngine
|