Chapter 44 · ShapeEx 填充与描边

渐变扩散模式

当渐变范围小于图形区域时,Pad / Reflect / Repeat 三种扩散模式决定超出部分如何填充。

44

概念

  • Pad(默认):超出范围用最近端颜色填充。
  • Reflect:镜像反射渐变,形成对称重复。
  • Repeat:平铺重复渐变。

API 速查

常量 / 函数说明
#define XGE_SHAPE_EX_GRADIENT_SPREAD_PAD 0钳制端色
#define XGE_SHAPE_EX_GRADIENT_SPREAD_REFLECT 1镜像反射
#define XGE_SHAPE_EX_GRADIENT_SPREAD_REPEAT 2平铺重复
int xgeShapeExFillGradientSpread(xge_shape_ex pShape, int iSpread)设置填充渐变扩散
int xgeShapeExFillGradientSpreadGet(xge_shape_ex pShape, int* pSpread)获取扩散模式

编译本章示例

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

示例:三种模式对比

xge_shape_ex_color_stop_t stops[] = {
    { 0.0f, 0x4FD8C2FF },
    { 1.0f, 0xFFB454FF },
};

int spreads[] = {
    XGE_SHAPE_EX_GRADIENT_SPREAD_PAD,
    XGE_SHAPE_EX_GRADIENT_SPREAD_REFLECT,
    XGE_SHAPE_EX_GRADIENT_SPREAD_REPEAT,
};

for (int i = 0; i < 3; i++) {
    xge_shape_ex s = NULL;
    xgeShapeExCreate(&s);
    xgeShapeExAppendRect(s, 50, 100+i*150, 700, 120, 0,0, 1);
    // 渐变只覆盖 1/3 宽度 → 超出部分由扩散模式决定
    xgeShapeExFillLinearGradient(s, 50,0, 280,0,
        XGE_SHAPE_EX_GRADIENT_USER_SPACE, stops, 2);
    xgeShapeExFillGradientSpread(s, spreads[i]);
    xgeShapeExDraw(s, 0.25f);
    xgeShapeExDestroy(s);
}

完整代码

将以下代码保存为 ch44_main.c,编译后运行即可看到三种渐变扩散模式的对比效果:

#include "xge.h"

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

    xge_shape_ex_color_stop_t stops[] = {
        { 0.0f, 0x4FD8C2FF },
        { 1.0f, 0xFFB454FF },
    };

    int spreads[] = {
        XGE_SHAPE_EX_GRADIENT_SPREAD_PAD,
        XGE_SHAPE_EX_GRADIENT_SPREAD_REFLECT,
        XGE_SHAPE_EX_GRADIENT_SPREAD_REPEAT,
    };
    const char* names[] = { "PAD", "REFLECT", "REPEAT" };

    for (int i = 0; i < 3; i++) {
        xge_shape_ex s = NULL;
        xgeShapeExCreate(&s);
        xgeShapeExAppendRect(s, 50, 80+i*170, 700, 130, 12,12, 1);
        // 渐变只覆盖 1/3 宽度,超出部分由扩散模式决定
        xgeShapeExFillLinearGradient(s, 50,0, 280,0,
            XGE_SHAPE_EX_GRADIENT_USER_SPACE, stops, 2);
        xgeShapeExFillGradientSpread(s, spreads[i]);
        xgeShapeExDraw(s, 0.25f);
        xgeShapeExDestroy(s);
    }
    return XGE_OK;
}

int main(void) {
    xge_desc_t d = {0};
    d.iWidth  = 800;
    d.iHeight = 600;
    d.sTitle  = "ch44 - Gradient Spread";
    d.iFlags  = XGE_INIT_VSYNC;
    xgeInit(&d);
    xgeRun(onFrame, NULL);
    xgeUnit();
    return 0;
}

代码讲解

  • stops 数组:定义两个色标(青→橙),渐变从 x=50 到 x=280(仅覆盖矩形 1/3 宽度)。
  • spreads 数组:三种扩散模式常量,循环中逐一应用。
  • USER_SPACE:使用用户坐标定义渐变起止点,便于精确控制覆盖范围。
  • xgeShapeExFillGradientSpread:在设置渐变后调用,决定超出渐变范围的颜色行为。
  • Create/Destroy:每帧创建销毁,实际项目中可缓存复用。

要点与陷阱

  • 默认 Pad:不设置时默认为 Pad。
  • 渐变覆盖全区域时:三种模式效果相同(没有超出部分)。
  • 对描边渐变也有效:StrokeGradientSpread(第 50 章)。

进阶练习

  1. 用 Repeat 模式 + 窄渐变实现条纹效果。
  2. 用 Reflect 模式实现金属拉丝质感。
渐变扩散模式效果
图:渐变扩散模式渲染效果