Solved

animation with opengl

Posted on 2003-10-27
5
1,715 Views
Last Modified: 2008-03-17
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!
0
Comment
Question by:joannak
  • 4
5 Comments
 
LVL 4

Expert Comment

by:n_fortynine
ID: 9631144
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.
0
 
LVL 4

Expert Comment

by:n_fortynine
ID: 9631161
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.
0
 

Author Comment

by:joannak
ID: 9631267
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.
0
 
LVL 4

Accepted Solution

by:
n_fortynine earned 125 total points
ID: 9634518
>> Is there a way for both of them to keep executing
You can map all events to one single idle function and distinguish the individual events in there. for example:

int leftClk, rightClk, kbHit;

void mouse(int button, int state, int x, int y)
{
     switch(button)
     {

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

void keyboard(unsigned char key, int x, int y)
{
    kbHit = key == 's' || key == 'S' ? 1 : 0;
}
void myIdle( ) {
    if(kbHit) {
       //change ball param
    }
    if(leftClk) {
       //change param to move up
    }
    if(rightClk) {
      //change param to move down.
    }
}

void myDisplay( ) {
  //Draw your things in here together accordingly to the params
}

You can tweak these around so that they'll fit in your program.
0
 
LVL 4

Expert Comment

by:n_fortynine
ID: 9634528
One thing I forgot to call glutPostRedisplay() in myIdle( )
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
How do I open an Access Data base with a password set using C++ 2 109
Problem with SqlConnection 4 156
gdb doesn't stop on breakpoint 2 45
Issues with C++ Class 19 77
IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

947 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now