Frame Rate limit problem.

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
SirSami
Posts: 20
Joined: Mon Mar 24, 2008 2:18 pm
Location: Finland

Frame Rate limit problem.

Post by SirSami »

I made a system to limit fps rate. But it's not working well. There is problem, it decrase fps too much.

Here is the code:

Code: Select all

#define FRAMELIMIT 60

    u32 beginTime;
    u32 endTime;
    u32 loopTime;
    u32 frameLimit = FRAMELIMIT;

while(device->run())
{
    
    beginTime = timer->getRealTime();

//here is other loop things

    endTime = timer->getRealTime();
    loopTime = endTime - beginTime;
    device->sleep(1000/frameLimit - loopTime);
}
This code makes FPS to 32. And when I try to calculate it, it should be 60... Because 1000/60 = 16.6666... and 1000 ms / 16 = 62.5. so FPS should be 62 but it is 32 ?
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Why don't you use vsync, which does exactly this limitation, but in a place where exact timing is possible. Moreover, you won't ever get it as exact as you'd need to rely on your frame rate. Better make your functions check how much time has passed and act upon that value.
SirSami
Posts: 20
Joined: Mon Mar 24, 2008 2:18 pm
Location: Finland

Post by SirSami »

If i use that method, does make a lot of extra work? Like moving objects etc.
And I cant use vsync cause this program is server and it is in windowed mode. Client side uses vsync.
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

I'm not sure what you're realy doing there... :lol:
but this line is wrong:

Code: Select all

device->sleep(1000/frameLimit - loopTime); 
it must be:

Code: Select all

device->sleep(1000 / (frameLimit - loopTime)); 
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
SirSami
Posts: 20
Joined: Mon Mar 24, 2008 2:18 pm
Location: Finland

Post by SirSami »

Acki wrote:I'm not sure what you're realy doing there... :lol:
but this line is wrong:

Code: Select all

device->sleep(1000/frameLimit - loopTime); 
it must be:

Code: Select all

device->sleep(1000 / (frameLimit - loopTime)); 
hmmm. Why should that work? Acki: It's working like this way in current system:

1000 ms = 1 sec and FPS = 1/s so if limit is 60 then it is 60 1/s.
1s / 60 1/s = time to wait. 1000 ms / 60 1/s = 16.666 ms

So if program waits 16 ms, the fps should be 60 1/s

1 s / 16 ms is about 60. So it should be take 60 loop rounds in a second.

And the loopTime is there only for smoothing FPS because if there is slow computer running program the loop compliting time is bigger and then there is no need to wait too much time.

Or what did you mean with that your fix?
rogerborg
Admin
Posts: 3590
Joined: Mon Oct 09, 2006 9:36 am
Location: Scotland - gonnae no slag aff mah Engleesh
Contact:

Post by rogerborg »

The code looks right, but:

1) There's no guarantee that sleep() will have a 1ms granularity. On Windows, for example, the default granularity is (or at least it used to be) 10ms. Call timeBeginPeriod(1) to lower it to 1ms. I'm not sure of the position on various Unices, but you should see what OS call is actually being made and check the documentation for it.

2) Sleep() (again, on Windows, possibly on Unices) idles the thread for at least the specified time. After that, it just makes it ready to run again, but there's no guarantee that it will run straight away if another thread of equal priority is busy.

3) You're ignoring the possibility of exceeding your allowed frame time, and also there's no real need to sleep (or catch up) if you've only drifted a few milliseconds either way.

I'd recommend that you keep a running total of how far the frame time has drifted from the required time, and adjust either way as necessary. So when you get too far ahead (e.g. only adjust when you've drifted >10ms or so ahead) do a sleep(), or if you drift too far behind, try to catch up e.g. by skipping any non-vital processing next time round your main loop.

If you're on Windows, you could also consider entering a busy sleep(0) loop until an appropriate amount of time has expired. This may (but you'd have to test it) give you a better chance of resuming closer to the desired time, while still being more friendly than stalling in a busy active loop.
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
floppyfreak
Posts: 117
Joined: Sat Apr 19, 2008 10:14 am

Post by floppyfreak »

I have a problem close to this.

