From b892736fb2cf6dd35c80caf965e9f7fa743f9729 Mon Sep 17 00:00:00 2001 From: ChestnutYueyue <952134128@qq.com> Date: Fri, 20 Feb 2026 12:48:36 +0800 Subject: [PATCH] =?UTF-8?q?refactor(render):=20=E7=A7=BB=E9=99=A4=E5=A4=9A?= =?UTF-8?q?=E5=90=8E=E7=AB=AF=E6=94=AF=E6=8C=81=EF=BC=8C=E4=BB=85=E4=BF=9D?= =?UTF-8?q?=E7=95=99GLFW=E5=92=8COpenGL?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 简化渲染模块和窗口模块,移除SDL2和Vulkan后端支持,仅保留GLFW窗口后端和OpenGL渲染后端。删除相关后端工厂代码和配置文件,修改模块初始化逻辑直接使用GLFW和OpenGL实现。 - 删除SDL2和Vulkan后端相关代码 - 移除后端工厂模式和相关注册逻辑 - 修改窗口模块直接使用GLFW实现 - 修改渲染模块直接使用OpenGL实现 - 更新构建配置仅支持GLFW+OpenGL组合 --- .../graphics/backends/backend_factory.h | 124 ---- .../graphics/backends/vulkan/vk_renderer.h | 78 --- .../extra2d/graphics/core/render_module.h | 6 +- .../extra2d/platform/backend_factory.h | 88 --- .../include/extra2d/platform/window_module.h | 10 +- .../src/graphics/backends/backend_factory.cpp | 141 ---- .../graphics/backends/opengl/gl_backend.cpp | 39 -- .../graphics/backends/vulkan/vk_backend.cpp | 39 -- .../graphics/backends/vulkan/vk_renderer.cpp | 150 ----- Extra2D/src/graphics/core/render_module.cpp | 35 +- .../{backends => }/opengl/gl_buffer.cpp | 0 .../{backends => }/opengl/gl_context.cpp | 0 .../{backends => }/opengl/gl_font_atlas.cpp | 0 .../{backends => }/opengl/gl_framebuffer.cpp | 0 .../{backends => }/opengl/gl_pipeline.cpp | 0 .../{backends => }/opengl/gl_renderer.cpp | 0 .../{backends => }/opengl/gl_shader.cpp | 0 .../{backends => }/opengl/gl_sprite_batch.cpp | 0 .../{backends => }/opengl/gl_texture.cpp | 0 Extra2D/src/platform/backend_factory.cpp | 46 -- .../platform/backends/glfw/glfw_backend.cpp | 30 - .../platform/backends/sdl2/sdl2_backend.cpp | 30 - .../src/platform/backends/sdl2/sdl2_input.cpp | 454 ------------- .../src/platform/backends/sdl2/sdl2_input.h | 104 --- .../platform/backends/sdl2/sdl2_window.cpp | 615 ------------------ .../src/platform/backends/sdl2/sdl2_window.h | 101 --- .../{backends => }/glfw/glfw_input.cpp | 0 .../platform/{backends => }/glfw/glfw_input.h | 0 .../{backends => }/glfw/glfw_window.cpp | 0 .../{backends => }/glfw/glfw_window.h | 0 Extra2D/src/platform/window_module.cpp | 30 +- xmake.lua | 125 +--- xmake/engine.lua | 81 +-- 33 files changed, 39 insertions(+), 2287 deletions(-) delete mode 100644 Extra2D/include/extra2d/graphics/backends/backend_factory.h delete mode 100644 Extra2D/include/extra2d/graphics/backends/vulkan/vk_renderer.h delete mode 100644 Extra2D/include/extra2d/platform/backend_factory.h delete mode 100644 Extra2D/src/graphics/backends/backend_factory.cpp delete mode 100644 Extra2D/src/graphics/backends/opengl/gl_backend.cpp delete mode 100644 Extra2D/src/graphics/backends/vulkan/vk_backend.cpp delete mode 100644 Extra2D/src/graphics/backends/vulkan/vk_renderer.cpp rename Extra2D/src/graphics/{backends => }/opengl/gl_buffer.cpp (100%) rename Extra2D/src/graphics/{backends => }/opengl/gl_context.cpp (100%) rename Extra2D/src/graphics/{backends => }/opengl/gl_font_atlas.cpp (100%) rename Extra2D/src/graphics/{backends => }/opengl/gl_framebuffer.cpp (100%) rename Extra2D/src/graphics/{backends => }/opengl/gl_pipeline.cpp (100%) rename Extra2D/src/graphics/{backends => }/opengl/gl_renderer.cpp (100%) rename Extra2D/src/graphics/{backends => }/opengl/gl_shader.cpp (100%) rename Extra2D/src/graphics/{backends => }/opengl/gl_sprite_batch.cpp (100%) rename Extra2D/src/graphics/{backends => }/opengl/gl_texture.cpp (100%) delete mode 100644 Extra2D/src/platform/backend_factory.cpp delete mode 100644 Extra2D/src/platform/backends/glfw/glfw_backend.cpp delete mode 100644 Extra2D/src/platform/backends/sdl2/sdl2_backend.cpp delete mode 100644 Extra2D/src/platform/backends/sdl2/sdl2_input.cpp delete mode 100644 Extra2D/src/platform/backends/sdl2/sdl2_input.h delete mode 100644 Extra2D/src/platform/backends/sdl2/sdl2_window.cpp delete mode 100644 Extra2D/src/platform/backends/sdl2/sdl2_window.h rename Extra2D/src/platform/{backends => }/glfw/glfw_input.cpp (100%) rename Extra2D/src/platform/{backends => }/glfw/glfw_input.h (100%) rename Extra2D/src/platform/{backends => }/glfw/glfw_window.cpp (100%) rename Extra2D/src/platform/{backends => }/glfw/glfw_window.h (100%) diff --git a/Extra2D/include/extra2d/graphics/backends/backend_factory.h b/Extra2D/include/extra2d/graphics/backends/backend_factory.h deleted file mode 100644 index 2b52214..0000000 --- a/Extra2D/include/extra2d/graphics/backends/backend_factory.h +++ /dev/null @@ -1,124 +0,0 @@ -#pragma once - -#include -#include - -#include -#include -#include -#include - -namespace extra2d { -namespace graphics { - -/** - * @brief 图形后端工厂 - * 用于注册和创建图形渲染后端 - */ -class BackendFactory { -public: - using BackendFn = std::function()>; - - /** - * @brief 注册图形后端 - * @param name 后端名称 - * @param backend 后端创建函数 - * @param windowBackends 支持的窗口后端名称列表 - */ - static void reg(const std::string &name, BackendFn backend, - const std::vector &windowBackends = {}); - - /** - * @brief 创建渲染后端实例 - * @param name 后端名称 - * @return 渲染后端实例,如果后端不存在返回 nullptr - */ - static UniquePtr createBackend(const std::string &name); - - /** - * @brief 创建默认渲染后端 - * @return 默认渲染后端实例 - */ - static UniquePtr createDefaultBackend(); - - /** - * @brief 创建与指定窗口后端兼容的渲染后端 - * @param windowBackend 窗口后端名称 - * @return 兼容的渲染后端实例 - */ - static UniquePtr - createBackendForWindow(const std::string &windowBackend); - - /** - * @brief 获取所有已注册的后端名称 - */ - static std::vector backends(); - - /** - * @brief 检查后端是否存在 - */ - static bool has(const std::string &name); - - /** - * @brief 获取推荐的后端名称 - * @return 推荐的后端名称 - */ - static std::string getRecommendedBackend(); - - /** - * @brief 获取与指定窗口后端兼容的推荐图形后端 - * @param windowBackend 窗口后端名称 - * @return 推荐的图形后端名称 - */ - static std::string - getRecommendedBackendForWindow(const std::string &windowBackend); - - /** - * @brief 检查图形后端是否支持指定窗口后端 - * @param graphicsBackend 图形后端名称 - * @param windowBackend 窗口后端名称 - * @return 支持返回 true - */ - static bool isCompatible(const std::string &graphicsBackend, - const std::string &windowBackend); - - /** - * @brief 获取图形后端支持的窗口后端列表 - * @param graphicsBackend 图形后端名称 - * @return 支持的窗口后端列表 - */ - static std::vector - getSupportedWindowBackends(const std::string &graphicsBackend); - -private: - struct BackendEntry { - BackendFn createFn; - std::vector windowBackends; - }; - - static std::unordered_map ®istry(); -}; - -/** - * @brief 图形后端注册宏 - * 在全局作用域使用此宏注册图形后端 - * - * @example - * E2D_REG_GRAPHICS_BACKEND(opengl, GLRenderer, {"sdl2", "glfw"}) - */ -#define E2D_REG_GRAPHICS_BACKEND(name, RendererClass, windowBackends) \ - namespace { \ - __attribute__((used)) static struct E2D_GRAPHICS_BACKEND_REG_##name { \ - E2D_GRAPHICS_BACKEND_REG_##name() { \ - ::extra2d::graphics::BackendFactory::reg( \ - #name, \ - []() -> ::extra2d::UniquePtr<::extra2d::RenderBackend> { \ - return ::extra2d::makeUnique(); \ - }, \ - windowBackends); \ - } \ - } e2d_graphics_backend_reg_##name; \ - } - -} // namespace graphics -} // namespace extra2d diff --git a/Extra2D/include/extra2d/graphics/backends/vulkan/vk_renderer.h b/Extra2D/include/extra2d/graphics/backends/vulkan/vk_renderer.h deleted file mode 100644 index 608dd8d..0000000 --- a/Extra2D/include/extra2d/graphics/backends/vulkan/vk_renderer.h +++ /dev/null @@ -1,78 +0,0 @@ -#pragma once - -#include - -namespace extra2d { - -/** - * @brief Vulkan 渲染器实现(占位) - * - * 这是一个占位实现,用于展示Vulkan后端应该包含的内容。 - * 完整的实现需要包含Vulkan上下文、设备、交换链、管线等。 - */ -class VulkanRenderer : public RenderBackend { -public: - VulkanRenderer(); - ~VulkanRenderer() override; - - // RenderBackend 接口实现 - bool init(IWindow* window) override; - void shutdown() override; - - void beginFrame(const Color &clearColor) override; - void endFrame() override; - void setViewport(int x, int y, int width, int height) override; - void setVSync(bool enabled) override; - - void setBlendMode(BlendMode mode) override; - void setViewProjection(const glm::mat4 &matrix) override; - - void pushTransform(const glm::mat4 &transform) override; - void popTransform() override; - glm::mat4 getCurrentTransform() const override; - - Ptr createTexture(int width, int height, const uint8_t *pixels, - int channels) override; - Ptr loadTexture(const std::string &filepath) override; - - void beginSpriteBatch() override; - void drawSprite(const Texture &texture, const Rect &destRect, - const Rect &srcRect, const Color &tint, float rotation, - const Vec2 &anchor) override; - void drawSprite(const Texture &texture, const Vec2 &position, - const Color &tint) override; - void endSpriteBatch() override; - - void drawLine(const Vec2 &start, const Vec2 &end, const Color &color, - float width) override; - void drawRect(const Rect &rect, const Color &color, float width) override; - void fillRect(const Rect &rect, const Color &color) override; - void drawCircle(const Vec2 ¢er, float radius, const Color &color, - int segments, float width) override; - void fillCircle(const Vec2 ¢er, float radius, const Color &color, - int segments) override; - void drawTriangle(const Vec2 &p1, const Vec2 &p2, const Vec2 &p3, - const Color &color, float width) override; - void fillTriangle(const Vec2 &p1, const Vec2 &p2, const Vec2 &p3, - const Color &color) override; - void drawPolygon(const std::vector &points, const Color &color, - float width) override; - void fillPolygon(const std::vector &points, - const Color &color) override; - - Ptr createFontAtlas(const std::string &filepath, int fontSize, - bool useSDF = false) override; - void drawText(const FontAtlas &font, const std::string &text, - const Vec2 &position, const Color &color) override; - void drawText(const FontAtlas &font, const std::string &text, float x, - float y, const Color &color) override; - - Stats getStats() const override { return stats_; } - void resetStats() override; - -private: - Stats stats_; - bool initialized_ = false; -}; - -} // namespace extra2d diff --git a/Extra2D/include/extra2d/graphics/core/render_module.h b/Extra2D/include/extra2d/graphics/core/render_module.h index 4f636a3..84cb08c 100644 --- a/Extra2D/include/extra2d/graphics/core/render_module.h +++ b/Extra2D/include/extra2d/graphics/core/render_module.h @@ -12,15 +12,13 @@ namespace extra2d { * @brief 渲染模块配置结构 */ struct RenderCfg { - std::string backend; int targetFPS; bool vsync; int multisamples; int priority; RenderCfg() - : backend("") - , targetFPS(60) + : targetFPS(60) , vsync(true) , multisamples(0) , priority(10) @@ -29,7 +27,7 @@ struct RenderCfg { /** * @brief 渲染模块 - * 管理渲染后端,自动根据窗口后端选择兼容的渲染器 + * 管理 OpenGL 渲染后端 */ class RenderModule : public Module { public: diff --git a/Extra2D/include/extra2d/platform/backend_factory.h b/Extra2D/include/extra2d/platform/backend_factory.h deleted file mode 100644 index eafe4aa..0000000 --- a/Extra2D/include/extra2d/platform/backend_factory.h +++ /dev/null @@ -1,88 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -namespace extra2d { -namespace platform { - -/** - * @brief 平台后端工厂 - * 用于注册和创建平台后端 - */ -class BackendFactory { -public: - using WindowFn = std::function()>; - using InputFn = std::function()>; - - /** - * @brief 注册平台后端 - * @param name 后端名称 - * @param win 窗口创建函数 - * @param in 输入创建函数 - */ - static void reg(const std::string &name, WindowFn win, InputFn in); - - /** - * @brief 创建窗口实例 - * @param name 后端名称 - * @return 窗口实例,如果后端不存在返回 nullptr - */ - static UniquePtr createWindow(const std::string &name); - - /** - * @brief 创建输入实例 - * @param name 后端名称 - * @return 输入实例,如果后端不存在返回 nullptr - */ - static UniquePtr createInput(const std::string &name); - - /** - * @brief 获取所有已注册的后端名称 - */ - static std::vector backends(); - - /** - * @brief 检查后端是否存在 - */ - static bool has(const std::string &name); - -private: - struct BackendEntry { - WindowFn windowFn; - InputFn inputFn; - }; - - static std::unordered_map ®istry(); -}; - -/** - * @brief 平台后端注册宏 - * 在全局作用域使用此宏注册平台后端 - * - * @example - * E2D_REG_BACKEND(sdl2, SDL2Window, SDL2Input) - */ -#define E2D_REG_BACKEND(name, WinClass, InClass) \ - namespace { \ - __attribute__((used)) static struct E2D_BACKEND_REG_##name { \ - E2D_BACKEND_REG_##name() { \ - ::extra2d::platform::BackendFactory::reg( \ - #name, \ - []() -> ::extra2d::UniquePtr<::extra2d::IWindow> { \ - return ::extra2d::makeUnique(); \ - }, \ - []() -> ::extra2d::UniquePtr<::extra2d::IInput> { \ - return ::extra2d::makeUnique(); \ - }); \ - } \ - } e2d_backend_reg_##name; \ - } - -} // namespace platform -} // namespace extra2d diff --git a/Extra2D/include/extra2d/platform/window_module.h b/Extra2D/include/extra2d/platform/window_module.h index 6aa058c..f4b7db3 100644 --- a/Extra2D/include/extra2d/platform/window_module.h +++ b/Extra2D/include/extra2d/platform/window_module.h @@ -16,11 +16,9 @@ struct WindowCfg { int h; bool vsync; int priority; - std::string backend; WindowCfg() - : title("Extra2D"), w(1280), h(720), vsync(true), priority(0), - backend("sdl2") {} + : title("Extra2D"), w(1280), h(720), vsync(true), priority(0) {} }; /** @@ -52,12 +50,6 @@ public: */ IWindow *win() const { return win_.get(); } - /** - * @brief 获取窗口后端名称 - * @return 窗口后端名称 - */ - const std::string &getWindowBackend() const { return cfg_.backend; } - private: WindowCfg cfg_; UniquePtr win_; diff --git a/Extra2D/src/graphics/backends/backend_factory.cpp b/Extra2D/src/graphics/backends/backend_factory.cpp deleted file mode 100644 index 1b22365..0000000 --- a/Extra2D/src/graphics/backends/backend_factory.cpp +++ /dev/null @@ -1,141 +0,0 @@ -#include -#include -#include - -namespace extra2d { -namespace graphics { - -std::unordered_map & -BackendFactory::registry() { - static std::unordered_map reg; - return reg; -} - -void BackendFactory::reg(const std::string &name, BackendFn backend, - const std::vector &windowBackends) { - registry()[name] = {backend, windowBackends}; - E2D_LOG_DEBUG("已注册图形后端: {} (窗口后端数量: {})", name, - windowBackends.size()); -} - -UniquePtr -BackendFactory::createBackend(const std::string &name) { - auto ® = registry(); - auto it = reg.find(name); - if (it != reg.end() && it->second.createFn) { - E2D_LOG_INFO("正在创建图形后端: {}", name); - return it->second.createFn(); - } - E2D_LOG_ERROR("未找到图形后端 '{}'", name); - return nullptr; -} - -UniquePtr BackendFactory::createDefaultBackend() { - std::string recommended = getRecommendedBackend(); - if (recommended.empty()) { - E2D_LOG_ERROR("无可用的图形后端"); - return nullptr; - } - return createBackend(recommended); -} - -UniquePtr -BackendFactory::createBackendForWindow(const std::string &windowBackend) { - std::string recommended = getRecommendedBackendForWindow(windowBackend); - if (recommended.empty()) { - E2D_LOG_ERROR("未找到与窗口后端 '{}' 兼容的图形后端", windowBackend); - return nullptr; - } - return createBackend(recommended); -} - -std::vector BackendFactory::backends() { - std::vector result; - for (const auto &pair : registry()) { - result.push_back(pair.first); - } - return result; -} - -bool BackendFactory::has(const std::string &name) { - return registry().find(name) != registry().end(); -} - -std::string BackendFactory::getRecommendedBackend() { - auto ® = registry(); - - static const std::vector priority = { - "vulkan", "opengl", "d3d12", "d3d11", "metal", "opengles"}; - - for (const auto &name : priority) { - if (reg.find(name) != reg.end()) { - return name; - } - } - - if (!reg.empty()) { - return reg.begin()->first; - } - - E2D_LOG_WARN("未注册任何图形后端"); - return ""; -} - -std::string BackendFactory::getRecommendedBackendForWindow( - const std::string &windowBackend) { - auto ® = registry(); - - static const std::vector priority = { - "vulkan", "opengl", "d3d12", "d3d11", "metal", "opengles"}; - - for (const auto &name : priority) { - auto it = reg.find(name); - if (it != reg.end() && isCompatible(name, windowBackend)) { - return name; - } - } - - for (const auto &pair : reg) { - if (isCompatible(pair.first, windowBackend)) { - return pair.first; - } - } - - E2D_LOG_WARN("未找到与窗口后端 '{}' 兼容的图形后端", windowBackend); - return ""; -} - -bool BackendFactory::isCompatible(const std::string &graphicsBackend, - const std::string &windowBackend) { - auto ® = registry(); - auto it = reg.find(graphicsBackend); - if (it == reg.end()) { - return false; - } - - const auto &windowBackends = it->second.windowBackends; - if (windowBackends.empty()) { - return true; - } - - for (const auto &wb : windowBackends) { - if (wb == windowBackend) { - return true; - } - } - - return false; -} - -std::vector -BackendFactory::getSupportedWindowBackends(const std::string &graphicsBackend) { - auto ® = registry(); - auto it = reg.find(graphicsBackend); - if (it != reg.end()) { - return it->second.windowBackends; - } - return {}; -} - -} // namespace graphics -} // namespace extra2d diff --git a/Extra2D/src/graphics/backends/opengl/gl_backend.cpp b/Extra2D/src/graphics/backends/opengl/gl_backend.cpp deleted file mode 100644 index d34b6e5..0000000 --- a/Extra2D/src/graphics/backends/opengl/gl_backend.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include -#include - -namespace extra2d { -namespace graphics { - -namespace { - static bool s_openglBackendRegistered = false; -} - -/** - * @brief 初始化 OpenGL 后端注册 - */ -void initOpenGLBackend() { - if (s_openglBackendRegistered) { - return; - } - s_openglBackendRegistered = true; - - BackendFactory::reg( - "opengl", - []() -> UniquePtr { - return makeUnique(); - }, - {"sdl2", "glfw"} - ); -} - -namespace { - struct OpenGLBackendAutoReg { - OpenGLBackendAutoReg() { - initOpenGLBackend(); - } - }; - static OpenGLBackendAutoReg s_openglAutoReg; -} - -} // namespace graphics -} // namespace extra2d diff --git a/Extra2D/src/graphics/backends/vulkan/vk_backend.cpp b/Extra2D/src/graphics/backends/vulkan/vk_backend.cpp deleted file mode 100644 index 095e234..0000000 --- a/Extra2D/src/graphics/backends/vulkan/vk_backend.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include -#include - -namespace extra2d { -namespace graphics { - -namespace { - static bool s_vulkanBackendRegistered = false; -} - -/** - * @brief 初始化 Vulkan 后端注册 - */ -void initVulkanBackend() { - if (s_vulkanBackendRegistered) { - return; - } - s_vulkanBackendRegistered = true; - - BackendFactory::reg( - "vulkan", - []() -> UniquePtr { - return makeUnique(); - }, - {"sdl2", "glfw"} - ); -} - -namespace { - struct VulkanBackendAutoReg { - VulkanBackendAutoReg() { - initVulkanBackend(); - } - }; - static VulkanBackendAutoReg s_vulkanAutoReg; -} - -} // namespace graphics -} // namespace extra2d diff --git a/Extra2D/src/graphics/backends/vulkan/vk_renderer.cpp b/Extra2D/src/graphics/backends/vulkan/vk_renderer.cpp deleted file mode 100644 index 8e7e200..0000000 --- a/Extra2D/src/graphics/backends/vulkan/vk_renderer.cpp +++ /dev/null @@ -1,150 +0,0 @@ -#include -#include -#include - - -namespace extra2d { - -VulkanRenderer::VulkanRenderer() = default; - -VulkanRenderer::~VulkanRenderer() { shutdown(); } - -bool VulkanRenderer::init(IWindow *window) { - E2D_LOG_WARN("Vulkan 渲染器尚未完全实现"); - initialized_ = true; - return true; -} - -void VulkanRenderer::shutdown() { initialized_ = false; } - -void VulkanRenderer::beginFrame(const Color &clearColor) { - // TODO: 实现Vulkan帧开始 -} - -void VulkanRenderer::endFrame() { - // TODO: 实现Vulkan帧结束 -} - -void VulkanRenderer::setViewport(int x, int y, int width, int height) { - // TODO: 实现视口设置 -} - -void VulkanRenderer::setVSync(bool enabled) { - // TODO: 实现垂直同步设置 -} - -void VulkanRenderer::setBlendMode(BlendMode mode) { - // TODO: 实现混合模式设置 -} - -void VulkanRenderer::setViewProjection(const glm::mat4 &matrix) { - // TODO: 实现视图投影矩阵设置 -} - -void VulkanRenderer::pushTransform(const glm::mat4 &transform) { - // TODO: 实现变换矩阵入栈 -} - -void VulkanRenderer::popTransform() { - // TODO: 实现变换矩阵出栈 -} - -glm::mat4 VulkanRenderer::getCurrentTransform() const { - return glm::mat4(1.0f); -} - -Ptr VulkanRenderer::createTexture(int width, int height, - const uint8_t *pixels, - int channels) { - // TODO: 实现Vulkan纹理创建 - return nullptr; -} - -Ptr VulkanRenderer::loadTexture(const std::string &filepath) { - // TODO: 实现Vulkan纹理加载 - return nullptr; -} - -void VulkanRenderer::beginSpriteBatch() { - // TODO: 实现精灵批处理开始 -} - -void VulkanRenderer::drawSprite(const Texture &texture, const Rect &destRect, - const Rect &srcRect, const Color &tint, - float rotation, const Vec2 &anchor) { - // TODO: 实现精灵绘制 -} - -void VulkanRenderer::drawSprite(const Texture &texture, const Vec2 &position, - const Color &tint) { - // TODO: 实现简化精灵绘制 -} - -void VulkanRenderer::endSpriteBatch() { - // TODO: 实现精灵批处理结束 -} - -void VulkanRenderer::drawLine(const Vec2 &start, const Vec2 &end, - const Color &color, float width) { - // TODO: 实现线条绘制 -} - -void VulkanRenderer::drawRect(const Rect &rect, const Color &color, - float width) { - // TODO: 实现矩形边框绘制 -} - -void VulkanRenderer::fillRect(const Rect &rect, const Color &color) { - // TODO: 实现矩形填充 -} - -void VulkanRenderer::drawCircle(const Vec2 ¢er, float radius, - const Color &color, int segments, float width) { - // TODO: 实现圆形边框绘制 -} - -void VulkanRenderer::fillCircle(const Vec2 ¢er, float radius, - const Color &color, int segments) { - // TODO: 实现圆形填充 -} - -void VulkanRenderer::drawTriangle(const Vec2 &p1, const Vec2 &p2, - const Vec2 &p3, const Color &color, - float width) { - // TODO: 实现三角形边框绘制 -} - -void VulkanRenderer::fillTriangle(const Vec2 &p1, const Vec2 &p2, - const Vec2 &p3, const Color &color) { - // TODO: 实现三角形填充 -} - -void VulkanRenderer::drawPolygon(const std::vector &points, - const Color &color, float width) { - // TODO: 实现多边形边框绘制 -} - -void VulkanRenderer::fillPolygon(const std::vector &points, - const Color &color) { - // TODO: 实现多边形填充 -} - -Ptr VulkanRenderer::createFontAtlas(const std::string &filepath, - int fontSize, bool useSDF) { - // TODO: 实现字体图集创建 - return nullptr; -} - -void VulkanRenderer::drawText(const FontAtlas &font, const std::string &text, - const Vec2 &position, const Color &color) { - // TODO: 实现文本绘制 -} - -void VulkanRenderer::drawText(const FontAtlas &font, const std::string &text, - float x, float y, const Color &color) { - // TODO: 实现文本绘制 -} - -void VulkanRenderer::resetStats() { stats_ = Stats{}; } - -} // namespace extra2d diff --git a/Extra2D/src/graphics/core/render_module.cpp b/Extra2D/src/graphics/core/render_module.cpp index e5b4177..cb9b297 100644 --- a/Extra2D/src/graphics/core/render_module.cpp +++ b/Extra2D/src/graphics/core/render_module.cpp @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include #include #include @@ -10,16 +10,6 @@ namespace extra2d { -// 前向声明后端初始化函数 -namespace graphics { -#ifdef E2D_BACKEND_OPENGL -void initOpenGLBackend(); -#endif -#ifdef E2D_BACKEND_VULKAN -void initVulkanBackend(); -#endif -} // namespace graphics - RenderModule::RenderModule(std::function configFn) { configFn(cfg_); } @@ -40,15 +30,6 @@ bool RenderModule::init() { return false; } - // 初始化图形后端(注册到工厂) -#ifdef E2D_BACKEND_OPENGL - graphics::initOpenGLBackend(); -#endif -#ifdef E2D_BACKEND_VULKAN - graphics::initVulkanBackend(); -#endif - - // 使用ShaderManager的默认路径初始化 if (!ShaderManager::getInstance().isInitialized()) { auto factory = makeShared(); if (!ShaderManager::getInstance().init(factory)) { @@ -56,18 +37,8 @@ bool RenderModule::init() { } } - std::string windowBackend = winMod->getWindowBackend(); - - if (cfg_.backend.empty()) { - E2D_LOG_INFO("未指定图形后端,正在为窗口后端自动选择:{}", windowBackend); - renderer_ = graphics::BackendFactory::createBackendForWindow(windowBackend); - } else { - if (!graphics::BackendFactory::isCompatible(cfg_.backend, windowBackend)) { - E2D_LOG_WARN("图形后端 '{}' 与窗口后端 '{}' 不兼容", cfg_.backend, - windowBackend); - } - renderer_ = graphics::BackendFactory::createBackend(cfg_.backend); - } + E2D_LOG_INFO("正在创建 OpenGL 渲染后端"); + renderer_ = makeUnique(); if (!renderer_) { E2D_LOG_ERROR("创建渲染后端失败"); diff --git a/Extra2D/src/graphics/backends/opengl/gl_buffer.cpp b/Extra2D/src/graphics/opengl/gl_buffer.cpp similarity index 100% rename from Extra2D/src/graphics/backends/opengl/gl_buffer.cpp rename to Extra2D/src/graphics/opengl/gl_buffer.cpp diff --git a/Extra2D/src/graphics/backends/opengl/gl_context.cpp b/Extra2D/src/graphics/opengl/gl_context.cpp similarity index 100% rename from Extra2D/src/graphics/backends/opengl/gl_context.cpp rename to Extra2D/src/graphics/opengl/gl_context.cpp diff --git a/Extra2D/src/graphics/backends/opengl/gl_font_atlas.cpp b/Extra2D/src/graphics/opengl/gl_font_atlas.cpp similarity index 100% rename from Extra2D/src/graphics/backends/opengl/gl_font_atlas.cpp rename to Extra2D/src/graphics/opengl/gl_font_atlas.cpp diff --git a/Extra2D/src/graphics/backends/opengl/gl_framebuffer.cpp b/Extra2D/src/graphics/opengl/gl_framebuffer.cpp similarity index 100% rename from Extra2D/src/graphics/backends/opengl/gl_framebuffer.cpp rename to Extra2D/src/graphics/opengl/gl_framebuffer.cpp diff --git a/Extra2D/src/graphics/backends/opengl/gl_pipeline.cpp b/Extra2D/src/graphics/opengl/gl_pipeline.cpp similarity index 100% rename from Extra2D/src/graphics/backends/opengl/gl_pipeline.cpp rename to Extra2D/src/graphics/opengl/gl_pipeline.cpp diff --git a/Extra2D/src/graphics/backends/opengl/gl_renderer.cpp b/Extra2D/src/graphics/opengl/gl_renderer.cpp similarity index 100% rename from Extra2D/src/graphics/backends/opengl/gl_renderer.cpp rename to Extra2D/src/graphics/opengl/gl_renderer.cpp diff --git a/Extra2D/src/graphics/backends/opengl/gl_shader.cpp b/Extra2D/src/graphics/opengl/gl_shader.cpp similarity index 100% rename from Extra2D/src/graphics/backends/opengl/gl_shader.cpp rename to Extra2D/src/graphics/opengl/gl_shader.cpp diff --git a/Extra2D/src/graphics/backends/opengl/gl_sprite_batch.cpp b/Extra2D/src/graphics/opengl/gl_sprite_batch.cpp similarity index 100% rename from Extra2D/src/graphics/backends/opengl/gl_sprite_batch.cpp rename to Extra2D/src/graphics/opengl/gl_sprite_batch.cpp diff --git a/Extra2D/src/graphics/backends/opengl/gl_texture.cpp b/Extra2D/src/graphics/opengl/gl_texture.cpp similarity index 100% rename from Extra2D/src/graphics/backends/opengl/gl_texture.cpp rename to Extra2D/src/graphics/opengl/gl_texture.cpp diff --git a/Extra2D/src/platform/backend_factory.cpp b/Extra2D/src/platform/backend_factory.cpp deleted file mode 100644 index ece530c..0000000 --- a/Extra2D/src/platform/backend_factory.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#include - -namespace extra2d { -namespace platform { - -std::unordered_map& BackendFactory::registry() { - static std::unordered_map reg; - return reg; -} - -void BackendFactory::reg(const std::string& name, WindowFn win, InputFn in) { - registry()[name] = {win, in}; -} - -UniquePtr BackendFactory::createWindow(const std::string& name) { - auto& reg = registry(); - auto it = reg.find(name); - if (it != reg.end() && it->second.windowFn) { - return it->second.windowFn(); - } - return nullptr; -} - -UniquePtr BackendFactory::createInput(const std::string& name) { - auto& reg = registry(); - auto it = reg.find(name); - if (it != reg.end() && it->second.inputFn) { - return it->second.inputFn(); - } - return nullptr; -} - -std::vector BackendFactory::backends() { - std::vector result; - for (const auto& pair : registry()) { - result.push_back(pair.first); - } - return result; -} - -bool BackendFactory::has(const std::string& name) { - return registry().find(name) != registry().end(); -} - -} // namespace platform -} // namespace extra2d diff --git a/Extra2D/src/platform/backends/glfw/glfw_backend.cpp b/Extra2D/src/platform/backends/glfw/glfw_backend.cpp deleted file mode 100644 index 7e688bc..0000000 --- a/Extra2D/src/platform/backends/glfw/glfw_backend.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "glfw_window.h" -#include "glfw_input.h" -#include - -namespace extra2d { -namespace platform { - -namespace { - static bool s_glfwBackendRegistered = false; -} - -void initGLFWBackend() { - if (s_glfwBackendRegistered) { - return; - } - s_glfwBackendRegistered = true; - - BackendFactory::reg( - "glfw", - []() -> UniquePtr { - return makeUnique(); - }, - []() -> UniquePtr { - return makeUnique(); - } - ); -} - -} // namespace platform -} // namespace extra2d diff --git a/Extra2D/src/platform/backends/sdl2/sdl2_backend.cpp b/Extra2D/src/platform/backends/sdl2/sdl2_backend.cpp deleted file mode 100644 index 71b6ba2..0000000 --- a/Extra2D/src/platform/backends/sdl2/sdl2_backend.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "sdl2_window.h" -#include "sdl2_input.h" -#include - -namespace extra2d { -namespace platform { - -namespace { - static bool s_sdl2BackendRegistered = false; -} - -void initSDL2Backend() { - if (s_sdl2BackendRegistered) { - return; - } - s_sdl2BackendRegistered = true; - - BackendFactory::reg( - "sdl2", - []() -> UniquePtr { - return makeUnique(); - }, - []() -> UniquePtr { - return makeUnique(); - } - ); -} - -} // namespace platform -} // namespace extra2d diff --git a/Extra2D/src/platform/backends/sdl2/sdl2_input.cpp b/Extra2D/src/platform/backends/sdl2/sdl2_input.cpp deleted file mode 100644 index a84660f..0000000 --- a/Extra2D/src/platform/backends/sdl2/sdl2_input.cpp +++ /dev/null @@ -1,454 +0,0 @@ -#include "sdl2_input.h" -#include -#include -#include - - -namespace extra2d { - -SDL2Input::SDL2Input() { - keyCurrent_.fill(false); - keyPrevious_.fill(false); - mouseCurrent_.fill(false); - mousePrevious_.fill(false); - gamepadCurrent_.fill(false); - gamepadPrevious_.fill(false); -} - -SDL2Input::~SDL2Input() { shutdown(); } - -void SDL2Input::init() { - E2D_LOG_INFO("SDL2Input 已初始化"); - - if (SDL_Init(SDL_INIT_GAMECONTROLLER) != 0) { - E2D_LOG_WARN("初始化游戏手柄子系统失败: {}", SDL_GetError()); - } - - openGamepad(); -} - -void SDL2Input::shutdown() { - closeGamepad(); - E2D_LOG_INFO("SDL2Input 已关闭"); -} - -void SDL2Input::update() { - keyPrevious_ = keyCurrent_; - mousePrevious_ = mouseCurrent_; - gamepadPrevious_ = gamepadCurrent_; - - scrollDelta_ = 0.0f; - mouseDelta_ = Vec2{0.0f, 0.0f}; - - updateGamepad(); -} - -void SDL2Input::setEventCallback(EventCallback callback) { - eventCallback_ = std::move(callback); -} - -void SDL2Input::handleSDLEvent(const SDL_Event &event) { - switch (event.type) { - case SDL_KEYDOWN: { - int key = event.key.keysym.scancode; - if (key >= 0 && key < static_cast(Key::Count)) { - if (!keyCurrent_[key]) { - keyCurrent_[key] = true; - - Event e = Event::createKeyPress(event.key.keysym.sym, - event.key.keysym.scancode, - event.key.keysym.mod); - dispatchEvent(e); - } - } - break; - } - - case SDL_KEYUP: { - int key = event.key.keysym.scancode; - if (key >= 0 && key < static_cast(Key::Count)) { - keyCurrent_[key] = false; - - Event e = Event::createKeyRelease(event.key.keysym.sym, - event.key.keysym.scancode, - event.key.keysym.mod); - dispatchEvent(e); - } - break; - } - - case SDL_MOUSEBUTTONDOWN: { - int btn = event.button.button - 1; - if (btn >= 0 && btn < static_cast(Mouse::Count)) { - mouseCurrent_[btn] = true; - - Vec2 pos{static_cast(event.button.x), - static_cast(event.button.y)}; - Event e = Event::createMouseButtonPress(btn, 0, pos); - dispatchEvent(e); - } - break; - } - - case SDL_MOUSEBUTTONUP: { - int btn = event.button.button - 1; - if (btn >= 0 && btn < static_cast(Mouse::Count)) { - mouseCurrent_[btn] = false; - - Vec2 pos{static_cast(event.button.x), - static_cast(event.button.y)}; - Event e = Event::createMouseButtonRelease(btn, 0, pos); - dispatchEvent(e); - } - break; - } - - case SDL_MOUSEMOTION: { - Vec2 newPos{static_cast(event.motion.x), - static_cast(event.motion.y)}; - Vec2 delta{static_cast(event.motion.xrel), - static_cast(event.motion.yrel)}; - - mouseDelta_ = mouseDelta_ + delta; - mousePos_ = newPos; - - Event e = Event::createMouseMove(newPos, delta); - dispatchEvent(e); - break; - } - - case SDL_MOUSEWHEEL: { - Vec2 offset{static_cast(event.wheel.x), - static_cast(event.wheel.y)}; - Vec2 pos = mousePos_; - - scroll_ += event.wheel.y; - scrollDelta_ += event.wheel.y; - - Event e = Event::createMouseScroll(offset, pos); - dispatchEvent(e); - break; - } - - case SDL_CONTROLLERDEVICEADDED: - E2D_LOG_INFO("游戏手柄已连接: 索引 {}", event.cdevice.which); - openGamepad(); - break; - - case SDL_CONTROLLERDEVICEREMOVED: - if (gamepad_ && - event.cdevice.which == - SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(gamepad_))) { - E2D_LOG_INFO("游戏手柄已断开"); - closeGamepad(); - } - break; - - case SDL_CONTROLLERBUTTONDOWN: - if (gamepad_) { - int btn = event.cbutton.button; - if (btn >= 0 && btn < static_cast(Gamepad::Count)) { - gamepadCurrent_[btn] = true; - - GamepadButtonEvent btnEvent; - btnEvent.gamepadId = gamepadIndex_; - btnEvent.button = btn; - - Event e; - e.type = EventType::GamepadButtonPressed; - e.data = btnEvent; - dispatchEvent(e); - } - } - break; - - case SDL_CONTROLLERBUTTONUP: - if (gamepad_) { - int btn = event.cbutton.button; - if (btn >= 0 && btn < static_cast(Gamepad::Count)) { - gamepadCurrent_[btn] = false; - - GamepadButtonEvent btnEvent; - btnEvent.gamepadId = gamepadIndex_; - btnEvent.button = btn; - - Event e; - e.type = EventType::GamepadButtonReleased; - e.data = btnEvent; - dispatchEvent(e); - } - } - break; - - default: - break; - } -} - -void SDL2Input::dispatchEvent(const Event &event) { - if (eventCallback_) { - eventCallback_(event); - } -} - -bool SDL2Input::down(Key key) const { - size_t idx = static_cast(key); - if (idx < keyCurrent_.size()) { - return keyCurrent_[idx]; - } - return false; -} - -bool SDL2Input::pressed(Key key) const { - size_t idx = static_cast(key); - if (idx < keyCurrent_.size()) { - return keyCurrent_[idx] && !keyPrevious_[idx]; - } - return false; -} - -bool SDL2Input::released(Key key) const { - size_t idx = static_cast(key); - if (idx < keyCurrent_.size()) { - return !keyCurrent_[idx] && keyPrevious_[idx]; - } - return false; -} - -bool SDL2Input::down(Mouse btn) const { - size_t idx = static_cast(btn); - if (idx < mouseCurrent_.size()) { - return mouseCurrent_[idx]; - } - return false; -} - -bool SDL2Input::pressed(Mouse btn) const { - size_t idx = static_cast(btn); - if (idx < mouseCurrent_.size()) { - return mouseCurrent_[idx] && !mousePrevious_[idx]; - } - return false; -} - -bool SDL2Input::released(Mouse btn) const { - size_t idx = static_cast(btn); - if (idx < mouseCurrent_.size()) { - return !mouseCurrent_[idx] && mousePrevious_[idx]; - } - return false; -} - -Vec2 SDL2Input::mouse() const { return mousePos_; } - -Vec2 SDL2Input::mouseDelta() const { return mouseDelta_; } - -float SDL2Input::scroll() const { return scroll_; } - -float SDL2Input::scrollDelta() const { return scrollDelta_; } - -void SDL2Input::setMouse(const Vec2 &pos) { - SDL_WarpMouseInWindow(nullptr, static_cast(pos.x), - static_cast(pos.y)); -} - -bool SDL2Input::gamepad() const { return gamepad_ != nullptr; } - -bool SDL2Input::down(Gamepad btn) const { - size_t idx = static_cast(btn); - if (idx < gamepadCurrent_.size()) { - return gamepadCurrent_[idx]; - } - return false; -} - -bool SDL2Input::pressed(Gamepad btn) const { - size_t idx = static_cast(btn); - if (idx < gamepadCurrent_.size()) { - return gamepadCurrent_[idx] && !gamepadPrevious_[idx]; - } - return false; -} - -bool SDL2Input::released(Gamepad btn) const { - size_t idx = static_cast(btn); - if (idx < gamepadCurrent_.size()) { - return !gamepadCurrent_[idx] && gamepadPrevious_[idx]; - } - return false; -} - -Vec2 SDL2Input::leftStick() const { return leftStick_; } - -Vec2 SDL2Input::rightStick() const { return rightStick_; } - -float SDL2Input::leftTrigger() const { return leftTrigger_; } - -float SDL2Input::rightTrigger() const { return rightTrigger_; } - -void SDL2Input::vibrate(float left, float right) { - if (gamepad_) { - Uint16 lowFreq = static_cast(left * 65535.0f); - Uint16 highFreq = static_cast(right * 65535.0f); - SDL_GameControllerRumble(gamepad_, lowFreq, highFreq, 500); - } -} - -bool SDL2Input::touching() const { return false; } - -int SDL2Input::touchCount() const { return 0; } - -Vec2 SDL2Input::touch(int index) const { - (void)index; - return Vec2{0.0f, 0.0f}; -} - -TouchPoint SDL2Input::touchPoint(int index) const { - (void)index; - return TouchPoint{}; -} - -void SDL2Input::updateKeyboard() {} - -void SDL2Input::updateMouse() { - int x = 0, y = 0; - SDL_GetMouseState(&x, &y); - mousePos_ = Vec2{static_cast(x), static_cast(y)}; -} - -void SDL2Input::updateGamepad() { - if (!gamepad_) { - return; - } - - auto applyDeadzone = [this](float value) -> float { - if (std::abs(value) < deadzone_) { - return 0.0f; - } - float sign = value >= 0.0f ? 1.0f : -1.0f; - return sign * (std::abs(value) - deadzone_) / (1.0f - deadzone_); - }; - - int lx = SDL_GameControllerGetAxis(gamepad_, SDL_CONTROLLER_AXIS_LEFTX); - int ly = SDL_GameControllerGetAxis(gamepad_, SDL_CONTROLLER_AXIS_LEFTY); - int rx = SDL_GameControllerGetAxis(gamepad_, SDL_CONTROLLER_AXIS_RIGHTX); - int ry = SDL_GameControllerGetAxis(gamepad_, SDL_CONTROLLER_AXIS_RIGHTY); - - leftStick_.x = applyDeadzone(lx / 32767.0f); - leftStick_.y = applyDeadzone(ly / 32767.0f); - rightStick_.x = applyDeadzone(rx / 32767.0f); - rightStick_.y = applyDeadzone(ry / 32767.0f); - - int lt = SDL_GameControllerGetAxis(gamepad_, SDL_CONTROLLER_AXIS_TRIGGERLEFT); - int rt = - SDL_GameControllerGetAxis(gamepad_, SDL_CONTROLLER_AXIS_TRIGGERRIGHT); - - leftTrigger_ = lt / 32767.0f; - rightTrigger_ = rt / 32767.0f; -} - -void SDL2Input::openGamepad() { - int numJoysticks = SDL_NumJoysticks(); - for (int i = 0; i < numJoysticks; ++i) { - if (SDL_IsGameController(i)) { - gamepad_ = SDL_GameControllerOpen(i); - if (gamepad_) { - gamepadIndex_ = i; - E2D_LOG_INFO("游戏手柄已打开: {}", SDL_GameControllerName(gamepad_)); - return; - } - } - } -} - -void SDL2Input::closeGamepad() { - if (gamepad_) { - SDL_GameControllerClose(gamepad_); - gamepad_ = nullptr; - gamepadIndex_ = -1; - gamepadCurrent_.fill(false); - gamepadPrevious_.fill(false); - } -} - -int SDL2Input::keyToSDL(Key key) { return static_cast(key); } - -int SDL2Input::mouseToSDL(Mouse btn) { - switch (btn) { - case Mouse::Left: - return SDL_BUTTON_LEFT; - case Mouse::Middle: - return SDL_BUTTON_MIDDLE; - case Mouse::Right: - return SDL_BUTTON_RIGHT; - case Mouse::X1: - return SDL_BUTTON_X1; - case Mouse::X2: - return SDL_BUTTON_X2; - default: - return 0; - } -} - -int SDL2Input::gamepadToSDL(Gamepad btn) { - switch (btn) { - case Gamepad::A: - return SDL_CONTROLLER_BUTTON_A; - case Gamepad::B: - return SDL_CONTROLLER_BUTTON_B; - case Gamepad::X: - return SDL_CONTROLLER_BUTTON_X; - case Gamepad::Y: - return SDL_CONTROLLER_BUTTON_Y; - case Gamepad::Back: - return SDL_CONTROLLER_BUTTON_BACK; - case Gamepad::Start: - return SDL_CONTROLLER_BUTTON_START; - case Gamepad::LStick: - return SDL_CONTROLLER_BUTTON_LEFTSTICK; - case Gamepad::RStick: - return SDL_CONTROLLER_BUTTON_RIGHTSTICK; - case Gamepad::LB: - return SDL_CONTROLLER_BUTTON_LEFTSHOULDER; - case Gamepad::RB: - return SDL_CONTROLLER_BUTTON_RIGHTSHOULDER; - case Gamepad::DUp: - return SDL_CONTROLLER_BUTTON_DPAD_UP; - case Gamepad::DDown: - return SDL_CONTROLLER_BUTTON_DPAD_DOWN; - case Gamepad::DLeft: - return SDL_CONTROLLER_BUTTON_DPAD_LEFT; - case Gamepad::DRight: - return SDL_CONTROLLER_BUTTON_DPAD_RIGHT; - case Gamepad::Guide: - return SDL_CONTROLLER_BUTTON_GUIDE; - default: - return 0; - } -} - -Key SDL2Input::sdlToKey(int sdlKey) { - if (sdlKey >= 0 && sdlKey < static_cast(Key::Count)) { - return static_cast(sdlKey); - } - return Key::None; -} - -Mouse SDL2Input::sdlToMouse(int sdlButton) { - switch (sdlButton) { - case SDL_BUTTON_LEFT: - return Mouse::Left; - case SDL_BUTTON_MIDDLE: - return Mouse::Middle; - case SDL_BUTTON_RIGHT: - return Mouse::Right; - case SDL_BUTTON_X1: - return Mouse::X1; - case SDL_BUTTON_X2: - return Mouse::X2; - default: - return Mouse::Count; - } -} - -} // namespace extra2d diff --git a/Extra2D/src/platform/backends/sdl2/sdl2_input.h b/Extra2D/src/platform/backends/sdl2/sdl2_input.h deleted file mode 100644 index df52122..0000000 --- a/Extra2D/src/platform/backends/sdl2/sdl2_input.h +++ /dev/null @@ -1,104 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -namespace extra2d { - -/** - * @brief SDL2 输入实现 - */ -class SDL2Input : public IInput { -public: - using EventCallback = std::function; - - SDL2Input(); - ~SDL2Input() override; - - void init() override; - void shutdown() override; - void update() override; - - bool down(Key key) const override; - bool pressed(Key key) const override; - bool released(Key key) const override; - - bool down(Mouse btn) const override; - bool pressed(Mouse btn) const override; - bool released(Mouse btn) const override; - Vec2 mouse() const override; - Vec2 mouseDelta() const override; - float scroll() const override; - float scrollDelta() const override; - void setMouse(const Vec2& pos) override; - - bool gamepad() const override; - bool down(Gamepad btn) const override; - bool pressed(Gamepad btn) const override; - bool released(Gamepad btn) const override; - Vec2 leftStick() const override; - Vec2 rightStick() const override; - float leftTrigger() const override; - float rightTrigger() const override; - void vibrate(float left, float right) override; - - bool touching() const override; - int touchCount() const override; - Vec2 touch(int index) const override; - TouchPoint touchPoint(int index) const override; - - /** - * @brief 设置事件回调 - * @param callback 事件回调函数 - */ - void setEventCallback(EventCallback callback); - - /** - * @brief 处理 SDL 事件 - * @param event SDL 事件 - */ - void handleSDLEvent(const SDL_Event& event); - -private: - void updateKeyboard(); - void updateMouse(); - void updateGamepad(); - void openGamepad(); - void closeGamepad(); - - static int keyToSDL(Key key); - static int mouseToSDL(Mouse btn); - static int gamepadToSDL(Gamepad btn); - static Key sdlToKey(int sdlKey); - static Mouse sdlToMouse(int sdlButton); - - void dispatchEvent(const Event& event); - - std::array(Key::Count)> keyCurrent_{}; - std::array(Key::Count)> keyPrevious_{}; - - std::array(Mouse::Count)> mouseCurrent_{}; - std::array(Mouse::Count)> mousePrevious_{}; - - Vec2 mousePos_; - Vec2 mouseDelta_; - float scroll_ = 0.0f; - float scrollDelta_ = 0.0f; - - SDL_GameController* gamepad_ = nullptr; - int gamepadIndex_ = -1; - std::array(Gamepad::Count)> gamepadCurrent_{}; - std::array(Gamepad::Count)> gamepadPrevious_{}; - Vec2 leftStick_; - Vec2 rightStick_; - float leftTrigger_ = 0.0f; - float rightTrigger_ = 0.0f; - float deadzone_ = 0.15f; - - EventCallback eventCallback_; -}; - -} diff --git a/Extra2D/src/platform/backends/sdl2/sdl2_window.cpp b/Extra2D/src/platform/backends/sdl2/sdl2_window.cpp deleted file mode 100644 index 3db155e..0000000 --- a/Extra2D/src/platform/backends/sdl2/sdl2_window.cpp +++ /dev/null @@ -1,615 +0,0 @@ -#include "sdl2_window.h" -#include "sdl2_input.h" -#include -#include -#include -#include -#include -#include - - -namespace extra2d { - -SDL2Window::SDL2Window() { - for (int i = 0; i < 7; ++i) { - sdlCursors_[i] = nullptr; - } -} - -SDL2Window::~SDL2Window() { destroy(); } - -bool SDL2Window::create(const std::string &title, int width, int height, - bool vsync) { - if (!initSDL()) { - return false; - } - - Uint32 flags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE; - -#ifdef __SWITCH__ - flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; -#endif - - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); - - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); - SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); - - sdlWindow_ = SDL_CreateWindow(title.c_str(), SDL_WINDOWPOS_CENTERED, - SDL_WINDOWPOS_CENTERED, width, height, flags); - - if (!sdlWindow_) { - E2D_LOG_ERROR("创建 SDL 窗口失败: {}", SDL_GetError()); - deinitSDL(); - return false; - } - - glContext_ = SDL_GL_CreateContext(sdlWindow_); - if (!glContext_) { - E2D_LOG_ERROR("创建 OpenGL 上下文失败: {}", SDL_GetError()); - SDL_DestroyWindow(sdlWindow_); - sdlWindow_ = nullptr; - deinitSDL(); - return false; - } - - if (!gladLoadGLES2Loader((GLADloadproc)SDL_GL_GetProcAddress)) { - E2D_LOG_ERROR("初始化 GLAD GLES2 失败"); - SDL_GL_DeleteContext(glContext_); - glContext_ = nullptr; - SDL_DestroyWindow(sdlWindow_); - sdlWindow_ = nullptr; - deinitSDL(); - return false; - } - - SDL_GL_SetSwapInterval(vsync ? 1 : 0); - - SDL_GetWindowSize(sdlWindow_, &width_, &height_); - fullscreen_ = (flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0; - vsync_ = vsync; - -#ifndef __SWITCH__ - initCursors(); -#endif - updateContentScale(); - - input_ = makeUnique(); - input_->init(); - - E2D_LOG_INFO("SDL2 窗口创建成功: {}x{}", width_, height_); - E2D_LOG_INFO(" 平台: OpenGL ES 3.2"); - return true; -} - -void SDL2Window::destroy() { - if (input_) { - input_->shutdown(); - input_.reset(); - } - -#ifndef __SWITCH__ - deinitCursors(); -#endif - - if (glContext_) { - SDL_GL_DeleteContext(glContext_); - glContext_ = nullptr; - } - - if (sdlWindow_) { - SDL_DestroyWindow(sdlWindow_); - sdlWindow_ = nullptr; - } - - deinitSDL(); -} - -void SDL2Window::poll() { - if (!sdlWindow_) - return; - - if (input_) { - input_->update(); - } - - SDL_Event event; - while (SDL_PollEvent(&event)) { - handleEvent(event); - } -} - -void SDL2Window::swap() { - if (sdlWindow_ && glContext_) { - SDL_GL_SwapWindow(sdlWindow_); - } -} - -bool SDL2Window::shouldClose() const { return shouldClose_; } - -void SDL2Window::close() { shouldClose_ = true; } - -void SDL2Window::setTitle(const std::string &title) { - if (sdlWindow_) { - SDL_SetWindowTitle(sdlWindow_, title.c_str()); - } -} - -void SDL2Window::setSize(int w, int h) { - if (sdlWindow_) { - SDL_SetWindowSize(sdlWindow_, w, h); - width_ = w; - height_ = h; - } -} - -void SDL2Window::setPos(int x, int y) { -#ifndef __SWITCH__ - if (sdlWindow_) { - SDL_SetWindowPosition(sdlWindow_, x, y); - } -#else - (void)x; - (void)y; -#endif -} - -void SDL2Window::setFullscreen(bool fs) { -#ifndef __SWITCH__ - if (sdlWindow_) { - SDL_SetWindowFullscreen(sdlWindow_, fs ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); - fullscreen_ = fs; - } -#else - (void)fs; -#endif -} - -void SDL2Window::setVSync(bool vsync) { - if (glContext_) { - SDL_GL_SetSwapInterval(vsync ? 1 : 0); - vsync_ = vsync; - } -} - -void SDL2Window::setVisible(bool visible) { -#ifndef __SWITCH__ - if (sdlWindow_) { - if (visible) { - SDL_ShowWindow(sdlWindow_); - } else { - SDL_HideWindow(sdlWindow_); - } - } -#else - (void)visible; -#endif -} - -int SDL2Window::width() const { return width_; } - -int SDL2Window::height() const { return height_; } - -Size SDL2Window::size() const { - return Size(static_cast(width_), static_cast(height_)); -} - -Vec2 SDL2Window::pos() const { - int x = 0, y = 0; -#ifndef __SWITCH__ - if (sdlWindow_) { - SDL_GetWindowPosition(sdlWindow_, &x, &y); - } -#endif - return Vec2(static_cast(x), static_cast(y)); -} - -bool SDL2Window::fullscreen() const { return fullscreen_; } - -bool SDL2Window::vsync() const { return vsync_; } - -bool SDL2Window::focused() const { return focused_; } - -bool SDL2Window::minimized() const { return minimized_; } - -float SDL2Window::scaleX() const { return scaleX_; } - -float SDL2Window::scaleY() const { return scaleY_; } - -void SDL2Window::setCursor(Cursor cursor) { -#ifndef __SWITCH__ - if (cursor == Cursor::Hidden) { - SDL_ShowCursor(SDL_DISABLE); - return; - } - - SDL_ShowCursor(SDL_ENABLE); - - int idx = static_cast(cursor); - if (idx >= 0 && idx < 7 && sdlCursors_[idx]) { - SDL_SetCursor(sdlCursors_[idx]); - currentCursor_ = idx; - } -#else - (void)cursor; -#endif -} - -void SDL2Window::showCursor(bool show) { -#ifndef __SWITCH__ - SDL_ShowCursor(show ? SDL_ENABLE : SDL_DISABLE); - cursorVisible_ = show; -#else - (void)show; -#endif -} - -void SDL2Window::lockCursor(bool lock) { -#ifndef __SWITCH__ - if (sdlWindow_) { - SDL_SetRelativeMouseMode(lock ? SDL_TRUE : SDL_FALSE); - cursorLocked_ = lock; - } -#else - (void)lock; -#endif -} - -IInput *SDL2Window::input() const { return input_.get(); } - -void SDL2Window::onResize(ResizeCb cb) { resizeCb_ = cb; } - -void SDL2Window::onClose(CloseCb cb) { closeCb_ = cb; } - -void SDL2Window::onFocus(FocusCb cb) { focusCb_ = cb; } - -void *SDL2Window::native() const { return sdlWindow_; } - -bool SDL2Window::initSDL() { - static int sdlInitCount = 0; - if (sdlInitCount == 0) { - Uint32 initFlags = SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER; - if (SDL_Init(initFlags) != 0) { - E2D_LOG_ERROR("初始化 SDL 失败: {}", SDL_GetError()); - return false; - } - sdlInitCount++; - } - return true; -} - -void SDL2Window::deinitSDL() { - static int sdlInitCount = 1; - sdlInitCount--; - if (sdlInitCount == 0) { - SDL_Quit(); - } -} - -#ifndef __SWITCH__ -void SDL2Window::initCursors() { - sdlCursors_[0] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); - sdlCursors_[1] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM); - sdlCursors_[2] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_CROSSHAIR); - sdlCursors_[3] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND); - sdlCursors_[4] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS); - sdlCursors_[5] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE); - sdlCursors_[6] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL); -} - -void SDL2Window::deinitCursors() { - for (int i = 0; i < 7; ++i) { - if (sdlCursors_[i]) { - SDL_FreeCursor(sdlCursors_[i]); - sdlCursors_[i] = nullptr; - } - } -} -#endif - -void SDL2Window::updateContentScale() { - if (sdlWindow_) { - SDL_GetWindowSize(sdlWindow_, &width_, &height_); - int dw, dh; - SDL_GL_GetDrawableSize(sdlWindow_, &dw, &dh); - scaleX_ = dw > 0 ? static_cast(dw) / width_ : 1.0f; - scaleY_ = dh > 0 ? static_cast(dh) / height_ : 1.0f; - } -} - -void SDL2Window::handleEvent(const SDL_Event &event) { - if (input_) { - input_->handleSDLEvent(event); - } - - // 将事件推送到事件服务 - auto eventService = ServiceLocator::instance().getService(); - - switch (event.type) { - case SDL_QUIT: - shouldClose_ = true; - if (closeCb_) - closeCb_(); - if (eventService) { - Event e = Event::createWindowClose(); - eventService->pushEvent(e); - } - break; - - case SDL_WINDOWEVENT: - switch (event.window.event) { - case SDL_WINDOWEVENT_RESIZED: - case SDL_WINDOWEVENT_SIZE_CHANGED: - width_ = event.window.data1; - height_ = event.window.data2; - updateContentScale(); - if (resizeCb_) - resizeCb_(width_, height_); - if (eventService) { - Event e = Event::createWindowResize(width_, height_); - eventService->pushEvent(e); - } - break; - - case SDL_WINDOWEVENT_FOCUS_GAINED: - focused_ = true; - if (focusCb_) - focusCb_(true); - break; - - case SDL_WINDOWEVENT_FOCUS_LOST: - focused_ = false; - if (focusCb_) - focusCb_(false); - break; - - case SDL_WINDOWEVENT_MINIMIZED: - minimized_ = true; - break; - - case SDL_WINDOWEVENT_RESTORED: - minimized_ = false; - break; - - case SDL_WINDOWEVENT_CLOSE: - shouldClose_ = true; - if (closeCb_) - closeCb_(); - if (eventService) { - Event e = Event::createWindowClose(); - eventService->pushEvent(e); - } - break; - } - break; - - case SDL_KEYDOWN: { - if (event.key.repeat == 0 && eventService) { - // 将 SDL scancode 转换为 Key 枚举 - Key key = sdlScancodeToKey(event.key.keysym.scancode); - if (key != Key::None) { - int keyCode = static_cast(key); - Event e = Event::createKeyPress(keyCode, event.key.keysym.scancode, - event.key.keysym.mod); - eventService->pushEvent(e); - } - } - break; - } - - case SDL_KEYUP: { - if (eventService) { - Key key = sdlScancodeToKey(event.key.keysym.scancode); - if (key != Key::None) { - int keyCode = static_cast(key); - Event e = Event::createKeyRelease(keyCode, event.key.keysym.scancode, - event.key.keysym.mod); - eventService->pushEvent(e); - } - } - break; - } - - case SDL_MOUSEBUTTONDOWN: { - if (eventService) { - Vec2 pos{static_cast(event.button.x), - static_cast(event.button.y)}; - Event e = Event::createMouseButtonPress(event.button.button - 1, 0, pos); - eventService->pushEvent(e); - } - break; - } - - case SDL_MOUSEBUTTONUP: { - if (eventService) { - Vec2 pos{static_cast(event.button.x), - static_cast(event.button.y)}; - Event e = - Event::createMouseButtonRelease(event.button.button - 1, 0, pos); - eventService->pushEvent(e); - } - break; - } - - case SDL_MOUSEMOTION: { - if (eventService) { - Vec2 pos{static_cast(event.motion.x), - static_cast(event.motion.y)}; - Vec2 delta{static_cast(event.motion.xrel), - static_cast(event.motion.yrel)}; - Event e = Event::createMouseMove(pos, delta); - eventService->pushEvent(e); - } - break; - } - - case SDL_MOUSEWHEEL: { - if (eventService) { - int x, y; - SDL_GetMouseState(&x, &y); - Vec2 offset{static_cast(event.wheel.x), - static_cast(event.wheel.y)}; - Vec2 pos{static_cast(x), static_cast(y)}; - Event e = Event::createMouseScroll(offset, pos); - eventService->pushEvent(e); - } - break; - } - } -} - -Key SDL2Window::sdlScancodeToKey(int scancode) { - switch (scancode) { - case SDL_SCANCODE_A: - return Key::A; - case SDL_SCANCODE_B: - return Key::B; - case SDL_SCANCODE_C: - return Key::C; - case SDL_SCANCODE_D: - return Key::D; - case SDL_SCANCODE_E: - return Key::E; - case SDL_SCANCODE_F: - return Key::F; - case SDL_SCANCODE_G: - return Key::G; - case SDL_SCANCODE_H: - return Key::H; - case SDL_SCANCODE_I: - return Key::I; - case SDL_SCANCODE_J: - return Key::J; - case SDL_SCANCODE_K: - return Key::K; - case SDL_SCANCODE_L: - return Key::L; - case SDL_SCANCODE_M: - return Key::M; - case SDL_SCANCODE_N: - return Key::N; - case SDL_SCANCODE_O: - return Key::O; - case SDL_SCANCODE_P: - return Key::P; - case SDL_SCANCODE_Q: - return Key::Q; - case SDL_SCANCODE_R: - return Key::R; - case SDL_SCANCODE_S: - return Key::S; - case SDL_SCANCODE_T: - return Key::T; - case SDL_SCANCODE_U: - return Key::U; - case SDL_SCANCODE_V: - return Key::V; - case SDL_SCANCODE_W: - return Key::W; - case SDL_SCANCODE_X: - return Key::X; - case SDL_SCANCODE_Y: - return Key::Y; - case SDL_SCANCODE_Z: - return Key::Z; - case SDL_SCANCODE_0: - return Key::Num0; - case SDL_SCANCODE_1: - return Key::Num1; - case SDL_SCANCODE_2: - return Key::Num2; - case SDL_SCANCODE_3: - return Key::Num3; - case SDL_SCANCODE_4: - return Key::Num4; - case SDL_SCANCODE_5: - return Key::Num5; - case SDL_SCANCODE_6: - return Key::Num6; - case SDL_SCANCODE_7: - return Key::Num7; - case SDL_SCANCODE_8: - return Key::Num8; - case SDL_SCANCODE_9: - return Key::Num9; - case SDL_SCANCODE_F1: - return Key::F1; - case SDL_SCANCODE_F2: - return Key::F2; - case SDL_SCANCODE_F3: - return Key::F3; - case SDL_SCANCODE_F4: - return Key::F4; - case SDL_SCANCODE_F5: - return Key::F5; - case SDL_SCANCODE_F6: - return Key::F6; - case SDL_SCANCODE_F7: - return Key::F7; - case SDL_SCANCODE_F8: - return Key::F8; - case SDL_SCANCODE_F9: - return Key::F9; - case SDL_SCANCODE_F10: - return Key::F10; - case SDL_SCANCODE_F11: - return Key::F11; - case SDL_SCANCODE_F12: - return Key::F12; - case SDL_SCANCODE_SPACE: - return Key::Space; - case SDL_SCANCODE_RETURN: - return Key::Enter; - case SDL_SCANCODE_ESCAPE: - return Key::Escape; - case SDL_SCANCODE_TAB: - return Key::Tab; - case SDL_SCANCODE_BACKSPACE: - return Key::Backspace; - case SDL_SCANCODE_INSERT: - return Key::Insert; - case SDL_SCANCODE_DELETE: - return Key::Delete; - case SDL_SCANCODE_HOME: - return Key::Home; - case SDL_SCANCODE_END: - return Key::End; - case SDL_SCANCODE_PAGEUP: - return Key::PageUp; - case SDL_SCANCODE_PAGEDOWN: - return Key::PageDown; - case SDL_SCANCODE_UP: - return Key::Up; - case SDL_SCANCODE_DOWN: - return Key::Down; - case SDL_SCANCODE_LEFT: - return Key::Left; - case SDL_SCANCODE_RIGHT: - return Key::Right; - case SDL_SCANCODE_LSHIFT: - return Key::LShift; - case SDL_SCANCODE_RSHIFT: - return Key::RShift; - case SDL_SCANCODE_LCTRL: - return Key::LCtrl; - case SDL_SCANCODE_RCTRL: - return Key::RCtrl; - case SDL_SCANCODE_LALT: - return Key::LAlt; - case SDL_SCANCODE_RALT: - return Key::RAlt; - case SDL_SCANCODE_CAPSLOCK: - return Key::CapsLock; - case SDL_SCANCODE_NUMLOCKCLEAR: - return Key::NumLock; - case SDL_SCANCODE_SCROLLLOCK: - return Key::ScrollLock; - default: - return Key::None; - } -} - -} // namespace extra2d diff --git a/Extra2D/src/platform/backends/sdl2/sdl2_window.h b/Extra2D/src/platform/backends/sdl2/sdl2_window.h deleted file mode 100644 index a9f4047..0000000 --- a/Extra2D/src/platform/backends/sdl2/sdl2_window.h +++ /dev/null @@ -1,101 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace extra2d { - -class SDL2Input; - -/** - * @brief SDL2 窗口实现 - */ -class SDL2Window : public IWindow { -public: - SDL2Window(); - ~SDL2Window() override; - - bool create(const std::string& title, int width, int height, bool vsync = true) override; - void destroy() override; - - void poll() override; - void swap() override; - bool shouldClose() const override; - void close() override; - - void setTitle(const std::string& title) override; - void setSize(int w, int h) override; - void setPos(int x, int y) override; - void setFullscreen(bool fs) override; - void setVSync(bool vsync) override; - void setVisible(bool visible) override; - - int width() const override; - int height() const override; - Size size() const override; - Vec2 pos() const override; - bool fullscreen() const override; - bool vsync() const override; - bool focused() const override; - bool minimized() const override; - - float scaleX() const override; - float scaleY() const override; - - void setCursor(Cursor cursor) override; - void showCursor(bool show) override; - void lockCursor(bool lock) override; - - IInput* input() const override; - - void onResize(ResizeCb cb) override; - void onClose(CloseCb cb) override; - void onFocus(FocusCb cb) override; - - void* native() const override; - - /** - * @brief 获取 SDL 窗口句柄 - */ - SDL_Window* sdlWindow() const { return sdlWindow_; } - - /** - * @brief 获取 OpenGL 上下文 - */ - SDL_GLContext glContext() const { return glContext_; } - -private: - bool initSDL(); - void deinitSDL(); - void initCursors(); - void deinitCursors(); - void updateContentScale(); - void handleEvent(const SDL_Event& event); - Key sdlScancodeToKey(int scancode); - - SDL_Window* sdlWindow_ = nullptr; - SDL_GLContext glContext_ = nullptr; - SDL_Cursor* sdlCursors_[7] = {}; - int currentCursor_ = 0; - - UniquePtr input_; - - int width_ = 1280; - int height_ = 720; - bool fullscreen_ = false; - bool vsync_ = true; - bool focused_ = true; - bool minimized_ = false; - bool shouldClose_ = false; - float scaleX_ = 1.0f; - float scaleY_ = 1.0f; - bool cursorVisible_ = true; - bool cursorLocked_ = false; - - ResizeCb resizeCb_; - CloseCb closeCb_; - FocusCb focusCb_; -}; - -} // namespace extra2d diff --git a/Extra2D/src/platform/backends/glfw/glfw_input.cpp b/Extra2D/src/platform/glfw/glfw_input.cpp similarity index 100% rename from Extra2D/src/platform/backends/glfw/glfw_input.cpp rename to Extra2D/src/platform/glfw/glfw_input.cpp diff --git a/Extra2D/src/platform/backends/glfw/glfw_input.h b/Extra2D/src/platform/glfw/glfw_input.h similarity index 100% rename from Extra2D/src/platform/backends/glfw/glfw_input.h rename to Extra2D/src/platform/glfw/glfw_input.h diff --git a/Extra2D/src/platform/backends/glfw/glfw_window.cpp b/Extra2D/src/platform/glfw/glfw_window.cpp similarity index 100% rename from Extra2D/src/platform/backends/glfw/glfw_window.cpp rename to Extra2D/src/platform/glfw/glfw_window.cpp diff --git a/Extra2D/src/platform/backends/glfw/glfw_window.h b/Extra2D/src/platform/glfw/glfw_window.h similarity index 100% rename from Extra2D/src/platform/backends/glfw/glfw_window.h rename to Extra2D/src/platform/glfw/glfw_window.h diff --git a/Extra2D/src/platform/window_module.cpp b/Extra2D/src/platform/window_module.cpp index c8044f7..196b762 100644 --- a/Extra2D/src/platform/window_module.cpp +++ b/Extra2D/src/platform/window_module.cpp @@ -1,23 +1,15 @@ #include -#include #include #include +#include "backends/glfw/glfw_window.h" + #ifdef __SWITCH__ #include #endif namespace extra2d { -// 前向声明后端初始化函数 -namespace platform { -#if defined(E2D_BACKEND_SDL2) -void initSDL2Backend(); -#elif defined(E2D_BACKEND_GLFW) -void initGLFWBackend(); -#endif -} // namespace platform - WindowModule::WindowModule(std::function configFn) { configFn(cfg_); } @@ -32,23 +24,11 @@ bool WindowModule::init() { if (initialized_) return true; - // 初始化后端(注册到工厂) -#if defined(E2D_BACKEND_SDL2) - platform::initSDL2Backend(); -#elif defined(E2D_BACKEND_GLFW) - platform::initGLFWBackend(); -#else -#error "No window backend defined" -#endif + E2D_LOG_INFO("正在创建 GLFW 窗口,尺寸 {}x{}", cfg_.w, cfg_.h); - E2D_LOG_INFO("窗口后端已初始化"); - - E2D_LOG_INFO("正在创建窗口,尺寸 {}x{}", cfg_.w, cfg_.h); - - // 创建窗口(使用配置的后端) - win_ = platform::BackendFactory::createWindow(cfg_.backend); + win_ = makeUnique(); if (!win_) { - E2D_LOG_ERROR("创建窗口后端失败: {}", cfg_.backend); + E2D_LOG_ERROR("创建窗口失败"); return false; } diff --git a/xmake.lua b/xmake.lua index 0f41b56..fde65cc 100644 --- a/xmake.lua +++ b/xmake.lua @@ -8,7 +8,8 @@ -- - macOS -- - Nintendo Switch -- --- 窗口后端: SDL2 / GLFW +-- 窗口后端: GLFW +-- 渲染后端: OpenGL -- ============================================== -- 项目元信息 @@ -33,20 +34,6 @@ option("debug_logs") set_description("Enable debug logging") option_end() -option("window_backend") - set_default("sdl2") - set_showmenu(true) - set_description("Window backend: sdl2 or glfw") - set_values("sdl2", "glfw") -option_end() - -option("render_backend") - set_default("opengl") - set_showmenu(true) - set_description("Render backend: opengl or vulkan") - set_values("opengl", "vulkan") -option_end() - -- ============================================== -- 平台检测与配置 -- ============================================== @@ -99,25 +86,7 @@ end if target_plat ~= "switch" then add_requires("glm") add_requires("nlohmann_json") - - -- 窗口后端依赖 - local backend = get_config("window_backend") or "sdl2" - if backend == "glfw" then - add_requires("glfw") - else - local sdl2_configs = { - configs = { - wayland = false - } - } - if target_plat == "linux" then - local is_wayland = os.getenv("XDG_SESSION_TYPE") == "wayland" - if is_wayland then - sdl2_configs.configs.wayland = true - end - end - add_requires("libsdl2", sdl2_configs) - end + add_requires("glfw") end @@ -171,30 +140,14 @@ target("demo_basic") -- 平台配置 local plat = get_config("plat") or os.host() - local backend = get_config("window_backend") or "sdl2" if plat == "mingw" or plat == "windows" then - add_packages("glm", "nlohmann_json") - if backend == "glfw" then - add_packages("glfw") - else - add_packages("libsdl2") - end + add_packages("glm", "nlohmann_json", "glfw") add_syslinks("opengl32", "glu32", "winmm", "imm32", "version", "setupapi") elseif plat == "linux" then - add_packages("glm", "nlohmann_json") - if backend == "glfw" then - add_packages("glfw") - else - add_packages("libsdl2") - end + add_packages("glm", "nlohmann_json", "glfw") add_syslinks("GL", "dl", "pthread") elseif plat == "macosx" then - add_packages("glm", "nlohmann_json") - if backend == "glfw" then - add_packages("glfw") - else - add_packages("libsdl2") - end + add_packages("glm", "nlohmann_json", "glfw") add_frameworks("OpenGL", "Cocoa", "IOKit", "CoreVideo") end @@ -212,30 +165,14 @@ target("demo_text_rendering") -- 平台配置 local plat = get_config("plat") or os.host() - local backend = get_config("window_backend") or "sdl2" if plat == "mingw" or plat == "windows" then - add_packages("glm", "nlohmann_json") - if backend == "glfw" then - add_packages("glfw") - else - add_packages("libsdl2") - end + add_packages("glm", "nlohmann_json", "glfw") add_syslinks("opengl32", "glu32", "winmm", "imm32", "version", "setupapi") elseif plat == "linux" then - add_packages("glm", "nlohmann_json") - if backend == "glfw" then - add_packages("glfw") - else - add_packages("libsdl2") - end + add_packages("glm", "nlohmann_json", "glfw") add_syslinks("GL", "dl", "pthread") elseif plat == "macosx" then - add_packages("glm", "nlohmann_json") - if backend == "glfw" then - add_packages("glfw") - else - add_packages("libsdl2") - end + add_packages("glm", "nlohmann_json", "glfw") add_frameworks("OpenGL", "Cocoa", "IOKit", "CoreVideo") end @@ -272,30 +209,14 @@ target("demo_hello_module") -- 平台配置 local plat = get_config("plat") or os.host() - local backend = get_config("window_backend") or "sdl2" if plat == "mingw" or plat == "windows" then - add_packages("glm", "nlohmann_json") - if backend == "glfw" then - add_packages("glfw") - else - add_packages("libsdl2") - end + add_packages("glm", "nlohmann_json", "glfw") add_syslinks("opengl32", "glu32", "winmm", "imm32", "version", "setupapi") elseif plat == "linux" then - add_packages("glm", "nlohmann_json") - if backend == "glfw" then - add_packages("glfw") - else - add_packages("libsdl2") - end + add_packages("glm", "nlohmann_json", "glfw") add_syslinks("GL", "dl", "pthread") elseif plat == "macosx" then - add_packages("glm", "nlohmann_json") - if backend == "glfw" then - add_packages("glfw") - else - add_packages("libsdl2") - end + add_packages("glm", "nlohmann_json", "glfw") add_frameworks("OpenGL", "Cocoa", "IOKit", "CoreVideo") end @@ -313,30 +234,14 @@ target("demo_image_display") -- 平台配置 local plat = get_config("plat") or os.host() - local backend = get_config("window_backend") or "sdl2" if plat == "mingw" or plat == "windows" then - add_packages("glm", "nlohmann_json") - if backend == "glfw" then - add_packages("glfw") - else - add_packages("libsdl2") - end + add_packages("glm", "nlohmann_json", "glfw") add_syslinks("opengl32", "glu32", "winmm", "imm32", "version", "setupapi") elseif plat == "linux" then - add_packages("glm", "nlohmann_json") - if backend == "glfw" then - add_packages("glfw") - else - add_packages("libsdl2") - end + add_packages("glm", "nlohmann_json", "glfw") add_syslinks("GL", "dl", "pthread") elseif plat == "macosx" then - add_packages("glm", "nlohmann_json") - if backend == "glfw" then - add_packages("glfw") - else - add_packages("libsdl2") - end + add_packages("glm", "nlohmann_json", "glfw") add_frameworks("OpenGL", "Cocoa", "IOKit", "CoreVideo") end diff --git a/xmake/engine.lua b/xmake/engine.lua index 3b692c3..1c59e3d 100644 --- a/xmake/engine.lua +++ b/xmake/engine.lua @@ -2,11 +2,8 @@ -- Extra2D 引擎库共享配置 -- 被主项目和示例共享使用 -- --- 窗口后端支持 SDL2 和 GLFW: --- - Windows (MinGW) - 支持 SDL2 和 GLFW --- - Linux - 支持 SDL2 和 GLFW --- - macOS - 支持 SDL2 和 GLFW --- - Nintendo Switch - 使用系统提供的后端 +-- 窗口后端: GLFW +-- 渲染后端: OpenGL -- ============================================== -- 获取当前平台 @@ -14,16 +11,6 @@ local function get_current_plat() return get_config("plat") or os.host() end --- 获取窗口后端 -local function get_window_backend() - return get_config("window_backend") or "sdl2" -end - --- 获取渲染后端 -local function get_render_backend() - return get_config("render_backend") or "opengl" -end - -- 定义 Extra2D 引擎库目标 function define_extra2d_engine() target("extra2d") @@ -32,28 +19,12 @@ function define_extra2d_engine() -- 引擎核心源文件(后端无关) add_files("Extra2D/src/**.cpp|platform/backends/**.cpp|graphics/backends/**.cpp") - -- 渲染后端源文件 - local render_backend = get_render_backend() - -- 图形后端工厂(始终编译) - add_files("Extra2D/src/graphics/backends/backend_factory.cpp") - if render_backend == "vulkan" then - add_files("Extra2D/src/graphics/backends/vulkan/*.cpp") - add_defines("E2D_BACKEND_VULKAN") - else - add_files("Extra2D/src/graphics/backends/opengl/*.cpp") - add_files("Extra2D/src/glad/glad.c") - add_defines("E2D_BACKEND_OPENGL") - end + -- OpenGL 渲染后端源文件 + add_files("Extra2D/src/graphics/backends/opengl/*.cpp") + add_files("Extra2D/src/glad/glad.c") - -- 窗口后端源文件 - local backend = get_window_backend() - if backend == "glfw" then - add_files("Extra2D/src/platform/backends/glfw/*.cpp") - add_defines("E2D_BACKEND_GLFW") - else - add_files("Extra2D/src/platform/backends/sdl2/*.cpp") - add_defines("E2D_BACKEND_SDL2") - end + -- GLFW 窗口后端源文件 + add_files("Extra2D/src/platform/backends/glfw/*.cpp") -- 头文件路径 add_includedirs("Extra2D/include", {public = true}) @@ -68,47 +39,21 @@ function define_extra2d_engine() add_includedirs(devkitPro .. "/portlibs/switch/include", {public = true}) add_linkdirs(devkitPro .. "/portlibs/switch/lib") - -- Switch 平台根据后端选择链接库 - local backend = get_window_backend() - if backend == "glfw" then - -- GLFW 后端(使用 libnx 提供的 GLFW) - add_syslinks("glfw", "GLESv2", "EGL", "glapi", "drm_nouveau", "nx", "m", - {public = true}) - else - -- SDL2 后端 - add_syslinks("SDL2", "GLESv2", "EGL", "glapi", "drm_nouveau", "nx", "m", - {public = true}) - end + -- GLFW 后端 + add_syslinks("glfw", "GLESv2", "EGL", "glapi", "drm_nouveau", "nx", "m", + {public = true}) elseif plat == "mingw" or plat == "windows" then -- Windows (MinGW) 平台配置 - add_packages("glm", "nlohmann_json", {public = true}) - local backend = get_window_backend() - if backend == "glfw" then - add_packages("glfw", {public = true}) - else - add_packages("libsdl2", {public = true}) - end + add_packages("glm", "nlohmann_json", "glfw", {public = true}) add_syslinks("opengl32", "glu32", "winmm", "imm32", "version", "setupapi", {public = true}) elseif plat == "linux" then -- Linux 平台配置 - add_packages("glm", "nlohmann_json", {public = true}) - local backend = get_window_backend() - if backend == "glfw" then - add_packages("glfw", {public = true}) - else - add_packages("libsdl2", {public = true}) - end + add_packages("glm", "nlohmann_json", "glfw", {public = true}) add_syslinks("GL", "dl", "pthread", {public = true}) elseif plat == "macosx" then -- macOS 平台配置 - add_packages("glm", "nlohmann_json", {public = true}) - local backend = get_window_backend() - if backend == "glfw" then - add_packages("glfw", {public = true}) - else - add_packages("libsdl2", {public = true}) - end + add_packages("glm", "nlohmann_json", "glfw", {public = true}) add_frameworks("OpenGL", "Cocoa", "IOKit", "CoreVideo", {public = true}) end