2017-10-08 1 views
2

glfwSetKeyCallback 함수를 사용하여 기본 카메라 동작을 만들려고합니다. 문제는 W와 A가 한 번에 여러 개의 키를 입력하는 것을 처리하지 않기 때문에 A가 대각선으로 왼쪽 상단 방향으로 이동해야한다는 것입니다. 대신 마지막 입력 키에 대해서만 알고있는 것처럼 작동합니다. 그래서 A를 눌러 왼쪽으로 움직이고, 왼쪽으로 가다가 W를 눌러 왼쪽 위의 대각선으로 가려면 A가 눌려지고 위로가는 것을 잊어 버리는 것입니다.GLFW로 한 번에 여러 개의 키 입력 처리

float cameraSpeed = 0.02f; 
    if (key == GLFW_KEY_ESCAPE && (action == GLFW_PRESS || action == GLFW_REPEAT)) 
     glfwSetWindowShouldClose(window, GLFW_TRUE); 
    if (key == GLFW_KEY_W && (action == GLFW_PRESS || action == GLFW_REPEAT)) 
     Game::GetInstance()->cameraY += cameraSpeed; 
    if (key == GLFW_KEY_A && (action == GLFW_PRESS || action == GLFW_REPEAT)) 
     Game::GetInstance()->cameraX -= cameraSpeed; 
    if (key == GLFW_KEY_S && (action == GLFW_PRESS || action == GLFW_REPEAT)) 
     Game::GetInstance()->cameraY -= cameraSpeed; 
    if (key == GLFW_KEY_D && (action == GLFW_PRESS || action == GLFW_REPEAT)) 
     Game::GetInstance()->cameraX += cameraSpeed; 

키보드 입력 내 자신의 부울 탭을 만들고처럼 그들을 설정 만 GLFW 기능을 사용처럼 내 마음에 합격 한 솔루션 :

if (key == GLFW_KEY_A && action == GLFW_PRESS) 
     // set 'A' to true; 
if (key == GLFW_KEY_A && action == GLFW_RELEASE) 
     // set 'A' to false; 

그리고 내가 함께하고 싶은 일을 그것은 완전히 분리 된 함수/클래스/무엇이든간에. 그것은 나에게 깨끗하게 보이지 않는다. 문제의 좋은 해결책은 무엇입니까?

+0

'GLFW_PRESS'와'GLFW_RELEASE'를 다루는데 특별한 어려움이 있습니까? – VTT

+0

아니요, 둘 이상의 키를 누를 때까지 제대로 작동합니다. 두 개의 키가 눌려진 경우 (다시 W와 A라고합시다) 맨 왼쪽으로 이동해야합니다 (키는 항상 눌려져 GLFW_REPEAT가됩니다). 대신 마지막으로 누른 키만 기억됩니다. – Dnoren

+0

첫 번째 키에 대해'GLFW_RELEASE'를받지 못한다는 것을 말하고 있습니까? – VTT

답변

1

같은 문제가 생겨 콜백을 사용하여 키 상태의 배열을 설정하기로 결정했습니다. GLFW_REPEAT은 마지막으로 누른 키만 전송됩니다. 내 콜백은 Input 클래스에 직접 위임되지만 관련이 없습니다. 모든 매개 변수를 전달합니다.

void key_callback(GLFWwindow *win, int key, int scancode, int action, int mods){ 
    Input *input = (Input*)glfwGetWindowUserPointer(win); 
    input->keys(win, key, scancode, action, mods); 
} 

입력 내에서 정의 된 키를 눌러 배열 : 나는 또한 윈도우 포인터가 필요 특수 키 처리하는

bool pressed[KEYS]; // KEYS = 349 (last GLFW macro, GLFW_KEY_MENU = 348) 

을 그리고 실제 처리 방법에있어서, 다음

Input::keys(GLFWwindow *win, int key, int scancode, int action, int mods){ 
    if(key == GLFW_UNKNOWN) return; // Don't accept unknown keys 
    if(action == GLFW_PRESS) 
     pressed[key] = true; 
    else if(action == GLFW_RELEASE) 
     pressed[key] = false; 

    switch(key){ 
    case GLFW_KEY_EXCAPE: 
     if(action == GLFW_PRESS) 
      glfwSetWindowShouldClose(win, true); 
    } 
} 

를 I 모든 렌더링 작업 후에 메인 루프 내부의 모든 키를 Input in(); in.handle() :

와 같이 사용하면 Input::handle(void)으로 처리하십시오.
void Input::handle(void){  // Things to do every frame 
    for(int i = 0; i < KEYS; i++){ 
     if(!pressed[i]) continue; // Skip if not pressed 
     switch(i){ 
     case GLFW_KEY_SPACE: 
      cam->ascend(1.0); // Ascend with camera 
     } 
    } 
} 

다양한 프레임 속도 문제를 해결하기 위해 시간 상수를 포함 할 계획이지만, 이것이 그 요지입니다.

결과 : 여러 키를 눌러도 카메라가 모든 방향으로 부드럽게 움직입니다.

관련 문제