From d6b6dd955c8353dcdc80675555402581e9f7b0c8 Mon Sep 17 00:00:00 2001 From: Kbz-8 Date: Thu, 23 Nov 2023 14:37:42 +0100 Subject: [PATCH] new feature, font loading --- includes/mlx.h | 26 ++++++++++++++- src/core/application.h | 4 ++- src/core/application.inl | 5 +++ src/core/bridge.cpp | 29 +++++++++++++++-- src/core/graphics.h | 3 +- src/core/graphics.inl | 5 +++ src/renderer/core/render_core.cpp | 2 +- src/renderer/text_pipeline.cpp | 52 ++++++++++++++++++++++++++---- src/renderer/text_pipeline.h | 3 +- test/.gdb_history | 8 +++++ test/font.ttf | Bin 0 -> 14488 bytes test/main.c | 5 ++- 12 files changed, 127 insertions(+), 15 deletions(-) create mode 100644 test/.gdb_history create mode 100644 test/font.ttf diff --git a/includes/mlx.h b/includes/mlx.h index 3494443..7b6aa0d 100644 --- a/includes/mlx.h +++ b/includes/mlx.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/04 16:56:35 by maldavid #+# #+# */ -/* Updated: 2023/04/25 15:09:04 by maldavid ### ########.fr */ +/* Updated: 2023/11/23 14:32:06 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -274,6 +274,30 @@ void* mlx_bmp_file_to_image(void* mlx, char* filename, int* width, int* height); int mlx_string_put(void* mlx, void* win, int x, int y, int color, char* str); +/** + * @brief Loads a font to be used by `mlx_string_put` + * + * @param mlx Internal MLX application + * @param win Internal window + * @param filepath Filepath to the font + * + * @return (void) + */ +void mlx_set_font(void* mlx, void* win, char* filepath); + +/** + * @brief Loads a font to be used by `mlx_string_put` and scales it + * + * @param mlx Internal MLX application + * @param win Internal window + * @param filepath Filepath to the font + * @param scale Scale to apply to the font + * + * @return (void) + */ +void mlx_set_font_scale(void* mlx, void* win, char* filepath, float scale); + + /** * @brief Clears the given window (resets all rendered data) * diff --git a/src/core/application.h b/src/core/application.h index 96c3373..007e525 100644 --- a/src/core/application.h +++ b/src/core/application.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/04 21:49:46 by maldavid #+# #+# */ -/* Updated: 2023/11/17 11:57:42 by maldavid ### ########.fr */ +/* Updated: 2023/11/23 14:25:43 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -56,6 +56,8 @@ namespace mlx::core inline void loopHook(int (*f)(void*), void* param); inline void loopEnd() noexcept; + inline void loadFont(void* win, const std::filesystem::path& filepath, float scale); + void run() noexcept; ~Application(); diff --git a/src/core/application.inl b/src/core/application.inl index bcdf48c..85fbd8f 100644 --- a/src/core/application.inl +++ b/src/core/application.inl @@ -67,6 +67,11 @@ namespace mlx::core _graphics[*static_cast(win)]->stringPut(x, y, color, str); } + void Application::loadFont(void* win, const std::filesystem::path& filepath, float scale) + { + _graphics[*static_cast(win)]->loadFont(filepath, scale); + } + void Application::texturePut(void* win, void* img, int x, int y) { Texture* texture = static_cast(img); diff --git a/src/core/bridge.cpp b/src/core/bridge.cpp index 7b424fa..37a67ba 100644 --- a/src/core/bridge.cpp +++ b/src/core/bridge.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/04 17:35:20 by maldavid #+# #+# */ -/* Updated: 2023/11/14 11:43:30 by maldavid ### ########.fr */ +/* Updated: 2023/11/23 14:32:41 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -27,8 +27,11 @@ extern "C" return NULL; } mlx::Render_Core::get().init(); + mlx::core::Application* app = new mlx::core::Application; + if(app == nullptr) + mlx::core::error::report(e_kind::fatal_error, "Tout a pété"); init = true; - return new mlx::core::Application(); + return app; } void* mlx_new_window(mlx::core::Application* mlx, int w, int h, const char* title) @@ -169,6 +172,28 @@ extern "C" return 0; } + void mlx_set_font(mlx::core::Application* mlx, void* win, char* filepath) + { + std::filesystem::path file(filepath); + if(file.extension() != ".ttf" && file.extension() != ".tte") + { + mlx::core::error::report(e_kind::error, "TTF loader : not a truetype font file '%s'", filepath); + return; + } + mlx->loadFont(win, file, 16.f); + } + + void mlx_set_font_scale(mlx::core::Application* mlx, void* win, char* filepath, float scale) + { + std::filesystem::path file(filepath); + if(file.extension() != ".ttf" && file.extension() != ".tte") + { + mlx::core::error::report(e_kind::error, "TTF loader : not a truetype font file '%s'", filepath); + return; + } + mlx->loadFont(win, file, scale); + } + int mlx_clear_window(mlx::core::Application* mlx, void* win) { mlx->clearGraphicsSupport(win); diff --git a/src/core/graphics.h b/src/core/graphics.h index 2e43bd6..0f2860f 100644 --- a/src/core/graphics.h +++ b/src/core/graphics.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/04/02 14:49:49 by maldavid #+# #+# */ -/* Updated: 2023/11/14 11:39:55 by maldavid ### ########.fr */ +/* Updated: 2023/11/23 14:26:06 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -44,6 +44,7 @@ namespace mlx inline void pixelPut(int x, int y, uint32_t color) noexcept; inline void stringPut(int x, int y, int color, std::string str); inline void texturePut(Texture* texture, int x, int y); + inline void loadFont(const std::filesystem::path& filepath, float scale); ~GraphicsSupport(); diff --git a/src/core/graphics.inl b/src/core/graphics.inl index d7bc2aa..c205af9 100644 --- a/src/core/graphics.inl +++ b/src/core/graphics.inl @@ -46,4 +46,9 @@ namespace mlx { _textures_to_render.emplace(texture, x, y); } + + void GraphicsSupport::loadFont(const std::filesystem::path& filepath, float scale) + { + _text_put_pipeline->loadFont(filepath, scale); + } } diff --git a/src/renderer/core/render_core.cpp b/src/renderer/core/render_core.cpp index 4d0593e..13e46cc 100644 --- a/src/renderer/core/render_core.cpp +++ b/src/renderer/core/render_core.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/12/17 23:33:34 by maldavid #+# #+# */ -/* Updated: 2023/11/16 14:06:46 by maldavid ### ########.fr */ +/* Updated: 2023/11/20 12:04:51 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/src/renderer/text_pipeline.cpp b/src/renderer/text_pipeline.cpp index e91ae8e..1d6497a 100644 --- a/src/renderer/text_pipeline.cpp +++ b/src/renderer/text_pipeline.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/04/06 16:41:13 by maldavid #+# #+# */ -/* Updated: 2023/11/14 05:36:09 by maldavid ### ########.fr */ +/* Updated: 2023/11/23 14:26:48 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,11 +14,14 @@ #include #include +#include #include #define STB_TRUETYPE_IMPLEMENTATION #include +constexpr const int RANGE = 1024; + namespace mlx { TextDrawData::TextDrawData(std::string _text, int _color, int _x, int _y) : @@ -40,7 +43,7 @@ namespace mlx continue; stbtt_aligned_quad q; - stbtt_GetBakedQuad(cdata.data(), 512, 512, c - 32, &stb_x, &stb_y, &q, 1); + stbtt_GetBakedQuad(cdata.data(), RANGE, RANGE, c - 32, &stb_x, &stb_y, &q, 1); std::size_t index = vertexData.size(); @@ -59,25 +62,59 @@ namespace mlx std::shared_ptr text_data = std::make_shared(); text_data->init(text, std::move(vertexData), std::move(indexData)); id = library.addTextToLibrary(text_data); + + #ifdef DEBUG + core::error::report(e_kind::message, "Text put : registered new text to render"); + #endif } void TextPutPipeline::init(Renderer* renderer) noexcept { _renderer = renderer; - uint8_t tmp_bitmap[512 * 512]; - uint8_t vulkan_bitmap[(512 * 512) * 4]; - stbtt_BakeFontBitmap(dogica_ttf, 0, 6.0f, tmp_bitmap, 512, 512, 32, 96, _cdata.data()); - for(int i = 0, j = 0; i < 512 * 512; i++, j += 4) + uint8_t tmp_bitmap[RANGE * RANGE]; + uint8_t vulkan_bitmap[RANGE * RANGE * 4]; + stbtt_BakeFontBitmap(dogica_ttf, 0, 6.0f, tmp_bitmap, RANGE, RANGE, 32, 96, _cdata.data()); + for(int i = 0, j = 0; i < RANGE * RANGE; i++, j += 4) { vulkan_bitmap[j + 0] = tmp_bitmap[i]; vulkan_bitmap[j + 1] = tmp_bitmap[i]; vulkan_bitmap[j + 2] = tmp_bitmap[i]; vulkan_bitmap[j + 3] = tmp_bitmap[i]; } - _atlas.create(vulkan_bitmap, 512, 512, VK_FORMAT_R8G8B8A8_UNORM, "__mlx_texts_pipeline_texture_atlas", true); + _atlas.create(vulkan_bitmap, RANGE, RANGE, VK_FORMAT_R8G8B8A8_UNORM, "__mlx_texts_pipeline_texture_atlas", true); _atlas.setDescriptor(renderer->getFragDescriptorSet().duplicate()); } + void TextPutPipeline::loadFont(const std::filesystem::path& filepath, float scale) + { + uint8_t tmp_bitmap[RANGE * RANGE]; + uint8_t vulkan_bitmap[RANGE * RANGE * 4]; + + std::ifstream file(filepath, std::ios::binary); + if(!file.is_open()) + { + core::error::report(e_kind::error, "Font load : cannot open font file, %s", filepath.string().c_str()); + return; + } + std::ifstream::pos_type fileSize = std::filesystem::file_size(filepath); + file.seekg(0, std::ios::beg); + std::vector bytes(fileSize); + file.read(reinterpret_cast(bytes.data()), fileSize); + file.close(); + + stbtt_BakeFontBitmap(bytes.data(), 0, scale, tmp_bitmap, RANGE, RANGE, 32, 96, _cdata.data()); + for(int i = 0, j = 0; i < RANGE * RANGE; i++, j += 4) + { + vulkan_bitmap[j + 0] = tmp_bitmap[i]; + vulkan_bitmap[j + 1] = tmp_bitmap[i]; + vulkan_bitmap[j + 2] = tmp_bitmap[i]; + vulkan_bitmap[j + 3] = tmp_bitmap[i]; + } + destroy(); + _atlas.create(vulkan_bitmap, RANGE, RANGE, VK_FORMAT_R8G8B8A8_UNORM, "__mlx_texts_pipeline_texture_atlas", true); + _atlas.setDescriptor(_renderer->getFragDescriptorSet().duplicate()); + } + void TextPutPipeline::put(int x, int y, int color, std::string str) { auto res = _drawlist.emplace(std::move(str), color, x, y); @@ -99,6 +136,7 @@ namespace mlx void TextPutPipeline::destroy() noexcept { _library.clearLibrary(); + _drawlist.clear(); _atlas.destroy(); } } diff --git a/src/renderer/text_pipeline.h b/src/renderer/text_pipeline.h index e3e3052..2e68a9a 100644 --- a/src/renderer/text_pipeline.h +++ b/src/renderer/text_pipeline.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/04/06 16:24:11 by maldavid #+# #+# */ -/* Updated: 2023/11/14 12:43:45 by maldavid ### ########.fr */ +/* Updated: 2023/11/23 14:26:34 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -60,6 +60,7 @@ namespace mlx void put(int x, int y, int color, std::string str); inline VkDescriptorSet getDescriptorSet() noexcept { return _atlas.getSet(); } inline void clear() { _drawlist.clear(); _library.clearLibrary(); } + void loadFont(const std::filesystem::path& filepath, float scale); void render(); void destroy() noexcept; diff --git a/test/.gdb_history b/test/.gdb_history new file mode 100644 index 0000000..1febdf8 --- /dev/null +++ b/test/.gdb_history @@ -0,0 +1,8 @@ +run +q +run +bt +q +run +bt +q diff --git a/test/font.ttf b/test/font.ttf new file mode 100644 index 0000000000000000000000000000000000000000..85c14725a3bf6d67aaf0f03292f9b763c1654f07 GIT binary patch literal 14488 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 Z*c*kN@$GAW{e3oGeYSI$CI24pe*xM150(G` literal 0 HcmV?d00001 diff --git a/test/main.c b/test/main.c index 562e762..81a3577 100644 --- a/test/main.c +++ b/test/main.c @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/04 17:55:21 by maldavid #+# #+# */ -/* Updated: 2023/11/17 09:08:51 by maldavid ### ########.fr */ +/* Updated: 2023/11/23 14:32:15 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -43,7 +43,10 @@ int update(t_mlx *mlx) } i++; if (i == 5000) + { mlx_clear_window(mlx->mlx, mlx->win); + mlx_set_font_scale(mlx->mlx, mlx->win, "font.ttf", 16.f); + } return (0); }