I encapsulated the the Windows API's CreateWindow around a class I call GLWindow, to which I render images using OpenGL.
It took me some time, I even encapsulated the message queue, so basically my main function looks like that:
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;
}
The render function obviously takes the most time, and it causes the window procedure function to get flooded with messages, which eventually creates a delay in the WM_KEYDOWN and WM_MOUSEMOVE messages and because of that the camera update is delayed as well. (inside updateCamera())
Any idea what can I do?
The issue is, that your code handles a single message in between rendering frames. Instead, it should drain the entire message queue. This can be as easy as replacing if with while for the message polling expression. It's probably also a good idea to break immediately out of the loop in case you hit the termination condition.
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);
}
Basically your OOP abstraction is rubbish. And, as the comments point out, you havn't included it.
win.pollEvent(ev) strongly implies that you are polling events for a single window only. This is wrong - message loops must pump messages for ALL the windows on a thread.
Its also entirely unclear what handleEvent() does - I hope it calls TranslateMessage / DispatchMessage to ensure the message arrives at your GLWindows window procedure.
So now, we can't see your WindowProc. Does it handle WM_PAINT at all? Does it handle it correctly? The inclusion of updateCamera and render in the message implies you might not be handling your painting requirements properly. While this is a pattern used to achieve high frame rate rendering, writing a game loop that pumps messages correctly is hard, and you would probably be better served (for now) getting the window to update on a timer, and to do painting by triggering WM_PAINT messages by calling InvalidateRect. You have to get this right anyway so you can handle window resizing, minimizing and being covered by other windows elegantly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With