【问题标题】:What happens if glutPostRedisplay() is called too quickly?如果 glutPostRedisplay() 被调用太快会发生什么?
【发布时间】:2016-02-24 19:18:42
【问题描述】:

我正在用 GLUT 编写一个 OpenGL 程序,它显示场景中的一些移动对象。使用我的函数Render() 完成渲染。但是,我还想在每个循环中移动这些对象的位置,这是在我的函数 Step() 中完成的。

现在,我尝试运行一个循环,在每个循环上调用Render(),然后是Step(),然后是glutPostRedisplay()。但是,这不起作用;显示的窗口没有响应。

我认为这是因为我还需要运行 glutMainLoop() 以便 GLUT 不断使窗口响应。因此,我需要一个在每一帧上调用的计时器函数,并更新对象位置并渲染它们。所以,我现在为此使用glutTimerFunc(...),如下:

glutDisplayFunc(Render);
glutTimerFunc(3, Step, 0);
glutMainLoop();

我对此的理解是每3ms,它就会调用我的Step()函数。如果我现在在Step() 的末尾添加对glutPostRedisplay() 的调用,我的程序运行良好并且对象按预期移动。

但是,我想知道的是,当对我的对象位置进行所有更改所需的时间超过 3 毫秒时会发生什么。在这种情况下,当下次调用Step() 时,我的程序仍将处理对Step() 的最后一次调用。这将导致积压的Step() 呼叫等待处理。

我应该如何处理这个问题?是从 3ms 增加到更大数字的唯一方法吗?还是有其他解决方案?

【问题讨论】:

    标签: opengl graphics glut


    【解决方案1】:

    glutPostRedisplay() 只是设置一个标志。它的工作原理是这样的:

    int do_display = 0;
    
    void glutPostRedisplay(void) {
        do_display = 1;
    }
    
    void glutMainLoop(void) {
        for(;;) {
            event ev = get_OS_event();
            switch(ev.type) {
            case keyboard_event: call_keyboard_function(ev); return;
            case mouse_event:    call_mouse_function(ev); return;
            /* ... */
            }
            if( do_display ) {
                call_display_function();
                do_display = 0;
            } else {
                call_idle_function();
            }
        }
    }
    

    因此,您可以随意调用glutPostRedisplay,只要您不让主循环有机会处理所有未决事件,它实际上不会调用您的显示函数。

    因此,我需要一个在每一帧上调用的计时器函数,并更新对象位置并渲染它们。

    不,你想要的是一个让动画前进并调用glutPostRedisplay的空闲函数。

    但是,我想知道的是,当对我的对象位置进行所有更改所需的时间超过 3 毫秒时会发生什么。在这种情况下,当对 Step() 进行下一次调用时,我的程序仍将处理对 Step() 的最后一次调用。

    不,因为计时器不会引入并发性。发生的事情是,计时器事件正在堆积。然而,使用定时器来控制动画是个坏主意。相反,您应该测量步进函数调用之间的时间,并根据时间差异推进动画。此外,为了最大限度地减少延迟,您不应在显示功能中直接实现动画步骤,以便使用最新的动画步骤进行绘制。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-01-16
      • 1970-01-01
      • 1970-01-01
      • 2014-01-16
      • 2011-04-02
      • 1970-01-01
      • 2022-07-31
      相关资源
      最近更新 更多