Chapter 59 · ShapeEx 进阶

裁剪:形状裁剪

用任意 Shape 路径作为裁剪区域,支持添加多个裁剪形状及模式控制。

59

概念

  • 形状裁剪:用路径轮廓定义裁剪区域,比矩形裁剪更灵活。
  • 多裁剪形状:可添加多个 ClipShape,取交集。
  • 模式:Ex 版本支持额外裁剪模式参数。

API 速查

函数说明
int xgeShapeExClipShapeAdd(xge_shape_ex pShape, xge_shape_ex pClipShape)添加形状裁剪
int xgeShapeExClipShapeAddEx(xge_shape_ex pShape, xge_shape_ex pClipShape, int iMode)添加形状裁剪(含模式)
int xgeShapeExClipShapeGetCount(xge_shape_ex pShape, int* pCount)获取裁剪形状数量
int xgeShapeExClipShapeGetAt(xge_shape_ex pShape, int iIndex, xge_shape_ex* ppClipShape)获取指定索引裁剪形状
int xgeShapeExClipShapeClear(xge_shape_ex pShape)清除所有形状裁剪

编译本章示例

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

示例:圆形裁剪区域

// 裁剪形状:圆形
xge_shape_ex clipShape = NULL;
xgeShapeExCreate(&clipShape);
xgeShapeExAppendCircle(clipShape, 400, 300, 180, 180, 1);

// 内容:大矩形
xge_shape_ex content = NULL;
xgeShapeExCreate(&content);
xgeShapeExAppendRect(content, 0,0, 800,600, 0,0, 1);
xgeShapeExFillColor(content, 0x4FD8C2FF);

// 应用圆形裁剪
xgeShapeExClipShapeAdd(content, clipShape);
xgeShapeExDraw(content, 0.25f);  // 只显示圆形区域

完整代码

将以下代码保存为 ch59_main.c,编译后运行即可看到形状裁剪效果:

#include "xge.h"

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

    // 裁剪形状:圆形
    xge_shape_ex clipShape = NULL;
    xgeShapeExCreate(&clipShape);
    xgeShapeExAppendCircle(clipShape, 400, 300, 180, 180, 1);

    // 内容:彩色渐变矩形
    xge_shape_ex content = NULL;
    xgeShapeExCreate(&content);
    xgeShapeExAppendRect(content, 0,0, 800,600, 0,0, 1);
    xge_shape_ex_color_stop_t stops[] = {
        { 0.0f, 0x4FD8C2FF },
        { 1.0f, 0xFFB454FF },
    };
    xgeShapeExFillLinearGradient(content, 0,0, 800,600,
        XGE_SHAPE_EX_GRADIENT_USER_SPACE, stops, 2);

    // 应用圆形裁剪
    xgeShapeExClipShapeAdd(content, clipShape);
    xgeShapeExDraw(content, 0.25f);

    xgeShapeExDestroy(content);
    xgeShapeExDestroy(clipShape);
    return XGE_OK;
}

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

代码讲解

  • ClipShapeAdd:添加任意形状作为裁剪区域,只显示裁剪形状内的内容。
  • 模板缓冲:形状裁剪使用 GPU 模板测试,比矩形裁剪开销稍大。
  • 多个裁剪取交集:多次 ClipShapeAdd 结果越来越小。
  • 与 ClipRect 共存:矩形裁剪和形状裁剪同时生效。

要点与陷阱

  • 引用保持:内部 AddRef 裁剪形状,Destroy content 时自动释放。
  • 多个裁剪:多次 ClipShapeAdd 取交集(越来越小)。
  • 与 ClipRect 共存:矩形裁剪和形状裁剪同时生效。
  • 性能:形状裁剪使用模板缓冲,比矩形裁剪开销大。

进阶练习

  1. 用五角星路径裁剪图片,实现星形头像。
  2. 动态旋转裁剪形状,实现"万花筒"效果。
裁剪:形状裁剪效果
图:裁剪:形状裁剪渲染效果