Solved

animation with opengl

Posted on 2003-10-27
5
1,732 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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

On Demand Webinar - Networking for the Cloud Era

This webinar discusses:
-Common barriers companies experience when moving to the cloud
-How SD-WAN changes the way we look at networks
-Best practices customers should employ moving forward with cloud migration
-What happens behind the scenes of SteelConnect’s one-click button

Question has a verified solution.

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

What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
C++ Properties One feature missing from standard C++ that you will find in many other Object Oriented Programming languages is something called a Property (http://www.experts-exchange.com/Programming/Languages/CPP/A_3912-Object-Properties-in-C.ht…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

735 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