Teil von Anwendungsbereich aktualisieren schneller, als alles zu aktualisieren?
-
Hallo,
es geht gerade um Performance:
Wenn ich einen Anwendungsbereich via InvalidateRect und NULL als 2. Parameter aktualisieren lasse, geht das dann langsamer, als wenn ich einen Bereich auf dem Anwendungsbereich angebe mittels eines RECTs? Oder wird einfach nur der andere Bereich nicht überschrieben?Und mein 2. Problem, was damit zu tun hat:
Wie kann man dieses Flackern beim ständigen Neuzeichnen verhindern? Kann man es verhindern, indem man immer nur einen bestimmten Bereich neu zeichnet?Hoffe ihr versteht meine Probleme, denn meine Fragen sind etwas wirr formuliert

Gruß Speedy_92
-
Flackern lässt sich ganz gut mittels BackBuffer vermeiden.
D.h.: Du machst alle Zeichenoperationen zuerst in eine Bitmap rein und wenn du fertig bist, kopierst du diese Bitmap auf dein Fenster.Den zweiten Parameter von InvalidateRect() zu nutzen könnte was bringen:
"The BeginPaint function automatically sets the clipping region of the device context to exclude any area outside the update region." (msdn)
-
geeky schrieb:
Flackern lässt sich ganz gut mittels BackBuffer vermeiden.
D.h.: Du machst alle Zeichenoperationen zuerst in eine Bitmap rein und wenn du fertig bist, kopierst du diese Bitmap auf dein Fenster.Den zweiten Parameter von InvalidateRect() zu nutzen könnte was bringen:
"The BeginPaint function automatically sets the clipping region of the device context to exclude any area outside the update region." (msdn)Vielen Dank schon einmal.
Aber ich habe auch gelesen, dass wenn man den dritten Parameter von InvalidateRect auf false setzt, dass dann flackern verhindert wird, da der Hintergrund nicht erst gelöscht wird. Wenn ich dies im Zusammenhang mit einem Rect als 2. Parameter benutze sollte es klappen, aber ich probiere auch mal die Methode mit dem Bitmap.
-
Sofern du den Hintergrund ohnehin selber zeichnest kannst du auch WM_ERASEBKGND entsprechen abfangen.
-
Speedy_92 schrieb:
Aber ich habe auch gelesen, dass wenn man den dritten Parameter von InvalidateRect auf false setzt, dass dann flackern verhindert wird, da der Hintergrund nicht erst gelöscht wird. Wenn ich dies im Zusammenhang mit einem Rect als 2. Parameter benutze sollte es klappen, aber ich probiere auch mal die Methode mit dem Bitmap.
Wenn man nicht den letzten Parameter auf TRUE setzt kann dies aber auch dazu führen, dass alte Bestandteile des Fensterinhaltes erhalten bleiben. Also nicht der gewünschte Inhalte hinterher sichtbar ist.
Das Flackern entsteht dadurch, dass der Hintergrund meistens komplett neu gezeichnet wird und anschließend der Inhalt darüber neu gemalt wird. Diesen kurzen Zeitraum nimmtunser Auge als Flackern war.
Double-Buffering vermeidet dieses Flackern, indem alle Daten inkl. Hintergrund in einen Memory DC gemalt werden und anschließend mit einem Schlag auf die eigentliche Anzeige kopiert werden.
Konsequenz: Double-Buffering funktioniert nur, wenn man auf WM_ERASEBKGND verzichtet und dort nichts macht (return FALSE/TRUE je nachdem was man braucht)!
-
Und als Buffer nimmt man, wie oben schon empfohlen, ein HBITMAP?
Oder kann man dies "noch besser" lösen?
-
Grundsätzlich ist es sicherlich natürlich schneller nur Teile anzeigen zu lassen, wenn Dein Algorithmus dazu fähig ist.
Hättest Du z.B. eine Tabelle darzustellen, dann ist es sicherlich schneller nur die Zellen neu zeichnen, die sich geändert haben, oderdie neu gezeichnet werden müssen weil sie verdeckt, waren, als immer alles neu zu zeichnen. Dafür gibt es ja auch das entsprechende Rectangle im Paint DC!Die Frage ist: Was wilst Du denn beschleunigen?
-
Naja... ich habe halt ein Labyrinth und wenn ich z.B. die rechte Pfeiltaste gedrückt halte, um die ganze Zeit nach rechts zu laufen, dann geht die "Figur" im Labyrinth nur relativ langsam und stockend voran... Dies wollte ich beschleunigen, da ich ein Recht großes Feld habe.
-
Dann sollten nur der Teilbereich eben neu gezeichnet werden! Der wo die Spielfigur war, und der wo sie hin soll.
Das Problem ist aber eher Deine WM_PAINT Routine, die auch das prüfen sollte was neu zu zeichnen ist!
-
Also ich habe es jetzt so gemacht (und es funktioniert :)), dass ich einfach das vorherige und das aktuelle Feld neuzeichne.
War einfacher als erwartet^^Also das Flackern hat aufgehört und mir kommt es so vor, als wenn es auch ein wenig beschleunigt wurde.
-
Grundsätzlich sollten WM_PAINT Handler so optimiert sein, dass nur notwendige Bereiche neu gemalt werden. Alles andere wird ja sowieso geclippt!