Forcing Vsync? Controlling fps.

Blitz3D Forums/Blitz3D Beginners Area/Forcing Vsync? Controlling fps.

Imperium(Posted 2013) [#1]
I have tested my game project on several different machines with varying hardware. (XP and Windows7) My game runs fine on each but on my main development machine I have to force vsync on in the Nvidia control panel. Otherwise my game runs way too fast.

Without resorting to creating a function using tics, or tweening, what is a easy way to force blitz3d to enable Vsync? My game will never need anything over 60fps. I thought by default this is enabled but certain user settings can override it?

Basically I need idea's on how to limit the frame rate.
Thanks in advance!


Yasha(Posted 2013) [#2]
1) Simplest way: on most machines Flip will vsync automatically, and only runs freely with an explicit False argument.

2) There's also a VWait command, which combines well with Flip False for pretty much the same effect. One of these may be more portable than the other. You could have an option to enable and disable each.

3) Do it the hard way: keep track of the number of milliseconds in each frame according to the frame rate, measure the number of milliseconds since the start of the frame, and Delay for the difference. While it will not be as precise (tends to get things between 58 and 63 when aiming for 60) because milliseconds are too granular for this really, it s guaranteed to work absolutely everywhere as a last resort.

You should actually be doing 3 anyway regardless of whether 1 or 2 work, because Delay is also the only way to reduce CPU usage - Flip and VWait seem to busywait. It's kind to the processor and the OS not to hog 100% of every core you're running on (you'll find you actually need very little!). Luckily this method can combine easily with 1 or 2 so you never need to turn it off except to intentionally raise the frame rate.


Midimaster(Posted 2013) [#3]
If you use a Timer and wait for it your code will also be forced to work with a fixed step rate:

FPS=CreateTimer(60)
Repeat
     Cls
     Draw...
     Flip 0
     WaitTimer FPS
Until KeyHit(1)



Imperium(Posted 2013) [#4]
Found some links worth mentioning. I'm going to experiment until I find the best result. Like Yasha said above reducing the cpu usage is the proper way to do it.

Blitz3D: Constant framerate on every system:
http://forums.indiegamer.com/showthread.php?4227-Blitz3D-Constant-framerate-on-every-system

Commented 3D game framework:
http://www.blitzbasic.com/codearcs/codearcs.php?code=9


Midimaster(Posted 2013) [#5]
both samples don't save energy and cpu usage, but "eat" all performance. Using instead a timer and WaitTimer() gives back control to the OS, reduce cpu usage and saves energy.


Imperium(Posted 2013) [#6]
Isn't using CLS in Graphics3d a bad idea? Because FLIP and the renderworld are already taking care of that.

I ended up doing this:

[bbcode]timer = CreateTimer(60)

While Not KeyHit(1)
;PROCESS FPS TIMER
frames = WaitTimer(timer)
For k = 0 To frames
Next

UpdateWorld
RenderWorld
Flip
Wend
End[/bbcode]

Now even if I force Vsync off the game runs fine even at higher and lower resolutions with no affect on speed. I see some slight vertical tearing with vsync off but my game is now performing as expected.


Stevie G(Posted 2013) [#7]
frames = WaitTimer(timer)
For k = 0 To frames
Next


You only need:
WaitTimer ( timer )


A quick test shows that waittimer for a 60 sec timer returns a number ( mainly 1 but sometimes 2 in my test) but it's not clear what this number represents. Regardless, your subsequent loop will run so fast it's pointless.


Midimaster(Posted 2013) [#8]
you need no CLS, it was only a placeholder for "any graphic action"

normaly the 60Hz timer fires every 16msec. but it can happen, that an OS process with higher priority needs more than 32msec, so your app "lost" one event. As I remember a returned value of 2 informs about "2 ticks passed" since last event.