如何清除Direct2D渲染目标以使其完全透明

我试图在一个看不见的HWND上绘制半透明的矩形 。 但是,使用ID2D1HwndRenderTarget :: Clear清除窗口会使整个窗口变黑,所以当我在顶部绘制矩形时,它们看起来是半黑色的。

如果我不清除()并且不绘制,那么窗口是不可见的,因为它应该是。 Clear()是罪魁祸首; 但是,如果我不使用它,那么绘画就会非常糟糕。

这是我在WindowProc中使用的代码:

case WM_PAINT: // Begin drawing pRenderTarget->BeginDraw(); pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity()); // Clear the window pRenderTarget->Clear(); // Paint the panel and its children D2DSurface()->StartPainting(); { D2DSurface()->PaintTraverse(panel); } D2DSurface()->FinishPainting(); // Finish drawing HRESULT hr = plat->pRenderTarget->EndDraw(); 

提前致谢!

在创建RenderTarget时,您必须告诉D2D您要以像素格式使用alpha(在预乘模式下):

  HRESULT hr = mD2DFactory->CreateHwndRenderTarget( D2D1::RenderTargetProperties( D2D1_RENDER_TARGET_TYPE_DEFAULT, D2D1::PixelFormat( DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED ) ), D2D1::HwndRenderTargetProperties( mWindow, size ), &mRenderTarget ); 

在此之后,使用alpha值为零调用Clear()可以正常工作。

透明度是一个问题。 支持每像素透明度的唯一窗口是WS_EX_LAYERED窗口。 这些窗口专为拖放图标等用途而设计,这会导致其他所有用途出现问题。

将D2D与WS_EX_LAYERED窗口一起使用需要使用DXGI渲染目标。 对于EndDraw,您将从渲染目标中获取DC,然后将其传递到分层窗口并告知分层窗口自行更新。 (尝试使用HWNDRenderTarget – 它可能会崩溃设备驱动程序)。

我怀疑你的窗户看起来很透明,因为它根本没有画画。

你可能遇到另一个问题……如果窗口足够透明,鼠标点击将通过它进入底层窗口。

使用ID2D1DCRendTarget而不是ID2D1HwndRendTarget ,然后在绘制开始之前绑定窗口的设备上下文(DC)。

当然,您需要为窗口设置WS_EX_LAYERED ,然后调用SetLayeredWindowAttributes来设置透明颜色:

 SetLayeredWindowAttributes(hWnd, RGB(0, 0, 0), 0, LWA_COLORKEY); 

截图:

D2D1 :: RenderTarget :: Clear()需要传入D2D1 :: ColorF()作为参数,作为清除窗口的颜色。