【问题标题】:GLUT animation with glutPostRedisplay带有 glutPostRedisplay 的 GLUT 动画
【发布时间】:2023-03-22 14:26:01
【问题描述】:

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

【问题讨论】:

    标签: opengl glut


    【解决方案1】:

    主循环通常如下所示:

    1. 处理和处理事件

      调用glutKeyboardFunc/glutMouseFunc之类的东西。

    2. 推进/更新 3D 状态(物理/动画等)

      通常在glutIdleFunc

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

      使用glutDisplayFunc

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

    如果您有一个游戏,它总是更新每一帧,这可能不是那么有用。也许如果您使用 alt 选项卡或拖动窗口,您就不需要调用 display。或者你可能会通过丢帧来限制帧(尽管我建议this)。

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

    当您不需要连续重新渲染时,使用“脏”标志会变得更加有用。也许在没有任何动画的 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,因为它消除了对过剩的一些控制。例如,如果存在 glut 需要覆盖重新显示后的情况(据我所知不是这样),它将无法做到。

    【讨论】:

    • 太棒了,谢谢。实际上,我更多地使用 GLUT 来绘制动画场景,所以我对图形程序的最小形式感兴趣。目前,这只是 displayFunc 和 keyboardFunc。我还使用 CGLSetParameter(kCGLPSwapInterval) 在 vsync 上将渲染锁定为 60Hz。不过,我很欣赏阅读有关 GLUT 的其他更详细的用法!
    猜你喜欢
    • 1970-01-01
    • 2012-08-16
    • 2012-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-08
    相关资源
    最近更新 更多