Das GDI-Rendering in direct2D ID2D1BitmapRenderTarget ist immer transparent

  • Ich möchte meine Movie-Rendering-Software von DirectDraw nach Direct2D portieren. Aufgrund von Kompatibilitätsproblemen muss das GDI-Rendering über dem Image erfolgen. Um die Leistung zu optimieren, möchte ich eine Art Backbuffer-Mechanismus implementieren, aber es scheint ein Problem mit den Alphakanalinformationen zu geben. Alle GDI-Zeichnungen erscheinen irgendwie transparent .

    Ich erstelle ein ID2D1HwndRenderTarget für mein Fensterhandle und eine ID2D1Bitmap , um die Bilder zu kopieren. Das Pixelformat der Bitmap ist DXGI_FORMAT_B8G8R8A8_UNORM , der Alpha-Modus ist D2D1_ALPHA_MODE_IGNORE . Das HwdRenderTarget ist GDI-kompatibel, daher sieht meine Renderfunktion in etwa wie folgt aus:

     HwdRenderTarget.BeginDraw;
    HwdRenderTarget.DrawBitMap(myBitMap);
    HwdRenderTarget.GetDC(dc);
    
    ... do GDI drawing here ...
    
    HwdRenderTarget.ReleaseDC();
    HwdRenderTarget.EndDraw;
     

    Diese Version funktioniert einwandfrei: Wenn die GDI-Objekte mit Volltonfarben gezeichnet werden, hat DrawTextEx-Text einen transparenten Hintergrund.

    Um die Leistung zu optimieren, möchte ich die GDI-Zeichnung in einem "Backbuffer" ausführen, so dass dies nur erforderlich ist zu tun, wenn sich etwas ändert. Ansonsten kann ich nur die zwischengespeicherte Bitmap rendern. Die Bitmap ist leer und transparent, daher sollten nur die gezeichneten Objekte sichtbar sein.

    Daher erstelle ich ein CompatibleRenderTarget ID2D1BitmapRenderTarget :

      HwdRenderTarget.CreateCompatibleRenderTarget(nil, nil, nil, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_GDI_COMPATIBLE, CompatibleRenderTarget);
     

    Jetzt mache ich das GDI-Rendering im CompatibleRenderTarget:

     CompatibleRenderTarget.BeginDraw;
    if Supports(CompatibleRenderTarget, ID2D1GdiInteropRenderTarget, GdiInteropRenderTarget) then
    begin
      GdiInteropRenderTarget.GetDC(D2D1_DC_INITIALIZE_MODE_CLEAR, dc);
    
      ... do GDI drawing here ...
    
      GdiInteropRenderTarget.ReleaseDC(fDstSize);
    end;
    GdiInteropRenderTarget := nil;
    CompatibleRenderTarget.EndDraw;
    CompatibleRenderTarget.GetBitmap(BackBuffer); // save the bitmap for drawing
     

    und meine Renderfunktion sieht jetzt so aus:

     HwdRenderTarget.BeginDraw;
    HwdRenderTarget.DrawBitMap(myBitMap);
    HwdRenderTarget.DrawBitmap(BackBuffer);
    HwdRenderTarget.EndDraw;
     

    Das Problem ist jetzt, dass alle GDI-Zeichnungen irgendwie transparent sind und der Transparenzgrad von den Werten der darunter liegenden Bildpixel abhängt. Dunkler Text erscheint auf einem dunklen Bildhintergrund dunkel, wird jedoch auf weißem Hintergrund weiß. Der Alphakanal wird jedoch nicht in GDI verwendet, und myBitmap enthält auch keine Alphainformationen.

    Woher kommen also die Alpha-Informationen? Hat jemand eine Idee? Vielen Dank im Voraus!

    Übrigens, verwenden Sie

    05 January 2011
    Norb
2 answers
  • Ich hatte das gleiche Problem. Folgendes hat für mich funktioniert (Sie müssen das Renderziel mit D2D1_ALPHA_MODE_IGNORE und nicht mit D2D1_ALPHA_MODE_PREMULTIPLIED erstellen).

     ID2D1HwndRenderTarget* pRenderTarget; // render target created sometime earlier
    
    D2D1_PIXEL_FORMAT pixelFormat = D2D1::PixelFormat(
        DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE);
    
    ID2D1BitmapRenderTarget* pOffscreenRT = NULL;
    pRenderTarget->CreateCompatibleRenderTarget(NULL, NULL, &pixelFormat,
        D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_GDI_COMPATIBLE, &pOffscreenRT);
     
                                        
    15 June 2011
    hex_omega
  • Es gibt ein schmutziges kleines Geheimnis beim Rendern mit GDI: Es wird immer den Alphakanal blockieren. Alles, was Sie damit zeichnen, setzt die Alpha-Werte in diesem Bereich auf Null. Ich vermute, es liegt daran, dass es nie für einen Alphakanal oder irgendeine Art von Compositing entwickelt wurde. Es wurde entwickelt, um direkt auf dem Bildschirm und auf Druckern zu rendern, wo keine Alphakanäle vorhanden sind.

    22 February 2012
    Rick Brewster