opengl c ++中的日夜效果

时间:2012-05-23 14:21:50

标签: visual-c++ opengl graphics

好吧,我正在尝试使用带有c ++的opengl在场景中进行日/夜循环。我试过glutTimerFunc。虽然我将时间片限制在10000毫秒= 10秒,但它给我一个非常快速的翻转效果。

这就是我所做的。

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
}

2 个答案:

答案 0 :(得分:2)

如果您的DrawGLScene已使用glutDisplayFunc注册并因此被调用以绘制每一帧,那么您还将(重新)每隔时间(重新)注册您的计时器功能重新绘制框架,即每次调用glutPostRedisplay()

要启动计时器序列,您只需拨打glutTimerFunc一次,然后再拨打glutMainLoop,而不是在DrawGLScene中拨打。

仍然需要在计时器功能中调用glutTimerFunc 来启动下一次翻转。


编辑我发现你甚至没有使用glutMainLoop。这意味着您对glutTimerFunc的调用没有做任何事情。基于GLUT的处理程序glutMainLoop函数调度时工作。

您的代码执行任何操作的唯一原因是因为您在 Windows 事件循环中调用DrawGLScene,然后在每次通过Windows事件时直接调用您的计时器函数环。这是出乎意料的高频率的来源。

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

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

答案 1 :(得分:0)

这是因为真实的白天/黑夜不是布尔值,它是白天和黑夜之间的逐渐变化。此外,只有10秒是非常短的日/夜循环 - 您通常至少需要几分钟。