diff --git a/CMakeLists.txt b/CMakeLists.txt index 1ff6374..0097c1c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -152,7 +152,7 @@ if(BUILD_SDL3_APP) src/services/impl/scene_service.cpp src/services/impl/graphics_service.cpp src/app/service_based_app.cpp - src/gui/gui_renderer.cpp + src/services/impl/gui_renderer.cpp ) target_include_directories(sdl3_app PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src") target_link_libraries(sdl3_app PRIVATE ${SDL_TARGET} Vulkan::Vulkan lua::lua CLI11::CLI11 rapidjson assimp::assimp Bullet::Bullet glm::glm Vorbis::vorbisfile Vorbis::vorbis) diff --git a/src/gui/gui_renderer.cpp b/src/services/impl/gui_renderer.cpp similarity index 92% rename from src/gui/gui_renderer.cpp rename to src/services/impl/gui_renderer.cpp index cc16263..ff6dd67 100644 --- a/src/gui/gui_renderer.cpp +++ b/src/services/impl/gui_renderer.cpp @@ -1,4 +1,4 @@ -#include "gui/gui_renderer.hpp" +#include "gui_renderer.hpp" #include #include @@ -14,14 +14,9 @@ #include "../../third_party/font8x8_basic.h" -namespace services = sdl3cpp::services; - -namespace sdl3cpp::gui { +namespace sdl3cpp::services::impl { namespace { -using ParsedSvg = sdl3cpp::gui::ParsedSvg; -using SvgCircle = sdl3cpp::gui::SvgCircle; - bool ExtractAttribute(const std::string& source, const char* name, std::string& outValue) { std::string key = name; size_t pos = source.find(key); @@ -61,7 +56,7 @@ float ParseFloatValue(const std::string& text) { } } -services::GuiColor ParseColorString(const std::string& text, const services::GuiColor& fallback) { +GuiColor ParseColorString(const std::string& text, const GuiColor& fallback) { if (text.empty() || text[0] != '#') { return fallback; } @@ -141,9 +136,9 @@ ParsedSvg ParseSvgFile(const std::filesystem::path& path) { return result; } -services::GuiCommand::RectData IntersectRect(const services::GuiCommand::RectData& a, - const services::GuiCommand::RectData& b) { - services::GuiCommand::RectData result; +GuiCommand::RectData IntersectRect(const GuiCommand::RectData& a, + const GuiCommand::RectData& b) { + GuiCommand::RectData result; result.x = std::max(a.x, b.x); result.y = std::max(a.y, b.y); float right = std::min(a.x + a.width, b.x + b.width); @@ -161,7 +156,7 @@ int ClampToRange(int value, int minimum, int maximum) { class GuiRenderer::Canvas { public: - using RectData = services::GuiCommand::RectData; + using RectData = GuiCommand::RectData; void Resize(uint32_t width, uint32_t height) { width_ = width; @@ -187,8 +182,8 @@ public: } } - void FillRect(const RectData& rect, const services::GuiColor& fillColor, - const services::GuiColor& borderColor, float borderWidth) { + void FillRect(const RectData& rect, const GuiColor& fillColor, + const GuiColor& borderColor, float borderWidth) { DrawFilledRect(rect, fillColor); if (borderWidth > 0.0f && borderColor.a > 0.0f) { DrawFilledRect({rect.x, rect.y, rect.width, borderWidth}, borderColor); @@ -199,7 +194,7 @@ public: } } - void DrawText(const std::string& text, const services::GuiColor& color, const RectData& bounds, + void DrawText(const std::string& text, const GuiColor& color, const RectData& bounds, const std::string& alignX, const std::string& alignY, float fontSize) { if (text.empty() || width_ == 0 || height_ == 0) { return; @@ -244,7 +239,7 @@ public: } } - void DrawSvg(const ParsedSvg& svg, const RectData& target, const services::GuiColor& tint) { + void DrawSvg(const ParsedSvg& svg, const RectData& target, const GuiColor& tint) { if (svg.circles.empty() || svg.viewWidth <= 0.0f || svg.viewHeight <= 0.0f || width_ == 0 || height_ == 0) { return; @@ -260,7 +255,7 @@ public: float cx = clipped.x + circle.cx * scaleX; float cy = clipped.y + circle.cy * scaleY; float radius = circle.r * scale; - services::GuiColor color = circle.color; + GuiColor color = circle.color; if (tint.a > 0.0f) { color.r *= tint.r; color.g *= tint.g; @@ -300,7 +295,7 @@ private: return clipped; } - void DrawFilledRect(const RectData& rect, const services::GuiColor& color) { + void DrawFilledRect(const RectData& rect, const GuiColor& color) { if (rect.width <= 0.0f || rect.height <= 0.0f) { return; } @@ -319,7 +314,7 @@ private: } } - void BlendPixel(int x, int y, const services::GuiColor& color) { + void BlendPixel(int x, int y, const GuiColor& color) { size_t index = (static_cast(y) * width_ + static_cast(x)) * 4; auto clampByte = [](float value) -> uint8_t { return static_cast(std::clamp(value, 0.0f, 1.0f) * 255.0f); @@ -348,7 +343,7 @@ private: GuiRenderer::GuiRenderer(VkDevice device, VkPhysicalDevice physicalDevice, VkFormat swapchainFormat, const std::filesystem::path& scriptDirectory, - std::shared_ptr bufferService) + std::shared_ptr bufferService) : device_(device), physicalDevice_(physicalDevice), swapchainFormat_(swapchainFormat), @@ -365,7 +360,7 @@ GuiRenderer::GuiRenderer(VkDevice device, VkPhysicalDevice physicalDevice, VkFor return canvasWidth_ > 0 && canvasHeight_ > 0 && stagingBuffer_ != VK_NULL_HANDLE; } - void GuiRenderer::Prepare(const std::vector& commands, uint32_t width, + void GuiRenderer::Prepare(const std::vector& commands, uint32_t width, uint32_t height) { if (width == 0 || height == 0 || !canvas_) { return; @@ -374,10 +369,10 @@ GuiRenderer::GuiRenderer(VkDevice device, VkPhysicalDevice physicalDevice, VkFor canvas_->Clear(); for (const auto& command : commands) { switch (command.type) { - case services::GuiCommand::Type::Rect: + case GuiCommand::Type::Rect: canvas_->FillRect(command.rect, command.color, command.borderColor, command.borderWidth); break; - case services::GuiCommand::Type::Text: { + case GuiCommand::Type::Text: { if (command.hasClipRect) { canvas_->PushClip(command.clipRect); } @@ -385,7 +380,7 @@ GuiRenderer::GuiRenderer(VkDevice device, VkPhysicalDevice physicalDevice, VkFor canvas_->DrawText(command.text, command.color, command.bounds, command.alignX, command.alignY, command.fontSize); } else { - services::GuiCommand::RectData fallback{ + GuiCommand::RectData fallback{ command.rect.x, command.rect.y, command.fontSize * static_cast(std::max(1, command.text.size())), command.fontSize}; canvas_->DrawText(command.text, command.color, fallback, command.alignX, @@ -396,13 +391,13 @@ GuiRenderer::GuiRenderer(VkDevice device, VkPhysicalDevice physicalDevice, VkFor } break; } - case services::GuiCommand::Type::ClipPush: + case GuiCommand::Type::ClipPush: canvas_->PushClip(command.rect); break; - case services::GuiCommand::Type::ClipPop: + case GuiCommand::Type::ClipPop: canvas_->PopClip(); break; - case services::GuiCommand::Type::Svg: + case GuiCommand::Type::Svg: if (command.svgPath.empty()) { break; } @@ -569,4 +564,4 @@ GuiRenderer::GuiRenderer(VkDevice device, VkPhysicalDevice physicalDevice, VkFor } } -} // namespace sdl3cpp::gui +} // namespace sdl3cpp::services::impl diff --git a/src/gui/gui_renderer.hpp b/src/services/impl/gui_renderer.hpp similarity index 79% rename from src/gui/gui_renderer.hpp rename to src/services/impl/gui_renderer.hpp index e4e88b5..bf836c7 100644 --- a/src/gui/gui_renderer.hpp +++ b/src/services/impl/gui_renderer.hpp @@ -1,5 +1,5 @@ -#ifndef SDL3CPP_GUI_GUI_RENDERER_HPP -#define SDL3CPP_GUI_GUI_RENDERER_HPP +#ifndef SDL3CPP_SERVICES_GUI_RENDERER_HPP +#define SDL3CPP_SERVICES_GUI_RENDERER_HPP #include #include @@ -11,13 +11,13 @@ #include "services/interfaces/gui_types.hpp" #include "services/interfaces/i_buffer_service.hpp" -namespace sdl3cpp::gui { +namespace sdl3cpp::services::impl { struct SvgCircle { float cx = 0.0f; float cy = 0.0f; float r = 0.0f; - services::GuiColor color{1.0f, 1.0f, 1.0f, 1.0f}; + GuiColor color{1.0f, 1.0f, 1.0f, 1.0f}; }; struct ParsedSvg { @@ -30,13 +30,13 @@ class GuiRenderer { public: GuiRenderer(VkDevice device, VkPhysicalDevice physicalDevice, VkFormat swapchainFormat, const std::filesystem::path& scriptDirectory, - std::shared_ptr bufferService); + std::shared_ptr bufferService); ~GuiRenderer(); GuiRenderer(const GuiRenderer&) = delete; GuiRenderer& operator=(const GuiRenderer&) = delete; - void Prepare(const std::vector& commands, uint32_t width, + void Prepare(const std::vector& commands, uint32_t width, uint32_t height); void BlitToSwapchain(VkCommandBuffer commandBuffer, VkImage image); void Resize(uint32_t width, uint32_t height, VkFormat format); @@ -65,9 +65,9 @@ private: uint32_t canvasHeight_ = 0; std::unique_ptr canvas_; std::unordered_map svgCache_; - std::shared_ptr bufferService_; + std::shared_ptr bufferService_; }; -} // namespace sdl3cpp::gui +} // namespace sdl3cpp::services::impl -#endif // SDL3CPP_GUI_GUI_RENDERER_HPP +#endif // SDL3CPP_SERVICES_GUI_RENDERER_HPP diff --git a/src/services/impl/gui_renderer_service.cpp b/src/services/impl/gui_renderer_service.cpp index 045daab..ec9589f 100644 --- a/src/services/impl/gui_renderer_service.cpp +++ b/src/services/impl/gui_renderer_service.cpp @@ -18,7 +18,7 @@ void GuiRendererService::Initialize(VkDevice device, if (logger_) { logger_->TraceFunction(__func__); } - renderer_ = std::make_unique( + renderer_ = std::make_unique( device, physicalDevice, format, resourcePath, bufferService_); } diff --git a/src/services/impl/gui_renderer_service.hpp b/src/services/impl/gui_renderer_service.hpp index 420f34e..cd39492 100644 --- a/src/services/impl/gui_renderer_service.hpp +++ b/src/services/impl/gui_renderer_service.hpp @@ -4,7 +4,7 @@ #include "../interfaces/i_gui_renderer_service.hpp" #include "../interfaces/i_logger.hpp" #include "../../di/lifecycle.hpp" -#include "../../gui/gui_renderer.hpp" +#include "gui_renderer.hpp" #include namespace sdl3cpp::services::impl { @@ -35,7 +35,7 @@ public: private: std::shared_ptr logger_; std::shared_ptr bufferService_; - std::unique_ptr renderer_; + std::unique_ptr renderer_; }; } // namespace sdl3cpp::services::impl diff --git a/src/services/impl/vulkan_gui_service.hpp b/src/services/impl/vulkan_gui_service.hpp index c2d87ed..2b53150 100644 --- a/src/services/impl/vulkan_gui_service.hpp +++ b/src/services/impl/vulkan_gui_service.hpp @@ -11,7 +11,7 @@ namespace sdl3cpp::services::impl { /** * @brief Vulkan GUI service implementation. * - * Small wrapper service (~60 lines) around GuiRenderer. + * Small wrapper service (~60 lines) around the GUI renderer service. * Provides 2D GUI overlay rendering for SVG, text, and shapes. */ class VulkanGuiService : public IGuiService, diff --git a/src/services/interfaces/i_gui_service.hpp b/src/services/interfaces/i_gui_service.hpp index ba5b111..e46e99d 100644 --- a/src/services/interfaces/i_gui_service.hpp +++ b/src/services/interfaces/i_gui_service.hpp @@ -14,7 +14,7 @@ struct GuiCommand; * @brief GUI rendering service interface. * * Handles 2D GUI overlay rendering using Vulkan. - * Wraps the GuiRenderer class with support for SVG, text, and shapes. + * Delegates low-level draw work to the GUI renderer service. */ class IGuiService { public: