diff --git a/src/dawn/CMakeLists.txt b/src/dawn/CMakeLists.txt index 17cd2c31..2a079d8e 100644 --- a/src/dawn/CMakeLists.txt +++ b/src/dawn/CMakeLists.txt @@ -18,4 +18,5 @@ target_include_directories(${DAWN_TARGET_NAME} # Subdirs add_subdirectory(asset) add_subdirectory(display) -add_subdirectory(scene) \ No newline at end of file +add_subdirectory(scene) +add_subdirectory(ui) \ No newline at end of file diff --git a/src/dawn/display/RenderPipeline.cpp b/src/dawn/display/RenderPipeline.cpp index d530b227..abd94d7c 100644 --- a/src/dawn/display/RenderPipeline.cpp +++ b/src/dawn/display/RenderPipeline.cpp @@ -5,6 +5,7 @@ #include "RenderPipeline.hpp" #include "game/DawnGame.hpp" +#include "display/mesh/QuadMesh.hpp" using namespace Dawn; @@ -44,6 +45,14 @@ 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(); + auto itCanvas = uiCanvasList.begin(); + while(itCanvas != uiCanvasList.end()) { + this->renderUI(scene, *backBufferCamera, **itCanvas); + ++itCanvas; + } } void RenderPipeline::renderSceneCamera(Scene &scene, Camera &camera) { @@ -53,6 +62,10 @@ void RenderPipeline::renderSceneCamera(Scene &scene, Camera &camera) { 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(); auto it = meshes.begin(); @@ -77,6 +90,51 @@ void RenderPipeline::renderSceneCamera(Scene &scene, Camera &camera) { } } +void RenderPipeline::renderUI( + Scene &scene, + Camera &camera, + UICanvas &canvas +) { + // Get the + 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: + throw "UI Draw modes are not yet supported."; + } + + // Clear / Bind / Update the render target. + renderTarget->bind(); + renderTarget->clear( + RENDER_TARGET_CLEAR_FLAG_DEPTH | + RENDER_TARGET_CLEAR_FLAG_COLOR + ); + this->renderManager.setRenderFlags( + RENDER_MANAGER_RENDER_FLAG_BLEND | + RENDER_MANAGER_RENDER_FLAG_DEPTH_TEST + ); + + // Prepare the UI Shader + auto shader = this->renderManager.getUIShader(); + 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() { } \ No newline at end of file diff --git a/src/dawn/display/RenderPipeline.hpp b/src/dawn/display/RenderPipeline.hpp index 3ab436fd..6d4a8bf8 100644 --- a/src/dawn/display/RenderPipeline.hpp +++ b/src/dawn/display/RenderPipeline.hpp @@ -8,6 +8,8 @@ #include "display/RenderManager.hpp" #include "scene/Scene.hpp" #include "scene/components/Components.hpp" +#include "scene/components/ui/UICanvas.hpp" +#include "ui/UIComponent.hpp" namespace Dawn { class RenderPipeline { @@ -49,6 +51,19 @@ 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. */ diff --git a/src/dawn/display/Transform.cpp b/src/dawn/display/Transform.cpp index 9697fdc2..b1a6fb0f 100644 --- a/src/dawn/display/Transform.cpp +++ b/src/dawn/display/Transform.cpp @@ -79,7 +79,7 @@ void Transform::setLocalPosition(glm::vec3 position) { } glm::vec3 Transform::getLocalScale() { - return this->scale; + return this->localScale; } void Transform::setLocalScale(glm::vec3 scale) { @@ -140,6 +140,9 @@ void Transform::setParent(Transform *parent) { this->parent = parent; if(parent != nullptr) parent->children.push_back(this); + + this->updateLocalTransformFromWorldTransform(); + this->updateChildrenTransforms(); } Transform * Transform::getParent() { @@ -148,6 +151,7 @@ Transform * Transform::getParent() { Transform::~Transform() { this->setParent(nullptr); + auto it = this->parent->children.begin(); while(it != this->parent->children.end()) { (*it)->setParent(nullptr); diff --git a/src/dawn/display/Transform.hpp b/src/dawn/display/Transform.hpp index 916505bb..a8e0ad16 100644 --- a/src/dawn/display/Transform.hpp +++ b/src/dawn/display/Transform.hpp @@ -21,9 +21,9 @@ namespace Dawn { glm::mat4 transformLocal; glm::mat4 transformWorld; - glm::vec3 position; - glm::vec3 scale; - glm::quat rotation; + // glm::vec3 position; + // glm::vec3 scale; + // glm::quat rotation; // Heirarchy Transform *parent = nullptr; diff --git a/src/dawn/display/_RenderManager.hpp b/src/dawn/display/_RenderManager.hpp index 23d8536e..9db0382f 100644 --- a/src/dawn/display/_RenderManager.hpp +++ b/src/dawn/display/_RenderManager.hpp @@ -6,12 +6,22 @@ #pragma once #include "RenderTarget.hpp" #include "display/shader/Shader.hpp" +#include "display/shader/UIShader.hpp" +#include "util/flag.hpp" + +#define RENDER_MANAGER_RENDER_FLAG_DEPTH_TEST FLAG_DEFINE(0) +#define RENDER_MANAGER_RENDER_FLAG_BLEND FLAG_DEFINE(1) + +typedef flag_t renderflag_t; namespace Dawn { class DawnGame; class RenderPipeline; class IRenderManager { + protected: + renderflag_t renderFlags = 0; + public: DawnGame &game; std::shared_ptr renderPipeline; @@ -47,6 +57,20 @@ namespace Dawn { */ virtual std::shared_ptr getDefaultShader() = 0; + /** + * Returns the UI Shader used by the game's UI engine. + * + * @return Pointer to the UI Shader. + */ + virtual std::shared_ptr getUIShader() = 0; + + /** + * Sets the render flags for the render manager to use. + * + * @param renderFlags Render flags to use. + */ + virtual void setRenderFlags(renderflag_t renderFlags) = 0; + /** * Initialize / Start the Render Manager. * diff --git a/src/dawn/display/mesh/QuadMesh.cpp b/src/dawn/display/mesh/QuadMesh.cpp index b4283be7..4c9f3ece 100644 --- a/src/dawn/display/mesh/QuadMesh.cpp +++ b/src/dawn/display/mesh/QuadMesh.cpp @@ -35,4 +35,15 @@ void QuadMesh::bufferQuadMeshWithZ( verticeStart + 1, verticeStart + 2, verticeStart + 3 }} ); +} + +void QuadMesh::bufferQuadMesh( + Mesh &mesh, + glm::vec2 xy0, glm::vec2 uv0, + glm::vec2 xy1, glm::vec2 uv1, + int32_t verticeStart, int32_t indiceStart +) { + QuadMesh::bufferQuadMeshWithZ( + mesh, xy0, uv0, xy1, uv1, 0, verticeStart, indiceStart + ); } \ No newline at end of file diff --git a/src/dawn/scene/Scene.cpp b/src/dawn/scene/Scene.cpp index ade5f528..21866ad0 100644 --- a/src/dawn/scene/Scene.cpp +++ b/src/dawn/scene/Scene.cpp @@ -35,5 +35,4 @@ std::shared_ptr Scene::createSceneItem() { } Scene::~Scene() { - std::cout << "What the dick" << std::endl; } \ No newline at end of file diff --git a/src/dawn/scene/SceneItem.hpp b/src/dawn/scene/SceneItem.hpp index 264c602d..78ad5b14 100644 --- a/src/dawn/scene/SceneItem.hpp +++ b/src/dawn/scene/SceneItem.hpp @@ -71,6 +71,42 @@ namespace Dawn { } return nullptr; } + + /** + * Finds a (direct) child of this component that has a matching component. + * + * @tparam T Component to find child of. + * @return Pointer to the child, or nullptr if not found. + */ + template + std::shared_ptr findChild() { + auto it = this->transform.children.begin(); + while(it != this->transform.children.end()) { + auto child = (*it)->item.getComponent(); + if(child != nullptr) return child; + ++it; + } + return nullptr; + } + + /** + * Finds all (direct) children of this component that match the queried + * component. + * + * @tparam T Component to find children for. + * @return Array of pointers to matching children. + */ + template + std::vector> findChildren() { + auto it = this->transform.children.begin(); + std::vector> children; + while(it != this->transform.children.end()) { + auto child = (*it)->item.getComponent(); + if(child != nullptr) children.push_back(child); + ++it; + } + return children; + } /** * Destroy this SceneItem. diff --git a/src/dawn/scene/components/CMakeLists.txt b/src/dawn/scene/components/CMakeLists.txt index 7873eac4..d22abb4e 100644 --- a/src/dawn/scene/components/CMakeLists.txt +++ b/src/dawn/scene/components/CMakeLists.txt @@ -4,4 +4,5 @@ # https://opensource.org/licenses/MIT # Subdirs -add_subdirectory(display) \ No newline at end of file +add_subdirectory(display) +add_subdirectory(ui) \ No newline at end of file diff --git a/src/dawn/scene/components/ui/CMakeLists.txt b/src/dawn/scene/components/ui/CMakeLists.txt new file mode 100644 index 00000000..65efd811 --- /dev/null +++ b/src/dawn/scene/components/ui/CMakeLists.txt @@ -0,0 +1,10 @@ +# Copyright (c) 2022 Dominic Masters +# +# This software is released under the MIT License. +# https://opensource.org/licenses/MIT + +# Sources +target_sources(${DAWN_TARGET_NAME} + PRIVATE + UICanvas.cpp +) \ No newline at end of file diff --git a/src/dawn/scene/components/ui/UICanvas.cpp b/src/dawn/scene/components/ui/UICanvas.cpp new file mode 100644 index 00000000..0ec9d80f --- /dev/null +++ b/src/dawn/scene/components/ui/UICanvas.cpp @@ -0,0 +1,32 @@ +// Copyright (c) 2022 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#include "UICanvas.hpp" +#include "scene/Scene.hpp" +#include "ui/UIComponent.hpp" +#include "game/DawnGame.hpp" + +using namespace Dawn; + +std::shared_ptr UICanvas::createCanvas(std::shared_ptr scene) { + auto item = scene->createSceneItem(); + return item->addComponent(); +} + +UICanvas::UICanvas(SceneItem &item) : SceneItemComponent(item) { + +} + +float_t UICanvas::getWidth() { + return this->getGame().renderManager.getBackBuffer().getWidth(); +} + +float_t UICanvas::getHeight() { + return this->getGame().renderManager.getBackBuffer().getHeight(); +} + +void UICanvas::start() { + +} \ No newline at end of file diff --git a/src/dawn/scene/components/ui/UICanvas.hpp b/src/dawn/scene/components/ui/UICanvas.hpp new file mode 100644 index 00000000..7b027210 --- /dev/null +++ b/src/dawn/scene/components/ui/UICanvas.hpp @@ -0,0 +1,42 @@ +// Copyright (c) 2022 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#pragma once +#include "scene/SceneItemComponent.hpp" + +namespace Dawn { + enum UIDrawType { + UI_DRAW_TYPE_WORLD_ABSOLUTE, + UI_DRAW_TYPE_WORLD_CAMERA_RELATIVE, + UI_DRAW_TYPE_CAMERA_OVERLAY + }; + + class UIComponent; + + class UICanvas : public SceneItemComponent { + public: + static std::shared_ptr createCanvas( + std::shared_ptr scene + ); + + // + std::vector> children; + UIDrawType drawType = UI_DRAW_TYPE_WORLD_CAMERA_RELATIVE; + + UICanvas(SceneItem &item); + + template + std::shared_ptr addElement() { + auto item = std::make_shared(*this); + this->children.push_back(item); + return item; + } + + float_t getWidth(); + float_t getHeight(); + + void start() override; + }; +} \ No newline at end of file diff --git a/src/dawn/ui/CMakeLists.txt b/src/dawn/ui/CMakeLists.txt new file mode 100644 index 00000000..41928fc7 --- /dev/null +++ b/src/dawn/ui/CMakeLists.txt @@ -0,0 +1,11 @@ +# Copyright (c) 2022 Dominic Masters +# +# This software is released under the MIT License. +# https://opensource.org/licenses/MIT + +# Sources +target_sources(${DAWN_TARGET_NAME} + PRIVATE + UIComponent.cpp + UISprite.cpp +) \ No newline at end of file diff --git a/src/dawn/ui/UIComponent.cpp b/src/dawn/ui/UIComponent.cpp new file mode 100644 index 00000000..d4b7d9d9 --- /dev/null +++ b/src/dawn/ui/UIComponent.cpp @@ -0,0 +1,119 @@ +// Copyright (c) 2022 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#include "UIComponent.hpp" + +using namespace Dawn; + +UIComponent::UIComponent(UICanvas &canvas) : + canvas(canvas) +{ +} + +void UIComponent::updatePositions() { + // X Alignment + if(this->alignX == UI_COMPONENT_ALIGN_STRETCH) { + if(this->parent == nullptr) { + this->width = this->canvas.getWidth(); + } else { + this->width = this->parent->getWidth(); + } + this->relativeX = this->alignment[0]; + this->width -= (this->alignment[0] + this->alignment[2]); + } else { + this->relativeX = this->alignment[0]; + this->width = this->alignment[2]; + } + + // Y Alignment + if(this->alignY == UI_COMPONENT_ALIGN_STRETCH) { + if(this->parent == nullptr) { + this->height = this->canvas.getHeight(); + } else { + this->height = this->parent->getHeight(); + } + this->relativeY = this->alignment[1]; + this->height -= (this->alignment[1] + this->alignment[3]); + } else { + this->relativeY = this->alignment[1]; + this->height = this->alignment[3]; + } + + // Update children + auto it = this->children.begin(); + while(it != this->children.end()) { + (*it)->updatePositions(); + ++it; + } +} + +float_t UIComponent::getWidth() { + return this->width; +} + +float_t UIComponent::getHeight() { + return this->height; +} + +float_t UIComponent::getRelativeX() { + return this->relativeX; +} + +float_t UIComponent::getRelativeY() { + return this->relativeY; +} + +void UIComponent::setTransform( + UIComponentAlign xAlign, + UIComponentAlign yAlign, + glm::vec4 alignment, + float_t z +) { + this->alignX = xAlign; + this->alignY = yAlign; + this->alignment = alignment; + this->z = z; + this->updatePositions(); +} + +void UIComponent::draw(UIShader &uiShader, glm::mat4 parentTransform) { + // Calculate self transform matrix + glm::mat4 selfTransform = parentTransform * glm::translate( + glm::mat4(1.0f), glm::vec3(this->relativeX, this->relativeY, this->z) + ); + + // Draw Self + this->drawSelf(uiShader, selfTransform); + + // Render children + auto it = this->children.begin(); + while(it != this->children.end()) { + (*it)->draw(uiShader, selfTransform); + ++it; + } +} + +void UIComponent::addChild(std::shared_ptr child) { + if(child->parent == this) return; + if(child->parent != nullptr) child->parent->removeChild(child); + this->children.push_back(child); + child->parent = this; +} + +void UIComponent::removeChild(std::shared_ptr child) { + if(child->parent != this) throw "Invalid child"; + auto it = this->children.begin(); + while(it != this->children.end()) { + if(it->get() == child.get()) { + this->children.erase(it); + break; + } + ++it; + } +} + +UIComponent::~UIComponent() { + +} \ No newline at end of file diff --git a/src/dawn/ui/UIComponent.hpp b/src/dawn/ui/UIComponent.hpp new file mode 100644 index 00000000..9b690280 --- /dev/null +++ b/src/dawn/ui/UIComponent.hpp @@ -0,0 +1,75 @@ +// Copyright (c) 2022 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#pragma once +#include "scene/components/ui/UICanvas.hpp" +#include "scene/Scene.hpp" +#include "display/Color.hpp" +#include "display/shader/UIShader.hpp" + +namespace Dawn { + enum UIComponentAlign { + UI_COMPONENT_ALIGN_START, + UI_COMPONENT_ALIGN_MIDDLE, + UI_COMPONENT_ALIGN_END, + UI_COMPONENT_ALIGN_STRETCH + }; + + class UIComponent { + protected: + // Calculated (and cached) values + float_t width = 1; + float_t height = 1; + float_t relativeX = 0; + float_t relativeY = 0; + + // Setting values + UIComponentAlign alignX = UI_COMPONENT_ALIGN_START; + UIComponentAlign alignY = UI_COMPONENT_ALIGN_START; + glm::vec4 alignment = glm::vec4(0, 0, 1, 1); + float_t z = 0; + std::vector> children; + UIComponent *parent = nullptr; + + // I currently don't support rotation or scale. Not because I can't but + // because it's basically un-necessary. Unity does support rotation but + // it doesn't affect how the alignment side of things work (similar to how + // CSS would handle things) When I need to support these I will add the + // code but right now it's not necessary + + /** + * Updates the cached/stored values based on the setting internal values. + * You should watchdog this if you intend to do something when values are + * updated, e.g. if you need to resize a quad, or something. + */ + virtual void updatePositions(); + + public: + UICanvas &canvas; + + UIComponent(UICanvas &canvas); + + float_t getWidth(); + float_t getHeight(); + float_t getRelativeX(); + float_t getRelativeY(); + + void setTransform( + UIComponentAlign xAlign, + UIComponentAlign yAlign, + glm::vec4 alignment, + float_t z + ); + + // virtual void update() = 0; + void draw(UIShader &uiShader, glm::mat4 parentTransform); + virtual void drawSelf(UIShader &uiShader, glm::mat4 selfTransform) = 0; + + void addChild(std::shared_ptr chidl); + void removeChild(std::shared_ptr child); + + virtual ~UIComponent(); + }; +} \ No newline at end of file diff --git a/src/dawn/ui/UISprite.cpp b/src/dawn/ui/UISprite.cpp new file mode 100644 index 00000000..7d707448 --- /dev/null +++ b/src/dawn/ui/UISprite.cpp @@ -0,0 +1,34 @@ +// Copyright (c) 2022 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#include "UISprite.hpp" + +using namespace Dawn; + +UISprite::UISprite(UICanvas &canvas) : UIComponent(canvas) { + this->mesh.createBuffers(QUAD_VERTICE_COUNT, QUAD_INDICE_COUNT); +} + +void UISprite::updatePositions() { + UIComponent::updatePositions(); + + std::cout << "Updating" << std::endl; + + QuadMesh::bufferQuadMesh( + this->mesh, + glm::vec2(0, 0), glm::vec2(0, 0), + glm::vec2(this->width, this->height), glm::vec2(1, 1), + 0, 0 + ); +} + +void UISprite::drawSelf(UIShader &uiShader, glm::mat4 selfTransform) { + uiShader.setUITexture(nullptr); + uiShader.setUIModel(selfTransform); + uiShader.setUIModel(glm::mat4(1.0f)); + uiShader.setUIColor(COLOR_WHITE); + + this->mesh.draw(MESH_DRAW_MODE_TRIANGLES, 0, -1); +} \ No newline at end of file diff --git a/src/dawn/ui/UISprite.hpp b/src/dawn/ui/UISprite.hpp new file mode 100644 index 00000000..5f818401 --- /dev/null +++ b/src/dawn/ui/UISprite.hpp @@ -0,0 +1,23 @@ +// Copyright (c) 2022 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#pragma once +#include "UIComponent.hpp" +#include "display/mesh/QuadMesh.hpp" + +namespace Dawn { + class UISprite : public UIComponent { + protected: + void updatePositions() override; + + public: + Mesh mesh; + + UISprite(UICanvas &canvas); + + // void update() override; + void drawSelf(UIShader &uiShader, glm::mat4 selfTransform) override; + }; +} \ No newline at end of file diff --git a/src/dawn/util/flag.hpp b/src/dawn/util/flag.hpp index 09045b3c..735b47ef 100644 --- a/src/dawn/util/flag.hpp +++ b/src/dawn/util/flag.hpp @@ -7,5 +7,9 @@ #include "dawnlibs.hpp" typedef uint_fast8_t flag8_t; +typedef uint_fast16_t flag16_t; +typedef uint_fast32_t flag32_t; + +typedef flag32_t flag_t; #define FLAG_DEFINE(n) (1 << n) \ No newline at end of file diff --git a/src/dawnopengl/display/RenderManager.cpp b/src/dawnopengl/display/RenderManager.cpp index e371a349..8c770994 100644 --- a/src/dawnopengl/display/RenderManager.cpp +++ b/src/dawnopengl/display/RenderManager.cpp @@ -16,17 +16,18 @@ RenderManager::RenderManager(DawnGame &game) : { this->standardRenderPipeline=std::make_shared(*this); this->simpleShader = std::make_shared(); + this->uiShader = std::make_shared(); } void RenderManager::init() { this->standardRenderPipeline->init(); this->simpleShader->compile(); + this->uiShader->compile(); - // Setup the alpha blend function. - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); + + // Prepare the initial values glEnable(GL_TEXTURE_2D); - glEnable(GL_DEPTH_TEST); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDepthMask(GL_TRUE); glDepthFunc(GL_LESS); } @@ -43,6 +44,26 @@ std::shared_ptr RenderManager::getDefaultShader() { return this->simpleShader; } +std::shared_ptr RenderManager::getUIShader() { + return this->uiShader; +} + +void RenderManager::setRenderFlags(renderflag_t flags) { + this->renderFlags = flags; + + if((flags & RENDER_MANAGER_RENDER_FLAG_DEPTH_TEST) == 0) { + glDisable(GL_DEPTH_TEST); + } else { + glEnable(GL_DEPTH_TEST); + } + + if((flags & RENDER_MANAGER_RENDER_FLAG_BLEND) == 0) { + glDisable(GL_BLEND); + } else { + glEnable(GL_BLEND); + } +} + void RenderManager::update() { this->getRenderPipeline().render(); } diff --git a/src/dawnopengl/display/RenderManager.hpp b/src/dawnopengl/display/RenderManager.hpp index 207772e1..3c0941f6 100644 --- a/src/dawnopengl/display/RenderManager.hpp +++ b/src/dawnopengl/display/RenderManager.hpp @@ -18,6 +18,7 @@ namespace Dawn { public: BackBufferRenderTarget backBuffer; std::shared_ptr simpleShader; + std::shared_ptr uiShader; /** * Construct a new RenderManager for a game instance. @@ -27,6 +28,8 @@ namespace Dawn { RenderTarget & getBackBuffer() override; RenderPipeline & getRenderPipeline() override; std::shared_ptr getDefaultShader() override; + std::shared_ptr getUIShader() override; + void setRenderFlags(renderflag_t renderFlags) override; void init() override; void update() override; diff --git a/src/dawnopengl/display/shader/SimpleTexturedShader.hpp b/src/dawnopengl/display/shader/SimpleTexturedShader.hpp index 50396d62..984eb9ca 100644 --- a/src/dawnopengl/display/shader/SimpleTexturedShader.hpp +++ b/src/dawnopengl/display/shader/SimpleTexturedShader.hpp @@ -9,7 +9,7 @@ namespace Dawn { class SimpleTexturedShader : public Shader { - private: + public: shaderparameter_t paramProjection; shaderparameter_t paramView; shaderparameter_t paramModel; @@ -17,7 +17,6 @@ namespace Dawn { shaderparameter_t paramTexture; shaderparameter_t paramHasTexture; - public: std::map getParameters() override { std::map ps; diff --git a/src/dawnopengl/display/shader/UIShader.hpp b/src/dawnopengl/display/shader/UIShader.hpp new file mode 100644 index 00000000..e25cedc6 --- /dev/null +++ b/src/dawnopengl/display/shader/UIShader.hpp @@ -0,0 +1,119 @@ +// Copyright (c) 2022 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#pragma once +#include "display/shader/Shader.hpp" +#include "scene/components/Components.hpp" + +namespace Dawn { + class UIShader : public Shader { + public: + shaderparameter_t paramProjection; + shaderparameter_t paramView; + shaderparameter_t paramModel; + shaderparameter_t paramColor; + shaderparameter_t paramTexture; + shaderparameter_t paramHasTexture; + + std::map + getParameters() override { + std::map ps; + + ps[this->paramColor] = SHADER_PARAMETER_TYPE_COLOR; + ps[this->paramHasTexture] = SHADER_PARAMETER_TYPE_BOOLEAN; + ps[this->paramTexture] = SHADER_PARAMETER_TYPE_TEXTURE; + + return ps; + } + + void setDefaultParameters(Material &material) override { + material.colorValues[this->paramColor] = COLOR_WHITE; + } + + void setGlobalParameters(glm::mat4 proj, glm::mat4 view) override { + this->setMatrix(this->paramProjection, proj); + this->setMatrix(this->paramView, view); + } + + void setMeshParameters(glm::mat4 transform) override { + this->setMatrix(this->paramModel, transform); + } + + void bindTexture( + shaderparameter_t param, + std::shared_ptr texture + ) override { + if(texture == nullptr) { + this->setBoolean(this->paramHasTexture, false); + } else { + this->setBoolean(this->paramHasTexture, true); + this->setTextureSlot(param, 0x00); + texture->bind(0x00); + } + } + + void compile() override { + this->compileShader( + // Vertex Shader + "#version 330 core\n" + "layout (location = 0) in vec3 aPos;\n" + "layout (location = 1) in vec2 aTexCoord;\n" + + "uniform mat4 u_Proj;\n" + "uniform mat4 u_View;\n" + "uniform mat4 u_Model;\n" + + "out vec2 o_TextCoord;\n" + "void main() {\n" + "gl_Position = u_Proj * u_View * u_Model * vec4(aPos, 1.0);\n" + "o_TextCoord = vec2(aTexCoord.x, aTexCoord.y);\n" + "}", + + // Fragment Shader + "#version 330 core\n" + "out vec4 o_Color;\n" + "in vec2 o_TextCoord;\n" + "uniform vec4 u_Color;\n" + "uniform sampler2D u_Text;\n" + "uniform bool u_HasTexture;\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" + ); + + this->paramProjection = this->getParameterByName("u_Proj"); + this->paramView = this->getParameterByName("u_View"); + 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->setBoolean(this->paramHasTexture, false); + } + + + void setUICamera(glm::mat4 view, glm::mat4 projection) { + this->setMatrix(this->paramView, view); + this->setMatrix(this->paramProjection, projection); + } + + void setUIModel(glm::mat4 model) { + this->setMatrix(this->paramModel, model); + } + + void setUITexture(std::shared_ptr texture) { + this->bindTexture(this->paramTexture, texture); + } + + void setUIColor(struct Color color) { + this->setColor(this->paramColor, color); + } + }; +} \ No newline at end of file diff --git a/src/dawnpokergame/game/DawnPokerGame.cpp b/src/dawnpokergame/game/DawnPokerGame.cpp index 1750fc06..2be99356 100644 --- a/src/dawnpokergame/game/DawnPokerGame.cpp +++ b/src/dawnpokergame/game/DawnPokerGame.cpp @@ -7,22 +7,6 @@ using namespace Dawn; -std::shared_ptr cubeCreate(std::shared_ptr scene) { - auto cubeObject = scene->createSceneItem(); - auto cubeMeshRenderer = cubeObject->addComponent(); - auto cubeMaterial = cubeObject->addComponent(); - cubeMeshRenderer->mesh = std::make_shared(); - cubeMeshRenderer->mesh->createBuffers(CUBE_VERTICE_COUNT, CUBE_INDICE_COUNT); - CubeMesh::buffer( - *cubeMeshRenderer->mesh, - glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(1, 1, 1), - 0, 0 - ); - return cubeObject; -} - -std::shared_ptr cubeParent; - DawnGame::DawnGame(DawnHost &host) : host(host), renderManager(*this) @@ -39,12 +23,14 @@ int32_t DawnGame::init() { auto camera = cameraObject->addComponent(); camera->transform.lookAt(glm::vec3(5, 5, 5), glm::vec3(0, 0, 0)); - cubeParent = cubeCreate(this->scene); - auto cubeChild = cubeCreate(this->scene); - cubeChild->getComponent()->colorValues[cubeChild->getComponent()->getShader()->getParameterByName("u_Color")] = COLOR_MAGENTA; - cubeChild->transform.setParent(&cubeParent->transform); - cubeChild->transform.setLocalPosition(glm::vec3(1, 0, 0)); - cubeParent->transform.setLocalPosition(glm::vec3(-0.5f, 0, 0)); + auto canvas = UICanvas::createCanvas(this->scene); + auto test = canvas->addElement(); + test->setTransform( + UI_COMPONENT_ALIGN_START, + UI_COMPONENT_ALIGN_START, + glm::vec4(0, 0, 32, 32), + 0 + ); return DAWN_GAME_INIT_RESULT_SUCCESS; } @@ -54,8 +40,6 @@ int32_t DawnGame::update(float_t delta) { if(this->scene != nullptr) this->scene->update(); - cubeParent->transform.setLocalPosition(cubeParent->transform.getLocalPosition() + glm::vec3(-delta, 0, 0)); - this->renderManager.update(); return DAWN_GAME_UPDATE_RESULT_SUCCESS; diff --git a/src/dawnpokergame/game/DawnPokerGame.hpp b/src/dawnpokergame/game/DawnPokerGame.hpp index c80e9eb1..3f8d52f4 100644 --- a/src/dawnpokergame/game/DawnPokerGame.hpp +++ b/src/dawnpokergame/game/DawnPokerGame.hpp @@ -6,7 +6,4 @@ #pragma once #include "game/DawnGame.hpp" #include "scene/components/Components.hpp" -#include "display/mesh/QuadMesh.hpp" -#include "display/mesh/TriangleMesh.hpp" -#include "display/mesh/CubeMesh.hpp" -#include "asset/assets/TextureAsset.hpp" \ No newline at end of file +#include "ui/UISprite.hpp" \ No newline at end of file