Subscenes

This commit is contained in:
2023-01-14 22:06:35 -08:00
parent 15e7efb7f3
commit 0558b3bb25
35 changed files with 733 additions and 116 deletions

View File

@ -29,6 +29,26 @@ void RenderPipeline::render() {
void RenderPipeline::renderScene(Scene *scene) {
assertNotNull(scene);
// Render subscenes first.
auto subSceneControllers = scene->findComponents<SubSceneController>();
auto itSubScene = subSceneControllers.begin();
while(itSubScene != subSceneControllers.end()) {
auto subScene = (*itSubScene)->getSubScene();
if(subScene == nullptr) {
++itSubScene;
continue;
}
if((*itSubScene)->onlyUpdateUnpaused && scene->game->timeManager.isPaused) {
++itSubScene;
continue;
}
this->renderScene(subScene);
++itSubScene;
}
// Now render backbuffers.
auto backBuffer = this->renderManager->getBackBuffer();
auto cameras = scene->findComponents<Camera>();
Camera *backBufferCamera = nullptr;
@ -38,7 +58,8 @@ void RenderPipeline::renderScene(Scene *scene) {
while(it != cameras.end()) {
RenderTarget *cameraTarget = (*it)->getRenderTarget();
// Leave the backbuffer camera(s) to last, so we skip them.
// Leave the backbuffer camera(s) to last, so we skip them. we do this so
// that children framebuffers contain the CURRENT frame, not LAST frame.
if(cameraTarget == backBuffer) {
backBufferCamera = *it;
} else {
@ -51,21 +72,15 @@ void RenderPipeline::renderScene(Scene *scene) {
// 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);
auto meshes = scene->findComponents<MeshRenderer>();
auto uiCanvasList = scene->findComponents<UICanvas>();
auto renderTarget = camera->getRenderTarget();
RenderTarget *renderTarget = camera->getRenderTarget();
assertNotNull(renderTarget);
renderTarget->bind();
@ -77,8 +92,8 @@ void RenderPipeline::renderSceneCamera(Scene *scene, Camera *camera) {
RENDER_MANAGER_RENDER_FLAG_DEPTH_TEST |
RENDER_MANAGER_RENDER_FLAG_BLEND
);
auto meshes = scene->findComponents<MeshRenderer>();
// Render all Meshes on the scene
auto it = meshes.begin();
while(it != meshes.end()) {
auto mesh = *it;
@ -91,6 +106,7 @@ void RenderPipeline::renderSceneCamera(Scene *scene, Camera *camera) {
}
auto shader = material->getShader();
assertNotNull(shader);
shader->bind();
shader->setGlobalParameters(camera->projection, camera->transform->getWorldTransform());
shader->setMeshParameters(mesh->item->transform.getWorldTransform());
@ -99,56 +115,69 @@ void RenderPipeline::renderSceneCamera(Scene *scene, Camera *camera) {
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;
// Now we only render world-absolute UI canvas'
auto uiShader = this->renderManager->getUIShader();
assertNotNull(uiShader);
uiShader->bind();
uiShader->setUICamera(camera->projection, camera->transform->getWorldTransform());
this->renderManager->setRenderFlags(RENDER_MANAGER_RENDER_FLAG_DEPTH_TEST);
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();
auto it2 = uiCanvasList.begin();
while(it2 != uiCanvasList.end()) {
auto canvas = *it2;
switch(canvas->drawType) {
case UI_DRAW_TYPE_WORLD_ABSOLUTE:
break;
default:
++it2;
continue;
}
auto it3 = canvas->children.begin();
auto rootMatrix = canvas->transform->getWorldTransform();
while(it3 != canvas->children.end()) {
(*it3)->draw(uiShader,
glm::translate(glm::scale(rootMatrix, glm::vec3(1.0f, -1.0f, 1.0f)), glm::vec3(0, -renderTarget->getHeight(), 0))
);
++it3;
}
++it2;
}
assertNotNull(renderTarget);
// Clear / Bind / Update the render target.
renderTarget->bind();
// renderTarget->clear(
// RENDER_TARGET_CLEAR_FLAG_DEPTH |
// RENDER_TARGET_CLEAR_FLAG_COLOR
// );
// Now render camera-relative UI
this->renderManager->setRenderFlags(
RENDER_MANAGER_RENDER_FLAG_BLEND
);
uiShader->setUICamera(
glm::ortho(0.0f, renderTarget->getWidth(), renderTarget->getHeight(), 0.0f),
glm::mat4(1.0f)
);
// Prepare the UI Shader
auto shader = this->renderManager->getUIShader();
assertNotNull(shader);
shader->bind();
shader->setUICamera(transform, projection);
it2 = uiCanvasList.begin();
while(it2 != uiCanvasList.end()) {
auto canvas = *it2;
// Render the children
glm::mat4 rootMatrix = canvas->transform->getWorldTransform();
auto it = canvas->children.begin();
while(it != canvas->children.end()) {
(*it)->draw(shader, rootMatrix);
++it;
switch(canvas->drawType) {
case UI_DRAW_TYPE_WORLD_CAMERA_RELATIVE:
break;
default:
++it2;
continue;
}
auto it3 = canvas->children.begin();
auto rootMatrix = canvas->transform->getWorldTransform();
while(it3 != canvas->children.end()) {
(*it3)->draw(uiShader, rootMatrix);
++it3;
}
++it2;
}
}

View File

@ -51,19 +51,6 @@ namespace Dawn {
*/
virtual void renderSceneCamera(Scene *scene, Camera *camera);
/**
* Renders a UI Canvas to the back buffer.
*
* @param scene Scene for the UI canvas.
* @param camera Main backbuffer camera for the canvas.
* @param canvas Canvas to render.
*/
virtual void renderUI(
Scene *scene,
Camera *camera,
UICanvas *canvas
);
/**
* Cleanup a render pipeline that has been initialized.
*/