Search code examples
c++openglglutopengl-compat

Animate cube inside an animation


Here i display a cube in different places each period, but i wanted it to be spawned with a transition and animation, for example i want it be translated from -1 to +1 as a loop (animation the cube)

    #include <windows.h>
    #include <GL/glut.h>
    #include <math.h>

    #ifdef __APPLE__
    #include <GLUT/glut.h>
    #else
    #include <GL/glut.h>
    #endif
    #include <stdio.h>
    #include <stdlib.h>

    float angle_Rotation = 0;
    float angle_Rotation2 = 0;

    float xx=0.5;
    float yy=0.5;
    float zz=0.5;

    int dx=0;
    int dy=1;
    int dz=0;

    float tabPos[3] = {-4.0,0.0,4.0};

    int cpt=0;

    GLint rings = 50;
    GLint side =50;
    GLdouble inner = 0.5;
    GLdouble outter = 1;

    void init(){
        /* choisir la couleur d'effacement */
        glClearColor(0.0,0.0,0.0,0.0);
        /* Projection et positionement de la camera*/
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluPerspective(90,1,0.1,100);
        gluLookAt(0,10,8,0,0,0,0,1,0);
    }

    static void Reshape(int width, int height){
        glViewport(0,0,width,height);
    }

    void whatINeed(){
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);


        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        //glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
        glRotatef(angle_Rotation, 0.0, 1.0, 0);
        glRotatef(angle_Rotation2, 1.0, 0.0, 0);
    }

    static void cercle(float r){
        float i;
        float PI=3.14;
        glBegin(GL_POLYGON);
        for(i=0;i<2*PI;i+=PI/48){
            glVertex3f(cos(i)*r,sin(i)*r,0.0);
            glVertex3f(cos(i)*r,sin(i)*r,6.0);
        }
        glEnd();
        //glFlush();
    }



    static void KeyPressed(unsigned char touche, int x, int y){

        switch (touche)
        {

          case 'q': ///rotaion � gauche
                angle_Rotation = angle_Rotation + 2;
                break;

          case 'd': ///rotaion � droite
                angle_Rotation = angle_Rotation - 2;
                break;

          case 'z': ///rotaion � gauche
                angle_Rotation2 = angle_Rotation2 + 2;
                break;

          case 's': ///rotaion � droite
                angle_Rotation2 = angle_Rotation2 - 2;
                break;
        }

        glutPostRedisplay();
    }


    void light(void){
        glEnable(GL_LIGHTING);
        //glEnable(GL_COLOR_MATERIAL);
        GLfloat light_couleur1[] = {0.7,0.5,0.6,0.7};
        GLfloat light_couleur2[] = {0.7,0.7,0.5,0.7};
        //GLfloat light_couleur3[] = {0.7,0.3,1.0,1.0};
        //GLfloat light_position[] = {0.0,1.0,0.5,0.5};
        GLfloat light_position2[] = {0.0,1.0,0.5,0.0};
        GLfloat obj_shine[] = {50.0};

        glLightfv(GL_LIGHT1,GL_POSITION,light_position2);
        glLightfv(GL_LIGHT1,GL_AMBIENT,light_couleur1);
        glLightfv(GL_LIGHT1,GL_DIFFUSE,light_couleur2);
        //glLightfv(GL_LIGHT4,GL_SPECULAR,light_couleur2);
        //glMaterialfv(GL_FRONT,GL_DIFFUSE,light_couleur2);
        glMaterialfv(GL_FRONT,GL_SPECULAR,light_couleur2);
        //glMaterialfv(GL_FRONT,GL_SHININESS,obj_shine);
        glEnable(GL_LIGHT1);
    }



    void table(void){

        glColor3f(0.6,0.0,0.6);
        glPushMatrix(); // Cube
        glTranslatef(0,0,0.0);
        glScalef(4,1,4);    // Scale Sur X et Z (Réctangle)
        glutSolidCube(3);
        glPopMatrix();

        glColor3f(0.3,0.0,0.8);
        glPushMatrix(); // Sphere
        glTranslatef(-4,1.2,-4);  // Ligne Haut Gauche
        glRotatef(90,1,0,0);
        glutSolidTorus(inner,outter,side,rings);
        glPopMatrix();

        glPushMatrix();
        glTranslatef(0,1.2,-4);   // Ligne haut Milieu
        glRotatef(90,1,0,0);
        glutSolidTorus(inner,outter,side,rings);
        glPopMatrix();

        glPushMatrix();
        glTranslatef(4,1.2,-4);   // Ligne haut droite
        glRotatef(90,1,0,0);
        glutSolidTorus(inner,outter,side,rings);
        glPopMatrix();


        glPushMatrix();
        glTranslatef(-4,1.2,0);   // Ligne Milieu droite
        glRotatef(90,1,0,0);
        glutSolidTorus(inner,outter,side,rings);
        glPopMatrix();

        glPushMatrix();
        glTranslatef(0,1.2,0);    // Ligne Milieu Milieu
        glRotatef(90,1,0,0);
        glutSolidTorus(inner,outter,side,rings);
        glPopMatrix();

        glPushMatrix();
        glTranslatef(4,1.2,0);    // Ligne Milieu Gauche
        glRotatef(90,1,0,0);
        glutSolidTorus(inner,outter,side,rings);
        glPopMatrix();

        glPushMatrix();
        glTranslatef(-4,1.2,4);   // Ligne Bas droite
        glRotatef(90,1,0,0);
        glutSolidTorus(inner,outter,side,rings);
        glPopMatrix();

        glPushMatrix();
        glTranslatef(0,1.2,4);    // Ligne Bas milieu
        glRotatef(90,1,0,0);
        glutSolidTorus(inner,outter,side,rings);
        glPopMatrix();

        glPushMatrix();
        glTranslatef(4,1.2,4);    // Ligne Bas gauche
        glRotatef(90,1,0,0);
        glutSolidTorus(inner,outter,side,rings);
        glPopMatrix();

    }


    void taupe(void){

        glPushMatrix();
        glTranslatef(tabPos[dx],dy,tabPos[dz]);   // Ligne Milieu droite
        glColor3f(0.8,0.3,0.5);
        glutSolidCube(2);
        glPopMatrix();

    }

