使用 glutPostRedisplay 的 GLUT 动画

GLUT animation with glutPostRedisplay

在我的显示函数末尾调用 glutPostRedisplay() 和使用除了调用我的显示函数什么都不做的空闲函数回调之间有什么区别吗?我已经看到示例中使用的两种方式,但无法通过观察来区分。

一个主循环通常是这样的:

  1. 处理和处理事件

    调用 glutKeyboardFunc/glutMouseFunc.

  2. Advance/update 3D 状态(physics/animation 等)

    通常在 glutIdleFunc

  3. 如果需要重新绘制场景

    使用glutDisplayFunc

glutPostRedisplay 只是设置一个标志,告诉 glut 在下一次循环迭代时调用显示回调。它实际上并没有调用 display [1] [2].

如果您有一款总是更新每一帧的游戏,这可能就没那么有用了。也许如果你是 alt-tabbed 或拖动 window 你不需要调用显示。或者您可能会通过丢帧来限制帧数(尽管我建议 this)。

void idle()
{
    ...
    animatedThing.value += deltaTime
    glutPostRedisplay(); //scene is always changing. always call display
}

当您不需要连续重新渲染时,拥有一个 "dirty" 标志会变得更有用。也许在像 3D 建模包这样的东西中,没有任何动画,你只是偶尔移动相机。或者只需要在悬停并单击内容时更新的 GUI。

void mousedown(int button, int state, int x, int y)
{
    if (clickedGUI(x, y))
        glutPostRedisplay();
}

void idle()
{
    ...
    if (myKeys[MOVE_VIEW_FORWARD])
    {
        view.z -= deltaTime;
        glutPostRedisplay();
    }
}

无论如何,回答你的问题,不,可能差别不大。然而...

  1. 我会像上面那样把 glutPostRedisplay 放在 idle 中。从 display 中调用可以,但会放弃您稍后可能需要的一些控制权。本质上是这样的:

    bool shouldDraw = true;
    while (1)
    {
        // check events, input etc
    
        // idle/update state
    
        if (shouldDraw)
        {
            shouldDraw = false;
            // draw
            shouldDraw = true;
        }
    }
    
  2. 我也不会从设计角度从 idle 调用 display,因为它从过剩中移除了一些控制。例如,如果存在过剩需要重写 post-重新显示(据我所知没有)的情况,它将无法做到。