Sign in to follow this  
kelcharge

Limiting Frames Per Second?

Recommended Posts

In my game engine, I would like it to run at a smooth 60 frames per second, but it always seems to be higher than this. How would I limit the number of FPS? I am using Dev-C++ and Allegro.

Share this post


Link to post
Share on other sites
Quote:

...thou shalt not limit your frame rate.
...thou shalt use time based updates.


found carved on stone plaques in during a cave excavation, heed the wisdom of ancient cultures and listen to the message.

Share this post


Link to post
Share on other sites
Quote:
Original post by skittleo
I recommend limiting your framerate, and you will find many games do. They do this because as framerates increases, movement distance decreases per frame and eventually you'll run into floating point errors and things happening that wouldn't normally happen at 60fps.


This is basicly a fallacy. Most games don't and the problems that you mention are easily remedied by using a 'scrap' counter and for physics using a fixed timestep (something you probably want todo anyhow). With that out of the way you can use the extra framerate to react faster to user input handle networking and do loads of stuff that's far better than sitting in a busy wait loop.

Share this post


Link to post
Share on other sites
Agreed, if you really want a fixed framerate, then for heavens sake, don't use a busy idle loop. Either use Sleep(), so other apps can use the leftover CPU time, oro do something with it yourself. You might be able to process input or physics or networking or other stuff while waiting for the next frame (or as DigitalDelusion says,just use a fixed timestep, and the entire game can run at the faster framerate, which will be a lot easier for you to manage)

Share this post


Link to post
Share on other sites
Quote:
Original post by skittleo
Ps: Sorry DigitalDelusion, but I had to disagree. I never used to cap my framerate until I started experiencing precision problems, and then I realized that capping the framerate is pretty common in games.


The inprecision arise because you're taking varied timesteps and will often cause very strange things indeed (like jump distance dependant on framerate etc) so you've correctly identified one problem (varied timesteps) but your solution is to be blunt, crap!

What you really ought todo, and what I've been trying to say all along is that you problaby want something like

delta = scrap + TimeSinceLastFrame();
//handle physics
for(; delta >= timestep; delta -= timestep)
StepPhysics( timestep);
scrap = delta;//save scrap time
//handle input and non time dependant stuff here


this way you keep your physics chugging along nicely and keep it quite deteremnistic while not busy waiting and spending the extra cycles doing real work (like responding to player input)

Share this post


Link to post
Share on other sites
I've been seeing a post about FPS limit at least once a week for some time now.

Try to recycle.
Answered here.

Share this post


Link to post
Share on other sites
Quote:
Original post by skittleo
I already acknowledged that fixed timesteps are a better solution. And it's good that you for providing some sample code to kelcharge. I have used both in my applications, and if you did not provide an example for fixed timesteps, I would have.

That said, my solution is not "blunt crap." I am sorry you became offended when I pushed for a very simple solution. Take it with a grain of salt next time. But it's better than no limit at all.


My main objection is that the solution is hiding a problem instead of solving it, correctly identifying what goes wrong and handling the cause is in my oppinion much more valuble than providing a quick fix in many circumstances.

Maybe my reply was overly rethoric but at a grander scale it did help foster a more throug discussion providing a more solid (although perhaps not as clear cut) answer to the original post.

Share this post


Link to post
Share on other sites
I'm going to come in with DigitalDelusion on this one, capping the framerate is a bad bad bad bad idea, it'll cheese off more people than it'll help [grin]

The best solution is an uncapped drawing rate, an update which runs every X milliseconds and a spot of interpolation.

