151 lines
3.8 KiB
C++
151 lines
3.8 KiB
C++
// Copyright (c) 2022 Dominic Masters
|
|
//
|
|
// This software is released under the MIT License.
|
|
// https://opensource.org/licenses/MIT
|
|
|
|
#include "RenderPipeline.hpp"
|
|
#include "game/DawnGame.hpp"
|
|
#include "display/mesh/QuadMesh.hpp"
|
|
#include "scene/SceneItem.hpp"
|
|
|
|
using namespace Dawn;
|
|
|
|
RenderPipeline::RenderPipeline(RenderManager *renderManager) {
|
|
assertNotNull(renderManager);
|
|
|
|
this->renderManager = renderManager;
|
|
}
|
|
|
|
void RenderPipeline::init() {
|
|
|
|
}
|
|
|
|
void RenderPipeline::render() {
|
|
this->renderScene(this->renderManager->game->scene);
|
|
}
|
|
|
|
void RenderPipeline::renderScene(Scene *scene) {
|
|
assertNotNull(scene);
|
|
|
|
auto backBuffer = this->renderManager->getBackBuffer();
|
|
auto cameras = scene->findComponents<Camera>();
|
|
Camera *backBufferCamera = nullptr;
|
|
|
|
// First, render all non-backbuffer cameras.
|
|
auto it = cameras.begin();
|
|
while(it != cameras.end()) {
|
|
RenderTarget *cameraTarget = (*it)->getRenderTarget();
|
|
|
|
// Leave the backbuffer camera(s) to last, so we skip them.
|
|
if(cameraTarget == backBuffer) {
|
|
backBufferCamera = *it;
|
|
} else {
|
|
this->renderSceneCamera(scene, *it);
|
|
}
|
|
|
|
++it;
|
|
}
|
|
|
|
// Now render the backbuffer camera.
|
|
if(backBufferCamera == nullptr) return;
|
|
this->renderSceneCamera(scene, backBufferCamera);
|
|
|
|
// Now we try and render UI components
|
|
auto uiCanvasList = scene->findComponents<UICanvas>();
|
|
auto itCanvas = uiCanvasList.begin();
|
|
while(itCanvas != uiCanvasList.end()) {
|
|
this->renderUI(scene, backBufferCamera, *itCanvas);
|
|
++itCanvas;
|
|
}
|
|
}
|
|
|
|
void RenderPipeline::renderSceneCamera(Scene *scene, Camera *camera) {
|
|
assertNotNull(scene);
|
|
assertNotNull(camera);
|
|
|
|
RenderTarget *renderTarget = camera->getRenderTarget();
|
|
assertNotNull(renderTarget);
|
|
|
|
renderTarget->bind();
|
|
renderTarget->clear(
|
|
RENDER_TARGET_CLEAR_FLAG_DEPTH |
|
|
RENDER_TARGET_CLEAR_FLAG_COLOR
|
|
);
|
|
this->renderManager->setRenderFlags(
|
|
RENDER_MANAGER_RENDER_FLAG_DEPTH_TEST |
|
|
RENDER_MANAGER_RENDER_FLAG_BLEND
|
|
);
|
|
|
|
auto meshes = scene->findComponents<MeshRenderer>();
|
|
auto it = meshes.begin();
|
|
while(it != meshes.end()) {
|
|
auto mesh = *it;
|
|
auto material = mesh->item->getComponent<Material>();
|
|
|
|
// TODO: fallback material?
|
|
if(material == nullptr) {
|
|
++it;
|
|
continue;
|
|
}
|
|
|
|
auto shader = material->getShader();
|
|
shader->bind();
|
|
shader->setGlobalParameters(camera->projection, camera->transform->getWorldTransform());
|
|
shader->setMeshParameters(mesh->item->transform.getWorldTransform());
|
|
material->setShaderParameters();
|
|
|
|
mesh->mesh->draw(MESH_DRAW_MODE_TRIANGLES, 0, -1);
|
|
++it;
|
|
}
|
|
}
|
|
|
|
void RenderPipeline::renderUI(
|
|
Scene *scene,
|
|
Camera *camera,
|
|
UICanvas *canvas
|
|
) {
|
|
assertNotNull(scene);
|
|
assertNotNull(camera);
|
|
assertNotNull(canvas);
|
|
|
|
RenderTarget *renderTarget;
|
|
|
|
glm::mat4 transform;
|
|
glm::mat4 projection;
|
|
switch(canvas->drawType) {
|
|
case UI_DRAW_TYPE_WORLD_CAMERA_RELATIVE:
|
|
transform = glm::mat4(1.0f);
|
|
projection = glm::ortho(0.0f, canvas->getWidth(), canvas->getHeight(), 0.0f);
|
|
renderTarget = camera->getRenderTarget();
|
|
break;
|
|
default:
|
|
assertUnreachable();
|
|
}
|
|
|
|
assertNotNull(renderTarget);
|
|
|
|
// Clear / Bind / Update the render target.
|
|
renderTarget->bind();
|
|
this->renderManager->setRenderFlags(
|
|
RENDER_MANAGER_RENDER_FLAG_BLEND
|
|
);
|
|
|
|
// Prepare the UI Shader
|
|
auto shader = this->renderManager->getUIShader();
|
|
assertNotNull(shader);
|
|
|
|
shader->bind();
|
|
shader->setUICamera(transform, projection);
|
|
|
|
// Render the children
|
|
glm::mat4 rootMatrix = canvas->transform->getWorldTransform();
|
|
auto it = canvas->children.begin();
|
|
while(it != canvas->children.end()) {
|
|
(*it)->draw(shader, rootMatrix);
|
|
++it;
|
|
}
|
|
}
|
|
|
|
RenderPipeline::~RenderPipeline() {
|
|
|
|
} |