Come faccio a cancellare un Direct2D rendering obiettivo di completamente trasparente
-
25-09-2019 - |
Domanda
Sto cercando di disegnare rettangoli semi-trasparente su un HWND invisibile . Tuttavia, aprendo la finestra con ID2D1HwndRenderTarget :: Clear fa solo l'intera finestra nera, così quando ho disegnare rettangoli in alto, sembrano semi-nero.
Se non lo faccio Clear () e non disegno, la finestra è invisibile, come dovrebbe essere. Cancella () è il colpevole qui; se io non lo uso poi pittura scombina piuttosto male.
Ecco il codice che sto usando nella mia 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();
Grazie in anticipo!
Soluzione
Quando si crea il RenderTarget, dovrete dire D2D che si desidera utilizzare alfa (in modalità premoltiplicato) nel formato di pixel:
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 );
Dopo questo, chiamando Clear()
con un valore alfa di zero funziona bene.
Altri suggerimenti
La trasparenza è un problema. L'unica finestra che il sostegno trasparenza per pixel sono Windows WS_EX_LAYERED. Queste finestre sono state progettate per usi come le icone drag-drop, e che porta a problemi in ogni altro uso.
Uso D2D con finestre WS_EX_LAYERED richiede l'utilizzo di un DXGI rende bersaglio. Per EndDraw, si ottiene un DC fuori del target render poi passare che nella finestra a più livelli e dire la finestra a più livelli di aggiornarsi. (Prova questo con un HWNDRenderTarget - probabilmente in crash il driver di periferica).
Ho il sospetto che la vostra finestra appare trasparente perché non è il disegno a tutti.
Un altro punto che si può incorrere in ... se la finestra è sufficientemente trasparente, clic del mouse sarà passare attraverso di essa alla finestra sottostante.
Usa ID2D1DCRendTarget
invece di ID2D1HwndRendTarget
, poi si legano il contesto di periferica (DC) della finestra prima di trarre inizio.
Naturalmente, è necessario impostare la WS_EX_LAYERED
per la finestra e quindi chiamare SetLayeredWindowAttributes
per impostare il colore trasparente:
SetLayeredWindowAttributes(hWnd, RGB(0, 0, 0), 0, LWA_COLORKEY);