关于opengl:带有glutPostRedisplay的GLUT动画

GLUT animation with glutPostRedisplay

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


主循环通常如下所示:

  • 处理和处理事件

    调用glutKeyboardFunc / glutMouseFunc之类的东西。

  • 前进/更新3D状态(物理/动画等)

    通常在glutIdleFunc

  • 根据需要重新绘制场景

    使用glutDisplayFunc

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

    如果您有一个游戏,该游戏总是更新每一帧,那么可能就没那么有用了。也许如果您按了Alt键或拖动了窗口,则不需要调用display。或者您可能会因为丢帧而受到帧限制(尽管我建议这样做)。

    1
    2
    3
    4
    5
    6
    void idle()
    {
        ...
        animatedThing.value += deltaTime
        glutPostRedisplay(); //scene is always changing. always call display
    }

    当您不需要连续重新渲染时,具有"脏"标志将变得更加有用。也许是在3D建模程序包之类的程序中,其中没有任何动画,而您只是偶尔移动相机。或者是一个GUI,您只需要在悬停并单击内容时进行更新即可。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    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();
        }
    }

    无论如何,要回答您的问题,不,可能没有太大区别。然而...

  • 我将glutPostRedisplay放在idle中,如上所述。从display内部调用可以工作,但是放弃了以后可能需要的一些控制。本质上是这样的:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    bool shouldDraw = true;
    while (1)
    {
        // check events, input etc

        // idle/update state

        if (shouldDraw)
        {
            shouldDraw = false;
            // draw
            shouldDraw = true;
        }
    }
  • 从设计角度来看,我也不会从idle调用display,因为它消除了过剩的部分控制。例如,如果存在过剩需要覆盖重新显示后(我不知道的情况)的情况,它将无法解决。