Dawn/src/dawn/display/RenderPipeline.cpp

110 lines
2.7 KiB
C++

// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "assert/assert.hpp"
#include "RenderPipeline.hpp"
#include "game/Game.hpp"
#include "scene/Scene.hpp"
#include "component/display/Camera.hpp"
#include "component/display/IRenderableComponent.hpp"
using namespace Dawn;
RenderPipeline::RenderPipeline() {
}
void RenderPipeline::render(
const std::shared_ptr<Game> game
) {
assertNotNull(game, "Game cannot be null");
auto scene = game->getCurrentScene();
if(!scene) return;
this->renderScene(game, scene);
}
void RenderPipeline::renderScene(
const std::shared_ptr<Game> game,
const std::shared_ptr<Scene> scene
) {
assertNotNull(game, "Game cannot be null");
assertNotNull(scene, "Scene cannot be null");
// TODO: Render Subscenes First
// Get a list of all cameras in the scene
auto cameras = scene->findComponents<Camera>();
auto backBuffer = scene->getGame()->renderHost.getBackBufferRenderTarget();
std::shared_ptr<Camera> backbufferCamera = nullptr;
for(auto camera : cameras) {
auto rt = camera->getRenderTarget();
// Is this camera the backbuffer camera?
if(rt == backBuffer) {
backbufferCamera = camera;
continue;
}
// Render scene with this camera
renderSceneCamera(game, scene, camera, rt);
}
if(backbufferCamera) {
// Render the backbuffer camera
renderSceneCamera(game, scene, backbufferCamera, backBuffer);
}
}
void RenderPipeline::renderSceneCamera(
const std::shared_ptr<Game> game,
const std::shared_ptr<Scene> scene,
const std::shared_ptr<Camera> camera,
const std::shared_ptr<RenderTarget> renderTarget
) {
assertNotNull(game, "Game cannot be null");
assertNotNull(scene, "Scene cannot be null");
assertNotNull(camera, "Camera cannot be null");
assertNotNull(renderTarget, "RenderTarget cannot be null");
struct RenderPassContext ctx = {
game,
scene,
camera,
renderTarget
};
// Get list of renderables
std::vector<std::shared_ptr<IRenderPass>> renderPasses;
auto renderables = scene->findComponents<IRenderableComponent>();
for(auto renderable : renderables) {
auto rp = renderable->getPasses(ctx);
renderPasses.insert(renderPasses.end(), rp.begin(), rp.end());
}
auto rp = renderPasses[0];
rp->bind();
// TODO: Make clearing the buffers editable!
renderTarget->bind();
renderTarget->clear(
RENDER_TARGET_CLEAR_COLOR |
RENDER_TARGET_CLEAR_DEPTH
);
rp->bind();
for(auto renderPass : renderPasses) {
renderPass->bind();
renderPass->setData();
renderPass->upload();
renderPass->draw();
}
}
RenderPipeline::~RenderPipeline() {
}