diff --git a/CMakeLists.txt b/CMakeLists.txt index 408214d..134f640 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,10 @@ target_include_directories(glad PUBLIC lib/glad/include ) +find_package(Freetype REQUIRED) +include_directories(${FREETYPE_INCLUDE_DIRS}) + + add_executable(Dicewars_Siedler src/main.cpp src/engine/core/Window.cpp src/engine/core/Window.h @@ -126,6 +130,18 @@ add_executable(Dicewars_Siedler src/main.cpp src/engine/core/gui/uiMain/UiContainer.h src/engine/core/gui/uiComponent/UiImage.cpp src/engine/core/gui/uiComponent/UiImage.h + src/engine/core/gui/uiComponent/UiText.cpp + src/engine/core/gui/uiComponent/UiText.h + src/engine/core/gui/text/Font.cpp + src/engine/core/gui/text/Font.h + src/engine/core/gui/uiComponent/UiRenderBundle.cpp + src/engine/core/gui/uiComponent/UiRenderBundle.h + src/engine/renderer/shaders/TextShader.cpp + src/engine/renderer/shaders/TextShader.h + src/engine/renderer/TextRenderer.cpp + src/engine/renderer/TextRenderer.h + src/engine/renderer/model/TextQuadModel.cpp + src/engine/renderer/model/TextQuadModel.h ) target_include_directories(Dicewars_Siedler PRIVATE @@ -140,4 +156,5 @@ target_link_libraries(Dicewars_Siedler glfw glad OpenGL::GL + ${FREETYPE_LIBRARIES} ) \ No newline at end of file diff --git a/assets/shaders/textFragmentShader.glsl b/assets/shaders/textFragmentShader.glsl new file mode 100644 index 0000000..60c4cfb --- /dev/null +++ b/assets/shaders/textFragmentShader.glsl @@ -0,0 +1,13 @@ +#version 400 core + +in vec2 pass_texCoords; + +out vec4 outColor; + +uniform sampler2D text; +uniform vec3 textColor; + +void main() { + float alpha = texture(text, pass_texCoords).r; + outColor = vec4(textColor, alpha); +} diff --git a/assets/shaders/textVertexShader.glsl b/assets/shaders/textVertexShader.glsl new file mode 100644 index 0000000..592542b --- /dev/null +++ b/assets/shaders/textVertexShader.glsl @@ -0,0 +1,12 @@ +#version 400 core + +layout(location = 0) in vec4 vertices; + +out vec2 pass_texCoords; + +uniform mat4 projectionMatrix; + +void main() { + gl_Position = projectionMatrix * vec4(vertices.x, vertices.y, 0.0, 1.0); + pass_texCoords = vec2(vertices.z, vertices.w); +} diff --git a/src/engine/core/gui/text/Font.cpp b/src/engine/core/gui/text/Font.cpp new file mode 100644 index 0000000..fa9ede2 --- /dev/null +++ b/src/engine/core/gui/text/Font.cpp @@ -0,0 +1,58 @@ +// +// Created by sebastian on 10.02.26. +// + +#include "Font.h" + +#include +#include + +Font::Font(const std::string &fontPath, unsigned int fontSize) { + if (FT_Init_FreeType(&ft)) throw std::runtime_error("Could not init FreeType"); + if (FT_New_Face(ft, fontPath.c_str(), 0, &face)) throw std::runtime_error("Failed to load font"); + + FT_Set_Pixel_Sizes(face, 0, fontSize); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // 1 byte per pixel + + for (unsigned char c = 0; c < 128; c++) { + if (FT_Load_Char(face, c, FT_LOAD_RENDER)) { + std::cerr << "Failed to load char: " << (int)c << "\n"; + continue; + } + + GLuint texture; + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, + face->glyph->bitmap.width, + face->glyph->bitmap.rows, + 0, GL_RED, GL_UNSIGNED_BYTE, + face->glyph->bitmap.buffer); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + Character character = { + texture, + {face->glyph->bitmap.width, face->glyph->bitmap.rows}, + {face->glyph->bitmap_left, face->glyph->bitmap_top}, + static_cast(face->glyph->advance.x) + }; + characters.insert({c, character}); + } + + FT_Done_Face(face); + FT_Done_FreeType(ft); +} + +Font::Character Font::getCharacter(char c) const { + unsigned char uc = static_cast(c); + auto it = characters.find(uc); + if (it != characters.end()) + return it->second; + else + throw std::runtime_error("Character not loaded: " + std::to_string(uc)); +} diff --git a/src/engine/core/gui/text/Font.h b/src/engine/core/gui/text/Font.h new file mode 100644 index 0000000..8c25c79 --- /dev/null +++ b/src/engine/core/gui/text/Font.h @@ -0,0 +1,38 @@ +// +// Created by sebastian on 10.02.26. +// + +#ifndef DICEWARS_SIEDLER_FONT_H +#define DICEWARS_SIEDLER_FONT_H +#include + +#include "glad/glad.h" +#include "glm/vec2.hpp" + +#include +#include + +#include FT_FREETYPE_H + +class Font { +public: + Font(const std::string& fontPath, unsigned int fontSize); + ~Font() = default; + + struct Character { + GLuint textureID; + glm::ivec2 size; + glm::ivec2 bearing; + unsigned int advance; + }; + + [[nodiscard]] Character getCharacter(char c) const; + +private: + FT_Library ft; + FT_Face face; + std::unordered_map characters; +}; + + +#endif //DICEWARS_SIEDLER_FONT_H \ No newline at end of file diff --git a/src/engine/core/gui/uiComponent/UiComponent.cpp b/src/engine/core/gui/uiComponent/UiComponent.cpp index 3affbfa..a6bc1cd 100644 --- a/src/engine/core/gui/uiComponent/UiComponent.cpp +++ b/src/engine/core/gui/uiComponent/UiComponent.cpp @@ -28,13 +28,13 @@ void UiComponent::update(float delta) { } } -void UiComponent::collectRenderData(std::vector &guiTextures) { +void UiComponent::collectRenderData(UiRenderBundle& uiRenderBundle) { if (!visible) return; - onCollectRenderData(guiTextures); + onCollectRenderData(uiRenderBundle); for (const auto &child : children) { - child->collectRenderData(guiTextures); + child->collectRenderData(uiRenderBundle); } } diff --git a/src/engine/core/gui/uiComponent/UiComponent.h b/src/engine/core/gui/uiComponent/UiComponent.h index 7f3cf53..97fc022 100644 --- a/src/engine/core/gui/uiComponent/UiComponent.h +++ b/src/engine/core/gui/uiComponent/UiComponent.h @@ -8,6 +8,7 @@ #include #include "UiPositioner.h" +#include "UiRenderBundle.h" #include "../../../renderer/model/GUITexture.h" @@ -19,7 +20,7 @@ public: void setVisible(bool visible); [[nodiscard]] bool isVisible() const; void update(float delta); - void collectRenderData(std::vector& guiTextures); + void collectRenderData(UiRenderBundle& uiRenderBundle); virtual bool isMouseOver(float mouseX, float mouseY); UiComponent* parent = nullptr; UiPositioner uiPositioner; @@ -30,7 +31,7 @@ protected: bool visible = true; virtual void onUpdate(float /*delta*/) {} - virtual void onCollectRenderData(std::vector&) {} + virtual void onCollectRenderData(UiRenderBundle& uiRenderBundle) {} }; diff --git a/src/engine/core/gui/uiComponent/UiImage.cpp b/src/engine/core/gui/uiComponent/UiImage.cpp index eae240d..9047ae3 100644 --- a/src/engine/core/gui/uiComponent/UiImage.cpp +++ b/src/engine/core/gui/uiComponent/UiImage.cpp @@ -4,8 +4,9 @@ #include "UiImage.h" -void UiImage::onCollectRenderData(std::vector &gui_textures) { +void UiImage::onCollectRenderData(UiRenderBundle& renderBundle) { if (!visible) return; Dimensions dims = uiPositioner.screenSpace; - gui_textures.emplace_back(textureID, glm::vec2(dims.x, dims.y), glm::vec2(dims.width, dims.height)); + GUITexture texture(textureID, glm::vec2(dims.x, dims.y), glm::vec2(dims.width, dims.height)); + renderBundle.addGUITexture(std::make_shared(texture));; } diff --git a/src/engine/core/gui/uiComponent/UiImage.h b/src/engine/core/gui/uiComponent/UiImage.h index d51b7fe..98b0a44 100644 --- a/src/engine/core/gui/uiComponent/UiImage.h +++ b/src/engine/core/gui/uiComponent/UiImage.h @@ -15,7 +15,7 @@ public: }; protected: - void onCollectRenderData(std::vector &) override; + void onCollectRenderData(UiRenderBundle& renderBundle) override; private: GLuint textureID; diff --git a/src/engine/core/gui/uiComponent/UiRenderBundle.cpp b/src/engine/core/gui/uiComponent/UiRenderBundle.cpp new file mode 100644 index 0000000..168d15d --- /dev/null +++ b/src/engine/core/gui/uiComponent/UiRenderBundle.cpp @@ -0,0 +1,5 @@ +// +// Created by sebastian on 10.02.26. +// + +#include "UiRenderBundle.h" \ No newline at end of file diff --git a/src/engine/core/gui/uiComponent/UiRenderBundle.h b/src/engine/core/gui/uiComponent/UiRenderBundle.h new file mode 100644 index 0000000..409611c --- /dev/null +++ b/src/engine/core/gui/uiComponent/UiRenderBundle.h @@ -0,0 +1,40 @@ +// +// Created by sebastian on 10.02.26. +// + +#ifndef DICEWARS_SIEDLER_UIRENDERBUNDLE_H +#define DICEWARS_SIEDLER_UIRENDERBUNDLE_H +#include +#include + +class UiText; +#include "../../../renderer/model/GUITexture.h" + + +class UiRenderBundle { +public: + void addText(UiText* text) { + texts.push_back(text); + } + + void addGUITexture(const std::shared_ptr& guiTexture) { + guiImages.push_back(guiTexture); + } + + std::vector> getGUITextures() { + return guiImages; + } + + std::vector getTexts() { + return texts; + } + +private: + std::vector> guiImages; + std::vector texts; + + +}; + + +#endif //DICEWARS_SIEDLER_UIRENDERBUNDLE_H \ No newline at end of file diff --git a/src/engine/core/gui/uiComponent/UiText.cpp b/src/engine/core/gui/uiComponent/UiText.cpp new file mode 100644 index 0000000..7a17bca --- /dev/null +++ b/src/engine/core/gui/uiComponent/UiText.cpp @@ -0,0 +1,20 @@ +// +// Created by sebastian on 10.02.26. +// + +#include "UiText.h" + +#include + +#include "../text/Font.h" + +UiText::UiText(Font &font, std::string text, const glm::vec2 &relativePos, const glm::vec2& relativeSize) : font(font), text(std::move(text)) { + uiPositioner.setRelativePos(relativePos); + uiPositioner.setRelativeSize(relativeSize); +} + +void UiText::onCollectRenderData(UiRenderBundle& ui_render_bundle) { + if (!visible) return; + + ui_render_bundle.addText(this); +} diff --git a/src/engine/core/gui/uiComponent/UiText.h b/src/engine/core/gui/uiComponent/UiText.h new file mode 100644 index 0000000..d39f24a --- /dev/null +++ b/src/engine/core/gui/uiComponent/UiText.h @@ -0,0 +1,32 @@ +// +// Created by sebastian on 10.02.26. +// + +#ifndef DICEWARS_SIEDLER_UITEXT_H +#define DICEWARS_SIEDLER_UITEXT_H +#include "UiComponent.h" +#include "UiRenderBundle.h" + +class Font; + + +class UiText : public UiComponent, public std::enable_shared_from_this { +public: + UiText(Font& font, std::string text, const glm::vec2& relativePos, const glm::vec2& relativeSize); + void setText(const std::string& text); + + [[nodiscard]] const Font& getFont() const { return font; } + + [[nodiscard]] std::string getText() const { + return text; + } + +protected: + void onCollectRenderData(UiRenderBundle &uiRenderBundle) override; +private: + std::string text; + Font& font; +}; + + +#endif //DICEWARS_SIEDLER_UITEXT_H \ No newline at end of file diff --git a/src/engine/core/gui/uiMain/UiContainer.cpp b/src/engine/core/gui/uiMain/UiContainer.cpp index c664f84..ef263b8 100644 --- a/src/engine/core/gui/uiMain/UiContainer.cpp +++ b/src/engine/core/gui/uiMain/UiContainer.cpp @@ -19,7 +19,7 @@ void UiContainer::onUpdate(float x) { } -void UiContainer::onCollectRenderData(std::vector &gui_textures) { +void UiContainer::onCollectRenderData(UiRenderBundle& render_bundle) { } diff --git a/src/engine/core/gui/uiMain/UiContainer.h b/src/engine/core/gui/uiMain/UiContainer.h index b7e62b5..486fb22 100644 --- a/src/engine/core/gui/uiMain/UiContainer.h +++ b/src/engine/core/gui/uiMain/UiContainer.h @@ -12,7 +12,7 @@ public: UiContainer(); bool isMouseOver(float mouseX, float mouseY) override; void onUpdate(float) override; - void onCollectRenderData(std::vector &) override; + void onCollectRenderData(UiRenderBundle& renderBundle) override; }; diff --git a/src/engine/renderer/GUIRenderer.cpp b/src/engine/renderer/GUIRenderer.cpp index f0e3926..417ac53 100644 --- a/src/engine/renderer/GUIRenderer.cpp +++ b/src/engine/renderer/GUIRenderer.cpp @@ -6,6 +6,7 @@ #include +#include "../core/gui/uiComponent/UiRenderBundle.h" #include "../toolbox/MathUtils.h" #include "loader/Loader.h" @@ -15,20 +16,25 @@ GUIRenderer::GUIRenderer(Loader &loader) { rawModel = std::make_unique(model); } -void GUIRenderer::render(const std::vector& guiTextures) { +void GUIRenderer::render(std::vector>& gui_textures) { guiShader.start(); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_DEPTH_TEST); glBindVertexArray(rawModel->vaoID); glEnableVertexAttribArray(0); - for (GUITexture texture : guiTextures) { + for (auto texture : gui_textures) { glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, texture.getTextureID()); - glm::mat4 transformationMatrix = MathUtils::createTransformationMatrix(texture.getPosition(), texture.getScale()); + glBindTexture(GL_TEXTURE_2D, texture->getTextureID()); + glm::mat4 transformationMatrix = MathUtils::createTransformationMatrix(texture->getPosition(), texture->getScale()); guiShader.loadTransformationMatrix(transformationMatrix); glDrawArrays(GL_TRIANGLE_STRIP, 0, rawModel->vertexCount); } //render glDisableVertexAttribArray(0); glBindVertexArray(0); + glEnable(GL_DEPTH_TEST); + glDisable(GL_BLEND); guiShader.stop(); } diff --git a/src/engine/renderer/GUIRenderer.h b/src/engine/renderer/GUIRenderer.h index e48e9a7..7de879b 100644 --- a/src/engine/renderer/GUIRenderer.h +++ b/src/engine/renderer/GUIRenderer.h @@ -7,6 +7,7 @@ #include #include +#include "../core/gui/uiComponent/UiRenderBundle.h" #include "model/GUITexture.h" #include "model/RawModel.h" #include "shaders/GUIShader.h" @@ -20,7 +21,7 @@ private: public: GUIShader guiShader; explicit GUIRenderer(Loader& loader); - void render(const std::vector &guiTextures); + void render(std::vector> &gui_textures); void cleanUp(); }; diff --git a/src/engine/renderer/TextRenderer.cpp b/src/engine/renderer/TextRenderer.cpp new file mode 100644 index 0000000..d6dfb74 --- /dev/null +++ b/src/engine/renderer/TextRenderer.cpp @@ -0,0 +1,79 @@ +// +// Created by sebastian on 11.02.26. +// + +#include "TextRenderer.h" + +#include "../core/Application.h" +#include "../core/Window.h" +#include "../core/gui/text/Font.h" +#include "glm/ext/matrix_clip_space.hpp" + +void TextRenderer::renderTexts(const std::vector &textsToRender) { + shader.start(); + shader.loadProjectionMatrix(calculateOrthographicProjectionMatrix()); + glEnable(GL_BLEND); + glDisable(GL_DEPTH_TEST); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + for (const auto &text : textsToRender) { + renderText(*text); + } + glEnable(GL_DEPTH_TEST); + glDisable(GL_BLEND); +} + +void TextRenderer::renderText(const UiText &textToRender) const { + const Dimensions& d = textToRender.uiPositioner.screenSpace; + + const Font& font = textToRender.getFont(); + const std::string& text = textToRender.getText(); + + float x = d.x; + float y = d.y; + + float scale = 1.0f; + + for (char c : text) { + const Font::Character& ch = font.getCharacter(c); + + float xpos = x + static_cast(ch.bearing.x) * scale; + float ypos = y - static_cast(ch.size.y - ch.bearing.y) * scale; + + float w = static_cast(ch.size.x) * scale; + float h = static_cast(ch.size.y) * scale; + + float vertices[6][4] = { + { xpos, ypos + h, 0.0f, 0.0f }, + { xpos, ypos, 0.0f, 1.0f }, + { xpos + w, ypos, 1.0f, 1.0f }, + + { xpos, ypos + h, 0.0f, 0.0f }, + { xpos + w, ypos, 1.0f, 1.0f }, + { xpos + w, ypos + h, 1.0f, 0.0f } + }; + + glBindVertexArray(textModel.vaoID); + glEnableVertexAttribArray(0); + + glBindTexture(GL_TEXTURE_2D, ch.textureID); + + + glBindBuffer(GL_ARRAY_BUFFER, textModel.vboID); + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); + + glDrawArrays(GL_TRIANGLES, 0, 6); + + x+= static_cast(ch.advance >> 6) * scale; + + glBindVertexArray(0); + glDisableVertexAttribArray(0); + } +} + +glm::mat4 TextRenderer::calculateOrthographicProjectionMatrix() { + const auto screenWidth = static_cast(Application::getInstance().getWindow().GetWidth()); + const auto screenHeight = static_cast(Application::getInstance().getWindow().GetHeight()); + + const glm::mat4 projectionMat = glm::ortho(0.f, screenWidth, 0.0f, screenHeight); + return projectionMat; +} diff --git a/src/engine/renderer/TextRenderer.h b/src/engine/renderer/TextRenderer.h new file mode 100644 index 0000000..aa60040 --- /dev/null +++ b/src/engine/renderer/TextRenderer.h @@ -0,0 +1,28 @@ +// +// Created by sebastian on 11.02.26. +// + +#ifndef DICEWARS_SIEDLER_TEXTRENDERER_H +#define DICEWARS_SIEDLER_TEXTRENDERER_H +#include + +#include "../core/gui/uiComponent/UiText.h" +#include "loader/Loader.h" +#include "model/RawModel.h" +#include "model/TextQuadModel.h" +#include "shaders/TextShader.h" + + +class TextRenderer { +public: + TextRenderer() : textModel(Loader::instance().loadTextModel()) {}; + void renderTexts(const std::vector &textsToRender); + void renderText(const UiText &textToRender) const; +private: + TextShader shader; + TextQuadModel textModel; + static glm::mat4 calculateOrthographicProjectionMatrix(); +}; + + +#endif //DICEWARS_SIEDLER_TEXTRENDERER_H \ No newline at end of file diff --git a/src/engine/renderer/loader/Loader.cpp b/src/engine/renderer/loader/Loader.cpp index 4faf0c8..9d44df6 100644 --- a/src/engine/renderer/loader/Loader.cpp +++ b/src/engine/renderer/loader/Loader.cpp @@ -51,6 +51,24 @@ ModelTexture Loader::loadTextureFromFile(const std::string &path) { return ModelTexture(loadTexture(path)); } +TextQuadModel Loader::loadTextModel() { + GLuint vaoID = createVAO(); + GLuint vboID; + glGenBuffers(1, &vboID); + vboIDs.push_back(vboID); + + glBindBuffer(GL_ARRAY_BUFFER, vboID); + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 6 * 4, nullptr, GL_DYNAMIC_DRAW); + + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 4 , GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); + + return {vaoID, vboID, 4}; +} + GLuint Loader::loadTexture(const std::string &path) { Texture2D texture = TextureLoader::loadTexture(path); textureIDs.push_back(texture.id); diff --git a/src/engine/renderer/loader/Loader.h b/src/engine/renderer/loader/Loader.h index 059b583..dc6652d 100644 --- a/src/engine/renderer/loader/Loader.h +++ b/src/engine/renderer/loader/Loader.h @@ -8,6 +8,7 @@ #include #include "../model/RawModel.h" +#include "../model/TextQuadModel.h" #include "../textures/ModelTexture.h" #include "glad/glad.h" @@ -23,6 +24,7 @@ public: void cleanUp(); ModelTexture loadTextureFromFile(const std::string& path); + TextQuadModel loadTextModel(); private: GLuint createVAO(); GLuint loadTexture(const std::string &path); diff --git a/src/engine/renderer/model/TextQuadModel.cpp b/src/engine/renderer/model/TextQuadModel.cpp new file mode 100644 index 0000000..7785c8a --- /dev/null +++ b/src/engine/renderer/model/TextQuadModel.cpp @@ -0,0 +1,5 @@ +// +// Created by sebastian on 11.02.26. +// + +#include "TextQuadModel.h" \ No newline at end of file diff --git a/src/engine/renderer/model/TextQuadModel.h b/src/engine/renderer/model/TextQuadModel.h new file mode 100644 index 0000000..1a7712e --- /dev/null +++ b/src/engine/renderer/model/TextQuadModel.h @@ -0,0 +1,19 @@ +// +// Created by sebastian on 11.02.26. +// + +#ifndef DICEWARS_SIEDLER_TEXTQUADMODEL_H +#define DICEWARS_SIEDLER_TEXTQUADMODEL_H +#include "glad/glad.h" + + +class TextQuadModel { +public: + TextQuadModel(GLuint vaoID, GLuint vboID, int vertexCount) : vaoID(vaoID), vboID(vboID), vertexCount(vertexCount) {}; + GLuint vaoID; + GLuint vboID; + int vertexCount; +}; + + +#endif //DICEWARS_SIEDLER_TEXTQUADMODEL_H \ No newline at end of file diff --git a/src/engine/renderer/shaders/TextShader.cpp b/src/engine/renderer/shaders/TextShader.cpp new file mode 100644 index 0000000..c830270 --- /dev/null +++ b/src/engine/renderer/shaders/TextShader.cpp @@ -0,0 +1,17 @@ +// +// Created by sebastian on 11.02.26. +// + +#include "TextShader.h" + +void TextShader::loadProjectionMatrix(glm::mat4 matrix) { + ShaderProgram::loadMatrix(location_projectionMatrix, matrix); +} + +void TextShader::getAllUniformLocations() { + location_projectionMatrix = ShaderProgram::getUniformLocation("projectionMatrix"); +} + +void TextShader::bindAttributes() const { + ShaderProgram::bindAttribute(0, "vertices"); +} diff --git a/src/engine/renderer/shaders/TextShader.h b/src/engine/renderer/shaders/TextShader.h new file mode 100644 index 0000000..ebefd91 --- /dev/null +++ b/src/engine/renderer/shaders/TextShader.h @@ -0,0 +1,29 @@ +// +// Created by sebastian on 11.02.26. +// + +#ifndef DICEWARS_SIEDLER_TEXTSHADER_H +#define DICEWARS_SIEDLER_TEXTSHADER_H +#include "ShaderProgram.h" + + +class TextShader : public ShaderProgram { +public : + TextShader() : ShaderProgram(VERTEX_FILE, FRAGMENT_FILE) { + TextShader::bindAttributes(); + TextShader::getAllUniformLocations(); + } + void loadProjectionMatrix(glm::mat4 matrix); + +protected: + void getAllUniformLocations() override; + void bindAttributes() const override; +private: + inline static const std::string VERTEX_FILE = "assets/shaders/textVertexShader.glsl"; + inline static const std::string FRAGMENT_FILE = "assets/shaders/textFragmentShader.glsl"; + + int location_projectionMatrix; +}; + + +#endif //DICEWARS_SIEDLER_TEXTSHADER_H \ No newline at end of file diff --git a/src/engine/toolbox/MathUtils.h b/src/engine/toolbox/MathUtils.h index 9e6e392..6e2d6e6 100644 --- a/src/engine/toolbox/MathUtils.h +++ b/src/engine/toolbox/MathUtils.h @@ -42,6 +42,7 @@ namespace MathUtils { glm::vec3 up(0.0f, 1.0f, 0.0f); return glm::lookAt(pos, pos + front, up); } + } #endif //MATHUTILS_H diff --git a/src/game/UILayer.cpp b/src/game/UILayer.cpp index d69b36a..98dcfeb 100644 --- a/src/game/UILayer.cpp +++ b/src/game/UILayer.cpp @@ -4,13 +4,16 @@ #include "UILayer.h" +#include "../engine/core/gui/text/Font.h" #include "../engine/core/gui/uiComponent/UiImage.h" +#include "../engine/core/gui/uiComponent/UiText.h" #include "../engine/renderer/loader/Loader.h" #include "../engine/renderer/model/GUITexture.h" UILayer::UILayer() { Loader& loader = Loader::instance(); guiRenderer = std::make_unique(loader); + textRenderer = std::make_unique(); } void UILayer::onAttach() { @@ -25,17 +28,29 @@ void UILayer::onAttach() { glm::vec2(0.5f, 0.5f), glm::vec2(0.5f) ); rootContainer->addChild(std::move(image)); + + + Font myFont("/usr/share/fonts/TTF/DejaVuSans.ttf", 48); + font = std::make_unique(myFont); + auto text = std::make_unique(*font, "Hello World!", glm::vec2(0.5f, 0.5f), glm::vec2(0.3f, 0.1f)); + + rootContainer->addChild(std::move(text)); } void UILayer::onUpdate() { Layer::onUpdate(); - std::vector guiTextures; + UiRenderBundle renderBundle; if (rootContainer) { - rootContainer->collectRenderData(guiTextures); + rootContainer->collectRenderData(renderBundle); } - printf("Found UI Textures: %lu\n", guiTextures.size()); - guiRenderer->render(guiTextures); + auto guis = renderBundle.getGUITextures(); + guiRenderer->render(guis); + + auto texts = renderBundle.getTexts(); + + textRenderer->renderTexts(texts); + } void UILayer::onDetach() { diff --git a/src/game/UILayer.h b/src/game/UILayer.h index ab8d01a..1084f46 100644 --- a/src/game/UILayer.h +++ b/src/game/UILayer.h @@ -6,15 +6,18 @@ #define UILAYER_H #include +#include "../engine/core/gui/text/Font.h" #include "../engine/core/gui/uiMain/UiContainer.h" #include "../engine/layer/Layer.h" #include "../engine/renderer/GUIRenderer.h" +#include "../engine/renderer/TextRenderer.h" class UILayer : public Layer{ private: std::unique_ptr guiRenderer; - + std::unique_ptr textRenderer; + std::unique_ptr font; std::unique_ptr rootContainer; public: UILayer();