You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Direct2D中清除右侧圆形区域以实现桌面穿透显示

问题场景

现有一个支持透明效果的分层窗口,使用Direct2D绘制内容:

  • 窗口背景为半透明蓝色(alpha=0.5)
  • 左侧是不透明红色圆形
  • 右侧是半透明绿色圆形,当前透过绿色圆形能看到左侧红色圆形及窗口蓝色背景

需求:绘制右侧绿色圆形前,先清除该区域的窗口内容,使右侧圆形位置能直接透出桌面,最终透过半透明绿色圆形看到的是桌面而非窗口内的其他内容。

原始代码

// ID2D1DCRenderTarget* pDCRT;
// ID2D1SolidColorBrush* pBrush;

pDCRT->Clear(D2D1::ColorF(D2D1::ColorF(0, 0, 1, 0.5f)));

D2D1_ELLIPSE pe1 = D2D1::Ellipse(D2D1::Point2F(200, 200), 150, 150); 
D2D1_ELLIPSE pe2 = D2D1::Ellipse(D2D1::Point2F(350, 200), 150, 150);

pDCRT->CreateSolidColorBrush(D2D1::ColorF(1, 0, 0, 1), &pBrush);    
pDCRT->FillEllipse(pe1, pBrush); 

pDCRT->CreateSolidColorBrush(D2D1::ColorF(0, 1, 0, 0.5f), &pBrush);       
pDCRT->FillEllipse(pe2, pBrush);

原始效果

图像说明

解决方案

核心思路

要让窗口局部透出桌面,需将该区域的窗口像素设置为完全透明(alpha=0),结合Direct2D的混合模式可实现这一效果:

  1. 使用D2D1_COMPOSITE_MODE_DEST_OUT混合模式,在目标区域绘制不透明内容,会将该区域的窗口像素alpha置为0,形成“透明洞”透出桌面。
  2. 恢复默认混合模式后,再绘制半透明绿色圆形,此时绿色圆形会叠加在桌面内容之上。

修改后的代码

// ID2D1DCRenderTarget* pDCRT;
// ID2D1SolidColorBrush* pBrush;
// 需提前实现SafeRelease宏:#define SafeRelease(p) { if(p) { (p)->Release(); (p)=nullptr; } }

pDCRT->Clear(D2D1::ColorF(D2D1::ColorF(0, 0, 1, 0.5f)));

D2D1_ELLIPSE pe1 = D2D1::Ellipse(D2D1::Point2F(200, 200), 150, 150); 
D2D1_ELLIPSE pe2 = D2D1::Ellipse(D2D1::Point2F(350, 200), 150, 150);

// 绘制左侧不透明红色圆形
pDCRT->CreateSolidColorBrush(D2D1::ColorF(1, 0, 0, 1), &pBrush);    
pDCRT->FillEllipse(pe1, pBrush); 
SafeRelease(&pBrush);

// 关键:清除右侧区域,透出桌面
pDCRT->CreateSolidColorBrush(D2D1::ColorF(1, 1, 1, 1), &pBrush);
// 设置混合模式为DEST_OUT,将目标区域像素置为完全透明
pDCRT->SetCompositeMode(D2D1_COMPOSITE_MODE_DEST_OUT);
pDCRT->FillEllipse(pe2, pBrush);
// 恢复默认混合模式,避免影响后续绘制
pDCRT->SetCompositeMode(D2D1_COMPOSITE_MODE_SRC_OVER);
SafeRelease(&pBrush);

// 绘制右侧半透明绿色圆形(此时叠加在桌面之上)
pDCRT->CreateSolidColorBrush(D2D1::ColorF(0, 1, 0, 0.5f), &pBrush);       
pDCRT->FillEllipse(pe2, pBrush);
SafeRelease(&pBrush);

注意事项

  • 窗口必须是分层窗口:创建窗口时添加WS_EX_LAYERED扩展样式,并通过SetLayeredWindowAttributes或UpdateLayeredWindow启用透明,这是透出桌面的基础条件。
  • 及时释放Direct2D资源:每次创建画刷后要调用Release()避免内存泄漏,示例中用SafeRelease宏简化操作。

内容的提问来源于stack exchange,提问作者Klein Moretti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 12:43:28