I am trying to figure out the best way to work with user input in OpenGL games for Windows. I have four options on my mind:
(1) Just peek messages for the game window inside main messages loop, which contains also rendering, like this:
while (running) {
while (PeekMessage(&msg, hWnd, 0, 0, PM_REMOVE)) {
DispatchMessage(&msg);
}
render();
SwapBuffers(hDC);
}
//...
LRESULT CALLBACK windowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
//do something with messages
}
This is the method used in most OpenGL tutorials. The big problem of this method is in FPS dependency.
(2) Use SetWindowsHookEx in a separate thread with WH_KEYBOARD_LL / WH_MOUSE_LL:
HHOOK hhK = SetWindowsHookEx(WH_KEYBOARD_LL,
[](int nCode, WPARAM wParam, LPARAM lParam)->LRESULT {
KBDLLHOOKSTRUCT *pkbhs = (KBDLLHOOKSTRUCT *) lParam;
//handle keyboard
return CallNextHookEx(0, nCode, wParam, lParam);
}
, GetModuleHandle(NULL), NULL);
HHOOK hhM = SetWindowsHookEx(WH_MOUSE_LL,
[](int nCode, WPARAM wParam, LPARAM lParam)->LRESULT {
MSLLHOOKSTRUCT *pkbhs = (MSLLHOOKSTRUCT *) lParam;
//handle mouse
return CallNextHookEx(0, nCode, wParam, lParam);
}
, GetModuleHandle(NULL), NULL);
//We don't event have to create a window
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
This method allows me to peek any number of messages per second, but it seems too artificial to me + it hooks the whole user input in the system, which doesn't seem right to me either.
(3) Same as (2), but using WH_KEYBOARD / WH_MOUSE. Requires a separate .dll, which seems an overhead.
(4) Use DirectInput. Didn't try it, but from what I saw in documentation and tutorials, may be the best way + we could easily capture input also from a gamepad.
The problem is that I'm trying to build OpenGL game, while DirectInput is a part of DirectX.
So, my question is - which way is the correct way to work with user input? Or maybe there are methods I missed?