Register for your free account! | Forgot your password?

Go Back   elitepvpers > Coders Den > C/C++
You last visited: Today at 18:53

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



Framerate Limit

Discussion on Framerate Limit within the C/C++ forum part of the Coders Den category.

Reply
 
Old   #1


 
X0R0N's Avatar
 
elite*gold: 138
Join Date: Jan 2009
Posts: 2,216
Received Thanks: 6,018
Arrow Framerate Limit

Hi Zusammen, da ich seid kurzem in C++ eingestiegen bin, schreibe ich gerade ein Spiel in C++ mit SDL und openGL.
Funktioniert schon alles ganz gut, nur hab ich das Problem, dass meine Framerate abhängig davon ist, wie schnell die Hauptschleife (Input, logic und renderingteil) durchlaufen wird. Das hat zur Folge, dass der Spielablauf auf verschiedenen Rechnern verschieden schnell ist.

Ich hab nun versucht die Framerate auf ein Festes Limit zu zwingen, indem ich die gesamte Schleife übersprungen hab, wenn das Limit überstiegen wurde, da ich mir nicht ganz vorstellen kann, wie ich die Bewegungen in Abhängigkeit von der Framerate berechnen kann.
Hier ein Stück code dazu zur Veranschaulichung:


Code:
#include <time.h>

int frames = 0;
int frameRate = 60;

if( frames/(clock()/CLOCKS_PER_SEC) <= frameRate)
{
    frames++;
    //INPUT
    ...
    //LOGIC
    ...
    //RENDERING
    ...
}
Jetzt habe ich aber das Problem, dass das Spiel immer kurz stehen bleibt, sobald die ausgerechnete Framerate (frames/(clock()/CLOCKS_PER_SEC))
den von mir in frameRate festgelegten Wert 60 übersteigt.
Weis vielleicht jemand, wie ich die Framerate limitieren, und doch den flüssigen Ablauf beibehalten kann?

Gruß,
X0R0N
X0R0N is offline  
Old 04/02/2012, 19:04   #2


 
MrSm!th's Avatar
 
elite*gold: 7110
Join Date: Jun 2009
Posts: 28,902
Received Thanks: 25,407
Außerdem hättest du noch das Problem, dass das Spiel auf Rechnern langsamer läuft, die nichtmal dein Framerate Limit erreichen.

Normalerweise macht man das, indem man in jede Bewegung einen Zeitfaktor einfließen lässt, sodass halt die Bewegung abhängig ist, wie lange das Rendering dauert.

Bspw. mit
Code:
//bewegung eines spielers
while(key_pressed("w"))
    player.position += velocity*time_passed;
Je schneller gerendert wird, desto weniger Zeit vergeht und desto weniger schnell ist der Spieler dafür.
MrSm!th is offline  
Old 04/02/2012, 19:07   #3
 
Dr. Coxxy's Avatar
 
elite*gold: 0
Join Date: Feb 2011
Posts: 1,206
Received Thanks: 736


liefert die benötigte auflösung...
Dr. Coxxy is offline  
Old 04/02/2012, 19:20   #4
 
elite*gold: 50
Join Date: Mar 2010
Posts: 1,373
Received Thanks: 521
Wenn du es mit Hilfe von SDL lösen willst kannst du das hier nutzen:
Klasse:

Implementierung

Nutze am besten nichts, was mit der WinAPI auf direktem Wege zu tun hat. Ich meine wenn schon SDL und OpenGL dann auch richtig
jacky919 is offline  
Old 04/02/2012, 20:20   #5


 
MrSm!th's Avatar
 
elite*gold: 7110
Join Date: Jun 2009
Posts: 28,902
Received Thanks: 25,407
Quote:
Nutze am besten nichts, was mit der WinAPI auf direktem Wege zu tun hat. Ich meine wenn schon SDL und OpenGL dann auch richtig
Plattformunabhängigkeit ist nicht der einzige Grund für die SDL, also wieso sollte man deshalb vollständig auf die Winapi verzichten?
MrSm!th is offline  
Old 04/02/2012, 20:41   #6
 
elite*gold: 50
Join Date: Mar 2010
Posts: 1,373
Received Thanks: 521
Quote:
Originally Posted by MrSm!th View Post
Plattformunabhängigkeit ist nicht der einzige Grund für die SDL, also wieso sollte man deshalb vollständig auf die Winapi verzichten?
Das war jetzt auch mehr auf diesen Fall bezogen. Wenn man nicht drum herum kommt ist das natürlich vollkommen legitim, aber ich finde es unnötig, wenn SDL dem Programmierer schon die Möglichkeit gibt, die Dinge mit einem viel höheren Abstraktionsgrad von sich aus zu nutzen.
jacky919 is offline  
Old 04/02/2012, 20:52   #7
 
elite*gold: 0
Join Date: Apr 2012
Posts: 11
Received Thanks: 1
Hallo,
Ich denke Ich kann dir helfen.

Code:
  // Framebremse (etwas veraltete, dafür einfache Variante, das 
  // Physikverhalten bei höheren Frameraten einigermaßen korrekt zu halten)
  // Achtung: hier werden Pipeline-Effekte des OpenGL vernachläßigt!
  //while((clock()-frame_start_time)*120 < CLOCKS_PER_SEC);						//Framebremse ist deaktiviert
clock_t frame_start_time = clock();
ef784fH/FAE7 is offline  
Old 04/02/2012, 21:23   #8


 
X0R0N's Avatar
 
elite*gold: 138
Join Date: Jan 2009
Posts: 2,216
Received Thanks: 6,018
Quote:
Originally Posted by MrSm!th View Post
Außerdem hättest du noch das Problem, dass das Spiel auf Rechnern langsamer läuft, die nichtmal dein Framerate Limit erreichen.

Normalerweise macht man das, indem man in jede Bewegung einen Zeitfaktor einfließen lässt, sodass halt die Bewegung abhängig ist, wie lange das Rendering dauert.

Bspw. mit
Code:
//bewegung eines spielers
while(key_pressed("w"))
    player.position += velocity*time_passed;
Je schneller gerendert wird, desto weniger Zeit vergeht und desto weniger schnell ist der Spieler dafür.
Danke, das hört sich gut an. Doch wie komme ich auf diesen Zeitfaktor?
Wenn ich, so wie ich es mache die FPS berechne, hab ich ja schonmal die Geschindigkeit, mit der die Schleife durchlaufen wird bestimmt (frames/(clock()/CLOCKS_PER_SEC)).
Damit sollte ich ja was anfangen können. Mir ist nur nicht ganz klar, wie ich den Wert verrechne, sodass ein passender Faktor rauskommt, der das Spiel auf allen Systemen unabhängig von der Framerate gleich schnell laufen lässt, wenn ich diesen wiederrum mit der Bewegungsgeschwindigkeit eines Objekts im Spiel verrechne.
X0R0N is offline  
Old 04/02/2012, 21:38   #9
 
elite*gold: 50
Join Date: Mar 2010
Posts: 1,373
Received Thanks: 521
Quote:
Originally Posted by X0R0N View Post
Danke, das hört sich gut an. Doch wie komme ich auf diesen Zeitfaktor?
Klasse:

Implementierung

Quote:
Originally Posted by X0R0N View Post
Wenn ich, so wie ich es mache die FPS berechne, hab ich ja schonmal die Geschindigkeit, mit der die Schleife durchlaufen wird bestimmt (frames/(clock()/CLOCKS_PER_SEC)).
Damit sollte ich ja was anfangen können. Mir ist nur nicht ganz klar, wie ich den Wert verrechne, sodass ein passender Faktor rauskommt, der das Spiel auf allen Systemen unabhängig von der Framerate gleich schnell laufen lässt, wenn ich diesen wiederrum mit der Bewegungsgeschwindigkeit eines Objekts im Spiel verrechne.
Also wenn du das von mit benutzt musst du nur Vergange Zeit(in Millisekunden)*Weg pro Millisekunde. Da das Rechnen mit Millisekunden vielleicht etwas umständlich ist, kannst du die Zeit natürlich einfach durch 1000 teilen, um mit Sekunden zu rechnen. Nach dem Rendern musst du den Timer dann einfach wieder zurücksetzen.
jacky919 is offline  
Old 04/02/2012, 21:51   #10


 
MrSm!th's Avatar
 
elite*gold: 7110
Join Date: Jun 2009
Posts: 28,902
Received Thanks: 25,407
Quote:
Originally Posted by X0R0N View Post
Danke, das hört sich gut an. Doch wie komme ich auf diesen Zeitfaktor?
Wenn ich, so wie ich es mache die FPS berechne, hab ich ja schonmal die Geschindigkeit, mit der die Schleife durchlaufen wird bestimmt (frames/(clock()/CLOCKS_PER_SEC)).
Damit sollte ich ja was anfangen können. Mir ist nur nicht ganz klar, wie ich den Wert verrechne, sodass ein passender Faktor rauskommt, der das Spiel auf allen Systemen unabhängig von der Framerate gleich schnell laufen lässt, wenn ich diesen wiederrum mit der Bewegungsgeschwindigkeit eines Objekts im Spiel verrechne.
Das ist einfach die vergangene Zeit.
Am Anfang jedes Durchgangs rufst du sie beispielsweise (Achtung: WinApi!) so ab:

Code:
DWORD time_passed = 0;

//in der loop
time_passed = timeGetTime() - time_passed;
//übergabe von time_passed an alle funktionen, die von der geschwindigkeit des PCs abhängig sein und es deshalb in die aktionen mit einberechnen sollen
Quote:
Also wenn du das von mit benutzt musst du nur Vergange Zeit(in Millisekunden)*Weg pro Millisekunde. Da das Rechnen mit Millisekunden vielleicht etwas umständlich ist, kannst du die Zeit natürlich einfach durch 1000 teilen, um mit Sekunden zu rechnen. Nach dem Rendern musst du den Timer dann einfach wieder zurücksetzen.
Ähm, es wäre eher umständlich, erst durch 1000 teilen zu müssen, zumal man dann Float als Datentyp nehmen muss, was wieder langsamer als int in der Berechnung ist (auch wenn es in so einem Fall vermutlich egal ist).
Da er die Zeit einfach immer nur weitergibt und Werte mit ihr multipliziert, gibt es keinen Grund, in Sekunden umrechnen zu müssen. Wo soll da der Vorteil liegen? Er will sie ja nicht ausgeben o.Ä. wo das Format eine Rolle spielen würde.
MrSm!th is offline  
Old 04/02/2012, 22:13   #11
 
elite*gold: 50
Join Date: Mar 2010
Posts: 1,373
Received Thanks: 521
Quote:
Originally Posted by MrSm!th View Post
Ähm, es wäre eher umständlich, erst durch 1000 teilen zu müssen, zumal man dann Float als Datentyp nehmen muss, was wieder langsamer als int in der Berechnung ist (auch wenn es in so einem Fall vermutlich egal ist).
Da er die Zeit einfach immer nur weitergibt und Werte mit ihr multipliziert, gibt es keinen Grund, in Sekunden umrechnen zu müssen. Wo soll da der Vorteil liegen? Er will sie ja nicht ausgeben o.Ä. wo das Format eine Rolle spielen würde.
Um floats wird er eh schlecht herum kommen, denn es sind ja relativ lange Wege pro Sekunde erforderlich, damit der Weg pro Sekunde größer als bzw. gleich 1 ist.
jacky919 is offline  
Old 04/02/2012, 23:49   #12


 
X0R0N's Avatar
 
elite*gold: 138
Join Date: Jan 2009
Posts: 2,216
Received Thanks: 6,018
Der sagt bei mir timeGetTime() ist nicht deklariert, obwohl die includes da sind, darum hab ich jetzt einfach mal SDL_GetTicks() genommen. Liefert im Grunde nichts anderes.

Ich habs so gemacht:
Code:
    int ticksPassed = 0;

    //Main Game loop ######################################
    while(isRunning)
    {
        ticksPassed = SDL_GetTicks() - ticksPassed;
        std::cout << "Time Passed: " << ticksPassed << " (Current: " << SDL_GetTicks() << ")\n";
Zum Test die cout Zeile eingefügt, die liefert mir jetzt aber unerwartete Ergebnisse... Ziemlich unregelmäßig und vor allem immer größer werdend.

Die kann ich ja wohl nicht verwenden... Eigentlich müsste der Millisekundenwert immer ziemlich gleich sein, da es ja immer der zeitabstand zum letzten Frame ist oder irre ich mich?


€dit:

Quote:
Originally Posted by MrSm!th View Post
Code:
DWORD time_passed = 0;

//in der loop
time_passed = timeGetTime() - time_passed;
//übergabe von time_passed an alle funktionen, die von der geschwindigkeit des PCs abhängig sein und es deshalb in die aktionen mit einberechnen sollen

Die Rechnung hatte einfach nicht so ganz gestimmt. Habs jetzt etwas korrigiert:

Code:
    int ticks = SDL_GetTicks();
    int ticksPassed = 0;

    //Main Game loop ######################################
    while(isRunning)
    {
        ticksPassed = SDL_GetTicks() - ticks;
        ticks = SDL_GetTicks();

        std::cout << "Time Passed: " << ticksPassed << " (Current: " << SDL_GetTicks() << ")\n";
Und bekomme jetzt auch akzeptable Werte:


Demnach dauert auf meinem Rechner ein Schleifendurchlauf im Schnitt 10ms.
Soll ich das jetzt einfach durch 10 Teilen, damit 1 rauskommt, und die velocity immer damit multiplizieren? Dürfte dann ja auf anderen Rechnern gleich schnell laufen, oder irre ich mich?
X0R0N is offline  
Old 04/03/2012, 01:07   #13


 
MrSm!th's Avatar
 
elite*gold: 7110
Join Date: Jun 2009
Posts: 28,902
Received Thanks: 25,407
Stimmt, hast Recht, war ein kleiner Denkfehler von mir. timeGetTime sollte eigentlich vorhanden sein, wenn du windows.h einbindest.

Wenn du durch 10 teilst erhälst du 1, korrekt. Damit hast du aber nichts gewonnen, was passiert denn, wenn du etwas mit 1 multiplizierst?
Du sollst nun einfach alles mit dieser 10 multiplizieren (genauer genommen mit ticksPassed). Auf PCs, die etwas langsamer sind wird dort vielleicht nicht 10 sondern 100 stehen, d.h. die Schleife wird zwar 10 mal weniger in der Sekunde durchlaufen, dafür bewegen sie sich 10 mal schneller und das ganze wird aufgehoben.
Ein Problem wird es erst, wenn die Zahl der Schleichendurchläufe so gering wird, dass es halt anfängt zu ruckeln, also die Schleife 2 mal durchlaufen wird und dafür die Geschwindigkeit 500facht wird.

Quote:
Um floats wird er eh schlecht herum kommen, denn es sind ja relativ lange Wege pro Sekunde erforderlich, damit der Weg pro Sekunde größer als bzw. gleich 1 ist.
Es war ein schwaches Argument, gebe ich zu, trotzdem gibt es auch keinen sinnvollen Grund, float hier int vorzuziehen.
Dennoch gebe ich dir nicht 100%ig Recht. Ein int bietet viel Speicherplatz, das kann dir theoretisch also egal sein. In S4 sind die Koordinaten nur Ganzzahlen, (auch wenn sie theoretisch in float gespeichert werden, ist ein Schritt circa ein +1) da ist dann ne Map halt mal 2000 Einheiten lang, na und?
Finde ich persönlich sogar einleuchtender als solche Spiele, in denen sich deine Koordinaten zwischen 1 und 10 bewegen :/

Du hast da übrigens einen kleinen Formulierungsfehler drin:

Quote:
denn es sind ja relativ lange Wege pro Sekunde erforderlich, damit der Weg pro Sekunde größer als bzw. gleich 1 ist.
Nö, dafür wird ein Weg von 1 pro Sekunde benötigt

Du meintest vermutlich es sind relativ lange Wege pro Sekunde erforderlich, damit die Wege pro Millisekunde 1 sind. Aber, wo ist das Problem? Interessiert doch nicht, wie hoch nun die tatsächliche Zahl ist, du kannst das in einer virtuellen Welt ja interepretieren wie du willst. Musst ja nicht die 1 = 1 Meter setzen.

Ich sehe weiterhin keinen Vorteil darin, float zu nutzen.
MrSm!th is offline  
Old 04/03/2012, 02:56   #14


 
X0R0N's Avatar
 
elite*gold: 138
Join Date: Jan 2009
Posts: 2,216
Received Thanks: 6,018
Oh sehr gut, dann muss ich, wenn ich das *ticksPassed nehme nur noch die Velocity bei mir so einstellen, dass es mit der neuen Rechnung optimal schnell läuft, und mein Problem müsste gelöst sein.
Danke für die Hilfe, ich schreib das dann nachher fertig und meld mich hier nochmal.
Jetzt erstmal ne Mütze Schlaf holen. N8

€dit: So funktioniert perfekt. Vielen Dank für die Hilfe!
X0R0N is offline  
Reply


Similar Threads Similar Threads
FrameRate abstürtze?!
01/21/2012 - Call of Duty - 0 Replies
Hey, also ich habe mal eine Frage. Seid ein paar Tagen stürtzt meine Framerate bei MW3 ab und zu ab. Ich dachte anfangs das wären leggs aber meine Leute mit denen ich zocke haben das auch. Kommt das von MW3 oder von uns?
Psf hack NGZ by:alkey99 Framerate V.6
08/21/2011 - Soldier Front Philippines - 3 Replies
removed
WoW - Niedrige Framerate
07/17/2011 - World of Warcraft - 2 Replies
Hallo, zu Anfang, ich habe das bewusst hier gepostet weil ich glaube, dass in der Technical-Support Section kaum Leute damit Erfahrung haben und mir weiterhelfen können. Es gibt hier bestimmt mehr Leute, mit Ahnung von dem Spiel und dessen Einstellungen. Ich wollte mal wieder auf einem privaten Server spielen, dieser hat die Version 3.3.5a und 20.000 Spieler. Es hat früher immer gut geklappt, es lief alles flüssig. Wie gesagt, ich wollte mal wieder spielen aber meine Framerate ist...
[Revised] Unlocking Framerate
02/14/2011 - CO2 Programming - 6 Replies
Ok, so I was looking back in to unlocking framerate for someone, and the old JNB-JMP method still works the same but the unfortunate side effect is that 100% of the resources go into that unlocked client, slowing down the rest of the PC. The proper way to do it is to set the framerate the same as the refresh rate, as most people have a screen that runs at 60Hz, I have attached a 60fps client for Patch 5363. REINFORCE: THERE IS NO POINT IN GETTING 100+ FPS IF YOU ONLY HAVE A SCREEN THAT...
Increased framerate!?
12/16/2005 - Conquer Online 2 - 3 Replies
hi all! I noticed a while back that sometimes the framerate of my co2 went from 31-32 up to 37-39 and i didnt find an explanation. Now i know, whenever i open a browser and load the conqueronline.com page and keep it open, the framerate increases and the game runs more smoothly. Can some1 confirm this?



All times are GMT +1. The time now is 18:53.


Powered by vBulletin®
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2025 elitepvpers All Rights Reserved.