Я пытаюсь найти лучший способ работы с пользовательским вводом в играх OpenGL для Windows. У меня на уме четыре варианта:
(1) Просто просмотрите сообщения для игрового окна внутри основного цикла сообщений, который также содержит рендеринг, например:
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
}
Этот метод используется в большинстве учебных пособий по OpenGL. Большая проблема этого метода заключается в зависимости FPS.
(2) использование SetWindowsHookEx в отдельной ветке с 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);
}
Этот метод позволяет мне просматривать любое количество сообщений в секунду, но мне он кажется слишком искусственным + он перехватывает весь пользовательский ввод в систему, что мне тоже не кажется правильным.
(3) То же, что (2), но с использованием WH_KEYBOARD / WH_MOUSE. Требуется отдельный файл .dll, который выглядит накладными.
(4) использование Прямой ввод. Не пробовал, но из того, что я видел в документации и руководствах, может быть лучший способ + мы могли бы легко захватить ввод с геймпада.
Проблема в том, что я пытаюсь построить игру OpenGL, в то время как DirectInput является частью DirectX.
Итак, мой вопрос — как правильно работать с пользовательским вводом? Или, может быть, есть методы, которые я пропустил?
Задача ещё не решена.