理解 XGE 的后端抽象层,学习如何替换默认的平台后端和图形后端,将引擎嵌入你自己的窗口系统。
XGE 将"窗口/事件"和"图形 API"分为两个独立的后端接口。默认使用 Sokol(跨平台窗口)+ OpenGL 3.3(图形)。你可以替换其中任何一个,甚至两个都替换。
typedef struct xge_platform_backend_t {
int iType; // 后端类型标识
const char* sName; // 后端名称(调试用)
int (*init)(void* pUser); // 初始化(创建窗口等)
void (*unit)(void* pUser); // 销毁
int (*poll)(void* pUser); // 轮询事件(每帧调用)
void (*present)(void* pUser); // 呈现(SwapBuffers)
void* pUser; // 用户数据
} xge_platform_backend_t;typedef struct xge_graphics_backend_t {
int iType; // 后端类型标识
const char* sName; // 后端名称
int (*init)(void* pUser); // 初始化 GL 上下文
void (*unit)(void* pUser); // 销毁
int (*begin)(void* pUser); // 帧开始(MakeCurrent)
int (*end)(void* pUser); // 帧结束
void* pUser;
} xge_graphics_backend_t;| 函数 | 说明 |
|---|---|
xge_platform_backend_t xgePlatformBackendDefault(void) | 获取默认平台后端(Sokol) |
int xgePlatformBackendSet(const xge_platform_backend_t*) | 设置自定义平台后端(xgeInit 之前) |
xge_platform_backend_t xgePlatformBackendGet(void) | 获取当前平台后端 |
xge_graphics_backend_t xgeGraphicsBackendDefault(void) | 获取默认图形后端 |
int xgeGraphicsBackendSet(const xge_graphics_backend_t*) | 设置自定义图形后端(xgeInit 之前) |
xge_graphics_backend_t xgeGraphicsBackendGet(void) | 获取当前图形后端 |
gcc -O2 -I. -o ch10.exe ch10_main.c build\xge.lib -lm -lws2_32 -liphlpapi -lgdi32 -luser32 -lshell32 -lopengl32 -lole32 -lwinmm -lavrt
.\ch10.exe
#include "xge.h"
// 你的窗口系统(伪代码)
static MyWindow* g_pWindow;
static int myInit(void* pUser) {
g_pWindow = MyCreateWindow(800, 600, "Custom");
MyCreateGLContext(g_pWindow);
return XGE_OK;
}
static void myUnit(void* pUser) {
MyDestroyWindow(g_pWindow);
}
static int myPoll(void* pUser) {
// 将你的事件转换为 XGE 事件
MyEvent e;
while (MyPollEvent(&e)) {
// xgeInputEventPost(...); // 推入 XGE 输入事件
}
return XGE_OK;
}
static void myPresent(void* pUser) {
MySwapBuffers(g_pWindow);
}
int main(void) {
// 在 xgeInit 之前设置自定义后端
xge_platform_backend_t backend = {0};
backend.iType = XGE_PLATFORM_BACKEND_CUSTOM;
backend.sName = "MyWindow";
backend.init = myInit;
backend.unit = myUnit;
backend.poll = myPoll;
backend.present = myPresent;
xgePlatformBackendSet(&backend);
// 正常初始化(引擎将使用你的后端)
xge_desc_t d = {0};
d.iWidth = 800; d.iHeight = 600;
xgeInit(&d);
xgeRun(onFrame, NULL);
xgeUnit();
return 0;
}xgePlatformBackendSet 和 xgeGraphicsBackendSet 必须在 xgeInit 之前调用。初始化后不可更改。
本章权威、可运行源码位于 examples/tutorial_capture/ch10_main1.c。它在默认引擎初始化后只读取 xgePlatformBackendGet 和 xgeGraphicsBackendGet,并可视化平台层与图形层的职责;这样可以安全验证当前后端配置。真正调用 xgePlatformBackendSet 或 xgeGraphicsBackendSet 时,必须把设置代码放在 xgeInit 之前,并为目标平台实现完整回调。
| 平台后端 | 图形后端 |
|---|---|
XGE_PLATFORM_BACKEND_NONE (0) | XGE_GPU_BACKEND_NONE (0) |
XGE_PLATFORM_BACKEND_SOKOL (1) | XGE_GPU_BACKEND_OPENGL33 (1) |
XGE_PLATFORM_BACKEND_MINIPROGRAM (2) | XGE_GPU_BACKEND_GLES30 (2) |
XGE_PLATFORM_BACKEND_EGL (3) | XGE_GPU_BACKEND_WEBGL2 (3) |
XGE_PLATFORM_BACKEND_CUSTOM (100) | XGE_GPU_BACKEND_CUSTOM (100) |
xgePlatformBackendGet() 打印当前使用的后端名称。XGE_PLATFORM_BACKEND_EGL 后端,理解嵌入式 Linux 上的离屏渲染流程。
init/poll/present 与 init/begin/end 的两层职责;替换后端必须发生在 xgeInit 之前。