Locking FPS- Part II

Started by
11 comments, last by Xtreme 23 years, 9 months ago
ok, I have a question similar to that topic called Locking FPS posted a couple of days ago. I am using OpenGL as my api and I want to rotate a line at constant speed. Now, the difficulty I am having with this is if I don''t "lock" the FPS , then I don''t get a constant rotation! The way I lock the FPS is like this: .... QueryPerformanceCounter((LARGE_INTEGER *) &time); while ( (double)(time - timer.performance_timer_start)*milli < double(DELAY)) QueryPerformanceCounter((LARGE_INTEGER *) &time); TimerInit(); //reset timer .....//draw the line here ...//loop back now if you have noticed, there is a variable called DELAY. This is my set delay variable in ms. If I set that to 1ms, then the line draws sooo fast that I can''t even see! timer.performance_timer_start holds the time since the program started. So how do I make my line rotate at a CONSTANT rate if I want to achieve as much as FPS as possible? P.S: I tried using Sleep() instead of the tight while loop and the program does not respond in Windows 98, but does in Windows NT. That''s another problem I cannot solve!
Yes! There are kangaroos in Australia but I haven't seen them...yet
Advertisement
sleep() is the worst timing device you can use. incacurate and can''t be set.

JoeMont001@aol.com www.polarisoft.n3.net
My HomepageSome shoot to kill, others shoot to mame. I say clear the chamber and let the lord decide. - Reno 911
the sole reason why I tried using Sleep() is that it releases the CPU usage. In the while loop I need to waste cycles so I thought sleep() should be ok, but it wasn''t!
Yes! There are kangaroos in Australia but I haven't seen them...yet
It''s my firm belief that locking the frame-rate down is a bad idea. There are too many different computer configurations out there for that to work well in practice.

Anyway, a good way to handle this situation is to decide how quickly you want that line to rotate. Maybe one complete rotation every two seconds? Figure out what speed you want, and then you implement it something like this:

First, when you''re setting up your quick timers in the first place, you want to call QueryPerformanceFrequency(). (I think that''s what its called) You save this value, and calculate it''s reciprocal. Now, every frame you''re finding out how much time has past since the last frame, right? Take that variable, and multiply it by that reciprocal you found, and you''ll have a fraction of a second to work with. (Calculate the reciprocal of that and I think you get the frame rate.

Now, I''m not sure how you''re representing that rotation, in radians or degrees. But, if you wanted say, a full rotation every two seconds, you''d define a rotation speed of 180 degrees/sec or 1 pi/sec for the line. Then, each frame, you multiply that value by the fraction of a second you calculated. That tells you how far to rotate your line. Update your rotation variable, move on to the next frame, find the time that''s elapsed, and do it all over again. There ya go, smooth rotation, and it will run as fast as is can.

Jonathan
hmmmm, this is getting way too complicated.
any examples? and yes I am using degrees not radians to rotate the line.

sig u say?
Yes! There are kangaroos in Australia but I haven't seen them...yet
What he''s trying to say is not as hard as it sounds, and it is -THE- correct way to do what you''re trying to do. See if you can understand this pseudocode:

Const RotationRate = 360 //rotate 360 degrees in one second
myAngle = 0

StartLoop

BeginTimer = currentTick
DrawLine
EndTimer = currentTick

elapsedTime = (endTimer - BeginTimer) //calculate elasped time
myAngle = myAngle + RotationRate * elapsedTime

EndLoop

This is the fundamental algorithm you should use. It''s very easy to understand and is completely independent of the framerate, since the more FPS you get, the lower the elapsedTime will be (and so the movement per frame is less).

If you want to actually have your units in seconds, as the previous poster said, just be sure to divide your ElapsedTime by (1/QueryPerformanceFrequency()).

G''luck


I just realized I had a question along the same lines as this. Obviously, I understand how to write framerate independent code, multiplying by DeltaTime or whatever. I have particles like this:

x = x + velocityX * ElapsedTime
y = y + velocityY * ElapsedTime

Which works wonderfully. -BUT-

The particles are subject to gravity, so I have to do a little

velocityY = velocityY + gravity * ElapsedTime

Which sort of makes "y" doubly dependant on the ElapsedTime, or something strange like that -- or is it my imagination? Is this code valid, or do I need to figure out some sort of integration or something? I can convince myself that it''s right but I''m not 100% sure, it seems to stutter a little when the game runs.

Thanks!
Compare your implementation with the formulae from physics and judge for yourself

Pos = Pos + Vel*dt
Vel = Vel + Acc*dt

In this case Acc is your gravity, and dt is an infinitely small timedifference. To get the pos after say 1 sec you would have to integrate the formulae over 1 sec. But with numerical representations it is difficult to use infinitely small numbers so just use the time since last frame instead. Oh, and you are already integrating your formulae in your implementation, the difference is that you are doing it iteratively.

- WitchLord

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

I think it''s better to have just one "timer" that updates the elapsed time when a frame is shown to the user (with a flip or a blit or whatever) and then uses that as a base in all calculations. If you have one timer for each object things drawn just before the frame is updated will appear to move much faster than things that are drawn shortly after the frame was updated.

Or something like that...

/CMN
Thanks Witchlord, and I know the formulas are correct, but are you 100% sure that your logic holds?

Let''s say the initial Y velocity was ZERO pixels/sec and gravity was 10 pixels/sec^2.

Now let''s say we''ve got one computer that can manage this simulation at 1 FPS, and another that can manage 2FPS.

On the computer with 1FPS, after one second, we increase the velocity to 10 p/s and then update the position, so y = 10.

On the computer with 2FPS, after .5 seconds, we increase velocity to 5 p/s and the position also, so y = 2.5. (Because deltaTime = .5 and velocity is 5). Then, after another .5 seconds, we increase velocity to 10 p/s (which is EQUAL!) and the position to y = 7.5, because deltaTime = .5 and velocity is 10.

So despite having an equal amount of time elapsed, the final POSITIONS are different, because they are intuitively "second-degree" (wrong mathematical term I''m sure) deltaTime functions. Note that the velocities are equal, however.

Please help, or point out a flaw in my logic!

This topic is closed to new replies.

Advertisement