Лучший способ получить пользовательский ввод в игру

Я пытаюсь найти лучший способ работы с пользовательским вводом в играх 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) Используйте DirectInput. Не пробовал, но из того, что я видел в документации и руководствах, может быть лучший способ + мы могли бы легко захватить ввод с геймпада.

Проблема в том, что я пытаюсь построить игру OpenGL, в то время как DirectInput является частью DirectX.


Итак, мой вопрос - как правильно работать с пользовательским вводом? Или, может быть, есть методы, которые я пропустил?

0 ответов

Другие вопросы по тегам