Double Buffering (Bildschirmflackern)



  • Hi ! 🙂

    ich arbeite gerade an einem Programm, welches GDI+ zur Grafikausgabe in Windows
    verwendet. Es handelt sich um eine Dialogfeldbasierte MFC Anwendung. Da ich per
    Maus Bilder verschieben möchte kommt es nun leider zu einem starken flackern,
    was man mithilfe von diesem Double Buffering beheben kann. Ich weiß nur nicht
    genau wie ich es einbauen soll. Bisher zeichne ich alles so :

    Graphics g(m_hWnd);		// GDI+ Zeichenkontext
    
    g.DrawImage(Bild, x, y, size_x, size_y);
    

    Graphics ist also mein Kontext für Zeichenoperationen. Jetzt müsste ich doch
    um Double Buffering zu erreichen einen 2. Kontext erstellen mit den gleichen
    Eigenschaften wie der von meinem Fenster (m_hWnd), dort dann alle Zeichenoperationen drin ausführen und wenn alles fertig ist diesen "Buffer - Kontext" in meinen Fenster Kontext kopieren.

    Wie stelle ich das jetzt am besten an ?! Ich habe schon ein Tutorial dafür
    gefunden, allerdings arbeiten die dort mit der WinAPI deshalb seh ich nicht
    so wirklich durch. (http://www.klangwerker.de/php/show.php?path=developer/german&doc=g_double_buf1&update=1)

    Wäre echt super wenn mir jemand auf die Sprünge helfen könnte.



  • Hm... Double Buffering...
    also mein Tipp: erstell' ein zum Ausgabegerät kompatibles Bitmap, in etwa so groß wie deine Zeichenfläche. Erzeuge einen zum Ausgabegerät kompatiblen Gerätekontext XYZ. Selektiere das Bitmap in den Gerätekontext XYZ. Mal' nicht in deine Zeichenfläche, sondern ins Bitmap. Zum Auffrischen des Bildes blittest (kopierst) du das Bitmap dann in deine eigentliche Zeichenfläche hinein. Fertig.

    Referenzen:
    CBitmap::CreateCompatibleBitmap(...)
    CDC::CreateCompatibleDC(...)
    CDC::SelectObject(...)
    CDC::BitBlt(...)



  • wollte nur kurz sagen das ich mein Problem gelöst hab :

    CRect rect;	        // Zeichenbereich
    GetClientRect(&rect);	// Zeichenbereich vom Fenster zuweisen
    
    Rect rc(rect.left,rect.top,rect.right,rect.bottom);
    Bitmap bmp(rect.right,rect.bottom);	
    
    Graphics* graph = Graphics::FromImage(&bmp);	// Backbuffer
    
    SolidBrush brush(Color(255, 255,255, 255));		
    graph->FillRectangle(&brush, rc);	// Backbuffer füllen
    

    dann zeichne ich über

    graph->DrawImage....
    

    alles was ich will und zeichne dann den Backbuffer per

    g.DrawImage(&bmp,rect.left,rect.top,rect.right,rect.bottom);
    

    auf den Bildschirm 🙂

    Klappt wunderbar und das flimmern gehört der Vergangenheit an 🙂

    Falls sich noch wer dafür interessiert hier ist ein ein gutes Beispiel dafür :

    http://www.codeproject.com/vcpp/gdiplus/gdiplus.asp?df=100

    Falls jemand noch eine effektivere Möglichkeit weiß bin ich natürlich dafür
    offen !

    Grüße !


Anmelden zum Antworten