好吧,我正在尝试使用带有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
}
答案 0 :(得分:2)
如果您的DrawGLScene
已使用glutDisplayFunc
注册并因此被调用以绘制每一帧,那么您还将(重新)每隔时间(重新)注册您的计时器功能重新绘制框架,即每次调用glutPostRedisplay()
。
要启动计时器序列,您只需拨打glutTimerFunc
一次,然后再拨打glutMainLoop
,而不是在DrawGLScene
中拨打。
仍然需要在计时器功能中调用glutTimerFunc
来启动下一次翻转。
编辑我发现你甚至没有使用glutMainLoop
。这意味着您对glutTimerFunc
的调用没有做任何事情。基于GLUT的处理程序仅在glutMainLoop
函数调度时工作。
您的代码执行任何操作的唯一原因是因为您在 Windows 事件循环中调用DrawGLScene
,然后在每次通过Windows事件时直接调用您的计时器函数环。这是出乎意料的高频率的来源。
如果您打算坚持使用Windows事件模型,那么您最好只使用标准的Windows计时器事件(即SetTimer
)来处理翻转。
或者重写代码以使用glutMainLoop
并让所有按键和其他事件由GLUT处理。
答案 1 :(得分:0)
这是因为真实的白天/黑夜不是布尔值,它是白天和黑夜之间的逐渐变化。此外,只有10秒是非常短的日/夜循环 - 您通常至少需要几分钟。