Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 81 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ option(EGE_BUILD_DEMO "Build ege demos" ${EGE_IS_ROOT_PROJECT})
option(EGE_BUILD_TEST "Build ege tests" ${EGE_IS_ROOT_PROJECT})
option(EGE_BUILD_TEMP "Build ege temp" ${EGE_IS_ROOT_PROJECT})

# OpenGL backend option - experimental cross-platform support
option(EGE_ENABLE_OPENGL "Enable OpenGL rendering backend (experimental)" OFF)

# EGE_DISABLE_DEBUG_INFO 选项:禁用调试信息,避免 LNK4099 警告
# 优先使用 CMake 参数,其次检查环境变量,默认 OFF
if(NOT DEFINED EGE_DISABLE_DEBUG_INFO)
Expand All @@ -47,6 +50,7 @@ message(STATUS "EGE_CLEAR_OPTIONS_CACHE: ${EGE_CLEAR_OPTIONS_CACHE}")
message(STATUS "EGE_BUILD_DEMO: ${EGE_BUILD_DEMO}")
message(STATUS "EGE_BUILD_TEST: ${EGE_BUILD_TEST}")
message(STATUS "EGE_BUILD_TEMP: ${EGE_BUILD_TEMP}")
message(STATUS "EGE_ENABLE_OPENGL: ${EGE_ENABLE_OPENGL}")
message(STATUS "EGE_DISABLE_DEBUG_INFO: ${EGE_DISABLE_DEBUG_INFO}")

if(CMAKE_HOST_UNIX)
Expand Down Expand Up @@ -129,8 +133,13 @@ if(EGE_ENABLE_CPP17)
set(CMAKE_CXX_EXTENSIONS OFF)
endif()

