GDI Plus Bild aus dem Backbuffer zeichen

  • Ich weiß, gefühlt schon 100 mal behandelt, leider konnte mir bisher kein Beitrag im Forum so richtig weiterhelfen.

    Ich spiele grade etwas mit GDI Plus rum und versuche Buttons aus transparenten PNG Bilder zu erstellen. Ab und an kommt es beim neuzeichnen der png Bilder zu einem Flackern. Ich hörte von diesem Backbuffer, bekomme ihn aber einfach nicht umgesetzt.

    Hier mal ein Beispiel, $Pic bitte anpassen:


    Im eigentlichen Programm zeichne ich natürlich nicht alle 500ms neu, ist nur ein Beispiel.
    Kann mir bitte jemand auf die Sprünge helfen.

    Edit: Das Beispiel ist vielleicht etwas unglücklich gewählt, ein Schuh wird draus wenn es nicht jedes mal wieder neu in den Backbuffer galaden wird sondern nur aus dem Backbuffer neu gezeichnet wird.
    Mir geht es hauptsächlich um das WIE in den Backbuffer und WIE von dort aufs GUI zeichen.

    2 Mal editiert, zuletzt von Gofel (9. Juli 2015 um 16:00)

  • Wenn du tranparente PNG Bilder als Buttons verwenden möchtest, würde ich dir eher empfehlen die PNGs in den Button zu kopieren, um einfach das Neuzeichen zu vermeiden.

    So was zum Beispiel:

    Funzt ab Vista. Für WinXP muss man einen Workaround machen, damit die Hintergrundfarbe des transparenten Bildes nicht schwarz ist.

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

    Einmal editiert, zuletzt von UEZ (9. Juli 2015 um 16:49)

  • ^^ Ein Backbuffer ist im Prinzip nur ein leeres Bild in das du hineinzeichnest.
    Wenn du dann mim Zeichnen fertig bist zeichnest du das Bild auf die GUI.

    Spoiler anzeigen

    Wenn du den Backbuffer zB aber mehrmals beschreibst, musst du ihn mit _GDIPlus_GraphicsClear() vorher aber noch "leeren", da ja noch das Bild vom verherigen Frame drinnen ist.

    Spoiler anzeigen

    Ich empfehl dir übrigens auch das was UEZ gesagt hat zu machen. Das ganze GUI-Zeugs mit dem Testen ist die Maus jz auf dem Button oder nicht ist einfach seeeehr umfangreich und kann sich mit solchen Tricks recht leicht umgehen lassen. Zudem sind dann solche "eigenen" Controls nicht so leicht zu automatisieren :D

    Einmal editiert, zuletzt von CentuCore (9. Juli 2015 um 17:23)

  • Das ganze GUI-Zeugs mit dem Testen ist die Maus jz auf dem Button oder nicht ist einfach seeeehr umfangreich und kann sich mit solchen Tricks recht leicht umgehen lassen. Zudem sind dann solche "eigenen" Controls nicht so leicht zu automatisieren :D

    Das habe ich bisher mit einem Pseudo Control gelöst. Event auf leeres GUICtrlCreatePic(), selbe stelle mit GDI Plus übermalen.
    Dein Beispiel hilft mir leider nicht weiter, du backbufferst ein _GraphicsDrawString und nicht ein transparentes png, genau bei dieser Umstellung habe ich ja den Knoten im Kopf

    An UEZ´s Variante stört mich jetzt nur noch das man den Button darunter noch sieht, ich wollte mir halt eigene Controls basteln die auch mal ihr Aussehen ändern können (aus Play Button wird z.B. der Laden Button). Ein unötiges neuzeichnen ließe sich sicherlich auch anders im Code abfangen, aber dann bleibt immer noch der Fall das wenn ich viele dieser eigenen Controls gleichzeitig ändern will ein deutliches nacheinander zeichen zu sehen ist. Schöner wäre wenn alle gepuffert wären und gleichzeitig angezeigt werden, dann flackert es zumindest nur einmal kurz.

    Hier vielleicht mal ein Screenshot um sich das besser vorstellen zu können:

    beispiel.JPG

    Links ist eine Liste mit Spielen die ich habe, rechts werden die Artworks für das Spiel gesetzt. Wähle ich ein anderes Spiel bauen sich die Artworks und Sprachen Symbole (manchmal) merklich nacheinander auf. Klicke ich auf das gleiche Spiel nur in einer anderen Sprache wird womöglich wieder das selbe Cover Artwork angezeigt (weil ich für die englische und deutsche Variante eventuell das gleiche Bild hinterlegt habe). Leider Flackert dann wieder alles. Sollte das mit dem Backbuffer nicht klappen müsste ich erstmal die Checksummen der Bilder vergleichen und dann nur bei Bedarf neu zeichnen, was wieder neu Probleme aufwirft da sich die Bilder teilweise überlagern...
    Dem Problem wollte ich am liebsten mit einem "unbemerkten" neuzeichnen entgegen treten.

    4 Mal editiert, zuletzt von Gofel (9. Juli 2015 um 20:02)

  • Das habe ich bisher mit einem Pseudo Control gelöst. Event auf leeres GUICtrlCreatePic(), selbe stelle mit GDI Plus übermalen.


    Nice, auf die Idee wär ich nicht gekommen.
    Ich mach echt zu wenig mit AutoIt :D

    Dein Beispiel hilft mir leider nicht weiter, du backbufferst ein _GraphicsDrawString und nicht ein transparentes png, genau bei dieser Umstellung habe ich ja den Knoten im Kopf


    na anstelle von DrawString fügst du einfach jeden Zeichenbefehl ein den du willst ^^ und schon ist das "gebackbuffert".

  • na anstelle von DrawString fügst du einfach jeden Zeichenbefehl ein den du willst ^^ und schon ist das "gebackbuffert".

    Ich mache schon den 2. Tag nichts anderes als von solchen Beispielen zu versuchen auf _GDIPlus_GraphicsDrawImageRect() umzustellen. :P
    Ich habe da entweder einen riesen Knoten im Kopf oder Transparente PNG lassen sich nicht mal ebend auf diese Weise in den Backbuffer schieben, ich erhalte immer eine leeres Bild.
    Daher meine Bitte mir möglichst meinen Code oben anzupassen.

    • Offizieller Beitrag

    Vielleicht möchtest Du ja meine UDF "_GuiCtrlSetImageEx" benutzen?!

    Damit kannst Du Pic-Controls beliebige Bilder (PNG, GIF, JPG, ICO, BMP, etc.) zuweisen.
    Auch transparente PNGs sind kein Problem (Hintergrundfarbe kann man angeben).

    Hier mal ein Beispiel:

  • Das klingt zu schön um wahr zu sein Oscar, ich schaue es mir morgen gleich an. Jetzt muss ich erstmal Sohnemann bespaßen. Ich geb dann bescheid.

  • Du kannst auch das Picture Control nehmen oder machst den Button "Flat", wenn du den Button nicht als Button nehmen willst.

    Dazu müsste mein Code umgeschrieben werden, aber Oscar ist ja eingesprungen, so dass du seine UDF nehmen kannst.

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • "WM_PAINT" und "einfach" in einem Satz zu verwenden betrachte ich jetzt "einfach" mal als Provokation :|
    Spaß, ich verwende ja WM_PAINT. Aber ich zeichne ja ebend nicht immer das selbe sondern die Artworks zum Spiel ändern sich. Dabei muss wieder die Stelle neutral eingefärbt werden und ein neues Bild gezeichnet werden. Das ganze 5 mal hintereinander für 5 Artworks ergibt ein leichtes Flackern.

    Egal, Oscar hat tatsächlich die Lösung geliefert wie mir scheint. Der komplette Umbau wird mich noch etwas Zeit kosten, aber erste Tests laufen schon sehr erfreulich.

    Danke