OpenGL Tutorial

------------------------------------
Intro
------------------------------------

  We will use a very limited subset of the OpenGL Library.  The OpenGL
  library is a 3D Graphics standard library and works on most platforms.  It
  includes commands for things like setting a camera in 3D space, adding
  textures to quadric patches and building an animated object with a
  transformation stack.  We'll mostly use it to draw a few dots on the
  screen.  After all, why take a graphics programming class if you just
  use OpenGL's calls?  If you want, you can think of this class as writing
  your own subset of OpenGL!

------------------------------------
Documentation and Include Files
------------------------------------

  There is a good set of online OpenGL documentation accessible through
  the "Help" menu on the Indys.  To access this documentation, choose
  the "Online Books" choice.  In the list of books that appears,
  choose the "OpenGL Programming Guide".  Chapter 2 is most pertinent
  to the commands you will be using.  (If you don't find the menu
  option, you be able to type 'insight' at the Unix command prompt and
  then find the OpenGL Manuals.)  

  For help on specific OpenGL commands, you can use the man utility available
  through the "Help" menu's "Man Pages" choice.  The "Graphics Subroutines
  (OpenGL)" section is most pertinant to class material.

  The traditional man command is also available and works just fine.  Note
  however that the glut windowing commands are not mentioned in any of
  these resources.  Detailed documentation for the glut library can be
  found at the following web site:
	http://www.sgi.com/Technology/openGL/glut3doc/spec3.html


------------------------------------
Quick Tutorial
------------------------------------

Initializing Your Windowing Environment

  void glutInit(int *argv, char **argv);

    Initializes the GLUT library.  glutInit() should be called before
    any of the other glut routines, and its parameters are the same as
    those to main().

  void glutCreateWindow(signed char *titleString);

    Opens a window with the characteristics specified by
    glutInitDisplayMode(), glutInitWindowSize() and
    glutInitWindowPosition().  The string titleString appears in the
    title bar.  

  void glutInitDisplayMode(unsigned int mask);

    Tells glutCreateWindow() whether to create an directly colored or
    color-mapped window, or a single- or double-buffered window. The
    mask argument is a bitwise combination of GLUT_RGBA (directly
    colored) or GLUT_INDEX (color mapped), and GLUT_SINGLE (buffered)
    or GLUT_DOUBLE (buffered).  For example, for a single-buffered,
    color-mapped window, use the command:
    glutInitDisplayMode(GLUT_SINGLE | GLUT_INDEX).  The default value
    is GLUT_RGBA | GLUT_SINGLE, or a direct colored, single-buffered
    window. 

  void glutInitWindowPosition(int x, int y);

    Tells glutCreateWindow() where to position a window on the screen. The
    arguments (x, y) indicate the location of the lower left corner of the
    window.

  void glutInitWindowSize(int width, int height);

    Tells glutCreateWindow() the window's size (width and height in
    pixels). 

  void glutDisplayFunc(void (*func)(void));

    Specifies the display function that will be called whenever the
    contents of the window need to be updated.  The display function
    will be called when the window is initially created, when portions
    of the window are uncovered, and when glutPostRedisplay() is
    explicitly called. 

  void glutPostRedisplay(void);

    Marks the window as needing to be redrawn.  Call this function
    whenever you change the window contents.

  void glClear(unsigned int mask)

    This command erases everything in your window and fills it with the
    color black (or in color mapped mode, the color at table location 0, 
    which is by default black).  Use this command whenever you open a new 
    window.  For now, the parameter mask should always be the special constant 
    GL_COLOR_BUFFER_BIT.  That is, 'glClear(GL_COLOR_BUFFER_BIT)'.

  void gluOrtho2D(double left, double right, double bottom, double top); 

    Sets your drawing coordinates in the current window.  You can use a
    different space in the graphics world that on the screen.  For instance,
    your screen can have 100 pixels horizontally, but you can think of
    that as values from 0 to 1 or -1 to 1 or 0 to 100 and have those values
    mapped to 100 different pixels.
    
