如何在GLFW窗口中以固定FPS进行渲染?

问题描述 投票:0回答:2

我尝试以 60 FPS 渲染,但我的场景渲染速度比 60 FPS 高得多。

这是我的渲染循环代码,这是以所需 FPS 渲染的正确方法还是有更好的方法?

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);

}
c++ opengl glsl glfw
2个回答
4
投票

根据上面评论中的讨论,您希望绘制最大 60 FPS,但您希望逻辑尽可能频繁地更新。正确吗?

只需一个循环、一个计时器和一个 if 语句即可实现这一点:

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;
}

您想要尽可能频繁执行的所有内容都应该位于该

while
循环的外部,并且您想要以每秒最多 60 次执行的所有内容都应该位于
if
语句内。

如果循环执行迭代所需的时间超过 1/60 秒,那么您的 FPS 和更新速率将下降到该工作负载/系统可实现的速率。


0
投票

以下游戏循环可确保更新和渲染的速率限制为 MAX_FPS(在您的情况下为 60)。

constexpr float MAX_FPS = 60.f;
constexpr float FRAME_TIME = 1.f / MAX_FPS;

float last_time = glfwGetTime();
float last_update_time = glfwGetTime();
float accumulated_time = 0.f;

while (!glfwWindowShouldClose(window))
{
    float current_time = glfwGetTime();
    float dt = current_time - last_time;
    last_time = current_time;
    accumulated_time += dt;

    glfwPollEvents();

    if (accumulated_time >= FRAME_TIME)
    {
        float update_dt = current_time - last_update_time;
        last_update_time = current_time;
        accumulated_time = 0.f;

        update(update_dt);
        render();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.