How do I clear a Direct2D render target to fully transparent

你离开我真会死。 提交于 2019-11-28 03:37:08

问题


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!


回答1:


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.




回答2:


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.




回答3:


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

Of course, you 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:



来源:https://stackoverflow.com/questions/2603276/how-do-i-clear-a-direct2d-render-target-to-fully-transparent

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!