Files
XCEngine/editor/src/Viewport/ViewportHostRenderFlowUtils.h

178 lines
5.4 KiB
C
Raw Normal View History

#pragma once
2026-04-02 15:03:31 +08:00
#include "IViewportHostService.h"
#include "SceneViewportPassSpecs.h"
#include "ViewportHostRenderTargets.h"
#include <XCEngine/Core/Math/Color.h>
#include <XCEngine/Rendering/CameraRenderRequest.h>
#include <string>
2026-04-02 15:03:31 +08:00
#include <vector>
namespace XCEngine {
namespace Editor {
struct ViewportRenderFallbackPolicy {
const char* statusText = nullptr;
Math::Color clearColor = Math::Color::Black();
bool shouldClear = false;
bool setStatusIfEmpty = false;
bool invalidateObjectIdFrame = true;
};
enum class SceneViewportRenderFailure {
MissingSceneViewCamera,
NoActiveScene,
SceneRendererFailed
};
enum class GameViewportRenderFailure {
NoActiveScene,
NoCameraInScene,
SceneRendererFailed
};
inline void SetViewportStatusIfEmpty(std::string& statusText, const char* message) {
if (statusText.empty()) {
statusText = message;
}
}
inline void ApplyViewportFailureStatus(
std::string& statusText,
const ViewportRenderFallbackPolicy& policy) {
if (policy.statusText == nullptr) {
return;
}
if (policy.setStatusIfEmpty) {
SetViewportStatusIfEmpty(statusText, policy.statusText);
return;
}
statusText = policy.statusText;
}
inline void InvalidateViewportObjectIdFrame(ViewportRenderTargets& targets) {
targets.hasValidObjectIdFrame = false;
}
inline ViewportRenderFallbackPolicy BuildViewportRenderTargetUnavailablePolicy() {
ViewportRenderFallbackPolicy policy = {};
policy.statusText = "Viewport render target is unavailable";
return policy;
}
inline ViewportRenderFallbackPolicy BuildSceneViewportRenderFailurePolicy(
SceneViewportRenderFailure failure) {
ViewportRenderFallbackPolicy policy = {};
policy.shouldClear = true;
switch (failure) {
case SceneViewportRenderFailure::MissingSceneViewCamera:
policy.statusText = "Scene view camera is unavailable";
policy.clearColor = Math::Color(0.18f, 0.07f, 0.07f, 1.0f);
break;
case SceneViewportRenderFailure::NoActiveScene:
policy.statusText = "No active scene";
policy.clearColor = Math::Color(0.07f, 0.08f, 0.10f, 1.0f);
break;
case SceneViewportRenderFailure::SceneRendererFailed:
policy.statusText = "Scene renderer failed";
policy.clearColor = Math::Color(0.18f, 0.07f, 0.07f, 1.0f);
policy.setStatusIfEmpty = true;
break;
default:
break;
}
return policy;
}
inline ViewportRenderFallbackPolicy BuildGameViewportRenderFailurePolicy(
GameViewportRenderFailure failure) {
ViewportRenderFallbackPolicy policy = {};
policy.shouldClear = true;
switch (failure) {
case GameViewportRenderFailure::NoActiveScene:
policy.statusText = "No active scene";
policy.clearColor = Math::Color(0.07f, 0.08f, 0.10f, 1.0f);
break;
case GameViewportRenderFailure::NoCameraInScene:
policy.statusText = "No camera in scene";
policy.clearColor = Math::Color(0.10f, 0.09f, 0.08f, 1.0f);
break;
case GameViewportRenderFailure::SceneRendererFailed:
policy.statusText = "Scene renderer failed";
policy.clearColor = Math::Color(0.18f, 0.07f, 0.07f, 1.0f);
break;
default:
break;
}
return policy;
}
inline SceneViewportGridPassData BuildSceneViewportGridPassData(
2026-04-02 15:03:31 +08:00
const SceneViewportOverlayData& overlay) {
SceneViewportGridPassData data = {};
2026-04-02 15:03:31 +08:00
data.valid = overlay.valid;
data.cameraPosition = overlay.cameraPosition;
data.cameraForward = overlay.cameraForward;
data.cameraRight = overlay.cameraRight;
data.cameraUp = overlay.cameraUp;
data.verticalFovDegrees = overlay.verticalFovDegrees;
data.nearClipPlane = overlay.nearClipPlane;
data.farClipPlane = overlay.farClipPlane;
data.orbitDistance = overlay.orbitDistance;
return data;
}
inline SceneViewportSelectionOutlineStyle BuildSceneViewportSelectionOutlineStyle(
bool debugSelectionMask = false) {
SceneViewportSelectionOutlineStyle style = {};
style.outlineColor = Math::Color(1.0f, 0.4f, 0.0f, 1.0f);
style.outlineWidthPixels = 2.0f;
style.debugSelectionMask = debugSelectionMask;
return style;
}
inline void ApplySceneViewportRenderRequestSetup(
const ViewportRenderTargets& targets,
Rendering::RenderPassSequence* postPasses,
Rendering::CameraRenderRequest& request) {
request.preScenePasses = nullptr;
request.postScenePasses = nullptr;
request.overlayPasses = nullptr;
request.objectId = {};
if (postPasses != nullptr && postPasses->GetPassCount() > 0) {
request.postScenePasses = postPasses;
}
if (targets.objectIdView == nullptr) {
return;
}
request.objectId.surface = BuildViewportObjectIdSurface(targets);
request.objectId.surface.SetRenderArea(request.surface.GetRenderArea());
}
inline void MarkSceneViewportRenderSuccess(
ViewportRenderTargets& targets,
const Rendering::CameraRenderRequest& request) {
targets.colorState = RHI::ResourceStates::PixelShaderResource;
targets.objectIdState = RHI::ResourceStates::PixelShaderResource;
targets.hasValidObjectIdFrame = request.objectId.IsRequested();
}
inline void MarkGameViewportRenderSuccess(ViewportRenderTargets& targets) {
targets.colorState = RHI::ResourceStates::PixelShaderResource;
targets.hasValidObjectIdFrame = false;
}
} // namespace Editor
} // namespace XCEngine