| |
va!n Member
Anmeldedatum: 23.05.2010 Beiträge: 122 Wohnort: Herne (NRW)
|
Verfasst am: 29.07.2010, 22:13 Titel: FPS unabhängiges programmieren? |
|
Mich wundert es irgendwie sehr, dass anscheinend überall im Umgang mit XNA für Phone7 Projekte die FPS auf 30 gesetzt wird und für Windows und XBox360 Projekte, die FPS auf 60 gesetzt wird! Ich weiß leider nicht wirklich, ob z.b. das Phone7 von der Hardwareseite nur max 30 FPS schafft oder auch mehr könnte. Wenn man ein Spiel auf eine feste FPS stellt, so arbeitet man im Spiel mit fixen Variablen wie z.b.: "x = x + 1", welches in diesem Fall tatsächlich pro Frame auich nur 1 Pixel entsprechen würde!
Entwickelt man nun ein Spiel für Windows und XBox360 mit vordefinierten 60 FPS, so müßte man für das gleiche Projekt unter Phone7 mit nur 30 FPS, ALLE Variablen abändern bzw an diesen 30 FPS anpassen, da dass Spiel ansonsten zu langsam (oder doch zu schnell?) laufen würde!? Was ist, wenn iin Zukunft ein Phone7 Nachfolger kommt, dessen Hardware 60 FPS kann und die Spiele für nur 30 FPS programmiert sind? Ich denke noch anschaulicher bzw nachdenklicher wird das ganze, wenn man an einem normalen PC denkt, wo eine MIttelklasse Grafikkarte und in einem anderen PC eine HighendGrafikkarte verbaut sind...
Ich persönlich finde, wenn ich schon eine "fette" Grafikkarte oder besser Hardware habe (hier auch schon mit Blick auf evtl zulünftige bzw bessere MobilPhone Hardware), dann möchte ich diese auch ausreizen und nicht, dass z.b. die FPS auf nur max 60 begrentzt wird... (Ja ich weiß, dass das menschliche Auge eine Bewegung ab ca 25 FPS als flüssig sieht)...
Okay, wir brauchen nicht unbedingt unnötige CPU / GPU Leistung verschwenden, um 100+ FPS zu haben - auch wenn die Hardware dieses hergeben würde! Was ich zumindest im HInterkopf nicht loswerde, ist die Frage, warum anscheinend unter XNA nicht FPS independent programmiert wird bzw mit DeltaTimes, so dass die Spiele auf jedem Rechner gleich schnell laufen - halt nur mit unterschiedlicher FPS.. (die FPS kann man in diesem Fall auch - um unnötige GPU/CPU Leistung zu sparen - auf max 60 oder 75 FPS begrenzen)
Ich glaube, meine Gedanken hier nicht so wirklich in Wort wiedergegeben zu haben... Hoffe dennoch, dass der eine oder andere halbwegs Versteht was ich meine... Würde gerne eure Meinung(en) zu FPS unabhängiges Programmieren und o.g. Punkte hören. |
|
| Nach oben |
|

|
Glatzemann Member
Anmeldedatum: 24.07.2009 Beiträge: 3327 Wohnort: Leverkusen
|
Verfasst am: 29.07.2010, 22:18 Titel: |
|
XNA unterstützt doch die "FPS-Unabhängige" Programmierung wunderbar. Multipliziere einfach alles was FPS-Unabhängig sein soll mit der GameTime und schon hast du aus
Pixel pro Frame
das bessere
Pixel pro Sekunde
gemacht und alles ist FPS-Unabhängig. _________________ Twitter · YouTube · MotoX Racers
|
|
| Nach oben |
|

|
FlySoft Member
Anmeldedatum: 16.04.2009 Beiträge: 143 Wohnort: Nähe von Stuttgart
|
Verfasst am: 29.07.2010, 22:26 Titel: |
|
Du musst einfach statt PixelPerFrame in PixelPerSecond umwandeln, und dann
x += pps * gameTime.ElapsedGameTime.TotalSeconds;
(um bei x += 1 zu bleiben, müsste pps = 60 sein) _________________ Wenn du es verstehen solltest, hätte ich es nicht "Code" genannt.
--------------------------------------------------
Mein Blog |
|
| Nach oben |
|

|
reisi89 Member
Anmeldedatum: 16.06.2009 Beiträge: 55
|
Verfasst am: 29.07.2010, 23:57 Titel: |
|
hmm?! das mit dem gameTime multiplizieren raff ich jetzt nicht ganz!?
Könnte mir das jemand näher erläutern bitte?
lg |
|
| Nach oben |
|

