C++ 如何正确设置 FPS 上限(使用 GLFW)

C++ How to correctly cap FPS (Using GLFW)

所以我一直在尝试将我的 fps 限制在 60:


//Those are members inside the Display class
double tracker = glfwGetTime();
const float frameCap = 1 / 60.0f;

void Display::present() {
    glfwSwapBuffers( _window );

    //Getting the time between each call
    double now = glfwGetTime( );
    double frameTime=now - tracker;
    tracker=now;
    
    //delaying if required
    if ( frameTime < frameCap )
        delay( frameCap - frameTime );
}

void game() {
//Creating window and opengl context
.....

//Disabling "vsync" so i can cap fps by my own
glfwSwapInterval(0);

 while(running) {
   //Rendering and updating
   .........   

   //Swap buffers and delay if required
   display.present();
 }
}

我的delay/sleep函数

#ifdef _WIN32
#include <Windows.h>
#else
#include <unistd.h>
#endif

void delay( uint32_t ms )
{
#ifdef _WIN32
    Sleep( ms );
#else
    usleep( ms * 1000 );
#endif
}

基本上是在每个 Display::present() 调用中限制帧速率的想法。

看起来没有任何上限,实际上 fps 是 4000+

对于 present 的第一次调用,您的 double frameTime=glfwGetTime( ) - tracker;,将 frameTime 设置为当前时间(glfwGetTime() 与 [=14= 的初始值之间的差值] 你用 glfwGetTime().

设置

在下一行中,您设置tracker=frameTime;frameTime不是时间,而是这里的差异。)

对于 present 的下一次调用,值 tracker 非常小(因为它是差异而不是时间),从那以后你的 double frameTime=glfwGetTime( ) - tracker; 变得非常大(大于 frameCap),所以睡眠不会发生。

对于 present 的下一次调用,( frameTime < frameCap ) 的条件可能再次为真,但对于向上的流程,它肯定不会再为真。

因此至少每第二次调用 present 时,delay 将不会被调用。

除了glfwGetTime returns秒之外,frameCap还表示一帧应该持续多少秒,但是你的void delay( uint32_t ms )需要毫秒。