mirror of
https://github.com/seekrs/MacroLibX.git
synced 2026-01-11 22:53:34 +00:00
fixing compilation issues, working on textures
This commit is contained in:
@@ -14,7 +14,7 @@ namespace mlx
|
||||
{
|
||||
}, "__Application" });
|
||||
|
||||
m_fps.init();
|
||||
m_fps.Init();
|
||||
SDLManager::Get().Init();
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ namespace mlx
|
||||
{
|
||||
if(!m_fps.Update())
|
||||
continue;
|
||||
m_in.Update();
|
||||
|
||||
if(f_loop_hook)
|
||||
f_loop_hook(p_param);
|
||||
@@ -37,27 +36,15 @@ namespace mlx
|
||||
gs->Render();
|
||||
}
|
||||
}
|
||||
|
||||
RenderCore::Get().GetSingleTimeCmdManager().UpdateSingleTimesCmdBuffersSubmitState();
|
||||
|
||||
for(auto& gs : m_graphics)
|
||||
{
|
||||
if(!gs)
|
||||
continue;
|
||||
for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
|
||||
gs->GetRenderer().GetCmdBuffer(i).WaitForExecution();
|
||||
}
|
||||
RenderCore::Get().WaitDeviceIdle();
|
||||
}
|
||||
|
||||
void* Application::NewTexture(int w, int h)
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
Texture* texture = new Texture;
|
||||
#ifdef DEBUG
|
||||
texture->Create(nullptr, w, h, VK_FORMAT_R8G8B8A8_UNORM, "__mlx_unamed_user_texture");
|
||||
#else
|
||||
texture->Create(nullptr, w, h, VK_FORMAT_R8G8B8A8_UNORM, nullptr);
|
||||
#endif
|
||||
Texture* texture;
|
||||
try { texture = new Texture({}, w, h); }
|
||||
catch(...) { return NULL; }
|
||||
m_image_registry.RegisterTexture(texture);
|
||||
return texture;
|
||||
}
|
||||
@@ -66,6 +53,8 @@ namespace mlx
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
Texture* texture = StbTextureLoad(file, w, h);
|
||||
if(texture == nullptr)
|
||||
return NULL; // NULL for C compatibility
|
||||
m_image_registry.RegisterTexture(texture);
|
||||
return texture;
|
||||
}
|
||||
@@ -74,7 +63,7 @@ namespace mlx
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
RenderCore::Get().WaitDeviceIdle(); // TODO : synchronize with another method than waiting for GPU to be idle
|
||||
if(!m_image_registry.Find(ptr))
|
||||
if(!m_image_registry.IsTextureKnown(static_cast<Texture*>(ptr)))
|
||||
{
|
||||
Error("invalid image ptr");
|
||||
return;
|
||||
@@ -85,10 +74,10 @@ namespace mlx
|
||||
Error("trying to destroy a texture that has already been destroyed");
|
||||
else
|
||||
texture->Destroy();
|
||||
for(auto& gs : _graphics)
|
||||
for(auto& gs : m_graphics)
|
||||
{
|
||||
if(gs)
|
||||
gs->TryEraseTextureFromManager(texture);
|
||||
gs->TryEraseSpritesInScene(texture);
|
||||
}
|
||||
m_image_registry.UnregisterTexture(texture);
|
||||
delete texture;
|
||||
@@ -96,8 +85,6 @@ namespace mlx
|
||||
|
||||
Application::~Application()
|
||||
{
|
||||
TextLibrary::Get().ClearLibrary();
|
||||
FontLibrary::Get().ClearLibrary();
|
||||
SDLManager::Get().Shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <PreCompiled.h>
|
||||
|
||||
#include <Core/Application.h>
|
||||
#include <Renderer/Core/RenderCore.h>
|
||||
#include <Renderer/RenderCore.h>
|
||||
#include <mlx.h>
|
||||
#include <Core/Memory.h>
|
||||
|
||||
@@ -18,7 +18,7 @@ extern "C"
|
||||
{
|
||||
if(__mlx_ptr != nullptr)
|
||||
{
|
||||
Error("MLX cannot be initialized multiple times");
|
||||
mlx::Error("MLX cannot be initialized multiple times");
|
||||
return nullptr;
|
||||
}
|
||||
mlx::MemManager::Get(); // just to initialize the C garbage collector
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace mlx
|
||||
RenderCore::Get().WaitDeviceIdle();
|
||||
p_scene.reset();
|
||||
m_scene_renderer.Destroy();
|
||||
m_renderer->Destroy();
|
||||
m_renderer.Destroy();
|
||||
if(p_window)
|
||||
p_window->Destroy();
|
||||
}
|
||||
|
||||
@@ -12,10 +12,31 @@ namespace mlx
|
||||
m_depth.Init(m_descriptor.renderer->GetSwapchainImages().back().GetWidth(), m_descriptor.renderer->GetSwapchainImages().back().GetHeight());
|
||||
}
|
||||
|
||||
Sprite& Scene::CreateSprite(std::shared_ptr<Texture> texture) noexcept
|
||||
Sprite& Scene::CreateSprite(NonOwningPtr<Texture> texture) noexcept
|
||||
{
|
||||
std::shared_ptr<Sprite> sprite = std::make_shared<Sprite>(texture);
|
||||
m_sprites.push_back(sprite);
|
||||
return *sprite;
|
||||
}
|
||||
|
||||
NonOwningPtr<Sprite> Scene::GetSpriteFromTextureAndPosition(NonOwningPtr<Texture> texture, const Vec2f& position) const
|
||||
{
|
||||
auto it = std::find_if(m_sprites.begin(), m_sprites.end(), [texture, position](const Sprite& sprite)
|
||||
{
|
||||
return sprite.GetPosition().x == position.x && sprite.GetPosition().y == position.y && sprite.GetTexture() == texture;
|
||||
});
|
||||
return (it != m_sprites.end() ? &(*it) : nullptr);
|
||||
}
|
||||
|
||||
void Scene::TryEraseSpriteFromTexture(NonOwningPtr<Texture> texture)
|
||||
{
|
||||
do
|
||||
{
|
||||
auto it = std::find_if(m_sprites.begin(), m_sprites.end(), [texture, position](const Sprite& sprite)
|
||||
{
|
||||
return sprite.GetPosition().x == position.x && sprite.GetPosition().y == position.y && sprite.GetTexture() == texture;
|
||||
});
|
||||
m_sprites.erase(it);
|
||||
} while(it != m_sprites.end());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace mlx
|
||||
return mesh;
|
||||
}
|
||||
|
||||
Sprite::Sprite(std::shared_ptr<Texture> texture)
|
||||
Sprite::Sprite(NonOwningPtr<Texture> texture)
|
||||
{
|
||||
Verify((bool)texture, "Sprite: invalid texture");
|
||||
p_mesh = CreateQuad(0, 0, texture->GetWidth(), texture->GetHeight());
|
||||
|
||||
@@ -4,22 +4,4 @@
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
void Input::update()
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
_xRel = 0;
|
||||
_yRel = 0;
|
||||
|
||||
glfwPollEvents();
|
||||
|
||||
static int i = 0;
|
||||
i++;
|
||||
if(i >= 500)
|
||||
{
|
||||
auto& hooks = _events_hooks[0];
|
||||
auto& win_hook = hooks[MLX_WINDOW_EVENT];
|
||||
if(win_hook.hook)
|
||||
win_hook.hook(0, win_hook.param);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,10 @@ namespace mlx
|
||||
return;
|
||||
bool is_single_time_cmd_buffer = (cmd == VK_NULL_HANDLE);
|
||||
if(is_single_time_cmd_buffer)
|
||||
{
|
||||
cmd = kvfCreateCommandBuffer(RenderCore::Get().GetDevice());
|
||||
kvfBeginCommandBuffer(cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
|
||||
}
|
||||
KvfImageType kvf_type = KVF_IMAGE_OTHER;
|
||||
switch(m_type)
|
||||
{
|
||||
@@ -61,6 +64,13 @@ namespace mlx
|
||||
}
|
||||
kvfTransitionImageLayout(RenderCore::Get().GetDevice(), m_image, kvf_type, cmd, m_format, m_layout, new_layout, is_single_time_cmd_buffer);
|
||||
m_layout = new_layout;
|
||||
if(is_single_time_cmd_buffer)
|
||||
{
|
||||
vkEndCommandBuffer(cmd);
|
||||
VkFence fence = kvfCreateFence(RenderCore::Get().GetDevice());
|
||||
kvfSubmitSingleTimeCommandBuffer(RenderCore::Get().GetDevice(), cmd, KVF_GRAPHICS_QUEUE, fence);
|
||||
kvfDestroyFence(RenderCore::Get().GetDevice(), fence);
|
||||
}
|
||||
}
|
||||
|
||||
void Image::Clear(VkCommandBuffer cmd, Vec4f color)
|
||||
@@ -112,4 +122,105 @@ namespace mlx
|
||||
RenderCore::Get().GetAllocator().DestroyImage(m_allocation, m_image);
|
||||
m_image = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
void Texture::SetPixel(int x, int y, std::uint32_t color) noexcept
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
if(x < 0 || y < 0 || static_cast<std::uint32_t>(x) > m_width || static_cast<std::uint32_t>(y) > m_height)
|
||||
return;
|
||||
if(!m_staging_buffer.has_value())
|
||||
OpenCPUBuffer();
|
||||
m_cpu_buffer[(y * m_width) + x] = color;
|
||||
m_has_been_modified = true;
|
||||
}
|
||||
|
||||
int GetPixel(int x, int y) noexcept
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
if(x < 0 || y < 0 || static_cast<std::uint32_t>(x) > getWidth() || static_cast<std::uint32_t>(y) > getHeight())
|
||||
return 0;
|
||||
if(!m_staging_buffer.has_value())
|
||||
OpenCPUBuffer();
|
||||
std::uint32_t color = m_cpu_buffer[(y * m_width) + x];
|
||||
std::uint8_t* bytes = reinterpret_cast<std::uint8_t*>(&color);
|
||||
std::uint8_t tmp = bytes[0];
|
||||
bytes[0] = bytes[2];
|
||||
bytes[2] = tmp;
|
||||
return *reinterpret_cast<int*>(bytes);
|
||||
}
|
||||
|
||||
void Update(VkCommandBuffer cmd) const
|
||||
{
|
||||
if(!m_has_been_modified)
|
||||
return;
|
||||
std::memcpy(m_staging_buffer.GetMap(), m_cpu_buffer.data(), m_cpu_buffer.size() * kvfGetFormatSize(m_format));
|
||||
|
||||
VkImageLayout old_layout = m_layout;
|
||||
VkCommandBuffer cmd = kvfCreateCommandBuffer(RenderCore::Get().GetDevice());
|
||||
kvfBeginCommandBuffer(cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
|
||||
TransitionLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, cmd);
|
||||
kvfCopyBufferToImage(cmd, Image::Get(), staging_buffer.Get(), staging_buffer.GetOffset(), VK_IMAGE_ASPECT_COLOR_BIT, { width, height, 1 });
|
||||
TransitionLayout(old_layout, cmd);
|
||||
vkEndCommandBuffer(cmd);
|
||||
VkFence fence = kvfCreateFence(RenderCore::Get().GetDevice());
|
||||
kvfSubmitSingleTimeCommandBuffer(RenderCore::Get().GetDevice(), cmd, KVF_GRAPHICS_QUEUE, fence);
|
||||
kvfDestroyFence(RenderCore::Get().GetDevice(), fence);
|
||||
|
||||
m_has_been_modified = false;
|
||||
}
|
||||
|
||||
void Texture::OpenCPUBuffer()
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
if(m_staging_buffer.has_value())
|
||||
return;
|
||||
DebugLog("Texture : enabling CPU mapping");
|
||||
m_staging_buffer.emplace();
|
||||
std::size_t size = m_width * m_height * kvfGetFormatSize(m_format);
|
||||
m_staging_buffer->Init(BufferType::Staging, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, {});
|
||||
|
||||
VkImageLayout old_layout = m_layout;
|
||||
VkCommandBuffer cmd = kvfCreateCommandBuffer(RenderCore::Get().GetDevice());
|
||||
kvfBeginCommandBuffer(cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
|
||||
TransitionLayout(VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, cmd);
|
||||
kvfImageToBuffer(cmd, m_image, m_staging_buffer.Get(), m_staging_buffer.GetOffset(), VK_IMAGE_ASPECT_COLOR_BIT, { m_width, m_height, 1 });
|
||||
TransitionLayout(old_layout, cmd);
|
||||
vkEndCommandBuffer(cmd);
|
||||
VkFence fence = kvfCreateFence(RenderCore::Get().GetDevice());
|
||||
kvfSubmitSingleTimeCommandBuffer(RenderCore::Get().GetDevice(), cmd, KVF_GRAPHICS_QUEUE, fence);
|
||||
kvfDestroyFence(RenderCore::Get().GetDevice(), fence);
|
||||
|
||||
m_cpu_buffer.resize(m_width * m_height);
|
||||
std::memcpy(m_cpu_buffer.data(), m_staging_buffer.GetMap(), m_cpu_buffer.size());
|
||||
}
|
||||
|
||||
Texture* StbTextureLoad(const std::filesystem::path& file, int* w, int* h)
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
std::string filename = file.string();
|
||||
|
||||
if(!std::filesystem::exists(file))
|
||||
{
|
||||
Error("Image : file not found %", file);
|
||||
return nullptr;
|
||||
}
|
||||
if(stbi_is_hdr(filename.c_str()))
|
||||
{
|
||||
Error("Texture : unsupported image format %", file);
|
||||
return nullptr;
|
||||
}
|
||||
int dummy_w;
|
||||
int dummy_h;
|
||||
int channels;
|
||||
std::uint8_t* data = stbi_load(filename.c_str(), (w == nullptr ? &dummy_w : w), (h == nullptr ? &dummy_h : h), &channels, 4);
|
||||
CPUBuffer buffer((w == nullptr ? dummy_w : *w) * (h == nullptr ? dummy_h : *h) * 4);
|
||||
std::memcpy(buffer.GetData(), data, buffer.GetSize());
|
||||
Texture* texture;
|
||||
|
||||
try { texture = new Texture(buffer, (w == nullptr ? dummy_w : *w), (h == nullptr ? dummy_h : *h)); }
|
||||
catch(...) { return NULL; }
|
||||
|
||||
stbi_image_free(data);
|
||||
return texture;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,6 +102,8 @@ namespace mlx
|
||||
sprite_data.color = sprite->GetColor();
|
||||
if(!sprite->IsSetInit())
|
||||
sprite->UpdateDescriptorSet(*p_texture_set);
|
||||
Verify((bool)sprite->GetTexture(), "a sprite has no texture attached");
|
||||
sprite->GetTexture()->Update(cmd);
|
||||
sprite->Bind(frame_index, cmd);
|
||||
std::array<VkDescriptorSet, 2> sets = { p_viewer_data_set->GetSet(frame_index), sprite->GetSet(frame_index) };
|
||||
vkCmdBindDescriptorSets(cmd, m_pipeline.GetPipelineBindPoint(), m_pipeline.GetPipelineLayout(), 0, sets.size(), sets.data(), 0, nullptr);
|
||||
|
||||
Reference in New Issue
Block a user