0
$\begingroup$

I am trying to detect when my left mouse button is released to store the result in a boolean variable in OpenGL GLUT. Currently, I am using the motion() function in glutMotionFunc(motion); and setting the boolean variable bool mouseIsHeldDown to true when the left mouse button is held in motion to trigger an if statement in my render function myDisplay(). However, I cannot find an efficient way to find when the left mouse button is released to declare the same variable as false.

Any ideas? Is there a way in Win32?

int main(int argc, char* argv[]) 
{
    ...
    glutMotionFunc(motion);
    ...
}

void motion(int x, int y)
{
    mouseIsHeldDown = true;
}

void myDisplay() 
{
    if (mouseIsHeldDown == true)
    {
        
    }
}
$\endgroup$

1 Answer 1

1
$\begingroup$

One common method is to store the LAST mouse button pressed and then test if the last state was not pressed compared to the current state.

E.g.

bool lastButtonState = false;

void readInput() {
     bool curButtonState = readButton();     

     // Detect "rising" edge of button (AKA, pressed)
     if(curButtonState == true && curButtonState != lastButtonState) {
         doStuff();
     }

     // Update last state for next call..
     lastButtonState = curButtonState;
}

You can also detect if the button was released using this method.

e.g.

if(curButtonState == false && curButtonState != lastButtonState)
    doStuffRelatedToButtonRelease();

Note: readInput() should be called once per frame because it keeps a copy of the current frames input state.

EDIT: The above example is a general solution, below is a solution specific to GLUT as per your update. You need to use the mouse() function to read the button state, motion() doesn't have the needed button state information. GLUT already tells you if that was pressed (transition from false->true) or released (transition from true->false) via the "state" variable.

void mouse(int button, int state, int x, int y)
{
    if (button == GLUT_LEFT_BUTTON) {
        if(state == GLUT_DOWN) 
            onLeftButtonPressed();    // do your thing here..

        // You can also test for (state == GLUT_UP) for mouse button release..
    }
}
$\endgroup$
8
  • $\begingroup$ Hi Paul, I am a little confused with your answer, I updated my question with the relevant code I'm using. Maybe you could show me your solution in my code? $\endgroup$ May 12, 2022 at 8:11
  • 1
    $\begingroup$ Updated with a GLUT specific solution. $\endgroup$
    – PaulHK
    May 12, 2022 at 9:02
  • 1
    $\begingroup$ Are you still updating mouse positions from the motion() function ? $\endgroup$
    – PaulHK
    May 12, 2022 at 9:10
  • 1
    $\begingroup$ You need to use both motion() [to track drags/movement] and mouse() [to detect button pressed] functions. $\endgroup$
    – PaulHK
    May 12, 2022 at 9:11
  • 1
    $\begingroup$ For your Bezier project, it's probably easier for you to track the current mouse state in a global variable. In mouse() inside the if(button == GLUT_LEFT_BUTTON) block you could capture a snapshot of the current left mouse button state e.g.: bIsLeftButtonDown = state == GLUT_DOWN; Then inside your render function you would draw the line for the current editing segment based on this variable. That way you are also controlling the order in which elements are drawn and you don't get out-of-order drawing like you would if that was inside the GLUT input reading functions. $\endgroup$
    – PaulHK
    May 12, 2022 at 9:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.