我试图找出在 Windows 的 OpenGL 游戏中使用用户输入的最佳方法。我有四个选择:
(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)在带有 WH_KEYBOARD_LL / WH_MOUSE_LL 的单独线程中使用SetWindowsHookEx :
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)使用DirectInput。没有尝试过,但从我在文档和教程中看到的内容来看,这可能是最好的方法 + 我们也可以轻松地从游戏手柄捕获输入。
问题是我正在尝试构建 OpenGL 游戏,而 DirectInput 是 DirectX 的一部分。
所以,我的问题是——哪种方式是处理用户输入的正确方式?或者也许我错过了一些方法?