Chapter 80 · SVG 引擎

SVG 光栅化与纹理

将 SVG 光栅化为像素数据或直接加载到 GPU 纹理,适合缩略图生成和纹理映射。

80

API 速查

函数说明
int xgeSvgRasterize(const char* sURI, int iWidth, int iHeight, void* pPixels, int iStride)文件光栅化到内存
int xgeSvgRasterizeMemory(const void* pData, int iSize, int iWidth, int iHeight, void* pPixels, int iStride)内存数据光栅化
int xgeSvgTextureLoad(xge_texture pTexture, const char* sURI, int iWidth, int iHeight)文件加载到纹理
int xgeSvgTextureLoadMemory(xge_texture pTexture, const void* pData, int iSize, int iWidth, int iHeight)内存加载到纹理

编译本章示例

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

示例:生成 SVG 缩略图

// 光栅化到 CPU 内存(RGBA 格式)
int w = 128, h = 128;
uint8_t pixels[128 * 128 * 4];
xgeSvgRasterize("assets/icon.svg",
    w, h, pixels, w * 4);
// pixels 现在是 128x128 RGBA 图像

// 保存为 PNG
xgeImageSavePNG("thumb.png", pixels, w, h, w * 4);

// 直接加载到 GPU 纹理
xge_texture tex;
xgeTextureCreateRGBA(&tex, w, h, NULL);
xgeSvgTextureLoad(tex, "assets/icon.svg", w, h);

// 从内存 SVG 数据加载纹理
const char* svgStr = "<svg>...</svg>";
xgeSvgTextureLoadMemory(tex,
    svgStr, (int)strlen(svgStr), 64, 64);

完整代码

将以下代码保存为 ch80_main.c,编译后运行即可看到 SVG 光栅化到纹理并绘制的效果:

#include "xge.h"

static xge_texture g_tex = NULL;
static int g_iFrame = 0;

static int onFrame(void* pUser) {
    (void)pUser;
    xgeClear(0x081114FF);
    g_iFrame++;

    // 用纹理绘制旋转的 SVG 缩略图
    float cx = 400.0f, cy = 300.0f;
    float angle = g_iFrame * 0.02f;
xge_draw_t t = { 0 };
    t.pTexture = g_tex;
    t.tDst = (xge_rect_t){cx - 64, cy - 64, 128, 128};
    t.tOrigin = (xge_vec2_t){64, 64};  /* 绕中心旋转 */
    t.fRotation = angle;
    xgeSpriteBatchAdd(&g_batch, &t);
    /* 帧尾 xgeSpriteBatchFlush(&g_batch); */
    return XGE_OK;
}

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

    // SVG 光栅化到 GPU 纹理
    int w = 128, h = 128;
    xgeTextureCreateRGBA(&g_tex, w, h, NULL);
    xgeSvgTextureLoad(g_tex, "assets/icon.svg", w, h);

    xgeRun(onFrame, NULL);
    xgeTextureFree(g_tex);
    xgeUnit();
    return 0;
}

代码讲解

  • SvgTextureLoad:将 SVG 光栅化并直接加载到 GPU 纹理,避免每帧重新解析。
  • TextureCreateRGBA:创建 128×128 的 RGBA 纹理作为光栅化目标。
  • 旋转绘制:用矩阵变换绘制旋转的纹理,展示光栅化结果可作为普通纹理使用。
  • 性能优势:一次光栅化,多次绘制,适合频繁使用的图标。

要点与陷阱

  • 光栅化尺寸:iWidth/iHeight 决定输出分辨率,与 SVG viewBox 无关。
  • iStride:每行字节数,通常 = width × 4(RGBA)。
  • TextureLoad:内部创建离屏上下文渲染,首次调用较慢。
  • 性能:频繁光栅化同一 SVG 建议缓存纹理,避免重复解析。

进阶练习

  1. 实现 SVG 图标集预览:批量光栅化生成缩略图网格。
  2. 动态分辨率:根据 DPI 缩放光栅化尺寸。
SVG 光栅化与纹理效果
图:SVG 光栅化与纹理渲染效果