Files
XCEngine/engine/src/Rendering/Execution/SceneRenderer.cpp

146 lines
4.5 KiB
C++

#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<CameraFramePlanBuilder>()) {
}
SceneRenderer::SceneRenderer(std::unique_ptr<RenderPipeline> pipeline)
: m_cameraRenderer(std::move(pipeline))
, m_framePlanBuilder(std::make_unique<CameraFramePlanBuilder>()) {
}
SceneRenderer::SceneRenderer(std::shared_ptr<const RenderPipelineAsset> pipelineAsset)
: m_cameraRenderer(std::move(pipelineAsset))
, m_framePlanBuilder(std::make_unique<CameraFramePlanBuilder>()) {
}
SceneRenderer::~SceneRenderer() = default;
void SceneRenderer::SetPipeline(std::unique_ptr<RenderPipeline> pipeline) {
m_cameraRenderer.SetPipeline(std::move(pipeline));
}
void SceneRenderer::SetPipelineAsset(std::shared_ptr<const RenderPipelineAsset> pipelineAsset) {
m_cameraRenderer.SetPipelineAsset(std::move(pipelineAsset));
}
std::vector<CameraRenderRequest> SceneRenderer::BuildRenderRequests(
const Components::Scene& scene,
Components::CameraComponent* overrideCamera,
const RenderContext& context,
const RenderSurface& surface) {
const std::vector<CameraFramePlan> plans =
BuildFramePlans(scene, overrideCamera, context, surface);
std::vector<CameraRenderRequest> requests = {};
requests.reserve(plans.size());
for (const CameraFramePlan& plan : plans) {
requests.push_back(BuildCompatibilityCameraRenderRequest(plan));
}
return requests;
}
std::vector<CameraFramePlan> SceneRenderer::BuildFramePlans(
const Components::Scene& scene,
Components::CameraComponent* overrideCamera,
const RenderContext& context,
const RenderSurface& surface) {
const std::vector<CameraRenderRequest> requests =
m_requestPlanner.BuildRequests(scene, overrideCamera, context, surface);
return m_framePlanBuilder != nullptr
? m_framePlanBuilder->BuildPlans(requests, GetPipelineAsset())
: std::vector<CameraFramePlan>();
}
bool SceneRenderer::Render(const CameraRenderRequest& request) {
return Render(CameraFramePlan::FromRequest(request));
}
bool SceneRenderer::Render(const std::vector<CameraRenderRequest>& requests) {
std::vector<CameraFramePlan> plans = CreateFramePlansFromLegacyRequests(requests);
return Render(plans);
}
bool SceneRenderer::Render(const CameraFramePlan& plan) {
return m_cameraRenderer.Render(plan);
}
bool SceneRenderer::Render(const std::vector<CameraFramePlan>& plans) {
if (plans.empty()) {
return false;
}
for (const CameraFramePlan& plan : plans) {
if (!plan.IsValid()) {
return false;
}
}
std::vector<CameraFramePlan> 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<CameraFramePlan> SceneRenderer::CreateFramePlansFromLegacyRequests(
const std::vector<CameraRenderRequest>& requests) const {
std::vector<CameraFramePlan> plans = {};
plans.reserve(requests.size());
for (const CameraRenderRequest& request : requests) {
plans.push_back(CameraFramePlan::FromRequest(request));
}
return plans;
}
} // namespace Rendering
} // namespace XCEngine