Question

I never got the concept down on how to get an animation working in OpenGL. I was working on his project trying to get it to work but never got the skier to move. Trying to figure out how to get this fixed.

 #include "../shared/gltools.h" // OpenGL toolkit
 #define PI 3.14159265
  float a = -5;//maybe
    float b = 29;
    float c = 27;
    float d = 28.25;
    float e = 28.5;
  bool lookUp;
  bool setback;
  bool lookDown;
  bool lookLeft;
  bool lookRight;
  bool walkForward;
  bool walkBackward;
  bool strafeLeft;
  bool strafeRight;
  float xTranslation;
  float yTranslation;
  float zTranslation;
  float yRotationAngle;
  float zRotationAngle;
  float xRotationAngle;
  int mouseLastx; 
  int mouseLasty; 
  float sunRotationAngle=0;
  float sunRadius = 150.0;
  float day=0;
  float dusk=1;
  // Light values and coordinates
  GLfloat    lightPos[] = { 0.0f, 30.0f, 0.0f, 1.0f };
  GLfloat    lightPos2[] = { 0.0f, 0.0f, 40.0f, 1.0f };
  GLfloat  specular[] = { 1.0f, 1.0f, 1.0f, 1.0f};
  GLfloat  specular2[] = { 0.0f, 1.0f, 0.0f, 1.0f};
  GLfloat  diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f};
  GLfloat  diffuse2[] = { 0.0f, 0.3f, 0.0f, 1.0f};
  GLloat  specref[] =  { 1.0f, 1.0f, 1.0f, 1.0f };
  GLfloat  ambientLight[] = { 0.5f, 0.5f, 0.5f, 1.0f};
  GLfloat  spotDir[] = { 0.0f, 0.0f, -1.0f };

  void mouseMovement(int x, int y) 
  {
    int mouseDiffx=x-mouseLastx; 
    int mouseDiffy=y-mouseLasty; 
    mouseLastx=x; 
    mouseLasty=y; //set lasty to the current y position
    xRotationAngle += (GLfloat) mouseDiffy; 
    yRotationAngle += (GLfloat) mouseDiffx;
    if (xRotationAngle>=90)
            xRotationAngle=90;
    if (xRotationAngle<=-90)
            xRotationAngle=-90;
    //cout << "x:" << x << "y:" << y << endl;
  } 


  void drawcabin()
  {
    glColor3ub(0, 0, 0);
    glBegin(GL_TRIANGLES);
        //glTranslatef(0,-5,0); // move view left
        //glNormal3f(-3,0.7,-1.7);
        //glutSolidCube(5.0f);

        glNormal3d(0,0.7,0.7);
        glVertex3d(0,6,0);
        glVertex3d(-3,3.5,-2);
        glVertex3d(2,3.5,-2);


        glNormal3d(2,-1,1);
        glVertex3d(0,6,0);
        glVertex3d(-3,3.5,-2);
        glVertex3d(2,3.5,-2);
        glTranslatef(0,-5,0); // move view left
        glNormal3d(-3,0.7,-1.7);

    glEnd();
    glColor3ub(185, 0, 0);
    glutSolidCube(5.0f);

  }
  void drawskislope()
  {
    glColor3ub(0, 0, 0);
    glBegin(GL_QUADS);
    glTranslatef(0,-5,90); // move view left
    glColor3ub(185, 122, 87);
        glNormal3d(0,5,1);
        glVertex3d(10,0,5);
        glVertex3d(10,.5,5);
        glVertex3d(15,.5,5);
        glVertex3d(15,0,5);//small square

    glColor3ub(201, 192, 187);  
        glVertex3d(11.5,.5,5);
        glVertex3d(13.5,.5,5);
        glVertex3d(13.5,-10,5);
        glVertex3d(11.5,-10,5);
        //slope start


        glTranslatef(0,-5,0); // move view left
    //  glNormal3d(-3,0.7,-1.7);

    glEnd();
  }


  void drawskier()
  {
    float a = -5;//maybe
    float b = 29;
    float c = 27;
    float d = 28.25;
    float e = 28.5;

    glBegin(GL_QUADS);
    glTranslatef(0,-5,0); // move view 
    glColor3ub(185, 122, 87);
        glNormal3d(0,5,1);
        //Do While loop
    //  do
    //  {


        // to move skier do a loop and update a in the translate
        glTranslatef(0,a,0); // move view 
        glVertex3d(c,0,5);//10
        glVertex3d(c,.1,5);//10
        glVertex3d(b,.1,5);//15
        glVertex3d(b,0,5);//skis on skier

        glNormal3d(0,5,1);
        glVertex3d(d,0,5);
        glVertex3d(d,1.35,5);
        glVertex3d(e,1.35,5);
        glVertex3d(e,0,5);//body on skier
        glutSwapBuffers;

  //    }while(b>15); //try to animate
    glEnd();
    glFlush();
    b=b-1;
            c=c-1;
            d=d-1;
            e=e-1;
            glutPostRedisplay();
        glTranslatef(30,3,0); // move view left
        glColor3ub(168, 220, 109);
        glutSolidSphere(.5,7,8);                //sphere-head


     glPushMatrix();
        glTranslatef(3.5,-100,2);
        glutSolidSphere(25,15,15);                //sphere
    glPopMatrix();


  }
  void updatescene()
  {




  }

  ///////////////////////////////////////////////////////////
  // Called to draw scene
  void RenderScene(void)
  {
    GLUquadricObj *pObj;    // Quadric Object
    pObj = gluNewQuadric(); 
    gluQuadricNormals(pObj, GLU_SMOOTH);
    GLfloat horizontalMovement=1;
    GLfloat verticalMovement=0;
    horizontalMovement=cos(xRotationAngle*PI/180);
    verticalMovement=-sin(xRotationAngle*PI/180);

        // Reset Model view matrix stack
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    horizontalMovement=cos(xRotationAngle*PI/180);
    verticalMovement=-sin(xRotationAngle*PI/180);

    if (lookDown)
    {
        xRotationAngle+=1;
        if (xRotationAngle>=90)
            xRotationAngle=90;
    }
    if (lookUp)
    {
        xRotationAngle-=1;
     if (xRotationAngle<=-90)
            xRotationAngle=-90;
    }
    if (lookRight)
    {
        yRotationAngle+=1;
        if (yRotationAngle>=360)
            yRotationAngle=0;
    }
    if (lookLeft)
    {
        yRotationAngle-=1;
        if (yRotationAngle<=-360)
            yRotationAngle=0;
    }
    if (walkForward)
    {
        zTranslation+=cos(yRotationAngle*PI/180)*horizontalMovement;
        xTranslation-=sin(yRotationAngle*PI/180)*horizontalMovement;
        yTranslation-=verticalMovement;
    }
    if (walkBackward)
    {
        zTranslation-=cos(yRotationAngle*PI/180)*horizontalMovement;
        xTranslation+=sin(yRotationAngle*PI/180)*horizontalMovement;
        yTranslation+=verticalMovement;
    }
    if (strafeRight)
    {
        zTranslation+=cos((yRotationAngle+90)*PI/180);
        xTranslation-=sin((yRotationAngle+90)*PI/180);
    }
    if (strafeLeft)
    {
        zTranslation-=cos((yRotationAngle+90)*PI/180);
        xTranslation+=sin((yRotationAngle+90)*PI/180);
    }

    if (setback)
    {
        zTranslation=0;
        xTranslation=0;
        yTranslation=0;
    }


        // Reset Model view matrix stack
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glRotatef(xRotationAngle,1,0,0);
    glRotatef(zRotationAngle,0,0,1);
    glRotatef(yRotationAngle,0,1,0);
    glTranslatef(xTranslation,yTranslation,zTranslation);




    //glRotatef(-15,1,0,0);
    //glRotatef(90,0,1,0);
    glTranslatef(0,-0.50,-10);




        glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
        sunRotationAngle++;


    // Clear the window with current clearing color
    glClear(GL_COLOR_BUFFER_BIT |  GL_DEPTH_BUFFER_BIT);


    glColor3d(0,0,0);
    glLineWidth(2);


    //snow
    glColor3ub(255, 255, 255);
    glBegin(GL_QUADS);
        glNormal3f(0,1,0);
        for (int i=-100;i<=200;i+=10) //x
            for (int j=-100;j<=200;j+=10)//z
            {

                float y1=(-j)*.25;
                float y2=(-j+10)*.25;
                glVertex3d(i+10,y2,-100);
                glVertex3d(i,y2,-100);
                glVertex3d(i,y1,-100);
                glVertex3d(i+10,y1,-100);
            }
    glEnd();





    glPushMatrix();
        glTranslatef(-10,14,-50);
        drawcabin();
        drawskislope();
        drawskier();
    glPopMatrix();




    // Flush drawing commands

    glutSwapBuffers();
    glutPostRedisplay();
    //GLfloat horizontalMovement=1;
  //    GLfloat verticalMovement=0;


  }

  void TimerFunction(int value)
    {
         // Redraw the scene with new coordinates
        glutPostRedisplay();
        updatescene();
        glutTimerFunc(16,TimerFunction, 1);
    }

  ///////////////////////////////////////////////////////////
  // Setup the rendering context
  void SetupRC(void)
  {
    lookUp=false;
    lookDown=false;
    lookLeft=false;
    lookRight=false;
    walkForward=false;
    walkBackward=false;
    strafeLeft=false;
    strafeRight=false;
    yRotationAngle=0;
    xRotationAngle=0;
    zRotationAngle=0;
    xTranslation=0;
    yTranslation=0;
    zTranslation=0;
    // White background
    glClearColor(0.5f,0.95f, 1.0f, 1.0f );

    // Set drawing color to green
    glColor3f(0.0f, 1.0f, 0.0f);

    // Set color shading model to flat
    glShadeModel(GL_SMOOTH);

    // Clock wise wound polygons are front facing, this is reversed
    // because we are using triangle fans
    glFrontFace(GL_CCW);

     glEnable (GL_DEPTH_TEST);










  }

  void ChangeSize(int w, int h)
    {
    //GLfloat nRange = 100.0f;

    // Prevent a divide by zero
    if(h == 0)
        h = 1;

    // Set Viewport to window dimensions
    glViewport(0, 0, w, h);

    // Reset projection matrix stack
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    // Establish clipping volume (left, right, bottom, top, near, far)
    GLfloat fAspect;
     fAspect = (GLfloat)w / (GLfloat)h;
    //glOrtho(-10,10,-10,10,0,1000);
    gluPerspective(45,fAspect,0.1,1000);

    // Reset Model view matrix stack
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();


    }
  // Respond to arrow keys by moving the camera frame of reference
  void SpecialKeys(int key, int x, int y)
    {
    if(key == GLUT_KEY_UP)
        lookUp=true;

    if(key == GLUT_KEY_DOWN)
        lookDown=true;

    if(key == GLUT_KEY_LEFT)
        lookLeft=true;

    if(key == GLUT_KEY_RIGHT)
        lookRight=true;

    // Refresh the Window
    glutPostRedisplay();
    }
  void SpecialKeysUp(int key, int x, int y)
    {
    if(key == GLUT_KEY_UP)
        lookUp=false;

    if(key == GLUT_KEY_DOWN)
        lookDown=false;

    if(key == GLUT_KEY_LEFT)
        lookLeft=false;

    if(key == GLUT_KEY_RIGHT)
        lookRight=false;

    // Refresh the Window
    glutPostRedisplay();
    }

  void keyboardFunc(unsigned char key, int x, int y)
  {

    switch(key)
    {
    case 'w':
        walkForward=true;
            break;
    case 's':
        walkBackward=true;
            break;
    case 'a':
        strafeLeft=true;
            break;
    case 'd':
        strafeRight=true;
            break;
    case 'r':
        setback=true;
            break;
    default:
            break;
    }

  }

  void keyboardUpFunc(unsigned char key, int x, int y)
  {
    switch(key)
    {
    case 'w':
        walkForward=false;
            break;
    case 's':
        walkBackward=false;
            break;
    case 'a':
        strafeLeft=false;
            break;
    case 'd':
        strafeRight=false;
            break;
    default:
            break;
    }


  }
  ///////////////////////////////////////////////////////////
  // Main program entry point
  int main(int argc, char* argv[])
  {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(500,500); 
    glutCreateWindow("Assignment 2");
    glutReshapeFunc(ChangeSize);
    glutDisplayFunc(RenderScene);
    glutSpecialFunc(SpecialKeys);
    glutSpecialUpFunc(SpecialKeysUp);
    glutKeyboardUpFunc(keyboardUpFunc);
    glutKeyboardFunc(keyboardFunc);
    glutPassiveMotionFunc(mouseMovement);
    SetupRC();

    glutMainLoop();

    return 0;
  }
