diff --git a/example/build.sh b/example/build.sh old mode 100644 new mode 100755 diff --git a/example/main.c b/example/main.c index 31191c6..ee817bb 100644 --- a/example/main.c +++ b/example/main.c @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/04 17:55:21 by maldavid #+# #+# */ -/* Updated: 2024/01/16 08:03:37 by maldavid ### ########.fr */ +/* Updated: 2024/01/18 09:58:15 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -135,25 +135,25 @@ int main(void) mlx_on_event(mlx.mlx, mlx.win, MLX_KEYDOWN, key_hook, &mlx); mlx_on_event(mlx.mlx, mlx.win, MLX_WINDOW_EVENT, window_hook, &mlx); - + mlx.logo_png = mlx_png_file_to_image(mlx.mlx, "42_logo.png", &dummy, &dummy); mlx.logo_bmp = mlx_bmp_file_to_image(mlx.mlx, "42_logo.bmp", &dummy, &dummy); mlx.logo_jpg = mlx_jpg_file_to_image(mlx.mlx, "42_logo.jpg", &dummy, &dummy); - + mlx_pixel_put(mlx.mlx, mlx.win, 200, 10, 0xFFFF00FF); mlx_put_image_to_window(mlx.mlx, mlx.win, mlx.logo_png, 10, 190); - + mlx.img = create_image(&mlx); - mlx_string_put(mlx.mlx, mlx.win, 20, 20, 0xFF0020FF, "that text will disappear"); mlx_set_font_scale(mlx.mlx, mlx.win, "font.ttf", 16.f); - + mlx_string_put(mlx.mlx, mlx.win, 20, 20, 0xFF0020FF, "that text will disappear"); + mlx_loop_hook(mlx.mlx, update, &mlx); mlx_loop(mlx.mlx); - - mlx_get_screens_size(mlx.mlx, &w, &h); + + mlx_get_screens_size(mlx.mlx, mlx.win, &w, &h); printf("screen size : %dx%d\n", w, h); - + mlx_destroy_image(mlx.mlx, mlx.logo_png); mlx_destroy_image(mlx.mlx, mlx.logo_jpg); mlx_destroy_image(mlx.mlx, mlx.logo_bmp); diff --git a/example/run.sh b/example/run.sh old mode 100644 new mode 100755 diff --git a/includes/mlx.h b/includes/mlx.h index 6c5c733..809058a 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: 2024/01/05 19:53:13 by maldavid ### ########.fr */ +/* Updated: 2024/01/18 09:55:36 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -349,15 +349,16 @@ MLX_API int mlx_destroy_display(void* mlx); /** - * @brief Get screen size + * @brief Get the size of the screen the given window is on * * @param mlx Internal MLX application + * @param win Internal window * @param w Get width size * @param h Get height size * * @return (int) Always return 0, made this to copy the behaviour of the original MLX */ -MLX_API int mlx_get_screens_size(void* mlx, int* w, int* h); +MLX_API int mlx_get_screens_size(void* mlx, void* win, int* w, int* h); #ifdef __cplusplus } diff --git a/src/core/application.cpp b/src/core/application.cpp index 514df83..cd33ee8 100644 --- a/src/core/application.cpp +++ b/src/core/application.cpp @@ -6,12 +6,13 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/04 22:10:52 by maldavid #+# #+# */ -/* Updated: 2024/01/11 05:08:42 by maldavid ### ########.fr */ +/* Updated: 2024/01/18 09:44:26 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ #include "application.h" #include +#include #include #include #include @@ -84,6 +85,7 @@ namespace mlx::core Application::~Application() { TextLibrary::get().clearLibrary(); + FontLibrary::get().clearLibrary(); if(__drop_sdl_responsability) return; SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_EVENTS); diff --git a/src/core/application.h b/src/core/application.h index 6b4ee97..fee2c33 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: 2024/01/10 19:57:12 by maldavid ### ########.fr */ +/* Updated: 2024/01/18 09:56:04 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -39,7 +39,7 @@ namespace mlx::core inline void onEvent(void* win, int event, int (*funct_ptr)(int, void*), void* param) noexcept; - inline void getScreenSize(int* w, int* h) noexcept; + inline void getScreenSize(void* win, int* w, int* h) noexcept; inline void* newGraphicsSuport(std::size_t w, std::size_t h, const char* title); inline void clearGraphicsSupport(void* win); diff --git a/src/core/application.inl b/src/core/application.inl index d25cb1d..9b27349 100644 --- a/src/core/application.inl +++ b/src/core/application.inl @@ -55,10 +55,11 @@ namespace mlx::core _in->onEvent(_graphics[*static_cast(win)]->getWindow()->getID(), event, funct_ptr, param); } - void Application::getScreenSize(int* w, int* h) noexcept + void Application::getScreenSize(void* win, int* w, int* h) noexcept { + CHECK_WINDOW_PTR(win); SDL_DisplayMode DM; - SDL_GetDesktopDisplayMode(0, &DM); + SDL_GetDesktopDisplayMode(SDL_GetWindowDisplayIndex(_graphics[*static_cast(win)]->getWindow()->getNativeWindow()), &DM); *w = DM.w; *h = DM.h; } diff --git a/src/core/bridge.cpp b/src/core/bridge.cpp index e6d5ca0..5e7b962 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: 2024/01/16 08:20:17 by maldavid ### ########.fr */ +/* Updated: 2024/01/18 09:55:53 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -271,10 +271,10 @@ extern "C" return 0; } - int mlx_get_screens_size(void* mlx, int* w, int* h) + int mlx_get_screens_size(void* mlx, void* win, int* w, int* h) { MLX_CHECK_APPLICATION_POINTER(mlx); - static_cast(mlx)->getScreenSize(w, h); + static_cast(mlx)->getScreenSize(win, w, h); return 0; } } diff --git a/src/renderer/core/memory.cpp b/src/renderer/core/memory.cpp index 1e3ede0..ccb8ed0 100644 --- a/src/renderer/core/memory.cpp +++ b/src/renderer/core/memory.cpp @@ -6,7 +6,7 @@ /* By: kbz_8 +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/10/20 22:02:37 by kbz_8 #+# #+# */ -/* Updated: 2024/01/10 21:54:35 by maldavid ### ########.fr */ +/* Updated: 2024/01/18 10:11:02 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -98,7 +98,7 @@ namespace mlx vmaSetAllocationName(_allocator, allocation, name); } #ifdef DEBUG - core::error::report(e_kind::message, "Graphics Allocator : created new buffer"); + core::error::report(e_kind::message, "Graphics Allocator : created new buffer '%s'", name); #endif _active_buffers_allocations++; return allocation; @@ -128,7 +128,7 @@ namespace mlx vmaSetAllocationName(_allocator, allocation, name); } #ifdef DEBUG - core::error::report(e_kind::message, "Graphics Allocator : created new image"); + core::error::report(e_kind::message, "Graphics Allocator : created new image '%s'", name); #endif _active_images_allocations++; return allocation; diff --git a/src/renderer/descriptors/vk_descriptor_pool.cpp b/src/renderer/descriptors/vk_descriptor_pool.cpp index 188403f..03df39e 100644 --- a/src/renderer/descriptors/vk_descriptor_pool.cpp +++ b/src/renderer/descriptors/vk_descriptor_pool.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/01/23 18:34:23 by maldavid #+# #+# */ -/* Updated: 2024/01/03 13:13:54 by maldavid ### ########.fr */ +/* Updated: 2024/01/18 10:19:55 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -22,6 +22,7 @@ namespace mlx poolInfo.poolSizeCount = n; poolInfo.pPoolSizes = size; poolInfo.maxSets = 8192; + poolInfo.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; VkResult res = vkCreateDescriptorPool(Render_Core::get().getDevice().get(), &poolInfo, nullptr, &_pool); if(res != VK_SUCCESS) diff --git a/src/renderer/descriptors/vk_descriptor_pool.h b/src/renderer/descriptors/vk_descriptor_pool.h index 82cf9c4..2c624ef 100644 --- a/src/renderer/descriptors/vk_descriptor_pool.h +++ b/src/renderer/descriptors/vk_descriptor_pool.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/01/23 18:32:43 by maldavid #+# #+# */ -/* Updated: 2024/01/03 15:27:45 by maldavid ### ########.fr */ +/* Updated: 2024/01/18 10:22:20 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -28,6 +28,8 @@ namespace mlx inline VkDescriptorPool& operator()() noexcept { return _pool; } inline VkDescriptorPool& get() noexcept { return _pool; } + inline bool isInit() const noexcept { return _pool != VK_NULL_HANDLE; } + private: VkDescriptorPool _pool = VK_NULL_HANDLE; }; diff --git a/src/renderer/descriptors/vk_descriptor_set.cpp b/src/renderer/descriptors/vk_descriptor_set.cpp index 423db02..8af5877 100644 --- a/src/renderer/descriptors/vk_descriptor_set.cpp +++ b/src/renderer/descriptors/vk_descriptor_set.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/01/23 18:40:44 by maldavid #+# #+# */ -/* Updated: 2024/01/10 18:28:34 by maldavid ### ########.fr */ +/* Updated: 2024/01/18 10:22:10 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -106,8 +106,24 @@ namespace mlx { return _desc_set[_renderer->getActiveImageIndex()]; } + VkDescriptorSet& DescriptorSet::get() noexcept { return _desc_set[_renderer->getActiveImageIndex()]; } + + void DescriptorSet::destroy() noexcept + { + MLX_PROFILE_FUNCTION(); + if(_pool->isInit()) + vkFreeDescriptorSets(Render_Core::get().getDevice().get(), _pool->get(), _desc_set.size(), _desc_set.data()); + for(auto& set : _desc_set) + { + if(set != VK_NULL_HANDLE) + set = VK_NULL_HANDLE; + } + #ifdef DEBUG + core::error::report(e_kind::message, "Vulkan : destroyed descriptor set"); + #endif + } } diff --git a/src/renderer/descriptors/vk_descriptor_set.h b/src/renderer/descriptors/vk_descriptor_set.h index d555d5c..5f2191e 100644 --- a/src/renderer/descriptors/vk_descriptor_set.h +++ b/src/renderer/descriptors/vk_descriptor_set.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/01/23 18:39:36 by maldavid #+# #+# */ -/* Updated: 2024/01/03 15:27:50 by maldavid ### ########.fr */ +/* Updated: 2024/01/18 10:13:25 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -35,6 +35,8 @@ namespace mlx VkDescriptorSet& operator()() noexcept; VkDescriptorSet& get() noexcept; + void destroy() noexcept; + private: std::array _desc_set; class DescriptorPool* _pool = nullptr; diff --git a/src/renderer/images/texture.cpp b/src/renderer/images/texture.cpp index 2206f64..16d693f 100644 --- a/src/renderer/images/texture.cpp +++ b/src/renderer/images/texture.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/03/31 18:03:35 by maldavid #+# #+# */ -/* Updated: 2024/01/11 01:20:29 by maldavid ### ########.fr */ +/* Updated: 2024/01/18 10:18:22 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -155,6 +155,7 @@ namespace mlx { MLX_PROFILE_FUNCTION(); Image::destroy(); + _set.destroy(); if(_buf_map.has_value()) _buf_map->destroy(); _vbo.destroy(); diff --git a/src/renderer/images/texture_atlas.cpp b/src/renderer/images/texture_atlas.cpp index b6eb61b..c03d712 100644 --- a/src/renderer/images/texture_atlas.cpp +++ b/src/renderer/images/texture_atlas.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/04/07 16:40:09 by maldavid #+# #+# */ -/* Updated: 2023/12/31 00:52:01 by maldavid ### ########.fr */ +/* Updated: 2024/01/18 10:18:08 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -51,5 +51,6 @@ namespace mlx void TextureAtlas::destroy() noexcept { Image::destroy(); + _set.destroy(); } } diff --git a/src/renderer/images/texture_atlas.h b/src/renderer/images/texture_atlas.h index 5fd4da9..bc465d7 100644 --- a/src/renderer/images/texture_atlas.h +++ b/src/renderer/images/texture_atlas.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/04/07 16:36:33 by maldavid #+# #+# */ -/* Updated: 2024/01/08 21:42:31 by maldavid ### ########.fr */ +/* Updated: 2024/01/18 02:47:30 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -30,7 +30,8 @@ namespace mlx void destroy() noexcept override; inline void setDescriptor(DescriptorSet&& set) noexcept { _set = set; } - inline VkDescriptorSet getSet() noexcept { return _set.isInit() ? _set.get() : VK_NULL_HANDLE; } + inline VkDescriptorSet getVkSet() noexcept { return _set.isInit() ? _set.get() : VK_NULL_HANDLE; } + inline DescriptorSet getSet() noexcept { return _set; } inline void updateSet(int binding) noexcept { _set.writeDescriptor(binding, *this); _has_been_updated = true; } inline bool hasBeenUpdated() const noexcept { return _has_been_updated; } inline constexpr void resetUpdate() noexcept { _has_been_updated = false; } diff --git a/src/renderer/images/vk_image.cpp b/src/renderer/images/vk_image.cpp index 3cf0592..412387e 100644 --- a/src/renderer/images/vk_image.cpp +++ b/src/renderer/images/vk_image.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/01/25 11:59:07 by maldavid #+# #+# */ -/* Updated: 2024/01/07 01:17:54 by maldavid ### ########.fr */ +/* Updated: 2024/01/18 09:47:26 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -252,16 +252,16 @@ namespace mlx void Image::destroy() noexcept { // not creating destroyer in `create` as some image may be copied (and so `this` will be invalid) - CmdResource::setDestroyer([this]() - { + //CmdResource::setDestroyer([this]() + //{ destroySampler(); destroyImageView(); if(_image != VK_NULL_HANDLE) Render_Core::get().getAllocator().destroyImage(_allocation, _image); _image = VK_NULL_HANDLE; - }); - CmdResource::requireDestroy(); + //}); + //CmdResource::requireDestroy(); } uint32_t formatSize(VkFormat format) diff --git a/src/renderer/texts/font.cpp b/src/renderer/texts/font.cpp index 35916a9..d025e12 100644 --- a/src/renderer/texts/font.cpp +++ b/src/renderer/texts/font.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/12/11 22:06:09 by kbz_8 #+# #+# */ -/* Updated: 2024/01/16 09:11:26 by maldavid ### ########.fr */ +/* Updated: 2024/01/18 13:16:18 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -19,51 +19,43 @@ constexpr const int RANGE = 1024; namespace mlx { - Font::Font(Renderer& renderer, const std::filesystem::path& path, float scale) : _name(path.string()), _scale(scale) + Font::Font(Renderer& renderer, const std::filesystem::path& path, float scale) : _name(path.string()), _renderer(renderer), _scale(scale) { - MLX_PROFILE_FUNCTION(); - std::vector tmp_bitmap(RANGE * RANGE); - std::vector vulkan_bitmap(RANGE * RANGE * 4); - - std::ifstream file(path, std::ios::binary); - if(!file.is_open()) - { - core::error::report(e_kind::error, "Font load : cannot open font file, %s", _name.c_str()); - return; - } - std::ifstream::pos_type fileSize = std::filesystem::file_size(path); - file.seekg(0, std::ios::beg); - std::vector bytes(fileSize); - file.read(reinterpret_cast(bytes.data()), fileSize); - file.close(); - - stbtt_pack_context pc; - stbtt_PackBegin(&pc, tmp_bitmap.data(), RANGE, RANGE, RANGE, 1, nullptr); - stbtt_PackFontRange(&pc, bytes.data(), 0, scale, 32, 96, _cdata.data()); - stbtt_PackEnd(&pc); - 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]; - } - #ifdef DEBUG - _atlas.create(vulkan_bitmap.data(), RANGE, RANGE, VK_FORMAT_R8G8B8A8_UNORM, std::string(_name + "_font_altas").c_str(), true); - #else - _atlas.create(vulkan_bitmap.data(), RANGE, RANGE, VK_FORMAT_R8G8B8A8_UNORM, nullptr, true); - #endif - _atlas.setDescriptor(renderer.getFragDescriptorSet().duplicate()); + _build_data = path; } - Font::Font(class Renderer& renderer, const std::string& name, const std::vector& ttf_data, float scale) : _name(name), _scale(scale) + Font::Font(class Renderer& renderer, const std::string& name, const std::vector& ttf_data, float scale) : _name(name), _renderer(renderer), _scale(scale) + { + _build_data = ttf_data; + } + + void Font::buildFont() { MLX_PROFILE_FUNCTION(); + std::vector file_bytes; + if(std::holds_alternative(_build_data)) + { + std::ifstream file(std::get(_build_data), std::ios::binary); + if(!file.is_open()) + { + core::error::report(e_kind::error, "Font load : cannot open font file, %s", _name.c_str()); + return; + } + std::ifstream::pos_type fileSize = std::filesystem::file_size(std::get(_build_data)); + file.seekg(0, std::ios::beg); + file_bytes.resize(fileSize); + file.read(reinterpret_cast(file_bytes.data()), fileSize); + file.close(); + } + std::vector tmp_bitmap(RANGE * RANGE); std::vector vulkan_bitmap(RANGE * RANGE * 4); stbtt_pack_context pc; stbtt_PackBegin(&pc, tmp_bitmap.data(), RANGE, RANGE, RANGE, 1, nullptr); - stbtt_PackFontRange(&pc, ttf_data.data(), 0, scale, 32, 96, _cdata.data()); + if(std::holds_alternative(_build_data)) + stbtt_PackFontRange(&pc, file_bytes.data(), 0, _scale, 32, 96, _cdata.data()); + else + stbtt_PackFontRange(&pc, std::get>(_build_data).data(), 0, _scale, 32, 96, _cdata.data()); stbtt_PackEnd(&pc); for(int i = 0, j = 0; i < RANGE * RANGE; i++, j += 4) { @@ -77,12 +69,20 @@ namespace mlx #else _atlas.create(vulkan_bitmap.data(), RANGE, RANGE, VK_FORMAT_R8G8B8A8_UNORM, nullptr, true); #endif - _atlas.setDescriptor(renderer.getFragDescriptorSet().duplicate()); + _atlas.setDescriptor(_renderer.getFragDescriptorSet().duplicate()); + _is_init = true; + } + + void Font::destroy() + { + MLX_PROFILE_FUNCTION(); + _atlas.destroy(); + _is_init = false; } Font::~Font() { - MLX_PROFILE_FUNCTION(); - _atlas.destroy(); + if(_is_init) + destroy(); } } diff --git a/src/renderer/texts/font.h b/src/renderer/texts/font.h index 02780fa..9e39cde 100644 --- a/src/renderer/texts/font.h +++ b/src/renderer/texts/font.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/12/11 21:17:04 by kbz_8 #+# #+# */ -/* Updated: 2024/01/16 09:14:53 by maldavid ### ########.fr */ +/* Updated: 2024/01/18 13:15:55 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,28 +17,39 @@ #include #include #include +#include namespace mlx { class Font { + friend class FontLibrary; public: Font() = delete; Font(class Renderer& renderer, const std::filesystem::path& path, float scale); Font(class Renderer& renderer, const std::string& name, const std::vector& ttf_data, float scale); + inline const std::string& getName() const { return _name; } inline float getScale() const noexcept { return _scale; } inline const std::array& getCharData() const { return _cdata; } inline const TextureAtlas& getAtlas() const noexcept { return _atlas; } inline bool operator==(const Font& rhs) const { return rhs._name == _name && rhs._scale == _scale; } inline bool operator!=(const Font& rhs) const { return rhs._name != _name || rhs._scale != _scale; } + void destroy(); + ~Font(); + private: + void buildFont(); + private: std::array _cdata; TextureAtlas _atlas; + std::variant> _build_data; std::string _name; + class Renderer& _renderer; float _scale = 0; + bool _is_init = false; }; } diff --git a/src/renderer/texts/font_library.cpp b/src/renderer/texts/font_library.cpp new file mode 100644 index 0000000..e3a04c0 --- /dev/null +++ b/src/renderer/texts/font_library.cpp @@ -0,0 +1,69 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* font_library.cpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maldavid +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/18 09:28:14 by maldavid #+# #+# */ +/* Updated: 2024/01/18 13:07:48 by maldavid ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include +#include +#include +#include +#include +#include + +namespace mlx +{ + std::shared_ptr FontLibrary::getFontData(FontID id) + { + MLX_PROFILE_FUNCTION(); + if(!_cache.count(id) || std::find(_invalid_ids.begin(), _invalid_ids.end(), id) != _invalid_ids.end()) + core::error::report(e_kind::fatal_error, "Font Library : wrong font ID '%d'", id); + return _cache[id]; + } + + FontID FontLibrary::addFontToLibrary(std::shared_ptr font) + { + MLX_PROFILE_FUNCTION(); + auto it = std::find_if(_cache.begin(), _cache.end(), [&](const std::pair>& v) + { + return v.second->getScale() == font->getScale() && + v.second->getName() == font->getName() && + std::find(_invalid_ids.begin(), _invalid_ids.end(), v.first) == _invalid_ids.end(); + }); + if(it != _cache.end()) + return it->first; + font->buildFont(); + _cache[_current_id] = font; + _current_id++; + return _current_id - 1; + } + + void FontLibrary::removeFontFromLibrary(FontID id) + { + MLX_PROFILE_FUNCTION(); + if(!_cache.count(id) || std::find(_invalid_ids.begin(), _invalid_ids.end(), id) != _invalid_ids.end()) + { + core::error::report(e_kind::warning, "Font Library : trying to remove a font with an unkown or invalid ID '%d'", id); + return; + } + _cache[id]->destroy(); + _invalid_ids.push_back(id); + } + + void FontLibrary::clearLibrary() + { + MLX_PROFILE_FUNCTION(); + for(auto& [id, font] : _cache) + { + font->destroy(); + _invalid_ids.push_back(id); + } + // do not `_cache.clear();` as it releases the fonts and may not destroy the texture atlas that is in use by command buffers + } +} diff --git a/src/renderer/texts/font_library.h b/src/renderer/texts/font_library.h new file mode 100644 index 0000000..9a1d4dc --- /dev/null +++ b/src/renderer/texts/font_library.h @@ -0,0 +1,52 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* font_library.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maldavid +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/18 09:26:03 by maldavid #+# #+# */ +/* Updated: 2024/01/18 09:33:30 by maldavid ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef __MLX_FONT_LIBRARY__ +#define __MLX_FONT_LIBRARY__ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace mlx +{ + using FontID = uint32_t; + constexpr FontID nullfont = 0; + + class FontLibrary : public Singleton + { + friend class Singleton; + + public: + std::shared_ptr getFontData(FontID id); + FontID addFontToLibrary(std::shared_ptr font); + void removeFontFromLibrary(FontID id); + + void clearLibrary(); + + private: + FontLibrary() = default; + ~FontLibrary() = default; + + private: + std::unordered_map> _cache; + std::vector _invalid_ids; + FontID _current_id = 1; + }; +} + +#endif diff --git a/src/renderer/texts/text.cpp b/src/renderer/texts/text.cpp index bf1823d..b26c01c 100644 --- a/src/renderer/texts/text.cpp +++ b/src/renderer/texts/text.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/01/11 00:11:56 by maldavid #+# #+# */ -/* Updated: 2024/01/11 03:31:57 by maldavid ### ########.fr */ +/* Updated: 2024/01/18 13:56:50 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,15 +16,21 @@ namespace mlx { - void Text::init(std::string text, Font const* font, std::vector vbo_data, std::vector ibo_data) + void Text::init(std::string text, FontID font, std::vector vbo_data, std::vector ibo_data) { MLX_PROFILE_FUNCTION(); _text = std::move(text); _font = font; #ifdef DEBUG + std::string debug_name = _text; + for(char& c : debug_name) + { + if(c == ' ' || c == '"' || c == '\'') + c = '_'; + } for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) - _vbo[i].create(sizeof(Vertex) * vbo_data.size(), static_cast(vbo_data.data()), _text.c_str()); - _ibo.create(sizeof(uint16_t) * ibo_data.size(), ibo_data.data(), _text.c_str()); + _vbo[i].create(sizeof(Vertex) * vbo_data.size(), static_cast(vbo_data.data()), debug_name.c_str()); + _ibo.create(sizeof(uint16_t) * ibo_data.size(), ibo_data.data(), debug_name.c_str()); #else for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) _vbo[i].create(sizeof(Vertex) * vbo_data.size(), static_cast(vbo_data.data()), nullptr); diff --git a/src/renderer/texts/text.h b/src/renderer/texts/text.h index eff6f8a..44bd7a1 100644 --- a/src/renderer/texts/text.h +++ b/src/renderer/texts/text.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/01/11 00:09:04 by maldavid #+# #+# */ -/* Updated: 2024/01/11 00:13:25 by maldavid ### ########.fr */ +/* Updated: 2024/01/18 09:37:42 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -26,9 +27,9 @@ namespace mlx public: Text() = default; - void init(std::string text, Font const* font, std::vector vbo_data, std::vector ibo_data); + void init(std::string text, FontID font, std::vector vbo_data, std::vector ibo_data); void bind(class Renderer& renderer) noexcept; - inline const Font& getFontInUse() const noexcept { return *_font; } + inline FontID getFontInUse() const noexcept { return _font; } void updateVertexData(int frame, std::vector vbo_data); inline uint32_t getIBOsize() noexcept { return _ibo.getSize(); } inline const std::string& getText() const { return _text; } @@ -40,7 +41,7 @@ namespace mlx std::array _vbo; C_IBO _ibo; std::string _text; - Font const* _font = nullptr; + FontID _font = nullfont; }; } diff --git a/src/renderer/texts/text_descriptor.cpp b/src/renderer/texts/text_descriptor.cpp index bc1f35a..4db185a 100644 --- a/src/renderer/texts/text_descriptor.cpp +++ b/src/renderer/texts/text_descriptor.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/01/11 00:23:11 by maldavid #+# #+# */ -/* Updated: 2024/01/11 03:40:54 by maldavid ### ########.fr */ +/* Updated: 2024/01/18 09:44:54 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -33,7 +33,7 @@ namespace mlx TextDrawDescriptor::TextDrawDescriptor(std::string text, uint32_t _color, int _x, int _y) : color(_color), x(_x), y(_y), _text(std::move(text)) {} - void TextDrawDescriptor::init(Font* const font) noexcept + void TextDrawDescriptor::init(FontID font) noexcept { MLX_PROFILE_FUNCTION(); std::vector vertexData; @@ -42,34 +42,38 @@ namespace mlx float stb_x = 0.0f; float stb_y = 0.0f; - for(char c : _text) { - if(c < 32) - continue; + std::shared_ptr font_data = FontLibrary::get().getFontData(font); - stbtt_aligned_quad q; - stbtt_GetPackedQuad(font->getCharData().data(), RANGE, RANGE, c - 32, &stb_x, &stb_y, &q, 1); + for(char c : _text) + { + if(c < 32) + continue; - std::size_t index = vertexData.size(); + stbtt_aligned_quad q; + stbtt_GetPackedQuad(font_data->getCharData().data(), RANGE, RANGE, c - 32, &stb_x, &stb_y, &q, 1); - glm::vec4 vertex_color = { - static_cast((color & 0x000000FF)) / 255.f, - static_cast((color & 0x0000FF00) >> 8) / 255.f, - static_cast((color & 0x00FF0000) >> 16) / 255.f, - static_cast((color & 0xFF000000) >> 24) / 255.f - }; + std::size_t index = vertexData.size(); - vertexData.emplace_back(glm::vec2{q.x0, q.y0}, vertex_color, glm::vec2{q.s0, q.t0}); - vertexData.emplace_back(glm::vec2{q.x1, q.y0}, vertex_color, glm::vec2{q.s1, q.t0}); - vertexData.emplace_back(glm::vec2{q.x1, q.y1}, vertex_color, glm::vec2{q.s1, q.t1}); - vertexData.emplace_back(glm::vec2{q.x0, q.y1}, vertex_color, glm::vec2{q.s0, q.t1}); + glm::vec4 vertex_color = { + static_cast((color & 0x000000FF)) / 255.f, + static_cast((color & 0x0000FF00) >> 8) / 255.f, + static_cast((color & 0x00FF0000) >> 16) / 255.f, + static_cast((color & 0xFF000000) >> 24) / 255.f + }; - indexData.emplace_back(index + 0); - indexData.emplace_back(index + 1); - indexData.emplace_back(index + 2); - indexData.emplace_back(index + 2); - indexData.emplace_back(index + 3); - indexData.emplace_back(index + 0); + vertexData.emplace_back(glm::vec2{q.x0, q.y0}, vertex_color, glm::vec2{q.s0, q.t0}); + vertexData.emplace_back(glm::vec2{q.x1, q.y0}, vertex_color, glm::vec2{q.s1, q.t0}); + vertexData.emplace_back(glm::vec2{q.x1, q.y1}, vertex_color, glm::vec2{q.s1, q.t1}); + vertexData.emplace_back(glm::vec2{q.x0, q.y1}, vertex_color, glm::vec2{q.s0, q.t1}); + + indexData.emplace_back(index + 0); + indexData.emplace_back(index + 1); + indexData.emplace_back(index + 2); + indexData.emplace_back(index + 2); + indexData.emplace_back(index + 3); + indexData.emplace_back(index + 0); + } } std::shared_ptr text_data = std::make_shared(); text_data->init(_text, font, std::move(vertexData), std::move(indexData)); @@ -84,13 +88,14 @@ namespace mlx { MLX_PROFILE_FUNCTION(); std::shared_ptr draw_data = TextLibrary::get().getTextData(id); - TextureAtlas& atlas = const_cast(draw_data->getFontInUse().getAtlas()); + std::shared_ptr font_data = FontLibrary::get().getFontData(draw_data->getFontInUse()); + TextureAtlas& atlas = const_cast(font_data->getAtlas()); draw_data->bind(renderer); - if(atlas.getSet() == VK_NULL_HANDLE) + if(!atlas.getSet().isInit()) atlas.setDescriptor(renderer.getFragDescriptorSet().duplicate()); if(!atlas.hasBeenUpdated()) atlas.updateSet(0); - sets[1] = const_cast(atlas).getSet(); + sets[1] = const_cast(atlas).getVkSet(); vkCmdBindDescriptorSets(renderer.getActiveCmdBuffer().get(), VK_PIPELINE_BIND_POINT_GRAPHICS, renderer.getPipeline().getPipelineLayout(), 0, sets.size(), sets.data(), 0, nullptr); atlas.render(renderer, x, y, draw_data->getIBOsize()); } @@ -98,7 +103,8 @@ namespace mlx void TextDrawDescriptor::resetUpdate() { std::shared_ptr draw_data = TextLibrary::get().getTextData(id); - TextureAtlas& atlas = const_cast(draw_data->getFontInUse().getAtlas()); + std::shared_ptr font_data = FontLibrary::get().getFontData(draw_data->getFontInUse()); + TextureAtlas& atlas = const_cast(font_data->getAtlas()); atlas.resetUpdate(); } } diff --git a/src/renderer/texts/text_descriptor.h b/src/renderer/texts/text_descriptor.h index b44300b..bc8d239 100644 --- a/src/renderer/texts/text_descriptor.h +++ b/src/renderer/texts/text_descriptor.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/01/11 00:13:34 by maldavid #+# #+# */ -/* Updated: 2024/01/11 04:28:58 by maldavid ### ########.fr */ +/* Updated: 2024/01/18 09:40:06 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -19,6 +19,7 @@ #include #include #include +#include #include namespace mlx @@ -36,7 +37,7 @@ namespace mlx public: TextDrawDescriptor(std::string text, uint32_t _color, int _x, int _y); - void init(Font* const font) noexcept; + void init(FontID font) noexcept; bool operator==(const TextDrawDescriptor& rhs) const { return _text == rhs._text && x == rhs.x && y == rhs.y && color == rhs.color; } void render(std::array& sets, Renderer& renderer) override; void resetUpdate() override; diff --git a/src/renderer/texts/text_library.cpp b/src/renderer/texts/text_library.cpp index ab90159..4a61b38 100644 --- a/src/renderer/texts/text_library.cpp +++ b/src/renderer/texts/text_library.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/04/10 11:59:57 by maldavid #+# #+# */ -/* Updated: 2024/01/16 08:54:22 by maldavid ### ########.fr */ +/* Updated: 2024/01/18 08:02:31 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/src/renderer/texts/text_manager.cpp b/src/renderer/texts/text_manager.cpp index 3ea7400..81dffd7 100644 --- a/src/renderer/texts/text_manager.cpp +++ b/src/renderer/texts/text_manager.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/04/06 16:41:13 by maldavid #+# #+# */ -/* Updated: 2024/01/17 03:47:46 by maldavid ### ########.fr */ +/* Updated: 2024/01/18 09:45:24 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -29,19 +29,13 @@ namespace mlx void TextManager::loadFont(Renderer& renderer, const std::filesystem::path& filepath, float scale) { MLX_PROFILE_FUNCTION(); - for(Font& font : _font_set) - { - if(filepath == font.getName() && scale == font.getScale()) - { - _font_in_use = &font; - return; - } - } - + std::shared_ptr font; if(filepath.string() == "default") - _font_in_use = &_font_set.emplace_back(renderer, "default", dogica_ttf, scale); + font = std::make_shared(renderer, "default", dogica_ttf, scale); else - _font_in_use = &_font_set.emplace_back(renderer, filepath, scale); + font = std::make_shared(renderer, filepath, scale); + + _font_in_use = FontLibrary::get().addFontToLibrary(font); } std::pair TextManager::registerText(int x, int y, uint32_t color, std::string str) @@ -55,8 +49,9 @@ namespace mlx } auto text_ptr = TextLibrary::get().getTextData(res.first->id); - if(*_font_in_use != text_ptr->getFontInUse()) + if(_font_in_use != text_ptr->getFontInUse()) { + // TODO : update text vertex buffers rather than destroying it and recreating it TextLibrary::get().removeTextFromLibrary(res.first->id); const_cast(*res.first).init(_font_in_use); } @@ -67,6 +62,5 @@ namespace mlx { MLX_PROFILE_FUNCTION(); _text_descriptors.clear(); - _font_set.clear(); } } diff --git a/src/renderer/texts/text_manager.h b/src/renderer/texts/text_manager.h index 1474232..8198b66 100644 --- a/src/renderer/texts/text_manager.h +++ b/src/renderer/texts/text_manager.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/04/06 16:24:11 by maldavid #+# #+# */ -/* Updated: 2024/01/16 09:04:05 by maldavid ### ########.fr */ +/* Updated: 2024/01/18 13:52:01 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -23,6 +23,8 @@ #include #include #include +#include +#include namespace mlx { @@ -33,7 +35,7 @@ namespace mlx void init(Renderer& renderer) noexcept; std::pair registerText(int x, int y, uint32_t color, std::string str); - inline void clear() { _text_descriptors.clear(); /*TextLibrary::get().clearLibrary();*/ } + inline void clear() { _text_descriptors.clear(); TextLibrary::get().clearLibrary(); } void loadFont(Renderer& renderer, const std::filesystem::path& filepath, float scale); void destroy() noexcept; @@ -41,8 +43,7 @@ namespace mlx private: std::unordered_set _text_descriptors; - std::vector _font_set; - Font* _font_in_use = nullptr; + FontID _font_in_use = nullfont; }; }