Hi,
zuerst weise ich mal darauf hin, dass das Thema schonmal angesprochen wurde nämlich in Thread "OpenGL friert ein" von Kathmai, dort wurde die Lösung aber nicht wirklich gefunden. Ich habe nun das gleiche Problem, bei meinem Framecounter über Application.OnIdle (in Delphi 5) habe ich einen Framecounter realisiert, dieser funktioniert auch super, nur wenn ich die Maus über das Fenster bewege funktioniert der Counter nicht mehr, und erst wenn ich sie wieder aus den Fenster bewege wird eine Framezahl angezeigt die der Frames seit der letzten Aktuallisierung entspricht. Auch wenn ich die Tastatur benutze werden ca 150 Frames angezeigt. Was mich gleich gewundert hat ist auch, das im Leerlauf nur 60 fps angezeigt werden. Bis jetzt hat mich das wenig gestört, aber in Moment habe ich ein Programm, bei dem ich öfters die Fps ablesen will, und da nervt es mich jedes mal die Maus aus dem Fenster zu ziehen. Habt ihr eine Lösung dazu, mir fällt nur ein, dass Windows mir ständig Nachrichten gibt, das die Maus im Fenster ist, genau weis ich es aber auch nicht.
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Dazu wäre dein Messcode interessant. Raten funktioniert meistens nicht so gut.
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
Und sieh mal was passiert, ich weiss ist kein richtiger Ersatz aber einen Versuch wert.
_________________ Gruß Andreas (aka DeepCopy) - Sic Luceat Lux
Classified Directive: initialization write in function for finalization, repeat until public case uses begin, if not case type as default, var in virtual override for while, in case of class type type asm until read begin.
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Ah, war wohl etwas fertig gestern Abend. DeepCopy, das was du da schreibst, passiert intern schon, und das ist das Problem schätze ich. OnIdle wird nach jedem Event nochmal aufgerufen. Daher erhöht sich deine Framezahl natürlich. Wobei mich das auch wieder verwundert, schließlich sollte das VSync deine Anwendung entsprechend ausbremsen.
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 Jun 18, 2009 07:17 Beiträge: 44 Wohnort: Gießen/Hessen
Eben einen Versuch wert!
_________________ Gruß Andreas (aka DeepCopy) - Sic Luceat Lux
Classified Directive: initialization write in function for finalization, repeat until public case uses begin, if not case type as default, var in virtual override for while, in case of class type type asm until read begin.
Hi,
ich habe es eingefügt, leider ändert sich gar nichts am Programm. Ich hatte auch schon daran gedacht die Maus komplett zu blockieren, aber da ich sie brauche geht das nicht. Außerdem funktioniert es auch nicht wenn die Maus sich nicht bewegt, also nur still über der Form steht.
Registriert: Fr Jan 04, 2008 21:29 Beiträge: 419 Wohnort: Lübeck
Hi! Ich hatte bei mir auf dem Laptop genau dieses Problem. Gelöst habe ich es wie folgt:
Code:
Render;
EndTime:= GetTickCount;
fps:=(EndTime - StartTime)/1000;
StartTime:= GetTickCount;
Die bezeichnung fps verwirrt hier, da es sich nicht um eine framerate handelt, sondern um eine Renderzeit. Um den Wert nur jede Sekunde zu aktualisieren (keine Durchschnittsberechnung) mache ich anschließend folgendes:
Code:
time:= time-fps;
iftime=<0
thenbegin
qfps := fps;
time:=1;
end;
Das funktioniert so, dass time mit 1 initialisiert wird und dann die verstrichene Zeit durchs rendern abgezogen wird. wandert time unter 0 ist die Sekunde vorbei und qfps wird der aktuelle fps wert übergeben. qfps wird dann gekehrwertet und an die Framerateausgabe geschickt, damit die tatsächliche Framerate und nicht die Renderzeit angezeigt wird. (das kehrwerten und initialisieren von time hab ich hier mal einfach weggelassen). Das hat nebenbei den Vorteil, dass man den fps wert, so wie er hier berechnet wird, als Multiplikator für Bewegungen nutzen kann, um so timebased-movement zu erhalten.
Sollte jemand wissen, warum dieser Ansatz scheinbar besser funktioniert als der Andere (den ich schon bei vielen gesehen habe und selbst auch nutzte), wäre es klasse, wenn das dieser Jemand erklären könnte. Ich selbst weiß es nicht.
Edit: Hab mich im ersten Codebrocken verschrieben! Die erste Zeile "StartTime:= GetTickCount;" ist jetzt die Letzte. Sonst funktionierts nicht.
Edit2: Die Variablen StartTime und EndTime sind MemberVariablen die im public Teil der Form deklariert wurden, also irgendwo, wo sie den Funktionsaufruf überleben. Das kann natürlich auch global in der Unit gemacht wrden oder von einem anderen Objekt übernommen werden, aber wichtig ist, dass StartTime den Wert des letzten onIdle-Aufrufes hat, was dafür sorgt, das im ersten Frame Grütze bei der Berechnung herraus kommt, da man ja 2 Messwerte braucht.
Allerdings kommen im (fast) Leerlauf Frameraten von 16000 FPS heraus, oder ist das normal? Das das Ergebniss mit mtime*frametime nicht die richtige FPS-Rate ist weis ich, es ist nur zum Test.
Registriert: Sa Nov 24, 2007 11:59 Beiträge: 116
Programmiersprache: FreePascal
16000 FPS ist nicht wenig, aber selbst mit glxgears komme ich mit meiner geforce 9800 GT auf ~12000 fps. Denke, das ist normal.
Zum Problem:
Probier es mal ohne den Idle-Handler, aber dafür in einer Schleife:
Code:
var
running:boolean=true;
...
implementation
...
procedure run;
begin
while running do
begin
render;
sleep(10);
end;
end;
;
Dann musst du nur noch festlegen, wann das Programm beendet werden soll (setze running auf false). Allerdings weiss ich nicht, wie sich dann das Formular unter Windows verhält.[/pascal]
Registriert: Fr Jan 04, 2008 21:29 Beiträge: 419 Wohnort: Lübeck
Das ist merkürdig was du da tust.
also frametime ist eine millisekunden Angabe, also muss man durch 1000 dividieren um eine Angabe in Sekunden zu erhalten. Das ist der erste Punkt der Fehlt. Deine Renderzeit ist also immer 1000x größer als bei jedem anderen. Anschließend schreibst du, dass mtime um frametime erhöht werden soll. Das ist in Ordnung. Danach kommt die 'If', die durchgeführt wird, wenn mtime größer oder gleich 1000 ist. Auch das ist in Ordnung, da 1000 bei dir einer Sekunde entspricht. Aber warum multiplizierst du deine frametime mit mtime? frametime ist schon in millisekunden (wegen der Fehlenden Division) , warum sollte man diesen Betrag nochmal mit mindestens 1000 multiplizieren? Dann liegt man doch bei mikrosekunden, obwohl eine framerate 1/sekunde ist. Theoretisch müsstest du bei aktivem VSync Werte von 0,016 haben um auf etwa 62,5 Frames pro Sekunde zu landen. die richtige berechnung ist 1/(Renderzeit/1000) und nicht Renderzeit*1000.
Ein Frame sollte etwa 16millisekunden benötigen. nach meiner Berechnung kommt man dann auf 16/1000 = 0,016 , anschließend 1/0,016 = 62,5 Frames pro Sekunde. Nach deiner Berechnung mit gleichem Ausgangswert 16 * 1000 = 16000Mikrosekunden Renderzeit. Deine Frameratecounter läuft also richtig. Deine Umrechnung ist nur falsch.
Ein Frame sollte etwa 16millisekunden benötigen. nach meiner Berechnung kommt man dann auf 16/1000 = 0,016 , anschließend 1/0,016 = 62,5 Frames pro Sekunde. Nach deiner Berechnung mit gleichem Ausgangswert 16 * 1000 = 16000Mikrosekunden Renderzeit. Deine Frameratecounter läuft also richtig. Deine Umrechnung ist nur falsch.
Du hast recht, ich habe * mit / vertauscht, , jetzt läuft es richtig, ich berechne jetzt noch einen Durchschnittswert für alle Frames dann solte der Framecounter richtig funktionieren.
Registriert: Fr Jan 04, 2008 21:29 Beiträge: 419 Wohnort: Lübeck
Schön, dass ich dir soweit helfen konnte!
Könntest du evtl. ein paar Worte zu deiner Durchschnittsberechnung verschwenden? Deine Formel kann ich leider nicht nachvollziehen, würde dann bei mir aber gerne auch lieber einen Durchschnittswert anzeigen, als eine Stichprobe.
Mitglieder in diesem Forum: 0 Mitglieder und 4 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.