#include "Rendering/Execution/SceneRenderer.h" #include "Components/CameraComponent.h" #include "Rendering/Caches/FullscreenPassSurfaceCache.h" #include "Rendering/Planning/CameraFramePlanBuilder.h" #include "Rendering/Planning/SceneRenderRequestUtils.h" namespace XCEngine { namespace Rendering { namespace { bool CompareCameraFramePlans( const CameraFramePlan& lhs, const CameraFramePlan& rhs) { return SceneRenderRequestUtils::CompareCameraRenderRequests( lhs.request, rhs.request); } } // namespace SceneRenderer::SceneRenderer() : m_framePlanBuilder(std::make_unique()) { } SceneRenderer::SceneRenderer(std::unique_ptr pipeline) : m_cameraRenderer(std::move(pipeline)) , m_framePlanBuilder(std::make_unique()) { } SceneRenderer::SceneRenderer(std::shared_ptr pipelineAsset) : m_cameraRenderer(std::move(pipelineAsset)) , m_framePlanBuilder(std::make_unique()) { } SceneRenderer::~SceneRenderer() = default; void SceneRenderer::SetPipeline(std::unique_ptr pipeline) { m_cameraRenderer.SetPipeline(std::move(pipeline)); } void SceneRenderer::SetPipelineAsset(std::shared_ptr pipelineAsset) { m_cameraRenderer.SetPipelineAsset(std::move(pipelineAsset)); } std::vector SceneRenderer::BuildRenderRequests( const Components::Scene& scene, Components::CameraComponent* overrideCamera, const RenderContext& context, const RenderSurface& surface) { const std::vector plans = BuildFramePlans(scene, overrideCamera, context, surface); std::vector requests = {}; requests.reserve(plans.size()); for (const CameraFramePlan& plan : plans) { requests.push_back(BuildCompatibilityCameraRenderRequest(plan)); } return requests; } std::vector SceneRenderer::BuildFramePlans( const Components::Scene& scene, Components::CameraComponent* overrideCamera, const RenderContext& context, const RenderSurface& surface) { const std::vector requests = m_requestPlanner.BuildRequests(scene, overrideCamera, context, surface); return m_framePlanBuilder != nullptr ? m_framePlanBuilder->BuildPlans(requests, GetPipelineAsset()) : std::vector(); } bool SceneRenderer::Render(const CameraRenderRequest& request) { return Render(CameraFramePlan::FromRequest(request)); } bool SceneRenderer::Render(const std::vector& requests) { std::vector plans = CreateFramePlansFromLegacyRequests(requests); return Render(plans); } bool SceneRenderer::Render(const CameraFramePlan& plan) { return m_cameraRenderer.Render(plan); } bool SceneRenderer::Render(const std::vector& plans) { if (plans.empty()) { return false; } for (const CameraFramePlan& plan : plans) { if (!plan.IsValid()) { return false; } } std::vector sortedPlans = plans; std::stable_sort( sortedPlans.begin(), sortedPlans.end(), CompareCameraFramePlans); bool rendered = false; for (const CameraFramePlan& plan : sortedPlans) { if (!m_cameraRenderer.Render(plan)) { return false; } if (m_framePlanBuilder != nullptr) { m_framePlanBuilder->UpdateTrackedSurfaceState(&plan.GetMainSceneSurface()); } if (plan.postProcess.IsRequested()) { if (m_framePlanBuilder != nullptr) { m_framePlanBuilder->UpdateTrackedSurfaceState(&plan.postProcess.destinationSurface); } } rendered = true; } return rendered; } bool SceneRenderer::Render( const Components::Scene& scene, Components::CameraComponent* overrideCamera, const RenderContext& context, const RenderSurface& surface) { return Render(BuildFramePlans(scene, overrideCamera, context, surface)); } std::vector SceneRenderer::CreateFramePlansFromLegacyRequests( const std::vector& requests) const { std::vector plans = {}; plans.reserve(requests.size()); for (const CameraRenderRequest& request : requests) { plans.push_back(CameraFramePlan::FromRequest(request)); } return plans; } } // namespace Rendering } // namespace XCEngine