"Unglaubwürdigkeitsproblem" bei Frameratenberechnung
-
xindon schrieb:
hustbaer schrieb:
Aber warum in aller Welt sollte ich wenn ich dann eben beides habe gerade die Framerate verwenden um irgendwelche Bewegungen zu steuern? Und schon garnicht wenn ich die Framerate gemittelt habe, die delta time aber noch "roh" ist?
Verstehe ich nicht wie man darauf kommen könnte das so zu machen. Klar wäre es Blödsinn, aber eben weil es so offensichtlich Blödsinn wäre verstehe ich den Hinweis darauf nicht...Wenn das Programm jetzt mit 90fps läuft, kann man ja mit deinen beiden Frameraten einen Faktor ausrechnen (60/90) und dann multipliziert man die Bewegungsgeschwindigkeit mit diesem Faktor...
das heisst, je nach framerate werden sie verschiedene kurven laufen und verschieden oft "nachdenken"? *hehe*
-
rapso schrieb:
das heisst, je nach framerate werden sie verschiedene kurven laufen und verschieden oft "nachdenken"? *hehe*
Versteh ich jetzt nicht, was du damit meinst?
-
xindon schrieb:
rapso schrieb:
das heisst, je nach framerate werden sie verschiedene kurven laufen und verschieden oft "nachdenken"? *hehe*
Versteh ich jetzt nicht, was du damit meinst?
was daran faellt dir schwer zu verstehen?
-
kurven laufen? nachdenken?
und wer ist überhaupt "sie" ?
-
xindon schrieb:
kurven laufen? nachdenken?
Prädikat?
xindon schrieb:
und wer ist überhaupt "sie" ?
xindon schrieb:
...meinen Figuren...
-
och man ich gebs gleich auf...
ich nehme mal an, mit "sie" sind die Figuren gemeint, aber warum sollten sie Kurven laufen? und über was sollen sie denn nachdenken?
-
xindon schrieb:
ich nehme mal an, mit "sie" sind die Figuren gemeint, aber warum sollten sie Kurven laufen?
weil es ziemlich langweilig waere nur geradeaus zu laufen, irgendwann muessen sie abbiegen/kurven laufen.
und über was sollen sie denn nachdenken?
die handlungen die sie durchfuehren.
-
Sag mal willst du jetzt auf einen Fehler/Bug in meiner Berechnung raus oder willst du mich einfach nur verscheissern? :p
-
xindon schrieb:
Sag mal willst du jetzt auf einen Fehler/Bug in meiner Berechnung raus oder willst du mich einfach nur verscheissern? :p
raffst du das echt nicht dass deine simple idee nur bei linearer bewegung richtig laufen kann?
-
rapso schrieb:
xindon schrieb:
Sag mal willst du jetzt auf einen Fehler/Bug in meiner Berechnung raus oder willst du mich einfach nur verscheissern? :p
raffst du das echt nicht dass deine simple idee nur bei linearer bewegung richtig laufen kann?
Ja was ist denn bitte eine lineare Bewegung? Wenn meine Objekte eine Position und einen Bewegungsvektor haben. Die Länge des Bewegungsvektors multipliziere ich mit dem oben genannten Faktor.. was soll da schief gehen?
-
xindon schrieb:
rapso schrieb:
xindon schrieb:
Sag mal willst du jetzt auf einen Fehler/Bug in meiner Berechnung raus oder willst du mich einfach nur verscheissern? :p
raffst du das echt nicht dass deine simple idee nur bei linearer bewegung richtig laufen kann?
lineare Bewegung?Position und Bewegungsvektor
xindon schrieb:
was soll da schief gehen?
rapso schrieb:
...nur bei linearer bewegung richtig laufen kann?
nicht lineare bewegung
-
Tut mir leid, es is schon spät und seit ich vorhin meine Matrix Klasse geschrieben hab, bin ich leicht matschig im Kopf (grr die ganzen Indizes)..
Du willst mir also sagen, dass ich das so nicht machen kann, wenn die Bewegungsgeschwindigkeit nicht konstant ist. Naja is mir jetzt auch egal, ich geh schlafen :p sorry, dass ich dich genervt hab

-
xindon schrieb:
Tut mir leid, es is schon spät und seit ich vorhin meine Matrix Klasse geschrieben hab, bin ich leicht matschig im Kopf (grr die ganzen Indizes)..
Du willst mir also sagen, dass ich das so nicht machen kann, wenn die Bewegungsgeschwindigkeit nicht konstant ist. Naja is mir jetzt auch egal, ich geh schlafen :p sorry, dass ich dich genervt hab

