From 49e590f77d66fb8cd27b27db5ead9f8bdb3d2a79 Mon Sep 17 00:00:00 2001 From: mkuritsu Date: Wed, 13 Nov 2024 03:12:59 +0000 Subject: [PATCH] feat(ui): add UI text rendering --- CHANGELOG.md | 2 + engine/CMakeLists.txt | 50 +++++ .../assets/font/Robot-Regular.fontatlas.meta | 4 + engine/assets/font/Roboto-Regular.ttf | Bin 0 -> 168260 bytes engine/assets/font/Roboto-Regular.ttf.meta | 3 + .../font/RussoOne-Regular.fontatlas.meta | 4 + engine/assets/font/RussoOne-Regular.ttf | Bin 0 -> 37480 bytes engine/assets/font/RussoOne-Regular.ttf.meta | 3 + engine/assets/ui/text.fs | 36 +++ engine/assets/ui/text.fs.meta | 3 + engine/assets/ui/text.vs | 25 +++ engine/assets/ui/text.vs.meta | 3 + .../include/cubos/engine/font/atlas/atlas.hpp | 41 ++++ .../cubos/engine/font/atlas/bridge.hpp | 35 +++ .../include/cubos/engine/font/atlas/glyph.hpp | 30 +++ engine/include/cubos/engine/font/bridge.hpp | 29 +++ engine/include/cubos/engine/font/font.hpp | 42 ++++ engine/include/cubos/engine/font/plugin.hpp | 30 +++ .../include/cubos/engine/ui/text/plugin.hpp | 30 +++ engine/include/cubos/engine/ui/text/text.hpp | 41 ++++ .../cubos/engine/ui/text/text_stretch.hpp | 19 ++ engine/samples/ui/main.cpp | 45 +++- engine/src/defaults/plugin.cpp | 4 + engine/src/font/atlas/atlas.cpp | 107 +++++++++ engine/src/font/atlas/bridge.cpp | 48 ++++ engine/src/font/atlas/glyph.cpp | 18 ++ engine/src/font/bridge.cpp | 42 ++++ engine/src/font/font.cpp | 62 ++++++ engine/src/font/plugin.cpp | 27 +++ engine/src/ui/canvas/plugin.cpp | 89 +++++--- engine/src/ui/text/plugin.cpp | 208 ++++++++++++++++++ engine/src/ui/text/text.cpp | 19 ++ engine/src/ui/text/text_impl.cpp | 13 ++ engine/src/ui/text/text_impl.hpp | 16 ++ engine/src/ui/text/text_stretch.cpp | 8 + 35 files changed, 1090 insertions(+), 46 deletions(-) create mode 100644 engine/assets/font/Robot-Regular.fontatlas.meta create mode 100644 engine/assets/font/Roboto-Regular.ttf create mode 100644 engine/assets/font/Roboto-Regular.ttf.meta create mode 100644 engine/assets/font/RussoOne-Regular.fontatlas.meta create mode 100644 engine/assets/font/RussoOne-Regular.ttf create mode 100644 engine/assets/font/RussoOne-Regular.ttf.meta create mode 100644 engine/assets/ui/text.fs create mode 100644 engine/assets/ui/text.fs.meta create mode 100644 engine/assets/ui/text.vs create mode 100644 engine/assets/ui/text.vs.meta create mode 100644 engine/include/cubos/engine/font/atlas/atlas.hpp create mode 100644 engine/include/cubos/engine/font/atlas/bridge.hpp create mode 100644 engine/include/cubos/engine/font/atlas/glyph.hpp create mode 100644 engine/include/cubos/engine/font/bridge.hpp create mode 100644 engine/include/cubos/engine/font/font.hpp create mode 100644 engine/include/cubos/engine/font/plugin.hpp create mode 100644 engine/include/cubos/engine/ui/text/plugin.hpp create mode 100644 engine/include/cubos/engine/ui/text/text.hpp create mode 100644 engine/include/cubos/engine/ui/text/text_stretch.hpp create mode 100644 engine/src/font/atlas/atlas.cpp create mode 100644 engine/src/font/atlas/bridge.cpp create mode 100644 engine/src/font/atlas/glyph.cpp create mode 100644 engine/src/font/bridge.cpp create mode 100644 engine/src/font/font.cpp create mode 100644 engine/src/font/plugin.cpp create mode 100644 engine/src/ui/text/plugin.cpp create mode 100644 engine/src/ui/text/text.cpp create mode 100644 engine/src/ui/text/text_impl.cpp create mode 100644 engine/src/ui/text/text_impl.hpp create mode 100644 engine/src/ui/text/text_stretch.cpp diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a00aee5ee..01f3ae702e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Compatibility with CMake find_package (#1326, **@RiscadoA**). - A proper Nix package which can be used to install Cubos and Tesseratos (#1327, **RiscadoA**). - Added the option to use Shadow Normal Offset Bias algorithm (#1308, **@GalaxyCrush**) +- UI text element using MSDF for text rendering (#1300, **@mkuritsu**). ### Changed @@ -31,6 +32,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Flipped documentation of SystemBuilder::before and SystemBuilder::after (#1371, **@RiscadoA**). - Inconsistent behavior on ECS queries on symmetric self-relations (**@RiscadoA**). - Undefined behavior on ECS entity removal due to creating tables while iterating over tables (#1363, **@RiscadoA**). +- Made canvas draw calls sorted by layer in order to prevent undeterministic behavior when drawing elements with transparency (**@mkuritsu**). ## [v0.4.0] - 2024-10-13 diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index 9a40651a12..0bb41db8f3 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -116,10 +116,21 @@ set(CUBOS_ENGINE_SOURCE "src/ui/color_rect/color_rect.cpp" "src/ui/image/plugin.cpp" "src/ui/image/image.cpp" + "src/ui/text/plugin.cpp" + "src/ui/text/text_impl.cpp" + "src/ui/text/text_stretch.cpp" + "src/ui/text/text.cpp" "src/fixed_step/plugin.cpp" "src/fixed_step/fixed_delta_time.cpp" + "src/font/atlas/glyph.cpp" + "src/font/atlas/bridge.cpp" + "src/font/atlas/atlas.cpp" + "src/font/plugin.cpp" + "src/font/font.cpp" + "src/font/bridge.cpp" + "src/render/defaults/plugin.cpp" "src/render/defaults/target.cpp" "src/render/shader/plugin.cpp" @@ -285,6 +296,44 @@ target_include_directories(imgui PUBLIC # Finally, link the target we created for both ImGui and Implot target_link_libraries(cubos-engine PUBLIC imgui) +# freetype (msdfgen dependency) - fails to build on windows without this +set(FT_DISABLE_ZLIB ON) +set(FT_DISABLE_BZIP2 ON) +set(FT_DISABLE_PNG ON) +set(FT_DISABLE_HARFBUZZ ON) +set(FT_DISABLE_BROTLI ON) +FetchContent_Declare(freetype + GIT_REPOSITORY "https://gitlab.freedesktop.org/freetype/freetype.git" + GIT_TAG "VER-2-13-3" + SYSTEM + FIND_PACKAGE_ARGS +) +FetchContent_MakeAvailable(freetype) +if (NOT TARGET Freetype::Freetype) + add_library(Freetype::Freetype ALIAS freetype) +endif() +set_property(TARGET freetype PROPERTY POSITION_INDEPENDENT_CODE ON) + +# msdf-atlas-gen +set(MSDF_ATLAS_USE_VCPKG OFF) +set(MSDF_ATLAS_USE_SKIA OFF) +set(MSDF_ATLAS_BUILD_STANDALONE OFF) +set(MSDF_ATLAS_NO_ARTERY_FONT ON) +set(MSDFGEN_DISABLE_PNG ON) +set(MSDFGEN_BUILD_STANDALONE OFF) +set(MSDF_ATLAS_DYNAMIC_RUNTIME ON) +FetchContent_Declare(msdf-atlas-gen + GIT_REPOSITORY "https://github.com/Chlumsky/msdf-atlas-gen.git" + SYSTEM + FIND_PACKAGE_ARGS +) +FetchContent_MakeAvailable(msdf-atlas-gen) +# To prevent reallocation errors when compiling engine as a shared library +set_property(TARGET msdf-atlas-gen PROPERTY POSITION_INDEPENDENT_CODE ON) +set_property(TARGET msdfgen-core PROPERTY POSITION_INDEPENDENT_CODE ON) + +target_link_libraries(cubos-engine PRIVATE msdf-atlas-gen) + # ------------------------ Configure tests and samples ------------------------ if(CUBOS_ENGINE_TESTS) @@ -312,4 +361,5 @@ if(CUBOS_ENABLE_INSTALL) install(DIRECTORY ${imgui_SOURCE_DIR}/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/imgui) install(DIRECTORY ${implot_SOURCE_DIR}/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/implot) install(DIRECTORY assets/ DESTINATION ${CUBOS_ENGINE_ASSETS_INSTALL_PATH}) + install(DIRECTORY ${msdf-atlas-gen_SOURCE_DIR}/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/msdf-atlas-gen) endif() diff --git a/engine/assets/font/Robot-Regular.fontatlas.meta b/engine/assets/font/Robot-Regular.fontatlas.meta new file mode 100644 index 0000000000..22b74fbb0d --- /dev/null +++ b/engine/assets/font/Robot-Regular.fontatlas.meta @@ -0,0 +1,4 @@ +{ + "id": "ab32bedd-8ea5-49f0-bca6-0b319feb1207", + "font": "93cbe82e-9c9b-4c25-aa55-5105c1afd0cc" +} diff --git a/engine/assets/font/Roboto-Regular.ttf b/engine/assets/font/Roboto-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..2d116d920580367caf6a179155f344ede856bf31 GIT binary patch literal 168260 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∾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 TwL*XSfJ*Ay literal 0 HcmV?d00001 diff --git a/engine/assets/font/Roboto-Regular.ttf.meta b/engine/assets/font/Roboto-Regular.ttf.meta new file mode 100644 index 0000000000..fa8f7495da --- /dev/null +++ b/engine/assets/font/Roboto-Regular.ttf.meta @@ -0,0 +1,3 @@ +{ + "id": "93cbe82e-9c9b-4c25-aa55-5105c1afd0cc" +} \ No newline at end of file diff --git a/engine/assets/font/RussoOne-Regular.fontatlas.meta b/engine/assets/font/RussoOne-Regular.fontatlas.meta new file mode 100644 index 0000000000..8e6433ffaa --- /dev/null +++ b/engine/assets/font/RussoOne-Regular.fontatlas.meta @@ -0,0 +1,4 @@ +{ + "id": "bd0387d2-af3d-4c65-8561-33f5bcf6ab37", + "font": "ffc53a73-ac38-4797-93ba-8adebbca1e79" +} diff --git a/engine/assets/font/RussoOne-Regular.ttf b/engine/assets/font/RussoOne-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..7250bc5fa2b7459bcb3843bcd9ed2439ad1990f7 GIT binary patch literal 37480 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 +#include + +#include +#include + +#include +#include + +namespace cubos::engine +{ + /// @brief Class that holds all the necessary data about a font atlas. This font atlas represents the texure + /// created from all the different glyphs in a font, that will be then used for drawing the text. + /// + /// @ingroup font-plugin + class CUBOS_ENGINE_API FontAtlas + { + public: + CUBOS_REFLECT; + + FontAtlas(void* font, double minimumScale, double pixelRange, double miterLimit, + cubos::core::gl::RenderDevice& renderDevice); + + std::optional requestGlyph(uint32_t unicode) const; + + /// @brief Returns the GPU texture created with this font atlas. + cubos::core::gl::Texture2D texture() const; + + private: + cubos::core::gl::Texture2D mTexture{nullptr}; + + std::unordered_map mGlyphs; + }; + +} // namespace cubos::engine diff --git a/engine/include/cubos/engine/font/atlas/bridge.hpp b/engine/include/cubos/engine/font/atlas/bridge.hpp new file mode 100644 index 0000000000..fbe6ad36ba --- /dev/null +++ b/engine/include/cubos/engine/font/atlas/bridge.hpp @@ -0,0 +1,35 @@ +/// @file +/// @brief Class @ref cubos::engine::FontAtlasBridge. +/// @ingroup font-plugin + +#pragma once + +#include + +#include +#include +#include +#include + +namespace cubos::engine +{ + /// @brief Bridge which loads @ref FontAtlas assets. + /// + /// @ingroup font-plugin + class CUBOS_ENGINE_API FontAtlasBridge : public AssetBridge + { + public: + FontAtlasBridge(cubos::core::gl::RenderDevice& renderDevice) + : AssetBridge(core::reflection::reflect(), false) + , mRenderDevice(renderDevice) + { + } + + protected: + bool load(Assets& assets, const AnyAsset& handle) override; + bool save(const Assets& assets, const AnyAsset& handle) override; + + private: + cubos::core::gl::RenderDevice& mRenderDevice; + }; +} // namespace cubos::engine diff --git a/engine/include/cubos/engine/font/atlas/glyph.hpp b/engine/include/cubos/engine/font/atlas/glyph.hpp new file mode 100644 index 0000000000..b39d9e0409 --- /dev/null +++ b/engine/include/cubos/engine/font/atlas/glyph.hpp @@ -0,0 +1,30 @@ +/// @file +/// @brief Struct @ref cubos::engine::Glyph. +/// @ingroup font-plugin + +#pragma once + +#include + +#include + +#include + +namespace cubos::engine +{ + /// @brief Struct that holds glyph data such as texcoords, position offsets and advance. + /// + /// @ingroup font-plugin + struct CUBOS_ENGINE_API FontGlyph + { + CUBOS_REFLECT; + + glm::vec2 texCoordsMin; + glm::vec2 texCoordsMax; + + glm::vec2 positionMin; + glm::vec2 positionMax; + + float advance; + }; +} // namespace cubos::engine diff --git a/engine/include/cubos/engine/font/bridge.hpp b/engine/include/cubos/engine/font/bridge.hpp new file mode 100644 index 0000000000..dee182a557 --- /dev/null +++ b/engine/include/cubos/engine/font/bridge.hpp @@ -0,0 +1,29 @@ +/// @file +/// @brief Class @ref cubos::engine::FontBridge. +/// @ingroup font-plugin + +#pragma once + +#include +#include + +namespace cubos::engine +{ + /// @brief Bridge which loads @ref Font assets. + /// + /// @ingroup font-plugin + class CUBOS_ENGINE_API FontBridge : public FileBridge + { + public: + FontBridge(); + + ~FontBridge() override; + + protected: + bool loadFromFile(Assets& assets, const AnyAsset& handle, core::memory::Stream& stream) override; + bool saveToFile(const Assets& assets, const AnyAsset& handle, core::memory::Stream& stream) override; + + private: + void* mFreetypeHandle; + }; +} // namespace cubos::engine diff --git a/engine/include/cubos/engine/font/font.hpp b/engine/include/cubos/engine/font/font.hpp new file mode 100644 index 0000000000..6647b107ec --- /dev/null +++ b/engine/include/cubos/engine/font/font.hpp @@ -0,0 +1,42 @@ +/// @file +/// @brief Struct @ref cubos::engine::Font. +/// @ingroup font-plugin + +#pragma once + +#include + +#include +#include + +#include + +namespace cubos::engine +{ + /// @brief Asset containing raw font data containing the glyphs and their shape. This is used to create @ref + /// FontAtlas that can be used for rendering text. + /// + /// @ingroup font-plugin + class CUBOS_ENGINE_API Font + { + public: + CUBOS_REFLECT; + + /// @brief Creates a new Font asset from the data in the stream. + Font(void* freetypeHandle, core::memory::Stream& stream); + + /// @brief Move constructor that moves the font handle to another Font asset. + Font(Font&& other) noexcept; + + /// @brief Destroys the associated handle to the font. + ~Font(); + + /// @brief Returns the handle to this loaded font. + void* handle() const; + + private: + void* mHandle{nullptr}; + + std::vector mData; + }; +} // namespace cubos::engine diff --git a/engine/include/cubos/engine/font/plugin.hpp b/engine/include/cubos/engine/font/plugin.hpp new file mode 100644 index 0000000000..35883fcd32 --- /dev/null +++ b/engine/include/cubos/engine/font/plugin.hpp @@ -0,0 +1,30 @@ +/// @dir +/// @brief @ref font-plugin plugin directory. + +/// @file +/// @brief Plugin entry point. +/// @ingroup font-plugin + +#pragma once + +#include + +namespace cubos::engine +{ + /// @defgroup font-plugin Font + /// @ingroup engine + /// @brief Adds fonts to @b Cubos using msdfgen. + /// + /// ## Bridges + /// - @ref FontBridge - loads @ref Font assets. + /// - @ref FontAtlasBridge - loads @ref FontAtlas assets. + /// + /// ## Dependencies + /// - @ref assets-plugin + /// - @ref window-plugin + + /// @brief Plugin entry function. + /// @param cubos @b Cubos main class. + /// @ingroup font-plugin + CUBOS_ENGINE_API void fontPlugin(Cubos& cubos); +} // namespace cubos::engine diff --git a/engine/include/cubos/engine/ui/text/plugin.hpp b/engine/include/cubos/engine/ui/text/plugin.hpp new file mode 100644 index 0000000000..3dbe1f0b98 --- /dev/null +++ b/engine/include/cubos/engine/ui/text/plugin.hpp @@ -0,0 +1,30 @@ +/// @dir +/// @brief @ref ui-text-plugin plugin directory. + +/// @file +/// @brief Plugin entry point. +/// @ingroup ui-text-plugin + +#pragma once + +#include + +namespace cubos::engine +{ + /// @defgroup ui-text-plugin + /// @ingroup ui-plugins + /// @brief Adds text element to UI. + /// + /// ## Dependencies: + /// - @ref ui-canvas-plugin + /// - @ref window-plugin + /// - @ref render-shader-plugin + /// - @ref assets-plugin + /// - @ref font-plugin + + /// @brief Plugin entry function. + /// @param cubos @b Cubos main class + /// @ingroup ui-text-plugin + CUBOS_ENGINE_API void uiTextPlugin(Cubos& cubos); + +} // namespace cubos::engine diff --git a/engine/include/cubos/engine/ui/text/text.hpp b/engine/include/cubos/engine/ui/text/text.hpp new file mode 100644 index 0000000000..5e6255f477 --- /dev/null +++ b/engine/include/cubos/engine/ui/text/text.hpp @@ -0,0 +1,41 @@ +/// @file +/// @brief Component @ref cubos::engine::UIText. +/// @ingroup ui-text-plugin + +#pragma once + +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include + +namespace cubos::engine +{ + /// @brief Component used to draw text on the UI. + /// + /// @ingroup ui-text-plugin + struct CUBOS_ENGINE_API UIText + { + CUBOS_REFLECT; + + /// @brief The text of the element. + std::string text; + + /// @brief The color of the text. + glm::vec4 color{1.0F}; + + /// @brief The font size to draw the characters. + float fontSize{24.0F}; + + /// @brief The font atlas to be used. + Asset fontAtlas{AnyAsset("ab32bedd-8ea5-49f0-bca6-0b319feb1207")}; + }; +} // namespace cubos::engine diff --git a/engine/include/cubos/engine/ui/text/text_stretch.hpp b/engine/include/cubos/engine/ui/text/text_stretch.hpp new file mode 100644 index 0000000000..937840cb2c --- /dev/null +++ b/engine/include/cubos/engine/ui/text/text_stretch.hpp @@ -0,0 +1,19 @@ +/// @file +/// @brief Component @ref cubos::engine::UITextStretch. +/// @ingroup ui-text-plugin + +#pragma once + +#include + +#include + +namespace cubos::engine +{ + /// @brief Component which makes a UI element fit the text it has. + /// @ingroup ui-text-plugin + struct CUBOS_ENGINE_API UITextStretch + { + CUBOS_REFLECT; + }; +} // namespace cubos::engine diff --git a/engine/samples/ui/main.cpp b/engine/samples/ui/main.cpp index 9562fdda67..36cce5218d 100644 --- a/engine/samples/ui/main.cpp +++ b/engine/samples/ui/main.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -22,6 +23,9 @@ #include #include #include +#include +#include +#include #include using namespace cubos::engine; @@ -43,6 +47,8 @@ int main(int argc, char** argv) cubos.plugin(imagePlugin); cubos.plugin(uiImagePlugin); cubos.plugin(colorRectPlugin); + cubos.plugin(fontPlugin); + cubos.plugin(uiTextPlugin); cubos.startupSystem("load and set the Input Bindings") .tagged(assetsTag) @@ -62,7 +68,7 @@ int main(int argc, char** argv) /// [Set up Canvas] /// [Set up Background] auto elementBg = commands.create() - .add(UIElement{}) + .add(UIElement{.layer = 0}) .add(UIHorizontalStretch{20, 20}) .add(UIVerticalStretch{20, 20}) .add(UIColorRect{{1, 1, 1, 1}}) @@ -73,28 +79,45 @@ int main(int argc, char** argv) /// [Set up Panel] auto elementPanel = commands.create() - .add(UIElement{.offset = {-50, 0}, .size = {200, 600}, .pivot = {1, 0.5F}, .anchor = {1, 0.5F}}) + .add(UIElement{ + .offset = {-50, 0}, .size = {200, 600}, .pivot = {1, 0.5F}, .anchor = {1, 0.5F}, .layer = 1}) .add(UIColorRect{{1, 0, 0, 1}}) .entity(); commands.relate(elementPanel, elementBg, ChildOf{}); /// [Set up Panel] /// [Set up Logo] - auto logo = commands.create() - .add(UIElement{.offset = {50, -50}, .size = {200, 200}, .pivot = {0, 1}, .anchor = {0, 1}}) - .add(UIImage{AnyAsset("50423317-a543-4614-9f4e-c2df975f5c0d")}) - .entity(); + auto logo = + commands.create() + .add(UIElement{.offset = {50, -50}, .size = {200, 200}, .pivot = {0, 1}, .anchor = {0, 1}, .layer = 1}) + .add(UIImage{AnyAsset("50423317-a543-4614-9f4e-c2df975f5c0d")}) + .entity(); commands.relate(logo, elementBg, ChildOf{}); /// [Set up Logo] /// [Set up Long Logo] - auto longLogo = commands.create() - .add(UIElement{.offset = {50, 50}, .size = {400, 400}, .pivot = {0, 0}, .anchor = {0, 0}}) - .add(UIImage{AnyAsset("6c24c031-2eac-47c9-be30-485238c3e355")}) - .add(UINativeAspectRatio{}) - .entity(); + auto longLogo = + commands.create() + .add(UIElement{.offset = {50, 50}, .size = {400, 400}, .pivot = {0, 0}, .anchor = {0, 0}, .layer = 1}) + .add(UIImage{AnyAsset("6c24c031-2eac-47c9-be30-485238c3e355")}) + .add(UINativeAspectRatio{}) + .entity(); commands.relate(longLogo, elementBg, ChildOf{}); /// [Set up Long Logo] + + /// [Setup title] + auto title = + commands.create() + .add(UIElement{ + .offset = {0, -20}, .size = {100, 100}, .pivot = {0.5F, 0.5F}, .anchor = {0.5F, 1.0F}, .layer = 2}) + .add(UIText{.text = "cubosengine.org", + .color = {0.13, 0.14, 0.15, 1}, + .fontSize = 48.0F, + .fontAtlas{AnyAsset{"bd0387d2-af3d-4c65-8561-33f5bcf6ab37"}}}) + .add(UITextStretch{}) + .entity(); + commands.relate(title, elementBg, ChildOf{}); + /// [Setup title] }); cubos.system("change scale mode").call([](Commands cmds, const Input& input, Query query) { diff --git a/engine/src/defaults/plugin.cpp b/engine/src/defaults/plugin.cpp index d052f9eb3e..212710cbcd 100644 --- a/engine/src/defaults/plugin.cpp +++ b/engine/src/defaults/plugin.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -14,6 +15,7 @@ #include #include #include +#include #include #include @@ -32,6 +34,7 @@ void cubos::engine::defaultsPlugin(Cubos& cubos) cubos.plugin(assetsPlugin); cubos.plugin(collisionsPlugin); cubos.plugin(windowPlugin); + cubos.plugin(fontPlugin); cubos.plugin(scenePlugin); cubos.plugin(voxelsPlugin); @@ -43,6 +46,7 @@ void cubos::engine::defaultsPlugin(Cubos& cubos) cubos.plugin(uiCanvasPlugin); cubos.plugin(colorRectPlugin); + cubos.plugin(uiTextPlugin); cubos.plugin(gizmosPlugin); cubos.plugin(imguiPlugin); diff --git a/engine/src/font/atlas/atlas.cpp b/engine/src/font/atlas/atlas.cpp new file mode 100644 index 0000000000..3c101d2e71 --- /dev/null +++ b/engine/src/font/atlas/atlas.cpp @@ -0,0 +1,107 @@ +#include + +#include + +#include +#include +#include +#include +#include + +#include + +constexpr double MaxCornerAngle = 3.0; //< Controls the signed distance field type, 3.0 = MSDF. +constexpr int ThreadCount = 4; //< Amount of threads to use when loading font glyphs. + +CUBOS_REFLECT_IMPL(cubos::engine::FontAtlas) +{ + using namespace cubos::core::reflection; + + return Type::create("cubos::engine::FontAtlas") + .with(ConstructibleTrait::typed().withMoveConstructor().build()); +} + +cubos::engine::FontAtlas::FontAtlas(void* font, double minimumScale, double pixelRange, double miterLimit, + cubos::core::gl::RenderDevice& renderDevice) +{ + std::vector glyphs; + msdf_atlas::FontGeometry fontGeometry(&glyphs); + int loaded = fontGeometry.loadCharset(static_cast(font), 1.0, msdf_atlas::Charset::ASCII); + int asciiSize = static_cast(msdf_atlas::Charset::ASCII.size()); + if (loaded != asciiSize) + { + CUBOS_WARN("Couldn't load all {} ASCII glyphs, only {} loaded!", asciiSize, loaded); + } + + for (msdf_atlas::GlyphGeometry& glyph : glyphs) + { + glyph.edgeColoring(&msdfgen::edgeColoringInkTrap, MaxCornerAngle, 0); + } + msdf_atlas::TightAtlasPacker packer; + packer.setDimensionsConstraint(msdf_atlas::DimensionsConstraint::SQUARE); + packer.setMinimumScale(minimumScale); + packer.setPixelRange(pixelRange); + packer.setMiterLimit(miterLimit); + packer.pack(glyphs.data(), static_cast(glyphs.size())); + int atlasWidth = 0; + int atlasHeight = 0; + packer.getDimensions(atlasWidth, atlasHeight); + + msdf_atlas::ImmediateAtlasGenerator> + generator(atlasWidth, atlasHeight); + msdf_atlas::GeneratorAttributes attributes; + generator.setAttributes(attributes); + generator.setThreadCount(ThreadCount); + generator.generate(glyphs.data(), static_cast(glyphs.size())); + + msdfgen::BitmapConstRef bitmap = generator.atlasStorage(); + for (const msdf_atlas::GlyphGeometry& glyph : glyphs) + { + FontGlyph outGlyph{}; + double left; + double bottom; + double right; + double top; + glyph.getQuadAtlasBounds(left, bottom, right, top); + outGlyph.texCoordsMin = {static_cast(left / bitmap.width), static_cast(bottom / bitmap.height)}; + outGlyph.texCoordsMax = {static_cast(right / bitmap.width), static_cast(top / bitmap.height)}; + glyph.getQuadPlaneBounds(left, bottom, right, top); + outGlyph.positionMin = {static_cast(left), static_cast(bottom)}; + outGlyph.positionMax = {static_cast(right), static_cast(top)}; + outGlyph.advance = static_cast(glyph.getAdvance()); + mGlyphs[glyph.getCodepoint()] = outGlyph; + } + auto bitmapWidth = static_cast(bitmap.width); + auto bitmapHeight = static_cast(bitmap.height); + std::vector pixels; + pixels.reserve(bitmapWidth * bitmapHeight * 4); + for (size_t i = 0; i < bitmapWidth * bitmapHeight * 3; i += 3) + { + pixels.push_back(bitmap.pixels[i]); + pixels.push_back(bitmap.pixels[i + 1]); + pixels.push_back(bitmap.pixels[i + 2]); + pixels.push_back(255); + } + core::gl::Texture2DDesc desc{.data = {pixels.data()}, + .width = bitmapWidth, + .height = bitmapHeight, + .usage = core::gl::Usage::Default, + .format = core::gl::TextureFormat::RGBA8UNorm}; + mTexture = renderDevice.createTexture2D(desc); +} + +std::optional cubos::engine::FontAtlas::requestGlyph(uint32_t unicode) const +{ + auto it = mGlyphs.find(unicode); + if (it == mGlyphs.end()) + { + return {}; + } + return it->second; +} + +cubos::core::gl::Texture2D cubos::engine::FontAtlas::texture() const +{ + return mTexture; +} diff --git a/engine/src/font/atlas/bridge.cpp b/engine/src/font/atlas/bridge.cpp new file mode 100644 index 0000000000..55006c401c --- /dev/null +++ b/engine/src/font/atlas/bridge.cpp @@ -0,0 +1,48 @@ +#include + +#include +#include + +bool cubos::engine::FontAtlasBridge::load(Assets& assets, const AnyAsset& handle) +{ + double minimumScale = 24.0; + double pixelRange = 4.0; + double miterLimit = 1.0; + AnyAsset fontAsset{}; + { + auto meta = assets.readMeta(handle); + if (auto optMinimumScale = meta->get("minimumScale")) + { + minimumScale = std::stod(*optMinimumScale); + } + if (auto optPixelRange = meta->get("pixelRange")) + { + pixelRange = std::stod(*optPixelRange); + } + if (auto optMiterLimit = meta->get("miterLimit")) + { + miterLimit = std::stod(*optMiterLimit); + } + if (auto optFont = meta->get("font")) + { + fontAsset = AnyAsset{*optFont}; + } + if (fontAsset.isNull()) + { + CUBOS_ERROR("Could not load FontAtlas: missing font identifier in .meta"); + return false; + } + } + auto assetRead = assets.read(fontAsset); + FontAtlas atlas{assetRead->handle(), minimumScale, pixelRange, miterLimit, mRenderDevice}; + assets.store(handle, std::move(atlas)); + return true; +} + +bool cubos::engine::FontAtlasBridge::save(const Assets& assets, const AnyAsset& handle) +{ + (void)assets; + (void)handle; + CUBOS_ERROR("Saving font atlas is currently unsupported!"); + return false; +} diff --git a/engine/src/font/atlas/glyph.cpp b/engine/src/font/atlas/glyph.cpp new file mode 100644 index 0000000000..8679509d82 --- /dev/null +++ b/engine/src/font/atlas/glyph.cpp @@ -0,0 +1,18 @@ +#include +#include +#include + +#include + +using namespace cubos::engine; + +CUBOS_REFLECT_IMPL(FontGlyph) +{ + return cubos::core::ecs::TypeBuilder("cubos::engine::Glyph") + .withField("texCoordsMin", &FontGlyph::texCoordsMin) + .withField("texCoordsMax", &FontGlyph::texCoordsMax) + .withField("positionMin", &FontGlyph::positionMin) + .withField("positionMax", &FontGlyph::positionMax) + .withField("advance", &FontGlyph::advance) + .build(); +} diff --git a/engine/src/font/bridge.cpp b/engine/src/font/bridge.cpp new file mode 100644 index 0000000000..e96097d527 --- /dev/null +++ b/engine/src/font/bridge.cpp @@ -0,0 +1,42 @@ +#include + +#include + +#include + +#include +#include +#include + +using namespace cubos::engine; + +FontBridge::FontBridge() + : FileBridge(core::reflection::reflect()) + , mFreetypeHandle(msdfgen::initializeFreetype()) +{ +} + +FontBridge::~FontBridge() +{ + msdfgen::deinitializeFreetype(static_cast(mFreetypeHandle)); +} + +bool FontBridge::loadFromFile(Assets& assets, const AnyAsset& handle, core::memory::Stream& stream) +{ + Font font{mFreetypeHandle, stream}; + if (font.handle() == nullptr) + { + return false; + } + assets.store(handle, std::move(font)); + return true; +} + +bool FontBridge::saveToFile(const Assets& assets, const AnyAsset& handle, core::memory::Stream& stream) +{ + (void)assets; + (void)handle; + (void)stream; + CUBOS_ERROR("Saving fonts is currently unsupported!"); + return false; +} diff --git a/engine/src/font/font.cpp b/engine/src/font/font.cpp new file mode 100644 index 0000000000..1b2635daad --- /dev/null +++ b/engine/src/font/font.cpp @@ -0,0 +1,62 @@ +#include + +#include +#include +#include +#include +#include + +#include + +CUBOS_REFLECT_IMPL(cubos::engine::Font) +{ + return cubos::core::reflection::Type::create("cubos::engine::Font"); +} + +namespace cubos::engine +{ + Font::Font(void* freetypeHandle, core::memory::Stream& stream) + { + if (freetypeHandle == nullptr) + { + CUBOS_ERROR("Couldn't load font: Invalid Freetype handle"); + return; + } + stream.seek(0, cubos::core::memory::SeekOrigin::End); + size_t streamSize = stream.tell(); + mData.resize(streamSize); + stream.seek(0, cubos::core::memory::SeekOrigin::Begin); + if (stream.read(mData.data(), streamSize) < streamSize) + { + CUBOS_ERROR("Couldn't load font: Read less than stream length"); + return; + } + mHandle = msdfgen::loadFontData(static_cast(freetypeHandle), mData.data(), + static_cast(streamSize)); + if (mHandle == nullptr) + { + CUBOS_ERROR("Couldn't load font: Failed to load data"); + } + } + + Font::Font(Font&& other) noexcept + : mHandle(other.mHandle) + , mData(std::move(other.mData)) + { + other.mHandle = nullptr; + } + + Font::~Font() + { + if (mHandle != nullptr) + { + msdfgen::destroyFont(static_cast(mHandle)); + } + } + + void* Font::handle() const + { + return mHandle; + } + +} // namespace cubos::engine diff --git a/engine/src/font/plugin.cpp b/engine/src/font/plugin.cpp new file mode 100644 index 0000000000..7506bd0713 --- /dev/null +++ b/engine/src/font/plugin.cpp @@ -0,0 +1,27 @@ +#include + +#include +#include +#include +#include +#include +#include + +void cubos::engine::fontPlugin(Cubos& cubos) +{ + cubos.depends(assetsPlugin); + cubos.depends(windowPlugin); + + cubos.startupSystem("setup Font assets bridge").tagged(assetsBridgeTag).call([](Assets& assets) { + auto bridge = std::make_shared(); + assets.registerBridge(".ttf", bridge); + assets.registerBridge(".otf", bridge); + }); + + cubos.startupSystem("setup FontAtlas assets bridge") + .tagged(assetsBridgeTag) + .call([](Assets& assets, const core::io::Window& window) { + auto bridge = std::make_shared(window->renderDevice()); + assets.registerBridge(".fontatlas", bridge); + }); +} diff --git a/engine/src/ui/canvas/plugin.cpp b/engine/src/ui/canvas/plugin.cpp index 2455487a94..c5b080f105 100644 --- a/engine/src/ui/canvas/plugin.cpp +++ b/engine/src/ui/canvas/plugin.cpp @@ -3,6 +3,7 @@ #include +#include #include #include @@ -38,21 +39,25 @@ namespace cubos::core::gl::DepthStencilState dss; cubos::core::gl::ConstantBuffer mvpBuffer; - State(cubos::core::gl::DepthStencilState depthStencilState, cubos::core::gl::ConstantBuffer mvpConstantBuffer) + cubos::core::gl::BlendState bs; + State(cubos::core::gl::DepthStencilState depthStencilState, cubos::core::gl::ConstantBuffer mvpConstantBuffer, + cubos::core::gl ::BlendState blendState) : dss(std::move(depthStencilState)) , mvpBuffer(std::move(mvpConstantBuffer)) + , bs(std::move(blendState)) { } }; } // namespace static void copyCommands(Query query, UIElement& element, Entity entity, - std::map& commands) + std::map>& commands) { for (size_t i = 0; i < element.drawList.size(); i++) { + int depth = element.layer * 100 + element.hierarchyDepth; auto entry = element.drawList.entry(i); - commands[&entry.type].push(entry.type, entry.command, element.drawList.data(i)); + commands[depth][&entry.type].push(entry.type, entry.command, element.drawList.data(i)); } element.drawList.clear(); for (auto [child, childElement, _] : query.pin(1, entity)) @@ -91,14 +96,26 @@ void cubos::engine::uiCanvasPlugin(Cubos& cubos) cubos.startupSystem("setup canvas state") .after(windowInitTag) .call([](Commands cmds, const core::io::Window& window) { - cubos::core::gl::DepthStencilStateDesc dssd; - dssd.depth.enabled = true; - dssd.depth.writeEnabled = true; - dssd.depth.near = -1.0F; - dssd.depth.compare = Compare::LEqual; + cubos::core::gl::DepthStencilStateDesc dssd = {.depth = {.enabled = false}, .stencil = {.enabled = false}}; + cubos::core::gl::BlendStateDesc bsd = { + .blendEnabled = true, + .color = + { + .src = BlendFactor::SrcAlpha, + .dst = BlendFactor::InvSrcAlpha, + .op = BlendOp::Add, + }, + .alpha = + { + .src = BlendFactor::One, + .dst = BlendFactor::Zero, + .op = BlendOp::Add, + }, + }; cmds.emplaceResource(window->renderDevice().createDepthStencilState(dssd), window->renderDevice().createConstantBuffer(sizeof(glm::mat4), nullptr, - cubos::core::gl::Usage::Dynamic)); + cubos::core::gl::Usage::Dynamic), + window->renderDevice().createBlendState(bsd)); }); cubos.system("scale canvas") @@ -139,7 +156,7 @@ void cubos::engine::uiCanvasPlugin(Cubos& cubos) canvas.virtualSize = canvas.referenceSize; } - canvas.mat = glm::ortho(0, canvas.virtualSize.x, 0, canvas.virtualSize.y); + canvas.mat = glm::ortho(0, canvas.virtualSize.x, 0, canvas.virtualSize.y, -1000.0F, 1000.0F); } }); @@ -256,7 +273,6 @@ void cubos::engine::uiCanvasPlugin(Cubos& cubos) window->renderDevice().clearColor(0.0F, 0.0F, 0.0F, 0.0F); target.cleared = true; } - window->renderDevice().clearDepth(1); } }); @@ -275,6 +291,7 @@ void cubos::engine::uiCanvasPlugin(Cubos& cubos) const State& state) { // For each render target with a UI canvas. window->renderDevice().setDepthStencilState(state.dss); + window->renderDevice().setBlendState(state.bs); for (auto [entity, canvas, renderTarget] : canvasQuery) { @@ -284,42 +301,44 @@ void cubos::engine::uiCanvasPlugin(Cubos& cubos) state.mvpBuffer->fill(&canvas.mat, sizeof(glm::mat4)); // Extract draw commands from all children UI elements, recursively. - std::map commands; + std::map> layerCommands; for (auto [child, childElement, _] : drawsToQuery.pin(1, entity)) { - copyCommands(childrenQuery, childElement, child, commands); + copyCommands(childrenQuery, childElement, child, layerCommands); } - // For each draw command type. - for (const auto& [type, list] : commands) + for (const auto& [layer, commands] : layerCommands) { - - // Prepare state common to all instances of this draw command type. - window->renderDevice().setShaderPipeline(type->pipeline); - type->pipeline->getBindingPoint("MVP")->bind(state.mvpBuffer); - type->constantBufferBindingPoint->bind(type->constantBuffer); - - // For all instances of this draw command type. - for (size_t i = 0; i < list.size(); i++) + // For each draw command type. + for (const auto& [type, list] : commands) { - // Prepare command-specific state and issue draw call. - auto entry = list.entry(i); - window->renderDevice().setVertexArray(entry.command.vertexArray); + // Prepare state common to all instances of this draw command type. + window->renderDevice().setShaderPipeline(type->pipeline); + type->pipeline->getBindingPoint("MVP")->bind(state.mvpBuffer); + type->constantBufferBindingPoint->bind(type->constantBuffer); - type->constantBuffer->fill(list.data(i), type->perElementSize); - - for (size_t j = 0; j < UIDrawList::Type::MaxTextures; j++) + // For all instances of this draw command type. + for (size_t i = 0; i < list.size(); i++) { - if (type->texBindingPoint[j] == nullptr) + // Prepare command-specific state and issue draw call. + auto entry = list.entry(i); + window->renderDevice().setVertexArray(entry.command.vertexArray); + + type->constantBuffer->fill(list.data(i), type->perElementSize); + + for (size_t j = 0; j < UIDrawList::Type::MaxTextures; j++) { - continue; + if (type->texBindingPoint[j] == nullptr) + { + continue; + } + type->texBindingPoint[j]->bind(entry.command.textures[j]); + type->texBindingPoint[j]->bind(entry.command.samplers[j]); } - type->texBindingPoint[j]->bind(entry.command.textures[j]); - type->texBindingPoint[j]->bind(entry.command.samplers[j]); + window->renderDevice().drawTriangles(entry.command.vertexOffset, entry.command.vertexCount); } - window->renderDevice().drawTriangles(entry.command.vertexOffset, entry.command.vertexCount); } } } }); -} \ No newline at end of file +} diff --git a/engine/src/ui/text/plugin.cpp b/engine/src/ui/text/plugin.cpp new file mode 100644 index 0000000000..68abfc570f --- /dev/null +++ b/engine/src/ui/text/plugin.cpp @@ -0,0 +1,208 @@ +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "text_impl.hpp" + +using cubos::core::io::Window; + +using namespace cubos::engine; + +namespace +{ + struct PerElement + { + glm::vec2 xRange; + glm::vec2 yRange; + glm::vec4 color; + int depth; + }; + + struct State + { + CUBOS_ANONYMOUS_REFLECT(State); + + UIDrawList::Type drawType; + Sampler sampler; + + State(RenderDevice& renderDevice, const ShaderPipeline& pipeline) + { + SamplerDesc sd = {.minFilter = TextureFilter::Linear, .magFilter = TextureFilter::Linear}; + sampler = renderDevice.createSampler(sd); + + drawType.constantBuffer = renderDevice.createConstantBuffer(sizeof(PerElement), nullptr, Usage::Dynamic); + drawType.texBindingPoint[0] = pipeline->getBindingPoint("fontAtlas"); + drawType.constantBufferBindingPoint = pipeline->getBindingPoint("PerElement"); + drawType.perElementSize = sizeof(PerElement); + drawType.pipeline = pipeline; + } + }; +} // namespace + +void cubos::engine::uiTextPlugin(Cubos& cubos) +{ + static const Asset VertexShader = AnyAsset("51c11c57-c819-4a51-806c-853178ec686a"); + static const Asset PixelShader = AnyAsset("b5b43fcb-0ec3-4f3a-9e90-a7b0b9978cc5"); + + cubos.component(); + cubos.component(); + cubos.component(); + + cubos.depends(uiCanvasPlugin); + cubos.depends(windowPlugin); + cubos.depends(shaderPlugin); + cubos.depends(assetsPlugin); + cubos.depends(fontPlugin); + + cubos.uninitResource(); + + cubos.startupSystem("setup UI text") + .tagged(assetsTag) + .after(windowInitTag) + .call([](Commands cmds, const Window& window, const Assets& assets) { + auto& rd = window->renderDevice(); + auto vs = assets.read(VertexShader)->shaderStage(); + auto ps = assets.read(PixelShader)->shaderStage(); + cmds.emplaceResource(rd, rd.createShaderPipeline(vs, ps)); + }); + + cubos.observer("add UITextImpl on add UIText").onAdd().call([](Commands cmds, Query query) { + for (auto [entity] : query) + { + cmds.add(entity, UITextImpl{}); + } + }); + + cubos.observer("remove UITextImpl on remove UIText") + .onRemove() + .call([](Commands cmds, Query query) { + for (auto [entity] : query) + { + cmds.remove(entity); + } + }); + + cubos.system("load UI text vertex array") + .call([](const Window& window, const State& state, Assets& assets, + Query> query) { + for (auto [element, uiText, textImpl, optStretch] : query) + { + if (textImpl.vertexArray == nullptr) + { + if (!uiText.fontAtlas.isStrong()) + { + uiText.fontAtlas = assets.load(uiText.fontAtlas); + } + auto atlas = assets.read(uiText.fontAtlas); + + std::size_t vertexCount = uiText.text.size() * 6; + textImpl.vertexCount = vertexCount; + float xPos = 0; + float yPos = 0; + + VertexArrayDesc vad; + vad.elementCount = 2; + vad.elements[0].name = "in_position"; + vad.elements[0].type = cubos::core::gl::Type::Float; + vad.elements[0].size = 2; + vad.elements[0].buffer.index = 0; + vad.elements[0].buffer.offset = 0; + vad.elements[0].buffer.stride = 4 * sizeof(float); + vad.elements[1].name = "in_texCoord"; + vad.elements[1].type = cubos::core::gl::Type::Float; + vad.elements[1].size = 2; + vad.elements[1].buffer.index = 0; + vad.elements[1].buffer.offset = 2 * sizeof(float); + vad.elements[1].buffer.stride = 4 * sizeof(float); + vad.shaderPipeline = state.drawType.pipeline; + + std::vector verts; + verts.reserve(4 * vertexCount); + /// @todo make add support for Unicode + /// @note This repeats a lot of vertices because currently the UI system does not support drawing + /// Indexed, something that needs to be worked on + for (char c : uiText.text) + { + auto uChar = static_cast(static_cast(c)); + std::optional optGlyph = atlas->requestGlyph(uChar); + if (!optGlyph.has_value()) + { + CUBOS_WARN("GLYPH NOT PRESENT!"); + optGlyph = atlas->requestGlyph(static_cast('?')); + } + FontGlyph glyph = optGlyph.value(); + auto advance = static_cast(glyph.advance * uiText.fontSize); + if (c == ' ') + { + xPos += advance; + continue; + } + float texCoordLeft = glyph.texCoordsMin.x; + float texCoordBottom = glyph.texCoordsMin.y; + float texCoordRight = glyph.texCoordsMax.x; + float texCoordTop = glyph.texCoordsMax.y; + + float posLeft = glyph.positionMin.x * uiText.fontSize + xPos; + float posBottom = glyph.positionMin.y * uiText.fontSize + yPos; + float posRight = glyph.positionMax.x * uiText.fontSize + xPos; + float posTop = glyph.positionMax.y * uiText.fontSize + yPos; + + std::array charVerts{ + posLeft, posBottom, texCoordLeft, texCoordBottom, posRight, posBottom, + texCoordRight, texCoordBottom, posLeft, posTop, texCoordLeft, texCoordTop, + posLeft, posTop, texCoordLeft, texCoordTop, posRight, posBottom, + texCoordRight, texCoordBottom, posRight, posTop, texCoordRight, texCoordTop}; + /// @note maybe possible to optimize with a memcpy, instead of iterating/pushing_back? + for (float f : charVerts) + { + verts.push_back(f); + } + xPos += advance; + } + vad.buffers[0] = window->renderDevice().createVertexBuffer(verts.size() * sizeof(float), + verts.data(), Usage::Default); + textImpl.vertexArray = window->renderDevice().createVertexArray(vad); + + if (optStretch.contains()) + { + element.size = {xPos, uiText.fontSize}; + } + } + } + }); + + cubos.system("draw UI text") + .tagged(uiDrawTag) + .call([](const State& state, const Assets& assets, Query query) { + for (auto [element, uiText, textImpl] : query) + { + if (textImpl.vertexArray != nullptr) + { + auto atlas = assets.read(uiText.fontAtlas); + glm::vec2 min = element.position - element.size * element.pivot; + glm::vec2 max = element.position + element.size * (glm::vec2(1.0F, 1.0F) - element.pivot); + element + .draw(state.drawType, textImpl.vertexArray, 0, textImpl.vertexCount, + PerElement{{min.x, max.x}, + {min.y, max.y}, + uiText.color, + element.layer * 100 + element.hierarchyDepth}) + .withTexture(0, atlas->texture(), state.sampler); + } + } + }); +} diff --git a/engine/src/ui/text/text.cpp b/engine/src/ui/text/text.cpp new file mode 100644 index 0000000000..e6665044fb --- /dev/null +++ b/engine/src/ui/text/text.cpp @@ -0,0 +1,19 @@ +#include +#include +#include +#include +#include + +#include + +using namespace cubos::engine; + +CUBOS_REFLECT_IMPL(UIText) +{ + return core::ecs::TypeBuilder("cubos::engine::UIText") + .withField("text", &UIText::text) + .withField("color", &UIText::color) + .withField("fontSize", &UIText::fontSize) + .withField("fontAtlas", &UIText::fontAtlas) + .build(); +} diff --git a/engine/src/ui/text/text_impl.cpp b/engine/src/ui/text/text_impl.cpp new file mode 100644 index 0000000000..141c06fb4b --- /dev/null +++ b/engine/src/ui/text/text_impl.cpp @@ -0,0 +1,13 @@ +#include "text_impl.hpp" + +#include +#include + +using namespace cubos::engine; + +CUBOS_REFLECT_IMPL(UITextImpl) +{ + return cubos::core::ecs::TypeBuilder("cubos::engine::UITextImpl") + .withField("vertexCount", &UITextImpl::vertexCount) + .build(); +} diff --git a/engine/src/ui/text/text_impl.hpp b/engine/src/ui/text/text_impl.hpp new file mode 100644 index 0000000000..78e2bd9ed7 --- /dev/null +++ b/engine/src/ui/text/text_impl.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include +#include + +namespace cubos::engine +{ + struct UITextImpl + { + CUBOS_REFLECT; + + core::gl::VertexArray vertexArray{nullptr}; + + size_t vertexCount{0}; + }; +} // namespace cubos::engine diff --git a/engine/src/ui/text/text_stretch.cpp b/engine/src/ui/text/text_stretch.cpp new file mode 100644 index 0000000000..b639a5ecf2 --- /dev/null +++ b/engine/src/ui/text/text_stretch.cpp @@ -0,0 +1,8 @@ +#include + +#include + +CUBOS_REFLECT_IMPL(cubos::engine::UITextStretch) +{ + return cubos::core::ecs::TypeBuilder("cubos::engine::UITextStretch").build(); +}