LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_ACTIVATE:
if(!HIWORD(wParam))
active = true;
else
active = false;
return 0;
case WM_SYSCOMMAND:
switch(wParam)
{
case SC_SCREENSAVE:
case SC_MONITORPOWER:
return 0;
}
break;
case WM_CLOSE:
PostQuitMessage(0);
return 0;
case WM_KEYDOWN:
if( (wParam >= VK_LEFT && wParam <= VK_DOWN) || wParam == VK_CONTROL)
myCalc.handleInput(wParam, true);
return 0;
case WM_CHAR:
myCalc.handleInput(wParam);
return 0;
case WM_SIZE:
ReSizeGLScene(LOWORD(lParam), HIWORD(lParam)); //LOWORD = Width; HIWORD = Height
return 0;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
MSG msg;
if(!CreateGLWindow(WINDOW_CAPTION, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_BPP))
{
return 0;
}
while(!done) //Main loop
{
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if(msg.message == WM_QUIT)
done = true;
else
{
TranslateMessage(&msg); //Translate the message
DispatchMessage(&msg); //Dispatch the message
}
}
else
{
//Start the time handler
myTimeHandler.Start();
//Draw the GL Scene
if(active)
{
DrawGLScene(); //Draw the scene
SwapBuffers(hDC); //Swap buffer (double buffering)
}
//Regulate the fps
myTimeHandler.RegulateFps();
}
}
//Shutdown
KillGLWindow();
return(msg.wParam);
}
答案 0 :(得分:6)
我的猜测是,如果active
为false,您的主循环会毫无延迟地运行。线程无限地旋转通过该循环并使两个处理器核心中的一个保持忙碌(这就是为什么你看到50%的CPU负载)。
如果active
为真,则交换操作会等待下一个vsync并延迟循环,直到您的下一次屏幕刷新发生,从而导致CPU负载降低。 (线程在等待事件发生的Windows函数内等待的时间不计入其CPU负载。)
要解决该问题,您可以切换到基于GetMessage的消息循环,直到您不想呈现任何内容。
答案 1 :(得分:3)
OpenGL窗口覆盖的区域越小,绘制的场景越快(关键术语是 fillrate ),因此事件循环以更高的频率迭代。我看到你有一些函数RegulateFps
- 对我而言,这听起来就像繁忙的循环,直到渲染器中消耗了一定的时间。即你真的在浪费CPU时间来获取......呃,你为什么要先保持帧率低?摆脱它。
当然,如果你最小化它,你设置active = false
所以根本不做GL的东西,但仍然在繁忙的循环中浪费时间。
尝试在驱动程序选项中启用V同步,并使用双重缓冲,然后wglSwapBuffers
将阻止,直到垂直空白。如果active==false
不PeekMessage
而GetMessage
答案 2 :(得分:0)
确定。我看到了你的一个逻辑流程。
while(!done) //Main loop
{
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
......
}
else
{
.... rendering.
}
}
当你最小化时,peekMessage将总是失败,所以你将来渲染部分。
导致你使用100%单核cpu,因为它在while循环中而且从不睡觉,等待,只是一次又一次地进行绘制。
您可能希望将最小时间用于渲染帧。
我的建议是:
// set a timer for wakeup ur process.
while (::GetMessage(&msg, NULL, 0, 0))
{
// handle the messages
// do check the rendering to see if you need to render.
if (currentTime - lastDrawTime > MINIMIUM_RENDER_INTERVAL)
// rendering.
}