mirror of
https://github.com/seekrs/MacroLibX.git
synced 2026-01-11 14:43:34 +00:00
working text pipeline
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* 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<Vertex> 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<uint16_t> 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<glm::vec2, 4> pos, std::array<glm::vec2, 4> 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<Vertex> 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<uint32_t>(_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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* 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<glm::vec2, 4> pos, std::array<glm::vec2, 4> 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;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* 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;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* 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{};
|
||||
|
||||
66
src/renderer/text_library.cpp
git.filemode.normal_file
66
src/renderer/text_library.cpp
git.filemode.normal_file
@@ -0,0 +1,66 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* text_library.cpp :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/04/10 11:59:57 by maldavid #+# #+# */
|
||||
/* Updated: 2023/04/11 12:28:42 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include <renderer/text_library.h>
|
||||
#include <core/errors.h>
|
||||
#include <renderer/renderer.h>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
void TextData::init(std::vector<Vertex> vbo_data, std::vector<uint16_t> 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<TextData> 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<TextData> 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();
|
||||
}
|
||||
}
|
||||
66
src/renderer/text_library.h
git.filemode.normal_file
66
src/renderer/text_library.h
git.filemode.normal_file
@@ -0,0 +1,66 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* text_library.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* 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 <renderer/buffers/vk_vbo.h>
|
||||
#include <renderer/buffers/vk_ibo.h>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
using TextID = uint32_t;
|
||||
constexpr TextID nulltext = 0;
|
||||
|
||||
class TextData
|
||||
{
|
||||
public:
|
||||
TextData() = default;
|
||||
|
||||
void init(std::vector<Vertex> vbo_data, std::vector<uint16_t> 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<TextData> getTextData(TextID id);
|
||||
TextID addTextToLibrary(std::shared_ptr<TextData> text);
|
||||
void removeTextFromLibrary(TextID id);
|
||||
|
||||
void clearLibrary();
|
||||
|
||||
~TextLibrary() = default;
|
||||
|
||||
private:
|
||||
std::unordered_map<TextID, std::shared_ptr<TextData>> _cache;
|
||||
TextID _current_id = 1;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* 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<stbtt_bakedchar, 96>& cdata) : x(_x), y(_y), color(_color)
|
||||
{
|
||||
std::vector<Vertex> vertexData;
|
||||
std::vector<uint16_t> 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<TextData> text_data = std::make_shared<TextData>();
|
||||
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<glm::vec2, 4> 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<glm::vec2, 4> 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<TextData> 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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* 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 <stb_truetype.h>
|
||||
#include <cstdint>
|
||||
#include <unordered_set>
|
||||
#include <renderer/text_library.h>
|
||||
|
||||
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<stbtt_bakedchar, 96>& 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<mlx::TextDrawData>
|
||||
{
|
||||
size_t operator()(const mlx::TextDrawData& d) const noexcept
|
||||
{
|
||||
return std::hash<mlx::TextID>()(d.id) + std::hash<int>()(d.x) + std::hash<int>()(d.y) + std::hash<int>()(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<stbtt_bakedchar, 96> _cdata;
|
||||
TextureAtlas _atlas;
|
||||
std::unordered_set<DrawData> _drawlist;
|
||||
TextLibrary _library;
|
||||
std::unordered_set<TextDrawData> _drawlist;
|
||||
Renderer* _renderer = nullptr;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* 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 */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user