/*
    anim2.c

    - Erster(*) Versuch mit Animation: Rotation.
      (*) anim1.c war der (aller)erste Animationsversuch im
      Crashkurs Mai 2001 und sollte nicht mehr verwendet werden.

    - Leertaste startet und stoppt Animation.
    - Programmabbruch mit q-Taste - siehe keyboard_func().


    > Das Programm basiert auf transform1.c und benutzt einen Glut-Timer,
      um die display_func() im Animationsmodus ständig neu aufrufen.
      Wie kann man die Animation schneller oder langsamer laufen lassen?

    > glutSwapBuffers() funktioniert nur, wenn
      GLUT_DOUBLE in glutInitDisplayMode(...) angegben wurde.
      Für Bastler: Was passiert, wenn man eines von beiden weglässt?

    > Andere Funktionen für affine Transformationen sind
      neben glRotatef(...) noch: glTranslatef(...) und glScalef().
      Kann man damit ebenfalls kleine Animationen "bauen"? Klar...
*/




# include       <stdio.h>
# include       <stdlib.h>
# include       <math.h>
# include       <GL/glut.h>


# define        MILLISEC_PRO_FRAME      50


static int      animation_laeuft = 0;
static float    theta = 0;  /* der aktuelle Rotationswinkel */
static GLuint   objekt_liste;



static void     erzeuge_objekt_liste (void)
/*****************************************/
{
    objekt_liste = glGenLists (1);
    glNewList (objekt_liste, GL_COMPILE);
        glBegin (GL_TRIANGLE_STRIP);
            glVertex2f (-0.2, -0.3);
            glVertex2f ( 0.0, -0.1);
            glVertex2f ( 0.0,  0.3);
            glVertex2f ( 0.2, -0.3);
        glEnd ();
    glEndList ();
}



static void     timer_func (int value)
/************************************/
{
    /* printf ("timer_func (value=%d)\n", value); */

    theta += 0.5;
    glutPostRedisplay ();
}



static void     display_func (void)
/*********************************/
{
    /* printf ("display_func()\n"); */

    if (animation_laeuft)
        glutTimerFunc (MILLISEC_PRO_FRAME, timer_func, 1);

    glClearColor (1, 1, 1, 0);
    glClear (GL_COLOR_BUFFER_BIT);

    glLoadIdentity ();
    glRotatef (theta, 0, 0, 1);
    glScalef (2, 2, 2);

    glColor3f (0, 0, 0);
    glCallList (objekt_liste);

    glutSwapBuffers ();
    /* glFlush (); nicht mehr nötig, wenn glutSwapBuffers() benutzt wird. */
    glutReportErrors ();
}


static void     keyboard_func (unsigned char key, int x, int y)
/*************************************************************/
{
    switch (key)
    {
        case ' ':   /* Leertaste */
            if (animation_laeuft)
                animation_laeuft = 0;
            else
                animation_laeuft = 1;
            glutPostRedisplay ();
            break;

        case 'q':
        case 'Q':
            exit (0);
    }
}



extern int      main (int argc, char **argv)
/******************************************/
{
    glutInit (&argc, argv);
    glutInitDisplayMode (GLUT_RGB | GLUT_DOUBLE);

    glutInitWindowPosition (200, 100);
    glutInitWindowSize (600, 600);
    glutCreateWindow ("anim2");

    glutDisplayFunc (display_func);
    glutKeyboardFunc (keyboard_func);

    erzeuge_objekt_liste ();

    glutTimerFunc (MILLISEC_PRO_FRAME, timer_func, 1);
    glutMainLoop ();

    return 0;
}