|
va!n Member
Anmeldedatum: 23.05.2010 Beiträge: 122 Wohnort: Herne (NRW)
|
Verfasst am: 30.07.2010, 00:16 Titel: |
|
@reisi89:
Da ich leider in XNA noch nicht so fitt bin, poste ich hier mal ein sehr alten BASIC source, an dem ich das ganze damals mal versucht habe zu erklären...
| Code: |
;-----------------------------------
;
; Run your prog in same speed on all
; PCs but FPS independent - Example
;
; Works 100% fine on all PCs :wink:
;
;-----------------------------------
;
#scrw = 640 ; screenwidth
#scrh = 480 ; screendheight
#scrd = 16 ; screendepth
;-------- Init Timer before innerloop --------
;
oldmillisecs.f = TimeGetTime_() ; TimeGetTime_ return better results as GetTickCount_
;
;-------- Test MainLoop --------
;
Repeat
deltatime.f = TimeGetTime_() -oldmillisecs.f ; Dont forget to use floats!
oldmillisecs.f = TimeGetTime_()
;
ClearScreen(#black) ; ClearScreen black
;
yscroll.f = yscroll.f+deltatime.f*(480/2000) ; this is movement by time elapsed.
If yscroll.f >= 480 : yscroll.f=yscroll.f-480 : EndIf
;
DrawBox(320,yscroll,16,16, Color.White)
Until KeyPressed
End
;-------- How to understand the stuff --------
;
; "yscroll.f" is our variable we would normaly use to move our object like "yscroll+1" or whatever but we dont have
; to use a fix variable like +1 for an independent fps! We have to calculate this variable (moving steps) :wink:
;
; We have to calculate the steps using "yscroll.f = yscroll+deltatime.f*(480/2000)" for example... The only important
; things in this line are the vals 480 and 2000 for us... This means: We want to move an object on a way of 480 pixel
; (our screenhigh for example) and the object should move this way in only 2 seconds (also 2000 millisecs) ...
;
; If you want for example, that our object will need 4,5 seconds to move this 480 pixels - you have to write (480/4500)
; Thats all... I think this small example with documentation should be good enough and not to hard to understand for
; your next projects :wink:
;
; Good luck... va!n aka Thorsten
|
Theoretisch hört sich das mit Deltatime recht gut an... Allerdings gibt es hier auch - bzw kann i.a. auch - einige unschöne Nebeneffekte haben.... Es gibt zu dem Theme FPS unabhängige Programmierung verschiedene Ansätze und Lösungen, die alle ihre Vor- und Nachteile haben..
[Edit]
Btw, zweimal den Timer aufrufen ist einfach nur sehr schlechter Programmierstil und man verschwendet damit ein paar ticks... Obriges Basic-Beispiel besser nicht verwenden... Das war damals mein erster Versuch FPS unabhängigkeit zu testen, was selbst mit verwendung von Float teils leichte unschöne Ruckler beim scrollen verursacht hat! |
|
| Nach oben |
|

|
Monsaic Member
Anmeldedatum: 20.08.2008 Beiträge: 203 Wohnort: Gelsenkirchen
|
Verfasst am: 30.07.2010, 01:05 Titel: |
|
| reisi89 hat Folgendes geschrieben: | hmm?! das mit dem gameTime multiplizieren raff ich jetzt nicht ganz!?
Könnte mir das jemand näher erläutern bitte?
lg |
Du willst nen Sprite 100px pro Sekunde bewegen. v = 100
t=0; pos=0 //Sprite befindet sich am Anfang an Position 0
t=1; pos=100 //Eine Sekunde später, der nächste Frame. 1 Sekunde = 100Pixel Bewegung
t=1.5; pos=150 //Eine halbe Sekunde später. elapsedSeconds = 0.5, elapsedSeconds * v = 0.5*100 = 50. Der Sprite wurde um 50px verschoben.
t=1.6; pos=160 //Eine weitere Zehntelsekunde später der nächste Frame. Eine Zehntelsekunde => Ein Zehntel der Strecke die pro Sekunde zurückgelegt werden muss. 10 Pixel
So setzt du immer die Translation in Abhängigkeit zur verstrichenen Zeit. |
|
| Nach oben |
|

|
Glatzemann Member
Anmeldedatum: 24.07.2009 Beiträge: 3327 Wohnort: Leverkusen
|
Verfasst am: 30.07.2010, 06:24 Titel: |
|
Was gibt es denn konkret für Probleme und was gibt es bei der XNA-Lösung für Nachteile? So wie das in XNA gemacht wird, hat sich das Tausendfach als gute Lösung herausgestellt.
Dein Source kann auch nicht funktionieren, da du nicht die Draw-Delta-Time ermittelst, sondern die Delta-Time zwischen zwei GetTime-Aufrufen. Wenn du die Deltatime als letzten Befehl in der Schleife speicherst, dann kommst du der Sache schon deutlich näher. _________________ Twitter · YouTube · MotoX Racers
|
|
| Nach oben |
|

|
Ganda Member
Anmeldedatum: 29.10.2009 Beiträge: 521 Wohnort: Germany, NRW
|
Verfasst am: 31.07.2010, 09:04 Titel: |
|
Ach ja, und wenn Du mal ausprobieren willst, ob es denn auch funktioniert, musst Du die konstante FPS-Rate ausschalten:
| Code: | [Game]
IsFixedTimeStep = false;
graphics.SynchronizeWithVerticalRetrace = false; |
Ich habe mich zu Anfang nämlich gewundert, warum selbst die einfachsten Szenen nicht über 62 FPS kommen ....
Gruß Ganda _________________ Mein Gameblog! |
|
| Nach oben |
|

|
simsmaster Member
Anmeldedatum: 05.08.2009 Beiträge: 603 Wohnort: Langenhagen
|
Verfasst am: 31.07.2010, 11:01 Titel: |
|
Ich kann auch nur die GameTime Methode empfelen, funktioniert 1A. Ist wohl auch der Hauptgrund, warum es die GameTime gibt  _________________ mfg Simsmaster
Mein Projekt: The Kingdom of Darkness |
|
| Nach oben |
|

|
JeReT Member
Anmeldedatum: 19.07.2007 Beiträge: 1566 Wohnort: µnchen
|
|
| Nach oben |
|

|
va!n Member
Anmeldedatum: 23.05.2010 Beiträge: 122 Wohnort: Herne (NRW)
|
|
| Nach oben |
|

|
Glatzemann Member
Anmeldedatum: 24.07.2009 Beiträge: 3327 Wohnort: Leverkusen
|
Verfasst am: 01.08.2010, 09:52 Titel: |
|
Ja, das was in Link 1 beschrieben ist, macht XNA doch ungefähr.
Du stellst eine TargetElapsedTime ein. Dies ist der gewünschte Zeitintervall in dem deine Update-Methode aufgerufen werden soll. Dies ist Standardmäßig bei allen Plattformen 1/60s also 16.6667ms = 60 Updates pro Sekunde. Kann diese Rate nicht erreicht werden (d.h. die Draw-Methode kann nicht so häufig aufgerufen werden, wie hier gefordert), so wird IsRunningSlowly auf True gesetzt.
Aktivieren kann man das ganze mit IsFixedTimeStep.
Das Verhalten ist nun wie folgt:
1. Update wird aufgerufen
2. Update wird solange wiederholt aufgerufen, solange TargetElapsedTime bereits wieder vergangen ist
3. Draw wird aufgerufen
4. es wird so lange gewartet, bis Update wieder aufgerugen werden muss und bei 1 weitergemacht. Diese Zeit kann auch 0 sein.
Wird Punkt 2 ausgeführt, so wird IsRunningSlowly gesetzt, da dies bedeutet, daß Update länger als die TargetElapsedTime dauert und damit der Intervall nicht gehalten werden kann.
Eine weitere Besonderheit ist, daß hier Draw-Aufrufe wegfallen können im Verhältnis zu Update bzw. einfacher ausgedrückt: Die Anzahl der Update und Draw Aufrufe kann unterschiedlich sein. Das ist auch logisch, wenn man sich deine weiteren Links durchliest. Es ist oft wichtig, daß man einen "FixedTimeStep" hat, also Update möglichst immer im gleichen Intervall aufgerufen wird. Wenn nicht, kann dies zu ruckeln oder der "Explosion" von Physik-Simulation führen (und vielem mehr). Ob jetzt ein so berechnetes Bild 60 mal pro Sekunde gerendert wird oder nicht ist rein optischer Natur. Wenn ich eine Simulation mit 60 Updates pro Sekunde laufen lasse, aber nur 10 Bilder pro Sekunde darstelle, dann ist das Ergebnis zumindest das gleiche, auch wenn die Darstellungsqualität darunter leidet.
Das sind unter anderem auch die Gründe, warum es keinen Sinn macht, ohne diese Limitierung zu arbeiten, sondern einfach so viele FPS wie möglich "durchjagt". Die Abstände zwishen den Update und Draw-Calls fluktuieren stark, wenn man am oberen Limit arbeitet und dies führt zu den Problemen, die hinter deinen Links beschrieben sind.
Das Standardverhalten von XNA ist also sehr gut geeignet. Alles was man noch machen muss ist, mit der GameTime zu multiplizieren, da so die (geringen) Unterschiede zwischen z.B. 30Hz (Windows Phone) und 60 Hz (PC, XBox) ausgeglichen werden können.
Es kommt also weniger auf die Anzahl der Update-Aufrufe an, sondern eher darauf, daß diese immer möglichst gleichmäßig sind. _________________ Twitter · YouTube · MotoX Racers
|
|
| Nach oben |
|

|
|
|
|