ja, sobald geschwindigkeit, richtung sich aendern, oder logic berechnet wird, ist diese interpolation ungenau und kann von pc zu pc ein anderes spiel erzeugen. bei jemandem mit 100fps kann es sein dass homing-missiles immer treffen, bei jemandem mit 15fps koennten sie in eine umlaufbahn um das ziel einschwenken.
-
Ja aber das ist ja dann immer so, wenn man Bewegungen von der Zeit abhängig macht.
Bei deinem Beispiel mit der Homing Missile könnte man der Rakete ja auch einen kleinen Radius verpassen, bei dem sie schon hochgeht..
-
xindon schrieb:
Ja aber das ist ja dann immer so, wenn man Bewegungen von der Zeit abhängig macht.
nein, wenn die bewegung immer fuer gleiche zeitabstaende berechnet wird, ist es auf jedem rechner gleich (falls die hardware nicht ungenauigkeiten hat)
Bei deinem Beispiel mit der Homing Missile könnte man der Rakete ja auch einen kleinen Radius verpassen, bei dem sie schon hochgeht..
das ist doch nicht der punkt. worauf es ankommt ist doch dass ein spiel fuer jeden gleich spielbar ist.
-
Ich weiß, der Thread ruhte jetzt schon so ein Paar Tage, doch kam ich bis jetzt einfach nicht dazu mal wieder vorbei zu schauen 0o.
Was die Glaubwürdigkeit der Frames angeht.
Das mit den 50 000 bzw 150 000 FPS trifft ausschließlich bei der Winapi zu.Ich habe jetzt mal Testweise versucht EXAKT DIE SELBE Frameratenberechnung bei einer simplen DirectX-Anwendung zu verwenden.
Der Aufbau der Spielschleife ist nahezu identisch zu meinem Winapi Versuch,
nur dass in der Schleife jetzt natürlich auch immer der Hintergrund gelöscht wird
und BeginScene() bzw EndScene() und Present aufgerufen wird,
mal abgesehen davon, dass ich die Framerate jetzt nicht mehr mit Textout auf den Bildschirm bringe.
Und die Framerate bewegt ist immer um die 60 FPS, sinkt zwischendurch zwar kurz auf Werte zwischen 50 und 60, doch so kleine Schwankungen sind ja normal.
Aber wie kommt es, dass die Werte nicht höher sind?
Da passiert doch nichts außer den Hintergrund in jedem Frame zu löschen und Text auszugeben.
Sicherlich gibt es da die Bildwiederholrate und so, doch diese DirectX-Beispiele aus dem SDK haben bei mir auch oft Werte zwischen 400-500.
Naja, ist ja jetzt auch erst mal egal.Und falls du noch einmal hier vorbeischauen solltest @raspo:
In dem von dir angegebenen Thread sprachst du von Logigtiks.
Ich war zwar noch nicht so weit, als dass ich mir darüber schon Gedanken
gemacht hätte, doch wäre mein Ansatz wohl auch gewesen die Bewegung von der Framerate abhängig zu machen, doch dein Ansatz gefällt mir besser.
Und als Beispiel gabst du folgenden code an:int LastTick=GetTickCount(); while(!g_bQuit) { while(LastTick<GetTickCount()) { g_pAktualModule->LogicTick(); LastTick+=TICKTIME; if(LastTick+10000<GetTickCount()) LastTick=GetTickCount()+TICKTIME; } Render(); if(PeekMessage(&msg,hWnd,0,0,PM_NOREMOVE)!=0) { g_bQuit = !((bool)(PeekMessage(&msg,hWnd,0,0,PM_REMOVE))); TranslateMessage(&msg); DispatchMessage(&msg); } }Und dazu hätte ich dann jetzt noch ein Paar Fragen.
Erstens, ist das hier deine Aktuelle Version davon?
Denn du schriebst später:DAS kann nicht nur, DAS ist so für den logictick, schliesslich rechnet man mit der abstrakten zeit, die das framework vorgibt und nicht mit z.B. GetTickCount oder sowat (siehe mein code snipple in früheren post)
In diesem Codeschnipsel findet sich jedoch GetTickCount, anfangs dachte ich mir, dass du meinst, GetTicCount würde intern bei der Logikberechnung nicht vorkommen, doch dann verstehe ich speziell in diesem Zusammenhang den Verweis auf diesen Codeschnipsel nicht (da man hier ja nicht das interne Zeug deienr Logikberechnung sieht).
Naja, vielleicht war das ja auch nur ein Missverständnis, doch dies war jetzt nicht das Hauptproblem weswegen ich hier jetzt nachfrage.Nun gut, zu Beginn deiner Spielschleife startest du die "Logigschleife", die so lange wiederholt wird bis LastTick größer ist als der Wert von GetTickCount.
Bei jedem Durchlauf wird hier ein LogigTick ausgeführt, welcher intern das nötige Zeug vorberechnet und die Animatoren einstellt(?).
Doch auch wenn dieses System mit der Framerate herzlich wenig zu tun hat, wird hierbei ein schneller Rechner weniger Ticks Pro Zeiteinheit durchführen als ein langsamer Rechner, einfach weil die LastTick-Variable bei einem Schnellen Rechner schneller erhöt wird, als sich der Wert von GetTickCount vergößert(bei jedem Durchlauf der Logikschleife liefert GetTickCount ja einen neuen Wert).
Nungut, dass der schnellere Rechner wirklich weniger durchführt muss nicht sein, so befindet sich ein langsamer Rechner zwar länger in der Logigschleife, doch dauert es somit natürlich auch länger bis ein Logigtick aufgerufen wird.
Doch betrachtet man Rechner die unterschiedlich schnell sind, doch beide schnell genug "selbstständig" einen höheren LastTickwert zu erhalten als GetTickCount zurückgibt, ist eine unterschiedliche Logigtickaufrufzahl ja klar und dieses indirekte Schleifenende bei einem zu großen Unterschied ( langsame Rechner) heißt auch nicht unbedingt, dass die Proportionen gewahrt sind.
Sicherlich, ein schneller Rechner der die Logigschleife mit den geringeren Logiktickaufrufen beendet die Logigschleife schneller und kommt somit auch schneller wieder beim nächsten Durchlauf der Spielschleife wieder hinein, doch ob dies das Selbe ist? Das wage ich zu bezweifeln.
Ok, du hast da einen Mechanismus eingebaut der die Logigschleife indirekt beendet sollte der Unterschied zwischen LastTick und GetTickCount zu groß sein (bei einem sehr langsamen Rechner).
Aber dennoch sind es nur spezialfälle an denen ein langsamer Rechner und ein schneller Rechner mit dieser Berechnung die selbe Anzahl an Logigticks pro Zeiteinheit hinbekommen.Nächste Frage, nehmen wir hier einfach mal an das zuvor erwähnte Problem hätte ich nicht angesprochen.
Also die Logigschleife wird beendet und das Rendern beginnt.
Im Animator herrscht nun eine Warteschlange von Zeichenoperatoren.
Doch das Problem ist, die Spielschleife hat doch nur eine einzige Zeichnung pro Spielschleifendurchlauf frei, zeichnet man mehrmals sieht man das Bildchen auch mehrmals auf dem Bildschirm, abhängig von der Geschwindigkeit auch nur ein Paar Überlagerungen, doch auch nicht nett.
Gedacht ist das Zeig sicherlich so, dass die Animatoren natürlch mehr Frames zur Verfügung haben um das Zeug zu zeichnen, doch da man eigentlich in jedem Frame wieder in die Logigschleife kommt, werden die Animatoren auch immer wieder neu eingestellt, was die ganze Einstellerei wieder nutzlos macht.Könnte zwar noch ein Paar Sachen schreiben, doch ich offe genug geschrieben zu haben damit du mein Verständnisproblem erkennst, wenn du dieses System schon Jahre benutzt und keine Ungereimtheiten festgestellt hast, wird es wohl auch funktionieren :D, ich würde nur gerne wissen wie.
Vielleicht hilft auch die Information was denn "TICKTIME" für einen Wert enthält.
Ist TICKTIME gar so klein, dass dieser Wert niemals in der Lage wäre LastTick auf einen höheren Wert zu bringen als GetTickCount zurückgibt?
Und die Geschwindigkeit des Rechners somit nur noch beeinflusst wie lange es dauert bis der Differenzbetrag zu groß ist? Und somit diese Indirekte Abbruchbedingung in Kraft tritt (if(LastTick+10000<GetTickCount())
LastTick=GetTickCount()+TICKTIME;
)? Und somit auch die Möglichkeit gegeben ist, dass die Startbedingung bei der Logigschleife mal tatsächlich nicht gegeben ist und die Animatoren dadurch einen Sinn machen?...
Wenn dem so ist, dann würde ich dennoch gerne wissen, weshalb pro Zeiteinheit somit immer die selbe Anzahl an Logigticks durchgeführt wird, egal wie schnell der Rechner ist.
Würde dieses System dann nämlich auch gerne selbst verwenden
-
Kahino schrieb:
Und dazu hätte ich dann jetzt noch ein Paar Fragen.
Erstens, ist das hier deine Aktuelle Version davon?das ist keine spezielle version, das ist ein 08/15 mainloop den ich immer wieder so hinklecksen wuerde

