Chapter 55 · ShapeEx 进阶

遮罩:Alpha / Luma

遮罩用另一个 Shape 或 Scene 的 Alpha/Luma 通道控制当前图形的可见区域。

55

概念

  • Alpha 遮罩:用遮罩图形的 Alpha 通道作为蒙版(透明=隐藏)。
  • Luma 遮罩:用遮罩图形的亮度(灰度值)作为蒙版。
  • 目标类型:可以是单个 Shape 或整个 Scene。

API 速查

常量 / 函数说明
#define XGE_SHAPE_EX_MASK_ALPHA 0Alpha 通道遮罩
#define XGE_SHAPE_EX_MASK_LUMA 1亮度遮罩
int xgeShapeExMaskShapeSet(xge_shape_ex pShape, xge_shape_ex pTarget, int iMethod)用 Shape 作为遮罩
int xgeShapeExMaskSceneSet(xge_shape_ex pShape, xge_shape_ex_scene pTarget, int iMethod)用 Scene 作为遮罩

编译本章示例

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

示例:圆形渐隐遮罩

// 遮罩:径向渐变圆(中心不透明→边缘透明)
xge_shape_ex mask = NULL;
xgeShapeExCreate(&mask);
xgeShapeExAppendCircle(mask, 400, 300, 200, 200, 1);

xge_shape_ex_color_stop_t stops[] = {
    { 0.0f, 0xFFFFFFFF },  // 中心不透明
    { 1.0f, 0xFFFFFF00 },  // 边缘全透明
};
xgeShapeExFillRadialGradient(mask, 400,300,200, 400,300,
    XGE_SHAPE_EX_GRADIENT_USER_SPACE, stops, 2);

// 被遮罩的图形:彩色矩形
xge_shape_ex content = NULL;
xgeShapeExCreate(&content);
xgeShapeExAppendRect(content, 100,100, 600,400, 0,0, 1);
xgeShapeExFillColor(content, 0x4FD8C2FF);

// 应用 Alpha 遮罩
xgeShapeExMaskShapeSet(content, mask, XGE_SHAPE_EX_MASK_ALPHA);
xgeShapeExDraw(content, 0.25f);

完整代码

将以下代码保存为 ch55_main.c,编译后运行即可看到圆形渐隐遮罩效果:

#include "xge.h"

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

    // 遮罩:径向渐变圆(中心不透明→边缘透明)
    xge_shape_ex mask = NULL;
    xgeShapeExCreate(&mask);
    xgeShapeExAppendCircle(mask, 400, 300, 200, 200, 1);
    xge_shape_ex_color_stop_t stops[] = {
        { 0.0f, 0xFFFFFFFF },
        { 1.0f, 0xFFFFFF00 },
    };
    xgeShapeExFillRadialGradient(mask, 400,300,200, 400,300,
        XGE_SHAPE_EX_GRADIENT_USER_SPACE, stops, 2);

    // 被遮罩的图形:彩色矩形
    xge_shape_ex content = NULL;
    xgeShapeExCreate(&content);
    xgeShapeExAppendRect(content, 100,100, 600,400, 0,0, 1);
    xgeShapeExFillColor(content, 0x4FD8C2FF);

    // 应用 Alpha 遮罩
    xgeShapeExMaskShapeSet(content, mask, XGE_SHAPE_EX_MASK_ALPHA);
    xgeShapeExDraw(content, 0.25f);

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

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

代码讲解

  • mask Shape:径向渐变圆,中心 Alpha=FF(不透明)→边缘 Alpha=00(全透明)。
  • MaskShapeSet:将 mask 作为 content 的遮罩,遮罩本身不绘制到画面。
  • MASK_ALPHA:用遮罩的 Alpha 通道决定显示程度。
  • MASK_LUMA:用颜色亮度决定(白=显示,黑=隐藏)。
  • 引用保持:内部 AddRef 遮罩目标,Destroy content 时自动释放。

要点与陷阱

  • 遮罩不绘制自身:mask Shape 仅作为蒙版数据,不会出现在画面中。
  • Alpha vs Luma:Alpha 看透明度,Luma 看颜色亮度(白=显示,黑=隐藏)。
  • 引用保持:内部会 AddRef 遮罩目标,Destroy content 时自动释放。
  • 一次一个:重复调用 MaskShapeSet 会替换之前的遮罩。

进阶练习

  1. 用文字 Shape 作为遮罩,实现"文字内显示图片"效果。
  2. 动态移动遮罩位置,实现聚光灯效果。
遮罩:Alpha / Luma效果
图:遮罩:Alpha / Luma渲染效果