【问题标题】:What is the correct way to update scene in Win32 OpenGL在 Win32 OpenGL 中更新场景的正确方法是什么
【发布时间】:2012-02-14 03:20:42
【问题描述】:

现在我有两个计时器。一种用于物理,一种用于显示。

显示计时器附加到主窗口。它大约每 5 毫秒发布一次消息 WM_PAINT,WM_PAINT 消息处理程序说运行 opengl 显示代码,然后执行 SwapBuffers()。

物理计时器附加到辅助窗口(没有其他原因,我知道如何实现窗口计时器的唯一方法是将其附加到窗口)。处理程序使它更新我的物理代码。

但是,我注意到有时显示“乱七八糟”。它几乎不引人注意,也许每秒只有一个微小的 spaz,但我怀疑有什么事情让物理运动在短时间内变慢或变快。

【问题讨论】:

    标签: winapi opengl


    【解决方案1】:

    交互式模拟(如您的)的正确方法是调用绘图函数作为空闲操作:

    ... idle_action(...)
    {
        redraw();
    }
    
    ... event_loop(...)
    {
        while(!quit) {
           event e = PeekEvent();
           if( e != NO_EVENT ) {
               process_event();
           } else {
               idle_action();
           }
        }
    }
    

    您应该测量绘制框架所需的时间,而不是使用计时器。

    另外,为了物理模拟的精确性,您也不应该为此使用计时器。相反,您应该以恒定长度的较小时间步长推进它,以便单个渲染帧有多个时间步长。因此,例如对于 60Hz 的刷新率,您的帧间隔约为 16ms。 如果您以 1 毫秒的步长执行物理模拟,则您将计算其间的 16 步。 *请注意,大多数(如果不是全部)物理模拟包都在内部执行此操作。 IE。您正在设置步长间隔,然后仅在您希望它进行的所需时间调用物理模拟。

    在实践中,这意味着您将在测量要绘制的帧之前推进物理模拟。

    【讨论】:

    • 但是windows循环是这样的:while(GetMessage(&msg, NULL, 0, 0) > 0) { TranslateMessage(&msg);调度消息(&msg); }
    • nvm,我找到了“PeekMessage”,但我仍然不知道如何对照“空事件”检查它。
    • nvm,我发现使用它的返回值来检查
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多