深入理解引擎初始化的每一个细节——xge_desc_t 的全部字段、初始化标志位组合,以及引擎生命周期管理。
XGE 的生命周期极其简洁:xgeInit → xgeRun → xgeUnit。整个引擎是单例模式——一个进程只能初始化一次。初始化时通过 xge_desc_t 结构体一次性声明窗口尺寸、标题、运行模式和功能标志。
typedef struct xge_desc_t {
int iWidth; // 窗口宽度(逻辑像素)
int iHeight; // 窗口高度(逻辑像素)
const char* sTitle; // 窗口标题(UTF-8)
int iFlags; // 初始化标志位(见下表)
int iRunMode; // 运行模式:GAME_LOOP / MANUAL
int iTargetFPS; // 目标帧率(0 = 不限制)
void* pNativeWindow; // 嵌入已有窗口句柄(可选)
void* pUser; // 用户自定义数据指针
} xge_desc_t;| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
iWidth | int | 800 | 窗口客户区宽度。HIGHDPI 模式下为逻辑像素 |
iHeight | int | 600 | 窗口客户区高度 |
sTitle | const char* | "XGE" | 窗口标题栏文本,支持 UTF-8 中文 |
iFlags | int | XGE_INIT_WINDOW | 功能标志位组合(按位或) |
iRunMode | int | XGE_RUN_GAME_LOOP | 帧驱动模式 |
iTargetFPS | int | 0 | 目标帧率上限,0 表示 VSync 或不限制 |
pNativeWindow | void* | NULL | 嵌入模式:传入 HWND / NSView 等原生句柄 |
pUser | void* | NULL | 透传到帧回调的用户数据 |
| 标志 | 值 | 说明 |
|---|---|---|
XGE_INIT_WINDOW | 0x0000 | 普通窗口模式(默认) |
XGE_INIT_FULLSCREEN | 0x0001 | 全屏模式 |
XGE_INIT_NOFRAME | 0x0002 | 无边框窗口 |
XGE_INIT_RESIZABLE | 0x0004 | 允许用户拖拽调整大小 |
XGE_INIT_HIGHDPI | 0x0008 | 高 DPI 感知(帧缓冲 = 逻辑尺寸 × DPI 缩放) |
XGE_INIT_VSYNC | 0x0010 | 启用垂直同步 |
XGE_INIT_OFFSCREEN | 0x0020 | 离屏模式(不创建可见窗口) |
XGE_INIT_ON_DEMAND | 0x0040 | 按需渲染(仅在 InvalidateRect 时重绘) |
gcc -O2 -I. -o ch02.exe ch02_main.c build\xge.lib -lm -lws2_32 -liphlpapi -lgdi32 -luser32 -lshell32 -lopengl32 -lole32 -lwinmm -lavrt
.\ch02.exe
// 创建一个高 DPI、可调大小、带 VSync 的窗口
#include "xge.h"
#include <stdio.h>
static int onFrame(void* pUser) {
// 获取实际帧缓冲尺寸(HIGHDPI 下可能 > 逻辑尺寸)
int w = xgeGetWidth();
int h = xgeGetHeight();
xgeClear(0x101820FF);
// 在标题栏实时显示窗口尺寸
char title[64];
snprintf(title, sizeof(title), "XGE — %dx%d", w, h);
xgeSetTitle(title);
return XGE_OK;
}
int main(void) {
xge_desc_t d = {0};
d.iWidth = 1280;
d.iHeight = 720;
d.sTitle = "XGE — 1280x720";
d.iFlags = XGE_INIT_WINDOW
| XGE_INIT_RESIZABLE
| XGE_INIT_HIGHDPI
| XGE_INIT_VSYNC;
d.iRunMode = XGE_RUN_GAME_LOOP;
d.iTargetFPS = 0; // VSync 已限制帧率
int r = xgeInit(&d);
if (r != XGE_OK) {
printf("Init failed: %d\n", r);
return 1;
}
xgeRun(onFrame, NULL);
xgeUnit();
return 0;
}可构建的权威源码为 examples/tutorial_capture/ch02_main1.c。它初始化窗口和离屏目标后,绘制窗口边框、标题栏与客户区标记;截图由该程序的 --capture 模式生成。

1280×720 可调整大小的窗口,标题栏实时显示当前尺寸。在 2x DPI 显示器上帧缓冲实际为 2560×1440。
xgeInit 返回 xge_result_t 枚举值:
| 返回值 | 含义 | 常见原因 |
|---|---|---|
XGE_OK (0) | 成功 | — |
XGE_ERROR_ALREADY_INITIALIZED (-4) | 重复初始化 | 调用了两次 xgeInit |
XGE_ERROR_BACKEND_FAILED (-8) | 平台后端失败 | 无法创建窗口/OpenGL 上下文 |
XGE_ERROR_GPU_FAILED (-9) | GPU 初始化失败 | 显卡不支持 GL 3.3 |
XGE_ERROR_OUT_OF_MEMORY (-5) | 内存不足 | 极端情况 |
{0} 初始化描述符——未赋值的字段应为 0/NULL,否则行为未定义。xgeGetWidth() 返回逻辑尺寸,但帧缓冲实际像素 = 逻辑 × DPI。绘制坐标使用逻辑像素。xgeRun 不会阻塞,需手动调用 xgeFrame()。HWND,引擎将在该窗口内渲染而非创建新窗口。XGE_INIT_NOFRAME | XGE_INIT_RESIZABLE 的无边框窗口,在帧回调中检测 ESC 键并调用 xgeQuit() 退出。XGE_INIT_OFFSCREEN 模式初始化,调用 xgeFrame() 渲染 60 帧后退出(无需窗口出现)。iTargetFPS = 30,观察帧率被限制在 30 FPS。