2010-04-08 70 views
7

我正在嘗試在隱形HWND上繪製半透明矩形。但是,使用ID2D1HwndRenderTarget :: Clear清除窗口只會使整個窗口變黑,所以當我在頂部繪製矩形時,它們看起來是半黑色的。如何清除Direct2D渲染目標以完全透明

如果我不清除()並不繪製,那麼該窗口是不可見的,因爲它應該是。 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(); 

提前感謝!

+0

注:我已經試過0.0作爲結算不透明度,結果完全相同。 – Saul 2010-04-08 22:25:01

+0

您可以粘貼透明效果的圖片嗎?我只是想知道它是如何工作的。 – zdd 2012-11-23 02:04:38

回答

2

在創建渲染目標,你必須告訴你想要的像素格式使用α(預乘模式)D2D:

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

在此之後,調用Clear()爲零的阿爾法值工作得很好。

+0

你確定這個工作嗎?這將清除渲染目標的背景爲黑色,因爲D2D1_ALPHA_MODE_PREMULTIPLIED標誌會將alpha分量乘以每種顏色,所以如果你使用零alpha,意味着r * 0,g * 0,b * 0會導致一個(0,0,0,0),這是一種黑色 – zdd 2012-10-26 13:10:02

+0

是的,這個效果非常好,在繪製窗口時需要使用D2D1_ALPHA_MODE_PREMULTIPLIED,背景顏色不是黑色,它是透明的 – Noora 2012-10-27 15:33:15

+1

它不適用於我,我用你的方法得到黑色背景,你可以將代碼粘貼到Clear方法嗎?或者粘貼screensho t的透明窗口? – zdd 2012-10-28 03:55:09

2

透明度是一個問題。支持每像素透明度的唯一窗口是WS_EX_LAYERED窗口。這些窗口是爲拖放圖標等用途而設計的,這會導致其他用途中的問題。

將D2D與WS_EX_LAYERED窗口結合使用需要您使用DXGI渲染目標。對於EndDraw,你從渲染目標中獲得一個DC,然後將其傳遞給分層窗口,並告訴分層窗口自行更新。 (試試用HWNDRenderTarget - 它可能會導致設備驅動程序崩潰)。

我懷疑你的窗口看起來是透明的,因爲它根本不是繪圖。

您可能遇到的另一個問題......如果窗口足夠透明,鼠標點擊將穿過它到底層窗口。

+1

不正確。首先,WS_EX_LAYERED工作得很好,使用它創建了各種古怪的窗口,沒有任何主要的缺點,除了更多的手寫代碼之外。 WS_EX_LAYERED也不是唯一能夠實現每像素透明度的方法:在Windows Vista和更高版本中,WS_EX_COMPOSITED具有非常好的性能,因爲您直接渲染到Aero的Direct3D表面。至於鼠標點擊,它們只會經過0像素。 – Noora 2012-05-16 22:34:35

+2

也就是說,當您將WS_EX_COMPOSITED與'DwmExtendFrameIntoClientArea(mWindow,&m);',使用-1的邊距組合在一起時,您將擁有一個直接繪製D3D曲面的清晰窗口,您必須在自己進行點擊測試時使用這個,不像分層窗口 – Noora 2012-05-25 11:08:39

-1

D2D1 :: RenderTarget :: Clear()需要一個D2D1 :: ColorF()作爲參數傳入,作爲清除窗口的顏色。

1

使用ID2D1DCRendTarget而不是ID2D1HwndRendTarget,然後在繪製開始前綁定窗口的設備上下文(DC)。

當然,你需要設置WS_EX_LAYERED爲你的窗口,然後調用SetLayeredWindowAttributes設置透明色:

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

截圖: