mirror of
https://github.com/seekrs/MacroLibX.git
synced 2026-01-11 14:43:34 +00:00
Merge branch 'seekrs:indev' into indev
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/04 17:55:21 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/10 20:21:45 by maldavid ### ########.fr */
|
||||
/* Updated: 2024/01/11 20:09:56 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@@ -30,9 +30,10 @@ int update(void *param)
|
||||
t_mlx *mlx;
|
||||
|
||||
mlx = (t_mlx *)param;
|
||||
mlx_set_font_scale(mlx->mlx, mlx->win, "default", 6.f);
|
||||
mlx_string_put(mlx->mlx, mlx->win, 160, 120, 0xFFFF2066, "this text should be hidden");
|
||||
mlx_put_image_to_window(mlx->mlx, mlx->win, mlx->logo, 100, 100);
|
||||
mlx_put_image_to_window(mlx->mlx, mlx->win, mlx->img, 150, 60);
|
||||
mlx_string_put(mlx->mlx, mlx->win, 90, 120, 0xFFFF2066, "this text should be hidden");
|
||||
if (i == 0)
|
||||
mlx_set_font_scale(mlx->mlx, mlx->win, "font.ttf", 16.f);
|
||||
mlx_string_put(mlx->mlx, mlx->win, 20, 50, 0xFFFFFFFF, "that's a text");
|
||||
|
||||
@@ -6,11 +6,12 @@
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/04 22:10:52 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/10 16:44:14 by maldavid ### ########.fr */
|
||||
/* Updated: 2024/01/11 05:08:42 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "application.h"
|
||||
#include <renderer/texts/text_library.h>
|
||||
#include <SDL2/SDL.h>
|
||||
#include <renderer/images/texture.h>
|
||||
#include <renderer/core/render_core.h>
|
||||
@@ -44,6 +45,14 @@ namespace mlx::core
|
||||
for(auto& gs : _graphics)
|
||||
gs->render();
|
||||
}
|
||||
|
||||
Render_Core::get().getSingleTimeCmdManager().updateSingleTimesCmdBuffersSubmitState();
|
||||
|
||||
for(auto& gs : _graphics)
|
||||
{
|
||||
for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
|
||||
gs->getRenderer().getCmdBuffer(i).waitForExecution();
|
||||
}
|
||||
}
|
||||
|
||||
void* Application::newTexture(int w, int h)
|
||||
@@ -74,6 +83,7 @@ namespace mlx::core
|
||||
|
||||
Application::~Application()
|
||||
{
|
||||
TextLibrary::get().clearLibrary();
|
||||
if(__drop_sdl_responsability)
|
||||
return;
|
||||
SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_EVENTS);
|
||||
|
||||
@@ -35,6 +35,11 @@ namespace mlx::core
|
||||
void Application::mouseMove(void* win, int x, int y) noexcept
|
||||
{
|
||||
CHECK_WINDOW_PTR(win);
|
||||
if(!_graphics[*static_cast<int*>(win)]->hasWindow())
|
||||
{
|
||||
error::report(e_kind::warning, "trying to move the mouse relative to a window that is targeting an image and not a real window, this is not allowed (move ignored)");
|
||||
return;
|
||||
}
|
||||
SDL_WarpMouseInWindow(_graphics[*static_cast<int*>(win)]->getWindow()->getNativeWindow(), x, y);
|
||||
SDL_PumpEvents();
|
||||
SDL_FlushEvent(SDL_MOUSEMOTION);
|
||||
@@ -43,6 +48,11 @@ namespace mlx::core
|
||||
void Application::onEvent(void* win, int event, int (*funct_ptr)(int, void*), void* param) noexcept
|
||||
{
|
||||
CHECK_WINDOW_PTR(win);
|
||||
if(!_graphics[*static_cast<int*>(win)]->hasWindow())
|
||||
{
|
||||
error::report(e_kind::warning, "trying to add event hook for a window that is targeting an image and not a real window, this is not allowed (hook ignored)");
|
||||
return;
|
||||
}
|
||||
_in->onEvent(_graphics[*static_cast<int*>(win)]->getWindow()->getID(), event, funct_ptr, param);
|
||||
}
|
||||
|
||||
@@ -82,7 +92,7 @@ namespace mlx::core
|
||||
CHECK_WINDOW_PTR(win);
|
||||
_graphics[*static_cast<int*>(win)]->clearRenderData();
|
||||
}
|
||||
|
||||
|
||||
void Application::destroyGraphicsSupport(void* win)
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
@@ -108,7 +118,7 @@ namespace mlx::core
|
||||
}
|
||||
if(std::strlen(str) == 0)
|
||||
{
|
||||
core::error::report(e_kind::error, "trying to put an empty text");
|
||||
core::error::report(e_kind::warning, "trying to put an empty text");
|
||||
return;
|
||||
}
|
||||
_graphics[*static_cast<int*>(win)]->stringPut(x, y, color, str);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/04/02 15:13:55 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/10 18:23:26 by maldavid ### ########.fr */
|
||||
/* Updated: 2024/01/11 04:38:53 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@@ -16,32 +16,32 @@ namespace mlx
|
||||
{
|
||||
GraphicsSupport::GraphicsSupport(std::size_t w, std::size_t h, Texture* render_target, int id) :
|
||||
_window(nullptr),
|
||||
_text_put_pipeline(std::make_unique<TextPutPipeline>()),
|
||||
_renderer(std::make_unique<Renderer>()),
|
||||
_width(w),
|
||||
_height(h),
|
||||
_id(id)
|
||||
_id(id),
|
||||
_has_window(false)
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
_renderer->setWindow(nullptr);
|
||||
_renderer->init(render_target);
|
||||
_pixel_put_pipeline.init(w, h, *_renderer);
|
||||
_text_put_pipeline->init(_renderer.get());
|
||||
_text_manager.init(*_renderer);
|
||||
}
|
||||
|
||||
GraphicsSupport::GraphicsSupport(std::size_t w, std::size_t h, std::string title, int id) :
|
||||
_window(std::make_shared<MLX_Window>(w, h, title)),
|
||||
_text_put_pipeline(std::make_unique<TextPutPipeline>()),
|
||||
_renderer(std::make_unique<Renderer>()),
|
||||
_width(w),
|
||||
_height(h),
|
||||
_id(id)
|
||||
_id(id),
|
||||
_has_window(true)
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
_renderer->setWindow(_window.get());
|
||||
_renderer->init(nullptr);
|
||||
_pixel_put_pipeline.init(w, h, *_renderer);
|
||||
_text_put_pipeline->init(_renderer.get());
|
||||
_text_manager.init(*_renderer);
|
||||
}
|
||||
|
||||
void GraphicsSupport::render() noexcept
|
||||
@@ -51,39 +51,21 @@ namespace mlx
|
||||
return;
|
||||
_proj = glm::ortho<float>(0, _width, 0, _height);
|
||||
_renderer->getUniformBuffer()->setData(sizeof(_proj), &_proj);
|
||||
auto cmd_buff = _renderer->getActiveCmdBuffer().get();
|
||||
|
||||
static std::array<VkDescriptorSet, 2> sets = {
|
||||
_renderer->getVertDescriptorSet().get(),
|
||||
VK_NULL_HANDLE
|
||||
};
|
||||
|
||||
for(auto& data : _textures_to_render)
|
||||
{
|
||||
if(!data.texture->isInit())
|
||||
continue;
|
||||
if(data.texture->getSet() == VK_NULL_HANDLE)
|
||||
data.texture->setDescriptor(_renderer->getFragDescriptorSet().duplicate());
|
||||
if(data.texture->getLayout() != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
|
||||
data.texture->transitionLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
if(!data.texture->hasBeenUpdated())
|
||||
data.texture->updateSet(0);
|
||||
sets[1] = data.texture->getSet();
|
||||
vkCmdBindDescriptorSets(cmd_buff, VK_PIPELINE_BIND_POINT_GRAPHICS, _renderer->getPipeline().getPipelineLayout(), 0, sets.size(), sets.data(), 0, nullptr);
|
||||
data.texture->render(*_renderer, data.x, data.y);
|
||||
}
|
||||
for(auto& data : _drawlist)
|
||||
data->render(sets, *_renderer);
|
||||
|
||||
_pixel_put_pipeline.present();
|
||||
sets[1] = _pixel_put_pipeline.getDescriptorSet();
|
||||
vkCmdBindDescriptorSets(cmd_buff, VK_PIPELINE_BIND_POINT_GRAPHICS, _renderer->getPipeline().getPipelineLayout(), 0, sets.size(), sets.data(), 0, nullptr);
|
||||
_pixel_put_pipeline.render(*_renderer);
|
||||
|
||||
_text_put_pipeline->render(sets);
|
||||
_pixel_put_pipeline.render(sets, *_renderer);
|
||||
|
||||
_renderer->endFrame();
|
||||
|
||||
for(auto& data : _textures_to_render)
|
||||
data.texture->resetUpdate();
|
||||
for(auto& data : _drawlist)
|
||||
data->resetUpdate();
|
||||
|
||||
#ifdef GRAPHICS_MEMORY_DUMP
|
||||
// dump memory to file every two seconds
|
||||
@@ -100,7 +82,7 @@ namespace mlx
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
vkDeviceWaitIdle(Render_Core::get().getDevice().get());
|
||||
_text_put_pipeline->destroy();
|
||||
_text_manager.destroy();
|
||||
_pixel_put_pipeline.destroy();
|
||||
_renderer->destroy();
|
||||
if(_window)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/04/02 14:49:49 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/10 19:59:58 by maldavid ### ########.fr */
|
||||
/* Updated: 2024/01/11 15:47:05 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@@ -23,7 +23,9 @@
|
||||
#include <platform/window.h>
|
||||
#include <renderer/renderer.h>
|
||||
#include <renderer/pixel_put.h>
|
||||
#include <renderer/text_pipeline.h>
|
||||
#include <renderer/core/drawable_resource.h>
|
||||
#include <renderer/images/texture_manager.h>
|
||||
#include <renderer/texts/text_manager.h>
|
||||
#include <utils/non_copyable.h>
|
||||
#include <renderer/images/texture.h>
|
||||
#include <mlx_profile.h>
|
||||
@@ -48,20 +50,31 @@ namespace mlx
|
||||
inline void texturePut(Texture* texture, int x, int y);
|
||||
inline void loadFont(const std::filesystem::path& filepath, float scale);
|
||||
|
||||
inline bool hasWindow() const noexcept { return _has_window; }
|
||||
|
||||
inline Renderer& getRenderer() { return *_renderer; }
|
||||
|
||||
~GraphicsSupport();
|
||||
|
||||
private:
|
||||
std::vector<TextureRenderData> _textures_to_render;
|
||||
PixelPutPipeline _pixel_put_pipeline;
|
||||
|
||||
std::vector<DrawableResource*> _drawlist;
|
||||
|
||||
TextManager _text_manager;
|
||||
TextureManager _texture_manager;
|
||||
|
||||
glm::mat4 _proj = glm::mat4(1.0);
|
||||
|
||||
std::shared_ptr<MLX_Window> _window;
|
||||
std::unique_ptr<TextPutPipeline> _text_put_pipeline; // unique_ptr because of the size of the class
|
||||
std::unique_ptr<Renderer> _renderer;
|
||||
|
||||
std::size_t _width = 0;
|
||||
std::size_t _height = 0;
|
||||
|
||||
int _id;
|
||||
|
||||
bool _has_window;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include <core/graphics.h>
|
||||
#include <type_traits>
|
||||
#include <iostream>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
@@ -21,9 +21,10 @@ namespace mlx
|
||||
void GraphicsSupport::clearRenderData() noexcept
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
_textures_to_render.clear();
|
||||
_drawlist.clear();
|
||||
_pixel_put_pipeline.clear();
|
||||
_text_put_pipeline->clear();
|
||||
_text_manager.clear();
|
||||
_texture_manager.clear();
|
||||
}
|
||||
|
||||
void GraphicsSupport::pixelPut(int x, int y, uint32_t color) noexcept
|
||||
@@ -35,21 +36,32 @@ namespace mlx
|
||||
void GraphicsSupport::stringPut(int x, int y, uint32_t color, std::string str)
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
_text_put_pipeline->put(x, y, color, str);
|
||||
std::pair<DrawableResource*, bool> res = _text_manager.registerText(x, y, color, str);
|
||||
if(!res.second) // if this is not a completly new text draw
|
||||
{
|
||||
auto it = std::find(_drawlist.begin(), _drawlist.end(), res.first);
|
||||
if(it != _drawlist.end())
|
||||
_drawlist.erase(it);
|
||||
}
|
||||
_drawlist.push_back(res.first);
|
||||
}
|
||||
|
||||
void GraphicsSupport::texturePut(Texture* texture, int x, int y)
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
_textures_to_render.emplace_back(texture, x, y);
|
||||
auto it = std::find(_textures_to_render.begin(), _textures_to_render.end() - 1, _textures_to_render.back());
|
||||
if(it != _textures_to_render.end() - 1)
|
||||
_textures_to_render.erase(it);
|
||||
auto res = _texture_manager.registerTexture(texture, x, y);
|
||||
if(!res.second) // if this is not a completly new texture draw
|
||||
{
|
||||
auto it = std::find(_drawlist.begin(), _drawlist.end(), res.first);
|
||||
if(it != _drawlist.end())
|
||||
_drawlist.erase(it);
|
||||
}
|
||||
_drawlist.push_back(res.first);
|
||||
}
|
||||
|
||||
void GraphicsSupport::loadFont(const std::filesystem::path& filepath, float scale)
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
_text_put_pipeline->loadFont(filepath, scale);
|
||||
_text_manager.loadFont(*_renderer, filepath, scale);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/05 16:30:19 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/10 18:31:13 by maldavid ### ########.fr */
|
||||
/* Updated: 2024/01/11 19:08:23 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace mlx
|
||||
}
|
||||
|
||||
uint32_t id = _event.window.windowID;
|
||||
if(!_events_hooks.count(id))
|
||||
if(_events_hooks.find(id) == _events_hooks.end())
|
||||
continue;
|
||||
auto& hooks = _events_hooks[id];
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/08 18:55:57 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/10 18:30:31 by maldavid ### ########.fr */
|
||||
/* Updated: 2024/01/11 05:21:20 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#include <core/profiler.h>
|
||||
#include <vma.h>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
@@ -56,15 +55,15 @@ namespace mlx
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
// not creating destroyer in `create` as some image may be copied (and so `this` will be invalid)
|
||||
CmdResource::setDestroyer([this]()
|
||||
{
|
||||
//CmdResource::setDestroyer([this]()
|
||||
//{
|
||||
if(_is_mapped)
|
||||
unmapMem();
|
||||
if(_buffer != VK_NULL_HANDLE)
|
||||
Render_Core::get().getAllocator().destroyBuffer(_allocation, _buffer);
|
||||
_buffer = VK_NULL_HANDLE;
|
||||
});
|
||||
CmdResource::requireDestroy();
|
||||
//});
|
||||
//CmdResource::requireDestroy();
|
||||
}
|
||||
|
||||
void Buffer::createBuffer(VkBufferUsageFlags usage, VmaAllocationCreateInfo info, VkDeviceSize size, [[maybe_unused]] const char* name)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/06 23:18:52 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/03 15:26:56 by maldavid ### ########.fr */
|
||||
/* Updated: 2024/01/11 05:16:58 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/01/25 15:05:05 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/03 15:27:02 by maldavid ### ########.fr */
|
||||
/* Updated: 2024/01/10 23:05:15 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace mlx
|
||||
{
|
||||
public:
|
||||
inline void create(uint32_t size, const uint16_t* data, const char* name) { Buffer::create(Buffer::kind::constant, size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, name, data); }
|
||||
inline void bind(Renderer& renderer) noexcept { vkCmdBindIndexBuffer(renderer.getActiveCmdBuffer().get(), _buffer, _offset, VK_INDEX_TYPE_UINT16); }
|
||||
inline void bind(Renderer& renderer) noexcept { renderer.getActiveCmdBuffer().bindIndexBuffer(*this); }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/06 18:27:38 by maldavid #+# #+# */
|
||||
/* Updated: 2023/12/12 22:46:21 by kbz_8 ### ########.fr */
|
||||
/* Updated: 2024/01/10 23:04:40 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace mlx
|
||||
public:
|
||||
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); }
|
||||
inline void bind(Renderer& renderer) noexcept { renderer.getActiveCmdBuffer().bindVertexBuffer(*this); }
|
||||
};
|
||||
|
||||
class D_VBO : public Buffer
|
||||
@@ -32,14 +32,14 @@ namespace mlx
|
||||
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); }
|
||||
inline void bind(Renderer& renderer) noexcept { renderer.getActiveCmdBuffer().bindVertexBuffer(*this); }
|
||||
};
|
||||
|
||||
class C_VBO : public Buffer
|
||||
{
|
||||
public:
|
||||
inline void create(uint32_t size, const void* data, const char* name) { Buffer::create(Buffer::kind::constant, size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, name, data); }
|
||||
inline void bind(Renderer& renderer) noexcept { vkCmdBindVertexBuffers(renderer.getActiveCmdBuffer().get(), 0, 1, &_buffer, &_offset); }
|
||||
inline void bind(Renderer& renderer) noexcept { renderer.getActiveCmdBuffer().bindVertexBuffer(*this); }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/12/15 19:57:49 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/07 01:30:49 by maldavid ### ########.fr */
|
||||
/* Updated: 2024/01/11 03:13:21 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@@ -52,7 +52,6 @@ namespace mlx
|
||||
cmd.waitForExecution();
|
||||
}
|
||||
|
||||
|
||||
void SingleTimeCmdManager::destroy() noexcept
|
||||
{
|
||||
std::for_each(_buffers.begin(), _buffers.end(), [](CmdBuffer& buf)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/12/16 20:44:29 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/07 01:19:10 by maldavid ### ########.fr */
|
||||
/* Updated: 2024/01/11 05:12:42 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
|
||||
32
src/renderer/core/drawable_resource.h
git.filemode.normal_file
32
src/renderer/core/drawable_resource.h
git.filemode.normal_file
@@ -0,0 +1,32 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* drawable_resource.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/01/10 21:00:37 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/11 01:21:15 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef __MLX_DRAWABLE_RESOURCE__
|
||||
#define __MLX_DRAWABLE_RESOURCE__
|
||||
|
||||
#include <mlx_profile.h>
|
||||
#include <volk.h>
|
||||
#include <array>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
class DrawableResource
|
||||
{
|
||||
public:
|
||||
DrawableResource() = default;
|
||||
virtual void render(std::array<VkDescriptorSet, 2>& sets, class Renderer& renderer) = 0;
|
||||
virtual void resetUpdate() {}
|
||||
virtual ~DrawableResource() = default;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: kbz_8 <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/10/20 22:02:37 by kbz_8 #+# #+# */
|
||||
/* Updated: 2024/01/10 18:29:07 by maldavid ### ########.fr */
|
||||
/* Updated: 2024/01/10 21:54:35 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@@ -193,5 +193,8 @@ namespace mlx
|
||||
vmaDestroyAllocator(_allocator);
|
||||
_active_buffers_allocations = 0;
|
||||
_active_images_allocations = 0;
|
||||
#ifdef DEBUG
|
||||
core::error::report(e_kind::message, "Vulkan : destroyed a graphics allocator");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/08 19:16:32 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/10 18:36:58 by maldavid ### ########.fr */
|
||||
/* Updated: 2024/01/11 05:14:03 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@@ -54,6 +54,7 @@ namespace mlx
|
||||
void init();
|
||||
void destroy();
|
||||
|
||||
inline bool isInit() const noexcept { return _is_init; }
|
||||
inline Instance& getInstance() noexcept { return _instance; }
|
||||
inline Device& getDevice() noexcept { return _device; }
|
||||
inline Queues& getQueue() noexcept { return _queues; }
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/08 19:14:29 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/08 23:48:53 by maldavid ### ########.fr */
|
||||
/* Updated: 2024/01/10 21:54:17 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@@ -159,5 +159,8 @@ namespace mlx
|
||||
{
|
||||
vkDestroyDevice(_device, nullptr);
|
||||
_device = VK_NULL_HANDLE;
|
||||
#ifdef DEBUG
|
||||
core::error::report(e_kind::message, "Vulkan : destroyed a logical device");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/08 19:04:21 by maldavid #+# #+# */
|
||||
/* Updated: 2023/12/31 00:40:10 by maldavid ### ########.fr */
|
||||
/* Updated: 2024/01/10 21:54:06 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@@ -84,5 +84,8 @@ namespace mlx
|
||||
{
|
||||
vkDestroyInstance(_instance, nullptr);
|
||||
_instance = VK_NULL_HANDLE;
|
||||
#ifdef DEBUG
|
||||
core::error::report(e_kind::message, "Vulkan : destroyed an instance");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/08 19:02:42 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/08 23:46:36 by maldavid ### ########.fr */
|
||||
/* Updated: 2024/01/10 21:54:54 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@@ -64,5 +64,8 @@ namespace mlx
|
||||
}
|
||||
vkGetDeviceQueue(Render_Core::get().getDevice().get(), _families->graphicsFamily.value(), 0, &_graphicsQueue);
|
||||
vkGetDeviceQueue(Render_Core::get().getDevice().get(), _families->presentFamily.value(), 0, &_presentQueue);
|
||||
#ifdef DEBUG
|
||||
core::error::report(e_kind::message, "Vulkan : got graphics and present queues");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/08 19:01:08 by maldavid #+# #+# */
|
||||
/* Updated: 2023/12/16 18:47:29 by maldavid ### ########.fr */
|
||||
/* Updated: 2024/01/10 21:55:12 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace mlx
|
||||
(res = vkCreateSemaphore(Render_Core::get().getDevice().get(), &semaphoreInfo, nullptr, &_renderFinishedSemaphores)) != VK_SUCCESS)
|
||||
core::error::report(e_kind::fatal_error, "Vulkan : failed to create a synchronization object (semaphore), %s", RCore::verbaliseResultVk(res));
|
||||
#ifdef DEBUG
|
||||
core::error::report(e_kind::message, "Vulkan : created new semaphore");
|
||||
core::error::report(e_kind::message, "Vulkan : created new semaphores");
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -36,5 +36,8 @@ namespace mlx
|
||||
_renderFinishedSemaphores = VK_NULL_HANDLE;
|
||||
vkDestroySemaphore(Render_Core::get().getDevice().get(), _imageAvailableSemaphores, nullptr);
|
||||
_imageAvailableSemaphores = VK_NULL_HANDLE;
|
||||
#ifdef DEBUG
|
||||
core::error::report(e_kind::message, "Vulkan : destroyed semaphores");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/08 18:58:49 by maldavid #+# #+# */
|
||||
/* Updated: 2023/12/30 23:14:54 by maldavid ### ########.fr */
|
||||
/* Updated: 2024/01/10 21:55:21 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@@ -42,5 +42,8 @@ namespace mlx
|
||||
{
|
||||
vkDestroySurfaceKHR(Render_Core::get().getInstance().get(), _surface, nullptr);
|
||||
_surface = VK_NULL_HANDLE;
|
||||
#ifdef DEBUG
|
||||
core::error::report(e_kind::message, "Vulkan : destroyed a surface");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/12/19 14:05:25 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/07 00:33:40 by maldavid ### ########.fr */
|
||||
/* Updated: 2024/01/10 21:55:54 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@@ -98,7 +98,12 @@ namespace mlx
|
||||
void ValidationLayers::destroy()
|
||||
{
|
||||
if constexpr(enableValidationLayers)
|
||||
{
|
||||
destroyDebugUtilsMessengerEXT(nullptr);
|
||||
#ifdef DEBUG
|
||||
core::error::report(e_kind::message, "Vulkan : destroyed validation layers");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
VkResult ValidationLayers::createDebugUtilsMessengerEXT(const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/03/31 18:03:35 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/10 18:28:11 by maldavid ### ########.fr */
|
||||
/* Updated: 2024/01/11 01:20:29 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@@ -126,7 +126,7 @@ namespace mlx
|
||||
#endif
|
||||
}
|
||||
|
||||
void Texture::render(Renderer& renderer, int x, int y)
|
||||
void Texture::render(std::array<VkDescriptorSet, 2>& sets, Renderer& renderer, int x, int y)
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
if(_has_been_modified)
|
||||
@@ -135,11 +135,19 @@ namespace mlx
|
||||
Image::copyFromBuffer(*_buf_map);
|
||||
_has_been_modified = false;
|
||||
}
|
||||
if(!_set.isInit())
|
||||
_set = renderer.getFragDescriptorSet().duplicate();
|
||||
if(getLayout() != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
|
||||
transitionLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
if(!_has_set_been_updated)
|
||||
updateSet(0);
|
||||
auto cmd = renderer.getActiveCmdBuffer();
|
||||
_vbo.bind(renderer);
|
||||
_ibo.bind(renderer);
|
||||
glm::vec2 translate(x, y);
|
||||
vkCmdPushConstants(cmd.get(), renderer.getPipeline().getPipelineLayout(), VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(translate), &translate);
|
||||
sets[1] = _set.get();
|
||||
vkCmdBindDescriptorSets(renderer.getActiveCmdBuffer().get(), VK_PIPELINE_BIND_POINT_GRAPHICS, renderer.getPipeline().getPipelineLayout(), 0, sets.size(), sets.data(), 0, nullptr);
|
||||
vkCmdDrawIndexed(cmd.get(), static_cast<uint32_t>(_ibo.getSize() / sizeof(uint16_t)), 1, 0, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/03/08 02:24:58 by maldavid #+# #+# */
|
||||
/* Updated: 2023/12/23 18:49:12 by kbz_8 ### ########.fr */
|
||||
/* Updated: 2024/01/11 01:18:25 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@@ -26,13 +26,13 @@
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
class Texture : public Image
|
||||
class Texture : public Image
|
||||
{
|
||||
public:
|
||||
Texture() = default;
|
||||
|
||||
|
||||
void create(uint8_t* pixels, uint32_t width, uint32_t height, VkFormat format, const char* name, bool dedicated_memory = false);
|
||||
void render(class Renderer& renderer, int x, int y);
|
||||
void render(std::array<VkDescriptorSet, 2>& sets, class Renderer& renderer, int x, int y);
|
||||
void destroy() noexcept override;
|
||||
|
||||
void setPixel(int x, int y, uint32_t color) noexcept;
|
||||
@@ -40,9 +40,9 @@ namespace mlx
|
||||
|
||||
inline void setDescriptor(DescriptorSet&& set) noexcept { _set = set; }
|
||||
inline VkDescriptorSet getSet() noexcept { return _set.isInit() ? _set.get() : VK_NULL_HANDLE; }
|
||||
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; }
|
||||
inline void updateSet(int binding) noexcept { _set.writeDescriptor(binding, *this); _has_set_been_updated = true; }
|
||||
inline bool hasBeenUpdated() const noexcept { return _has_set_been_updated; }
|
||||
inline constexpr void resetUpdate() noexcept { _has_set_been_updated = false; }
|
||||
|
||||
~Texture() = default;
|
||||
|
||||
@@ -60,20 +60,10 @@ namespace mlx
|
||||
std::optional<Buffer> _buf_map = std::nullopt;
|
||||
void* _map = nullptr;
|
||||
bool _has_been_modified = false;
|
||||
bool _has_been_updated = false;
|
||||
bool _has_set_been_updated = false;
|
||||
};
|
||||
|
||||
Texture stbTextureLoad(std::filesystem::path file, int* w, int* h);
|
||||
|
||||
struct TextureRenderData
|
||||
{
|
||||
Texture* texture;
|
||||
int x;
|
||||
int y;
|
||||
|
||||
TextureRenderData(Texture* _texture, int _x, int _y) : texture(_texture), x(_x), y(_y) {}
|
||||
bool operator==(const TextureRenderData& rhs) const { return texture == rhs.texture && x == rhs.x && y == rhs.y; }
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
59
src/renderer/images/texture_descriptor.h
git.filemode.normal_file
59
src/renderer/images/texture_descriptor.h
git.filemode.normal_file
@@ -0,0 +1,59 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* texture_descriptor.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/01/11 01:00:13 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/11 01:21:52 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef __MLX_TEXTURE_DESCRIPTOR__
|
||||
#define __MLX_TEXTURE_DESCRIPTOR__
|
||||
|
||||
#include <renderer/images/texture.h>
|
||||
#include <renderer/core/drawable_resource.h>
|
||||
#include <utils/combine_hash.h>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
struct TextureRenderDescriptor : public DrawableResource
|
||||
{
|
||||
Texture* texture;
|
||||
int x;
|
||||
int y;
|
||||
|
||||
TextureRenderDescriptor(Texture* _texture, int _x, int _y) : texture(_texture), x(_x), y(_y) {}
|
||||
inline bool operator==(const TextureRenderDescriptor& rhs) const { return texture == rhs.texture && x == rhs.x && y == rhs.y; }
|
||||
inline void render(std::array<VkDescriptorSet, 2>& sets, class Renderer& renderer) override
|
||||
{
|
||||
if(!texture->isInit())
|
||||
return;
|
||||
texture->render(sets, renderer, x, y);
|
||||
}
|
||||
inline void resetUpdate() override
|
||||
{
|
||||
if(!texture->isInit())
|
||||
return;
|
||||
texture->resetUpdate();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <>
|
||||
struct hash<mlx::TextureRenderDescriptor>
|
||||
{
|
||||
std::size_t operator()(const mlx::TextureRenderDescriptor& d) const noexcept
|
||||
{
|
||||
std::size_t hash = 0;
|
||||
mlx::hashCombine(hash, d.texture, d.x, d.y);
|
||||
return hash;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
43
src/renderer/images/texture_manager.h
git.filemode.normal_file
43
src/renderer/images/texture_manager.h
git.filemode.normal_file
@@ -0,0 +1,43 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* texture_manager.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/01/11 00:56:15 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/11 01:49:12 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef __MLX_TEXTURE_MANAGER__
|
||||
#define __MLX_TEXTURE_MANAGER__
|
||||
|
||||
#include <unordered_set>
|
||||
#include <renderer/images/texture_descriptor.h>
|
||||
#include <core/profiler.h>
|
||||
#include <utility>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
class TextureManager
|
||||
{
|
||||
public:
|
||||
TextureManager() = default;
|
||||
|
||||
inline void clear() { _texture_descriptors.clear(); }
|
||||
inline std::pair<DrawableResource*, bool> registerTexture(Texture* texture, int x, int y)
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
auto res = _texture_descriptors.emplace(texture, x, y);
|
||||
return std::make_pair(static_cast<DrawableResource*>(&const_cast<TextureRenderDescriptor&>(*res.first)), res.second);
|
||||
}
|
||||
|
||||
~TextureManager() = default;
|
||||
|
||||
private:
|
||||
std::unordered_set<TextureRenderDescriptor> _texture_descriptors;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/12/18 21:27:38 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/03 13:16:57 by maldavid ### ########.fr */
|
||||
/* Updated: 2024/01/10 21:53:38 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@@ -320,5 +320,9 @@ namespace mlx
|
||||
{
|
||||
vkDestroyPipeline(Render_Core::get().getDevice().get(), _graphicsPipeline, nullptr);
|
||||
vkDestroyPipelineLayout(Render_Core::get().getDevice().get(), _pipelineLayout, nullptr);
|
||||
_graphicsPipeline = VK_NULL_HANDLE;
|
||||
#ifdef DEBUG
|
||||
core::error::report(e_kind::message, "Vulkan : destroyed a graphics pipeline");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/03/31 15:14:50 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/10 18:26:59 by maldavid ### ########.fr */
|
||||
/* Updated: 2024/01/11 00:06:01 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace mlx
|
||||
_has_been_modified = true;
|
||||
}
|
||||
|
||||
void PixelPutPipeline::present() noexcept
|
||||
void PixelPutPipeline::render(std::array<VkDescriptorSet, 2>& sets, Renderer& renderer) noexcept
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
if(_has_been_modified)
|
||||
@@ -55,12 +55,7 @@ namespace mlx
|
||||
_has_been_modified = false;
|
||||
}
|
||||
_texture.updateSet(0);
|
||||
}
|
||||
|
||||
void PixelPutPipeline::render(Renderer& renderer) noexcept
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
_texture.render(renderer, 0, 0);
|
||||
_texture.render(sets, renderer, 0, 0);
|
||||
}
|
||||
|
||||
void PixelPutPipeline::destroy() noexcept
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/03/31 13:18:50 by maldavid #+# #+# */
|
||||
/* Updated: 2023/12/14 18:24:58 by maldavid ### ########.fr */
|
||||
/* Updated: 2024/01/11 00:06:05 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@@ -27,9 +27,7 @@ namespace mlx
|
||||
void init(uint32_t width, uint32_t height, class Renderer& renderer) noexcept;
|
||||
|
||||
void setPixel(int x, int y, uint32_t color) noexcept;
|
||||
void present() noexcept;
|
||||
void render(class Renderer& renderer) noexcept;
|
||||
inline VkDescriptorSet getDescriptorSet() noexcept { return _texture.getSet(); }
|
||||
void render(std::array<VkDescriptorSet, 2>& sets, class Renderer& renderer) noexcept;
|
||||
|
||||
void clear();
|
||||
void destroy() noexcept;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/06 18:18:06 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/03 13:17:27 by maldavid ### ########.fr */
|
||||
/* Updated: 2024/01/10 21:52:51 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@@ -45,5 +45,8 @@ namespace mlx
|
||||
{
|
||||
vkDestroyFramebuffer(Render_Core::get().getDevice().get(), _framebuffer, nullptr);
|
||||
_framebuffer = VK_NULL_HANDLE;
|
||||
#ifdef DEBUG
|
||||
core::error::report(e_kind::message, "Vulkan : destroyed a framebuffer");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/06 18:21:36 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/10 18:27:43 by maldavid ### ########.fr */
|
||||
/* Updated: 2024/01/10 21:53:03 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@@ -112,5 +112,8 @@ namespace mlx
|
||||
{
|
||||
vkDestroyRenderPass(Render_Core::get().getDevice().get(), _renderPass, nullptr);
|
||||
_renderPass = VK_NULL_HANDLE;
|
||||
#ifdef DEBUG
|
||||
core::error::report(e_kind::message, "Vulkan : destroyed a renderpass");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,152 +0,0 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* text_pipeline.cpp :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/04/06 16:41:13 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/10 20:20:30 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include <renderer/text_pipeline.h>
|
||||
#include <core/profiler.h>
|
||||
#include <fstream>
|
||||
|
||||
#include <utils/dogica_ttf.h>
|
||||
#include <iostream>
|
||||
#include <cstdio>
|
||||
|
||||
#define STB_RECT_PACK_IMPLEMENTATION
|
||||
#include <stb_rect_pack.h>
|
||||
|
||||
#include <core/memory.h>
|
||||
|
||||
#define STB_TRUETYPE_IMPLEMENTATION
|
||||
#define STB_malloc(x, u) ((void)(u), MemManager::malloc(x))
|
||||
#define STB_free(x, u) ((void)(u), MemManager::free(x))
|
||||
#include <stb_truetype.h>
|
||||
|
||||
constexpr const int RANGE = 1024;
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
TextDrawData::TextDrawData(std::string _text, uint32_t _color, int _x, int _y) :
|
||||
x(_x), y(_y), color(_color),
|
||||
text(std::move(_text))
|
||||
{}
|
||||
|
||||
void TextDrawData::init(TextLibrary& library, Font* const font) noexcept
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
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 != '\n')
|
||||
continue;
|
||||
|
||||
stbtt_aligned_quad q;
|
||||
stbtt_GetPackedQuad(font->getCharData().data(), RANGE, RANGE, c - 32, &stb_x, &stb_y, &q, 1);
|
||||
|
||||
std::size_t index = vertexData.size();
|
||||
|
||||
glm::vec4 vertex_color = {
|
||||
static_cast<float>((color & 0x000000FF)) / 255.f,
|
||||
static_cast<float>((color & 0x0000FF00) >> 8) / 255.f,
|
||||
static_cast<float>((color & 0x00FF0000) >> 16) / 255.f,
|
||||
static_cast<float>((color & 0xFF000000) >> 24) / 255.f
|
||||
};
|
||||
|
||||
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<TextData> text_data = std::make_shared<TextData>();
|
||||
text_data->init(text, font, 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
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
_renderer = renderer;
|
||||
_font_in_use = &const_cast<Font&>(*_font_set.emplace(*_renderer, "default", dogica_ttf, 6.0f).first);
|
||||
}
|
||||
|
||||
void TextPutPipeline::loadFont(const std::filesystem::path& filepath, float scale)
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
if(filepath.string() == "default") // we're sure it is already loaded
|
||||
_font_in_use = &const_cast<Font&>(*_font_set.emplace(*_renderer, "default", dogica_ttf, scale).first);
|
||||
else
|
||||
_font_in_use = &const_cast<Font&>(*_font_set.emplace(*_renderer, filepath, scale).first);
|
||||
}
|
||||
|
||||
void TextPutPipeline::put(int x, int y, uint32_t color, std::string str)
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
auto res = _drawlist.emplace(std::move(str), color, x, y);
|
||||
if(res.second)
|
||||
const_cast<TextDrawData&>(*res.first).init(_library, _font_in_use);
|
||||
else
|
||||
{
|
||||
auto text_ptr = _library.getTextData(res.first->id);
|
||||
if(*_font_in_use != text_ptr->getFontInUse())
|
||||
{
|
||||
_library.removeTextFromLibrary(res.first->id);
|
||||
const_cast<TextDrawData&>(*res.first).init(_library, _font_in_use);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TextPutPipeline::render(std::array<VkDescriptorSet, 2>& sets)
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
for(auto& draw : _drawlist)
|
||||
{
|
||||
std::shared_ptr<TextData> draw_data = _library.getTextData(draw.id);
|
||||
TextureAtlas& atlas = const_cast<TextureAtlas&>(draw_data->getFontInUse().getAtlas());
|
||||
draw_data->bind(*_renderer);
|
||||
if(atlas.getSet() == VK_NULL_HANDLE)
|
||||
atlas.setDescriptor(_renderer->getFragDescriptorSet().duplicate());
|
||||
if(!atlas.hasBeenUpdated())
|
||||
atlas.updateSet(0);
|
||||
sets[1] = const_cast<TextureAtlas&>(atlas).getSet();
|
||||
vkCmdBindDescriptorSets(_renderer->getActiveCmdBuffer().get(), VK_PIPELINE_BIND_POINT_GRAPHICS, _renderer->getPipeline().getPipelineLayout(), 0, sets.size(), sets.data(), 0, nullptr);
|
||||
atlas.render(*_renderer, draw.x, draw.y, draw_data->getIBOsize());
|
||||
}
|
||||
|
||||
for(auto& draw : _drawlist)
|
||||
{
|
||||
std::shared_ptr<TextData> draw_data = _library.getTextData(draw.id);
|
||||
TextureAtlas& atlas = const_cast<TextureAtlas&>(draw_data->getFontInUse().getAtlas());
|
||||
atlas.resetUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
void TextPutPipeline::destroy() noexcept
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
_library.clearLibrary();
|
||||
_drawlist.clear();
|
||||
_font_set.clear();
|
||||
}
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* text_pipeline.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/04/06 16:24:11 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/10 19:58:22 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef __MLX_TEXT_PIPELINE__
|
||||
#define __MLX_TEXT_PIPELINE__
|
||||
|
||||
#include <renderer/renderer.h>
|
||||
#include <renderer/images/texture_atlas.h>
|
||||
#include <string>
|
||||
#include <stb_truetype.h>
|
||||
#include <cstdint>
|
||||
#include <unordered_set>
|
||||
#include <renderer/text_library.h>
|
||||
#include <mlx_profile.h>
|
||||
#include <utils/combine_hash.h>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
struct TextDrawData
|
||||
{
|
||||
TextID id;
|
||||
int x;
|
||||
int y;
|
||||
uint32_t color;
|
||||
std::string text;
|
||||
|
||||
TextDrawData(std::string text, uint32_t _color, int _x, int _y);
|
||||
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; }
|
||||
TextDrawData() = default;
|
||||
};
|
||||
}
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <>
|
||||
struct hash<mlx::TextDrawData>
|
||||
{
|
||||
std::size_t operator()(const mlx::TextDrawData& d) const noexcept
|
||||
{
|
||||
std::size_t hash = 0;
|
||||
mlx::hashCombine(hash, d.text, d.x, d.y, d.color);
|
||||
return hash;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
class TextPutPipeline
|
||||
{
|
||||
public:
|
||||
TextPutPipeline() = default;
|
||||
|
||||
void init(Renderer* renderer) noexcept;
|
||||
void put(int x, int y, uint32_t color, std::string str);
|
||||
inline void clear() { _drawlist.clear(); _library.clearLibrary(); }
|
||||
void loadFont(const std::filesystem::path& filepath, float scale);
|
||||
void render(std::array<VkDescriptorSet, 2>& sets);
|
||||
void destroy() noexcept;
|
||||
|
||||
~TextPutPipeline() = default;
|
||||
|
||||
private:
|
||||
std::unordered_set<Font> _font_set;
|
||||
TextLibrary _library;
|
||||
std::unordered_set<TextDrawData> _drawlist;
|
||||
Renderer* _renderer = nullptr;
|
||||
Font* _font_in_use = nullptr;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -6,11 +6,11 @@
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/12/11 22:06:09 by kbz_8 #+# #+# */
|
||||
/* Updated: 2024/01/10 18:27:14 by maldavid ### ########.fr */
|
||||
/* Updated: 2024/01/11 01:23:20 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include <renderer/font.h>
|
||||
#include <renderer/texts/font.h>
|
||||
#include <renderer/renderer.h>
|
||||
#include <core/profiler.h>
|
||||
#include <fstream>
|
||||
@@ -6,7 +6,7 @@
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/12/11 21:17:04 by kbz_8 #+# #+# */
|
||||
/* Updated: 2023/12/14 17:51:40 by maldavid ### ########.fr */
|
||||
/* Updated: 2024/01/11 20:08:55 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@@ -31,8 +31,8 @@ namespace mlx
|
||||
inline float getScale() const noexcept { return _scale; }
|
||||
inline const std::array<stbtt_packedchar, 96>& getCharData() const { return _cdata; }
|
||||
inline const TextureAtlas& getAtlas() const noexcept { return _atlas; }
|
||||
inline bool operator==(const Font& rhs) const { return rhs._name == _name; }
|
||||
inline bool operator!=(const Font& rhs) const { return rhs._name != _name; }
|
||||
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; }
|
||||
~Font();
|
||||
|
||||
private:
|
||||
@@ -1,24 +1,22 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* text_library.cpp :+: :+: :+: */
|
||||
/* text.cpp :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/04/10 11:59:57 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/10 18:26:44 by maldavid ### ########.fr */
|
||||
/* Created: 2024/01/11 00:11:56 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/11 03:31:57 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include <renderer/text_library.h>
|
||||
#include <core/errors.h>
|
||||
#include <renderer/renderer.h>
|
||||
#include <algorithm>
|
||||
#include <core/profiler.h>
|
||||
#include <renderer/texts/text.h>
|
||||
#include <renderer/renderer.h>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
void TextData::init(std::string text, Font const* font, std::vector<Vertex> vbo_data, std::vector<uint16_t> ibo_data)
|
||||
void Text::init(std::string text, Font const* font, std::vector<Vertex> vbo_data, std::vector<uint16_t> ibo_data)
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
_text = std::move(text);
|
||||
@@ -34,64 +32,24 @@ namespace mlx
|
||||
#endif
|
||||
}
|
||||
|
||||
void TextData::bind(Renderer& renderer) noexcept
|
||||
void Text::bind(Renderer& renderer) noexcept
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
_vbo[renderer.getActiveImageIndex()].bind(renderer);
|
||||
_ibo.bind(renderer);
|
||||
}
|
||||
|
||||
void TextData::updateVertexData(int frame, std::vector<Vertex> vbo_data)
|
||||
void Text::updateVertexData(int frame, std::vector<Vertex> vbo_data)
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
_vbo[frame].setData(sizeof(Vertex) * vbo_data.size(), static_cast<const void*>(vbo_data.data()));
|
||||
}
|
||||
|
||||
void TextData::destroy() noexcept
|
||||
void Text::destroy() noexcept
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
|
||||
_vbo[i].destroy();
|
||||
_ibo.destroy();
|
||||
}
|
||||
|
||||
std::shared_ptr<TextData> TextLibrary::getTextData(TextID id)
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
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)
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
auto it = std::find_if(_cache.begin(), _cache.end(), [=](const std::pair<TextID, std::shared_ptr<TextData>>& 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)
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
if(_cache.count(id))
|
||||
{
|
||||
_cache[id]->destroy();
|
||||
_cache.erase(id);
|
||||
}
|
||||
}
|
||||
|
||||
void TextLibrary::clearLibrary()
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
for(auto [id, text] : _cache)
|
||||
text->destroy();
|
||||
_cache.clear();
|
||||
}
|
||||
}
|
||||
@@ -1,38 +1,30 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* text_library.h :+: :+: :+: */
|
||||
/* text.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/04/10 11:52:30 by maldavid #+# #+# */
|
||||
/* Updated: 2023/12/12 23:07:13 by kbz_8 ### ########.fr */
|
||||
/* Created: 2024/01/11 00:09:04 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/11 00:13:25 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef __MLX_TEXT_LIBRARY__
|
||||
#define __MLX_TEXT_LIBRARY__
|
||||
#ifndef __MLX_TEXT__
|
||||
#define __MLX_TEXT__
|
||||
|
||||
#include <renderer/buffers/vk_vbo.h>
|
||||
#include <renderer/buffers/vk_ibo.h>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
#include <mlx_profile.h>
|
||||
#include <renderer/font.h>
|
||||
#include <renderer/core/render_core.h>
|
||||
#include <renderer/texts/font.h>
|
||||
#include <renderer/buffers/vk_ibo.h>
|
||||
#include <renderer/buffers/vk_vbo.h>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
using TextID = uint32_t;
|
||||
constexpr TextID nulltext = 0;
|
||||
|
||||
class TextData
|
||||
class Text
|
||||
{
|
||||
public:
|
||||
TextData() = default;
|
||||
Text() = default;
|
||||
|
||||
void init(std::string text, Font const* font, std::vector<Vertex> vbo_data, std::vector<uint16_t> ibo_data);
|
||||
void bind(class Renderer& renderer) noexcept;
|
||||
@@ -42,32 +34,14 @@ namespace mlx
|
||||
inline const std::string& getText() const { return _text; }
|
||||
void destroy() noexcept;
|
||||
|
||||
~TextData() = default;
|
||||
~Text() = default;
|
||||
|
||||
private:
|
||||
std::array<D_VBO, MAX_FRAMES_IN_FLIGHT> _vbo;
|
||||
C_IBO _ibo;
|
||||
std::string _text;
|
||||
Font const* _font = nullptr;
|
||||
};
|
||||
|
||||
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
|
||||
104
src/renderer/texts/text_descriptor.cpp
git.filemode.normal_file
104
src/renderer/texts/text_descriptor.cpp
git.filemode.normal_file
@@ -0,0 +1,104 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* text_descriptor.cpp :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/01/11 00:23:11 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/11 03:40:54 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include <core/profiler.h>
|
||||
#include <renderer/texts/text_descriptor.h>
|
||||
#include <renderer/images/texture_atlas.h>
|
||||
#include <renderer/texts/font.h>
|
||||
#include <renderer/texts/text.h>
|
||||
|
||||
#define STB_RECT_PACK_IMPLEMENTATION
|
||||
#include <stb_rect_pack.h>
|
||||
|
||||
#include <core/memory.h>
|
||||
|
||||
#define STB_TRUETYPE_IMPLEMENTATION
|
||||
#define STB_malloc(x, u) ((void)(u), MemManager::malloc(x))
|
||||
#define STB_free(x, u) ((void)(u), MemManager::free(x))
|
||||
#include <stb_truetype.h>
|
||||
|
||||
constexpr const int RANGE = 1024;
|
||||
|
||||
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
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
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)
|
||||
continue;
|
||||
|
||||
stbtt_aligned_quad q;
|
||||
stbtt_GetPackedQuad(font->getCharData().data(), RANGE, RANGE, c - 32, &stb_x, &stb_y, &q, 1);
|
||||
|
||||
std::size_t index = vertexData.size();
|
||||
|
||||
glm::vec4 vertex_color = {
|
||||
static_cast<float>((color & 0x000000FF)) / 255.f,
|
||||
static_cast<float>((color & 0x0000FF00) >> 8) / 255.f,
|
||||
static_cast<float>((color & 0x00FF0000) >> 16) / 255.f,
|
||||
static_cast<float>((color & 0xFF000000) >> 24) / 255.f
|
||||
};
|
||||
|
||||
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> text_data = std::make_shared<Text>();
|
||||
text_data->init(_text, font, std::move(vertexData), std::move(indexData));
|
||||
id = TextLibrary::get().addTextToLibrary(text_data);
|
||||
|
||||
#ifdef DEBUG
|
||||
core::error::report(e_kind::message, "Text put : registered new text to render");
|
||||
#endif
|
||||
}
|
||||
|
||||
void TextDrawDescriptor::render(std::array<VkDescriptorSet, 2>& sets, Renderer& renderer)
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
std::shared_ptr<Text> draw_data = TextLibrary::get().getTextData(id);
|
||||
TextureAtlas& atlas = const_cast<TextureAtlas&>(draw_data->getFontInUse().getAtlas());
|
||||
draw_data->bind(renderer);
|
||||
if(atlas.getSet() == VK_NULL_HANDLE)
|
||||
atlas.setDescriptor(renderer.getFragDescriptorSet().duplicate());
|
||||
if(!atlas.hasBeenUpdated())
|
||||
atlas.updateSet(0);
|
||||
sets[1] = const_cast<TextureAtlas&>(atlas).getSet();
|
||||
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());
|
||||
}
|
||||
|
||||
void TextDrawDescriptor::resetUpdate()
|
||||
{
|
||||
std::shared_ptr<Text> draw_data = TextLibrary::get().getTextData(id);
|
||||
TextureAtlas& atlas = const_cast<TextureAtlas&>(draw_data->getFontInUse().getAtlas());
|
||||
atlas.resetUpdate();
|
||||
}
|
||||
}
|
||||
65
src/renderer/texts/text_descriptor.h
git.filemode.normal_file
65
src/renderer/texts/text_descriptor.h
git.filemode.normal_file
@@ -0,0 +1,65 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* text_descriptor.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/01/11 00:13:34 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/11 04:28:58 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef __MLX_TEXT_DESCRIPTOR__
|
||||
#define __MLX_TEXT_DESCRIPTOR__
|
||||
|
||||
#include <string>
|
||||
#include <mlx_profile.h>
|
||||
#include <volk.h>
|
||||
#include <utils/combine_hash.h>
|
||||
#include <renderer/core/drawable_resource.h>
|
||||
#include <renderer/texts/text_library.h>
|
||||
#include <array>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
class TextDrawDescriptor : public DrawableResource
|
||||
{
|
||||
friend class std::hash<TextDrawDescriptor>;
|
||||
|
||||
public:
|
||||
TextID id;
|
||||
uint32_t color;
|
||||
int x;
|
||||
int y;
|
||||
|
||||
public:
|
||||
TextDrawDescriptor(std::string text, uint32_t _color, int _x, int _y);
|
||||
|
||||
void init(Font* const 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<VkDescriptorSet, 2>& sets, Renderer& renderer) override;
|
||||
void resetUpdate() override;
|
||||
|
||||
TextDrawDescriptor() = default;
|
||||
|
||||
private:
|
||||
std::string _text;
|
||||
};
|
||||
}
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <>
|
||||
struct hash<mlx::TextDrawDescriptor>
|
||||
{
|
||||
std::size_t operator()(const mlx::TextDrawDescriptor& d) const noexcept
|
||||
{
|
||||
std::size_t hash = 0;
|
||||
mlx::hashCombine(hash, d.x, d.y, d.color, d._text);
|
||||
return hash;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
67
src/renderer/texts/text_library.cpp
git.filemode.normal_file
67
src/renderer/texts/text_library.cpp
git.filemode.normal_file
@@ -0,0 +1,67 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* text_library.cpp :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/04/10 11:59:57 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/11 05:19:24 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include <iostream>
|
||||
#include <renderer/texts/text_library.h>
|
||||
#include <renderer/texts/text.h>
|
||||
#include <core/errors.h>
|
||||
#include <renderer/renderer.h>
|
||||
#include <algorithm>
|
||||
#include <core/profiler.h>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
std::shared_ptr<Text> TextLibrary::getTextData(TextID 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, "Text Library : wrong text ID '%d'", id);
|
||||
return _cache[id];
|
||||
}
|
||||
|
||||
TextID TextLibrary::addTextToLibrary(std::shared_ptr<Text> text)
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
auto it = std::find_if(_cache.begin(), _cache.end(), [&](const std::pair<TextID, std::shared_ptr<Text>>& v)
|
||||
{
|
||||
return v.second->getText() == text->getText() && std::find(_invalid_ids.begin(), _invalid_ids.end(), v.first) == _invalid_ids.end();
|
||||
});
|
||||
if(it != _cache.end())
|
||||
return it->first;
|
||||
_cache[_current_id] = text;
|
||||
_current_id++;
|
||||
return _current_id - 1;
|
||||
}
|
||||
|
||||
void TextLibrary::removeTextFromLibrary(TextID 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, "Text Library : trying to remove a text with an unkown or invalid ID '%d'", id);
|
||||
return;
|
||||
}
|
||||
_cache[id]->destroy();
|
||||
_invalid_ids.push_back(id);
|
||||
}
|
||||
|
||||
void TextLibrary::clearLibrary()
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
for(auto& [id, text] : _cache)
|
||||
{
|
||||
text->destroy();
|
||||
_invalid_ids.push_back(id);
|
||||
}
|
||||
// do not `_cache.clear();` as it releases the texts and may not destroy Vertex and Index buffers that are in use by command buffers
|
||||
}
|
||||
}
|
||||
55
src/renderer/texts/text_library.h
git.filemode.normal_file
55
src/renderer/texts/text_library.h
git.filemode.normal_file
@@ -0,0 +1,55 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* text_library.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/04/10 11:52:30 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/11 05:08:04 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>
|
||||
#include <mlx_profile.h>
|
||||
#include <renderer/texts/font.h>
|
||||
#include <renderer/core/render_core.h>
|
||||
#include <utils/singleton.h>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
using TextID = uint32_t;
|
||||
constexpr TextID nulltext = 0;
|
||||
|
||||
class TextLibrary : public Singleton<TextLibrary>
|
||||
{
|
||||
friend class Singleton<TextLibrary>;
|
||||
|
||||
public:
|
||||
std::shared_ptr<class Text> getTextData(TextID id);
|
||||
TextID addTextToLibrary(std::shared_ptr<Text> text);
|
||||
void removeTextFromLibrary(TextID id);
|
||||
|
||||
void clearLibrary();
|
||||
|
||||
private:
|
||||
TextLibrary() = default;
|
||||
~TextLibrary() = default;
|
||||
|
||||
private:
|
||||
std::unordered_map<TextID, std::shared_ptr<class Text>> _cache;
|
||||
std::vector<TextID> _invalid_ids;
|
||||
TextID _current_id = 1;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
66
src/renderer/texts/text_manager.cpp
git.filemode.normal_file
66
src/renderer/texts/text_manager.cpp
git.filemode.normal_file
@@ -0,0 +1,66 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* text_manager.cpp :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/04/06 16:41:13 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/11 04:54:16 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include <renderer/texts/text_descriptor.h>
|
||||
#include <renderer/texts/text_library.h>
|
||||
#include <renderer/texts/text.h>
|
||||
#include <renderer/texts/text_manager.h>
|
||||
#include <array>
|
||||
#include <core/profiler.h>
|
||||
#include <fstream>
|
||||
|
||||
#include <utils/dogica_ttf.h>
|
||||
#include <cstdio>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
void TextManager::init(Renderer& renderer) noexcept
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
_font_in_use = &const_cast<Font&>(*_font_set.emplace(renderer, "default", dogica_ttf, 6.0f).first);
|
||||
}
|
||||
|
||||
void TextManager::loadFont(Renderer& renderer, const std::filesystem::path& filepath, float scale)
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
if(filepath.string() == "default") // we're sure it is already loaded
|
||||
_font_in_use = &const_cast<Font&>(*_font_set.emplace(renderer, "default", dogica_ttf, scale).first);
|
||||
else
|
||||
_font_in_use = &const_cast<Font&>(*_font_set.emplace(renderer, filepath, scale).first);
|
||||
}
|
||||
|
||||
std::pair<DrawableResource*, bool> TextManager::registerText(int x, int y, uint32_t color, std::string str)
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
auto res = _text_descriptors.emplace(std::move(str), color, x, y);
|
||||
if(res.second)
|
||||
{
|
||||
const_cast<TextDrawDescriptor&>(*res.first).init(_font_in_use);
|
||||
return std::make_pair(static_cast<DrawableResource*>(&const_cast<TextDrawDescriptor&>(*res.first)), true);
|
||||
}
|
||||
|
||||
auto text_ptr = TextLibrary::get().getTextData(res.first->id);
|
||||
if(*_font_in_use != text_ptr->getFontInUse())
|
||||
{
|
||||
TextLibrary::get().removeTextFromLibrary(res.first->id);
|
||||
const_cast<TextDrawDescriptor&>(*res.first).init(_font_in_use);
|
||||
}
|
||||
return std::make_pair(static_cast<DrawableResource*>(&const_cast<TextDrawDescriptor&>(*res.first)), false);
|
||||
}
|
||||
|
||||
void TextManager::destroy() noexcept
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
_text_descriptors.clear();
|
||||
_font_set.clear();
|
||||
}
|
||||
}
|
||||
48
src/renderer/texts/text_manager.h
git.filemode.normal_file
48
src/renderer/texts/text_manager.h
git.filemode.normal_file
@@ -0,0 +1,48 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* text_manager.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/04/06 16:24:11 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/11 18:48:01 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef __MLX_TEXT_MANAGER__
|
||||
#define __MLX_TEXT_MANAGER__
|
||||
|
||||
#include <renderer/renderer.h>
|
||||
#include <renderer/images/texture_atlas.h>
|
||||
#include <string>
|
||||
#include <stb_truetype.h>
|
||||
#include <cstdint>
|
||||
#include <unordered_set>
|
||||
#include <mlx_profile.h>
|
||||
#include <renderer/texts/text_descriptor.h>
|
||||
#include <renderer/texts/text_library.h>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
class TextManager
|
||||
{
|
||||
public:
|
||||
TextManager() = default;
|
||||
|
||||
void init(Renderer& renderer) noexcept;
|
||||
std::pair<DrawableResource*, bool> registerText(int x, int y, uint32_t color, std::string str);
|
||||
inline void clear() { _text_descriptors.clear(); /*TextLibrary::get().clearLibrary();*/ }
|
||||
void loadFont(Renderer& renderer, const std::filesystem::path& filepath, float scale);
|
||||
void destroy() noexcept;
|
||||
|
||||
~TextManager() = default;
|
||||
|
||||
private:
|
||||
std::unordered_set<TextDrawDescriptor> _text_descriptors;
|
||||
std::unordered_set<Font> _font_set;
|
||||
Font* _font_in_use = nullptr;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,7 +1,31 @@
|
||||
|
||||
{
|
||||
name
|
||||
Memcheck:Leak
|
||||
fun:*alloc
|
||||
fun:*
|
||||
...
|
||||
obj:*libmlx*
|
||||
...
|
||||
}
|
||||
{
|
||||
name
|
||||
Memcheck:Cond
|
||||
fun:*
|
||||
...
|
||||
obj:*libmlx*
|
||||
...
|
||||
}
|
||||
{
|
||||
name
|
||||
Memcheck:Value8
|
||||
fun:*
|
||||
...
|
||||
obj:*libmlx*
|
||||
...
|
||||
}
|
||||
{
|
||||
name
|
||||
Memcheck:Addr4
|
||||
fun:*
|
||||
...
|
||||
obj:*libmlx*
|
||||
...
|
||||
@@ -9,7 +33,7 @@
|
||||
{
|
||||
name
|
||||
Memcheck:Leak
|
||||
fun:*alloc
|
||||
fun:*
|
||||
...
|
||||
obj:*SDL*
|
||||
...
|
||||
@@ -17,7 +41,7 @@
|
||||
{
|
||||
name
|
||||
Memcheck:Leak
|
||||
fun:*alloc
|
||||
fun:*
|
||||
...
|
||||
obj:*X11*
|
||||
...
|
||||
@@ -25,7 +49,7 @@
|
||||
{
|
||||
name
|
||||
Memcheck:Leak
|
||||
fun:*alloc
|
||||
fun:*
|
||||
...
|
||||
obj:*nvidia.so*
|
||||
...
|
||||
@@ -33,7 +57,7 @@
|
||||
{
|
||||
name
|
||||
Memcheck:Leak
|
||||
fun:*alloc
|
||||
fun:*
|
||||
obj:*
|
||||
...
|
||||
fun:X11*
|
||||
@@ -51,7 +75,16 @@
|
||||
{
|
||||
name
|
||||
Memcheck:Leak
|
||||
fun:*alloc
|
||||
fun:*
|
||||
obj:*
|
||||
...
|
||||
fun:_dl_*
|
||||
...
|
||||
}
|
||||
{
|
||||
name
|
||||
Memcheck:Leak
|
||||
fun:*
|
||||
obj:*
|
||||
...
|
||||
fun:dl_*
|
||||
@@ -94,4 +127,3 @@
|
||||
obj:*
|
||||
obj:*
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user