feat: 添加SDL2后端支持并实现基础示例程序
添加SDL2作为平台后端支持,包括窗口创建、输入处理和GLAD初始化 实现基础示例程序展示引擎基本功能 重构平台配置代码以提高可读性 移除未使用的input_codes.h头文件 添加demo_basic构建目标到xmake配置
This commit is contained in:
parent
34fe0bafcb
commit
38148a6c54
|
|
@ -48,7 +48,6 @@
|
||||||
#include <extra2d/event/event.h>
|
#include <extra2d/event/event.h>
|
||||||
#include <extra2d/event/event_dispatcher.h>
|
#include <extra2d/event/event_dispatcher.h>
|
||||||
#include <extra2d/event/event_queue.h>
|
#include <extra2d/event/event_queue.h>
|
||||||
#include <extra2d/event/input_codes.h>
|
|
||||||
|
|
||||||
// Utils
|
// Utils
|
||||||
#include <extra2d/utils/logger.h>
|
#include <extra2d/utils/logger.h>
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,7 @@ private:
|
||||||
*/
|
*/
|
||||||
#define E2D_REG_BACKEND(name, WinClass, InClass) \
|
#define E2D_REG_BACKEND(name, WinClass, InClass) \
|
||||||
namespace { \
|
namespace { \
|
||||||
|
__attribute__((used)) \
|
||||||
static struct E2D_BACKEND_REG_##name { \
|
static struct E2D_BACKEND_REG_##name { \
|
||||||
E2D_BACKEND_REG_##name() { \
|
E2D_BACKEND_REG_##name() { \
|
||||||
::extra2d::BackendFactory::reg( \
|
::extra2d::BackendFactory::reg( \
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,18 @@
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
|
#include <SDL.h>
|
||||||
|
|
||||||
#ifdef __SWITCH__
|
#ifdef __SWITCH__
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef E2D_BACKEND_SDL2
|
||||||
|
namespace extra2d {
|
||||||
|
void initSDL2Backend();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace extra2d {
|
namespace extra2d {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -56,10 +64,16 @@ bool Application::init() {
|
||||||
|
|
||||||
bool Application::init(const AppConfig& config) {
|
bool Application::init(const AppConfig& config) {
|
||||||
if (initialized_) {
|
if (initialized_) {
|
||||||
E2D_LOG_WARN("Application already initialized");
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS | SDL_INIT_TIMER) != 0) {
|
||||||
|
E2D_LOG_ERROR("Failed to initialize SDL: {}", SDL_GetError());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger::init();
|
||||||
|
|
||||||
E2D_LOG_INFO("Initializing application with config...");
|
E2D_LOG_INFO("Initializing application with config...");
|
||||||
|
|
||||||
if (!ConfigManager::instance().initialize()) {
|
if (!ConfigManager::instance().initialize()) {
|
||||||
|
|
@ -92,6 +106,10 @@ bool Application::init(const std::string& configPath) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Application::initImpl() {
|
bool Application::initImpl() {
|
||||||
|
#ifdef E2D_BACKEND_SDL2
|
||||||
|
initSDL2Backend();
|
||||||
|
#endif
|
||||||
|
|
||||||
auto& configMgr = ConfigManager::instance();
|
auto& configMgr = ConfigManager::instance();
|
||||||
AppConfig& appConfig = configMgr.appConfig();
|
AppConfig& appConfig = configMgr.appConfig();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
#include <extra2d/config/platform_config.h>
|
|
||||||
#include <extra2d/config/app_config.h>
|
#include <extra2d/config/app_config.h>
|
||||||
|
#include <extra2d/config/platform_config.h>
|
||||||
#include <extra2d/utils/logger.h>
|
#include <extra2d/utils/logger.h>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
@ -16,320 +16,328 @@ namespace {
|
||||||
|
|
||||||
class WindowsPlatformConfig : public PlatformConfig {
|
class WindowsPlatformConfig : public PlatformConfig {
|
||||||
public:
|
public:
|
||||||
WindowsPlatformConfig() {
|
WindowsPlatformConfig() {
|
||||||
caps_.supportsWindowed = true;
|
caps_.supportsWindowed = true;
|
||||||
caps_.supportsFullscreen = true;
|
caps_.supportsFullscreen = true;
|
||||||
caps_.supportsBorderless = true;
|
caps_.supportsBorderless = true;
|
||||||
caps_.supportsCursor = true;
|
caps_.supportsCursor = true;
|
||||||
caps_.supportsCursorHide = true;
|
caps_.supportsCursorHide = true;
|
||||||
caps_.supportsDPIAwareness = true;
|
caps_.supportsDPIAwareness = true;
|
||||||
caps_.supportsVSync = true;
|
caps_.supportsVSync = true;
|
||||||
caps_.supportsMultiMonitor = true;
|
caps_.supportsMultiMonitor = true;
|
||||||
caps_.supportsClipboard = true;
|
caps_.supportsClipboard = true;
|
||||||
caps_.supportsGamepad = true;
|
caps_.supportsGamepad = true;
|
||||||
caps_.supportsTouch = false;
|
caps_.supportsTouch = false;
|
||||||
caps_.supportsKeyboard = true;
|
caps_.supportsKeyboard = true;
|
||||||
caps_.supportsMouse = true;
|
caps_.supportsMouse = true;
|
||||||
caps_.supportsResize = true;
|
caps_.supportsResize = true;
|
||||||
caps_.supportsHighDPI = true;
|
caps_.supportsHighDPI = true;
|
||||||
caps_.maxTextureSize = 16384;
|
caps_.maxTextureSize = 16384;
|
||||||
caps_.preferredScreenWidth = 1920;
|
caps_.preferredScreenWidth = 1920;
|
||||||
caps_.preferredScreenHeight = 1080;
|
caps_.preferredScreenHeight = 1080;
|
||||||
caps_.defaultDPI = 96.0f;
|
caps_.defaultDPI = 96.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
PlatformType platformType() const override { return PlatformType::Windows; }
|
PlatformType platformType() const override { return PlatformType::Windows; }
|
||||||
const char* platformName() const override { return "Windows"; }
|
const char *platformName() const override { return "Windows"; }
|
||||||
const PlatformCapabilities& capabilities() const override { return caps_; }
|
const PlatformCapabilities &capabilities() const override { return caps_; }
|
||||||
|
|
||||||
void applyConstraints(AppConfig& config) const override {
|
void applyConstraints(AppConfig &config) const override {
|
||||||
if (config.window.width < 320) config.window.width = 320;
|
if (config.window.width < 320)
|
||||||
if (config.window.height < 240) config.window.height = 240;
|
config.window.width = 320;
|
||||||
if (config.window.width > caps_.maxTextureSize) config.window.width = caps_.maxTextureSize;
|
if (config.window.height < 240)
|
||||||
if (config.window.height > caps_.maxTextureSize) config.window.height = caps_.maxTextureSize;
|
config.window.height = 240;
|
||||||
}
|
if (config.window.width > caps_.maxTextureSize)
|
||||||
|
config.window.width = caps_.maxTextureSize;
|
||||||
|
if (config.window.height > caps_.maxTextureSize)
|
||||||
|
config.window.height = caps_.maxTextureSize;
|
||||||
|
}
|
||||||
|
|
||||||
void applyDefaults(AppConfig& config) const override {
|
void applyDefaults(AppConfig &config) const override {
|
||||||
config.window.highDPI = true;
|
config.window.highDPI = true;
|
||||||
config.window.resizable = true;
|
config.window.resizable = true;
|
||||||
config.render.vsync = true;
|
config.render.vsync = true;
|
||||||
config.render.targetFPS = 60;
|
config.render.targetFPS = 60;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool validateConfig(AppConfig& config) const override {
|
bool validateConfig(AppConfig &config) const override {
|
||||||
if (config.window.width <= 0 || config.window.height <= 0) {
|
if (config.window.width <= 0 || config.window.height <= 0) {
|
||||||
E2D_LOG_ERROR("Windows: Invalid window dimensions");
|
E2D_LOG_ERROR("Windows: Invalid window dimensions");
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int getRecommendedWidth() const override { return 1920; }
|
int getRecommendedWidth() const override { return 1920; }
|
||||||
int getRecommendedHeight() const override { return 1080; }
|
int getRecommendedHeight() const override { return 1080; }
|
||||||
bool isResolutionSupported(int width, int height) const override {
|
bool isResolutionSupported(int width, int height) const override {
|
||||||
return width >= 320 && height >= 240 &&
|
return width >= 320 && height >= 240 && width <= caps_.maxTextureSize &&
|
||||||
width <= caps_.maxTextureSize && height <= caps_.maxTextureSize;
|
height <= caps_.maxTextureSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PlatformCapabilities caps_;
|
PlatformCapabilities caps_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class LinuxPlatformConfig : public PlatformConfig {
|
class LinuxPlatformConfig : public PlatformConfig {
|
||||||
public:
|
public:
|
||||||
LinuxPlatformConfig() {
|
LinuxPlatformConfig() {
|
||||||
caps_.supportsWindowed = true;
|
caps_.supportsWindowed = true;
|
||||||
caps_.supportsFullscreen = true;
|
caps_.supportsFullscreen = true;
|
||||||
caps_.supportsBorderless = true;
|
caps_.supportsBorderless = true;
|
||||||
caps_.supportsCursor = true;
|
caps_.supportsCursor = true;
|
||||||
caps_.supportsCursorHide = true;
|
caps_.supportsCursorHide = true;
|
||||||
caps_.supportsDPIAwareness = true;
|
caps_.supportsDPIAwareness = true;
|
||||||
caps_.supportsVSync = true;
|
caps_.supportsVSync = true;
|
||||||
caps_.supportsMultiMonitor = true;
|
caps_.supportsMultiMonitor = true;
|
||||||
caps_.supportsClipboard = true;
|
caps_.supportsClipboard = true;
|
||||||
caps_.supportsGamepad = true;
|
caps_.supportsGamepad = true;
|
||||||
caps_.supportsTouch = false;
|
caps_.supportsTouch = false;
|
||||||
caps_.supportsKeyboard = true;
|
caps_.supportsKeyboard = true;
|
||||||
caps_.supportsMouse = true;
|
caps_.supportsMouse = true;
|
||||||
caps_.supportsResize = true;
|
caps_.supportsResize = true;
|
||||||
caps_.supportsHighDPI = true;
|
caps_.supportsHighDPI = true;
|
||||||
caps_.maxTextureSize = 16384;
|
caps_.maxTextureSize = 16384;
|
||||||
caps_.preferredScreenWidth = 1920;
|
caps_.preferredScreenWidth = 1920;
|
||||||
caps_.preferredScreenHeight = 1080;
|
caps_.preferredScreenHeight = 1080;
|
||||||
caps_.defaultDPI = 96.0f;
|
caps_.defaultDPI = 96.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
PlatformType platformType() const override { return PlatformType::Linux; }
|
PlatformType platformType() const override { return PlatformType::Linux; }
|
||||||
const char* platformName() const override { return "Linux"; }
|
const char *platformName() const override { return "Linux"; }
|
||||||
const PlatformCapabilities& capabilities() const override { return caps_; }
|
const PlatformCapabilities &capabilities() const override { return caps_; }
|
||||||
|
|
||||||
void applyConstraints(AppConfig& config) const override {
|
void applyConstraints(AppConfig &config) const override {
|
||||||
if (config.window.width < 320) config.window.width = 320;
|
if (config.window.width < 320)
|
||||||
if (config.window.height < 240) config.window.height = 240;
|
config.window.width = 320;
|
||||||
}
|
if (config.window.height < 240)
|
||||||
|
config.window.height = 240;
|
||||||
|
}
|
||||||
|
|
||||||
void applyDefaults(AppConfig& config) const override {
|
void applyDefaults(AppConfig &config) const override {
|
||||||
config.window.resizable = true;
|
config.window.resizable = true;
|
||||||
config.render.vsync = true;
|
config.render.vsync = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool validateConfig(AppConfig& config) const override {
|
bool validateConfig(AppConfig &config) const override {
|
||||||
if (config.window.width <= 0 || config.window.height <= 0) {
|
if (config.window.width <= 0 || config.window.height <= 0) {
|
||||||
E2D_LOG_ERROR("Linux: Invalid window dimensions");
|
E2D_LOG_ERROR("Linux: Invalid window dimensions");
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int getRecommendedWidth() const override { return 1920; }
|
int getRecommendedWidth() const override { return 1920; }
|
||||||
int getRecommendedHeight() const override { return 1080; }
|
int getRecommendedHeight() const override { return 1080; }
|
||||||
bool isResolutionSupported(int width, int height) const override {
|
bool isResolutionSupported(int width, int height) const override {
|
||||||
return width >= 320 && height >= 240;
|
return width >= 320 && height >= 240;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PlatformCapabilities caps_;
|
PlatformCapabilities caps_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MacOSPlatformConfig : public PlatformConfig {
|
class MacOSPlatformConfig : public PlatformConfig {
|
||||||
public:
|
public:
|
||||||
MacOSPlatformConfig() {
|
MacOSPlatformConfig() {
|
||||||
caps_.supportsWindowed = true;
|
caps_.supportsWindowed = true;
|
||||||
caps_.supportsFullscreen = true;
|
caps_.supportsFullscreen = true;
|
||||||
caps_.supportsBorderless = true;
|
caps_.supportsBorderless = true;
|
||||||
caps_.supportsCursor = true;
|
caps_.supportsCursor = true;
|
||||||
caps_.supportsCursorHide = true;
|
caps_.supportsCursorHide = true;
|
||||||
caps_.supportsDPIAwareness = true;
|
caps_.supportsDPIAwareness = true;
|
||||||
caps_.supportsVSync = true;
|
caps_.supportsVSync = true;
|
||||||
caps_.supportsMultiMonitor = true;
|
caps_.supportsMultiMonitor = true;
|
||||||
caps_.supportsClipboard = true;
|
caps_.supportsClipboard = true;
|
||||||
caps_.supportsGamepad = true;
|
caps_.supportsGamepad = true;
|
||||||
caps_.supportsTouch = false;
|
caps_.supportsTouch = false;
|
||||||
caps_.supportsKeyboard = true;
|
caps_.supportsKeyboard = true;
|
||||||
caps_.supportsMouse = true;
|
caps_.supportsMouse = true;
|
||||||
caps_.supportsResize = true;
|
caps_.supportsResize = true;
|
||||||
caps_.supportsHighDPI = true;
|
caps_.supportsHighDPI = true;
|
||||||
caps_.maxTextureSize = 16384;
|
caps_.maxTextureSize = 16384;
|
||||||
caps_.preferredScreenWidth = 1920;
|
caps_.preferredScreenWidth = 1920;
|
||||||
caps_.preferredScreenHeight = 1080;
|
caps_.preferredScreenHeight = 1080;
|
||||||
caps_.defaultDPI = 144.0f;
|
caps_.defaultDPI = 144.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
PlatformType platformType() const override { return PlatformType::macOS; }
|
PlatformType platformType() const override { return PlatformType::macOS; }
|
||||||
const char* platformName() const override { return "macOS"; }
|
const char *platformName() const override { return "macOS"; }
|
||||||
const PlatformCapabilities& capabilities() const override { return caps_; }
|
const PlatformCapabilities &capabilities() const override { return caps_; }
|
||||||
|
|
||||||
void applyConstraints(AppConfig& config) const override {
|
void applyConstraints(AppConfig &config) const override {
|
||||||
if (config.window.width < 320) config.window.width = 320;
|
if (config.window.width < 320)
|
||||||
if (config.window.height < 240) config.window.height = 240;
|
config.window.width = 320;
|
||||||
}
|
if (config.window.height < 240)
|
||||||
|
config.window.height = 240;
|
||||||
|
}
|
||||||
|
|
||||||
void applyDefaults(AppConfig& config) const override {
|
void applyDefaults(AppConfig &config) const override {
|
||||||
config.window.highDPI = true;
|
config.window.highDPI = true;
|
||||||
config.window.resizable = true;
|
config.window.resizable = true;
|
||||||
config.render.vsync = true;
|
config.render.vsync = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool validateConfig(AppConfig& config) const override {
|
bool validateConfig(AppConfig &config) const override {
|
||||||
if (config.window.width <= 0 || config.window.height <= 0) {
|
if (config.window.width <= 0 || config.window.height <= 0) {
|
||||||
E2D_LOG_ERROR("macOS: Invalid window dimensions");
|
E2D_LOG_ERROR("macOS: Invalid window dimensions");
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int getRecommendedWidth() const override { return 1920; }
|
int getRecommendedWidth() const override { return 1920; }
|
||||||
int getRecommendedHeight() const override { return 1080; }
|
int getRecommendedHeight() const override { return 1080; }
|
||||||
bool isResolutionSupported(int width, int height) const override {
|
bool isResolutionSupported(int width, int height) const override {
|
||||||
return width >= 320 && height >= 240;
|
return width >= 320 && height >= 240;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PlatformCapabilities caps_;
|
PlatformCapabilities caps_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __SWITCH__
|
#ifdef __SWITCH__
|
||||||
class SwitchPlatformConfig : public PlatformConfig {
|
class SwitchPlatformConfig : public PlatformConfig {
|
||||||
public:
|
public:
|
||||||
SwitchPlatformConfig() {
|
SwitchPlatformConfig() {
|
||||||
caps_.supportsWindowed = false;
|
caps_.supportsWindowed = false;
|
||||||
caps_.supportsFullscreen = true;
|
caps_.supportsFullscreen = true;
|
||||||
caps_.supportsBorderless = false;
|
caps_.supportsBorderless = false;
|
||||||
caps_.supportsCursor = false;
|
caps_.supportsCursor = false;
|
||||||
caps_.supportsCursorHide = false;
|
caps_.supportsCursorHide = false;
|
||||||
caps_.supportsDPIAwareness = false;
|
caps_.supportsDPIAwareness = false;
|
||||||
caps_.supportsVSync = true;
|
caps_.supportsVSync = true;
|
||||||
caps_.supportsMultiMonitor = false;
|
caps_.supportsMultiMonitor = false;
|
||||||
caps_.supportsClipboard = false;
|
caps_.supportsClipboard = false;
|
||||||
caps_.supportsGamepad = true;
|
caps_.supportsGamepad = true;
|
||||||
caps_.supportsTouch = true;
|
caps_.supportsTouch = true;
|
||||||
caps_.supportsKeyboard = false;
|
caps_.supportsKeyboard = false;
|
||||||
caps_.supportsMouse = false;
|
caps_.supportsMouse = false;
|
||||||
caps_.supportsResize = false;
|
caps_.supportsResize = false;
|
||||||
caps_.supportsHighDPI = false;
|
caps_.supportsHighDPI = false;
|
||||||
caps_.maxTextureSize = 8192;
|
caps_.maxTextureSize = 8192;
|
||||||
caps_.preferredScreenWidth = 1920;
|
caps_.preferredScreenWidth = 1920;
|
||||||
caps_.preferredScreenHeight = 1080;
|
caps_.preferredScreenHeight = 1080;
|
||||||
caps_.defaultDPI = 96.0f;
|
caps_.defaultDPI = 96.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
PlatformType platformType() const override { return PlatformType::Switch; }
|
PlatformType platformType() const override { return PlatformType::Switch; }
|
||||||
const char* platformName() const override { return "Nintendo Switch"; }
|
const char *platformName() const override { return "Nintendo Switch"; }
|
||||||
const PlatformCapabilities& capabilities() const override { return caps_; }
|
const PlatformCapabilities &capabilities() const override { return caps_; }
|
||||||
|
|
||||||
void applyConstraints(AppConfig& config) const override {
|
void applyConstraints(AppConfig &config) const override {
|
||||||
config.window.width = 1920;
|
config.window.width = 1920;
|
||||||
config.window.height = 1080;
|
config.window.height = 1080;
|
||||||
config.window.mode = WindowMode::Fullscreen;
|
config.window.mode = WindowMode::Fullscreen;
|
||||||
config.window.resizable = false;
|
config.window.resizable = false;
|
||||||
config.window.borderless = false;
|
config.window.borderless = false;
|
||||||
config.window.highDPI = false;
|
config.window.highDPI = false;
|
||||||
config.render.vsync = true;
|
config.render.vsync = true;
|
||||||
config.render.targetFPS = 60;
|
config.render.targetFPS = 60;
|
||||||
config.input.enableVibration = true;
|
config.input.enableVibration = true;
|
||||||
config.input.maxGamepads = 2;
|
config.input.maxGamepads = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
void applyDefaults(AppConfig& config) const override {
|
void applyDefaults(AppConfig &config) const override {
|
||||||
config.window.width = 1920;
|
config.window.width = 1920;
|
||||||
config.window.height = 1080;
|
config.window.height = 1080;
|
||||||
config.window.mode = WindowMode::Fullscreen;
|
config.window.mode = WindowMode::Fullscreen;
|
||||||
config.window.resizable = false;
|
config.window.resizable = false;
|
||||||
config.render.vsync = true;
|
config.render.vsync = true;
|
||||||
config.render.targetFPS = 60;
|
config.render.targetFPS = 60;
|
||||||
config.input.enableVibration = true;
|
config.input.enableVibration = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool validateConfig(AppConfig& config) const override {
|
bool validateConfig(AppConfig &config) const override {
|
||||||
if (config.window.mode != WindowMode::Fullscreen) {
|
if (config.window.mode != WindowMode::Fullscreen) {
|
||||||
E2D_LOG_WARN("Switch: Only fullscreen mode is supported");
|
E2D_LOG_WARN("Switch: Only fullscreen mode is supported");
|
||||||
config.window.mode = WindowMode::Fullscreen;
|
config.window.mode = WindowMode::Fullscreen;
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int getRecommendedWidth() const override { return 1920; }
|
int getRecommendedWidth() const override { return 1920; }
|
||||||
int getRecommendedHeight() const override { return 1080; }
|
int getRecommendedHeight() const override { return 1080; }
|
||||||
bool isResolutionSupported(int width, int height) const override {
|
bool isResolutionSupported(int width, int height) const override {
|
||||||
return (width == 1920 && height == 1080) ||
|
return (width == 1920 && height == 1080) ||
|
||||||
(width == 1280 && height == 720);
|
(width == 1280 && height == 720);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PlatformCapabilities caps_;
|
PlatformCapabilities caps_;
|
||||||
};
|
};
|
||||||
#else
|
#else
|
||||||
class SwitchPlatformConfig : public PlatformConfig {
|
class SwitchPlatformConfig : public PlatformConfig {
|
||||||
public:
|
public:
|
||||||
SwitchPlatformConfig() {
|
SwitchPlatformConfig() {
|
||||||
caps_.supportsWindowed = false;
|
caps_.supportsWindowed = false;
|
||||||
caps_.supportsFullscreen = true;
|
caps_.supportsFullscreen = true;
|
||||||
caps_.supportsBorderless = false;
|
caps_.supportsBorderless = false;
|
||||||
caps_.supportsCursor = false;
|
caps_.supportsCursor = false;
|
||||||
caps_.supportsCursorHide = false;
|
caps_.supportsCursorHide = false;
|
||||||
caps_.supportsDPIAwareness = false;
|
caps_.supportsDPIAwareness = false;
|
||||||
caps_.supportsVSync = true;
|
caps_.supportsVSync = true;
|
||||||
caps_.supportsMultiMonitor = false;
|
caps_.supportsMultiMonitor = false;
|
||||||
caps_.supportsClipboard = false;
|
caps_.supportsClipboard = false;
|
||||||
caps_.supportsGamepad = true;
|
caps_.supportsGamepad = true;
|
||||||
caps_.supportsTouch = true;
|
caps_.supportsTouch = true;
|
||||||
caps_.supportsKeyboard = false;
|
caps_.supportsKeyboard = false;
|
||||||
caps_.supportsMouse = false;
|
caps_.supportsMouse = false;
|
||||||
caps_.supportsResize = false;
|
caps_.supportsResize = false;
|
||||||
caps_.supportsHighDPI = false;
|
caps_.supportsHighDPI = false;
|
||||||
caps_.maxTextureSize = 8192;
|
caps_.maxTextureSize = 8192;
|
||||||
caps_.preferredScreenWidth = 1920;
|
caps_.preferredScreenWidth = 1920;
|
||||||
caps_.preferredScreenHeight = 1080;
|
caps_.preferredScreenHeight = 1080;
|
||||||
caps_.defaultDPI = 96.0f;
|
caps_.defaultDPI = 96.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
PlatformType platformType() const override { return PlatformType::Switch; }
|
PlatformType platformType() const override { return PlatformType::Switch; }
|
||||||
const char* platformName() const override { return "Nintendo Switch"; }
|
const char *platformName() const override { return "Nintendo Switch"; }
|
||||||
const PlatformCapabilities& capabilities() const override { return caps_; }
|
const PlatformCapabilities &capabilities() const override { return caps_; }
|
||||||
|
|
||||||
void applyConstraints(AppConfig& config) const override {
|
void applyConstraints(AppConfig &config) const override {
|
||||||
config.window.width = 1920;
|
config.window.width = 1920;
|
||||||
config.window.height = 1080;
|
config.window.height = 1080;
|
||||||
config.window.mode = WindowMode::Fullscreen;
|
config.window.mode = WindowMode::Fullscreen;
|
||||||
config.window.resizable = false;
|
config.window.resizable = false;
|
||||||
config.window.borderless = false;
|
config.window.borderless = false;
|
||||||
config.window.highDPI = false;
|
config.window.highDPI = false;
|
||||||
config.render.vsync = true;
|
config.render.vsync = true;
|
||||||
config.render.targetFPS = 60;
|
config.render.targetFPS = 60;
|
||||||
config.input.enableVibration = true;
|
config.input.enableVibration = true;
|
||||||
config.input.maxGamepads = 2;
|
config.input.maxGamepads = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
void applyDefaults(AppConfig& config) const override {
|
void applyDefaults(AppConfig &config) const override {
|
||||||
config.window.width = 1920;
|
config.window.width = 1920;
|
||||||
config.window.height = 1080;
|
config.window.height = 1080;
|
||||||
config.window.mode = WindowMode::Fullscreen;
|
config.window.mode = WindowMode::Fullscreen;
|
||||||
config.window.resizable = false;
|
config.window.resizable = false;
|
||||||
config.render.vsync = true;
|
config.render.vsync = true;
|
||||||
config.render.targetFPS = 60;
|
config.render.targetFPS = 60;
|
||||||
config.input.enableVibration = true;
|
config.input.enableVibration = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool validateConfig(AppConfig& config) const override {
|
bool validateConfig(AppConfig &config) const override {
|
||||||
if (config.window.mode != WindowMode::Fullscreen) {
|
if (config.window.mode != WindowMode::Fullscreen) {
|
||||||
E2D_LOG_WARN("Switch: Only fullscreen mode is supported");
|
E2D_LOG_WARN("Switch: Only fullscreen mode is supported");
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int getRecommendedWidth() const override { return 1920; }
|
int getRecommendedWidth() const override { return 1920; }
|
||||||
int getRecommendedHeight() const override { return 1080; }
|
int getRecommendedHeight() const override { return 1080; }
|
||||||
bool isResolutionSupported(int width, int height) const override {
|
bool isResolutionSupported(int width, int height) const override {
|
||||||
return (width == 1920 && height == 1080) ||
|
return (width == 1920 && height == 1080) ||
|
||||||
(width == 1280 && height == 720);
|
(width == 1280 && height == 720);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PlatformCapabilities caps_;
|
PlatformCapabilities caps_;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
} // namespace
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 创建平台配置实例
|
* @brief 创建平台配置实例
|
||||||
|
|
@ -338,37 +346,37 @@ private:
|
||||||
* @return 平台配置的智能指针
|
* @return 平台配置的智能指针
|
||||||
*/
|
*/
|
||||||
UniquePtr<PlatformConfig> createPlatformConfig(PlatformType type) {
|
UniquePtr<PlatformConfig> createPlatformConfig(PlatformType type) {
|
||||||
if (type == PlatformType::Auto) {
|
if (type == PlatformType::Auto) {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
type = PlatformType::Windows;
|
type = PlatformType::Windows;
|
||||||
#elif defined(__SWITCH__)
|
#elif defined(__SWITCH__)
|
||||||
type = PlatformType::Switch;
|
type = PlatformType::Switch;
|
||||||
#elif defined(__linux__)
|
#elif defined(__linux__)
|
||||||
type = PlatformType::Linux;
|
type = PlatformType::Linux;
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
type = PlatformType::macOS;
|
type = PlatformType::macOS;
|
||||||
#else
|
#else
|
||||||
type = PlatformType::Windows;
|
type = PlatformType::Windows;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case PlatformType::Windows:
|
case PlatformType::Windows:
|
||||||
E2D_LOG_INFO("Creating Windows platform config");
|
E2D_LOG_INFO("Creating Windows platform config");
|
||||||
return makeUnique<WindowsPlatformConfig>();
|
return makeUnique<WindowsPlatformConfig>();
|
||||||
case PlatformType::Switch:
|
case PlatformType::Switch:
|
||||||
E2D_LOG_INFO("Creating Nintendo Switch platform config");
|
E2D_LOG_INFO("Creating Nintendo Switch platform config");
|
||||||
return makeUnique<SwitchPlatformConfig>();
|
return makeUnique<SwitchPlatformConfig>();
|
||||||
case PlatformType::Linux:
|
case PlatformType::Linux:
|
||||||
E2D_LOG_INFO("Creating Linux platform config");
|
E2D_LOG_INFO("Creating Linux platform config");
|
||||||
return makeUnique<LinuxPlatformConfig>();
|
return makeUnique<LinuxPlatformConfig>();
|
||||||
case PlatformType::macOS:
|
case PlatformType::macOS:
|
||||||
E2D_LOG_INFO("Creating macOS platform config");
|
E2D_LOG_INFO("Creating macOS platform config");
|
||||||
return makeUnique<MacOSPlatformConfig>();
|
return makeUnique<MacOSPlatformConfig>();
|
||||||
default:
|
default:
|
||||||
E2D_LOG_WARN("Unknown platform type, defaulting to Windows");
|
E2D_LOG_WARN("Unknown platform type, defaulting to Windows");
|
||||||
return makeUnique<WindowsPlatformConfig>();
|
return makeUnique<WindowsPlatformConfig>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -377,15 +385,21 @@ UniquePtr<PlatformConfig> createPlatformConfig(PlatformType type) {
|
||||||
* @param type 平台类型枚举值
|
* @param type 平台类型枚举值
|
||||||
* @return 平台名称字符串
|
* @return 平台名称字符串
|
||||||
*/
|
*/
|
||||||
const char* getPlatformTypeName(PlatformType type) {
|
const char *getPlatformTypeName(PlatformType type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case PlatformType::Auto: return "Auto";
|
case PlatformType::Auto:
|
||||||
case PlatformType::Windows: return "Windows";
|
return "Auto";
|
||||||
case PlatformType::Switch: return "Switch";
|
case PlatformType::Windows:
|
||||||
case PlatformType::Linux: return "Linux";
|
return "Windows";
|
||||||
case PlatformType::macOS: return "macOS";
|
case PlatformType::Switch:
|
||||||
default: return "Unknown";
|
return "Switch";
|
||||||
}
|
case PlatformType::Linux:
|
||||||
|
return "Linux";
|
||||||
|
case PlatformType::macOS:
|
||||||
|
return "macOS";
|
||||||
|
default:
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace extra2d
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,25 @@
|
||||||
|
|
||||||
namespace extra2d {
|
namespace extra2d {
|
||||||
|
|
||||||
E2D_REG_BACKEND(sdl2, SDL2Window, SDL2Input)
|
namespace {
|
||||||
|
static bool s_sdl2BackendRegistered = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void initSDL2Backend() {
|
||||||
|
if (s_sdl2BackendRegistered) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
s_sdl2BackendRegistered = true;
|
||||||
|
|
||||||
|
BackendFactory::reg(
|
||||||
|
"sdl2",
|
||||||
|
[]() -> UniquePtr<IWindow> {
|
||||||
|
return makeUnique<SDL2Window>();
|
||||||
|
},
|
||||||
|
[]() -> UniquePtr<IInput> {
|
||||||
|
return makeUnique<SDL2Input>();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace extra2d
|
} // namespace extra2d
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#include "sdl2_window.h"
|
#include "sdl2_window.h"
|
||||||
#include "sdl2_input.h"
|
#include "sdl2_input.h"
|
||||||
#include <extra2d/utils/logger.h>
|
#include <extra2d/utils/logger.h>
|
||||||
|
#include <glad/glad.h>
|
||||||
|
|
||||||
namespace extra2d {
|
namespace extra2d {
|
||||||
|
|
||||||
|
|
@ -73,6 +74,16 @@ bool SDL2Window::create(const WindowConfigData& cfg) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!gladLoadGLES2Loader((GLADloadproc)SDL_GL_GetProcAddress)) {
|
||||||
|
E2D_LOG_ERROR("Failed to initialize GLAD");
|
||||||
|
SDL_GL_DeleteContext(glContext_);
|
||||||
|
glContext_ = nullptr;
|
||||||
|
SDL_DestroyWindow(sdlWindow_);
|
||||||
|
sdlWindow_ = nullptr;
|
||||||
|
deinitSDL();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
SDL_GL_SetSwapInterval(cfg.vsync ? 1 : 0);
|
SDL_GL_SetSwapInterval(cfg.vsync ? 1 : 0);
|
||||||
|
|
||||||
SDL_GetWindowSize(sdlWindow_, &width_, &height_);
|
SDL_GetWindowSize(sdlWindow_, &width_, &height_);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
/**
|
||||||
|
* @file main.cpp
|
||||||
|
* @brief Extra2D 基础示例程序
|
||||||
|
*
|
||||||
|
* 演示如何使用 Extra2D 引擎创建一个简单的窗口应用程序。
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <extra2d/extra2d.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace extra2d;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 主函数
|
||||||
|
*
|
||||||
|
* 初始化应用程序,创建场景,运行主循环。
|
||||||
|
*/
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
(void)argc;
|
||||||
|
(void)argv;
|
||||||
|
|
||||||
|
std::cout << "Extra2D Demo - Starting..." << std::endl;
|
||||||
|
|
||||||
|
AppConfig config = AppConfig::createDefault();
|
||||||
|
config.appName = "Extra2D Demo";
|
||||||
|
config.appVersion = "1.0.0";
|
||||||
|
config.window.title = "Extra2D Demo";
|
||||||
|
config.window.width = 800;
|
||||||
|
config.window.height = 600;
|
||||||
|
config.window.mode = WindowMode::Windowed;
|
||||||
|
config.window.resizable = true;
|
||||||
|
config.window.vsync = true;
|
||||||
|
config.render.targetFPS = 60;
|
||||||
|
|
||||||
|
Application& app = Application::get();
|
||||||
|
|
||||||
|
if (!app.init(config)) {
|
||||||
|
std::cerr << "Failed to initialize application!" << std::endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "Application initialized successfully!" << std::endl;
|
||||||
|
std::cout << "Window: " << app.window().width() << "x" << app.window().height() << std::endl;
|
||||||
|
std::cout << "Running main loop. Press ESC or close window to exit." << std::endl;
|
||||||
|
|
||||||
|
auto scene = Scene::create();
|
||||||
|
scene->setBackgroundColor(Colors::SkyBlue);
|
||||||
|
scene->setViewportSize(static_cast<float>(config.window.width),
|
||||||
|
static_cast<float>(config.window.height));
|
||||||
|
app.enterScene(scene);
|
||||||
|
|
||||||
|
app.run();
|
||||||
|
|
||||||
|
std::cout << "Shutting down..." << std::endl;
|
||||||
|
app.shutdown();
|
||||||
|
|
||||||
|
std::cout << "Goodbye!" << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
20
xmake.lua
20
xmake.lua
|
|
@ -95,3 +95,23 @@ includes("xmake/engine.lua")
|
||||||
-- 定义引擎库
|
-- 定义引擎库
|
||||||
define_extra2d_engine()
|
define_extra2d_engine()
|
||||||
|
|
||||||
|
-- ==============================================
|
||||||
|
-- 示例程序
|
||||||
|
-- ==============================================
|
||||||
|
|
||||||
|
-- 基础示例
|
||||||
|
target("demo_basic")
|
||||||
|
set_kind("binary")
|
||||||
|
set_default(false)
|
||||||
|
|
||||||
|
add_deps("extra2d")
|
||||||
|
add_files("examples/basic/main.cpp")
|
||||||
|
|
||||||
|
-- 平台配置
|
||||||
|
local target_plat = get_config("plat") or os.host()
|
||||||
|
if target_plat == "mingw" then
|
||||||
|
add_packages("glm", "nlohmann_json", "libsdl2")
|
||||||
|
add_syslinks("opengl32", "glu32", "winmm", "imm32", "version", "setupapi")
|
||||||
|
end
|
||||||
|
target_end()
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue