user1031204
user1031204

Reputation: 701

GLFW switching boolean toggle

I am using GLFW for keyboard input but the processing happens too quick thus my boolean switch on a single press gets changed like 10 times, as input is processed every frame. All I need that for a single press of space bar it would switch the state. My current code is below:

if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS)
{
    show = !show;
}

Is there a better way of doing this?

Upvotes: 2

Views: 3125

Answers (3)

Whizbuzzer
Whizbuzzer

Reputation: 81

I am kinda late to this question, but I too had trouble implementing a key toggle like you. Here is how I fixed it without using key_callback (writing w.r.t your code in mind):

In yourClass.h file:

class yourClass {
    ...
    bool spacePressed = false;
    ...
}

In yourClass.cpp file:

void yourClass::yourFunction(...) {
    ...
    if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS)    
    {
        if (!spacePressed) {
            show = !show;
            spacePressed = true;
        }
    } else if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_RELEASE) {
        spacePressed = false;
    }
    ...
}

Upvotes: 0

perivesta
perivesta

Reputation: 4021

I reccommend using GLFWs key callbacks instead of getting the key state yourself every frame. This way you will only receive one keypress and one keyrelease event per key.

void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
    if(action == GLFW_RELEASE) return; //only handle press events
    if(key == GLFW_KEY_SPACE) show = !show;
}

//in main or init
glfwSetKeyCallback(window, key_callback);

Upvotes: 1

Bartek Banachewicz
Bartek Banachewicz

Reputation: 39370

Yes. glfwGetKey is meant to be used for continuous key input. GLFW manual lists glfwSetKeyCallback as a better alternative if you want one-time notification about key press.

Thus, for your case it'd be something like this:

void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
    if (key == GLFW_KEY_SPACE && action == GLFW_PRESS)
        show = !show;
}

If you don't want to use this method for whatever reason, you can always implement a similar thing yourself. You'll need a boolean value (or array of values) representing the key state. Then, in your input handling, you must only react on the change of the button state, like so:

bool spacePressed;

// in handling
bool spaceCurrentlyPressed = glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS;

if (!spacePressed && spaceCurrentlyPressed) { // wasn't before, is now
    show = !show;
}
spacePressed = spaceCurrentlyPressed;

Upvotes: 3

Related Questions