Files
XCEngine/engine/src/Rendering/CameraRenderer.cpp

161 lines
4.6 KiB
C++
Raw Normal View History

#include "Rendering/CameraRenderer.h"
#include "Rendering/Pipelines/BuiltinForwardPipeline.h"
#include "Rendering/RenderPipelineAsset.h"
#include "Rendering/RenderSurface.h"
#include "Scene/Scene.h"
namespace XCEngine {
namespace Rendering {
namespace {
bool InitializePassSequence(
RenderPassSequence* sequence,
const RenderContext& context,
bool& initialized) {
if (sequence == nullptr) {
initialized = false;
return true;
}
initialized = sequence->Initialize(context);
if (!initialized) {
sequence->Shutdown();
}
return initialized;
}
void ShutdownPassSequence(RenderPassSequence* sequence, bool initialized) {
if (sequence != nullptr && initialized) {
sequence->Shutdown();
}
}
std::shared_ptr<const RenderPipelineAsset> CreateDefaultPipelineAsset() {
static const std::shared_ptr<const RenderPipelineAsset> s_defaultPipelineAsset =
std::make_shared<Pipelines::BuiltinForwardPipelineAsset>();
return s_defaultPipelineAsset;
}
std::unique_ptr<RenderPipeline> CreatePipelineFromAsset(
const std::shared_ptr<const RenderPipelineAsset>& pipelineAsset) {
if (pipelineAsset != nullptr) {
std::unique_ptr<RenderPipeline> pipeline = pipelineAsset->CreatePipeline();
if (pipeline != nullptr) {
return pipeline;
}
}
return std::make_unique<Pipelines::BuiltinForwardPipeline>();
}
} // namespace
CameraRenderer::CameraRenderer()
: CameraRenderer(CreateDefaultPipelineAsset()) {
}
CameraRenderer::CameraRenderer(std::unique_ptr<RenderPipeline> pipeline)
: m_pipelineAsset(nullptr) {
ResetPipeline(std::move(pipeline));
}
CameraRenderer::CameraRenderer(std::shared_ptr<const RenderPipelineAsset> pipelineAsset)
: m_pipelineAsset(std::move(pipelineAsset)) {
SetPipelineAsset(m_pipelineAsset);
}
CameraRenderer::~CameraRenderer() {
if (m_pipeline) {
m_pipeline->Shutdown();
}
}
void CameraRenderer::SetPipeline(std::unique_ptr<RenderPipeline> pipeline) {
m_pipelineAsset.reset();
ResetPipeline(std::move(pipeline));
}
void CameraRenderer::SetPipelineAsset(std::shared_ptr<const RenderPipelineAsset> pipelineAsset) {
m_pipelineAsset = pipelineAsset != nullptr ? std::move(pipelineAsset) : CreateDefaultPipelineAsset();
ResetPipeline(CreatePipelineFromAsset(m_pipelineAsset));
}
void CameraRenderer::ResetPipeline(std::unique_ptr<RenderPipeline> pipeline) {
if (m_pipeline != nullptr) {
m_pipeline->Shutdown();
}
m_pipeline = std::move(pipeline);
if (m_pipeline == nullptr) {
m_pipelineAsset = CreateDefaultPipelineAsset();
m_pipeline = CreatePipelineFromAsset(m_pipelineAsset);
}
}
bool CameraRenderer::Render(
const CameraRenderRequest& request) {
if (!request.IsValid() || m_pipeline == nullptr) {
return false;
}
RenderSceneData sceneData = m_sceneExtractor.ExtractForCamera(
*request.scene,
*request.camera,
request.surface.GetWidth(),
request.surface.GetHeight());
if (!sceneData.HasCamera()) {
return false;
}
sceneData.cameraData.clearFlags = request.clearFlags;
const RenderPassContext passContext = {
request.context,
request.surface,
sceneData
};
bool preScenePassesInitialized = false;
if (!InitializePassSequence(
request.preScenePasses,
request.context,
preScenePassesInitialized)) {
return false;
}
if (request.preScenePasses != nullptr &&
!request.preScenePasses->Execute(passContext)) {
ShutdownPassSequence(request.preScenePasses, preScenePassesInitialized);
return false;
}
if (!m_pipeline->Render(request.context, request.surface, sceneData)) {
ShutdownPassSequence(request.preScenePasses, preScenePassesInitialized);
return false;
}
bool postScenePassesInitialized = false;
if (!InitializePassSequence(
request.postScenePasses,
request.context,
postScenePassesInitialized)) {
ShutdownPassSequence(request.preScenePasses, preScenePassesInitialized);
return false;
}
if (request.postScenePasses != nullptr &&
!request.postScenePasses->Execute(passContext)) {
ShutdownPassSequence(request.postScenePasses, postScenePassesInitialized);
ShutdownPassSequence(request.preScenePasses, preScenePassesInitialized);
return false;
}
ShutdownPassSequence(request.postScenePasses, postScenePassesInitialized);
ShutdownPassSequence(request.preScenePasses, preScenePassesInitialized);
return true;
}
} // namespace Rendering
} // namespace XCEngine