refactor: extract viewport render flow helpers

This commit is contained in:
2026-04-01 21:37:15 +08:00
parent 1fbbf318de
commit 846666bb2c
4 changed files with 438 additions and 40 deletions

View File

@@ -6,6 +6,7 @@
#include "IViewportHostService.h"
#include "SceneViewportPicker.h"
#include "SceneViewportCameraController.h"
#include "ViewportHostRenderFlowUtils.h"
#include "ViewportHostRenderTargets.h"
#include "ViewportObjectIdPicker.h"
#include "UI/ImGuiBackendBridge.h"
@@ -70,12 +71,6 @@ std::unique_ptr<Rendering::RenderPass> MakeLambdaRenderPass(const char* name, Ca
LambdaRenderPass::ExecuteCallback(std::forward<Callback>(callback)));
}
inline void SetViewportStatusIfEmpty(std::string& statusText, const char* message) {
if (statusText.empty()) {
statusText = message;
}
}
Rendering::Passes::InfiniteGridPassData BuildInfiniteGridPassData(
const SceneViewportOverlayData& overlay) {
Rendering::Passes::InfiniteGridPassData data = {};
@@ -429,8 +424,26 @@ private:
return BuildViewportColorSurface(entry.renderTargets);
}
Rendering::RenderSurface BuildObjectIdSurface(const ViewportEntry& entry) const {
return BuildViewportObjectIdSurface(entry.renderTargets);
void ApplyViewportRenderFailure(
ViewportEntry& entry,
const Rendering::RenderContext& renderContext,
const ViewportRenderFallbackPolicy& policy) {
ApplyViewportFailureStatus(entry.statusText, policy);
if (policy.invalidateObjectIdFrame) {
InvalidateViewportObjectIdFrame(entry.renderTargets);
}
if (!policy.shouldClear) {
return;
}
ClearViewport(
entry,
renderContext,
policy.clearColor.r,
policy.clearColor.g,
policy.clearColor.b,
policy.clearColor.a);
}
void AddSceneColorToRenderTargetPass(
@@ -633,18 +646,22 @@ private:
Rendering::RenderSurface& surface) {
surface.SetClearColorOverride(Math::Color(0.27f, 0.27f, 0.27f, 1.0f));
if (!EnsureSceneViewCamera()) {
entry.statusText = "Scene view camera is unavailable";
ClearViewport(entry, renderContext, 0.18f, 0.07f, 0.07f, 1.0f);
entry.renderTargets.hasValidObjectIdFrame = false;
ApplyViewportRenderFailure(
entry,
renderContext,
BuildSceneViewportRenderFailurePolicy(
SceneViewportRenderFailure::MissingSceneViewCamera));
return false;
}
ApplySceneViewCameraController();
entry.statusText.clear();
if (scene == nullptr) {
entry.statusText = "No active scene";
ClearViewport(entry, renderContext, 0.07f, 0.08f, 0.10f, 1.0f);
entry.renderTargets.hasValidObjectIdFrame = false;
ApplyViewportRenderFailure(
entry,
renderContext,
BuildSceneViewportRenderFailurePolicy(
SceneViewportRenderFailure::NoActiveScene));
return false;
}
@@ -654,31 +671,29 @@ private:
std::vector<Rendering::CameraRenderRequest> requests =
m_sceneRenderer->BuildRenderRequests(*scene, m_sceneViewCamera.camera, renderContext, surface);
if (requests.empty()) {
SetViewportStatusIfEmpty(entry.statusText, "Scene renderer failed");
ClearViewport(entry, renderContext, 0.18f, 0.07f, 0.07f, 1.0f);
entry.renderTargets.hasValidObjectIdFrame = false;
ApplyViewportRenderFailure(
entry,
renderContext,
BuildSceneViewportRenderFailurePolicy(
SceneViewportRenderFailure::SceneRendererFailed));
return false;
}
if (sceneState.postPasses.GetPassCount() > 0) {
requests[0].postScenePasses = &sceneState.postPasses;
}
if (entry.renderTargets.objectIdView != nullptr) {
requests[0].objectId.surface = BuildObjectIdSurface(entry);
requests[0].objectId.surface.SetRenderArea(requests[0].surface.GetRenderArea());
}
ApplySceneViewportRenderRequestSetup(
entry.renderTargets,
&sceneState.postPasses,
requests[0]);
if (!m_sceneRenderer->Render(requests)) {
SetViewportStatusIfEmpty(entry.statusText, "Scene renderer failed");
ClearViewport(entry, renderContext, 0.18f, 0.07f, 0.07f, 1.0f);
entry.renderTargets.hasValidObjectIdFrame = false;
ApplyViewportRenderFailure(
entry,
renderContext,
BuildSceneViewportRenderFailurePolicy(
SceneViewportRenderFailure::SceneRendererFailed));
return false;
}
entry.renderTargets.colorState = RHI::ResourceStates::PixelShaderResource;
entry.renderTargets.objectIdState = RHI::ResourceStates::PixelShaderResource;
entry.renderTargets.hasValidObjectIdFrame = requests[0].objectId.IsRequested();
MarkSceneViewportRenderSuccess(entry.renderTargets, requests[0]);
return true;
}
@@ -688,26 +703,34 @@ private:
const Rendering::RenderContext& renderContext,
const Rendering::RenderSurface& surface) {
if (scene == nullptr) {
entry.statusText = "No active scene";
ClearViewport(entry, renderContext, 0.07f, 0.08f, 0.10f, 1.0f);
ApplyViewportRenderFailure(
entry,
renderContext,
BuildGameViewportRenderFailurePolicy(
GameViewportRenderFailure::NoActiveScene));
return false;
}
const auto cameras = scene->FindObjectsOfType<Components::CameraComponent>();
if (cameras.empty()) {
entry.statusText = "No camera in scene";
ClearViewport(entry, renderContext, 0.10f, 0.09f, 0.08f, 1.0f);
ApplyViewportRenderFailure(
entry,
renderContext,
BuildGameViewportRenderFailurePolicy(
GameViewportRenderFailure::NoCameraInScene));
return false;
}
if (!m_sceneRenderer->Render(*scene, nullptr, renderContext, surface)) {
entry.statusText = "Scene renderer failed";
ClearViewport(entry, renderContext, 0.18f, 0.07f, 0.07f, 1.0f);
entry.renderTargets.hasValidObjectIdFrame = false;
ApplyViewportRenderFailure(
entry,
renderContext,
BuildGameViewportRenderFailurePolicy(
GameViewportRenderFailure::SceneRendererFailed));
return false;
}
entry.renderTargets.colorState = RHI::ResourceStates::PixelShaderResource;
MarkGameViewportRenderSuccess(entry.renderTargets);
entry.statusText.clear();
return true;
}
@@ -718,7 +741,10 @@ private:
const Components::Scene* scene,
const Rendering::RenderContext& renderContext) {
if (entry.renderTargets.colorView == nullptr || entry.renderTargets.depthView == nullptr) {
entry.statusText = "Viewport render target is unavailable";
ApplyViewportFailureStatus(
entry.statusText,
BuildViewportRenderTargetUnavailablePolicy());
InvalidateViewportObjectIdFrame(entry.renderTargets);
return;
}