in this function spawn, i have to update dy i've to make it from -1 to 1 with 0.05 as a step the problem is when i add the code i lose my primary animation

 void spawn(void){
        if(cpt%500000==0){
            if(cpt>500000){
                cpt=0;
            }
            dx = rand() % 3; //generates a ra

ndom number between 0 and 2 dz = rand() % 3; //generates a random number between 0 and 3

        glutPostRedisplay();
    }
    cpt++;

}

void display(){

    whatINeed();

    table();
    taupe();
    glutSwapBuffers();

    }

    int main(){

        // Considérer la profondeur
        glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA);
        /* Initialisationd e glut et création  de la fenetre */
        glutInitWindowSize(720,720);
        glutInitWindowPosition(100,100);
        glutCreateWindow("OpenGL TP");
        /*Autre Initialisation */
        init();
        /*enregistrement des fonction rappel*/
        glutDisplayFunc(display);
        glutReshapeFunc(Reshape);
        glutKeyboardFunc(KeyPressed);

here i spawn the cube as animation

    glutIdleFunc(spawn);
    glEnable(GL_DEPTH_TEST);
    //light();
    /* entré dans mla boucle principal de glut*/
    glutMainLoop();

return 0;
}

Solution

  • To make an animation, you have to continuously update the display. Remove all calls to glutPostRedisplay and do a single call in display. e.g.:

    void display(){
    
        whatINeed();
    
        table();
        taupe();
        glutSwapBuffers();
    
        glutPostRedisplay(); // <---
    }
    

    To animate between 2 positions, you have to know the previous (pdx) and new position (dx):

    int pdx=0;
    int dx=0;
    

    Define a time interval for the animation. Use a timer (glutTimerFunc) instead of glutIdleFunc to start a new animation:

    int interval = 1000; // 1 second
    void spawntimer(int value);
    
    int main()
    {
      // [...]
    
      // glutIdleFunc(spawn); <--- DELETE
    
      glutTimerFunc(interval, spawntimer, 0); // <--- ADD
    
    
      // [...]
    

    In spawntimer store the current position to dx and get ane random position. Store the current elapsed time to start_time. This states the start time of the animation and can be get by glutGet(GLUT_ELAPSED_TIME). Restart the timer:

    int start_time = 0;
    void spawntimer( int value )
    {
        pdx = dx;
        dx = rand() % 3;
        start_time = glutGet(GLUT_ELAPSED_TIME);
    
        glutTimerFunc(interval, spawntimer, 0);
    }
    

    In taupe Calculate the relative position of the object dependent on the time in range [0.0, 1.0] and interpolate between tabPos[pdx] and tabPos[dx]. e.g:

    void taupe(void){
    
        int current_time = glutGet( GLUT_ELAPSED_TIME );
        float dt = (float)(current_time - start_time) / interval;
        if (dt > 1.0f)
            dt = 1.0f;
        float interx = tabPos[pdx] * (1.0f - dt) + tabPos[dx] * dt;
    
        glPushMatrix();
        glTranslatef(interx,dy,tabPos[dz]);   // Ligne Milieu droite
        glColor3f(0.8,0.3,0.5);
        glutSolidCube(2);
        glPopMatrix();
    }