Chapter 106 · 精灵批处理与九宫格

ShapeBatch

ShapeBatch 将多个纯色三角形/矩形合并为一次 Draw Call,适合调试绘制、粒子、批量图元。

106

概念

ShapeBatch 与 SpriteBatch 类似,但不需要纹理——直接批量绘制纯色三角形和矩形。 初始化时指定统一颜色,所有添加的图元共享该颜色。 适合:调试碰撞盒、批量粒子、背景网格。

API 速查

函数说明
int xgeShapeBatchInit(xge_shape_batch pBatch, uint32_t iColor, int iTriangleCapacity, uint32_t iFlags)初始化(指定颜色 + 容量)
void xgeShapeBatchFree(xge_shape_batch pBatch)释放
void xgeShapeBatchClear(xge_shape_batch pBatch)清空
int xgeShapeBatchTriangleFill(xge_shape_batch pBatch, xge_vec2_t tA, xge_vec2_t tB, xge_vec2_t tC)添加三角形
int xgeShapeBatchRectFill(xge_shape_batch pBatch, xge_rect_t tRect)添加矩形
int xgeShapeBatchFlush(xge_shape_batch pBatch)提交绘制

编译本章示例

gcc -O2 -I. -o ch106.exe ch106_main.c build\xge.lib -lm -lws2_32 -liphlpapi -lgdi32 -luser32 -lshell32 -lopengl32 -lole32 -lwinmm -lavrt
.\ch106.exe

示例:批量调试绘制

// 初始化:绿色,容量 500 个三角形
xge_shape_batch_t dbgBatch;
xgeShapeBatchInit(&dbgBatch,
    0x00FF0080, 500, 0);

// 每帧:添加碰撞盒
xgeShapeBatchClear(&dbgBatch);

for (int i = 0; i < entityCount; i++) {
    xge_rect_t box = entities[i].aabb;
    xgeShapeBatchRectFill(&dbgBatch, box);
}

// 添加自定义三角形(如方向指示器)
xgeShapeBatchTriangleFill(&dbgBatch,
    (xge_vec2_t){ 400, 100 },
    (xge_vec2_t){ 380, 140 },
    (xge_vec2_t){ 420, 140 });

// 一次提交
xgeShapeBatchFlush(&dbgBatch);

完整代码

将以下代码保存为 ch106_main.c,编译后运行即可看到 ShapeBatch 批量调试绘制效果:

#include "xge.h"
#include <math.h>

static xge_shape_batch_t g_batch;
static xge_font g_font = NULL;
static float g_time = 0.0f;

static int onFrame(void* pUser) {
    (void)pUser;
    xgeClear(0x081114FF);
    g_time += 0.016f;

    xgeShapeBatchClear(&g_batch);

    // 批量绘制动态碰撞盒
    for (int i = 0; i < 20; i++) {
        float x = 50.0f + i * 35.0f;
        float y = 200.0f + 80.0f *
            sinf(g_time * 2.0f + i * 0.5f);
        xge_rect_t box = { x, y, 30, 30 };
        xgeShapeBatchRectFill(&g_batch, box);
    }

    // 添加方向指示器三角形
    float tipX = 400.0f + 100.0f * cosf(g_time);
    float tipY = 450.0f + 50.0f * sinf(g_time);
    xgeShapeBatchTriangleFill(&g_batch,
        (xge_vec2_t){ tipX, tipY - 20 },
        (xge_vec2_t){ tipX - 15, tipY + 15 },
        (xge_vec2_t){ tipX + 15, tipY + 15 });

    // 一次提交
    xgeShapeBatchFlush(&g_batch);

    xgeTextDraw(g_font, "ShapeBatch: 20 AABBs + 1 triangle",
        50.0f, 50.0f, 0xFFFFFFFF)

    return XGE_OK;
}

int main(void) {
    xge_desc_t d = {0};
    d.iWidth  = 800;
    d.iHeight = 600;
    d.sTitle  = "ch106 - ShapeBatch Debug Draw";
    d.iFlags  = XGE_INIT_VSYNC;
    xgeInit(&d);

    xgeFontLoad(&g_font, "Roboto.ttf", 18.0f);

    // 初始化:绿色半透明,容量 500 个三角形
    xgeShapeBatchInit(&g_batch,
        0x00FF0080, 500, 0);

    xgeRun(onFrame, NULL);

    xgeShapeBatchFree(&g_batch);
    xgeFontFree(g_font);
    xgeUnit();
    return 0;
}

代码讲解

  • ShapeBatchInit:初始化单色形状批处理器,指定颜色和三角形容量。
  • RectFill:添加矩形(内部转为 2 个三角形),适合碰撞盒/AABB 调试。
  • TriangleFill:添加自定义三角形,适合方向指示器/箭头。
  • 半透明:Alpha < 255 的颜色适合叠加显示调试信息。

要点与陷阱

  • 单色:一个 Batch 只有一种颜色;多色需多个 Batch。
  • 容量:以三角形为单位;RectFill 内部转为 2 个三角形。
  • vs SpriteBatch:ShapeBatch 无纹理,纯顶点色。
  • 调试:半透明颜色(Alpha < 255)适合叠加显示。

进阶练习

  1. 实现物理引擎调试视图:批量绘制所有刚体 AABB。
  2. 星空背景:数百个小矩形粒子一次 Flush。
ShapeBatch效果
图:ShapeBatch渲染效果