Search code examples
c++openglanimationglut

Translate a triangle using animation(one by one after some interval) with opengl and c++


I want to make a space invader game in opengl. So I thought of creating the enemies using triangles. Before making the game, I want to try out my hand in animation. I have triangle. i want to translate it left upto some point with animation(i.e, triangle is translated after some interval of time. It should look as if it is moving).After reaching some point in the left, I want to translate it back to the same position or some distances right. The process should go on till the screen is open. I used sleep function. But it is not working. No animation is shown. Only the translated triangle is drawn at different translated position. Help me.

Here is my code-

#include "windows.h"
#include <gl/glut.h>
#include<stdio.h>

void init( void )
{
    printf( "OpenGL version: %s\n", (char*)glGetString(GL_VERSION));
    printf( "OpenGL renderer: %s\n", (char*)glGetString(GL_RENDERER));

    //Configure basic OpenGL settings

    glClearColor(1.0, 1.0, 0.0, 0.0);
    glMatrixMode(GL_PROJECTION); 
    gluOrtho2D(0.0,640.0,0.0,480.0);
    glColor3f(1.0,0.0,0.0);
glPointSize(3);
}

void house(int x, int y,int z)
{
  glPushMatrix();
  glTranslatef(x, y,z);
  glBegin (GL_LINES);    
     glVertex2i (0,30);
     glVertex2i (15,60);
      glVertex2i (15,60);
       glVertex2i (30,30);
        glVertex2i (30,30);
        glVertex2i (0,30);
        glEnd();
        //Sleep(200);
  glPopMatrix();
    //glutSwapBuffers();
}


// Main drawing routine. Called repeatedly by GLUT's main loop
void display( void )
{
    //Clear the screen and set our initial view matrix

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);


    int i;
    for(i = 10; i < 350; i = i + 50)
  {
    house(i,20,0);
    Sleep(200);
  }

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
 glFlush();

}

// Entry point - GLUT setup and initialization
int main( int argc, char** argv )
{

   glutInit( &argc, argv );
   glutInitDisplayMode (GLUT_DEPTH | GLUT_SINGLE| GLUT_RGB);
   glutInitWindowSize (800, 600);
   glutInitWindowPosition (100, 100);
   glutCreateWindow( "OpenGL Test" );

   glutDisplayFunc( display );


   init();

   glutMainLoop();

   return 0;
}

Solution

  • In main() you have declared your display() as display callback function. GLUT will call this function either when it determines that the window need to be redrawn or when it is told to redraw it for example by the function glutPostRedisplay().

    The display function is expected to call redraw the windows at a specific point in time. The glFlush() will force the execution of the GL commands.

    The problem is that your animation loop is inside the redraw function and glFlush() is called at the end, showing the result at once. And you don't tell GLUT to redraw the windows. This is why you don't seee the animation.

    For the purpose of the tutorial, I propose you to define a global variable for the initial position of the house drawing. Of course, you'll have to improve this as soon as you understood how all this works.

    static int pos = 10;    // temporary work around, just for the demo  
    

    Then define a timer function, that gets called after a time interval. This will be the core of your animation, organizing the moving, and the redrawing of the window by calling glutPostRedisplay() :

    void timerfunc(int value)    // handle animation 
    {
        pos += 50;               // update the postion 
        if (pos<350)             // as in your originial loop 
            glutTimerFunc(200, timerfunc, 0);  // plan next occurence
        glutPostRedisplay();     // redraw the window
    }
    

    Activate your timer function, in main() just before launching glutMainLoop():

    glutTimerFunc(200, timerfunc, 0);       // call a timer function 
    glutMainLoop();                      // this call is already in your code
    

    Your display function can then be changed into:

    void display(void)
    {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
        house(pos, 20, 0);   // draw the house at its last calculated position 
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glFlush();
    }
    

    Then it works in animated modus !