Chapter 42 · ShapeEx 填充与描边

填充:线性渐变

线性渐变沿一条直线方向插值颜色,用 color_stop 数组定义多个颜色停靠点。

42

概念

  • 渐变轴:由 (X1,Y1) → (X2,Y2) 定义渐变方向。
  • color_stop_t:{ fOffset (0~1), iColor },偏移量从小到大排列。
  • 坐标单位:USER_SPACE(世界坐标)或 OBJECT_BOUNDING_BOX(0~1 归一化)。

API 速查

函数 / 类型说明
xge_shape_ex_color_stop_t { float fOffset; uint32_t iColor; }颜色停靠点
#define XGE_SHAPE_EX_GRADIENT_USER_SPACE 0世界坐标
#define XGE_SHAPE_EX_GRADIENT_OBJECT_BOUNDING_BOX 1归一化坐标
int xgeShapeExFillLinearGradient(xge_shape_ex pShape, float fX1, float fY1, float fX2, float fY2, int iUnits, const xge_shape_ex_color_stop_t* pStops, int iStopCount)设置线性渐变填充
int xgeShapeExFillLinearGradientGet(...)获取线性渐变参数

编译本章示例

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

示例 1:水平双色渐变

xge_shape_ex_color_stop_t stops[] = {
    { 0.0f, 0x4FD8C2FF },  // 起点:青色
    { 1.0f, 0xFFB454FF },  // 终点:橙色
};

xge_shape_ex shape = NULL;
xgeShapeExCreate(&shape);
xgeShapeExAppendRect(shape, 100,200, 600,150, 12,12, 1);

xgeShapeExFillLinearGradient(shape,
    100, 0, 700, 0,  // 从左到右
    XGE_SHAPE_EX_GRADIENT_USER_SPACE,
    stops, 2);

xgeShapeExDraw(shape, 0.25f);

示例 2:多停靠点彩虹渐变

xge_shape_ex_color_stop_t rainbow[] = {
    { 0.0f,  0xFF0000FF },
    { 0.2f,  0xFFFF00FF },
    { 0.4f,  0x00FF00FF },
    { 0.6f,  0x00FFFFFF },
    { 0.8f,  0x0000FFFF },
    { 1.0f,  0xFF00FFFF },
};

xgeShapeExFillLinearGradient(shape,
    0, 0, 1, 0,  // 归一化:左→右
    XGE_SHAPE_EX_GRADIENT_OBJECT_BOUNDING_BOX,
    rainbow, 6);

完整代码

将以下代码保存为 ch42_main.c,编译后运行即可看到线性渐变填充效果:

#include "xge.h"

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

    // 水平双色渐变
    xge_shape_ex_color_stop_t stops2[] = {
        { 0.0f, 0x4FD8C2FF },
        { 1.0f, 0xFFB454FF },
    };
    xge_shape_ex bar = NULL;
    xgeShapeExCreate(&bar);
    xgeShapeExAppendRect(bar, 80,80, 640,120, 16,16, 1);
    xgeShapeExFillLinearGradient(bar,
        80, 0, 720, 0,
        XGE_SHAPE_EX_GRADIENT_USER_SPACE,
        stops2, 2);
    xgeShapeExDraw(bar, 0.25f);
    xgeShapeExDestroy(bar);

    // 彩虹多停靠点渐变
    xge_shape_ex_color_stop_t rainbow[] = {
        { 0.0f,  0xFF0000FF },
        { 0.2f,  0xFFFF00FF },
        { 0.4f,  0x00FF00FF },
        { 0.6f,  0x00FFFFFF },
        { 0.8f,  0x0000FFFF },
        { 1.0f,  0xFF00FFFF },
    };
    xge_shape_ex rb = NULL;
    xgeShapeExCreate(&rb);
    xgeShapeExAppendRect(rb, 80,280, 640,120, 16,16, 1);
    xgeShapeExFillLinearGradient(rb,
        0, 0, 1, 0,
        XGE_SHAPE_EX_GRADIENT_OBJECT_BOUNDING_BOX,
        rainbow, 6);
    xgeShapeExDraw(rb, 0.25f);
    xgeShapeExDestroy(rb);

    return XGE_OK;
}

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

代码讲解

  • 颜色停靠点:xge_shape_ex_color_stop_t 包含 fOffset(0~1) 和 iColor,至少 2 个。
  • USER_SPACE:渐变轴用世界坐标,(X1,Y1)→(X2,Y2) 决定方向。
  • OBJECT_BOUNDING_BOX:归一化坐标,(0,0)→(1,0) 表示左→右,与图形尺寸无关。
  • 多停靠点:6 个停靠点实现彩虹渐变,Offset 均匀分布。

要点与陷阱

  • 至少 2 个停靠点:少于 2 个会失败。
  • Offset 范围:0.0 ~ 1.0,超出会被钳制。
  • 覆盖纯色:设置渐变后,之前的 FillColor 被替换。
  • 方向任意:(X1,Y1)→(X2,Y2) 可以是任意角度(对角线、垂直等)。

进阶练习

  1. 实现 45° 对角线渐变背景。
  2. 动态移动渐变轴:每帧改变 X1/X2,形成"流光"动画。
填充:线性渐变效果
图:填充:线性渐变渲染效果