Many games wont limit their framerate beyond that which v-sync provides (for example, I'll always try to run a game with v-sync on and a refresh rate of at least 75hz to prevent my eyes becoming strained), instead they use desceet steps to update the world/physics so that the varying step sizes dont accure and the simulation becomes unbalanced.

Then to get the smooth movement they can interpolate between two frames of data (last and current) to generate the movement.

Doing this means that the simulation stays intact whilst the guy who paid out a few £1000 for his top of the line super PC with more graphics power than you can shake a stick at can run the game at a smooth 85fps.

I'm disapointed that no one has linked to the page on the canioical game loop, which is designed to solve just this problem (extra credit to those who can make it work sanely in a Multi-thread enviroment, dont laugh as MT is the future and this does infact scale very well for it).

So in short, I refer you back to DigitalDelusion's opening post;
...thou shalt not limit your frame rate.
...thou shalt use time based updates.

Share this post


Link to post
Share on other sites
Quick lets all get into a heated debate on when to use KISS and AGILE development practices! You should always look at the simple solution in this case limit the framerate. You should also see if any other solutions available becuase you might not see a problem that will arise but others might. It is easy to just keep it simple, but problems can arise so you should at least try to figure out what they might be then judge to see which way is the overall best. In this case it all depends on how indepth your game is going to be. If you think you can get away with frame limit, then hey, its very easy. I personally have used it before, but I am going to try to go the other direction with my current project just to expand a little.

-THACO

Share this post


Link to post
Share on other sites
Quote:
Original post by _the_phantom_
I'm going to come in with DigitalDelusion on this one, capping the framerate is a bad bad bad bad idea, it'll cheese off more people than it'll help [grin]

The best solution is an uncapped drawing rate, an update which runs every X milliseconds and a spot of interpolation.

Many games wont limit their framerate beyond that which v-sync provides (for example, I'll always try to run a game with v-sync on and a refresh rate of at least 75hz to prevent my eyes becoming strained), instead they use desceet steps to update the world/physics so that the varying step sizes dont accure and the simulation becomes unbalanced.

Then to get the smooth movement they can interpolate between two frames of data (last and current) to generate the movement.

Doing this means that the simulation stays intact whilst the guy who paid out a few £1000 for his top of the line super PC with more graphics power than you can shake a stick at can run the game at a smooth 85fps.

I'm disapointed that no one has linked to the page on the canioical game loop, which is designed to solve just this problem (extra credit to those who can make it work sanely in a Multi-thread enviroment, dont laugh as MT is the future and this does infact scale very well for it).

So in short, I refer you back to DigitalDelusion's opening post;
...thou shalt not limit your frame rate.
...thou shalt use time based updates.

Although i do agree with most of what you say, there is still another perpective.

Not limiting the frame rate, is great for the graphics, animation, and so on, but it will take much more, if not all, CPU power. Now that may be meaningless in many cases, but if someone wanted to process some extra physics, AI, or whatever else, the extra cpu power could come in handy. So instead of processing 100+ frames that the monitor may not even be able to keep up with, why not just use the extra time in other areas? The extra cpu time could even be used by the player himself to run other applications besides the game, like Skype, FRAPS, or his favorite media player without stalls.

I for one wouldn't be so quick to throw the frame rate limiting in the bin, depending on the situation, it might come in handy.

Share this post


Link to post
Share on other sites
Actually that's a good reason to decouple your drawing from the rest of the game and put it in its own thread that way you can either use vsync or draw things as fast as you can and let updates and user interaction flow free in parallel.

Needless to say such an arangement needs quite much care to both avoid oversynchronization and ugly update glitches.

Share this post


Link to post
Share on other sites
Quote:
Original post by DigitalDelusion
Needless to say such an arangement needs quite much care to both avoid oversynchronization and ugly update glitches.


Indeed, however its not as hard as it first appears however, once you get the idea of having 3 frames of data in flight at any given time. (this was the biggest brain breaker for me, heh, that and getting my interpolation utterly wrong due to a lack of sleep [grin])

The only time I'd consider framerate limiting is for a window'd app which didnt have focus and even then I'd prefer to rely on v-sync todo the limiting, however while a game is fullscreen it is perfectly fine for it to use all the resource it requires, so if the end user has switched off v-sync (always make this an option, never force it) they have given you permission to use as much CPU time as you require, by the same token if they enforce v-sync they are limiting your refresh rate and thus (with a MT system and aways) the CPU time you are using to render.

The point about 'giving more CPU time to other section' is a tad moot imo, these routines should take as long as they require, in a single thread system that means kick off your update and then render once its done, you can ofcourse simplify the updates but that should be either an application detected setting or a per-cpu setting (for example, if you start to use too much time on an update you might want to automatically scale things down a bit until the update time stablises a bit lower).

In a MT world this becomes even easier todo, as thread will be automatically swapped in an out as they block on hardware, so while rendering if your rendering thread blocks because a resource is busy the OS can flip to your update thread which could get some work done and then say it gets stalled on a page fault the thread can be swapped back to the rendering thread and so it repeats.
(and thats on a single CPU system, on a multiple CPU system you'll have the two threads running at teh same time anyways, so the amount of time the rendering thread takes is moot.)

As with all tools there are times when frame rate limiting might come in handy, for example if I was working on a map editor I might well try and maintain a lowish framerate as you dont need to see the map at 100s of frames per second, however the OP was working on an engine and it just seems daft to limit at the engine level, really the limiting needs to be defined at the user application level if at all (as to how I leave as an exercise for the reader)

Share this post


Link to post
Share on other sites
This is what I'm using. It was originally writen by the maker of SDL_gfx. I re-wrote it in C# and put it directly into something I'm working on right now.
private static uint m_FrameCount = 0;
private static float m_RateTicks = 1000F / 60F;
private static uint m_LastTicks = 0;
private static uint m_Rate = 60;


/// <summary>
/// Gets and sets the desired framerate.
/// </summary>
public static uint Framerate
{
get
{
return m_Rate;
}
set
{
if ((value >= 1) && (value <= 200))
{
m_FrameCount = 0;
m_Rate = value;
m_RateTicks = (1000.0F / (float) value);
}

}
}

private static void FramerateDelay()
{
uint current_ticks = 0;
uint target_ticks = 0;
m_FrameCount++;
current_ticks = (uint) // Get Ticks
target_ticks = m_LastTicks + (uint) ((float) m_FrameCount * m_RateTicks);

if (current_ticks <= target_ticks)
{
// Sleep the number of milliseconds required to create the right framerate
//Sleep((int)(target_ticks - current_ticks));
}
else
{
m_FrameCount = 0;
m_LastTicks = current_ticks;
}
}


You can see that you change the FrameRate property to set the amount of frames that will be called per second. All you do is call the FramerateDelay() function within your gameloop and it manages the rest for you. Of course, you're going to have to change the sleep and get ticks methods depending on your API.

Share this post


Link to post
Share on other sites
Ok, how about multiplier games?
Every instance has to simulate same environment (this mostly appears to physics). So I cannot use fixed timestep. Limiting the update frequency is the only way, AFAIK.
There is a little point in rendering additional frames just for the sake of rendering, if the data is not changing (however, the GUI could, perspective could). Interpolating between data-frames could be the way, but I cannot even imagine how that should be done, without turning the program code into a mess (but the challenge is entertaining ;))

Share this post


Link to post
Share on other sites
For multi-player games a fixed world update pulse is PERFECT, every client will update the same amount each time and at a set time, making data syncing that much easier to achieve and physics much more predictable.

While the frame position data might not be changing each frame (which is a good thing) you can improve the animation because for 10ms you'll be interpolating between two positions giving smooth movement and the more frames you can throw at the user the smoother this will appear.

The whole interpolation is very each to achieve, at the most basic level you'll have a function which performs the creation of the new state and when rendering you select the correct two states and perform simple linear interpolation between them.

The following is some snippets from a Multi-thread version of what I'm talking about, 3 functions do all the work (basic work, but it is only proof of concept).

void Scene::UpdateTimeSteps(int time)
{
// check if we need to update and if we can update
if(time < currentframeptr->time || currentframeptr->time > nextframeptr->time)
return;

// Copy middle to oldest, newest to middle and dump the oldest timestep to being free to we can update it next 'frame'
std::swap(lastframeptr,currentframeptr);
std::swap(currentframeptr,nextframeptr);
}

void Scene::Draw(int time)
{

int diff = time - lastframeptr->time;
float a = float(diff)/float(time_delta);
yrot = lastframeptr->yrot + ((currentframeptr->yrot - lastframeptr->yrot) * a);
xrot = lastframeptr->xrot + ((currentframeptr->xrot - lastframeptr->xrot) * a);

DrawNormal(-2.0f,0.0f); // left
DrawNormal(2.0f,0.0f); // right
DrawNormal(0.0f,-2.0f); // bottom
DrawNormal(0.0f,2.0f); // top
DrawNormal(-2.0f,-2.0f); // bottom left
DrawNormal(2.0f,2.0f); // top right
DrawNormal(-2.0f,2.0f); // top left
DrawNormal(2.0f,-2.0f); // bottom right
}

void Scene::Update(int time)
{
nextframeptr->xrot = currentframeptr->xrot + xspeed;
nextframeptr->yrot = currentframeptr->yrot + yspeed;
nextframeptr->time = time;
}



So, the update system calls Update() when its time to produce the next time set, the renderer then ensures we have the correct time data via UpdateTimeSteps() and finally the new data for the renderer is calcluated in the Draw() function.
(note, this is first generation code, it could be refined some more, by moving the interpolation into the UpdateTimeSteps() function leaving Draw() only responciable for drawing).

Share this post


Link to post
Share on other sites
Wait, let me get this straight.. I have nearly no experience in this area, so don't mock me [grin]

Anyway, what you're saying, phantom, is that, basically what you want to be doing is, say, every 10ms, sending an update to your physics management system, telling it where the position of all the bodies will be after the next 10 ms. Then, it can update as many times as it likes in between, interpolating between the old value and the new value based on the delta time, independant on the frame rate? I'm afraid the discussion hasn't been making very much sense to me, so I'm kind of looking for some clarification, in layman's terms [smile]
Thanks

Share this post


Link to post
Share on other sites
Basically: one thread updates all the data, and another one only renders, trying to smoothly interpolate between data-frames, that are already calculated.
It could be shown as:

// assume update 0 and 1 are already done.
update 2 starts...
render - 0.0
render - 0.3
render - 0.6
render - 0.9
update 2 ends.
update 3 starts...
render - 1.2
render - 1.5
render - 1.8
update 3 ends.
update 4 starts...
render - 2.1
render - 2.4
render - 2.7
render - 3.0
update 4 ends...
// that was somewhat ideal, but it could go as follows:
update 5 starts...
render - 3.3
render - 3.6
update 5 ends.
update 6 starts...
render - 4.0
render - 4.5
update 6 ends.
update 7 starts...
render - 5.0
render - 5.5
render - 6.0
// render stall, as we got no new data, give all the power to update thread.
update 7 ends.
update 8 starts...
render - 6.3
// ...





@_the_phantom_: your example is rather general. What I meant was that I would be having problems with rewriting all the objects that rely on their physics-specific data. As an entity, that has it's position, would now have 3. The same for velocity? And what-not? All of it?

Or do I have to simply have 3 copies of each object? With managers and all the stuff...
I'm a bit confused...

Share this post


Link to post
Share on other sites
ah right, I get you and yes, you'd have to duplicate the data, however its not as bad as you think [smile]

The reson being for this to work properly you'll want to contain all the per-frame state in a structure (this will mostly be positional infomation), so you'll have 3 copies of this structure in the class which represents the object.
You'll then need 3 pointers to this data, updates always work on the 'new data' pointer, while drawing always interpolates between 'old' and 'current', with pointer swapping taking place when you swap between frame data.

So, for the example above I have the following setup;

// very simple as its just spinning cubes, real world might be a little bigger
struct scenedata
{
float xrot; // current x rotation position
float yrot; // current y rotation position
int time; // time this update accured
};
class Scene
{

... stuff

private:
scenedata nextframe;
scenedata currentframe;
scenedata lastframe;
scenedata * lastframeptr;
scenedata * currentframeptr;
scenedata * nextframeptr;
}
Scene::Scene(GLfloat xrotspeed, GLfloat yrotspeed, GLfloat zoffset)
: xspeed(xrotspeed),yspeed(yrotspeed),zpos(zoffset)
{
currentframe.time = 0;
currentframe.xrot = 0;
currentframe.yrot = 0;
currentframeptr = &currentframe;

lastframe.xrot = 0;
lastframe.yrot = 0;
lastframe.time = 0;
lastframeptr = &lastframe;

nextframe.xrot = 0;
nextframe.yrot = 0;
nextframe.time = 0;
nextframeptr = &nextframe;
}



So, its a bit of minor extra setup work, however with the proper use of structs and pointer flipping it need not at all complex [smile]

Share this post


Link to post
Share on other sites
Quote:
Original post by xor
Not limiting the frame rate, is great for the graphics, animation, and so on, but it will take much more, if not all, CPU power. Now that may be meaningless in many cases, but if someone wanted to process some extra physics, AI, or whatever else, the extra cpu power could come in handy. So instead of processing 100+ frames that the monitor may not even be able to keep up with, why not just use the extra time in other areas? The extra cpu time could even be used by the player himself to run other applications besides the game, like Skype, FRAPS, or his favorite media player without stalls.


The problem is that framerate-limiting in general is a less robust solution. An engine that doesn't restrict framerate might use all of the AVAILABLE cpu time, but your program can decide precisely what that means. If lots of time is allocated to physics (or even to other programs), then the time to render a frame increases and the engine (hopefully) responds appropriately.

Basically, any engine that can run at variable framerate, can run at 60fps. But it can do a lot of other things as well, depending on the situation. Which is why this is clearly a superior solution for most things, and why it is the prevailing solution around here.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this