# Collect source files from src/ directory
file(GLOB EGE_CPP_SRC CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
add_library(xege STATIC ${EGE_CPP_SRC})

# Collect backend source files
file(GLOB EGE_BACKEND_SRC CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/src/backend/*.cpp)

add_library(xege STATIC ${EGE_CPP_SRC} ${EGE_BACKEND_SRC})

target_include_directories(xege PUBLIC include)

Expand Down Expand Up @@ -223,6 +232,77 @@ else()
message(WARNING "Camera capture is disabled because your compiler does not support C++17.")
endif()

# OpenGL backend configuration (experimental cross-platform support)
if(EGE_ENABLE_OPENGL)
message(STATUS "OpenGL backend enabled (experimental)")

# Find OpenGL
find_package(OpenGL REQUIRED)

# Check for GLFW
find_package(glfw3 CONFIG QUIET)
if(NOT glfw3_FOUND)
# Try to find GLFW via pkg-config
find_package(PkgConfig QUIET)
if(PKG_CONFIG_FOUND)
pkg_check_modules(GLFW3 glfw3)
endif()

if(NOT GLFW3_FOUND)
message(STATUS "GLFW3 not found in system, checking 3rdparty...")
# Check if GLFW is available in 3rdparty
if(EXISTS "${PROJECT_SOURCE_DIR}/3rdparty/glfw/CMakeLists.txt")
set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
add_subdirectory(${PROJECT_SOURCE_DIR}/3rdparty/glfw)
set(GLFW_LIBRARIES glfw)
set(GLFW_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/3rdparty/glfw/include)
else()
message(WARNING "GLFW not found. OpenGL backend disabled.")
message(WARNING "To enable, install GLFW or add it as a submodule in 3rdparty/glfw")
set(EGE_ENABLE_OPENGL OFF)
endif()
else()
set(GLFW_LIBRARIES ${GLFW3_LIBRARIES})
set(GLFW_INCLUDE_DIRS ${GLFW3_INCLUDE_DIRS})
endif()
else()
set(GLFW_LIBRARIES glfw)
endif()

# Check for GLAD
if(EGE_ENABLE_OPENGL)
if(EXISTS "${PROJECT_SOURCE_DIR}/3rdparty/glad/include/glad/glad.h")
set(GLAD_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/3rdparty/glad/include)
# Add GLAD source file if it exists
if(EXISTS "${PROJECT_SOURCE_DIR}/3rdparty/glad/src/glad.c")
target_sources(xege PRIVATE ${PROJECT_SOURCE_DIR}/3rdparty/glad/src/glad.c)
endif()
else()
message(WARNING "GLAD not found in 3rdparty/glad. OpenGL backend disabled.")
message(WARNING "To enable, add GLAD to 3rdparty/glad with include/glad/glad.h")
set(EGE_ENABLE_OPENGL OFF)
endif()
endif()

# Apply OpenGL configuration if still enabled
if(EGE_ENABLE_OPENGL)
target_compile_definitions(xege PRIVATE EGE_ENABLE_OPENGL=1)
target_include_directories(xege PRIVATE ${GLFW_INCLUDE_DIRS})
if(DEFINED GLAD_INCLUDE_DIRS)
target_include_directories(xege PRIVATE ${GLAD_INCLUDE_DIRS})
endif()
target_link_libraries(xege INTERFACE OpenGL::GL)
if(DEFINED GLFW_LIBRARIES)
target_link_libraries(xege INTERFACE ${GLFW_LIBRARIES})
endif()
message(STATUS "OpenGL backend configured successfully")
endif()
else()
message(STATUS "OpenGL backend disabled (use -DEGE_ENABLE_OPENGL=ON to enable)")
endif()

# 设置库文件名
# MSVC 下 Debug 版本使用 graphicsd.lib,Release 版本使用 graphics.lib
# MinGW 不区分 Debug/Release,统一使用 graphics
Expand Down
89 changes: 89 additions & 0 deletions demo/graph_opengl_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* EGE (Easy Graphics Engine)
* Demo: graph_opengl_test.cpp
*
* This demo demonstrates the usage of the OpenGL rendering backend.
* It draws basic shapes using the same EGE API that works with both
* GDI and OpenGL backends.
*
* To enable OpenGL backend:
* 1. Build EGE with -DEGE_ENABLE_OPENGL=ON
* 2. Use INIT_OPENGL flag: initgraph(640, 480, INIT_OPENGL);
*
* Note: This is an experimental feature for cross-platform support.
* The OpenGL backend currently supports basic drawing operations.
*/

#include <ege.h>

int main()
{
// Initialize with OpenGL backend (experimental)
// If OpenGL backend is not available, falls back to GDI
#ifdef EGE_ENABLE_OPENGL
ege::initgraph(640, 480, ege::INIT_OPENGL | ege::INIT_RENDERMANUAL);
ege::setcaption("EGE OpenGL Backend Demo");
#else
ege::initgraph(640, 480, ege::INIT_RENDERMANUAL);
ege::setcaption("EGE Demo (GDI Backend)");
#endif

// Set background color
ege::setbkcolor(ege::EGERGB(32, 32, 48));
ege::cleardevice();

// Draw some shapes to demonstrate rendering
// These functions work with both GDI and OpenGL backends

// Draw a circle
ege::setcolor(ege::EGERGB(255, 100, 100));
ege::circle(160, 160, 80);

// Draw a filled circle
ege::setfillcolor(ege::EGERGB(100, 255, 100));
ege::fillellipse(320, 160, 80, 80);

// Draw a rectangle outline
ege::setcolor(ege::EGERGB(100, 100, 255));
ege::rectangle(420, 80, 580, 240);

// Draw a filled rectangle
ege::setfillcolor(ege::EGERGB(255, 255, 100));
ege::bar(80, 280, 200, 400);

// Draw some lines
ege::setcolor(ege::EGERGB(255, 128, 0));
for (int i = 0; i < 10; i++) {
ege::line(240, 280 + i * 12, 560, 280 + i * 12);
}

// Draw an ellipse
ege::setcolor(ege::EGERGB(255, 0, 255));
ege::ellipse(400, 360, 0, 360, 120, 60);

// Draw filled ellipse
ege::setfillcolor(ege::EGERGB(0, 255, 255));
ege::fillellipse(160, 360, 60, 40);

// Draw some text
ege::setcolor(ege::WHITE);
ege::outtextxy(10, 10, "EGE Cross-Platform Backend Demo");
ege::outtextxy(10, 30, "Press any key to exit...");

#ifdef EGE_ENABLE_OPENGL
ege::outtextxy(10, 450, "Backend: OpenGL (experimental)");
#else
ege::outtextxy(10, 450, "Backend: GDI (default)");
#endif

// Update the display
ege::flushwindow();

// Wait for user input
ege::getch();

// Close graphics
ege::closegraph();

return 0;
}
122 changes: 122 additions & 0 deletions docs/CROSS_PLATFORM.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# EGE 跨平台支持 / Cross-Platform Support

## 概述 / Overview

EGE 现在支持多渲染后端架构,允许在保持向后兼容的同时,支持跨平台渲染。

EGE now supports a multi-backend rendering architecture, allowing cross-platform rendering while maintaining backward compatibility.

## 渲染后端 / Rendering Backends

### GDI 后端 (默认) / GDI Backend (Default)

- **平台 / Platform**: Windows only
- **状态 / Status**: 稳定 / Stable
- **说明 / Description**: 使用 Windows GDI/GDI+ 进行渲染,这是 EGE 的原始实现。

### OpenGL 后端 (实验性) / OpenGL Backend (Experimental)

- **平台 / Platform**: Windows, macOS, Linux
- **状态 / Status**: 实验性 / Experimental
- **说明 / Description**: 使用 OpenGL 进行渲染,通过 GLFW 管理窗口,实现真正的跨平台支持。

## 使用方法 / Usage

### 编译时启用 OpenGL / Enable OpenGL at Build Time

```bash
# CMake 配置时启用 OpenGL 后端
cmake .. -DEGE_ENABLE_OPENGL=ON
```

### 运行时选择后端 / Select Backend at Runtime

```cpp
#include <ege.h>

int main() {
// 使用默认 GDI 后端 / Use default GDI backend
ege::initgraph(640, 480, ege::INIT_DEFAULT);

// 或使用 OpenGL 后端 / Or use OpenGL backend
ege::initgraph(640, 480, ege::INIT_OPENGL);

// ... 绑定代码相同 / binding code is the same
}
```

## 后端抽象层 / Backend Abstraction Layer

### 目录结构 / Directory Structure

```
src/
└── backend/
├── render_backend.h # 抽象接口 / Abstract interface
├── render_backend.cpp # 后端工厂 / Backend factory
├── gdi_backend.h # GDI 后端头文件
├── gdi_backend.cpp # GDI 后端实现
├── opengl_backend.h # OpenGL 后端头文件
└── opengl_backend.cpp # OpenGL 后端实现
```

### RenderBackend 接口 / Interface

所有渲染后端都实现 `RenderBackend` 接口,提供以下功能:

All rendering backends implement the `RenderBackend` interface, providing:

- 初始化和关闭 / Initialization and shutdown
- 缓冲区交换 / Buffer swapping
- 清屏 / Clear screen
- 像素操作 / Pixel operations
- 基本图形绘制(线、矩形、圆、椭圆)/ Basic shape drawing (line, rectangle, circle, ellipse)
- 事件处理 / Event processing

## 依赖 / Dependencies

### OpenGL 后端依赖 / OpenGL Backend Dependencies

- **GLFW**: 窗口管理 / Window management
- **GLAD**: OpenGL 加载器 / OpenGL loader

这些依赖可以通过以下方式添加 / These dependencies can be added via:

1. 系统包管理器 / System package manager
2. Git 子模块到 `3rdparty/` / Git submodules to `3rdparty/`

## 已知限制 / Known Limitations

OpenGL 后端目前处于实验阶段,以下功能可能不完全支持:

The OpenGL backend is currently experimental, the following features may not be fully supported:

1. 文字渲染 / Text rendering
2. 图像操作 / Image operations
3. 部分高级 GDI+ 功能 / Some advanced GDI+ features

## 路线图 / Roadmap

1. **阶段 1** (已完成): 添加 `INIT_OPENGL` 标志和后端抽象层
2. **阶段 2**: 集成 GLFW 和 GLAD
3. **阶段 3**: 实现基本绘图功能的 OpenGL 版本
4. **阶段 4**: 添加文字渲染支持
5. **阶段 5**: 添加图像操作支持

---

## 开发者指南 / Developer Guide

### 添加新后端 / Adding a New Backend

1. 在 `src/backend/` 创建新的后端类
2. 继承 `RenderBackend` 接口
3. 实现所有虚函数
4. 在 `render_backend.cpp` 中注册后端
5. 更新 CMakeLists.txt 添加条件编译

### 测试后端 / Testing a Backend

使用 `demo/graph_opengl_test.cpp` 作为测试参考。

Use `demo/graph_opengl_test.cpp` as a testing reference.
1 change: 1 addition & 0 deletions include/ege.h
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ enum initmode_flag
INIT_UNICODE = 0x20, ///< Unicode character messages (equivalent to setunicodecharmessage(true))
INIT_HIDE = 0x40, ///< Hidden window
INIT_WITHLOGO = 0x100, ///< Show EGE Logo animation on startup (not shown by default in Debug version)
INIT_OPENGL = 0x200, ///< Use OpenGL rendering backend (experimental, for cross-platform support)
INIT_ANIMATION = INIT_DEFAULT | INIT_RENDERMANUAL | INIT_NOFORCEEXIT ///< Animation mode
};

Expand Down
1 change: 1 addition & 0 deletions include/ege.zh_CN.h
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ enum initmode_flag
INIT_UNICODE = 0x20, ///< Unicode字符消息 (等同于setunicodecharmessage(true))
INIT_HIDE = 0x40, ///< 隐藏窗口
INIT_WITHLOGO = 0x100, ///< 启动时显示EGE Logo 动画 (Debug版本下默认不显示)
INIT_OPENGL = 0x200, ///< 使用OpenGL渲染后端 (实验性功能,用于跨平台支持)
INIT_ANIMATION = INIT_DEFAULT | INIT_RENDERMANUAL | INIT_NOFORCEEXIT ///< 动画模式
};

Expand Down
Loading
Loading