From 8df7cd23eabfd1569ec425288ad0229d8f10acac Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Mon, 9 Oct 2023 17:55:46 -0500 Subject: [PATCH] Added text alignment support. --- src/dawn/scene/components/ui/text/UILabel.cpp | 53 +++++++++++++++++++ src/dawn/scene/components/ui/text/UILabel.hpp | 2 + .../shader/ShaderParameterBufferTypes.hpp | 7 +++ .../display/shader/shaders/FontShader.cpp | 5 +- .../display/shader/shaders/FontShader.hpp | 1 + 5 files changed, 67 insertions(+), 1 deletion(-) diff --git a/src/dawn/scene/components/ui/text/UILabel.cpp b/src/dawn/scene/components/ui/text/UILabel.cpp index 6f9107ab..a9a3bc93 100644 --- a/src/dawn/scene/components/ui/text/UILabel.cpp +++ b/src/dawn/scene/components/ui/text/UILabel.cpp @@ -22,12 +22,65 @@ void UILabel::onStart() { this->shaderBuffer.init(); useEvent([&]{ + // TODO: I believe I only need to rebuffer here if maxWidth is not -1 this->rebufferQuads(this->texts); }, eventAlignmentUpdated); useEffect([&]{ this->rebufferQuads(this->texts); }, lineHeight); + + useEvent([&]{ + this->updateTextAlignments(); + }, eventTextChanged); + + useEffect([&]{ + this->updateTextAlignments(); + }, this->textAlign); +} + +void UILabel::updateTextAlignments() { + struct FontShaderBufferData data; + + switch(this->textAlign) { + case UI_LABEL_TEXT_ALIGN_LEFT: { + auto itLine = lines.begin(); + int32_t i = 0; + while(itLine != lines.end()) { + data.linePositions[i] = glm::vec2(0, 0); + ++itLine; + } + break; + } + + case UI_LABEL_TEXT_ALIGN_RIGHT: { + float_t widthBased = this->getWidth(); + auto itLine = lines.begin(); + int32_t i = 0; + while(itLine != lines.end()) { + data.linePositions[i] = glm::vec2(widthBased - itLine->width, 0); + ++itLine; + } + break; + } + + case UI_LABEL_TEXT_ALIGN_CENTER: { + float_t widthBased = this->getWidth(); + auto itLine = lines.begin(); + int32_t i = 0; + while(itLine != lines.end()) { + float_t x = (widthBased - itLine->width) / 2.0f; + data.linePositions[i] = glm::vec2(x, 0); + ++itLine; + } + break; + } + + default: + assertUnreachable("UILabel::updateTextAlignments: TextAlign invalid"); + } + + this->shaderBuffer.buffer(&data, &data.linePositions); } std::vector UILabel::getUIRenderPasses() { diff --git a/src/dawn/scene/components/ui/text/UILabel.hpp b/src/dawn/scene/components/ui/text/UILabel.hpp index 0e881fcc..8ca3a0bd 100644 --- a/src/dawn/scene/components/ui/text/UILabel.hpp +++ b/src/dawn/scene/components/ui/text/UILabel.hpp @@ -59,6 +59,8 @@ namespace Dawn { bool_t ignoreAlignmentUpdate = false; bool_t hasDecorations = false; + void updateTextAlignments(); + public: int32_t quadStart = 0; int32_t quadCount = -1; diff --git a/src/dawnopengl/display/shader/ShaderParameterBufferTypes.hpp b/src/dawnopengl/display/shader/ShaderParameterBufferTypes.hpp index 1d200a68..0f5e9b1b 100644 --- a/src/dawnopengl/display/shader/ShaderParameterBufferTypes.hpp +++ b/src/dawnopengl/display/shader/ShaderParameterBufferTypes.hpp @@ -43,5 +43,12 @@ #define SHADER_PARAMETER_BUFFER_MAT4(name) \ glm::mat4 name; +// VEC2 +#define SHADER_PARAMETER_BUFFER_VEC2(name) \ + glm::vec2 name; + +#define SHADER_PARAMETER_BUFFER_VEC2_ARRAY(name, size) \ + glm::vec2 name[size]; + // EOF Fix #define NOTHING "Fixes an error with EOF" \ No newline at end of file diff --git a/src/dawnopengl/display/shader/shaders/FontShader.cpp b/src/dawnopengl/display/shader/shaders/FontShader.cpp index 12b59379..7ef2dc0f 100644 --- a/src/dawnopengl/display/shader/shaders/FontShader.cpp +++ b/src/dawnopengl/display/shader/shaders/FontShader.cpp @@ -28,6 +28,7 @@ void FontShader::compile() { "layout (shared) uniform ub_Font {\n" "vec4 u_FontColors[" MACRO_STRINGIFY(FONT_SHADER_PARTS_MAX) "];\n" "int u_FontTextures[" MACRO_STRINGIFY(FONT_SHADER_PARTS_MAX) "];\n" + "vec2 u_FontLinePositions[" MACRO_STRINGIFY(FONT_SHADER_PARTS_MAX) "];\n" "int u_FontQuadMappings[" MACRO_STRINGIFY(FONT_SHADER_QUADS_MAX) "];\n" "};\n" @@ -37,10 +38,12 @@ void FontShader::compile() { "flat out int o_TextIndex;\n" "void main() {\n" - "gl_Position = u_Projection * u_View * u_Model * vec4(aPos.xy, 0, 1.0);\n" "o_TextCoord = vec2(aTexCoord.x, aTexCoord.y);\n" "int quadIndex = gl_VertexID / " MACRO_STRINGIFY(QUAD_VERTICE_COUNT) ";\n" "int partIndex = u_FontQuadMappings[quadIndex];\n" + "gl_Position = u_Projection * u_View * u_Model * (\n" + "vec4(aPos.xy, 0, 1.0) + vec4(u_FontLinePositions[partIndex], 0, 0)\n" + ");\n" "o_VertColor = u_FontColors[partIndex];\n" "o_TextIndex = u_FontTextures[partIndex];\n" "}", diff --git a/src/dawnopengl/display/shader/shaders/FontShader.hpp b/src/dawnopengl/display/shader/shaders/FontShader.hpp index 66eb90b0..0bcd5b4e 100644 --- a/src/dawnopengl/display/shader/shaders/FontShader.hpp +++ b/src/dawnopengl/display/shader/shaders/FontShader.hpp @@ -15,6 +15,7 @@ namespace Dawn { SHADER_PARAMETER_BUFFER_DEFINE(FontShaderBuffer, \ SHADER_PARAMETER_BUFFER_COLOR_ARRAY(colors, FONT_SHADER_PARTS_MAX); SHADER_PARAMETER_BUFFER_INTEGER_ARRAY(textures, FONT_SHADER_PARTS_MAX); + SHADER_PARAMETER_BUFFER_VEC2_ARRAY(linePositions, FONT_SHADER_PARTS_MAX); SHADER_PARAMETER_BUFFER_INTEGER_ARRAY(quadMappings, FONT_SHADER_QUADS_MAX); );