From 026f83ca81f1c0e95d619b5c49477ea6d8c0af1b Mon Sep 17 00:00:00 2001 From: Kbz-8 Date: Tue, 11 Apr 2023 13:21:11 +0200 Subject: [PATCH] working text pipeline --- src/renderer/images/texture_atlas.cpp | 41 ++------------- src/renderer/images/texture_atlas.h | 9 +--- src/renderer/images/vk_image.cpp | 4 +- src/renderer/renderer.h | 4 +- src/renderer/text_library.cpp | 66 ++++++++++++++++++++++++ src/renderer/text_library.h | 66 ++++++++++++++++++++++++ src/renderer/text_pipeline.cpp | 74 ++++++++++++++++----------- src/renderer/text_pipeline.h | 47 +++++++++++------ test/main.c | 2 +- 9 files changed, 217 insertions(+), 96 deletions(-) create mode 100644 src/renderer/text_library.cpp create mode 100644 src/renderer/text_library.h diff --git a/src/renderer/images/texture_atlas.cpp b/src/renderer/images/texture_atlas.cpp index 011a675..3e57926 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/04/08 18:41:44 by maldavid ### ########.fr */ +/* Updated: 2023/04/11 12:30:28 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -25,25 +25,6 @@ namespace mlx Image::createImageView(VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT); Image::createSampler(); - _color = 0xFFFFFFFF; - - float red = (_color & 0x00FF0000) / 255; - float green = (_color & 0x0000FF00) / 255; - float blue = (_color & 0x000000FF) / 255; - - std::vector vertexData = { - {{0, 0}, {red, green, blue, 1.f}, {0.0f, 0.0f}}, - {{20, 0}, {red, green, blue, 1.f}, {1.0f, 0.0f}}, - {{20, 20}, {red, green, blue, 1.f}, {1.0f, 1.0f}}, - {{0, 20}, {red, green, blue, 1.f}, {0.0f, 1.0f}} - }; - - std::vector indexData = { 0, 1, 2, 2, 3, 0 }; - - _vbo.create(sizeof(Vertex) * vertexData.size()); - _vbo.setData(sizeof(Vertex) * vertexData.size(), vertexData.data()); - _ibo.create(sizeof(uint16_t) * indexData.size(), indexData.data()); - if(pixels != nullptr) { Buffer staging_buffer; @@ -54,33 +35,17 @@ namespace mlx } } - void TextureAtlas::render(Renderer& renderer, int x, int y, std::array pos, std::array uv) + void TextureAtlas::render(Renderer& renderer, int x, int y, uint32_t ibo_size) { auto cmd = renderer.getActiveCmdBuffer().get(); - float red = (_color & 0x00FF0000) / 255; - float green = (_color & 0x0000FF00) / 255; - float blue = (_color & 0x000000FF) / 255; - - std::vector vertexData = { - {pos[0], {red, green, blue, 1.f}, uv[0]}, - {pos[1], {red, green, blue, 1.f}, uv[1]}, - {pos[2], {red, green, blue, 1.f}, uv[2]}, - {pos[3], {red, green, blue, 1.f}, uv[3]} - }; - _vbo.setData(sizeof(Vertex) * vertexData.size(), vertexData.data()); - - _vbo.bind(renderer); - _ibo.bind(renderer); glm::vec2 translate(x, y); vkCmdPushConstants(cmd, renderer.getPipeline().getPipelineLayout(), VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(translate), &translate); - vkCmdDrawIndexed(cmd, static_cast(_ibo.getSize() / sizeof(uint16_t)), 1, 0, 0, 0); + vkCmdDrawIndexed(cmd, ibo_size / sizeof(uint16_t), 1, 0, 0, 0); } void TextureAtlas::destroy() noexcept { Image::destroy(); - _vbo.destroy(); - _ibo.destroy(); } } diff --git a/src/renderer/images/texture_atlas.h b/src/renderer/images/texture_atlas.h index 026f53a..dc9f004 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: 2023/04/08 00:27:46 by maldavid ### ########.fr */ +/* Updated: 2023/04/11 12:04:16 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -25,11 +25,9 @@ namespace mlx TextureAtlas() = default; void create(uint8_t* pixels, uint32_t width, uint32_t height, VkFormat format); - void render(class Renderer& renderer, int x, int y, std::array pos, std::array uv); + void render(class Renderer& renderer, int x, int y, uint32_t ibo_size); void destroy() noexcept override; - inline void setColor(int color) noexcept { _color = color; } - inline void setDescriptor(DescriptorSet set) noexcept { _set = std::move(set); } inline VkDescriptorSet getSet() noexcept { return _set.isInit() ? _set.get() : VK_NULL_HANDLE; } inline void updateSet(int binding) noexcept { _set.writeDescriptor(binding, getImageView(), getSampler()); } @@ -37,10 +35,7 @@ namespace mlx ~TextureAtlas() = default; private: - VBO _vbo; - C_IBO _ibo; DescriptorSet _set; - int _color; }; } diff --git a/src/renderer/images/vk_image.cpp b/src/renderer/images/vk_image.cpp index 9c611c3..222cb2a 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: 2023/04/08 18:41:15 by maldavid ### ########.fr */ +/* Updated: 2023/04/11 13:20:26 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -93,7 +93,7 @@ namespace mlx info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; info.magFilter = VK_FILTER_LINEAR; info.minFilter = VK_FILTER_LINEAR; - info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; + info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; info.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT; info.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT; info.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT; diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index d8373f3..1a6231d 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/12/18 17:14:45 by maldavid #+# #+# */ -/* Updated: 2023/04/03 14:23:46 by maldavid ### ########.fr */ +/* Updated: 2023/04/11 12:33:33 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -41,6 +41,8 @@ namespace mlx glm::vec4 color; glm::vec2 uv; + Vertex(glm::vec2 _pos, glm::vec4 _color, glm::vec2 _uv) : pos(std::move(_pos)), color(std::move(_color)), uv(std::move(_uv)) {} + static VkVertexInputBindingDescription getBindingDescription() { VkVertexInputBindingDescription bindingDescription{}; diff --git a/src/renderer/text_library.cpp b/src/renderer/text_library.cpp new file mode 100644 index 0000000..c908241 --- /dev/null +++ b/src/renderer/text_library.cpp @@ -0,0 +1,66 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* text_library.cpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maldavid +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/04/10 11:59:57 by maldavid #+# #+# */ +/* Updated: 2023/04/11 12:28:42 by maldavid ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include +#include +#include + +namespace mlx +{ + void TextData::init(std::vector vbo_data, std::vector ibo_data) + { + _vbo.create(sizeof(Vertex) * vbo_data.size(), vbo_data.data()); + _ibo.create(sizeof(uint16_t) * ibo_data.size(), ibo_data.data()); + } + + void TextData::bind(Renderer& renderer) noexcept + { + _vbo.bind(renderer); + _ibo.bind(renderer); + } + + void TextData::destroy() noexcept + { + _vbo.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) + { + _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/text_library.h b/src/renderer/text_library.h new file mode 100644 index 0000000..76ac73f --- /dev/null +++ b/src/renderer/text_library.h @@ -0,0 +1,66 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* text_library.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maldavid +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/04/10 11:52:30 by maldavid #+# #+# */ +/* Updated: 2023/04/11 12:28:08 by maldavid ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef __MLX_TEXT_LIBRARY__ +#define __MLX_TEXT_LIBRARY__ + +#include +#include +#include +#include +#include +#include +#include + +namespace mlx +{ + using TextID = uint32_t; + constexpr TextID nulltext = 0; + + class TextData + { + public: + TextData() = default; + + void init(std::vector vbo_data, std::vector ibo_data); + void bind(class Renderer& renderer) noexcept; + inline uint32_t getIBOsize() noexcept { return _ibo.getSize(); } + void destroy() noexcept; + + ~TextData() = default; + + private: + C_VBO _vbo; + C_IBO _ibo; + + }; + + class TextLibrary + { + public: + TextLibrary() = default; + + std::shared_ptr getTextData(TextID id); + TextID addTextToLibrary(std::shared_ptr text); + void removeTextFromLibrary(TextID id); + + void clearLibrary(); + + ~TextLibrary() = default; + + private: + std::unordered_map> _cache; + TextID _current_id = 1; + }; +} + +#endif diff --git a/src/renderer/text_pipeline.cpp b/src/renderer/text_pipeline.cpp index 849760a..3f3f065 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/04/08 20:44:51 by maldavid ### ########.fr */ +/* Updated: 2023/04/11 12:49:59 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -25,17 +25,53 @@ namespace mlx { uint8_t tmp_bitmap[512 * 512]; + TextDrawData::TextDrawData(std::string text, int _color, int _x, int _y, TextLibrary& library, std::array& cdata) : x(_x), y(_y), color(_color) + { + std::vector vertexData; + std::vector indexData; + + float stb_x = 0.0f; + float stb_y = 0.0f; + + for(char c : text) + { + if(c < 32 || c > 127) + continue; + + stbtt_aligned_quad q; + stbtt_GetBakedQuad(cdata.data(), 512, 512, c - 32, &stb_x, &stb_y, &q, 1); + + std::size_t index = vertexData.size(); + + vertexData.emplace_back(glm::vec2{q.x0, q.y0}, glm::vec4{color & 0x00FF0000, color & 0x0000FF00, color & 0x000000FF, 0xFF}, glm::vec2{q.s0, q.t0}); + vertexData.emplace_back(glm::vec2{q.x1, q.y0}, glm::vec4{color & 0x00FF0000, color & 0x0000FF00, color & 0x000000FF, 0xFF}, glm::vec2{q.s1, q.t0}); + vertexData.emplace_back(glm::vec2{q.x1, q.y1}, glm::vec4{color & 0x00FF0000, color & 0x0000FF00, color & 0x000000FF, 0xFF}, glm::vec2{q.s1, q.t1}); + vertexData.emplace_back(glm::vec2{q.x0, q.y1}, glm::vec4{color & 0x00FF0000, color & 0x0000FF00, color & 0x000000FF, 0xFF}, 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(std::move(vertexData), std::move(indexData)); + id = library.addTextToLibrary(text_data); + } + void TextPutPipeline::init(Renderer* renderer) noexcept { _renderer = renderer; - stbtt_BakeFontBitmap(opensans_regular_ttf, 0, 20.0f, tmp_bitmap, 512, 512, 32, 96, _cdata); + stbtt_BakeFontBitmap(opensans_regular_ttf, 0, 18.0f, tmp_bitmap, 512, 512, 32, 96, _cdata.data()); _atlas.create(tmp_bitmap, 512, 512, VK_FORMAT_R8_UNORM); _atlas.setDescriptor(renderer->getFragDescriptorSet().duplicate()); } void TextPutPipeline::put(int x, int y, int color, std::string str) { - _drawlist.emplace(std::move(str), color, x, y); + _drawlist.emplace(std::move(str), color, x, y, _library, _cdata); } void TextPutPipeline::render() @@ -43,39 +79,15 @@ namespace mlx _atlas.updateSet(0); for(auto& draw : _drawlist) { - _atlas.setColor(draw.color); - int i = 0; - for(char c : draw.text) - { - if(c < 32 || c > 127) - continue; - - stbtt_aligned_quad q; - float null_x = 0.0f; - float null_y = 0.0f; - stbtt_GetBakedQuad(_cdata, 512, 512, c - 32, &null_x, &null_y, &q, 1); - - std::array pos = { - glm::vec2{q.x0, q.y0}, - glm::vec2{q.x1, q.y0}, - glm::vec2{q.x1, q.y1}, - glm::vec2{q.x0, q.y1} - }; - - std::array uv = { - glm::vec2{q.s0, q.t0}, - glm::vec2{q.s1, q.t0}, - glm::vec2{q.s1, q.t1}, - glm::vec2{q.s0, q.t1} - }; - - _atlas.render(*_renderer, draw.x, draw.y, std::move(pos), std::move(uv)); - } + std::shared_ptr draw_data = _library.getTextData(draw.id); + draw_data->bind(*_renderer); + _atlas.render(*_renderer, draw.x, draw.y, draw_data->getIBOsize()); } } void TextPutPipeline::destroy() noexcept { + _library.clearLibrary(); _atlas.destroy(); } } diff --git a/src/renderer/text_pipeline.h b/src/renderer/text_pipeline.h index 77cf335..5502b52 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/04/08 20:44:33 by maldavid ### ########.fr */ +/* Updated: 2023/04/11 12:24:59 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -19,6 +19,33 @@ #include #include #include +#include + +namespace mlx +{ + struct TextDrawData + { + TextID id; + int x; + int y; + int color; + + TextDrawData(std::string text, int _color, int _x, int _y, TextLibrary& library, std::array& cdata); + bool operator==(const TextDrawData& rhs) const { return id == rhs.id && x == rhs.x && y == rhs.y && color == rhs.color; } + }; +} + +namespace std +{ + template <> + struct hash + { + size_t operator()(const mlx::TextDrawData& d) const noexcept + { + return std::hash()(d.id) + std::hash()(d.x) + std::hash()(d.y) + std::hash()(d.color); + } + }; +} namespace mlx { @@ -37,22 +64,10 @@ namespace mlx ~TextPutPipeline() = default; private: - struct DrawData - { - std::string text; - int x; - int y; - int color; - - DrawData(std::string _text, int _color, int _x, int _y) : - text(std::move(_text)), color(_color), x(_x), y(_y) - {} - bool operator==(const DrawData& rhs) const { return text == rhs.text && x == rhs.x && y == rhs.y && color == rhs.color; } - }; - - stbtt_bakedchar _cdata[96]; + std::array _cdata; TextureAtlas _atlas; - std::unordered_set _drawlist; + TextLibrary _library; + std::unordered_set _drawlist; Renderer* _renderer = nullptr; }; } diff --git a/test/main.c b/test/main.c index 91040e3..e58ddc3 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/04/08 19:04:29 by maldavid ### ########.fr */ +/* Updated: 2023/04/11 12:50:58 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */