From c0e2750fb39a74e97d35293f8de25e416322f5b2 Mon Sep 17 00:00:00 2001 From: Kbz-8 Date: Wed, 13 Dec 2023 00:33:34 +0100 Subject: [PATCH] working on font system --- 4 | 83 +++++++++++++++++++++++++++++ src/renderer/buffers/vk_buffer.cpp | 63 ++++++++++++++-------- src/renderer/buffers/vk_buffer.h | 5 +- src/renderer/buffers/vk_vbo.cpp | 26 ++++++++- src/renderer/buffers/vk_vbo.h | 12 ++++- src/renderer/font.cpp | 84 ++++++++++++++++++++++++++++++ src/renderer/font.h | 53 +++++++++++++++++++ src/renderer/text_library.cpp | 21 +++++--- src/renderer/text_library.h | 11 ++-- src/renderer/text_pipeline.cpp | 58 +++------------------ src/renderer/text_pipeline.h | 9 ++-- 11 files changed, 333 insertions(+), 92 deletions(-) create mode 100644 4 create mode 100644 src/renderer/font.cpp create mode 100644 src/renderer/font.h diff --git a/4 b/4 new file mode 100644 index 0000000..042353f --- /dev/null +++ b/4 @@ -0,0 +1,83 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* text_library.cpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maldavid +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/04/10 11:59:57 by maldavid #+# #+# */ +/* Updated: 2023/12/12 22:47:33 by kbz_8 ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include +#include +#include +#include + +namespace mlx +{ + void TextData::init(std::string text, Font const* font, std::vector vbo_data, std::vector ibo_data) + { + _text = std::move(text); + _font = font; + #ifdef DEBUG + 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()); + #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); + _ibo.create(sizeof(uint16_t) * ibo_data.size(), ibo_data.data(), nullptr); + #endif + } + + void TextData::bind(Renderer& renderer) noexcept + { + _vbo[renderer.getActiveImageIndex()].bind(renderer); + _ibo.bind(renderer); + } + + void TextData::destroy() noexcept + { + for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) + _vbo[i].destroy(); + _ibo.destroy(); + } + + std::shared_ptr TextLibrary::getTextData(TextID id) + { + if(!_cache.count(id)) + core::error::report(e_kind::fatal_error, "Text Library : wrong text ID '%d'", id); + return _cache[id]; + } + + TextID TextLibrary::addTextToLibrary(std::shared_ptr text) + { + auto it = std::find_if(_cache.begin(), _cache.end(), [=](const std::pair>& v) + { + return v.second->getText() == text->getText(); + }); + if(it != _cache.end()) + return it->first; + _cache[_current_id] = text; + _current_id++; + return _current_id - 1; + } + + void TextLibrary::removeTextFromLibrary(TextID id) + { + if(_cache.count(id)) + { + _cache[id]->destroy(); + _cache.erase(id); + } + } + + void TextLibrary::clearLibrary() + { + for(auto [id, text] : _cache) + text->destroy(); + _cache.clear(); + } +} diff --git a/src/renderer/buffers/vk_buffer.cpp b/src/renderer/buffers/vk_buffer.cpp index bd25952..a98bb74 100644 --- a/src/renderer/buffers/vk_buffer.cpp +++ b/src/renderer/buffers/vk_buffer.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/08 18:55:57 by maldavid #+# #+# */ -/* Updated: 2023/12/10 23:05:14 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/12 22:11:47 by kbz_8 ### ########.fr */ /* */ /* ************************************************************************** */ @@ -23,9 +23,9 @@ namespace mlx void Buffer::create(Buffer::kind type, VkDeviceSize size, VkBufferUsageFlags usage, const char* name, const void* data) { _usage = usage; - if(type == Buffer::kind::constant) + if(type == Buffer::kind::constant || type == Buffer::kind::dynamic_device_local) { - if(data == nullptr) + if(data == nullptr && type == Buffer::kind::constant) { core::error::report(e_kind::warning, "Vulkan : trying to create constant buffer without data (constant buffers cannot be modified after creation)"); return; @@ -45,7 +45,7 @@ namespace mlx mapMem(&mapped); std::memcpy(mapped, data, size); unmapMem(); - if(type == Buffer::kind::constant) + if(type == Buffer::kind::constant || type == Buffer::kind::dynamic_device_local) pushToGPU(); } } @@ -83,6 +83,40 @@ namespace mlx _size = size; } + bool Buffer::copyFromBuffer(const Buffer& buffer) noexcept + { + if(!(_usage & VK_BUFFER_USAGE_TRANSFER_DST_BIT)) + { + core::error::report(e_kind::error, "Vulkan : buffer cannot be the destination of a copy because it does not have the correct usage flag"); + return false; + } + if(!(buffer._usage & VK_BUFFER_USAGE_TRANSFER_SRC_BIT)) + { + core::error::report(e_kind::error, "Vulkan : buffer cannot be the source of a copy because it does not have the correct usage flag"); + return false; + } + + // TODO, use global cmd buffer pool to manage resources + CmdPool cmdpool; + cmdpool.init(); + CmdBuffer cmdBuffer; + cmdBuffer.init(&cmdpool); + + cmdBuffer.beginRecord(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); + + VkBufferCopy copyRegion{}; + copyRegion.size = _size; + vkCmdCopyBuffer(cmdBuffer.get(), buffer._buffer, _buffer, 1, ©Region); + + cmdBuffer.endRecord(); + cmdBuffer.submitIdle(); + + cmdBuffer.destroy(); + cmdpool.destroy(); + + return true; + } + void Buffer::pushToGPU() noexcept { VmaAllocationCreateInfo alloc_info{}; @@ -97,25 +131,8 @@ namespace mlx newBuffer.createBuffer(newBuffer._usage, alloc_info, _size, nullptr); #endif - CmdPool cmdpool; - cmdpool.init(); - CmdBuffer cmdBuffer; - cmdBuffer.init(&cmdpool); - - cmdBuffer.beginRecord(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); - - VkBufferCopy copyRegion{}; - copyRegion.size = _size; - vkCmdCopyBuffer(cmdBuffer.get(), _buffer, newBuffer._buffer, 1, ©Region); - - cmdBuffer.endRecord(); - cmdBuffer.submitIdle(); - - cmdBuffer.destroy(); - cmdpool.destroy(); - - this->swap(newBuffer); - + if(newBuffer.copyFromBuffer(*this)) // if the copy succeded we swap the buffers, else the new one is deleted + this->swap(newBuffer); newBuffer.destroy(); } diff --git a/src/renderer/buffers/vk_buffer.h b/src/renderer/buffers/vk_buffer.h index 08b4344..f3f1669 100644 --- a/src/renderer/buffers/vk_buffer.h +++ b/src/renderer/buffers/vk_buffer.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/06 23:18:52 by maldavid #+# #+# */ -/* Updated: 2023/12/11 19:47:39 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/12 21:12:44 by kbz_8 ### ########.fr */ /* */ /* ************************************************************************** */ @@ -22,7 +22,7 @@ namespace mlx class Buffer { public: - enum class kind { dynamic, uniform, constant }; + enum class kind { dynamic, dynamic_device_local, uniform, constant }; void create(kind type, VkDeviceSize size, VkBufferUsageFlags usage, const char* name, const void* data = nullptr); void destroy() noexcept; @@ -32,6 +32,7 @@ namespace mlx inline void unmapMem() noexcept { Render_Core::get().getAllocator().unmapMemory(_allocation); _is_mapped = false; } void flush(VkDeviceSize size = VK_WHOLE_SIZE, VkDeviceSize offset = 0); + bool copyFromBuffer(const Buffer& buffer) noexcept; inline VkBuffer& operator()() noexcept { return _buffer; } inline VkBuffer& get() noexcept { return _buffer; } diff --git a/src/renderer/buffers/vk_vbo.cpp b/src/renderer/buffers/vk_vbo.cpp index 1b2a0d3..8ceab7d 100644 --- a/src/renderer/buffers/vk_vbo.cpp +++ b/src/renderer/buffers/vk_vbo.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/06 18:28:08 by maldavid #+# #+# */ -/* Updated: 2023/11/10 08:33:52 by maldavid ### ########.fr */ +/* Updated: 2023/12/12 22:17:14 by kbz_8 ### ########.fr */ /* */ /* ************************************************************************** */ @@ -18,7 +18,10 @@ namespace mlx void VBO::setData(uint32_t size, const void* data) { if(size > getSize()) + { core::error::report(e_kind::error, "Vulkan : trying to store to much data in a vertex buffer (%d bytes in %d bytes)", size, getSize()); + return; + } if(data == nullptr) core::error::report(e_kind::warning, "Vulkan : mapping null data in a vertex buffer"); @@ -28,4 +31,25 @@ namespace mlx std::memcpy(temp, data, static_cast(size)); unmapMem(); } + + void D_VBO::setData(uint32_t size, const void* data) + { + if(size > getSize()) + { + core::error::report(e_kind::error, "Vulkan : trying to store to much data in a vertex buffer (%d bytes in %d bytes)", size, getSize()); + return; + } + + if(data == nullptr) + core::error::report(e_kind::warning, "Vulkan : mapping null data in a vertex buffer"); + + Buffer tmp_buf; + #ifdef DEBUG + tmp_buf.create(Buffer::kind::dynamic, size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT, "tmp_buffer", data); + #else + tmp_buf.create(Buffer::kind::dynamic, size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT, nullptr, data); + #endif + copyFromBuffer(tmp_buf); + tmp_buf.destroy(); + } } diff --git a/src/renderer/buffers/vk_vbo.h b/src/renderer/buffers/vk_vbo.h index 6c67332..1bf2209 100644 --- a/src/renderer/buffers/vk_vbo.h +++ b/src/renderer/buffers/vk_vbo.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/06 18:27:38 by maldavid #+# #+# */ -/* Updated: 2023/12/08 19:06:45 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/12 22:46:21 by kbz_8 ### ########.fr */ /* */ /* ************************************************************************** */ @@ -22,7 +22,15 @@ namespace mlx class VBO : public Buffer { public: - inline void create(uint32_t size, const char* name) { Buffer::create(Buffer::kind::dynamic, size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, name); } + inline void create(uint32_t size, const void* data, const char* name) { Buffer::create(Buffer::kind::dynamic, size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, name, data); } + void setData(uint32_t size, const void* data); + inline void bind(Renderer& renderer) noexcept { vkCmdBindVertexBuffers(renderer.getActiveCmdBuffer().get(), 0, 1, &_buffer, &_offset); } + }; + + class D_VBO : public Buffer + { + public: + inline void create(uint32_t size, const void* data, const char* name) { Buffer::create(Buffer::kind::dynamic_device_local, size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, name, data); } void setData(uint32_t size, const void* data); inline void bind(Renderer& renderer) noexcept { vkCmdBindVertexBuffers(renderer.getActiveCmdBuffer().get(), 0, 1, &_buffer, &_offset); } }; diff --git a/src/renderer/font.cpp b/src/renderer/font.cpp new file mode 100644 index 0000000..a75aadb --- /dev/null +++ b/src/renderer/font.cpp @@ -0,0 +1,84 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* font.cpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maldavid +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/12/11 22:06:09 by kbz_8 #+# #+# */ +/* Updated: 2023/12/12 23:57:53 by kbz_8 ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include +#include +#include + +constexpr const int RANGE = 1024; + +namespace mlx +{ + Font::Font(Renderer& renderer, const std::filesystem::path& path, float scale) : non_copyable(), _name(path.string()) + { + 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()); + } + + Font::Font(class Renderer& renderer, const std::string& name, const std::vector& ttf_data, float scale) + { + 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, 6.0, 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()); + } + + Font::~Font() + { + _atlas.destroy(); + } +} diff --git a/src/renderer/font.h b/src/renderer/font.h new file mode 100644 index 0000000..8e3ba08 --- /dev/null +++ b/src/renderer/font.h @@ -0,0 +1,53 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* font.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maldavid +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/12/11 21:17:04 by kbz_8 #+# #+# */ +/* Updated: 2023/12/13 00:25:30 by kbz_8 ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef __MLX_FONT__ +#define __MLX_FONT__ + +#include +#include +#include +#include + +namespace mlx +{ + class Font : public non_copyable + { + public: + 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 const std::array& getCharData() const { return _cdata; } + inline VkDescriptorSet getDescriptorSet() noexcept { return _atlas.getSet(); } + inline bool operator==(const Font& rhs) { return rhs._name == _name; } + ~Font(); + + private: + std::array _cdata; + TextureAtlas _atlas; + std::string _name; + }; +} + +namespace std +{ + template <> + struct hash + { + std::size_t operator()(const mlx::Font& f) const noexcept + { + return std::hash()(f.getName()); + } + }; +} + +#endif diff --git a/src/renderer/text_library.cpp b/src/renderer/text_library.cpp index ec34951..0a68dd4 100644 --- a/src/renderer/text_library.cpp +++ b/src/renderer/text_library.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/04/10 11:59:57 by maldavid #+# #+# */ -/* Updated: 2023/11/16 13:45:31 by maldavid ### ########.fr */ +/* Updated: 2023/12/12 23:03:33 by kbz_8 ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,27 +17,36 @@ namespace mlx { - void TextData::init(std::string text, std::vector vbo_data, std::vector ibo_data) + void TextData::init(std::string text, Font const* font, std::vector vbo_data, std::vector ibo_data) { _text = std::move(text); + _font = font; #ifdef DEBUG - _vbo.create(sizeof(Vertex) * vbo_data.size(), vbo_data.data(), _text.c_str()); + 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()); #else - _vbo.create(sizeof(Vertex) * vbo_data.size(), vbo_data.data(), nullptr); + for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) + _vbo[i].create(sizeof(Vertex) * vbo_data.size(), static_cast(vbo_data.data()), nullptr); _ibo.create(sizeof(uint16_t) * ibo_data.size(), ibo_data.data(), nullptr); #endif } void TextData::bind(Renderer& renderer) noexcept { - _vbo.bind(renderer); + _vbo[renderer.getActiveImageIndex()].bind(renderer); _ibo.bind(renderer); } + void TextData::updateVertexData(int frame, std::vector vbo_data) + { + _vbo[frame].setData(sizeof(Vertex) * vbo_data.size(), static_cast(vbo_data.data())); + } + void TextData::destroy() noexcept { - _vbo.destroy(); + for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) + _vbo[i].destroy(); _ibo.destroy(); } diff --git a/src/renderer/text_library.h b/src/renderer/text_library.h index b889224..1283a99 100644 --- a/src/renderer/text_library.h +++ b/src/renderer/text_library.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/04/10 11:52:30 by maldavid #+# #+# */ -/* Updated: 2023/12/08 19:12:24 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/12 23:07:13 by kbz_8 ### ########.fr */ /* */ /* ************************************************************************** */ @@ -21,6 +21,8 @@ #include #include #include +#include +#include namespace mlx { @@ -32,8 +34,10 @@ namespace mlx public: TextData() = default; - void init(std::string text, std::vector vbo_data, std::vector ibo_data); + void init(std::string text, Font const* font, std::vector vbo_data, std::vector ibo_data); void bind(class Renderer& renderer) noexcept; + inline const Font& 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; } void destroy() noexcept; @@ -41,9 +45,10 @@ namespace mlx ~TextData() = default; private: - C_VBO _vbo; + std::array _vbo; C_IBO _ibo; std::string _text; + Font const* _font = nullptr; }; class TextLibrary diff --git a/src/renderer/text_pipeline.cpp b/src/renderer/text_pipeline.cpp index 4468a0b..d5606d4 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/12/11 15:12:02 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/13 00:25:48 by kbz_8 ### ########.fr */ /* */ /* ************************************************************************** */ @@ -36,7 +36,7 @@ namespace mlx text(std::move(_text)) {} - void TextDrawData::init(TextLibrary& library, std::array& cdata) noexcept + void TextDrawData::init(TextLibrary& library, Font* const font) noexcept { std::vector vertexData; std::vector indexData; @@ -50,7 +50,7 @@ namespace mlx continue; stbtt_aligned_quad q; - stbtt_GetPackedQuad(cdata.data(), RANGE, RANGE, c - 32, &stb_x, &stb_y, &q, 1); + stbtt_GetPackedQuad(font->getCharData().data(), RANGE, RANGE, c - 32, &stb_x, &stb_y, &q, 1); std::size_t index = vertexData.size(); @@ -67,7 +67,7 @@ namespace mlx indexData.emplace_back(index + 0); } std::shared_ptr text_data = std::make_shared(); - text_data->init(text, std::move(vertexData), std::move(indexData)); + text_data->init(text, font, std::move(vertexData), std::move(indexData)); id = library.addTextToLibrary(text_data); #ifdef DEBUG @@ -78,61 +78,19 @@ namespace mlx void TextPutPipeline::init(Renderer* renderer) noexcept { _renderer = renderer; - 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, dogica_ttf, 0, 6.0, 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]; - } - _atlas.create(vulkan_bitmap.data(), RANGE, RANGE, VK_FORMAT_R8G8B8A8_UNORM, "__mlx_texts_pipeline_texture_atlas", true); - _atlas.setDescriptor(renderer->getFragDescriptorSet().duplicate()); + _font_set.emplace(*_renderer, "default", dogica_ttf, 6.0f); } void TextPutPipeline::loadFont(const std::filesystem::path& filepath, float scale) { - std::vector tmp_bitmap(RANGE * RANGE); - std::vector 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_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]; - } - destroy(); - _atlas.create(vulkan_bitmap.data(), RANGE, RANGE, VK_FORMAT_R8G8B8A8_UNORM, "__mlx_texts_pipeline_texture_atlas", true); - _atlas.setDescriptor(_renderer->getFragDescriptorSet().duplicate()); + _font_set.emplace(*_renderer, filepath, scale); } void TextPutPipeline::put(int x, int y, int color, std::string str) { auto res = _drawlist.emplace(std::move(str), color, x, y); if(res.second) - const_cast(*res.first).init(_library, _cdata); + const_cast(*res.first).init(_library, _font_in_use); } void TextPutPipeline::render() @@ -150,6 +108,6 @@ namespace mlx { _library.clearLibrary(); _drawlist.clear(); - _atlas.destroy(); + _font_set.clear(); } } diff --git a/src/renderer/text_pipeline.h b/src/renderer/text_pipeline.h index b6ca962..db6f405 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/12/08 19:12:40 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/13 00:24:21 by kbz_8 ### ########.fr */ /* */ /* ************************************************************************** */ @@ -33,7 +33,7 @@ namespace mlx std::string text; TextDrawData(std::string text, int _color, int _x, int _y); - void init(TextLibrary& library, std::array& cdata) noexcept; + void init(TextLibrary& library, Font* const font) noexcept; bool operator==(const TextDrawData& rhs) const { return text == rhs.text && x == rhs.x && y == rhs.y && color == rhs.color; } }; } @@ -59,7 +59,6 @@ namespace mlx void init(Renderer* renderer) noexcept; void put(int x, int y, int color, std::string str); - inline VkDescriptorSet getDescriptorSet() noexcept { return _atlas.getSet(); } inline void clear() { _drawlist.clear(); } void loadFont(const std::filesystem::path& filepath, float scale); void render(); @@ -68,11 +67,11 @@ namespace mlx ~TextPutPipeline() = default; private: - std::array _cdata; - TextureAtlas _atlas; + std::unordered_set _font_set; TextLibrary _library; std::unordered_set _drawlist; Renderer* _renderer = nullptr; + Font* _font_in_use = nullptr; }; }