From 09200c38169eb6434d6fe60634f9b9e2865d33dc Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Mon, 11 Dec 2023 23:54:52 -0600 Subject: [PATCH] Uniform arrays working. --- src/dawn/CMakeLists.txt | 1 + src/dawn/component/CMakeLists.txt | 3 +- src/dawn/component/ui/CMakeLists.txt | 9 ++ src/dawn/component/ui/UICanvas.cpp | 64 ++++++++++++ src/dawn/component/ui/UICanvas.hpp | 28 ++++++ src/dawn/display/pass/RenderPass.hpp | 1 + src/dawn/ui/CMakeLists.txt | 10 ++ src/dawn/ui/UIAlign.hpp | 13 +++ src/dawn/ui/UIComponent.cpp | 37 +++++++ src/dawn/ui/UIComponent.hpp | 30 ++++++ src/dawn/ui/UIQuad.hpp | 34 +++++++ src/dawn/ui/UIRectangle.cpp | 24 +++++ src/dawn/ui/UIRectangle.hpp | 22 ++++ src/dawnhelloworld/scene/HelloWorldScene.cpp | 36 ++++--- src/dawnopengl/display/shader/CMakeLists.txt | 1 + src/dawnopengl/display/shader/Shader.hpp | 31 ++++-- src/dawnopengl/display/shader/UIShader.cpp | 100 +++++++++++++++++++ src/dawnopengl/display/shader/UIShader.hpp | 26 +++++ 18 files changed, 447 insertions(+), 23 deletions(-) create mode 100644 src/dawn/component/ui/CMakeLists.txt create mode 100644 src/dawn/component/ui/UICanvas.cpp create mode 100644 src/dawn/component/ui/UICanvas.hpp create mode 100644 src/dawn/ui/CMakeLists.txt create mode 100644 src/dawn/ui/UIAlign.hpp create mode 100644 src/dawn/ui/UIComponent.cpp create mode 100644 src/dawn/ui/UIComponent.hpp create mode 100644 src/dawn/ui/UIQuad.hpp create mode 100644 src/dawn/ui/UIRectangle.cpp create mode 100644 src/dawn/ui/UIRectangle.hpp create mode 100644 src/dawnopengl/display/shader/UIShader.cpp create mode 100644 src/dawnopengl/display/shader/UIShader.hpp diff --git a/src/dawn/CMakeLists.txt b/src/dawn/CMakeLists.txt index e20f8360..e6617171 100644 --- a/src/dawn/CMakeLists.txt +++ b/src/dawn/CMakeLists.txt @@ -35,6 +35,7 @@ add_subdirectory(scene) # add_subdirectory(state) add_subdirectory(time) add_subdirectory(util) +add_subdirectory(ui) # Definitions # target_compile_definitions(${DAWN_TARGET_NAME} diff --git a/src/dawn/component/CMakeLists.txt b/src/dawn/component/CMakeLists.txt index 8e276b0f..65820b61 100644 --- a/src/dawn/component/CMakeLists.txt +++ b/src/dawn/component/CMakeLists.txt @@ -9,4 +9,5 @@ target_sources(${DAWN_TARGET_NAME} ) # 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/component/ui/CMakeLists.txt b/src/dawn/component/ui/CMakeLists.txt new file mode 100644 index 00000000..6cadd54f --- /dev/null +++ b/src/dawn/component/ui/CMakeLists.txt @@ -0,0 +1,9 @@ +# Copyright (c) 2023 Dominic Masters +# +# This software is released under the MIT License. +# https://opensource.org/licenses/MIT + +target_sources(${DAWN_TARGET_NAME} + PRIVATE + UICanvas.cpp +) \ No newline at end of file diff --git a/src/dawn/component/ui/UICanvas.cpp b/src/dawn/component/ui/UICanvas.cpp new file mode 100644 index 00000000..ce8cfde9 --- /dev/null +++ b/src/dawn/component/ui/UICanvas.cpp @@ -0,0 +1,64 @@ +// Copyright (c) 2023 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#include "UICanvas.hpp" +#include "display/pass/RenderPass.hpp" +#include "display/shader/UIShader.hpp" + +#include "display/mesh/QuadMesh.hpp" + +using namespace Dawn; + +void UICanvas::onInit() { + +} + +void UICanvas::onDispose() { + +} + +std::vector> UICanvas::getPasses( + struct RenderPassContext &ctx +) { + std::vector> passes; + + auto selfTransform = this->getItem()->getWorldTransform(); + + auto mesh = std::make_shared(); + mesh->createBuffers(QUAD_VERTICE_COUNT, QUAD_INDICE_COUNT); + QuadMesh::buffer(mesh, glm::vec4(0, 0, 32, 32), glm::vec4(0, 0, 1, 1), 0, 0); + UIShaderData data = { + .projection = ctx.camera->getProjection(), + .view = ctx.camera->getItem()->getWorldTransform(), + .model = selfTransform + }; + + data.colors[0] = COLOR_WHITE; + data.colors[1] = COLOR_RED; + data.colors[2] = COLOR_GREEN; + data.colors[3] = COLOR_BLUE; + + auto pass = createRenderPass( + std::ref(*this), + data, + std::unordered_map>(), + mesh, + MeshDrawMode::TRIANGLES, + 0, -1 + ); + passes.push_back(pass); + + auto itComponents = components.begin(); + while(itComponents != components.end()) { + auto component = *itComponents; + + // Get this components' quads. + auto quads = component->getQuads(selfTransform); + + ++itComponents; + } + + return passes; +} \ No newline at end of file diff --git a/src/dawn/component/ui/UICanvas.hpp b/src/dawn/component/ui/UICanvas.hpp new file mode 100644 index 00000000..1e75fa69 --- /dev/null +++ b/src/dawn/component/ui/UICanvas.hpp @@ -0,0 +1,28 @@ +// Copyright (c) 2023 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#pragma once +#include "scene/SceneItem.hpp" +#include "component/display/IRenderableComponent.hpp" +#include "ui/UIComponent.hpp" + +namespace Dawn { + class UICanvas : + public SceneComponent, + public IRenderableComponent + { + protected: + virtual void onInit() override; + virtual void onDispose() override; + + public: + std::vector> components; + + + std::vector> getPasses( + struct RenderPassContext &ctx + ) override; + }; +} \ No newline at end of file diff --git a/src/dawn/display/pass/RenderPass.hpp b/src/dawn/display/pass/RenderPass.hpp index 82bac4c0..746c0136 100644 --- a/src/dawn/display/pass/RenderPass.hpp +++ b/src/dawn/display/pass/RenderPass.hpp @@ -4,6 +4,7 @@ // https://opensource.org/licenses/MIT #pragma once +#include "game/Game.hpp" #include "display/pass/IRenderPass.hpp" #include "display/shader/Shader.hpp" #include "display/Texture.hpp" diff --git a/src/dawn/ui/CMakeLists.txt b/src/dawn/ui/CMakeLists.txt new file mode 100644 index 00000000..c5a485e0 --- /dev/null +++ b/src/dawn/ui/CMakeLists.txt @@ -0,0 +1,10 @@ +# Copyright (c) 2023 Dominic Masters +# +# This software is released under the MIT License. +# https://opensource.org/licenses/MIT + +target_sources(${DAWN_TARGET_NAME} + PRIVATE + UIComponent.cpp + UIRectangle.cpp +) \ No newline at end of file diff --git a/src/dawn/ui/UIAlign.hpp b/src/dawn/ui/UIAlign.hpp new file mode 100644 index 00000000..e3a8de5c --- /dev/null +++ b/src/dawn/ui/UIAlign.hpp @@ -0,0 +1,13 @@ +// Copyright (c) 2023 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#pragma once +#include "dawnlibs.hpp" + +namespace Dawn { + struct UIAlign { + glm::vec2 position; + }; +} \ 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..9e3fc14d --- /dev/null +++ b/src/dawn/ui/UIComponent.cpp @@ -0,0 +1,37 @@ +// Copyright (c) 2023 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#include "UIComponent.hpp" + +using namespace Dawn; + +std::vector> UIComponent::getChildren() { + return {}; +} + +std::vector UIComponent::getQuads( + const glm::mat4 parent +) { + // Get self transform + glm::mat4 transform = glm::translate( + glm::mat4(1.0f), glm::vec3(position, 0.0f) + ); + + // Add parent transform + transform = parent * transform; + + // Get self quads and insert new transform. + std::vector quads; + auto selfQuads = this->getSelfQuads(transform); + + // Get children + auto children = getChildren(); + for(auto &c : children) { + auto childQuads = c->getQuads(transform); + quads.insert(quads.end(), childQuads.begin(), childQuads.end()); + } + + return quads; +} \ 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..c4b86877 --- /dev/null +++ b/src/dawn/ui/UIComponent.hpp @@ -0,0 +1,30 @@ +// Copyright (c) 2023 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#pragma once +#include "ui/UIAlign.hpp" +#include "ui/UIQuad.hpp" + +namespace Dawn { + class UICanvas; + + class UIComponent { + protected: + virtual std::vector getSelfQuads( + const glm::mat4 transform + ) = 0; + + virtual std::vector> getChildren(); + + std::vector getQuads( + const glm::mat4 parent + ); + + public: + glm::vec2 position; + + friend class UICanvas; + }; +} \ No newline at end of file diff --git a/src/dawn/ui/UIQuad.hpp b/src/dawn/ui/UIQuad.hpp new file mode 100644 index 00000000..5b727609 --- /dev/null +++ b/src/dawn/ui/UIQuad.hpp @@ -0,0 +1,34 @@ +// Copyright (c) 2023 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#pragma once +#include "display/Color.hpp" +#include "display/Texture.hpp" + +namespace Dawn { + struct UIQuad { + glm::mat4 transform; + glm::vec4 quad; + glm::vec4 uv; + struct Color color; + std::shared_ptr texture; + + UIQuad( + const glm::mat4 transform, + const glm::vec4 quad, + const glm::vec4 uv, + const struct Color color, + const std::shared_ptr texture + ) : + transform(transform), + quad(quad), + uv(uv), + color(color), + texture(texture) + { + + } + }; +} \ No newline at end of file diff --git a/src/dawn/ui/UIRectangle.cpp b/src/dawn/ui/UIRectangle.cpp new file mode 100644 index 00000000..b4fa3e8b --- /dev/null +++ b/src/dawn/ui/UIRectangle.cpp @@ -0,0 +1,24 @@ +// Copyright (c) 2023 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#include "UIRectangle.hpp" + +using namespace Dawn; + +std::vector UIRectangle::getSelfQuads( + const glm::mat4 transform +) { + std::vector quads; + + quads.push_back(UIQuad( + transform, + glm::vec4(0,0,size.x,size.y), + uv, + color, + texture + )); + + return quads; +} \ No newline at end of file diff --git a/src/dawn/ui/UIRectangle.hpp b/src/dawn/ui/UIRectangle.hpp new file mode 100644 index 00000000..826bba31 --- /dev/null +++ b/src/dawn/ui/UIRectangle.hpp @@ -0,0 +1,22 @@ +// Copyright (c) 2023 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#pragma once +#include "ui/UIComponent.hpp" + +namespace Dawn { + class UIRectangle final : public UIComponent { + protected: + std::vector getSelfQuads( + const glm::mat4 transform + ) override; + + public: + struct Color color = COLOR_WHITE; + std::shared_ptr texture = nullptr; + glm::vec2 size = glm::vec2(32, 32); + glm::vec4 uv = glm::vec4(0,0,1,1); + }; +} \ No newline at end of file diff --git a/src/dawnhelloworld/scene/HelloWorldScene.cpp b/src/dawnhelloworld/scene/HelloWorldScene.cpp index 0fea2832..87553782 100644 --- a/src/dawnhelloworld/scene/HelloWorldScene.cpp +++ b/src/dawnhelloworld/scene/HelloWorldScene.cpp @@ -10,6 +10,9 @@ #include "component/display/material/SimpleTexturedMaterial.hpp" #include "display/mesh/QuadMesh.hpp" +#include "component/ui/UICanvas.hpp" +#include "ui/UIRectangle.hpp" + #include #include FT_FREETYPE_H @@ -28,20 +31,27 @@ void Dawn::helloWorldScene(Scene &s) { auto camera = cameraItem->addComponent(); cameraItem->lookAt({ 120, 120, 120 }, { 0, 0, 0 }, { 0, 1, 0 }); - auto quad = s.createSceneItem(); - auto quadMesh = std::make_shared(); + // auto quad = s.createSceneItem(); + // auto quadMesh = std::make_shared(); - glm::vec2 position = { 0, 0 }; - glm::vec2 size = texture->bufferStringToMesh( - quadMesh, - L"Hello World!", - position, - true - ); + // glm::vec2 position = { 0, 0 }; + // glm::vec2 size = texture->bufferStringToMesh( + // quadMesh, + // L"Hello World!", + // position, + // true + // ); - auto quadRenderer = quad->addComponent(); - quadRenderer->mesh = quadMesh; + // auto quadRenderer = quad->addComponent(); + // quadRenderer->mesh = quadMesh; - auto quadMaterial = quad->addComponent(); - quadMaterial->setTexture(texture->texture); + // auto quadMaterial = quad->addComponent(); + // quadMaterial->setTexture(texture->texture); + + + auto uiCanvasItem = s.createSceneItem(); + auto uiCanvas = uiCanvasItem->addComponent(); + + auto rect = std::make_shared(); + uiCanvas->components.push_back(rect); } \ No newline at end of file diff --git a/src/dawnopengl/display/shader/CMakeLists.txt b/src/dawnopengl/display/shader/CMakeLists.txt index 8a2f6769..c73ac167 100644 --- a/src/dawnopengl/display/shader/CMakeLists.txt +++ b/src/dawnopengl/display/shader/CMakeLists.txt @@ -9,4 +9,5 @@ target_sources(${DAWN_TARGET_NAME} Shader.cpp ShaderStage.cpp SimpleTexturedShader.cpp + UIShader.cpp ) \ No newline at end of file diff --git a/src/dawnopengl/display/shader/Shader.hpp b/src/dawnopengl/display/shader/Shader.hpp index a3a0e58e..791c18b3 100644 --- a/src/dawnopengl/display/shader/Shader.hpp +++ b/src/dawnopengl/display/shader/Shader.hpp @@ -22,6 +22,7 @@ namespace Dawn { std::string name; size_t offset; enum ShaderParameterType type; + int32_t count; GLint location = -1; @@ -33,6 +34,19 @@ namespace Dawn { this->name = name; this->offset = (size_t)offset; this->type = type; + this->count = 1; + } + + ShaderOpenGLParameter( + const std::string &name, + const void *offset, + const enum ShaderParameterType type, + const int32_t count + ) { + this->name = name; + this->offset = (size_t)offset; + this->type = type; + this->count = count; } }; @@ -136,6 +150,9 @@ namespace Dawn { switch(param.type) { case ShaderParameterType::MAT4: { glm::mat4 *matrix = (glm::mat4 *)value; + if(param.count != 1) { + assertUnreachable("I haven't implemented multiple mat4s"); + } glUniformMatrix4fv( param.location, 1, GL_FALSE, glm::value_ptr(*matrix) ); @@ -144,25 +161,21 @@ namespace Dawn { case ShaderParameterType::COLOR: { auto color = (Color *)value; - glUniform4f( + glUniform4fv( param.location, - color->r, - color->g, - color->b, - color->a + param.count, + (GLfloat*)value ); break; } case ShaderParameterType::BOOLEAN: { - auto boolean = (bool_t *)value; - glUniform1i(param.location, *boolean ? 1 : 0); + glUniform1iv(param.location, param.count, (GLint*)value); break; } case ShaderParameterType::TEXTURE: { - textureslot_t texture = *((textureslot_t*)value); - glUniform1i(param.location, texture); + glUniform1iv(param.location, param.count, (GLint*)value); break; } diff --git a/src/dawnopengl/display/shader/UIShader.cpp b/src/dawnopengl/display/shader/UIShader.cpp new file mode 100644 index 00000000..a2d33874 --- /dev/null +++ b/src/dawnopengl/display/shader/UIShader.cpp @@ -0,0 +1,100 @@ +// Copyright (c) 2023 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#include "display/shader/UIShader.hpp" + +using namespace Dawn; + +void UIShader::getStages( + const enum ShaderOpenGLVariant variant, + const struct UIShaderData *rel, + std::vector> &stages, + std::vector ¶meters +) { + // Stages + std::shared_ptr vertex; + std::shared_ptr fragment; + + switch(variant) { + case ShaderOpenGLVariant::GLSL_330_CORE: + vertex = std::make_shared( + ShaderStageType::VERTEX, + "#version 330 core\n" + "layout (location = 0) in vec3 aPos;\n" + "layout (location = 1) in vec2 aTexCoord;\n" + "uniform mat4 u_Projection;\n" + "uniform mat4 u_View;\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 = std::make_shared( + ShaderStageType::FRAGMENT, + "#version 330 core\n" + "in vec2 o_TextCoord;\n" + "uniform vec4 u_Color[4];\n" + "out vec4 o_Color;\n" + "void main() {\n" + "o_Color = u_Color[2];\n" + "}\n" + ); + break; + + default: + assertUnreachable("Unsupported ShaderOpenGLVariant"); + } + + // Add stages + stages.push_back(vertex); + stages.push_back(fragment); + + // Parameters + parameters.push_back(ShaderOpenGLParameter( + "u_Projection", + &rel->projection, + ShaderParameterType::MAT4 + )); + + parameters.push_back(ShaderOpenGLParameter( + "u_View", + &rel->view, + ShaderParameterType::MAT4 + )); + + parameters.push_back(ShaderOpenGLParameter( + "u_Model", + &rel->model, + ShaderParameterType::MAT4 + )); + + parameters.push_back(ShaderOpenGLParameter( + "u_Color", + &rel->colors, + ShaderParameterType::COLOR, + 4 + )); + + // parameters.push_back(ShaderOpenGLParameter( + // "u_Color", + // &rel->color, + // ShaderParameterType::COLOR + // )); + + // parameters.push_back(ShaderOpenGLParameter( + // "u_HasTexture", + // &rel->hasTexture, + // ShaderParameterType::BOOLEAN + // )); + + // parameters.push_back(ShaderOpenGLParameter( + // "u_Texture", + // &rel->texture, + // ShaderParameterType::TEXTURE + // )); +} \ No newline at end of file diff --git a/src/dawnopengl/display/shader/UIShader.hpp b/src/dawnopengl/display/shader/UIShader.hpp new file mode 100644 index 00000000..a664f192 --- /dev/null +++ b/src/dawnopengl/display/shader/UIShader.hpp @@ -0,0 +1,26 @@ +// Copyright (c) 2023 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#pragma once +#include "display/shader/Shader.hpp" + +namespace Dawn { + struct UIShaderData { + glm::mat4 projection; + glm::mat4 view; + glm::mat4 model; + struct Color colors[4]; + }; + + class UIShader : public Shader { + protected: + void getStages( + const enum ShaderOpenGLVariant variant, + const struct UIShaderData *rel, + std::vector> &stages, + std::vector ¶meters + ) override; + }; +} \ No newline at end of file