Canvas wird gelöscht bzw. "wegraddiert"
-
- Lazarusforum e. V.
- Beiträge: 7192
- Registriert: So 19. Nov 2006, 12:06
- OS, Lazarus, FPC: Linux Mint 19.3
- CPU-Target: AMD
- Wohnort: Oldenburg(Oldenburg)
Re: Canvas wird gelöscht bzw. "wegraddiert"
Die Forschleife bringt hier nichts. Daher würde das nicht gehen. Du kannst den Timer z.b. auf 20 oder 40 MS stellen, muss mal schauen.
MFG
Michael Springwald
Michael Springwald
-
- Beiträge: 36
- Registriert: Di 13. Apr 2010, 19:15
- OS, Lazarus, FPC: Windows 7 Ultimate 64bit (L 0.9.28.2 Beta FPC 2.2.4)
- CPU-Target: 32Bit-Anw.
- Wohnort: Nürnberg
Re: Canvas wird gelöscht bzw. "wegraddiert"
Warum bringt die nichts? Würde das nicht bezewecken, dass nur jeder vierte Wert grafisch umgesetzt wird?
Oder darf man im Timer keine For-Schleife benutzen?
Oder darf man im Timer keine For-Schleife benutzen?
- af0815
- Lazarusforum e. V.
- Beiträge: 6771
- Registriert: So 7. Jan 2007, 10:20
- OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
- CPU-Target: 32Bit (64Bit)
- Wohnort: Burgenland
- Kontaktdaten:
Re: Canvas wird gelöscht bzw. "wegraddiert"
Relativ betrachtet hast du rechtalex189 hat geschrieben:Warum bringt die nichts? Würde das nicht bezewecken, dass nur jeder vierte Wert grafisch umgesetzt wird?
Oder darf man im Timer keine For-Schleife benutzen?