I want to make my prog vsync independend, because the famerate may sometimes go under 60 and that causes the cam's movements slow down (because lesser frames).
When I now try to fix this with getting the frametimes (while vsync is switches off) and computing the correct movements frametime dependend, the movements become jerky. The general timing is correct, but in some frames the movements seem ways too fast. I can't figure out the reason for this. I tried average frametimes, but it only fixes it a little. How are such timer problems handled in video games? Any howtos, manuals, tutorials?
rogerborg
Admin
Posts: 3590
Joined: Mon Oct 09, 2006 9:36 am
Location: Scotland - gonnae no slag aff mah Engleesh
Contact:

Post by rogerborg »

It shouldn't be more complicated than calculating a delta time and multiplying all of your movements by that.

Either you have some genuinely bad outlying delta times, or your implementation is screwy. You could clamp your delta times to sensible limits, or debug the problem and try and find out where your implementation is going wrong. We could help with that, if you post code.
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
SirSami
Posts: 20
Joined: Mon Mar 24, 2008 2:18 pm
Location: Finland

Post by SirSami »

Do you mean the change of time with delta time? Like endTime - beginTime.
I am not sure about that term cause I am not native english speaker. But that should work. There is only one problem with distances then. Distances will come more uncontrolable.

EDIT:
By the way, what is the best way to do main menu? I have tried 2 ways now and there is a problem in a both one. First I tried to make menu by irrlicht gui system. But the problem is that it's not scaling with resolution. Then I tried to do it with billboards. It's scaling with resolution but it is heavy weight and textures don't fit perfectly. Is there any possible ways to do non-resolution depending menu by gui enviroment?
Last edited by SirSami on Fri May 30, 2008 7:31 am, edited 1 time in total.
floppyfreak
Posts: 117
Joined: Sat Apr 19, 2008 10:14 am

Post by floppyfreak »

SirSami wrote:Do you mean the change of time with delta time? Like endTime - beginTime.
I am not sure about that term cause I am not native english speaker. But that should work. There is only one problem with distances then. Distances will come more uncontrolable.
Delta generally means difference.
http://de.wikipedia.org/wiki/Subtraktion
rogerborg means the difference time between two frames. If you have a continuous movement you must multyply it by this deltatime in each frame, so the movement becomes smooth.
For me the problem is solved. When I had jerks in some frames, it was a complicated output of some influence (using of burp manager, yield() etc). Result is stil better with vsynch switched on.
SirSami
Posts: 20
Joined: Mon Mar 24, 2008 2:18 pm
Location: Finland

Post by SirSami »

Should it work like this?

Code: Select all


u32 frameBeginTime;
u32 frameEndTime;
u32 frameTime;
u32 lastFrameTime = 0;
u32 deltaTime;

while(device->run())
{

frameBeginTime=timer->getRealTime();

//Loop things

frameEndTime=timer->getRealTime();
frameTime = frameEndTime - frameBeginTime;

deltaTime = frameTime - lastFrameTime;
lastFrameTime = frameTime;

}
Is that what you meant?
JP
Posts: 4526
Joined: Tue Sep 13, 2005 2:56 pm
Location: UK
Contact:

Post by JP »

your frameTime is the real deltaTime there, you don't need the extra stuff after you calculate frameTime.
Image Image Image
SirSami
Posts: 20
Joined: Mon Mar 24, 2008 2:18 pm
Location: Finland

Post by SirSami »

Ahh. Now I understood the point : ) But isn't it possible to do it like that:
If velocities are m/s and one coordinate unit is 1 m. Velocity / FPS

Example: Some object is moving 6 m/s and FPS = 142

x = movement in one frame.
x = 6 / FPS
x = 6/142
x= 0,04225 m/frame
JP
Posts: 4526
Joined: Tue Sep 13, 2005 2:56 pm
Location: UK
Contact:

Post by JP »

The FPS is only updated once a second so you wouldn't get enough accuracy from it as the framerate will actually vary much more often than once a second and could vary a lot!
Image Image Image
floppyfreak
Posts: 117
Joined: Sat Apr 19, 2008 10:14 am

Post by floppyfreak »

JP wrote:your frameTime is the real deltaTime there, you don't need the extra stuff after you calculate frameTime.
really? I read, that "frametime" here gives the time the loop needs to take, this can be any time lower than deltatime. It's not clear to me why this time is needed. Deltatime is the time you take from one frame to the next. in 60 fps it will be 16.666 milliseconds. I understand it like this. :?:
to make the confusion complete i want to interject, that generally as I have understood frametime is another term for what we have called deltatime here. the codelines compute this correctly imho.
Post Reply