如何将 Direct2D 渲染目标清除为完全透明

发布于 2024-08-28 08:33:32 字数 727 浏览 15 评论 0原文

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

如果我不 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();

提前致谢!

I'm trying to draw semi-transparent rectangles on an invisible HWND. However, clearing the window with ID2D1HwndRenderTarget::Clear just makes the entire window black, so when I draw rectangles on top, they look semi-black.

If I don't Clear() and don't draw, then the window is invisible, as it should be. Clear() is the culprit here; however if I don't use it then painting messes up pretty badly.

Here's the code I'm using in my 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();

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

柠栀 2024-09-04 08:33:40

创建 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() 就可以了美好的。

When creating your RenderTarget, you'll have to tell D2D that you want to use alpha (in premultiplied mode) in the pixel format:

  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 );

After this, calling Clear() with an alpha value of zero works just fine.

唯憾梦倾城 2024-09-04 08:33:36

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

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

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

屏幕截图:

Use ID2D1DCRenderTarget instead of ID2D1HwndRendTarget, then bind the device context (DC) of your window before drawing begins.

Of course, you will need to set the WS_EX_LAYERED for your window and then call SetLayeredWindowAttributes to set the transparent color:

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

Screenshot:

三生殊途 2024-09-04 08:33:35

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

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

我怀疑你的窗口看起来是透明的,因为它根本没有绘制。

您可能会遇到的另一个问题...如果窗口足够透明,鼠标单击将穿过它到达底层窗口。

Transparency is a problem. The only window that support per-pixel transparency are WS_EX_LAYERED windows. These windows were designed for uses like drag-drop icons, and that leads to problems in every other usage.

Using D2D with WS_EX_LAYERED windows requires that you use a DXGI render target. To EndDraw, you get a DC out of the render target then pass that into the layered window and tell the layered window to update itself. (Try this with a HWNDRenderTarget - it will probably crash the device driver).

I suspect your window appears transparent because it's not drawing at all.

Another gotcha you may run into... if the window is sufficiently transparent, mouse clicks will go through it to the underlying window.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文