Gedacht war bei den Tips, das der Tick (zB. Bewegung) gleich bleibt und nur nach jeder x-ten Berechnung der zeitaufwendigere Zeichenprozeß durchgeführt wird. Dadurch kann der Timer besser seine Teilung halten, die er durch die langsame Grafikroutine verliert.
Bei deiner Version wird die relative Bewegung pro TimerEvent auf das 4. fache gebracht. Der Timer wird genauso unkonstant/zu langsam sein wie original, du hast aber die Möglichkeit jetzt das Intervall auf das 4fache zu strecken, damit gehts natürlich auch.
Zwei Lösungen, was dir besser erscheint nehmen.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
-
- Lazarusforum e. V.
- Beiträge: 7192
- Registriert: So 19. Nov 2006, 12:06
- OS, Lazarus, FPC: Linux Mint 19.3
- CPU-Target: AMD
- Wohnort: Oldenburg(Oldenburg)
Re: Canvas wird gelöscht bzw. "wegraddiert"
Die Forschleife kann hier nicht in dieser Form gehen. Du müsstest eine Art zeit Schleife einfügen. Nicht per Sleep. Sondern mit einer Localen Integer Variable, z.b. die du mit GettickCount füllst.
Grund:
Innerhalb der Forschleife zeichnest du jetzt ein Bild. Es wird jedoch so schnell gezeichnet, dass du theoretisch nur das letzte siehst. Am einfachsten wäre es, wie schon gesagt, ohne Forschleife mit einem Timer, denn du auf einen bestimmten Interval stellst und Pro onTimer eine Variable hoch zählst.
Grund:
Innerhalb der Forschleife zeichnest du jetzt ein Bild. Es wird jedoch so schnell gezeichnet, dass du theoretisch nur das letzte siehst. Am einfachsten wäre es, wie schon gesagt, ohne Forschleife mit einem Timer, denn du auf einen bestimmten Interval stellst und Pro onTimer eine Variable hoch zählst.
MFG
Michael Springwald
Michael Springwald
-
- Beiträge: 36
- Registriert: Di 13. Apr 2010, 19:15
- OS, Lazarus, FPC: Windows 7 Ultimate 64bit (L 0.9.28.2 Beta FPC 2.2.4)
- CPU-Target: 32Bit-Anw.
- Wohnort: Nürnberg
Re: Canvas wird gelöscht bzw. "wegraddiert"
@af0815: Ich habe das mit dem Hochzählen ja schon verstanden, ich glaube nur einfach, dass dadurch die Performace nicht viel besser wird, da wir in einem Crashkurs eine grafisch einfach Stoppuhr gemacht haben, und auch da waren die 10 ms langsamer.
@pluto: Ich zeichne doch nicht innerhalb der for-Schleife. Da werden doch nur hintereinander Werte berechnet und der letzte wird dann dem Shape-Objekt zugewiesen.
@pluto: Ich zeichne doch nicht innerhalb der for-Schleife. Da werden doch nur hintereinander Werte berechnet und der letzte wird dann dem Shape-Objekt zugewiesen.
- af0815
- Lazarusforum e. V.
- Beiträge: 6771
- Registriert: So 7. Jan 2007, 10:20
- OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
- CPU-Target: 32Bit (64Bit)
- Wohnort: Burgenland
- Kontaktdaten:
Re: Canvas wird gelöscht bzw. "wegraddiert"
Windows hat einen nicht deterministischen Scheduler. Daher können die Timer abweichen. Du sagst hier dem System bitte rufe mich in 10ms auf, inwieweit das System dem entgegenkommt sei dahingestellt und wird dir auch nicht garantiert. Der Aufruf erfolgt nach 10ms, ev. auch 15ms wenn andere Prozesse mit höheren Prioritäten es verlangt haben. Jeder Prozess bekommt vom Scheduler nach einem bestimmten Verfahren eine Zeitscheibe zugeteilt, so auch die Timer. Brauchen jetzt andere Prozesse mit höherer Priorität Leistung, so wird die auch zugeteilt und die Zeitscheibe der niederen Prozesse verzögert bzw. gekürzt.alex189 hat geschrieben:@af0815: Ich habe das mit dem Hochzählen ja schon verstanden, ich glaube nur einfach, dass dadurch die Performace nicht viel besser wird, da wir in einem Crashkurs eine grafisch einfach Stoppuhr gemacht haben, und auch da waren die 10 ms langsamer.
Siehe auch in der Wiki (Englisch)
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
-
- Lazarusforum e. V.
- Beiträge: 7192
- Registriert: So 19. Nov 2006, 12:06
- OS, Lazarus, FPC: Linux Mint 19.3
- CPU-Target: AMD
- Wohnort: Oldenburg(Oldenburg)
Re: Canvas wird gelöscht bzw. "wegraddiert"
Vielleicht hilft folgendes Beispiel:
Nehmen wir an, du möchtest eine Animation erstellen. Du hast dir jetzt 4 Grafiken erstellt und das wird jetzt eine Art "Daumkino".
Es gibt natürlich viele Möglichkeiten, dass jetzt Automatisch abspielen zu lassen. Nehmen wir an, du verwendest eine ImageList. Jetzt zeichnest, du alle Grafiken in einer Forschleife auf ein Canvas. Was würde jetzt Passieren ? oder anders gefragt: Würdest du die Animation erkennen können ? Ich meine es jetzt einfach so: Du schreibst in ein OnPaint Event oder beim Klicken auf einen Button das rein. Oder auch in ein Timer. Es geht mir letztendlich nur um die Forschleife. Du könnte ja von 0 bis 3 gehen. Was meinst du ?
Nehmen wir an, du möchtest eine Animation erstellen. Du hast dir jetzt 4 Grafiken erstellt und das wird jetzt eine Art "Daumkino".
Es gibt natürlich viele Möglichkeiten, dass jetzt Automatisch abspielen zu lassen. Nehmen wir an, du verwendest eine ImageList. Jetzt zeichnest, du alle Grafiken in einer Forschleife auf ein Canvas. Was würde jetzt Passieren ? oder anders gefragt: Würdest du die Animation erkennen können ? Ich meine es jetzt einfach so: Du schreibst in ein OnPaint Event oder beim Klicken auf einen Button das rein. Oder auch in ein Timer. Es geht mir letztendlich nur um die Forschleife. Du könnte ja von 0 bis 3 gehen. Was meinst du ?
MFG
Michael Springwald
Michael Springwald
-
- Beiträge: 586
- Registriert: Mi 25. Mär 2009, 21:12
- OS, Lazarus, FPC: Laz trunk / fpc latest release / Win and other
- CPU-Target: mostly 32 bit
Re: Canvas wird gelöscht bzw. "wegraddiert"
Also zunächst mal versteh ich die ganzen Antworten: "Die for schleife bringt nix" nicht.
In der Form wie der original Autor sie gemeint hat, bringt die doch genau was sie soll:
- Timer.Interval := 4 * 10; // 40 ms
- in der procedure Timer1Timer:
4 mal berechnen (schnell)
1 mal zeichnen
Davon ausgehend das die Berechnung wirklich nicht zusammengefasst werden kann, ist diese Lösung sogar besser als:
- Timer.Interval := 10; // 10 ms
- in der procedure Timer1Timer:
1 mal berechnen (schnell)
IF (wenn dies ein vierter Aufruf ist) THEN 1 mal zeichnen
Die erste Lösung hat nur ein viertel der Timer-Aufrufe, jeder Aufruf kostet in sich selbst Zeit. Die Timer Message muss vom OS/LCL behandelt werden.
Beide Lösungen leiden unter der Ungenauigkeit des Timer. Sowohl als auch darunter, das der im Timer1Timer ausgeführte Code laenger dauern kann als das Intervall.
Das ließe sich über eine Referenz Zeit verbessern:
procedure BeforeFirstTimerCall;
begin
// object member
TimerLast := TimeInMillSecs(); // 40 ms before
end;
procedure Timer1Timer;
var TimerThis, TimeUsed: ...;
begin
TimerThis := TimeInMillSecs();
TimeUsed := TimeThis - TimeLast;
TimeLast := TimeThis;
for i := 0 to TimeUsed div 10 do begin // fuer jede 10 msec
// calc
end;
// draw
end
------------
Soweit sogut.....
Allerdings, wenn zu viele Ereignisse eintreffen, werden die Paint (paint on real screen) Ereignisse übergangen, bis wieder Zeit ist...... Daher muss man testen ob wirklich gezeichnet wurde. Wenn nicht muss man dafür sorgen das weniger andere Ereignisse anstehen.
In der Form wie der original Autor sie gemeint hat, bringt die doch genau was sie soll:
- Timer.Interval := 4 * 10; // 40 ms
- in der procedure Timer1Timer:
4 mal berechnen (schnell)
1 mal zeichnen
Davon ausgehend das die Berechnung wirklich nicht zusammengefasst werden kann, ist diese Lösung sogar besser als:
- Timer.Interval := 10; // 10 ms
- in der procedure Timer1Timer:
1 mal berechnen (schnell)
IF (wenn dies ein vierter Aufruf ist) THEN 1 mal zeichnen
Die erste Lösung hat nur ein viertel der Timer-Aufrufe, jeder Aufruf kostet in sich selbst Zeit. Die Timer Message muss vom OS/LCL behandelt werden.
Beide Lösungen leiden unter der Ungenauigkeit des Timer. Sowohl als auch darunter, das der im Timer1Timer ausgeführte Code laenger dauern kann als das Intervall.
Das ließe sich über eine Referenz Zeit verbessern:
procedure BeforeFirstTimerCall;
begin
// object member
TimerLast := TimeInMillSecs(); // 40 ms before
end;
procedure Timer1Timer;
var TimerThis, TimeUsed: ...;
begin
TimerThis := TimeInMillSecs();
TimeUsed := TimeThis - TimeLast;
TimeLast := TimeThis;
for i := 0 to TimeUsed div 10 do begin // fuer jede 10 msec
// calc
end;
// draw
end
------------
Soweit sogut.....
Allerdings, wenn zu viele Ereignisse eintreffen, werden die Paint (paint on real screen) Ereignisse übergangen, bis wieder Zeit ist...... Daher muss man testen ob wirklich gezeichnet wurde. Wenn nicht muss man dafür sorgen das weniger andere Ereignisse anstehen.
-
- Lazarusforum e. V.
- Beiträge: 7192
- Registriert: So 19. Nov 2006, 12:06
- OS, Lazarus, FPC: Linux Mint 19.3
- CPU-Target: AMD
- Wohnort: Oldenburg(Oldenburg)
Re: Canvas wird gelöscht bzw. "wegraddiert"
Du meinst, es funken irgendwelche Eventes dazwischen ?Daher muss man testen ob wirklich gezeichnet wurde
MFG
Michael Springwald
Michael Springwald
-
- Beiträge: 586
- Registriert: Mi 25. Mär 2009, 21:12
- OS, Lazarus, FPC: Laz trunk / fpc latest release / Win and other
- CPU-Target: mostly 32 bit
Re: Canvas wird gelöscht bzw. "wegraddiert"
Das hängt davon ab wann und wie gezeichnet wird.pluto hat geschrieben:Du meinst, es funken irgendwelche Eventes dazwischen ?Daher muss man testen ob wirklich gezeichnet wurde
Das "painten" auf den aktuellen Handle (also das painten das dann wirklich im Fenster sichtbar wird) sollte normaler weise nur Im OnPaint Ereignis passieren (genau gesagt während der Paint-Message)
Dann würde Timer1Timer auf eine Bitmap zeichnen die dann später übertragen wird?
Das handling der Paint-Message passiert aber nur bei leere msg queue (afaik), Wenn das nächste Timer Ereignis schon in der Queue liegt, wird das vorgezogen.
Um zu vermeiden, das nie gezeichnet wird, kann man im OnPaint ein flag setzten. Ist dieses Flag nicht gesetzt, dann wird im Timer1Timer nicht mehr gezeichnet => der Timer1Timer ist dann schneller fertig, und hoffentlich reicht die Zeit für ein Paint Ereignis.
-
- Beiträge: 36
- Registriert: Di 13. Apr 2010, 19:15
- OS, Lazarus, FPC: Windows 7 Ultimate 64bit (L 0.9.28.2 Beta FPC 2.2.4)
- CPU-Target: 32Bit-Anw.
- Wohnort: Nürnberg
Re: Canvas wird gelöscht bzw. "wegraddiert"
martin_frb: Schön, dass du mich verstehst, aber das mit der Referenzzeit habe ich nicht so ganz verstanden.
Also ich habe jetzt die drei Varianten getestet. Dabei habe ich einen Sprung ablaufen lassen, der laut der Anzeige 14,25 s dauert. Nun habe ich jeweils die wahre Zeit gestoppt:
Ohne for-Schleife oder Zähler: 22,5 s.
Mit Zähler: 22 s.
Mit for-Schleife: 17 s.
Die for-Schleife-Lösung scheint also am besten zu funktionieren.
MfG
Also ich habe jetzt die drei Varianten getestet. Dabei habe ich einen Sprung ablaufen lassen, der laut der Anzeige 14,25 s dauert. Nun habe ich jeweils die wahre Zeit gestoppt:
Ohne for-Schleife oder Zähler: 22,5 s.
Mit Zähler: 22 s.
Mit for-Schleife: 17 s.
Die for-Schleife-Lösung scheint also am besten zu funktionieren.
MfG