Denn du schriebst später:
DAS kann nicht nur, DAS ist so für den logictick, schliesslich rechnet man mit der abstrakten zeit, die das framework vorgibt und nicht mit z.B. GetTickCount oder sowat (siehe mein code snipple in früheren post)
In diesem Codeschnipsel findet sich jedoch GetTickCount, anfangs dachte ich mir, dass du meinst, GetTicCount würde intern bei der Logikberechnung nicht vorkommen, doch dann verstehe ich speziell in diesem Zusammenhang den Verweis auf diesen Codeschnipsel nicht (da man hier ja nicht das interne Zeug deienr Logikberechnung sieht).
Naja, vielleicht war das ja auch nur ein Missverständnis, doch dies war jetzt nicht das Hauptproblem weswegen ich hier jetzt nachfrage.{ g_pAktualModule->LogicTick(); //<--aufruf der internen logik die nichts ueber GetTickCount weiss LastTick+=TICKTIME; if(LastTick+10000<GetTickCount()) LastTick=GetTickCount()+TICKTIME; }eigentlich ist gettickcount auch nicht genau genug, timegettime oder query performance counter waere eher angebracht.
Nun gut, zu Beginn deiner Spielschleife startest du die "Logigschleife", die so lange wiederholt wird bis LastTick größer ist als der Wert von GetTickCount.
Bei jedem Durchlauf wird hier ein LogigTick ausgeführt, welcher intern das nötige Zeug vorberechnet und die Animatoren einstellt(?).ja genau
Doch auch wenn dieses System mit der Framerate herzlich wenig zu tun hat, wird hierbei ein schneller Rechner weniger Ticks Pro Zeiteinheit durchführen als ein langsamer Rechner, einfach weil die LastTick-Variable bei einem Schnellen Rechner schneller erhöt wird, als sich der Wert von GetTickCount vergößert(bei jedem Durchlauf der Logikschleife liefert GetTickCount ja einen neuen Wert).
nein, es werden immer gleich viel berechnungen pro zeiteinheit, sagen wir mal, pro sekunde, durchgefuehrt, da TICKTIME eine konstante ist, sagen wir mal sie ist 40ms, das heisst also dass der logic-aufruf 25mal pro sekunde stattfindet, unabhaengig vom rechner.
Nungut, dass der schnellere Rechner wirklich weniger durchführt muss nicht sein, so befindet sich ein langsamer Rechner zwar länger in der Logigschleife, doch dauert es somit natürlich auch länger bis ein Logigtick aufgerufen wird.
Doch betrachtet man Rechner die unterschiedlich schnell sind, doch beide schnell genug "selbstständig" einen höheren LastTickwert zu erhalten als GetTickCount zurückgibt, ist eine unterschiedliche Logigtickaufrufzahl ja klar und dieses indirekte Schleifenende bei einem zu großen Unterschied ( langsame Rechner) heißt auch nicht unbedingt, dass die Proportionen gewahrt sind.ja, die proportionen koennen anders sein. rendert ein rechner 250fps, so berechnet er nur alle 10renderframes ein logikframe, rendert ein anderer 12.5fps, so berechnet er jedes renderframe zwei logikframes. am ende berechnen aber beide die selben 25 logikschritte (natuerlich ein bisschen idealisiert gesehen, weil manche dinge wie z.b. input nicht immer so abzuarbeiten sind)
Sicherlich, ein schneller Rechner der die Logigschleife mit den geringeren Logiktickaufrufen beendet die Logigschleife schneller und kommt somit auch schneller wieder beim nächsten Durchlauf der Spielschleife wieder hinein, doch ob dies das Selbe ist? Das wage ich zu bezweifeln.
was laesst dich das anzweifeln? wieso ist 25mal/s auf einem rechner nicht 25mal/s auf nem anderen?
bezweifeln ist gut, aber nur wenn ein argument folgt;)Ok, du hast da einen Mechanismus eingebaut der die Logigschleife indirekt beendet sollte der Unterschied zwischen LastTick und GetTickCount zu groß sein (bei einem sehr langsamen Rechner).
Aber dennoch sind es nur spezialfälle an denen ein langsamer Rechner und ein schneller Rechner mit dieser Berechnung die selbe Anzahl an Logigticks pro Zeiteinheit hinbekommen.nein, gemittelt sind es immer gleich viele ticks. der abfang des sonderfalles ist eben wirklich fuer sonderfaelle. manche rechner haben z.b. stand-by fuer ihre festplatte, wenn man spiel ist faellt sie eventuell in diesen zustand und wenn sie dann anspringt, dann dauert es eventuell 10s, da will ja niemand diese 10s nachgerechnet bekommen und nur noch den "game over"-screen sehen, sondern z.b. maximal 250ms dafuer nachrechnen lassen. anderes beispiel sony-psp, du kannst das teil sofort in stand-by schalten, es am naechsten tag einschalten und dort weiterspielen wo du warst, da waere 24h nachrechnen auch nervig.
Also die Logigschleife wird beendet und das Rendern beginnt.
Im Animator herrscht nun eine Warteschlange von Zeichenoperatoren.
Doch das Problem ist, die Spielschleife hat doch nur eine einzige Zeichnung pro Spielschleifendurchlauf frei, zeichnet man mehrmals sieht man das Bildchen auch mehrmals auf dem Bildschirm, abhängig von der Geschwindigkeit auch nur ein Paar Überlagerungen, doch auch nicht nett.das ist eine falsche sichtweise. die logik generiert keine zeichenoperationen die irgendwo eingefaedeltwerden. die logik rechnet nur einen neuen status an. schau dir dazu das MVC pattern an.
Gedacht ist das Zeig sicherlich so, dass die Animatoren natürlch mehr Frames zur Verfügung haben um das Zeug zu zeichnen, doch da man eigentlich in jedem Frame wieder in die Logigschleife kommt, werden die Animatoren auch immer wieder neu eingestellt, was die ganze Einstellerei wieder nutzlos macht.
die animatoren haben den zustand von time(n) und time(n+1). gerendert wird in der zeit dazwischen, du musst dir also fuer rendern entweder einen der beiden zustaende raussuchen (z.b. wenn es eine langsame langweilige windanimation ist auf blaettern) oder dazwischen interpolieren, abhaengig von der renderzeit (wenn z.b. sich ein karusel rotiert)
Könnte zwar noch ein Paar Sachen schreiben, doch ich offe genug geschrieben zu haben damit du mein Verständnisproblem erkennst, wenn du dieses System schon Jahre benutzt und keine Ungereimtheiten festgestellt hast, wird es wohl auch funktionieren :D, ich würde nur gerne wissen wie.
Vielleicht hilft auch die Information was denn "TICKTIME" für einen Wert enthält.
wenn du baldurs gate spielst, dann kannst du die logikzeit selber einstellen, von 10ms bis 100ms glaube ich. wenn du ein strategiespiel machst, dann kannst du die logiktime eventuell auf 500ms stellen und die ganze logik asynachron im extra thread laufen lassen (das ist sehr tricky
), wenn du einen shooter machst der physic simuliert, dann ist diese logictime eventuell maimal 10ms.Ist TICKTIME gar so klein, dass dieser Wert niemals in der Lage wäre LastTick auf einen höheren Wert zu bringen als GetTickCount zurückgibt?
normalerweise ist die logic leicht dem rendering voraus, damit das rendering fuer die aktuelle zeit aufgrund der zukuenftigen logiktime interpolieren kann.
[quote]Wenn dem so ist, dann würde ich dennoch gerne wissen, weshalb pro Zeiteinheit somit immer die selbe Anzahl an Logigticks durchgeführt wird, egal wie schnell der Rechner ist.
Würde dieses System dann nämlich auch gerne selbst verwenden
weil die zeit fuer alle gleich ablaeuft
weil alle die selbe TICKTIME haben
-> ZeitDieDasSpielGespieltWurde/TICKTIME = ticks die berechnet wurden... nirgens fliesst die rechnergeschwindigkeit ein.und wie gesagt, die ticktime haengt davon ab was gemacht werden muss. muss viel komplexes gerechnet werden, dann ist die ticktime groesser z.b. wegfindung fuer tausende von einheiten. muss hingegen sehr genau simuliert werden, z.b. damit ein schuss nicht durch ein rotierendes rotorblatt durchfliegen kann, dann ist die logictime sehr klein.
wenn du ein spiel fuer z.b. konsolen machst und ganz genau weisst, dass du 30 oder 60hz machst, dann nimmt man oefters auch das als richtwert und erspart sich die interpolation im renderframe.
-
Danke erstmal für diese ausführliche Antwort

Ich werde mir das dann jetzt mal genauer anschauen und wenn es dich nicht nervt, später eventuelle weitere Fragen stellen ;).