2010-04-08 12 views
7

Estoy tratando de dibujar rectángulos semitransparentes en un HWND invisible. Sin embargo, borrar la ventana con ID2D1HwndRenderTarget :: Clear solo hace que toda la ventana se vuelva negra, así que cuando dibujo rectángulos en la parte superior, se ven semi-negros.Cómo borro un destino de renderizado Direct2D a totalmente transparente

Si no borro() y no dibujo, entonces la ventana es invisible, como debería ser. Clear() es el culpable aquí; sin embargo, si no lo uso, la pintura se estropea bastante.

Aquí está el código que estoy usando en mi 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(); 

Gracias de antemano!

+0

Nota: He tratado de despejar con 0.0 como la opacidad, con exactamente el mismo resultado. – Saul

+0

¿Puedes pegar una imagen del efecto transparente? Solo quiero saber cómo funciona. – zdd

Respuesta

2

Al crear su RenderTarget, tendrá que contar D2D que desea utilizar alfa (en modo premultiplicado) en el formato de píxel:

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

Después de esto, llamando Clear() con un valor alfa de cero funciona bien

+0

¿Estás seguro de que esto funciona? Esto borrará el fondo del destino del renderizado también en negro, ya que el indicador D2D1_ALPHA_MODE_PREMULTIPLIED multiplicará el componente alfa por cada color, por lo que si usas el alfa cero, eso significa r * 0, g * 0, b * 0 que resulta en un (0, 0, 0, 0), que es un color negro – zdd

+0

Sí, esto funciona perfectamente. Necesita dibujar D2D1_ALPHA_MODE_PREMULTIPLIED cuando se dibuja en una ventana, y el color de fondo no es negro, es transparente. – Noora

+1

no funciona para mí, tengo fondo negro con su método, ¿puede pegar el código en el método Clear? o pegar un screensho t de la ventana transparente? – zdd

2

La transparencia es un problema. La única ventana que admite la transparencia por píxel son ventanas WS_EX_LAYERED. Estas ventanas fueron diseñadas para usos como iconos de arrastrar y soltar, y eso genera problemas en cualquier otro uso.

El uso de D2D con ventanas WS_EX_LAYERED requiere que utilice un destino de renderizado DXGI. Para EndDraw, obtienes un DC del objetivo de renderización y luego lo pasas a la ventana en capas y le dices a la ventana en capas que se actualice a sí misma. (Pruebe esto con HWNDRenderTarget: probablemente bloqueará el controlador del dispositivo).

Sospecho que su ventana parece transparente porque no está dibujando en absoluto.

Otro problema con el que se puede topar ... si la ventana es lo suficientemente transparente, los clics del mouse lo pasarán a la ventana subyacente.

+1

No es cierto. En primer lugar, WS_EX_LAYERED funciona bien, se han creado todo tipo de ventanas extravagantes utilizando, sin mayores inconvenientes, aparte de más código para escribir a mano. WS_EX_LAYERED tampoco es la única forma de hacer más transparencia por píxel: en Windows Vista y en adelante, WS_EX_COMPOSITED, que ofrece un rendimiento enormemente mejor, ya que se procesa directamente en la superficie Direct3D de Aero. En cuanto a los clics del mouse, solo pasarán por píxeles 0-alfa. – Noora

+2

Es decir, cuando combina WS_EX_COMPOSITED con 'DwmExtendFrameIntoClientArea (mWindow, &m);' usando un margen de -1, tendrá una ventana despejada que se dibuja directamente en la superficie del D3D. Deberá realizar las pruebas de clics usted mismo cuando usando esto, a diferencia de las ventanas en capas. – Noora

-1

D2D1 :: RenderTarget :: Clear() requiere un pase D2D1 :: ColorF() como parámetro, como el color con el que borrar la ventana.

1

Use ID2D1DCRendTarget en lugar de ID2D1HwndRendTarget, luego vincule el contexto del dispositivo (DC) de su ventana antes de que comience el dibujo.

Por supuesto, es necesario establecer el WS_EX_LAYERED para su ventana y luego llamar SetLayeredWindowAttributes para establecer el color transparente:

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

Captura de pantalla:

Cuestiones relacionadas