opengl c++中的昼夜效果

v440hwme  于 2022-11-04  发布在  其他
关注(0)|答案(2)|浏览(212)

我尝试用C++和opengl在一个场景中实现昼夜循环。我试过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
}
gstyhher

gstyhher1#

如果您的DrawGLScene已经使用glutDisplayFunc注册,并因此被调用来绘制每一帧,那么您也将在 * 每次 * 重绘帧时(即每次调用glutPostRedisplay()时)注册您的定时器函数。
要启动定时器序列,您应该只调用glutTimerFunc一次,* 在 * 调用glutMainLoop之前,而不是在DrawGLScene中调用它。
仍然需要调用glutTimerFunc *within * timer函数来启动下一次翻转。

EDIT我发现你甚至没有使用glutMainLoop。这意味着你对glutTimerFunc的调用没有做任何事情。基于GLUT的处理程序 * 只有 * 在由glutMainLoop函数调度时才能工作。

您的代码执行任何操作的唯一原因是,您在 Windows 事件循环中调用DrawGLScene,然后在每次通过Windows事件循环时直接调用您的计时器函数。这就是意外高频率的来源。
如果您打算坚持使用Windows事件模型,那么最好使用标准的Windows计时器事件(即SetTimer)来处理翻转。
或者,重写代码以使用glutMainLoop,并让GLUT处理所有按键和其他事件。

4zcjmb1e

4zcjmb1e2#

这是因为真实的白天/黑夜不是布尔型的,它是白天和黑夜之间的渐变。此外,只有10秒是一个非常短的白天/黑夜周期-你通常至少想要几分钟。

相关问题