我将Windows API的CreateWindow封装在一个我称之为GLWindow的类中,我使用OpenGL渲染图像。
我花了一些时间,甚至封装了消息队列,所以基本上我的main
函数看起来像这样:
int main()
{
GLWindow win;
win.create("OpenGL Window", false, 1600, 800, -1, -1, true);
win.hideCursor();
win.moveMouseToCenter();
init(); //initialize some opengl stuff
bool quit = false;
WindowEvent ev;
while (!quit) {
if (win.pollEvent(ev))
{
if (ev.type == ev.WindowClosed || (ev.type == ev.KeyboardKeyPressed && ev.keyboardKey.key == Keyboard::Key::Escape))
quit = true;
else
handleEvent(ev);
}
updateCamera(&win);
render(&win);
}
return 0;
}
render
函数显然占用了大部分时间,它会导致窗口过程函数被消息淹没,最终会在WM_KEYDOWN
和WM_MOUSEMOVE
消息中产生延迟,因为其中相机更新也被延迟了。 (在updateCamera()
内)
知道我该怎么办?
答案 0 :(得分:3)
问题是,您的代码处理渲染帧之间的单个消息。相反,它应该耗尽整个消息队列。这可以像使用if
替换消息轮询表达式while
一样简单。如果你遇到终止条件,break
可能会立即退出循环。
while (!quit) {
while (win.pollEvent(ev))
{
if (ev.type == ev.WindowClosed || (ev.type == ev.KeyboardKeyPressed && ev.keyboardKey.key == Keyboard::Key::Escape))
{
quit = true;
break;
}
else
handleEvent(ev);
}
updateCamera(&win);
render(&win);
}
答案 1 :(得分:1)
基本上你的OOP抽象是垃圾。而且,正如评论所指出的那样,你没有把它包括在内。
win.pollEvent(ev)
强烈暗示您仅轮询单个窗口的事件。这是错误的 - 消息循环必须为线程上的所有窗口泵送消息。
它还完全不清楚handleEvent()
的作用 - 我希望它调用TranslateMessage / DispatchMessage
来确保消息到达你的GLWindows窗口过程。
现在,我们看不到您的WindowProc。它完全处理WM_PAINT吗?它能正确处理吗?在邮件中包含updateCamera
和render
意味着您可能无法正确处理您的绘画要求。虽然这是用于实现高帧率渲染的模式,但编写正确抽取消息的游戏循环很难,并且您可能会更好地服务(现在)让窗口更新计时器,并通过触发进行绘制通过调用InvalidateRect来WM_PAINT消息。无论如何你必须正确使用它,这样你就可以处理窗口大小调整,最大限度地减少其他窗口的覆盖范围。