c++openglglslglfw

How to render at a fixed FPS in a GLFW window?


I am trying to render at 60 FPS but my scene is rendering at a much higher rate than 60 FPS.

This is my code for the Render Loop, is this the correct way to render at a desired FPS or are there better ways?

double lastTime = glfwGetTime(), timer = lastTime;
double deltaTime = 0, nowTime = 0;
int frames = 0, updates = 0;

while (!glfwWindowShouldClose(window))
{
// input
// -----
processInput(window);
// - Measure time
nowTime = glfwGetTime();
deltaTime += (nowTime - lastTime) / limitFPS;  // limitFPS = 1.0 / 60.0
lastTime = nowTime;

// - Only update at 60 frames / s
while (deltaTime >= 1.0) {
    updates++;
    deltaTime--;
    glClearColor(0.0, 0.0, 0.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT |  GL_STENCIL_BUFFER_BIT);
    w.render();  // Render function
    frames++; 
}

glfwPollEvents();

// - Reset after one second
if (glfwGetTime() - timer > 1.0) {
    timer++;

}
glfwSwapBuffers(window);

}

Solution

  • Based on the discussion in comments above, you want to draw a maximum of 60 FPS, but you want the logic to update as often as possible. Correct?

    That can be achieved with just one loop, a timer, and an if statement:

    const double fpsLimit = 1.0 / 60.0;
    double lastUpdateTime = 0;  // number of seconds since the last loop
    double lastFrameTime = 0;   // number of seconds since the last frame
    
    // This while loop repeats as fast as possible
    while (!glfwWindowShouldClose(window))
    {
        double now = glfwGetTime();
        double deltaTime = now - lastUpdateTime;
    
        glfwPollEvents();
    
        // update your application logic here,
        // using deltaTime if necessary (for physics, tweening, etc.)
    
        // This if-statement only executes once every 60th of a second
        if ((now - lastFrameTime) >= fpsLimit)
        {
            // draw your frame here
    
            glfwSwapBuffers(window);
    
            // only set lastFrameTime when you actually draw something
            lastFrameTime = now;
        }
    
        // set lastUpdateTime every iteration
        lastUpdateTime = now;
    }
    

    Everything that you want to execute as often as possible should be in the outer part of that while loop, and everything you want to execute at a maximum of 60 times per second should be inside the if statement.

    If the loop takes longer than 1/60th of a second to execute an iteration then your FPS and update rate will drop to whatever rate is achievable for that workload/system.