8
votes

Comment puis-je effacer une cible de rendement direct2D à une cible entièrement transparente

J'essaie de Dessiner des rectangles semi-transparents sur une HWND invisible forte>. Cependant, effacer la fenêtre avec id2d1hwndrendertarget :: Effacer code> fait tout simplement la fenêtre entière noir, alors quand je dessine des rectangles sur le dessus, ils ont l'air semi-noir.

Si je n'effectue pas () et Ne dessinez pas, alors la fenêtre est invisible, comme cela devrait être. Clear () est le coupable ici; Toutefois, si je ne l'utilise pas, la peinture de la peinture est très malade. p>

Voici le code que j'utilise dans ma fenêtreProc: p>

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


2 commentaires

Remarque: j'ai essayé de dégager avec 0,0 comme opacité, avec exactement le même résultat.


Pouvez-vous coller une image de l'effet transparent? Je veux juste savoir comment ça marche.


3 Réponses :


5
votes

La transparence est un problème. La seule fenêtre qui prend en charge la transparence par pixel sont WS_EX_LAYERED Windows. Ces fenêtres ont été conçues pour des utilisations telles que des icônes de drag-goutte, ce qui entraîne des problèmes dans tous les autres usages.

Utiliser D2D avec WS_EX_LAYERED Windows exige que vous utilisiez une cible de rendu DXGI. Pour enddrer, vous obtenez un CC hors de la cible de rendu puis transmettez-la dans la fenêtre en couches et indiquez la fenêtre en couches de se mettre à jour. (Essayez-le avec un hwndendertarget - il va probablement planter le pilote de périphérique).

Je soupçonne que votre fenêtre semble transparente car elle ne dessine pas du tout.

Un autre gotcha Vous pouvez rencontrer ... Si la fenêtre est suffisamment transparente, les clics de la souris passeront à la fenêtre sous-jacente.


2 commentaires

Pas vrai. Premièrement, WS_EX_LAYERED fonctionne simplement bien, toutes sortes de fenêtres de pluie ont été créées en l'utilisant, sans aucun inconvénient majeur, autres que davantage de code pour écrire. WS_EX_LAYERED n'est pas non plus le seul moyen de faire de la transparence par pixels plus, de Windows Vista et de la hausse, il existe WS_EX_COMPOSITÉD, qui présente des performances extrêmement meilleures, car vous rendant directement la surface Direct3D de Aero. Quant aux clics de la souris, ils ne passeront que les pixels 0-alpha.


C'est-à-dire que lorsque vous combinez ws_ex_composite avec Dwmextendframeintoclientarea (mwindow, & m); à l'aide d'une marge de -1, vous aurez une fenêtre transparente qui tire droit à la surface D3D. Vous devrez faire des tests sur vous-même lorsque vous utilisez cela, contrairement aux fenêtres en couches.



1
votes

Lors de la création de votre RenderTarget, vous devrez dire à D2D que vous souhaitez utiliser Alpha (en mode PremuLtIltiPlied) dans le format pixel: xxx

après cela, appeler effacer () avec une valeur alpha de zéro fonctionne parfaitement.


13 commentaires

Êtes-vous sûr que cela fonctionne? Cela effacera également le fond de la cible de rendu. Comme l'indicateur D2D1_ALPHA_MODE_PREMULLULLULLULTIPLULLULLULLULLULLULLULLULLULLULLULLULLULLULLULLULLULLULLULLULLULLULLULTURELLA TOCLE COULEUR, donc si vous utilisez Zero Alpha, cela signifie R * 0, G * 0, B * 0 qui entraîne un (0, 0, 0, 0), c'est un couleur noire.


Oui, cela fonctionne parfaitement. Vous devez utiliser d2d1_alpha_mode_premultiplied lors du dessin à une fenêtre et la couleur d'arrière-plan n'est pas noire, elle est transparente.


Cela ne fonctionne pas pour moi, j'ai eu des antécédents noirs avec votre méthode, pouvez-vous coller le code à la méthode claire? ou coller une capture d'écran de la fenêtre transparente?


Comment sur Terre une capture d'écran vous aiderait-elle? Bien sûr, voici comment vous appelez clairement: mrendertarget-> Begindraw (); mrendertarget-> settransform (D2D1 :: matrix3x2f :: identité ()); MRENDERTARGET-> Effacer (D2D1 :: Colorf (0, 0.0F)); MRENDERTARGET-> ENDDRAW (); J'espère que vous avez également veillé à ce que votre classe de fenêtre n'ait aucun pinceau de fond qui lui est attribué. Voir mes commentaires dans l'autre réponse pour le ws_ex_composited méthode sur Aero.


Vous ne travaillez toujours pas, je n'avais pas de brosse de fond pour ma fenêtre, dois-je faire des paramètres supplémentaires lors de la création de la fenêtre? Par exemple, le style de la fenêtre?


Je colle tout mon code ici, goo.gl/mvrqt , veuillez vous aider à voir où est faux.


Salut Noora, je veux toujours voir une photo de l'effet, vous avez dit que cela fonctionne parfaitement, pouvez-vous coller une image de la fenêtre transparente?


ZDD: Jetez un oeil à la page MSDN pour d2d1_alpha_mode ( bit.ly/u3dzm1 ) Sous le "mode alpha pour rendre les cibles de rendu". Le code de Noora devrait fonctionner parfaitement.


@Saul rennison, mais, en fait, cela ne fonctionne pas! Veuillez coller le code ou l'écran shot si cela fonctionne pour vous.


@Saulrennison, voudriez-vous accepter la réponse et annuler le bowvote? Vous savez que ma réponse fonctionne, et je n'ai pas envie de perdre la réputation, car une troisième personne agit comme un trou un trou.


@ZDD Comment avez-vous réussi cette transparence après tout? Votre explication serait tellement obligée. Merci.


@ Mk1 Je pense que vous devriez demander à Saul Rennison car cela ne fonctionne pas pour moi, j'ai demandé à l'affiche de coller des coups d'écran, mais pas encore de réponse.


@ZDD J'ai republié la question ici, j'espère accroître la traction de ce problème car elle n'a pas vraiment répondu clairement. Stackoverflow.com/ Questions / 18836921 / ...



4
votes

Utilisez ID2D1DCRENDERTARGET code> au lieu de id2d1hwndrendtarget code>, lie le contexte du périphérique (DC) de votre fenêtre avant le début du dessin.

Bien sûr, vous devrez définir le ws_ex_layered Code> Pour votre fenêtre, puis appelez SetLayeredWindowattributes CODE> Pour définir la couleur transparente: P>

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


0 commentaires