2010-04-08 12 views
7

Sto provando a disegnare rettangoli semitrasparenti su un HWND invisibile. Tuttavia, cancellare la finestra con ID2D1HwndRenderTarget :: Clear rende l'intera finestra nera, quindi quando disegno i rettangoli in cima, sembrano semi-neri.Come cancellare una destinazione di rendering Direct2D completamente trasparente

Se non si cancella() e non si disegna, la finestra è invisibile, come dovrebbe essere. Clear() è il colpevole qui; tuttavia, se non lo uso, la pittura incasina molto 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!

+0

Nota: ho cercato di compensazione con 0.0 come l'opacità, con esattamente lo stesso risultato. – Saul

+0

È possibile incollare un'immagine dell'effetto trasparente? Voglio solo sapere come funziona. – zdd

risposta

2

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 pari a zero funziona bene

+0

Sei sicuro che questo funzioni? Questo eliminerà lo sfondo della destinazione del rendering anche in nero, poiché il flag D2D1_ALPHA_MODE_PREMULTIPLIED moltiplicherà il componente alfa per ogni colore, quindi se usi l'alfa zero, quello significa r * 0, g * 0, b * 0 che produce un (0, 0, 0, 0), ovvero un colore nero – zdd

+0

Sì, funziona perfettamente. Devi utilizzare D2D1_ALPHA_MODE_PREMULTIPLIED quando disegni in una finestra, e il colore di sfondo non è nero, è trasparente – Noora

+1

non funziona per me, ho uno sfondo nero con il tuo metodo, puoi incollare il codice al metodo Clear o incollare uno screensho t della finestra trasparente? – zdd

2

La trasparenza è un problema. Le uniche finestre che supportano la trasparenza per pixel sono finestre WS_EX_LAYERED. Queste finestre sono state progettate per usi come le icone drag-drop e questo porta a problemi in ogni altro utilizzo.

L'utilizzo di D2D con WS_EX_LAYERED richiede l'uso di una destinazione di rendering DXGI. A EndDraw, si ottiene un DC fuori dal target di rendering, quindi lo si passa nella finestra a livelli e si dice alla finestra a strati di aggiornarsi. (Provalo con un HWNDRenderTarget - probabilmente causerà il crash del driver del dispositivo).

Sospetto che la finestra appaia trasparente perché non sta affatto disegnando.

Un altro trucchetto che potresti incontrare ... se la finestra è sufficientemente trasparente, i clic del mouse passeranno attraverso la finestra sottostante.

+1

Non vero. In primo luogo, WS_EX_LAYERED funziona bene, sono stati creati tutti i tipi di finestre stravaganti che lo utilizzano, senza grossi inconvenienti, se non più codice per scrivere a mano. WS_EX_LAYERED non è più l'unico modo per rendere più trasparente il per-pixel: su Windows Vista e verso l'alto, c'è WS_EX_COMPOSITED, che offre prestazioni incredibilmente migliori, dal momento che stai tornando direttamente alla superficie Direct 3D di Aero. Per quanto riguarda i clic del mouse, passeranno solo 0 pixel alfa. – Noora

+2

Cioè, quando si combina WS_EX_COMPOSITED con 'DwmExtendFrameIntoClientArea (mWindow, &m);' utilizzando un margine di -1, si avrà una finestra chiara che si indirizza direttamente alla superficie D3D. Dovrai fare dei test click-through quando – Noora

-1

D2D1 :: RenderTarget :: Clear() richiede un pass D2D1 :: ColorF() come parametro, come il colore con cui deselezionare la finestra.

1

Utilizzare ID2D1DCRendTarget anziché ID2D1HwndRendTarget, quindi associare il contesto del dispositivo (DC) della finestra prima dell'inizio del disegno.

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

Screenshot:

Problemi correlati