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

Draw 系列函数

xgeDraw / DrawEx / DrawQuad3D / DrawPx 是纹理绘制的核心 API,覆盖从简单贴图到 3D 透视变换的所有场景。

108

概念

Draw 系列是 XGE 最基础的纹理绘制接口:
• xgeDraw:在 (x,y) 绘制整张纹理(最简)
• xgeDrawEx:完整参数(源矩形、目标矩形、颜色、旋转、锚点)
• xgeDrawQuad3D:四顶点 3D 透视绘制
• xgeDrawPx:像素对齐绘制(避免模糊)

API 速查

函数说明
void xgeDraw(xge_texture pTexture, float fX, float fY)简单绘制
void xgeDrawEx(const xge_draw_t* pDraw)完整参数绘制
void xgeDrawQuad3D(xge_texture pTexture, const xge_vertex_t* pVertices, uint32_t iFlags)3D 四边形绘制
void xgeDrawPx(xge_texture pTexture, int iX, int iY)像素对齐绘制

编译本章示例

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

示例:各种绘制方式

// 1. 最简单:在 (100,100) 绘制
xgeDraw(&tex, 100, 100);

// 2. 像素对齐(UI 元素避免模糊)
xgeDrawPx(&iconTex, 50, 50);

// 3. DrawEx:裁剪 + 缩放 + 旋转 + 染色
xge_draw_t draw = { 0 };
draw.pTexture = &spriteTex;
draw.tSrc = (xge_rect_t){ 0, 0, 64, 64 };
draw.tDst = (xge_rect_t){ 200, 200, 128, 128 };
draw.iColor = 0xFFFFFFFF;
draw.fRotation = 0.5f; // 弧度
draw.tAnchor = (xge_vec2_t){ 0.5f, 0.5f };
xgeDrawEx(&draw);

// 4. 3D 透视四边形
xge_vertex_t quad[4] = {
    { { 100,100 }, { 0,0 }, 0xFFFFFFFF },
    { { 300,120 }, { 1,0 }, 0xFFFFFFFF },
    { { 280,300 }, { 1,1 }, 0xFFFFFFFF },
    { { 120,280 }, { 0,1 }, 0xFFFFFFFF },
};
xgeDrawQuad3D(&tex, quad, 0);

完整代码

将以下代码保存为 ch108_main.c,编译后运行即可看到各种绘制方式对比效果:

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

static xge_texture_t g_tex;
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;

    // 1. 简单绘制
    xgeDraw(&g_tex, 50.0f, 50.0f);
    xgeTextDraw(g_font, "xgeDraw",
        50.0f, 120.0f, 0xFFFFFFFF)

    // 2. 像素对齐绘制
    xgeDrawPx(&g_tex, 200, 50);
    xgeTextDraw(g_font, "xgeDrawPx",
        200.0f, 120.0f, 0xFFFFFFFF)

    // 3. DrawEx:缩放 + 旋转 + 染色
    xge_draw_t draw = { 0 };
    draw.pTexture = &g_tex;
    draw.tSrc = (xge_rect_t){ 0, 0, 64, 64 };
    draw.tDst = (xge_rect_t){ 400, 80, 96, 96 };
    draw.iColor = 0xFF88CCFF;
    draw.fRotation = g_time;
    draw.tAnchor = (xge_vec2_t){ 0.5f, 0.5f };
    xgeDrawEx(&draw);
    xgeTextDraw(g_font, "xgeDrawEx (rotate)",
        360.0f, 140.0f, 0xFFFFFFFF)

    // 4. 3D 透视四边形
    xge_vertex_t quad[4] = {
        { 100,300, 0,0, 0xFFFFFFFF },
        { 300,320, 1,0, 0xFFFFFFFF },
        { 280,480, 1,1, 0xFFFFFFFF },
        { 120,460, 0,1, 0xFFFFFFFF },
    };
    xgeDrawQuad3D(&g_tex, quad, 0);
    xgeTextDraw(g_font, "xgeDrawQuad3D",
        100.0f, 500.0f, 0xFFFFFFFF)

    return XGE_OK;
}

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

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

    // 创建 64x64 渐变纹理
    uint8_t px[64 * 64 * 4];
    for (int y = 0; y < 64; y++)
        for (int x = 0; x < 64; x++) {
            int i = (y * 64 + x) * 4;
            px[i] = (uint8_t)(x * 4);
            px[i+1] = (uint8_t)(y * 4);
            px[i+2] = 180;
            px[i+3] = 255;
        }
    xgeTextureCreateRGBA(&g_tex, 64, 64, px);

    xgeRun(onFrame, NULL);

    xgeTextureFree(&g_tex);
    xgeFontFree(g_font);
    xgeUnit();
    return 0;
}

代码讲解

  • xgeDraw:最简单的绘制,在 (fX,fY) 绘制原始尺寸纹理。
  • xgeDrawPx:像素对齐绘制,避免线性过滤导致的边缘模糊。
  • xgeDrawEx:完整参数绘制,支持裁剪/缩放/旋转/染色/锚点。
  • xgeDrawQuad3D:四顶点任意放置,实现透视/扭曲效果。

要点与陷阱

  • DrawPx:坐标取整到像素,避免线性过滤导致的边缘模糊。
  • Anchor:(0,0) 左上,(0.5,0.5) 中心,(1,1) 右下。
  • Src 矩形:指定纹理子区域(精灵表裁剪)。
  • Quad3D:四顶点可任意放置,实现透视/扭曲效果。

进阶练习

  1. 实现精灵动画:Src 矩形按帧偏移。
  2. 伪 3D 地面:Quad3D 透视变换绘制地砖。
Draw 系列函数效果
图:Draw 系列函数渲染效果