2010-04-08 8 views
7

Ich versuche zeichnen semi-transparente Rechtecke auf einem unsichtbaren HWND. Wenn Sie jedoch das Fenster mit ID2D1HwndRenderTarget :: Clear löschen, wird das gesamte Fenster schwarz. Wenn ich also oben Rechtecke zeichne, sehen sie halbschwarz aus.Wie lösche ich ein Direct2D Renderziel vollständig transparent

Wenn ich nicht Clear() und nicht zeichnen, dann ist das Fenster unsichtbar, wie es sein sollte. Clear() ist der Schuldige hier; aber wenn ich es nicht benutze, vermasselt sich die Malerei ziemlich schlecht.

Hier ist der Code, den ich in meinem WindowProc bin mit:

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

Vielen Dank im Voraus!

+0

Hinweis: Ich habe Clearing versucht, mit 0,0 als die Opazität, mit genau dem gleichen Ergebnis. – Saul

+0

Können Sie ein Bild des transparenten Effekts einfügen? Ich will nur wissen, wie es funktioniert. – zdd

Antwort

2

Wenn Ihre RenderTarget Erstellen Sie D2D haben zu sagen, dass Sie wollen:

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

Nach diesem Aufruf Clear() mit einem Alpha-Wert von Null funktioniert gut.

+0

Sind Sie sicher, dass dies funktioniert, wird der Hintergrund des Renderziels ebenfalls schwarz, da das D2D1_ALPHA_MODE_PREMULTIPLIED-Flag die Alpha-Komponente mit jeder Farbe multipliziert, also wenn Sie das Null-Alpha verwenden bedeutet r * 0, g * 0, b * 0 was zu einem (0, 0, 0, 0) führt, das ist eine schwarze Farbe – zdd

+0

Ja, das funktioniert perfekt Sie müssen D2D1_ALPHA_MODE_PREMULTIPLIED verwenden, wenn Sie in ein Fenster zeichnen, und die Hintergrundfarbe ist nicht schwarz, es ist transparent – Noora

+1

es funktioniert nicht für mich, ich habe schwarzen Hintergrund mit Ihrer Methode, können Sie den Code in die Clear-Methode einfügen? oder fügen Sie einen ScreenSho ein t des transparenten Fensters? – zdd

2

Transparenz ist ein Problem. Das einzige Fenster, das die Transparenz pro Pixel unterstützt, sind WS_EX_LAYERED-Fenster. Diese Fenster wurden für Anwendungen wie Drag-Drop-Symbole entworfen, und das führt bei jeder anderen Verwendung zu Problemen.

Wenn Sie D2D mit WS_EX_LAYERED-Fenstern verwenden, müssen Sie ein DXGI-Renderziel verwenden. Zu EndDraw erhalten Sie eine DC aus dem Renderziel, dann übergeben Sie diese in das geschichtete Fenster und sagen dem geschichteten Fenster, sich selbst zu aktualisieren. (Versuchen Sie dies mit einem HWNDRenderTarget - es wird wahrscheinlich den Gerätetreiber zum Absturz bringen).

Ich vermute, dass Ihr Fenster transparent erscheint, weil es überhaupt nicht zeichnet.

Ein weiterer Fehler, auf den Sie stoßen können ... Wenn das Fenster ausreichend transparent ist, werden Mausklicks durch das darunter liegende Fenster geleitet.

+1

Nicht wahr. Erstens, WS_EX_LAYERED funktioniert gut, alle Arten von verrückten Fenstern wurden mit ihm erstellt, ohne größere Nachteile, außer mehr Code zum Handschreiben. WS_EX_LAYERED ist auch nicht die einzige Möglichkeit, die Transparenz pro Pixel zu erhöhen: Auf Windows Vista und höher gibt es WS_EX_COMPOSITED, das eine deutlich bessere Leistung bietet, da Sie direkt auf Aeros Direct3D-Oberfläche rendern. Wie bei den Mausklicks werden sie nur durch 0-Alpha-Pixel gehen. – Noora

+2

Das heißt, wenn Sie WS_EX_COMPOSITED mit 'DwmExtendFrameIntoClientArea (mWindow, &m);' 'mit einem Rand von -1 kombinieren, haben Sie ein klares Fenster, das direkt auf die D3D-Oberfläche zeigt. Sie müssen selbst Click-through-Tests durchführen Anders als bei Ebenenfenstern: – Noora

-1

D2D1 :: RenderTarget :: Clear() benötigt einen D2D1 :: ColorF() als Parameter als Farbe, mit der das Fenster gelöscht werden soll. alpha verwenden (in premultiplied-Modus) im Pixelformat

1

Verwenden Sie ID2D1DCRendTarget anstelle von ID2D1HwndRendTarget, binden Sie dann den Gerätekontext (DC) Ihres Fensters, bevor die Zeichnung beginnt.

Natürlich müssen Sie die WS_EX_LAYERED für Ihre Fenster setzen und dann SetLayeredWindowAttributes rufen Sie die transparente Farbe einzustellen:

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

Screenshot: