diff --git a/assets/games/liminal/scenes/SceneBase.xml b/assets/games/liminal/scenes/SceneBase.xml index 490e63a7..857c3d84 100644 --- a/assets/games/liminal/scenes/SceneBase.xml +++ b/assets/games/liminal/scenes/SceneBase.xml @@ -11,7 +11,7 @@ - + diff --git a/src/dawn/display/RenderPipeline.cpp b/src/dawn/display/RenderPipeline.cpp index aca204f1..70d8cad7 100644 --- a/src/dawn/display/RenderPipeline.cpp +++ b/src/dawn/display/RenderPipeline.cpp @@ -226,9 +226,8 @@ void RenderPipeline::renderSceneCamera(Scene *scene, Camera *camera) { // Now we've sorted everything! Let's actually start rendering. Shader *boundShader = nullptr; std::map boundTextures; - std::map locationSlotMap; - std::map*, shaderbufferslot_t> bufferSlotMap; - shaderbufferslot_t globalSlot = 0; + std::map boundBuffers; + shaderbufferslot_t slot; // TODO: This will be editable! renderTarget->bind(); @@ -262,25 +261,14 @@ void RenderPipeline::renderSceneCamera(Scene *scene, Camera *camera) { } // Bind the buffers to their slots + slot = 0; auto itBufferSlot = item.parameterBuffers.begin(); while(itBufferSlot != item.parameterBuffers.end()) { - // First check if buffer is already bound auto location = itBufferSlot->first; auto buff = itBufferSlot->second; - // auto existingBind = bufferSlotMap.find(buff); - shaderbufferslot_t slot; - - // if(existingBind == bufferSlotMap.end()) { - // Not bound, let's find a slot we can use! - // slot = -1; - slot = globalSlot++; - // } else { - // // Already bound - // slot = existingBind->second; - // } - + boundBuffers[itBufferSlot->first] = slot; buff->bind(slot); - locationSlotMap[itBufferSlot->first] = slot; + slot++; ++itBufferSlot; } @@ -317,7 +305,7 @@ void RenderPipeline::renderSceneCamera(Scene *scene, Camera *camera) { auto itBuffer = item.parameterBuffers.begin(); while(itBuffer != item.parameterBuffers.end()) { - item.shader->setParameterBuffer(itBuffer->first, locationSlotMap[itBuffer->first]); + item.shader->setParameterBuffer(itBuffer->first, boundBuffers[itBuffer->first]); ++itBuffer; } diff --git a/src/dawn/scene/components/ui/UIBorder.cpp b/src/dawn/scene/components/ui/UIBorder.cpp index 8bbebcbd..6c5576c5 100644 --- a/src/dawn/scene/components/ui/UIBorder.cpp +++ b/src/dawn/scene/components/ui/UIBorder.cpp @@ -26,17 +26,11 @@ float_t UIBorder::getContentHeight() { } std::vector UIBorder::getRenderPasses() { - glm::mat4 view, proj; - auto canvas = this->getCanvas(); - assertNotNull(canvas); - canvas->getProjectionAndView(&proj, &view); - struct ShaderPassItem item; auto shader = getGame()->renderManager.uiShader; item.shader = shader; item.colorValues[shader->paramColor] = COLOR_WHITE; - item.matrixValues[shader->paramProjection] = proj; - item.matrixValues[shader->paramView] = view; + item.parameterBuffers[shader->bufferUiCanvas] = &this->getCanvas()->shaderBuffer; item.matrixValues[shader->paramModel] = this->transform->getWorldTransform(); if(this->texture == nullptr) { item.boolValues[shader->paramHasTexture] = false; diff --git a/src/dawn/scene/components/ui/UICanvas.cpp b/src/dawn/scene/components/ui/UICanvas.cpp index 169bcf7b..4f9b47fe 100644 --- a/src/dawn/scene/components/ui/UICanvas.cpp +++ b/src/dawn/scene/components/ui/UICanvas.cpp @@ -20,6 +20,32 @@ UICanvas::UICanvas(SceneItem *item) : { } +void UICanvas::rebufferShaderParameters() { + struct UICanvasShaderParameterBufferData data; + + switch(this->drawType) { + case UI_DRAW_TYPE_WORLD_ABSOLUTE: + data.projection = camera->getProjection(); + data.view = camera->transform->getWorldTransform(); + break; + + case UI_DRAW_TYPE_WORLD_CAMERA_RELATIVE: + data.projection = glm::ortho( + 0.0f, + camera->getRenderTarget()->getWidth(), + camera->getRenderTarget()->getHeight(), + 0.0f + ); + data.view = glm::mat4(1.0f); + break; + + default: + assertUnreachable(); + } + + this->shaderBuffer.buffer(&data); +} + float_t UICanvas::getWidth() { return w; } @@ -36,41 +62,22 @@ float_t UICanvas::getContentHeight() { return this->getHeight(); } -void UICanvas::getProjectionAndView(glm::mat4 *proj, glm::mat4 *view) { - assertNotNull(proj); - assertNotNull(view); - - switch(this->drawType) { - case UI_DRAW_TYPE_WORLD_ABSOLUTE: - *proj = camera->getProjection(); - *view = camera->transform->getWorldTransform(); - break; - - case UI_DRAW_TYPE_WORLD_CAMERA_RELATIVE: - *proj = glm::ortho( - 0.0f, - camera->getRenderTarget()->getWidth(), - camera->getRenderTarget()->getHeight(), - 0.0f - ); - *view = glm::mat4(1.0f); - break; - - default: - assertUnreachable(); - } -} - void UICanvas::onStart() { if(camera == nullptr) camera = getScene()->findComponent(); + this->shaderBuffer.init(); + this->rebufferShaderParameters(); + useEffectWithTeardown([&]{ if(camera == nullptr) return evtRenderResize = [&] {}; this->w = camera->getRenderTarget()->getWidth(); this->h = camera->getRenderTarget()->getHeight(); + this->rebufferShaderParameters(); + return evtRenderResize = useEvent([&](float_t w, float_t h){ this->w = w; this->h = h; + this->rebufferShaderParameters(); auto comps = this->item->findChildren(); auto itComps = comps.begin(); diff --git a/src/dawn/scene/components/ui/UICanvas.hpp b/src/dawn/scene/components/ui/UICanvas.hpp index 2143ad5a..515e3a5e 100644 --- a/src/dawn/scene/components/ui/UICanvas.hpp +++ b/src/dawn/scene/components/ui/UICanvas.hpp @@ -7,6 +7,7 @@ #include "scene/SceneItemComponent.hpp" #include "display/RenderTarget.hpp" #include "scene/components/display/Camera.hpp" +#include "display/shader/shaders/UIShader.hpp" namespace Dawn { class UIComponentDimensional { @@ -52,7 +53,15 @@ namespace Dawn { float_t w = 1; float_t h = 1; + /** + * Rebuffers all of the necessary shader buffer data for this canvas to + * the GPU. + */ + void rebufferShaderParameters(); + public: + UICanvasShaderParameterBuffer shaderBuffer; + /** * Creates a UI Canvas Scene Item Element, and attaches it to the provided * scene. @@ -73,14 +82,6 @@ namespace Dawn { */ UICanvas(SceneItem *item); - /** - * Return the type of projection and view matrixes are used. - * - * @param proj Projection matrix output. - * @param view View matrix ouput. - */ - void getProjectionAndView(glm::mat4 *proj, glm::mat4 *view); - float_t getWidth() override; float_t getHeight() override; float_t getContentWidth() override; diff --git a/src/dawn/scene/components/ui/UIComponent.cpp b/src/dawn/scene/components/ui/UIComponent.cpp index 25d12428..6fead769 100644 --- a/src/dawn/scene/components/ui/UIComponent.cpp +++ b/src/dawn/scene/components/ui/UIComponent.cpp @@ -169,6 +169,7 @@ UICanvas * UIComponent::getCanvas() { if(canvas != nullptr) return canvas; parent = parent->getParent(); } + assertUnreachable(); return nullptr; } diff --git a/src/dawn/scene/components/ui/UIImage.cpp b/src/dawn/scene/components/ui/UIImage.cpp index fba4909c..779ff541 100644 --- a/src/dawn/scene/components/ui/UIImage.cpp +++ b/src/dawn/scene/components/ui/UIImage.cpp @@ -26,17 +26,11 @@ float_t UIImage::getContentHeight() { } std::vector UIImage::getRenderPasses() { - glm::mat4 view, proj; - auto canvas = this->getCanvas(); - assertNotNull(canvas); - canvas->getProjectionAndView(&proj, &view); - struct ShaderPassItem item; auto shader = getGame()->renderManager.uiShader; item.shader = shader; item.colorValues[shader->paramColor] = this->color; - item.matrixValues[shader->paramProjection] = proj; - item.matrixValues[shader->paramView] = view; + item.parameterBuffers[shader->bufferUiCanvas] = &this->getCanvas()->shaderBuffer; item.matrixValues[shader->paramModel] = this->transform->getWorldTransform(); if(this->texture == nullptr) { item.boolValues[shader->paramHasTexture] = false; diff --git a/src/dawn/scene/components/ui/UILabel.cpp b/src/dawn/scene/components/ui/UILabel.cpp index af969619..fe5b612c 100644 --- a/src/dawn/scene/components/ui/UILabel.cpp +++ b/src/dawn/scene/components/ui/UILabel.cpp @@ -71,17 +71,11 @@ std::vector UILabel::getRenderPasses() { if(!this->hasText()) return {}; this->updateMesh(); - glm::mat4 view, proj; - auto canvas = this->getCanvas(); - assertNotNull(canvas); - canvas->getProjectionAndView(&proj, &view); - struct ShaderPassItem item; - auto shader = getGame()->renderManager.fontShader; + auto shader = getGame()->renderManager.uiShader; item.shader = shader; item.colorValues[shader->paramColor] = textColor; - item.matrixValues[shader->paramProjection] = proj; - item.matrixValues[shader->paramView] = view; + item.parameterBuffers[shader->bufferUiCanvas] = &getCanvas()->shaderBuffer; item.matrixValues[shader->paramModel] = this->transform->getWorldTransform(); item.textureSlots[0] = this->font->getTexture(); item.textureValues[shader->paramTexture] = 0; diff --git a/src/dawnliminal/game/LiminalGame.cpp b/src/dawnliminal/game/LiminalGame.cpp index 2fb7671b..0b992f0f 100644 --- a/src/dawnliminal/game/LiminalGame.cpp +++ b/src/dawnliminal/game/LiminalGame.cpp @@ -10,5 +10,6 @@ using namespace Dawn; Scene * Dawn::dawnGameGetInitialScene(DawnGame *game) { - return new HelloWorldScene(game); + // return new HelloWorldScene(game); + return new Scene1Prologue(game); } \ No newline at end of file diff --git a/src/dawnopengl/display/RenderManager.cpp b/src/dawnopengl/display/RenderManager.cpp index f481ff74..e2fa5cf0 100644 --- a/src/dawnopengl/display/RenderManager.cpp +++ b/src/dawnopengl/display/RenderManager.cpp @@ -21,8 +21,8 @@ void RenderManager::init() { this->lockSimpleTextured = this->shaderManager.lockShader(); this->simpleTexturedShader = this->shaderManager.getShader(this->lockSimpleTextured); - this->lockUIShaderProgram = this->shaderManager.lockShader(); - this->uiShader = this->shaderManager.getShader(this->lockUIShaderProgram); + this->lockUIShaderProgram = this->shaderManager.lockShader(); + this->uiShader = this->shaderManager.getShader(this->lockUIShaderProgram); this->lockFontShader = this->shaderManager.lockShader(); this->fontShader = this->shaderManager.getShader(this->lockFontShader); @@ -78,6 +78,6 @@ void RenderManager::update() { RenderManager::~RenderManager() { this->shaderManager.releaseShader(this->lockSimpleTextured); - this->shaderManager.releaseShader(this->lockUIShaderProgram); + this->shaderManager.releaseShader(this->lockUIShaderProgram); this->shaderManager.releaseShader(this->lockFontShader); } \ No newline at end of file diff --git a/src/dawnopengl/display/RenderManager.hpp b/src/dawnopengl/display/RenderManager.hpp index af5bcd3e..646492ea 100644 --- a/src/dawnopengl/display/RenderManager.hpp +++ b/src/dawnopengl/display/RenderManager.hpp @@ -27,7 +27,7 @@ namespace Dawn { public: BackBufferRenderTarget backBuffer; SimpleTexturedShader *simpleTexturedShader = nullptr; - SimpleTexturedShader *uiShader = nullptr; + UIShader *uiShader = nullptr; FontShader *fontShader = nullptr; ExampleFont defaultFont; diff --git a/src/dawnopengl/display/shader/shaders/CMakeLists.txt b/src/dawnopengl/display/shader/shaders/CMakeLists.txt index 775fbb74..9cf4f9c3 100644 --- a/src/dawnopengl/display/shader/shaders/CMakeLists.txt +++ b/src/dawnopengl/display/shader/shaders/CMakeLists.txt @@ -9,4 +9,5 @@ target_sources(${DAWN_TARGET_NAME} FontShader.cpp SimpleTexturedShader.cpp SimpleBillboardedShader.cpp + UIShader.cpp ) diff --git a/src/dawnopengl/display/shader/shaders/SimpleTexturedShader.hpp b/src/dawnopengl/display/shader/shaders/SimpleTexturedShader.hpp index 8890c868..9b6fb01f 100644 --- a/src/dawnopengl/display/shader/shaders/SimpleTexturedShader.hpp +++ b/src/dawnopengl/display/shader/shaders/SimpleTexturedShader.hpp @@ -10,9 +10,6 @@ namespace Dawn { class SimpleTexturedShader : public Shader { public: - shaderparameter_t paramProjection; - shaderparameter_t paramView; - shaderparameter_t paramModel; shaderparameter_t paramColor; shaderparameter_t paramTexture; diff --git a/src/dawnopengl/display/shader/shaders/UIShader.cpp b/src/dawnopengl/display/shader/shaders/UIShader.cpp new file mode 100644 index 00000000..f7f4172e --- /dev/null +++ b/src/dawnopengl/display/shader/shaders/UIShader.cpp @@ -0,0 +1,61 @@ +// Copyright (c) 2023 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#include "UIShader.hpp" + +using namespace Dawn; + +void UIShader::compile() { + #if DAWN_OPENGL_GLSL + this->compileShader( + { + { "aPos", 0 }, + { "aTexCoord", 1 } + }, + // Vertex Shader + "#version 330 core\n" + "layout (location = 0) in vec3 aPos;\n" + "layout (location = 1) in vec2 aTexCoord;\n" + + "layout (std140) uniform ub_UICanvas {\n" + "mat4 u_View;\n" + "mat4 u_Projection;\n" + "};" + + "uniform mat4 u_Model;\n" + + "out vec2 o_TextCoord;\n" + "void main() {\n" + "gl_Position = u_Projection * u_View * u_Model * vec4(aPos, 1.0);\n" + "o_TextCoord = vec2(aTexCoord.x, aTexCoord.y);\n" + "}", + + // Fragment Shader + "#version 330 core\n" + + "in vec2 o_TextCoord;\n" + "out vec4 o_Color;\n" + "uniform vec4 u_Color;\n" + "uniform bool u_HasTexture;\n" + "uniform sampler2D u_Text;\n" + + "void main() {\n" + "if(u_HasTexture) {\n" + "o_Color = texture(u_Text, o_TextCoord) * u_Color;\n" + "} else {\n" + "o_Color = u_Color;" + "}\n" + "}\n" + ); + #else + #error Shader Type must be GLSL + #endif + + this->paramModel = this->getParameterByName("u_Model"); + this->paramColor = this->getParameterByName("u_Color"); + this->paramTexture = this->getParameterByName("u_Text"); + this->paramHasTexture = this->getParameterByName("u_HasTexture"); + this->bufferUiCanvas = this->getBufferLocationByName("ub_UICanvas"); +} \ No newline at end of file diff --git a/src/dawnopengl/display/shader/shaders/UIShader.hpp b/src/dawnopengl/display/shader/shaders/UIShader.hpp index 4c929790..8eec0571 100644 --- a/src/dawnopengl/display/shader/shaders/UIShader.hpp +++ b/src/dawnopengl/display/shader/shaders/UIShader.hpp @@ -4,11 +4,30 @@ // https://opensource.org/licenses/MIT #pragma once -#include "SimpleTexturedShader.hpp" +#include "display/shader/buffers/RenderPipelineShaderBuffer.hpp" +#include "display/shader/Shader.hpp" #define UI_SHADER_PROGRAM_PRIORITY 100 namespace Dawn { - class UIShader : public SimpleTexturedShader { + struct UICanvasShaderParameterBufferData { + glm::mat4 projection; + glm::mat4 view; + }; + + class UICanvasShaderParameterBuffer : + public ShaderParameterBuffer + { + }; + + class UIShader : public Shader { + public: + shaderparameter_t paramModel; + shaderparameter_t paramColor; + shaderparameter_t paramTexture; + shaderparameter_t paramHasTexture; + shaderbufferlocation_t bufferUiCanvas; + + void compile() override; }; } \ No newline at end of file