#include #include #include #include namespace mlx { GraphicsSupport::GraphicsSupport(const mlx_window_create_info* info, int id) : m_put_pixel_manager(&m_renderer), m_id(id) { MLX_PROFILE_FUNCTION(); if(info->render_target == nullptr) { p_window = std::make_shared(info); m_has_window = true; } else m_has_window = false; if(info->render_target != nullptr) { m_renderer.Init(info->render_target->texture); m_scene_renderer.Init(info->render_target->texture); } else { m_renderer.Init(p_window.get()); m_scene_renderer.Init(nullptr); } p_scene = std::make_unique(); } void GraphicsSupport::Render() noexcept { MLX_PROFILE_FUNCTION(); m_renderer.BeginFrame(); m_draw_layer = 0; m_scene_renderer.Render(*p_scene, m_renderer); m_renderer.EndFrame(); #ifdef GRAPHICS_MEMORY_DUMP // Dump memory usage to file every two seconds using namespace std::chrono_literals; static std::int64_t timer = static_cast(std::chrono::duration_cast(std::chrono::high_resolution_clock::now().time_since_epoch()).count()); if(std::chrono::duration{ static_cast(std::chrono::duration_cast(std::chrono::high_resolution_clock::now().time_since_epoch()).count()) - timer } >= 1s) { RenderCore::Get().GetAllocator().DumpMemoryToJson(); timer = static_cast(std::chrono::duration_cast(std::chrono::high_resolution_clock::now().time_since_epoch()).count()); } #endif } void GraphicsSupport::ResetRenderData(mlx_color color) noexcept { MLX_PROFILE_FUNCTION(); Vec4f vec_color = { static_cast(color.r) / 255.0f, static_cast(color.g) / 255.0f, static_cast(color.b) / 255.0f, static_cast(color.a) / 255.0f }; p_scene->ResetScene(std::move(vec_color)); m_put_pixel_manager.ResetRenderData(); m_draw_layer = 0; m_pixelput_called = false; } void GraphicsSupport::PixelPut(int x, int y, mlx_color color) noexcept { MLX_PROFILE_FUNCTION(); NonOwningPtr texture = m_put_pixel_manager.DrawPixel(x, y, m_draw_layer, color); if(texture) { m_pixelput_called = true; Sprite& new_sprite = p_scene->CreateSprite(texture); new_sprite.SetPosition(Vec2f{ 0.0f, 0.0f }); } } void GraphicsSupport::PixelPutArray(int x, int y, mlx_color* pixels, std::size_t pixels_size) noexcept { MLX_PROFILE_FUNCTION(); NonOwningPtr texture = m_put_pixel_manager.DrawPixelsArray(x, y, m_draw_layer, pixels, pixels_size); if(texture) { m_pixelput_called = true; Sprite& new_sprite = p_scene->CreateSprite(texture); new_sprite.SetPosition(Vec2f{ 0.0f, 0.0f }); } } void GraphicsSupport::PixelPutRegion(int x, int y, int w, int h, mlx_color* pixels) noexcept { MLX_PROFILE_FUNCTION(); NonOwningPtr texture = m_put_pixel_manager.DrawPixelsRegion(x, y, w, h, m_draw_layer, pixels); if(texture) { m_pixelput_called = true; Sprite& new_sprite = p_scene->CreateSprite(texture); new_sprite.SetPosition(Vec2f{ 0.0f, 0.0f }); } } void GraphicsSupport::StringPut(int x, int y, mlx_color color, std::string str) { MLX_PROFILE_FUNCTION(); if(str.empty()) return; Vec4f vec_color = { static_cast(color.r) / 255.0f, static_cast(color.g) / 255.0f, static_cast(color.b) / 255.0f, static_cast(color.a) / 255.0f, }; NonOwningPtr text = p_scene->GetTextFromPositionAndColor(str, Vec2f{ static_cast(x), static_cast(y) }, vec_color); if(!text) { if(m_pixelput_called) { m_draw_layer++; m_pixelput_called = false; } Text& new_text = p_scene->CreateText(str); new_text.SetPosition(Vec2f{ static_cast(x), static_cast(y) }); new_text.SetColor(std::move(vec_color)); } else if(!p_scene->IsTextAtGivenDrawLayer(str, m_draw_layer)) p_scene->BringToDrawLayer(text.Get(), m_draw_layer); } void GraphicsSupport::TexturePut(NonOwningPtr texture, int x, int y, float scale_x, float scale_y, float angle) { MLX_PROFILE_FUNCTION(); NonOwningPtr sprite = p_scene->GetSpriteFromTexturePositionScaleRotation(texture, Vec2f{ static_cast(x), static_cast(y) }, scale_x, scale_y, angle); if(!sprite) { if(m_pixelput_called) { m_draw_layer++; m_pixelput_called = false; } Sprite& new_sprite = p_scene->CreateSprite(texture); new_sprite.SetCenter(Vec2f{ texture->GetWidth() / 2.0f, texture->GetHeight() / 2.0f }); new_sprite.SetPosition(Vec2f{ static_cast(x), static_cast(y) }); new_sprite.SetScale(Vec2f{ scale_x, scale_y }); new_sprite.SetRotation(angle); } else if(!p_scene->IsTextureAtGivenDrawLayer(texture, m_draw_layer)) p_scene->BringToDrawLayer(sprite.Get(), m_draw_layer); } GraphicsSupport::~GraphicsSupport() { MLX_PROFILE_FUNCTION(); RenderCore::Get().WaitDeviceIdle(); p_scene.reset(); m_scene_renderer.Destroy(); m_renderer.Destroy(); if(p_window) p_window->Destroy(); } }