*Notes anotated from some material by                    by Miguel A Sepulveda.
                The OpenGL Utility Toolkit (GLUT) is a programming interface with

               ANSI C, C++,  VB and FORTRAN bindings for writing window system
                independent OpenGL programs. It was written by Mark J. Kilgard and
                covers a great hole left by the OpenGL specification. Thanks to GLUT
                developers we can use a common window system interface independently
                of the target platform. OpenGL applications using GLUT can be easily
                ported between platforms without having to introduce numerous changes
                to the source code. GLUT definitely simplifies the production of
                OpenGL code and it complements the OpenGL library.
 

                The GLUT API is a state machine like OpenGL. This means that GLUT
                has a number of state variables that live during the execution of the
                application. The initial states of the GLUT machine has been reasonably
                chosen to fit most applications. The program can modify the values of
                the state variables as it sees fit. Whenever a GLUT function is invoked
                its action is modified according to the values of the state variables.
                GLUT functions are simple, they take few parameters. No pointers are
                returned and the only pointers passed to GLUT functions are pointers to
                character strings and opaque font handles.

                GLUT functions can be classified into several sub-APIs according to
                their functionality:

                    Initialization
                    Beginning Event Processing
                    Window Management
                    Overlay Management
                    Menu Management
                    Callback registration
                    Color Index Colormap Management
                    State Retrieval
                    Font Rendering
                    Geometric Shape Rendering

                Initializations

                Every OpenGL program using GLUT must begin by initializing the
                GLUT state machine. The glut initialization functions are prefixed by
                glutInit-. The main initialization routine is glutInit:
                Usage:
                  glutInit(int **argcp, char **argv);
                  argcp is a pointer to the program's unmodified argc variable from
                main. Upon return, the value pointed to by argcp is updated because
                glutInit extracts any command line options relevant for the GLUT
                library, for example: under the X Window System environment, any
                options relevant for the X window associated to the GLUT window.
                  argv is the program's unmodified argv variable for main.

                glutInit takes care of initializing the GLUT state variables and
                negotiating a session with the window system. There are a few routines
                that could appear before glutInit; only routines prefixed by
                glutInit-. These routines can be used to set the default window
                initialization state.  For example:
                Usage:
                  glutInitWindowPosition(int x, int **y);
                  glutInitWindowSize(int width, int **height);
                  x,y  = screen position in pixels of the window (upper left corner)
                  width,height  in pixels of the window.

                There is another initialization routine always present in every OpenGL
                application, glutInitDisplayMode():
                Usage:
                  glutInitDisplayMode(unsigned int mode);
                  mode is the Display mode, a bitwise OR-ing of GLUT display mode bit masks.
                The possible bitmask values are:
                GLUT_RGBA
                                  Select an RGBA mode window. This is the default if
                                  neither GLUT_RGBA nor GLUT_INDEX are
                                  specified.
                GLUT_RGB
                                  same as GLUT_RGBA.
                GLUT_INDEX
                                  Select color index window mode. This overrides
                                  GLUT_RGBA.
                GLUT_SINGLE
                                  Select a single buffered window. This is the default.
                GLUT_DOUBLE
                                  Select a double buffered window. This overrides
                                  GLUT_SINGLE.
                GLUT_ACCUM
                                  Select a window with an accumulation buffer.
                GLUT_ALPHA
                                  Select a window with an alpha component to the color
                                  buffer(s).
                GLUT_DEPTH
                                  Select a window with a depth buffer.
                GLUT_STENCIL
                                  Select a window with a stencil buffer.
                GLUT_MULTISAMPLE
                                  Select a window with multismapling support.
                GLUT_STEREO
                                  Select a stereo window.
                GLUT_LUMINANCE
                                  Select a stereo window with a "luminance" color
                                  model.

                #include <GL/glut.h>

                void main(int argcp, char **argv){

                /* Set window size and location */
                glutInitWindowSize(640, 480);
                glutInitWindowPosition(0, 0);

                /* Select type of Display mode:
                   Single buffer & RGBA color */
                glutInitDisplayMode(GLUT_RGBA | GLUT_SINGLE);

                /* Initialize GLUT state */
                glutInit(&argcp, argv);

                .....more code

                };

                Second an example of an animation program:

                #include <GL/glut.h>

                void main(int argcp, char **argv){

                /* Set window size and location */
                glutInitWindowSize(640, 480);
                glutInitWindowPosition(0, 0);

                /* Select type of Display mode:
                   Double buffer & RGBA color */
                glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);

                /* Initialize GLUT state */
                glutInit(&argcp, argv);

                .....more code

                };

                Event Processing

                As mentioned before, GLUT is a state machine. Now we will learn it is
                also designed as an event driven engine. This means that there is a
                "timer" or continuous loop that gets started after the proper
                initializations and that processes, one by one, all the events declared to
                GLUT during initialization. Events are: a mouse being clicked, a window
                closed, a window reshape, a cursor moved, keyboard keys pressed, and
                even more curiously the "idle" event, i.e. nothing happens!  Each one of
                the possible events must be registered in one of the GLUT state variables
                for the "timer" or event processing loop of GLUT to periodically check
                whether that event has been triggered by the user.
 
                For example, we could register "click mouse button" as an event for
                GLUT to watch out for. Events are registered through callback
                registration routines. All have the syntax glut[someEvent]Func, in
                the case of the mouse clicking it would be glutMouseFunc. A callback
                registration tells the GLUT engine which user-defined function is to be
                called if the corresponding event is triggered. So, if I write my own
                routine MyMouse which specifies what to do if the left mouse button is
                clicked, (or the right, etc.) then I can register my callback function after
                the glutInit() in main() using the statement
                "glutMouseFunc(MyMouse);" .

                Let us leave for later which callback functions and events are permitted
                in GLUT. The important thing now is that after all the important events
                in our application have been registered we must invoke the event
                processing routine of GLUT, namely glutMainLoop(). The function
                never comes back, our program basically enters an infinite loop. It will
                call as necessary any callbacks that have been previously registered.
                Every main() for an OpenGL application must then end in a
                glutMainLoop() statement. So in the case of our animation template:

                #include <GL/glut.h>

                void main(int argcp, char **argv){

                /* Initialize GLUT state */
                glutInit(&argcp, argv);
                glutInitWindowSize(640, 480);
                glutInitWindowPosition(0, 0);

                /* Open a window */
                glutCreateWindow("My OpenGL Application");

                /* Select type of Display mode:
                   Double buffer & RGBA color */
                glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
 

                /* Register Callback Functions */
                .....

                /* Start Event Processing Engine */
                glutMainLoop();
                };

                Back to events... I want now to introduce two callback registration
                functions that are very fundamental in any animation program. The
                glutDisplayFunc which sets the display function for the current
                window and the glutIdleFunc which sets the idle callback. Both
                registration routines expect a function of type void *(void). Say we
                write two additional callback functions to our animation template, void
                MyDisplay(void) which takes care of invoking the OpenGL
                instructions that actually draw our scene onto the window, and void
                MyIdle(void) which is a function that gets called whenever there is no
                other user input, that is, each time the event processing machine of
                GLUT goes once around the infinite loop (glutMainLoop()) and does
                not find any new event triggered, it processes MyIdle. Why do I need to
                register an Idle callback function in an animation program? Because if
                we wish to modify each one of the images (frames) shown during the
                animation independently of any user input, there has to be a function (the
                idle callback function) that gets called every so often during the life of
                the OpenGL program and changes the frames before they get drawn by
                Mydisplay().

                Animation Example

                Finally here is a simple template for an animation program:
                #include <GL/glut.h>

                void MyIdle(void){
                /* Some code to modify the variables defining next
                frame */
                ....
                };

                void MyDisplay(void){
                /* Some OpenGL code that draws a frame */
                ....
                /* After drawing the frame we swap the buffers */
                glutSwapBuffers();
                };

                void main(int argcp, char **argv){

                /* Initialize GLUT state */
                glutInit(&argcp, argv);
                glutInitWindowSize(640, 480);
                glutInitWindowPosition(0, 0);

                /* Open a window */
                glutCreateWindow("My OpenGL Application");

                /* Select type of Display mode:
                   Double buffer & RGBA color */
                glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);

                /* Register Callback Functions */
                glutDisplayFunc(MyDisplay)
                glutIdleFunc(MyIdle)

                /* Start Event Processing Engine */
                glutMainLoop();
                };

                Notice that at the end of MyDisplay, a new GLUT routine,
                glutSwapBuffers(). This is very useful in animations. We are using
                a window in DOUBLE buffer mode, one shown and one hidden. The
                drawing OpenGL instructions in this case always render into the hidden
                buffer. The glutSwapBuffers call, exchanges the buffers, showing in
                the window at once what was drawn. This technique is common in
                computer animations because it prevents the human eye from seeing the
                frame being constructed line by line.

               Drawing Points

                OpenGL has only a few geometric primitives: points, lines, polygons.
                All of them are described in terms of their respective vertices. A vertex
                is characterized by 2 or 3 floating points, the Cartesian coordinates of
                the vertex, (x,y) in 2D and (x, y, z) in 3D. While Cartesian coordinates
                are the most common, in computer graphics there is also the
                homogeneous coordinate system in which every point is described by 4
                floating points (x, y, z, w). We will come back to them after covering
                some elementary notions of 3D rendering.

                Since in OpenGL all geometric objects are eventually described as an
                ordered set of vertices, there is a family of routines to declare a vertex.
                Its syntax is:

                void glVertex{234}{sifd}[v](TYPE coords);

                Get familiar with this notation. The curly brackets indicate part of the
                name of the routine.  The routines can take 2, 3 or 4 parameters in either
                short, long, float or double type. Optionally these parameters can be
                supplied in a vector form, in which case we would use the v-type
                routines. Here are some examples:

                void glVertex2s(1, 3);
                void glVertex2i(23L, 43L);
                void glVertex3f(1.0F, 1.0F, 5.87220972F);

                float vector[3];
                void glVertex3fv(vector);

                To simplify all these routines are refered to as glVertex*.

                OpenGL interprets any sequence of vertices according to its context. The
                context is declared by the pair of routines glBegin(GLenum mode)
                and glEnd(), any glVertex* statements executed between the two are
                interpreted according to the value of mode, for example:
                glBegin(GL_POINTS);
                glVertex2f(0.0, 0.0);
                glVertex2f(1.0, 0.0);
                glVertex2f(0.0, 1.0);
                glVertex2f(1.0, 1.0);
                glVertex2f(0.5, 0.5);
                glEnd();

                draws 5 points in 2D with the coordinates specified. GL_POINTS is one
                of the labels defined in the OpenGL header file <GL/gl.h>. There are
                many other modes available but we will review then as necessary.

                Every point is drawn with the color currently stored in the OpenGL state
                variable associated with the color buffer. To change the current color,
                use the family of routines glColor*; there is a lot to say about selecting
                and manipulating colors (there will be another article only on this
                subject).  For the moment, we will be using three floating point numbers
                from 0.0 to 1.0 - this is the RGB (Red-Green-Blue) encoding;
                glColor3f(1.0, 1.0, 1.0); /* White */
                glColor3f(1.0, 0.0, 0.0); /* Red */
                glColor3f(1.0, 1.0, 0.0); /* Magenta */
                etc...
 

                  Drawing Lines and Polygons

                As previously mentioned glBegin(GLenum mode) accepts various
                modes and the sequence of vertices v0, v1,v2, v3,v4,... vn-1 declared
                afterwards are interpreted accordingly. The possible values for mode and
                the actions taken are:

                    GL_POINTS    Draws a points at each of the n vertices.
                    GL_LINES    Draws a series of unconnected lines. The segments
                    are drawn between v0 and v1, v2 and v3,...etc. If n is odd vn-1 is
                    ignored.
                    GL_POLYGON    Draws a polygon using v0, v1,..,vn-1 as
                    vertices.  n must be at least 3 or nothing is drawn, also the polygon
                    can not intersect itself and must be convex (due to the hardware's
                    algorithm limitations).
                    GL_TRIANGLES    Draws a series of triangles using vertices v0,
                    v1 and v2, then v3, v4 and v5 etc. If n is not a multiple of 3 the
                    remaining points are ignored.
                    GL_LINE_STRIP    Draws a line from v0 to v1, them from v1 to
                    v2 and so on. Finally from vn-2 to vn-1 for a total of n-1 line
                    segments. There are no restrictions on the vertices describing a line
                    strip, lines can intersect arbitrarily.
                    GL_LINE_LOOP    Same as GL_LINE_STRIP except that a final
                    line segment is drawn from vn-1 to v0, closing the loop.
                    GL_QUADS    Draws a series of quadrilaterals using vertices v0,
                    v1, v2, v3 and v4, v5, v6, v7 and so on.
                    GL_QUAD_STRIP    Draws a series of quadrilaterals using
                    vertices v0, v1, v3, v2 then v2, v3, v5, v4 and so on.
                    GL_TRIANGLE_STRIP    Draws a series of triangles using
                    vertices in the following order v0, v1, v2, then v2, v1, v3, then v2,
                    v3, v4, etc. The ordering is to ensure that the triangles has the
                    correct orientation and the strip can be used to form part of a
                    surface.
                    GL_TRIANGLE_FAN    Similar to GL_TRIANGLE_STRIP
                    except that the triangles are v0, v1, v2, then v0, v2, v3, then v0, v3,
                    v4, and so on. All the triangles have v0 as a common vertix.
 

                As before there is an idle() callback function whose aim here is to keep
                the clock running (updating the variable time). The display() draws two
                objects; the pendulum cord and weight (in white and red respectively).
                The motion of the pendulum coordinates is implicit in the formulas for
                xcenter and ycenter:

                void display(void){
                  static double radius = 0.05;
                  const double delta_theta = pi2/20;
                  double xcenter , ycenter;
                  double x, y;
                  double theta = 0.0;

                  double current_angle = cos(omega * time);

                  glColor3f(0.0, 0.0, 0.0);
                  glClear(GL_COLOR_BUFFER_BIT);
                  glColor3f(1.0, 1.0, 1.0);

                  /* Draw pendulum cord */
                  glColor3f(1.0, 1.0, 1.0);
                  glBegin(GL_LINES);
                  glVertex2f(0.0, 0.0);
                  xcenter = -cord_length * sin(current_angle);
                  ycenter = -cord_length * cos(current_angle);
                  glVertex2f(xcenter, ycenter);
                  glEnd();

                  /* Draw pendulum dish */
                  glColor3f(1.0, 0.0, 0.0);
                  glBegin(GL_POLYGON);
                  while (theta <= pi2) {
                    x = xcenter + radius * sin(theta);
                    y = ycenter + radius * cos(theta);
                    glVertex2f(x, y);
                    theta += delta_theta;
                  };
                  glEnd();
 
                  glutSwapBuffers();
                };

 void glutWireSphere(GLdouble radius, GLint slices, GLint stacks);
 void glutSolidSphere(GLdouble radius, GLint slices, GLint stacks);

void glutWireCube(GLdouble size);
void glutSolidCube(GLdouble size);

void glutWireTorus(GLdouble innerRadius, GLdouble outerRadius,
GLint nsides, GLint rings);
void glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius,
GLint nsides, GLint rings);

void glutWireIcosahedron(void);
void glutSolidIcosahedron(void);

void glutWireOctahedron(void);
void glutSolidOctahedron(void);

void glutWireTetrahedron(void);
void glutSolidTetrahedron(void);

void glutWireDodecahedron(GLdouble radius);
void glutSolidDodecahedron(GLdouble radius);

void glutWireCone(GLdouble radius, GLdouble height, GLint slices,
GLint stacks);
void glutSolidCone(GLdouble radius, GLdouble height, GLint slices,
GLint stacks);

void glutWireTeapot(GLdouble size);
void glutSolidTeapot(GLdouble size);