Защо получавам 2 обратни извиквания в GLFW3 - OpenGL

Използвам GLFW3 за обработка на прозорци на OpenGL3.3+. Всичко работи правилно, но не разбирам защо отпечатва "A натиснато" два пъти, когато натисна моя клавиш A. По-специално искам да се отпечата само веднъж за 1 натискане на клавиш A.

static void My_Key_Callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
    if( key == 'A' )
    {
        std::cout<< "A pressed\n";
        return;
    }
}


int main( int argc, char ** argv )
{
    // --1-- Initialise GLFW
    if( glfwInit() == false )
    {
        std::cerr << "Failed to initialize GLFW3\nQuiting....\n";
        exit(1);
    }


    // --2-- Create Window
    glfwWindowHint(GLFW_SAMPLES, 4); // 4x antialiasing
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // We want OpenGL 3.3
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // To make MacOS happy; should not be needed
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //We don't want the old OpenGL

    GLFWwindow * window=NULL;
    window = glfwCreateWindow( 400, 400, "hello", NULL, NULL );
    if( window == NULL )
    {
        std::cerr << "Failed to create glfw window\nQuiting....\n";
        glfwTerminate();
        exit(1);
    }

    // --3-- Make current context
    glfwMakeContextCurrent( window );


// 
// .
// . Normal OpenGL code goes here
// .
//

    // set call back
    glfwSetKeyCallback( window, My_Key_Callback);

    // --5-- Main loop
    glfwSetInputMode( window, GLFW_STICKY_KEYS, GL_TRUE );
    glClearColor(0,0,.4,0);



    do
    {


        ////// Some more OpenGL code here 

        glDrawArrays(GL_TRIANGLES, 0, 36); 


        // swap buffers
        glfwSwapBuffers( window );
        glfwPollEvents();
    }
    while( glfwWindowShouldClose(window)==false );



}

person mkuse    schedule 25.09.2014    source източник


Отговори (2)


Има едно обратно извикване на събитие от клавиатурата в GLFW3, което обработва и GLFW_RELEASE събития:

typedef void(* GLFWkeyfun)(GLFWwindow *, int, int, int, int)

Четвъртият аргумент е action: GLFW_PRESS, GLFW_RELEASE or GLFW_REPEAT. Можете да игнорирате събитието за освобождаване на ключ, напр.

if (action == GLFW_RELEASE)
    return;

// ... handle PRESS, REPEAT of a key...
person Brett Hale    schedule 25.09.2014

Начинът, по който е проектиран GLFW, функцията за обратно извикване се извиква при всяко събитие, като например натиснат или освободен клавиш. За да игнорирате събитието за освобождаване на ключ, кодът ви трябва да бъде заобиколен от условен оператор, като в „ако (действие != GLFW_RELEASE)“:

void keyCallback(GLFWwindow *window, int key, int scancode, int action, int mods) {

    std::cout << "Key pressed, action! " << key << ", " << action << std::endl;

    if (action != GLFW_RELEASE) {       // avoid double updates

    switch (key) {
        case GLFW_KEY_W: camZ -= 0.5f; break;
        case GLFW_KEY_S: camZ += 0.5f; break;

        case GLFW_KEY_A: camX -= 0.5f; break;
        case GLFW_KEY_D: camX += 0.5f; break;

        case GLFW_KEY_Z: camY -= 0.5f; break;
        case GLFW_KEY_X: camY += 0.5f; break;

        case GLFW_KEY_E: yaw -= 0.5f; break;        // around y axis
        case GLFW_KEY_R: yaw += 0.5f; break;

        case GLFW_KEY_UP: pitch -= 0.5f; break;     // around x axis
        case GLFW_KEY_DOWN: pitch += 0.5f; break;

        case GLFW_KEY_LEFT: roll -= 0.5f; break;    // around z axis
        case GLFW_KEY_RIGHT: roll += 0.5f; break;

        case GLFW_KEY_SPACE:
            scaleAmount = 1.0; theta = 0.5;
            yaw = 0.0; pitch = 0.5; roll = 0.0;
            camX = 0.0; camY = 0.0; camZ = 0.0;
            break;
        }

        print(Model);
    }
}
person LastBlow    schedule 09.06.2016