Chapter 56 · ShapeEx 进阶

遮罩:复合运算

MaskCompositeScene 在 Scene 级遮罩渲染时执行复合运算,支持自定义源绘制回调。

56

概念

  • 复合遮罩:将 Scene 遮罩与源内容进行复合运算后输出。
  • 自定义绘制回调:pSourceDraw 允许你提供任意绘制逻辑作为源。
  • 输出混合:iOutputBlend 控制复合结果与帧缓冲的混合方式。

API 速查

函数说明
int xgeShapeExMaskCompositeScene(xge_shape_ex_scene pMaskScene, int iMethod, int iOutputBlend, xge_rect_t tSourceBounds, xge_shape_ex_draw_proc pSourceDraw, void* pSourceUser, float fTolerance, const xge_shape_ex_matrix_t* pParentMatrix, int bScreenSpace)Scene 遮罩复合运算

编译本章示例

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

示例:Scene 遮罩复合

// 自定义源绘制回调
static void DrawSource(void* pUser) {
    xge_shape_ex src = (xge_shape_ex)pUser;
    xgeShapeExDraw(src, 0.25f);
}

// 构建遮罩 Scene
xge_shape_ex_scene maskScene = NULL;
xgeShapeExSceneCreate(&maskScene);
xgeShapeExSceneAdd(maskScene, g_maskShape);

// 执行复合运算
xge_rect_t bounds = { 0, 0, 800, 600 };
xgeShapeExMaskCompositeScene(maskScene,
    XGE_SHAPE_EX_MASK_ALPHA,
    XGE_BLEND_ALPHA,
    bounds,
    DrawSource, g_contentShape,
    0.25f, NULL, 0);

完整代码

将以下代码保存为 ch56_main.c,编译后运行即可看到 Scene 遮罩复合运算效果:

#include "xge.h"

static void DrawSource(void* pUser) {
    xge_shape_ex src = (xge_shape_ex)pUser;
    xgeShapeExDraw(src, 0.25f);
}

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

    // 遮罩形状:径向渐变圆
    xge_shape_ex maskShape = NULL;
    xgeShapeExCreate(&maskShape);
    xgeShapeExAppendCircle(maskShape, 400, 300, 200, 200, 1);
    xge_shape_ex_color_stop_t stops[] = {
        { 0.0f, 0xFFFFFFFF },
        { 1.0f, 0xFFFFFF00 },
    };
    xgeShapeExFillRadialGradient(maskShape, 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);

    // 构建遮罩 Scene
    xge_shape_ex_scene maskScene = NULL;
    xgeShapeExSceneCreate(&maskScene);
    xgeShapeExSceneAdd(maskScene, maskShape);

    // 执行复合运算
    xge_rect_t bounds = { 0, 0, 800, 600 };
    xgeShapeExMaskCompositeScene(maskScene,
        XGE_SHAPE_EX_MASK_ALPHA,
        XGE_BLEND_ALPHA,
        bounds, DrawSource, content,
        0.25f, NULL, 0);

    xgeShapeExSceneDestroy(maskScene);
    xgeShapeExDestroy(content);
    xgeShapeExDestroy(maskShape);
    return XGE_OK;
}

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

代码讲解

  • MaskCompositeScene:高级遮罩 API,支持多 Shape 组合遮罩 + 自定义源绘制回调。
  • DrawSource 回调:在离屏缓冲中执行,绘制源内容。
  • Scene 遮罩:可包含多个 Shape,组合成复杂形状蒙版。
  • ScreenSpace:0 = 遮罩坐标随父矩阵变换,1 = 屏幕空间固定。

要点与陷阱

  • 高级 API:大多数场景用 MaskShapeSet/MaskSceneSet 即可(第 55 章)。
  • ScreenSpace:1 = 遮罩坐标在屏幕空间,不随父矩阵变换。
  • 回调约定:pSourceDraw 在离屏缓冲中执行,绘制源内容。
  • 性能:复合运算需要离屏渲染,避免每帧对大量 Shape 使用。

进阶练习

  1. 用 Luma 遮罩 + 灰度渐变实现"老照片"边缘褪色效果。
  2. 组合多个 Shape 到 Scene 遮罩,实现复杂形状蒙版。
遮罩:复合运算效果
图:遮罩:复合运算渲染效果