OpenGL Windowing Tip

    Typically, you'll want to set up your windows so that placing a point
    at (50, 50) means coloring the pixel in the 50th row (from the bottom)
    and 50th column (from the left).  It can be a little trick to set this
    up believe it or not.  Suppose you have width m and length n.  Here is
    a set of commands to do it:

      glutInitDisplayMode( GLUT_RGBA | GLUT_SINGLE );
      glutInitWindowPosition( 0, 0 );
      glutInitWindowSize( w, h );
      glutCreateWindow( "myWindow" );
      gluOrtho2D( -0.5, m+0.5, -0.5, n+0.5 );
      
    It would seem that the window is one too big since you position it from
    0 to w, not 0 to w-1.  Also, notice how you stretch the view one extra
    pixel in size and shift it over half a pixel from -0.5 to m+0.5.  Trust
    me.  It works!

Setting Your Colors

  void glColor3f(float red, float green, float blue )

    Sets the current color when in direct coloring mode.  The parameters may
    take values between 0.0 and 1.0, the lowest and highest intensities,
    respectively. 

  void glIndexi(int c)

    Sets the current color when in color mapped mode.  The parameter c
    identifies an entry in the current color map lookup table.

  void glutSetColor(int index, float red, float green, float blue);

    Loads the color map entry identified by the parameter index with the 
    color given by the red, green, and blue parameters.  These parameters 
    make take values between 0.0 and 1.0.  To avoid annoying color changes
    in your windows, leave the color entries 0 to 15 unchanged.

Drawing Points (Pixels) and Lines

  void glVertex2i(int x, int y) 

    Specifies a vertex for use in describing a point, line or polygon.  Calls
    to glVertex2i should be executed between a glBegin() and glEnd() pair.

  void glBegin(unsigned int mode); 

    Marks the beginning of a vertex list that describes a point, line or
    polygon.  To interpret the vertex list as a series of points, pass the
    special value GL_POINTS.  To interpret the vertex list as a list of
    vertex pairs describing lines, pass the special value GL_LINES.  To
    interpret the vertex list as the points in a polygon, pass the special
    value GL_POLYGON.  Note that it is not necessary to explicitly close
    polygon vertex lists, and that polygons must be convex and their edges
    non-intersecting.

  void glEnd(void);

    Marks the end of a vertex list.

  void glFlush(void);
   
    Some machines may buffer pixel writes.  It seems that when a glEnd()
    is called, that is definitely a good time to flush this buffer.  Some
    implentations don't think so.  This pretty much means that somewhere
    in your program, in particular about where you want to see something,
    it is a good idea to throw in a call to glFlush(), just to be safe.
    glFlush() ensures that all pixels are written and the window is up
    to date.

Ending Your Program

  glutMainLoop(void); 

    Enters the glut processing loop, which will call the display
    function registed using glutDisplayFunc().
 
Compiling

  Here are the specifics.  If you don't know what I'm talking about, skip
  to the bottom about Makefiles.

  To access OpenGL and related glut windowing commands, you'll
  need to include the following headers in your source code:

    #include 
    #include 
    #include "glut.h"
    
  The library "glut.h" is located in a strange place, so you'll
  need the following path during compilation

    -I/net/hc26/cs4451/OpenGL/include
  
  Then you'll need to link in the following libraries:

    -lGL
    -lGLU
    -lXmu
    -lXext
    -lX11
    -lm
    /net/hc26/cs4451/OpenGL/lib/libglut.a

Makefile Compiling

  To compile your c/OpenGL program, use the make command.  To use this
  command, you need a file called "Makefile".  This file tells the
  make command how to compile your program.  The make file you should
  use at the moment is stored at ~cs4451/samples/Makefile.  To use it,
  copy it to your work directory.  Then edit it, and replace the
  program and source name with your program's name and source.  You
  then need only issue the command make, without parameters, to
  compile your program.

  A NOTE: This make file, although functional, was not specifically
  designed for this course.  As the quarter progresses, your TA may
  create a new make file.  Watch your class newsgroup for such an update.

Examples!

  There is also an example of a simple OpenGL program in 
  ~cs4451/samples/