Visual c++ opengl c+中的日夜效果+; P>我试图用C++的OpenGL来实现场景中的昼夜循环。我试过glutTimerFunc。虽然我已经将时间片限制为10000毫秒=10秒,但它给了我一个非常快速的翻转效果
这就是我所做的Visual c++ opengl c+中的日夜效果+; P>我试图用C++的OpenGL来实现场景中的昼夜循环。我试过glutTimerFunc。虽然我已经将时间片限制为10000毫秒=10秒,但它给了我一个非常快速的翻转效果,visual-c++,opengl,graphics,Visual C++,Opengl,Graphics,这就是我所做的 void turn (int value){ if(night) { glDisable(GL_LIGHT0); glEnable(GL_LIGHT1); night=!night; } else { glDisable(GL_LIGHT1); glEnable(GL_LIGHT0); night=!night; } //glut
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
}
这是因为真实的昼夜不是布尔值,而是昼夜之间的渐变。此外,只有10秒是一个非常短的昼夜循环-您通常至少需要几分钟。如果您的
DrawGLScene
已使用glutDisplayFunc
注册,因此被调用来绘制每个帧,那么每次重新绘制帧时,您也将(重新)注册计时器函数,即每次调用glutPostRedisplay()
要启动计时器序列,只需在调用glutMainLoop
之前调用glutTimerFunc
一次,而不要在DrawGLScene
中调用它
仍然需要在计时器函数中调用glutTimerFunc
,以启动下一次翻转
编辑我发现您甚至没有使用
glutMainLoop
。这意味着您对glutTimerFunc
的调用没有任何作用。基于GLUT的处理程序只有在由glutMainLoop
函数调度时才能工作
代码执行任何操作的唯一原因是,在Windows事件循环中调用DrawGLScene
,然后在每次通过Windows事件循环时直接调用计时器函数。这是出人意料的高频率的来源
如果您打算坚持使用Windows事件模型,那么最好只使用标准Windows计时器事件(即SetTimer
)来处理翻转
或者重写代码以使用
glutMainLoop
,并由GLUT处理所有按键和其他事件。我使用10秒仅用于测试目的。结果是在不到一秒钟的时间内实现了昼夜循环。GLUTIMERFUNC
只有100作为参数。我尝试过,但得到了恒定的光。我的意思是根本没有变化。@user1412823您看到更新了吗,关于在计时器函数中仍然需要调用glutTimerFunc
?是的,我看到了。注意:我有WinMain函数和while循环,我想它和mainloop是一样的,不是吗?@user1412823我不这么认为,但我从来没有在Windows上使用过GLUT。向我们展示while
循环中的内容。GLUT和Win32的超现实组合是什么?选择一个事件循环。一个事件循环。@genpfault是的,我的回答差不多就是这么说的,只要OP澄清他没有使用glutMainLoop
。