0

好吧,我正在尝试在使用 opengl 和 c++ 的场景中制作白天/黑夜循环。我试过 glutTimerFunc。虽然我将时间片限制为 10000 ms = 10 s,但它给了我一个非常快速的翻转效果。

这是我所做的。

void turn (int value){
    if(night)
    {
        glDisable(GL_LIGHT0);
        glEnable(GL_LIGHT1);
        night=!night;
    }
    else
    {
        glDisable(GL_LIGHT1);
        glEnable(GL_LIGHT0);
        night=!night;
    }
    //glutPostRedisplay();
    glutTimerFunc(10000,&turn,2);
}

DrawGLScene函数中,我调用了该函数。这是 WinMain 函数:

int WINAPI WinMain( HINSTANCE   hInstance,          // Instance
    HINSTANCE   hPrevInstance,      // Previous Instance
    LPSTR       lpCmdLine,          // Command Line Parameters
    int         nCmdShow)           // Window Show State
{
    MSG     msg;                                    // Windows Message Structure
    BOOL    done=FALSE;                             // Bool Variable To Exit Loop

    // Ask The User Which Screen Mode They Prefer
    //if (MessageBox(NULL,"Would You Like To Run In Fullscreen Mode?", "Start FullScreen?",MB_YESNO|MB_ICONQUESTION)==IDNO)
    //{
    fullscreen=FALSE;                           // Windowed Mode
    //}

    // Create Our OpenGL Window
    if (!CreateGLWindow("day night",700,500,16,fullscreen))
    {
        return 0;                                   // Quit If Window Was Not Created
    }
    glutTimerFunc(10000,&turn,2);
    //turn(1);
    while(!done)                                    // Loop That Runs While done=FALSE
    {

        if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))   // Is There A Message Waiting?
        {
            if (msg.message==WM_QUIT)               // Have We Received A Quit Message?
            {
                done=TRUE;                          // If So done=TRUE
            }
            else                                    // If Not, Deal With Window Messages
            {
                TranslateMessage(&msg);             // Translate The Message
                DispatchMessage(&msg);              // Dispatch The Message
            }
        }
        else                                        // If There Are No Messages
        {
            // Draw The Scene.  Watch For ESC Key And Quit Messages From DrawGLScene()
            if (active)                             // Program Active?
            {
                if (keys[VK_ESCAPE])                // Was ESC Pressed?
                {
                    done=TRUE;                      // ESC Signalled A Quit
                }
                else                                // Not Time To Quit, Update Screen
                {
                    DrawGLScene();                  // Draw The Scene
                    SwapBuffers(hDC);               // Swap Buffers (Double Buffering)
                }
            }
            if (keys[VK_F1])                        // Is F1 Being Pressed?
            {
                keys[VK_F1]=FALSE;                  // If So Make Key FALSE
                KillGLWindow();                     // Kill Our Current Window
                fullscreen=!fullscreen;             // Toggle Fullscreen / Windowed Mode
                // Recreate Our OpenGL Window
                if (!CreateGLWindow("day night",700,500,16,fullscreen))
                {
                    return 0;                       // Quit If Window Was Not Created
                }

            }
        }
    }

    // Shutdown
    KillGLWindow();                                 // Kill The Window
    return (msg.wParam);                            // Exit The Program
}
4

2 回答 2

2

如果您DrawGLScene已使用注册glutDisplayFunc并因此被调用以绘制每一帧,那么您还将在每次重绘帧时(即每次调用glutPostRedisplay().

要启动计时器序列,您应该在调用之前调用glutTimerFunc一次,而不是调用它。glutMainLoopDrawGLScene

仍然需要glutTimerFunc 计时器函数中调用以启动下一次翻转。


编辑 我看到你甚至没有使用glutMainLoop. 这意味着您的呼叫glutTimerFunc没有做任何事情。基于 GLUT 的处理程序在由函数调度时才glutMainLoop起作用。

您的代码做任何事情的唯一原因是因为您在DrawGLSceneWindows事件循环中调用,然后在每次通过 Windows 事件循环时直接调用您的计时器函数。这就是意外高频的来源。

如果您打算坚持使用 Windows 事件模型,那么您最好只使用标准 Windows 计时器事件(即SetTimer)来处理翻转。

或者重写您的代码以使用glutMainLoop并让 GLUT 处理所有按键和其他事件。

于 2012-05-23T14:30:04.547 回答
0

这是因为真正的昼夜不是布尔值,而是昼夜之间的渐变。此外,只有 10 秒是一个非常短的白天/黑夜循环——您通常至少需要几分钟。

于 2012-05-23T14:22:56.570 回答