-
- Beiträge: 586
- Registriert: Mi 25. Mär 2009, 21:12
- OS, Lazarus, FPC: Laz trunk / fpc latest release / Win and other
- CPU-Target: mostly 32 bit
Re: Canvas wird gelöscht bzw. "wegraddiert"
Denkbar...alex189 hat geschrieben:martin_frb: Schön, dass du mich verstehst, aber das mit der Referenzzeit habe ich nicht so ganz verstanden.
Also ich habe jetzt die drei Varianten getestet. Dabei habe ich einen Sprung ablaufen lassen, der laut der Anzeige 14,25 s dauert. Nun habe ich jeweils die wahre Zeit gestoppt:
Ohne for-Schleife oder Zähler: 22,5 s.
Mit Zähler: 22 s.
Mit for-Schleife: 17 s.
Die for-Schleife-Lösung scheint also am besten zu funktionieren.
Da jedem Timer-Intervall ein par millisecs länger ist als geplant. Mit schleife findet nur ein viertel der Intervalle statt, Die extra zeit ist also geringer.
Über die Referenzzeit: Du gehst davon aus das genau 40 millisecs vergangen sind, es ist aber mehr. Also misst du die Zeit, und berechnest dann entsprechend der tatsächlich abgelaufenen Zeit. (Holst also die versäumte Zeit wieder auf). Damit spielt es keine rolle mehr wie lang das Intervall ist, solange es nur ausreichend Zeit zum Zeichnen lässt.
Übrigens:
for i := o to TimeUsed div 10 do
"div" ist falsch
int(round(TimerUsed / 10, 0))
oder sowas.
damit du auch hin und wieder aufrundest => sonst verlierst du ja doch zeit.