Hi, folgendes Problem. Das kleine Spielchen an dem ich grad bastle, ist sehr rechen-unintensiv. Bei wenig zu berechnenden Objekten erziele ich teilw. Frameraten von über 2000. Auf manchen Rechnern, auf denen ich es getestet habe war die FPS-Zahl sogar noch höher.
Als Framelimiter habe ich diese Prozedur aus dem DGL-Wiki eingebaut http://wiki.delphigl.com/index.php/Frameratenbegrenzung .. läuft soweit auch prima. Leider nur, sofern die Berechnungszeit eines Frames nicht zu kurz war, dann wird es scheinbar ungenau. Ich habe als Übergabewert sogar schon Extended anstatt Double verwendet um die Berechnung noch genauer zu haben. Aber selbst das scheint nicht auszureichen. Das Spiel läuft also mitunter zu langsam - weil es zu schnell läuft
Ich hatte mir sogar schon überlegt eine Schleife zu schreiben, die lediglich dafür sorgt, dass die CPU genug zu tun hat, damit die Framezeit nicht zu klein wird - aber das scheint mir irgendwie idiotisch ;D
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Was benutzt du zur Ermittlung der Zeit? GetTickCount ist nicht genau genug. Du müsstest den PerformanceCounter nehmen bzw unter Linux clock_gettime mit der Realtime-Clock (siehe dazu die entsprechende Manpage).
greetings
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Warum willst du überhaupt framelimiting machen? Am besten steigst du auf Timebased Movement um. Damit ist die Framerate egal, solange die Frequenz des Counters größer ist als die Framerate. Beim Performance-Counter liegt die Frequenz üblicherweise im sechs bis siebenstelligen Bereich .
greetings
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Time-Based-Movement klingt zwar nach der perfekten Lösung, aber die letztliche Implementierung gestaltet dann leider doch nicht so einfach für jemanden wie mich Frame-Based-Movement macht alles so schön leicht. Habe es jetzt mit einer Sleep-Prozedur gelöst, die den QPC nutzt. Danke für eure Antworten!
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Hast du dir unseren Wiki-Artikel durchgelesen?
Zeig zumindest mal deinen Sleep-Code her, denn wenn du's nicht sauber löst, frisst dir das deine ganze CPU-Zeit weg.
greetings
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Nichts für ungut. Aber beim Lesen dieses Themas habe ich irgendwie Schmerzen auf der rechten hinteren Seiten meines Kopfes bekommen.
Meiner Meinung nach bringt Frameraten begrenzen nur etwas, wenn man nicht unnötig die komplette CPU/GPU belegen will. Was also wohl in recht vielen Anwendungen vorteile mit sich bringen kann. Egal ob man Frameraten begrenzt oder nicht. Sobald man flüssige Animationen darstellen will benötigt man immer Time Based Movement. Die beiden Sachen schließen sich aber keineswegs aus oder ersetzen den jeweils Anderen.
Ein eigenes Sleep, was nichts anderes macht als BusyWaiting (100% CPU-Last), ist Schrott. Dann kann man solch ein Sleep auch gleich lassen. Den einzigen Fall wo ich so etwas akzeptieren würde sind Echtzeitanwendungen die genau einen Zeitpunkt abpassen müssen. Was hier aber nicht der Fall sein dürfte.
Genug gemäcker. Sleep ist kein richtiges Warten. Sondern es übergibt die Ausführung an den TaskSheduler von Windows für mindesten die angegeben Zeit. Nach oben hin kann durchaus Luft sein. Sobald dein Rechner mit anderen Sachen stark beschäftigt ist kann das deutlich länger dauern. Und es kann eine Mindestauflösung von ca. 16ms haben. Das kann man per API Befehl auch beeinflussen. Kann mir nie merken wie der heißt. Wenn ich das richtig sehe, dann verlässt sich der Code aus dem Wiki darauf, dass das Sleep genau so lange wartet wie es theoretisch sollte.
Es sollte ausreichen, wenn du für deine Berechnung nicht nur die Zeit berücksichtigst die du für das reine Rendern benötigst hast, sondern du musst die Zeit zwischen zwei Frame berücksichtigen. Sleep kann länger dauern oder du kannst in deiner Anwendung ja selber Sachen machen die nicht direkt zum Rendern gehören. Aber all das kann deine Anwendung ausbremsen. Und wenn du das beim Warten nicht berücksichtigst, dann rutscht dir die Zeit unter deiner Berechnung durch und wird zu jedem Frame dazu gerechnet. Indirekt. Und dadurch wirkt deine Anwendung langsamer als sie sollte. Für TBM bräuchtest du sowieso die richtige FPS und nicht nur die Zeit fürs reine Rendern.
Ein Begrenzen der FPS auf 30 wird wegen der Tolleranz von Sleep allerdings immer geringer ausfallen. Also es werden immer weniger FPS als gewollt. Von daher lieber mal ein paar FPS anpeilen mehr. Falls das Sleep zu klein werden sollte kann das aber auch zu unschönen Effekten führen. Wenn du nur 1-2 ms warten willst er aber jedes mal 16 warten würde. Aber dafür müsste das Rendern des Bildes schon einige Millisekunden in anspruch nehmen.
Alternativ kann man auch in einem OnTimer rendern. Für normale Anwendungen ist das wohl okay. Für Spiele eher nicht. Auf 30ms eingestellt und gemessen wie viel Zeit tatsächlich zwischen den OnTimer Events liegt und schon hat man die Zeit die zwischen zwei Bildern liegt. Die kann man dann für das TBM verwenden. Um das Begrenzen der Framerate bräuchte man sich dann nicht direkt kümmern. Sollte aber ein Menü offen sein oder das Fenstr verschoben werden werden Timer Events ausgesetzt.
Ich denke also das Hauptproblem liegt nicht im Sleep ansich sondern auf dem blinden Vertrauen darauf und der ungenügenden Messung der Zeiten. Das eben "Blindzeiten" nicht mit erfasst werden und somit nicht mit berechnet werden.
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Die ungenauigkeit von Sleep ist nicht zu unterschätzen. Vorallem in Spielen merkt man es dann doch irgendwie, der Zeitfluss wirkt unkontinuierlich, wenn man Pech hat, funkt einem das bei schnelleren Stellen gehörig in den Plan. Das macht ein Spiel dann „irgendwie komisch“ oder „blöd, weil es irgendwie unlogisch ist“ (sowas hört man öfter über kleinere Spiele mit solchen oder ähnlichen Macken).
greetings
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Mitglieder in diesem Forum: 0 Mitglieder und 11 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.