Wie das Neuzeichnen des Canvasgadgets unterbinden?

Fragen zu Grafik- & Soundproblemen und zur Spieleprogrammierung haben hier ihren Platz.
Benutzeravatar
Kurzer
Beiträge: 1617
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

Wie das Neuzeichnen des Canvasgadgets unterbinden?

Beitrag von Kurzer »

Hallo,

mein Problem scheint auf den ersten Blick hier schon einmal behandelt worden zu sein, aber eine Lösung habe ich dort leider nicht gefunden.

Ich programmiere ein Customgadget unter Verwendung des Canvas Gadgets.
Das Erscheinungsbild des Gadgets (81 Sudoku-Felder mit Zahlen) wird mit mehr oder weniger vielen Zeichenoperationen erstellt. Nun wird das Canvasgadget aber leider nach jeder Zeichenoperation neu auf dem Window gezeichnet. Das Gadget besteht aus 9 x 9 Feldern, die aus programmtechnischen Gründen nacheinander mit jeweils einem StartDrawing / Stopdrawing Block gezeichnet werden (es gibt halt eine Prozedur die ein einzelnes Feld zeichnet und die wird 81 mal aufgerufen).

Leider sieht man den Aufbau des Gadgets bzw. der Grafik schon recht deutlich, da das Canvasgadget sich immer wieder aktualisiert. Besser wäre es, wenn ich erstmal alles fertig zeichnen könnte und sich dann das Gadget einmal auf dem Window neuzeichnet.

Gibt's da eine Möglichkeit bei der ich kein Callback für das ganze Fenster erstellen muss, um die Canvas-repaints zu unterdrücken? Es soll ein universell einsetzbares Customgadget werden, daher möchte ich kein Callback auf das Fenster setzen, auf dem sich das Gadget später befinden wird. Das wäre meiner Meinung nach dann kein transparentes Verhalten.

Man kann das mit HideGadget() erreichen, aber dann ist das Gadget in der Zeit des Neuzeichnens komplett verschwunden. Das kommt auch nicht in Frage, da das Gadget später auch "während des Betriebs" z.B. mit neuen Zahlenreihen befüllt werden kann.
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.02 x64, OS: Win 7 Pro x64 & Win 11 x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Useralter in 2024: 56 Jahre.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6999
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Wie das Neuzeichnen des Canvasgadgets unterbinden?

Beitrag von STARGÅTE »

Du könntest zB erst mal auf einem eigene Image zeichnen und dann mit einem Mal DrawImage() auf dem Canvas ausführen.
Allerdings ist mir auch nicht ganz klar, wieso du mehrere Start/Stop brauchst.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
Kurzer
Beiträge: 1617
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

Re: Wie das Neuzeichnen des Canvasgadgets unterbinden?

Beitrag von Kurzer »

STARGÅTE hat geschrieben:Du könntest zB erst mal auf einem eigene Image zeichnen und dann mit einem Mal DrawImage() auf dem Canvas ausführen.
Allerdings ist mir auch nicht ganz klar, wieso du mehrere Start/Stop brauchst.
Weil ich die Zeichenoperationen als einzelne, unabhängige Prozeduren realisiert habe, die auch einzeln aufrufbar sind. DrawGrid(), DrawCell(), DrawDebugNumbers()... die haben alle Ihre einzelnen Start/Stop Aufrufe.

Wenn ich das ganze Gadget zeichne, dann sind das zwei verschachtelte For Schleifen (1-9) in denen DrawCell(x,y) usw. aufgerufen wird.

Aber ich sehe schon, dass ich das dann wohl doch so umbauen sollte, dass die Prozeduren sowohl mit ihrem eigenen StartDrawing-Block als auch mit einem externen StartDrawing-Block außerhalb der Prozedur umgehen können.

