Solved

animation with opengl

Posted on 2003-10-27
5
1,711 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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
>> 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
Comment Utility
One thing I forgot to call glutPostRedisplay() in myIdle( )
0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

762 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

12 Experts available now in Live!

Get 1:1 Help Now