Question About GLUT and Global Variables

Below is a small GLUT-OpenGL program that animates a teapot turning and provides keyboard input to start/stop the turning, change the point of view, scale the teapot, etc. This code runs as is. I just tested it. This is a demo program I gave to a class I’m teaching on Introduction To OpenGL. Note that I use global variables to pass keyboard actions from my Keyboard callback function back to my Display function. One of my students asked if there was a way to avoid using globals. It’s a reasonable question because the use of globals is generally discouraged. Can anyone suggest a graceful way to pass actions from the keyboard through to the Display function without using global variables? Thanx.


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

float  xs = 0.0, ys = 0.0, rot = 0.0, tip = 20.0, trn = -30.0, zum = 1.0;

//--------------------------------------   Rotate_Teapot   -----------------------------------------

void Rotate_Teapot (void)
{
	rot += 2.0;

	glutPostRedisplay ();
}

//-----------------------------------------   Keyboard   -------------------------------------------

void Keyboard (unsigned char key, int x, int y)
{
    switch (key)  {

	   case 'a':  glutIdleFunc (Rotate_Teapot);  break;
	   case 'z':  glutIdleFunc (     NULL    );  break;

	   case 'x':  tip += 3.0;  break;
	   case 'X':  tip -= 3.0;  break;
	   case 'y':  trn += 3.0;  break;
	   case 'Y':  trn -= 3.0;  break;
	   case 's':  zum *= 1.1;  break;
	   case 'S':  zum *= 0.9;  break;

	   case 'r':  tip = 0.0; trn = 0.0; zum = 1.0;  break;

           case  27:  exit(0);  break;      // Quit program with 'esc' key.

           default :  printf ("   Keyboard -> key = %d, key = %c
", key, key);   break;
    }

    glutPostRedisplay ();
}

//----------------------------------------   Arrow_Keys   ------------------------------------------

void Arrow_Keys (int s_keys, int x, int y)
{
    switch (s_keys)  {

       case  GLUT_KEY_RIGHT:  xs += 0.01;  break;
       case  GLUT_KEY_LEFT :  xs -= 0.01;  break;
       case  GLUT_KEY_UP   :  ys += 0.01;  break;
       case  GLUT_KEY_DOWN :  ys -= 0.01;  break;

       default:  printf ("   Keyboard -> key = %d, key = %c
", s_keys, s_keys);   break;
    }

    glutPostRedisplay ();
}

//-----------------------------------------   Display   --------------------------------------------

void Display (void)
{
    glClear (GL_COLOR_BUFFER_BIT);

    glMatrixMode (GL_MODELVIEW);   // Perform operations on the Modeling matrix.
    glLoadIdentity ();             // Clears Model transformation stack to the identity matrix.

    glTranslatef (xs, ys, 0 );    // Use arrow keys to move scene up-down, right-left.
    glRotatef (tip, 1, 0, 0 );    // Use 'x' key to rotate around X axis (tipping)
    glRotatef (trn, 0, 1, 0 );    // Use 'y' key to rotate around Y axis (turning)
    glScalef  (zum, zum, zum);    // Use 's' key to scale objects in scene.

    glRotatef (rot, 0, 1, 0 );
    glColor3f (1.0, 1.0, 0.5);
    glLineWidth (1.0);
    glutWireTeapot (0.20);

    glutSwapBuffers ();
}

//-------------------------------------------   main   ---------------------------------------------

void main (int argc, char** argv) 
{
    glutInit (&argc, argv);

    glutInitDisplayMode    (GLUT_RGB | GLUT_DOUBLE); 
    glutInitWindowSize     (600, 600); 
    glutInitWindowPosition (600, 150);
    glutCreateWindow       ("GLUT Globals");

    glutKeyboardFunc ( Keyboard );
    glutDisplayFunc  ( Display  );
    glutSpecialFunc  (Arrow_Keys);

    glClearColor (0.0, 0.1, 0.2, 0.0);    // Clear screen to dark blue.

    glutMainLoop ();
}

You could stick everything in a class, where the registered functions pass their arguments into functions within that class. Of course, now you have to have the class instance be global.

In short, no. Something will have to be visibly global to your program. That’s just how GLUT works.

[QUOTE=Alfonse Reinheart;1243609]You could stick everything in a class, where the registered functions pass their arguments into functions within that class. Of course, now you have to have the class instance be global.

In short, no. Something will have to be visibly global to your program. That’s just how GLUT works.[/QUOTE]

That’s kinda what I thought.
One of my students passed in a homework assignment which he did in C++.
He did have to use a few global objects.

Thanks.