2026-02-28 23:35:34 +08:00
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
|
|
#include <SDL.h>
|
|
|
|
|
|
#include <config/app_config.h>
|
|
|
|
|
|
#include <config/window_config.h>
|
2026-03-01 00:01:48 +08:00
|
|
|
|
#include <event/events.h>
|
2026-02-28 23:35:34 +08:00
|
|
|
|
#include <functional>
|
2026-03-01 00:01:48 +08:00
|
|
|
|
#include <memory>
|
2026-02-28 23:35:34 +08:00
|
|
|
|
#include <module/module.h>
|
|
|
|
|
|
#include <module/module_registry.h>
|
|
|
|
|
|
#include <types/math/size.h>
|
|
|
|
|
|
#include <types/math/vec2.h>
|
|
|
|
|
|
|
|
|
|
|
|
namespace extra2d {
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 窗口事件回调
|
|
|
|
|
|
*/
|
|
|
|
|
|
using ResizeCb = std::function<void(int32 w, int32 h)>;
|
|
|
|
|
|
using CloseCb = std::function<void()>;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2026-03-01 03:48:51 +08:00
|
|
|
|
* @brief 窗口模块 - OpenGL ES 3.2 版本
|
2026-02-28 23:35:34 +08:00
|
|
|
|
*
|
2026-03-01 03:48:51 +08:00
|
|
|
|
* 管理 SDL2 窗口,支持 OpenGL ES 3.2 渲染
|
2026-02-28 23:35:34 +08:00
|
|
|
|
* 使用新的 Module 基类,支持自动注册
|
|
|
|
|
|
*/
|
|
|
|
|
|
class WindowModule : public Module {
|
|
|
|
|
|
// 自动注册到模块系统,优先级为 0(最先初始化)
|
|
|
|
|
|
E2D_REGISTER_MODULE(WindowModule, "Window", 0)
|
|
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
WindowModule();
|
|
|
|
|
|
~WindowModule() override;
|
|
|
|
|
|
|
|
|
|
|
|
// 禁止拷贝
|
|
|
|
|
|
WindowModule(const WindowModule &) = delete;
|
|
|
|
|
|
WindowModule &operator=(const WindowModule &) = delete;
|
|
|
|
|
|
|
|
|
|
|
|
// 允许移动
|
|
|
|
|
|
WindowModule(WindowModule &&) noexcept;
|
|
|
|
|
|
WindowModule &operator=(WindowModule &&) noexcept;
|
|
|
|
|
|
|
|
|
|
|
|
// Module 接口实现
|
|
|
|
|
|
bool init() override;
|
|
|
|
|
|
void shutdown() override;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 使用配置创建窗口
|
|
|
|
|
|
*/
|
|
|
|
|
|
bool create(const WindowCfg &cfg);
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 处理窗口事件
|
|
|
|
|
|
* @return true 继续运行,false 应退出
|
|
|
|
|
|
*/
|
|
|
|
|
|
bool pollEvents();
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 获取 SDL 窗口句柄
|
|
|
|
|
|
*/
|
|
|
|
|
|
SDL_Window *handle() const { return window_; }
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 获取窗口尺寸
|
|
|
|
|
|
*/
|
|
|
|
|
|
Size getSize() const;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 获取窗口位置
|
|
|
|
|
|
*/
|
|
|
|
|
|
Vec2 getPosition() const;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 设置窗口尺寸
|
|
|
|
|
|
*/
|
|
|
|
|
|
void setSize(int32 w, int32 h);
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 设置窗口标题
|
|
|
|
|
|
*/
|
|
|
|
|
|
void setTitle(const std::string &title);
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 设置全屏模式
|
|
|
|
|
|
*/
|
|
|
|
|
|
void setFullscreen(bool fullscreen);
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 检查是否全屏
|
|
|
|
|
|
*/
|
|
|
|
|
|
bool isFullscreen() const;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 显示/隐藏窗口
|
|
|
|
|
|
*/
|
|
|
|
|
|
void setVisible(bool visible);
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 检查窗口是否可见
|
|
|
|
|
|
*/
|
|
|
|
|
|
bool isVisible() const;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 设置窗口关闭回调
|
|
|
|
|
|
*/
|
|
|
|
|
|
void setOnClose(CloseCb cb) { onClose_ = std::move(cb); }
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 设置窗口大小改变回调
|
|
|
|
|
|
*/
|
|
|
|
|
|
void setOnResize(ResizeCb cb) { onResize_ = std::move(cb); }
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 请求关闭窗口
|
|
|
|
|
|
*/
|
|
|
|
|
|
void requestClose() { shouldClose_ = true; }
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 检查是否应该关闭
|
|
|
|
|
|
*/
|
|
|
|
|
|
bool shouldClose() const { return shouldClose_; }
|
|
|
|
|
|
|
2026-03-01 00:01:48 +08:00
|
|
|
|
/**
|
2026-03-01 03:48:51 +08:00
|
|
|
|
* @brief 创建 OpenGL ES 上下文
|
|
|
|
|
|
* @return 是否成功
|
2026-03-01 00:01:48 +08:00
|
|
|
|
*/
|
2026-03-01 03:48:51 +08:00
|
|
|
|
bool createGLContext();
|
2026-03-01 00:01:48 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
2026-03-01 03:48:51 +08:00
|
|
|
|
* @brief 销毁 OpenGL ES 上下文
|
|
|
|
|
|
*/
|
|
|
|
|
|
void destroyGLContext();
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 交换缓冲区(呈现渲染结果)
|
|
|
|
|
|
*/
|
|
|
|
|
|
void swapBuffers();
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 获取 OpenGL ES 上下文句柄
|
|
|
|
|
|
* @return SDL_GLContext 句柄
|
2026-03-01 00:01:48 +08:00
|
|
|
|
*/
|
2026-03-01 03:48:51 +08:00
|
|
|
|
void* getGLContext() const;
|
2026-03-01 00:01:48 +08:00
|
|
|
|
|
2026-02-28 23:35:34 +08:00
|
|
|
|
private:
|
|
|
|
|
|
void handleWindowEvent(const SDL_WindowEvent &evt);
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 监听模块配置事件
|
2026-03-01 00:01:48 +08:00
|
|
|
|
* @param config 应用配置对象
|
2026-02-28 23:35:34 +08:00
|
|
|
|
*
|
2026-03-01 00:01:48 +08:00
|
|
|
|
* 处理 AppConfig 类型的配置,创建窗口
|
|
|
|
|
|
*/
|
|
|
|
|
|
void onModuleConfig(const AppConfig &config);
|
2026-02-28 23:35:34 +08:00
|
|
|
|
|
2026-03-02 04:50:28 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 监听渲染呈现事件
|
|
|
|
|
|
*
|
|
|
|
|
|
* 当渲染完成时调用 swapBuffers 呈现渲染结果
|
|
|
|
|
|
*/
|
|
|
|
|
|
void onRenderPresent();
|
|
|
|
|
|
|
2026-02-28 23:35:34 +08:00
|
|
|
|
SDL_Window *window_ = nullptr;
|
2026-03-01 03:48:51 +08:00
|
|
|
|
SDL_GLContext glContext_ = nullptr;
|
2026-02-28 23:35:34 +08:00
|
|
|
|
bool shouldClose_ = false;
|
|
|
|
|
|
|
|
|
|
|
|
CloseCb onClose_;
|
|
|
|
|
|
ResizeCb onResize_;
|
2026-03-01 00:01:48 +08:00
|
|
|
|
|
|
|
|
|
|
// 模块配置事件监听器
|
|
|
|
|
|
std::unique_ptr<events::OnModuleConfig<AppConfig>::Listener> configListener_;
|
2026-03-02 04:50:28 +08:00
|
|
|
|
|
|
|
|
|
|
// 渲染呈现事件监听器
|
|
|
|
|
|
std::unique_ptr<events::OnRenderPresent::Listener> renderPresentListener_;
|
2026-02-28 23:35:34 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
} // namespace extra2d
|