Was it helpful?

Solution

My general approach is to use a glutTimerFunc() callback to post a redisplay event every 16 milliseconds or so (~60 FPS).

Then in the glutDisplayFunc() callback you can grab the new GLUT_ELAPSED_TIME to calculate a delta-time (dt) from the last frame.

With dt in hand you can update any number of variables such as angles or translation offsets. You'll want to use dt instead of fixed increment values to decouple your animation speed from your framerate.

Then back in the glutDisplayFunc() callback you draw a new frame using the updated state variables.

This is an example that uses the method above to rotate a square at about 30 degrees per second:

#include <GL/glut.h>

float angle = 0;
void update( const double dt )
{
    // in degrees per second
    const float SPEED = 30.0f;

    // update angle
    angle += ( SPEED * dt );
}

void display()
{
    // GLUT_ELAPSED_TIME is in milliseconds
    static int prvMs = glutGet( GLUT_ELAPSED_TIME );
    const int curMs = glutGet( GLUT_ELAPSED_TIME );

    // dt is in seconds
    const double dt = ( curMs - prvMs ) / 1000.0;
    prvMs = curMs;

    // update world state
    update( dt );

    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    // reset projection/modelview matrices each frame;
    // this makes sure we have a known-good matrix 
    // stack each time through display()
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    glOrtho( -2, 2, -2, 2, -1, 1 );

    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();

    // draw rotated square
    glRotatef( angle, 0, 0, 1 );
    glBegin( GL_QUADS );
    glColor3ub( 255, 0, 0 );
    glVertex2i( -1, -1 );
    glVertex2i(  1, -1 );
    glVertex2i(  1,  1 );
    glVertex2i( -1,  1 );
    glEnd();

    glutSwapBuffers();
}

void timer( int value )
{
    glutPostRedisplay();
    glutTimerFunc( 16, timer, 0 );
}

int main( int argc, char **argv )
{
    glutInit( &argc, argv );
    glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
    glutInitWindowSize( 600, 600 );
    glutCreateWindow( "GLUT" );
    glutDisplayFunc( display );
    glutTimerFunc( 0, timer, 0 );
    glutMainLoop();
    return 0;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top