动画中的动画立方体

Animate cube inside an animation

在这里,我在每个时期的不同位置显示一个立方体,但我希望它生成一个过渡和动画,例如我希望它作为一个循环从 -1 转换为 +1(动画立方体)

    #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();

    }

在这个函数spawn中,我必须更新dy 我必须以 0.05 作为一个步骤从 -1 到 1 问题是当我添加代码时我失去了我的主要动画

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

ndom 0 到 2 之间的数字 dz = rand() % 3; //生成一个0到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);

在这里我将立方体生成为动画

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

return 0;
}

要制作动画,您必须不断更新显示。删除对 glutPostRedisplay 的所有调用并在 display 中进行一次调用。例如:

void display(){

    whatINeed();

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

    glutPostRedisplay(); // <---
}

要在 2 个位置之间设置动画,您必须知道前一个 (pdx) 和新位置 (dx):

int pdx=0;
int dx=0;

定义动画的时间间隔。使用计时器(glutTimerFunc) instead of glutIdleFunc 开始新的动画:

int interval = 1000; // 1 second
void spawntimer(int value);
int main()
{
  // [...]

  // glutIdleFunc(spawn); <--- DELETE

  glutTimerFunc(interval, spawntimer, 0); // <--- ADD


  // [...]

spawntimer中将当前位置存储到dx并得到一个随机位置。将当前经过的时间存储到 start_time。这表示动画的开始时间,可以通过 glutGet(GLUT_ELAPSED_TIME) 获取。重新启动计时器:

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 在[0.0, 1.0] 范围内根据时间计算对象的相对位置,并在tabPos[pdx]tabPos[dx] 之间进行插值。例如:

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();
}