Posts
Search
Contact
Cookies
About
RSS

Why you shouldn't use SetTargetFPS with Raylib

Added 10 Mar 2021, 8:52 p.m. edited 18 Jun 2023, 1:12 a.m.

Raylib uses, in part a library called GLFW, its a great way to help isolate your application from the vagaries of cross platform development, and adds a nice suite of functions to do tiresome things like creating a GL context (and much more besides).

One nice feature is you can sync screen swaps to the GPU/monitors frame rate, because this this also nicely side steps the issue of tearing where the frame is flipped mid way through the monitor drawing an image.

When you do use SetTargetFPS there are various strategies that you can set in Raylibs config.h, but beside the lack of frame synchronisation (If you ask for sync you may well not get your required FPS depending on a number of issues) there is also an issue with high resolution timers. The reasons are quite technical and lots has been said on the subject already. Under some circumstances you could be seeing higher than expected CPU usage too.

For a nice smooth moving picture the most reliable timing source is your GPU/monitor.

So job done then, set FLAG_VSYNC_HINT during initialisation and don't use SetTargetFPS ?

Alas not! there is a slight snag (isn't there always) as you can't tell ahead of time what frequency the GPU/monitor will be working at (it could even change when full screen resolution changes) then you are in a position where your code will be running at different speeds depending on what system its running on - far from ideal.

However the solution is really quite simple, first stash the result of GetFrameTime in a variable (It'll be used a lot so why have the overhead of repeatedly calling GetFrameTime)

Frame time is (hopefully!) a fraction lower than one, a value of one would mean your code took 1 second to update and render !

Any time you need to move something, multiply the movement value by the frame time.

    If (IsKeyDown(KEY_LEFT) {
        player.x -= SPEED * delta;
    }

Where SPEED is a define of a decent sized value for your players movement increment, and delta is the value from GetFrameTime.

It is possible that when GLFW requests to synchronise with the frame rate, it will fail, this is much less likely to happen these days and often on installing an OS, it will just work out of the box.

In the event that GLFW can't sync to the frame, at least your player will be moving at a consistent rate, the price the end user pays for not knowing how to configure a system, excessive CPU load and frame tearing !