Link to home
Start Free TrialLog in
Avatar of joannak
joannak

asked on

animation with opengl

I'm trying to do two simultaneous animations.

One is a rectangle that moves back and forth by control of the mouse. Ie. when the left mouse button is held down the rectangle moves up, when it is released it stops; when the right mouse button is held down it moves down, when released it stops moving.
At the same time when I press 's' on the keyboard a ball starts moving. It should move continously regardless of what happens with the rectangle or the mouse.

The only way I know to do animation is by using glutIdleFunc(). I have a method for moving the rectangle and one for moving the ball. I pass one of these to glutIdleFunc(), however I need glutIdleFunc to handle both of them. Is there any way to do this???

Please, please help!
Avatar of n_fortynine
n_fortynine

you should use glutMouseFunc( ) to handle mouse events, and glutKeyboardFunc( ) for keyboard events. Use double buffer (and swap them) if you need to. Using glutIdleFunc( ) to handle drawing is a very bad idea, because you would slow down the response time for other events. glutIdleFunc() should contain the less code the better. What you can do is to do the computational stuff when you handle the mouse/keyboard events. To be able to draw more efficiently (faster - less flickering) you can use display lists and double buffer (and the depth buffer if need be).

To use a mouse function:

void OnMouseClick(int btn, int state, int x, int y) {
   if(btn == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
   {
   }
   if(btn == GLUT_LEFT_BUTTON && state == GLUT_UP)
   {
   }
   if(btn == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
   {
   }
   if(btn == GLUT_RIGHT_BUTTON && state == GLUT_UP)
   {
   }
  //or middle button etc.
}

and in main

glutMouseFunc(OnMouseClick);
glutKeyboardFunc( ) is very similar.

You can keep track of the mouse motion while the mouse is being dragged by glutMotionFunc( ).
Quite fundamental stuff! There are many OpenGL tutorials/examples out there you can learn a lot from.
For your idle function, the best way is to have something like:

int ypos, isMouseClicked;

void myIdle() {
   if(isMouseClicked) { //you can modify this to distinguish between left and right.
      ypos += 2; //going up
      glutPostRedisplay(); //request your redraw.
   }
}

something like that. If you don't know how to create a display list just ask.
Avatar of joannak

ASKER

hmm.... I guess I wasn't very clear with my question:

here's my basic code structure:

int main(int argc, char **argv)
{
// basic initialization stuff
      GLint windowW=DEFAULT_WINDOW_WIDTH, windowH=DEFAULT_WINDOW_HEIGHT;
      glutInit(&argc,argv);
      glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
      glutInitWindowSize(windowW, windowH);
      glutCreateWindow("my window");

      init();
      createMenus();

      glutDisplayFunc(display);
      glutReshapeFunc(reshape);
  // here are my keyboard and mouse event handlers
      glutKeyboardFunc(keyboard);
      glutMouseFunc(mouse);
      glutMainLoop();

      return 0;
}


// callbacks.c (pseudocode)
void keyboard(unsigned char key, int x, int y)
{
      switch(key)
      {
      case 's':
      case 'S':
            glutIdleFunc(ball);
                }
}
void mouse(int button, int state, int x, int y)
{
      switch(button)
      {

      case GLUT_LEFT_BUTTON:  // move paddle up
            if (state == GLUT_DOWN)
                glutIdleFunc(moveUp);
            else if (state == GLUT_UP)
               glutIdleFunc(NULL);
            break;
      case GLUT_RIGHT_BUTTON: // move paddle down
            if (state == GLUT_DOWN)
                glutIdleFunc(moveDown);
            else if (state == GLUT_UP)
               glutIdleFunc(NULL);
            break;
      default:
            break;
      }
}

ball()
{
    change translation parameters;
    glutPostRedisplay();
}

moveUP()
{
    change translation parameters;
    glutPostRedisplay();
}

moveDown()
{
    change translation parameters;
    glutPostRedisplay();
}


So when I press "s" the ball gets going. Now I need to move my rectangle up or down with the mouse. When I press and hold the left button it should move up, when I release it should stop. (similarly with right button).  BUT, when the mouse button is pressed the ball() function stops executing and moveUp() starts instead. Is there a way for both of them to keep executing or do I have to do my animation some other way. If so, then how do I get my rectangle to move without using glutIdleFunc(). The way you described it above it only moves by one translation parameter at each click. I need it to keep moving when the button is held down.
ASKER CERTIFIED SOLUTION
Avatar of n_fortynine
n_fortynine

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
One thing I forgot to call glutPostRedisplay() in myIdle( )