Das mit dem Image hatte ich auch schon überlegt. Die Idee fühlte sich aber "gegurkt" an.
Falls es so etwas wie ein RepaintOff(#Gadget, 1/0) nicht gibt, dann schreib ich meine Zeichenprozeduren nochmal um.
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.02 x64, OS: Win 7 Pro x64 & Win 11 x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Useralter in 2024: 56 Jahre.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6999
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Wie das Neuzeichnen des Canvasgadgets unterbinden?

Beitrag von STARGÅTE »

Das CanvasGadget bietet ja sogar SetGadgetAttribute(#Gadget, #PB_Canvas_Image, ImageID(...)).
Und das halte ich für "ungegurkt"
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
Bisonte
Beiträge: 2430
Registriert: 01.04.2007 20:18

Re: Wie das Neuzeichnen des Canvasgadgets unterbinden?

Beitrag von Bisonte »

Wenn ich das recht verstanden habe hast du sowas gemacht ? :

Code: Alles auswählen

Procedure DrawCell()
  StartDrawing(Canvasou.....
  Box(....
  StopDrawing()
EndProcedure
Procedure DrawCellHere()
  StartDrawing(Canvasou.....
  Box(....
  StopDrawing()
EndProcedure
Procedure DrawCellThere()
  StartDrawing(Canvasou.....
  Box(....
  StopDrawing()
EndProcedure
; ----
Procedure NeuZEichnen()
  DrawCell()
  DrawCellHere()
  DrawCellThere()
EndProcedure
Wobei sowas sinnvoller wäre :

Code: Alles auswählen

Procedure DrawCell()
  Box(....
EndProcedure
Procedure DrawCellHere()
  Box(....
EndProcedure
Procedure DrawCellThere()
  Box(....
EndProcedure
; ----
Procedure NeuZEichnen()
  StartDrawing(Canv....
  DrawCell()
  DrawCellHere()
  DrawCellThere()
  StopDrawing()
EndProcedure
Meinst du das ? Wenn nicht hab ich völliges missverständnis meinerseits ;)

Ansonsten muss man auch nicht das komplette Canvas neuzeichnen, wenn sich nur ein Teil davon ändert.
Man braucht "nur" den Teil neu zeichnen, der sich auch tatsächlich ändert...
PureBasic 6.10 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​
Benutzeravatar
Thorium
Beiträge: 1722
Registriert: 12.06.2005 11:15
Wohnort: Germany
Kontaktdaten:

Re: Wie das Neuzeichnen des Canvasgadgets unterbinden?

Beitrag von Thorium »

Kurzer hat geschrieben: Das mit dem Image hatte ich auch schon überlegt. Die Idee fühlte sich aber "gegurkt" an.
Das ist kein gegurke, das ist ganz normales Double Buffering wie es jedes Spiel verwendet um eben solche Effekte zu verhindern.
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.

Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke! Bild
Lord
Beiträge: 313
Registriert: 21.01.2008 19:11

Re: Wie das Neuzeichnen des Canvasgadgets unterbinden?

Beitrag von Lord »

Vielleicht (Windows only):

Code: Alles auswählen

SendMessage_(GadgetID(#Canvas),#WM_SETREDRAW,#False,0)
...
...
...
SendMessage_(GadgetID(#Canvas),#WM_SETREDRAW,#True,0)
Eventuell danach ein

Code: Alles auswählen

RedrawWindow_(WindowID(#Window),#Null,#Null,#RDW_INVALIDATE|#RDW_UPDATENOW|#RDW_ERASE)
Bild
Benutzeravatar
Kurzer
Beiträge: 1617
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

Re: Wie das Neuzeichnen des Canvasgadgets unterbinden?

Beitrag von Kurzer »

Danke für Eure Hinweise.
Das mit dem "gegurkt" klang vermutlich dramatischer, als ich es eigentlich gemeint hatte. Sorry.

Ich wollte die Image-Idee damit nicht schlechtreden, nur kam es mir nicht richtig vor, weil das Canvasgadget lt. PB-Hilfe von sich aus schon double buffered gezeichnet wird. Das Problem ist einzig, dass ich nicht bedachte habe, dass das double buffering mit Startdrawing eingeleitet und mit StopDrawing beendet wird. Ich werde meine Routinen dahingehend anpassen und dann funktioniert vermutlich alles genau im Sinne des Erfinders. ;-)

@Bisonte: Ja, so in etwa ist das richtig, wie Du es aufgezeigt hast. Zusätzlich nutze ich DrawCell(x,y) aber auch noch einzeln, um die Zelle unter der Maus hervorzuheben. Daher muss das auch einzeln funktionieren.
Ich werde die Startdrawing/StopDrawing-Befehle jetzt außerhalb der Zeichnungsprozeduren platzieren.

@Thorium & Stargate: Wie gesagt, das war ein Verständnisproblem. Double buffering ist mir geläufig, ich hab's im Fall des Canvasgadgets halt nur nicht korrekt angewendet (mehrfache Start-/StopDrawings). Die Nutzung eines extenen Images löst die Problematik mit den mehrfachen Start-/StopDrawings, erhöht aber den Verwaltungsaufwand für das Gadegt, da man das flipping koordinieren muss.

Ich brauchte halt nur einen Wink, um in die richtige Richtung zu denken. Ist hiermit erfolgreich geschehen. ;)
Besten Dank.
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.02 x64, OS: Win 7 Pro x64 & Win 11 x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Useralter in 2024: 56 Jahre.
Antworten