Chapter 01 · 引擎基础

环境搭建与工具链

在编写第一行 XGE 代码之前,你需要准备好编译工具链并了解项目目录结构。本章将带你完成从零到可编译的全部准备工作。

01

为什么需要工具链准备

XGE 是一个纯 C99 图形引擎,不依赖任何包管理器或 IDE 工程系统。它通过 批处理脚本 + GCC 命令行 的方式构建,这意味着你只需要一个正确的编译器环境即可。这种设计让 XGE 可以无缝嵌入任何构建系统——无论是 Makefile、CMake、MSBuild 还是你自研的构建脚本。

核心理念:XGE 的构建产物是一个动态库(xge.dll / libxge.so),你的应用只需链接这个库并包含两个头文件(xge.h + xui.h)即可使用全部功能。

环境要求

组件最低版本说明
MinGW-w64 GCC12.x+C99 编译器,需包含 gcc、windres
OpenGL 驱动3.3+桌面平台需要支持 GL 3.3 的显卡驱动
Windows SDK—MinGW-w64 自带,提供 gdi32、user32 等系统库
Git任意用于克隆仓库
注意:不要使用 MSVC 的 cl.exe。XGE 的构建脚本针对 MinGW-w64 编写,链接参数(-lgdi32 -luser32 等)是 GCC 风格。如果你使用 Visual Studio,请安装 MinGW-w64 工具链并通过命令行构建。

项目目录结构

克隆仓库后,你会看到如下结构:

xge/
├── xge.h              # 引擎公开头文件(3,870 行,含 3D 的全部 API 声明)
├── xui.h              # XUI 框架头文件(12,687 行,80+ 控件)
├── xui_document.h # 富文本/Markdown 文档控件(154 个 API)
├── xge.c              # Unity build 入口(仅 4 行)
├── src/               # 引擎实现源码
│   └── xge_impl.c    # 核心实现(包含全部模块)
├── lib/               # 内置第三方库(单头文件)
│   ├── xrt/xrt.h     # 自研运行时(318,537 行)
│   ├── sokol_app.h   # 跨平台窗口/输入
│   ├── stb_image.h   # 图像解码
│   ├── stb_truetype.h # TTF 光栅化
│   └── miniaudio.h   # 音频引擎
├── examples/          # 可运行示例(每个子目录一个工程)
├── test_xui/          # XUI 控件测试
├── docs/              # 架构设计文档
├── build_dll.bat      # Release DLL 构建
├── build_dbg_dll.bat  # Debug DLL 构建
├── build_test.bat     # 测试构建
└── build/             # 构建输出目录
    ├── xge.dll
    ├── xge.lib
    └── xgedbg.dll

构建引擎 DLL

Release 版本

$ cd xge
$ build_dll.bat

脚本内部执行的核心命令等价于:

gcc -shared -o build/xge.dll xge.c \
    -DXGE_BUILD_DLL -DXGE_DLL -DNDEBUG -O2 \
    -lm -lws2_32 -lgdi32 -luser32 -lshell32 -lole32 -lwinmm \
    -Wl,--out-implib,build/xge.lib

Debug 版本

$ build_dbg_dll.bat

Debug 版额外定义 -DXGE_DEBUGMODE=1,暴露调试统计 API(xgeDebugGetStats、xgedbgDirtyRectCount 等)。产物为 build/xgedbg.dll。

编写第一个程序

创建 hello/main.c:

// hello/main.c — 最小 XGE 程序
#include "xge.h"

static int onFrame(void* pUser) {
    (void)pUser;
    xgeClear(0x0C181CFF);  // 深蓝色清屏
    return XGE_OK;           // 返回 XGE_OK 继续循环
}

int main(void) {
    xge_desc_t d = {0};
    d.iWidth  = 800;
    d.iHeight = 600;
    d.sTitle  = "Hello XGE";
    d.iFlags  = XGE_INIT_WINDOW | XGE_INIT_RESIZABLE;

    xgeInit(&d);
    xgeRun(onFrame, NULL);
    xgeUnit();
    return 0;
}

编译与运行

$ gcc hello/main.c -o hello/app.exe \
    -I. -Lbuild -lxge -lm -lws2_32 -lgdi32 -luser32 -lshell32 -lole32 -lwinmm
$ copy build\xge.dll hello\
$ hello\app.exe
XGE 工具链和构建流水线示例
图:本章权威示例以可运行画面串起源码、MinGW-w64、XGE DLL 和最终窗口;运行 ch01_main1.exe --frames 1 可自动退出。

本章 API 速查

函数 / 宏说明
xgeInit(const xge_desc_t*)初始化引擎,创建窗口
xgeUnit(void)销毁引擎,释放全部资源
xgeRun(proc, user)进入主循环
xgeClear(uint32_t)以 RGBA8 颜色清屏
XGE_INIT_WINDOW窗口模式(默认)
XGE_INIT_RESIZABLE允许用户调整窗口大小
XGE_OK帧回调返回此值继续运行

要点与常见陷阱

  • 运行时必须找到 xge.dll——将 xge.dll 放在可执行文件同目录或系统 PATH 中。
  • 链接顺序:-lxge 必须在 -lm -lws2_32 等系统库之前。
  • 头文件路径:xge.h 内部 #include "lib/xrt/xrt.h",所以编译时需要 -I.(仓库根目录)。
  • 不要同时链接 Release 和 Debug DLL——二者的结构体布局可能不同(Debug 版有额外字段)。
  • Unity Build:xge.c 仅包含 src/xge_impl.c。如果你想把源码并入自己的工程,直接编译 src/ 下的 .c 文件即可,无需 xge.c。

进阶练习

  1. 修改 iWidth / iHeight 为 1920×1080,观察窗口变化。
  2. 将 iFlags 改为 XGE_INIT_FULLSCREEN,运行后按 Alt+F4 退出。
  3. 在帧回调中每帧改变清屏颜色(提示:用静态变量递增 R 分量)。