CS437 Selected Lecture Notes

This is one big WEB page, used for printing

 These are not intended to be complete lecture notes.
 Complicated figures or tables or formulas are included here
 in case they were not clear or not copied correctly in class.
 Computer commands, directory names and file names are included.
 Specific help may be included here yet not presented in class.
 Source code may be included in line or by a link.

 Lecture numbers correspond to the syllabus numbering.

Contents

  • Lecture 1, Introduction
  • Getting Started, solving setup problems
  • Lecture 2, Mouse Handling
  • Lecture 3, Color
  • Lecture 4, Multiple windows and motion
  • Lecture 5, Menu Design and Implementation
  • Lecture 6, Getting user input
  • Lecture 7, Lighting in 3D
  • Lecture 8, Texture Mapping in 3D
  • Lecture 9, Review 1
  • Lecture 10, Quiz 1
  • Lecture 11, Painters Algorithm, Objects
  • Lecture 12, Pan and Zoom, Scroll Bars
  • Lecture 13, Text Sizes and Fonts
  • Lecture 14, Perspective Viewing
  • Lecture 15, Capturing Screen
  • Lecture 16, More Graphics Math
  • Lecture 17, Writing and restroing users work
  • Lecture 18, Rendering Survey
  • Lecture 18a, Timing
  • Lecture 19, Review 2
  • Lecture 20, Quiz 2
  • Lecture 21, Curves and Surfaces
  • Lecture 22, Windowing Systems
  • Lecture 23, Motion and movement
  • Lecture 26, 3D with motion
  • Lecture 24, Data Structures for Rendering
  • Lecture 25, Physics in your GUI
  • Lecture 27, Kinematics and timing
  • Lecture 28, Output Jpeg, PostScript
  • Lecture 29, Project Demonstrations and Review
  • Lecture 30, Final Exam
  • Lecture cs, Color Scale
  • Other Links
  • Lecture 1

    
    The purpose of this course is to provide the student both
    knowledge and a basic Graphical User Interface, GUI, program
    that the student has written and can be expanded into
    various applications the student wants to develop.
    
    Building GUI programs is non-trivial yet rewarding.
    The student needs to understand the operating system,
    the windowing system and "tool kits."
    
    There are many potential employment opportunities for
    graduates with computer graphics skills. The film
    industry and advertising industry have many types of
    positions available. The gaming industry, with some
    firms local to the Baltimore area, have various
    positions available. Check out Firaxis, Breakaway,
    Day 1 Studios, Big Huge Games and others.
    
    Course motto: If it works, use it.
                  If not, find another way.
    
    You will be dealing with windowing systems and graphical
    libraries that are much larger and more complex than
    operating systems. I guarantee they will have bugs.
    Your grade depends of finding a way around any bugs.
    Your program must work in spite of system/library bugs.
    
    The basic prerequisite for this course is to be able to
    write working code in some reasonable programming language.
    You will probably be writing 1,000 to 10,000 lines of code
    in this course. Do not panic. A lot of code is repetitive.
    
    You are expected to know the software development cycle:
    
          Edit          <-----------+
               Compile              |
                       Run          |
                           Curse ---+
    
    As an acknowledged expert, Edsger Dijkstra, has stated:
    "Top down design and programming is right every time
    except the first time." For your rapid learning you
    do not want to use the "waterfall model" or even
    Barry Boehms "spiral model", but rather use 
    "rapid prototyping".
    
    Do not worry about the details, for a while, yet look over
    the organization and structure of the same GUI application
    written for X Windows Motif, OpenGL and Java.
    
    You will need to make a choice of "platform" for doing
    the programming for this course. My lectures will cover:
    
       Microsoft Windows - OpenGL in C, C++ (same code for Linux and Mac OSX)
                         - Java             (same code every where)
    
       Linux, Unix       - OpenGL in C, C++ (same code  MS Windows)
                         - Java             (same code every where)
                         - X Windows Motif  (same code for Mac OSX)
    
       Mac OSX           - OpenGL in C, C++ (same code for MS Windows and Linux)
                         - Java             (same code every where)
                         - X Windows Motif  (same code for Linux, Unix)
    
       Other             - The adventurous student may use Python wx or Qt,
                           PyQt, or other language and graphics tool kit.
                           Microsoft's C# and game software may be used.
    
          On Microsoft Windows you need Windows XP or Vista and
          Microsoft Visual Studio installed in order to use OpenGL.
          (In past, buy from UMBC bookstore at very low price.
           now may be download free or see instructor.))
          You will need OpenGL Utility Toolkit, GLUT, also.
          On Microsoft Windows you need Java 1.5 or later installed
          (Download from internet.)
    
          On Linux, Unix gnu compilers should be available. Install
          OpenGL (called Mesa) if not already available.
          You will need OpenGL Utility Toolkit, GLUT, also.
          On Linux, Unix you need Java 1.5 or later installed.
          On Linux, Unix you need Motif (called Lesstif or OpenMotif) installed.
          (UMBC linux.gl.umbc.edu has all software installed with the
           possible exception of GLUT. For your computer - download from
           the internet.)
    
          On Mac the underlying operating system is Unix. Thus you can
          download X windows, OpenGL, GLUT, Motif and other software if
          it is not already installed. You may also use the Mac IDE.
    
          Java has two execution models. "Frame" makes standard applications
          that run in a standard window on all platforms. "App" or applet is
          much more restrictive and must run in a WEB browser or appletviewer.
          Then you have a choice of using just AWT or additionally Swing
          or Swing2 and optionally Java3D. Explore "java.sun.com".
    
          "Other" becomes the students responsibility to set up the
          environment and do the homework and project. Just running a
          demo project is not acceptable. You must make significant
          additions and changes.
    
    
    GUI Human factors: Make sure it is obvious to the user of your
                       application how to quit, exit, kill or stop.
    
    
    Just a quick look at some sample code.
    See which will run on your development system
    
      w1.c basic X windows
    
      w1.jpg - screen
    
      w1gl.c - w1.c in OpenGL
    
      w1gl.jpg - screen
    
      W1frame.java - w1.c in Java
    
      W1frame.jpg - screen
    
      W1app.java - W1frame as an applet
    
      hw1s.py - contributed Python wx
    
      app1qt4.py - contributed Python Qt
    
    Note that:
    w1.c, the basic X Windows GUI application can be compiled
          and executed on all Unix based operating systems,
          including MacOS X
    
    w1gl.c, the OpenGL GUI application can be compiled
            and executed on almost all operating systems
            that provide windowing (All forms of Unix,
            MacOS and Microsoft Windows, etc.)
    
    W1frame.java, the Java GUI application can be compiled
                  and run on any system that has Java
                  J2SE 1.4.2 or later available.
    
    W1app.java, the Java GUI application can be compiled
                  on any system that has Java J2SE 1.4.2 or
                  later available. Then run in almost any
                  WEB browser. But, the user may not have
                  Java applets enabled. There are also some
                  severe restrictions on applets.
    
    Other demonstrations of sample applications may include:
    
    split_cube - visualization, color, movement, inside
    teapots - lighting
    planets - lighting and glowing 1
    sky_fly - terrain
    pilot - do your own flight simulator
    springgl - education
    spring2gl - build on previous applications
    alpha_fade - scene transitions using fading
    earth - texture map pictures onto objects
    gears4 - modeling
    tenseggl - modeling user controls viewing
    light_dat - skull, more modeling
    
    draw - default object oriented graphics (digital logic added)
    pairs2 - card game
    hull_draw - modeling boat hull
    mover - independent window control
    fractal.c    - create scenes (art vs composition)
    fractalgl.c  - create scenes (art vs composition)
    Fractal.java - create scenes (art vs composition)
    
    Now, you need to set up your system for GUI programming.
    
    linux.gl.umbc.edu has everything for Linux X Windows,
    OpenGL and java. You may have to download software or
    set up links or change directory names on your Linux
    or Unix system.
    
    Microsoft Windows needs to have Microsoft Visual Studio to
    be able to compile programs for OpenGL. There are many
    versions of Microsoft Visual Studio and thus they are
    not covered in this course. The essential component is
    "cl.exe" the C and C++ compiler that can be used from
    a standard command prompt. If you use Visual Studio
    be sure you turn off preference "precompiled header files".
    
    Mac OSX, use either the Mac IDE or download the X environment.
    
    More information is in getting started
    
    That said, here are the Linux/Unix/Mac "Makefile" and the
    Microsoft Windows "make.bat" files that compile and execute
    the source code shown above.
    
    
      Makefile1.linux
      Makefile_mac_w1
      make1.bat make1.bat.txt
    
    In my personal directory, I have some Makefiles and
    some  make.bat  files that includes all commands to make
    most programs in that directory. 
    A start of my Makefile and make.bat is shown above.
    
    An option to  make.bat is to use  nmake  on Microsoft Windows.
    (This is an optional exercise for the student.)
    Or, use an IDE such as Visual Studio, Eclipse, etc. etc.
    
    

    CMSC 437 Getting Started

    
    Each student needs to choose an operating
    system to which they have access.
    
    UMBC makes available computers running Microsoft Windows XP,
    Linux, Solaris, MacOS and several others.
    Students may configure and use their personal computers.
    UMBC offers economical software through my.umbc.edu "business".
    
    The "windowing" system is chosen by default from the operating
    system choice. MS Windows, X windows or Macintosh.
    In Unix/Linux operating systems the user has a choice of window
    manager and possibly a choice of desktop. There may be a graphical
    software development environment available. Students may use any
    tools they have learned and like. This course can not hope to
    cover all possible development environments. Thus, tested command
    line instructions are provided that will work for this course.
    Do not expect help from the instructor on other development
    environments, they generally have a long learning curve and are
    found to be marginally more productive that command line development.
    
    In the chosen operating system, the student
    should choose a programming language, "C", C++,
    Java, or other that has available interface to OpenGL.
    
    You may tart by using a UMBC machine and getting sample files
    
     From any computer on the Internet that has "ssh" available
    
       ssh -X linux.gl.umbc.edu  (older systems)
       ssh -Y linux.gl.umbc.edu  (up to date systems)
       (then enter your UMBC username and password)
    
     Starter files may be copied to your subdirectory on
     GL  using commands such as (be sure to type the last space-dot):
    
     cp  /afs/umbc.edu/users/s/q/squire/pub/download/w1.c  .
     cp  /afs/umbc.edu/users/s/q/squire/pub/download/w1gl.c  .
     cp  /afs/umbc.edu/users/s/q/squire/pub/download/W1frame.java  .
     cp  /afs/umbc.edu/users/s/q/squire/pub/download/W1app.java  .
     cp  /afs/umbc.edu/users/s/q/squire/pub/download/W1app.html  .
     cp  /afs/umbc.edu/users/s/q/squire/pub/download/Makefile1.linux  .
    
     *** currently on linux.gl.umbc.edu most students also need:
     cp  /afs/umbc.edu/users/s/q/squire/pub/download/libglut.so.3.7  .
     cp  /afs/umbc.edu/users/s/q/squire/pub/download/libXm.so.1  .
     ln -s libglut.so.3.7 libglut.so.3
     ln -s libglut.so.3.7 libglut.so
     mkdir GL
     cp  /afs/umbc.edu/users/s/q/squire/pub/download/glut.h  GL
     setenv LD_LIBRARY_PATH .
     *** the above is needed when GLUT and Motif are not installed
    
    
     type   make -f Makefile1.linux
            make -f Makefile1.linux java
    
     The java program runs upon typing the second command.
     Type   w1    to run the basic X Windows program.
     Type   w1gl  to run the OpenGL program.
    
     If you get a message about a missing  .so  file, you also need
            setenv LD_LIBRARY_PATH .
     in order for the ".so" shared object files to be found.
    
    
    
     On the old UMBC lab machine running MS Windows 2000, there was a lot more
     setup required. Here are the steps I needed to be able to use OpenGL
     with Glut. (do NOT type the (stuff) ) (J: may be S:)
     ((Or you may use  WinSCP, it works great for me.))
    
        log on    (I was in J:\umbc.edu\users\s\q\squire\home,
                   you will be in your  /afs  directory)
        md cs437  (a special directory for this course)
        cd cs437  (be there)
        md GL     (needed for GLUT)
        cd GL     (be there)
        copy J:\umbc.edu\users\s\q\squire\pub\download\glut.h
        cd ..     (you are back in cs437)
        copy J:\umbc.edu\users\s\q\squire\pub\download\glut32.lib
        copy J:\umbc.edu\users\s\q\squire\pub\download\glut32.dll
        copy J:\umbc.edu\users\s\q\squire\pub\download\w1gl.c
        copy J:\umbc.edu\users\s\q\squire\pub\download\cl_setup.bat
        cl_setup  (you are running the .bat file)
        cl /GX /ML /I. w1gl.c
        w1gl
    
    On Mac OSX you can use Cocoa, the native Mac graphics,
    or use "fink" to download X Windows, Motif, possibly OpenGL
    if not installed.
       Cocoa will look like
          #import 
          #import "your_stuff.h"
          int main(int argc, char *argv[])
          {
            return NSAapplicationMain(argc,(const char *)argv);
          }
    
       or use the same command line commands as Linux, SunOS, or
       any version of Unix.
    
    
     Follow this link to Solve Setup Problems, Unix-Linux
    
     Follow this link to Solve Setup Problems, Microsoft
     
    

    Solving Setup Problems Unix-Linux

    Do not expect you system to be set up for GUI programming.
    You are now into the expert programmer realm.
    
    You must be able to find out how your specific computer is configured.
    
    Use the command    printenv | more   to see your environment.
    Specifically look at some environment variables:
         echo $PATH     # direct access to executable programs
         echo $INCLUDE  # direct access to include files
         echo $LIB      # direct access to linking libraries
    
    You can modify environment variables for your use using:
         set LIB=$LIB;/your-directory-path
         export LIB
    
     On some systems, X Windows and Motif may not be installed in default
     directories.  For these, use    find /usr  -name Xm.h -print
     to get the include directory,   CFLAGS= -I<path to directory>
    
        CFLAGS= -I/usr/X11R6/include
    
     Use    find /usr -name libXm\* -print
     to get the link directory,  LIBX= -L<path to directory>
    
        LIBX= -L/usr/X11R6/lib -lXm -lXt -lXi -lX11 -lm
    
     Then use expanded compile and link command in the Makefile
     tab gcc -o w1 $(CFLAGS) w1.c $(LIBS)
    
     To get X windows manual pages, you may need, in your .bashrc file
    
       set MANPATH=/usr/local/man:/usr/X11R6/man
       export MANPATH
    
     or in your .cshrc file
    
       setenv MANPATH /usr/local/man:/usr/X11R6/man
    
     OpenGL use requires access to the file  GL/gl.h
     and libgl.so or libgl.a
    
     For gl.h, use    find /usr  -name gl.h -print
     to get the include directory,   CFLAGS= -I<path to directory>
     (do not keep the trailing "/GL" in the "path to directory")
    
          CFLAGS= -I/web/www/help/C++/opengl/glut-3.7/include
    
     For libgl, use     find /usr -name libgl\* -print
     to get the link directory,  LIBGL= -L<path to directory>
    
          LIBGL= -L/usr/lib -lGLw -lGL 
    
     glut use requires access to the file  GL/glut.h
     and libglut.so or libglut.a
    
     For glut.h, use    find /usr  -name glut.h -print
     to get the include directory,   CFLAGS= -I<path to directory>
     (do not keep the trailing "/GL" in the "path to directory")
    
     For libglut, use     find /usr -name libglut\* -print
     to get the link directory,  LIBGL= -L<path to directory>
    
          LIBGL= -L/usr/lib -lGLw -lGL -lGLU 
    
     There may be systems where links may be missing in /usr/lib
     On one system, it was necessary, to specifically include the
     ".so" file
    
        LIBGL= /usr/lib/libglut.so.3 -lGLw -lGL -lGLU 
    
    
     Combine library information using:
    
          LIBS=$(LIBGL) $(LIBX)
    
     Then compile using:
    
          gcc -o w1 $(CFLAGS) w1.c $(LIBS)
    
    You may want to use the Perl Script below to set up a UMBC lab
    computer running Linux to have a friendly environment:
    
      Be in a UMBC computer lab, booted up in Linux. Be in your cs437 directory.
      ssh linux.gl.umbc.edu   # log in, cd to your cs437 directory
                                do above to get w1.c, w2gl.c, Makefile1
      cp /afs/umbc.edu/users/s/q/squire/pub/download/oglsetup.pl.txt  .
      mv oglsetup.pl.txt oglsetup.pl
      ./oglsetup.pl
      1
                       this should set up a directory and links, if successful:
      ./oglsetup.pl
      2
      Makefile1
                       this augments Makefile1
      ^D               log off linux.gl.umbc.edu back to lab machine
      make
                       This should compile, without error, w1.c and w1gl.c
      w1               # run w1
      w1gl             # run w1gl  if it does not work, read the Pearl script
    
    

    Solving Setup Problems, Microsoft

    Do not expect you system to be set up for GUI programming.
    You are now into the expert programmer realm.
    
    
    Use the command    set | more   to see your environment.
    Specifically look at some environment variables:
         echo %PATH%     # direct access to executable programs
         echo %INCLUDE%  # direct access to include files
         echo %LIB%      # direct access to linking libraries
    
    You can modify environment variables for your use using:
         set LIB=%LIB%;S:\your-directory-path
    
     On some systems, OpenGL and glut may not be installed in default
     directories. If not, just copy the needed files to the required
     directories. The assumption is that Microsoft Visual Studio is
     installed. This is not free software and must be purchased in
     order to have a C and C++ compiler and associated libraries.
    
     The following shows the directories and the necessary files:
     (uppercase is the same as lowercase on Microsoft)
     (replace Microsoft Visual Studio\VC98 with
              Microsoft Visual Studio .NET 2003\VC7\PlatformSDK
              Microsoft Visual Studio .NET\VC7\PlatformSDK
              Microsoft Visual Studio 9.0\VC
      for various versions)
    
     C:\Program Files\Microsoft Visual Studio\VC98\include\GL\gl.h
     C:\Program Files\Microsoft Visual Studio\VC98\include\GL\glaux.h
     C:\Program Files\Microsoft Visual Studio\VC98\include\GL\glu.h
     C:\Program Files\Microsoft Visual Studio\VC98\include\GL\glut.h
    
     C:\Program Files\Microsoft Visual Studio\VC98\lib\opengl32.lib
     C:\Program Files\Microsoft Visual Studio\VC98\lib\glu32.lib
     C:\Program Files\Microsoft Visual Studio\VC98\lib\glaux.lib
     C:\Program Files\Microsoft Visual Studio\VC98\lib\glut32.lib
    
     C:\Windows\System32\opengl32.dll
     C:\Windows\System32\glu32.dll
     C:\Windows\System32\glut32.dll
    
    You can get these files, if not on your system, from
     /afs/umbc.edu/users/s/q/squire/pub/download
    
     basically 7 files  glut32 and opengl32  for   .lib  and   .dll
                  and   gl.h  glut.h  glu.h
    
    If you are not set up for Command Prompt "C" programming, you need
    to set up Environment Variables
    
      Mouse your way to  Control Panel     on your computer
                           System
                             Advanced
                               Environment Variables
    
      You have a choice of "user variables " just for current user
      or                   "system variables" apply to all users
    
      Check or add for appropriate version:
          lib       ;C:\Program Files\Microsoft Visual Studio\VC98\lib
          lib       ;C:\Program Files\Microsoft Visual Studio .NET 2003\VC7
                                                           \platformSDK\lib
          lib       ;C:\Program Files\Microsoft Visual Studio 9.0\VC\lib
    
          include   ;C:\Program Files\Microsoft Visual Studio\VC98\include
          include   ;C:\Program Files\Microsoft Visual Studio .NET 2003\VC7
                                                       \platformSDK\include
          include   ;C:\Program Files\Microsoft Visual Studio 9.0\VC\include
    
          path      ;C:\Program Files\Microsoft Visual Studio\VC98\bin
          path      ;C:\Program Files\Microsoft Visual Studio\VC7\bin
          path      ;C:\Program Files\Microsoft Visual Studio 9.0\VC\bin
    
                    (Concatenate, separating them by a semicolon, ;)
    
    To set your environment variable on GL for a UMBC lab machine:
      Right click on "my computer" click on properties,
                                                advanced,
                                                  environment variables.
    
    Note: There may be a \Microsoft Visual Studio .net\ (no 2003 )
    
    To find missing or misplaced  .dll  files
      cd \
      dir /s mspdb71.dll   (this is an example, probably not found)
      dir /s mspdb80.dll   (for visual studio 9.0)
    
    Then copy the misplaced  .dll  to  \windows\system32
    (it is safe to add  .dll  files to \windows\system32 but suggest not overwrite)
    
      Now use a Command Prompt window to compile
    
           cl /GX /ML w1gl.c
    
      Then execute the program
    
            w1gl
    
      You may use "nmake" on Microsoft, similar but not quite the same
      as "make" or "gmake" on Unix-Linux
    
    Note: When in command prompt window, the two commands:
    
          cd \
          dir /s opengl32.lib
    
          will tell you if you have OpenGL and where the "lib" is
    
          dir /s cl.exe   will tell you the "path" to the compiler
    
          dir /s gl.h     will tell you where its "include" directory is.
    
    You will probably have to add glut.h in directory with gl.h
    You will probably have to add glut32.lib in directory with opengl32.lib
    You will probably have to add glut32.dll in \windows\system32
             or in working directory
    
    Setup is a one time effort per machine per operating system.
    
    Windows XP commands are command.help
    
    Microsoft C and C++ compiler options are cl.help
    
    Remember: Microsoft came after Unix and copied much.
              Unix command line works in Microsoft command window
              prog < data    redirection of file 'data' to stdin
              prog > reslt   redirection of stdout to file 'reslt'
              prog | more    pipe output through 'more' same as Unix
              prog -help     often both /option and -option are allowed
              "root" and directories are forward slash on Unix
              "root" and directories are backward slash on Microsoft
              some tools accept both " / " and " \ " on Microsoft, WWW, FTP, etc.
              Microsoft 'nmake' much line Unix 'make' or 'gmake'
              "C", "C++", Java, etc languages same on both.
              Microsoft is case insensitive file system, thus
              use all lower case in programs for compatibility.
              e.g. #include <stdio.h>  /* include path */
                   #include "your.h"         /* local directory */
                   fopen("my_file.stuff", "r");
              Both take long file names. No more 8.3 restriction.
              Both allow spaces but save the headache, use underscore, _.
              Both use environment variables and substitution in scripts.
    
    Know and use tools to help yourself be efficient.
    You many wish to keep old versions of programs (renamed or in separate
    directories) and use  "diff" on Unix, "fc" on MS Windows to find
    the DIFFerences using a File Compare tool.
    
    
    
    

    Lecture 2 Mouse Handling

    An extension of the very basic w1.c is to use the mouse to
    select points, then connect the points with lines.
    You may download these programs, changing "1" to "2" in
    the 'cp' commands in lecture 1.
    
      cp /afs/umbc.edu/users/s/q/squire/pub/download/w2.c
      cp /afs/umbc.edu/users/s/q/squire/pub/download/w2gl.c
      cp /afs/umbc.edu/users/s/q/squire/pub/download/W2frame.java
      cp /afs/umbc.edu/users/s/q/squire/pub/download/W2app.java
    
    
    Modify the Makefile1.linux by copying the groups of lines and
    also changing "1" to "2" in the copied lines.
    
    After running the programs, look through the source code to
    see how the mouse is handled (in a number of places!).
    3D select will be covered in Lecture 11.
    
      w2.c connect points X windows
    
      w2gl.c - w2.c in OpenGL
    
      W2frame.java - w2.c in Java
    
      W2app.java - W2frame as an applet
    
    
    
    
    

    User placement, Rubber band

    One common GUI for the user to place objects at a position
    with a user chosen size is to draw a "rubber band" rectangle.
    
    This GUI feature uses "mouse motion" and typically has
    the user first select the object to be placed, then press
    and hold left mouse button down. The start coordinate is recorded
    on the button down, the rectangle is displayed stippled (dashed)
    while the user moves the mouse, then the end coordinate is
    recorded on the button up.
    
    Most systems provide a three button mouse with the buttons
    labeled left, middle and right or 1, 2 and 3.  Any of the buttons
    may be used for any action, yet users expect the left button to
    be used for the most common actions.
    
    First the code is shown for just showing the rubber band
    rectangle.
    rubber.c Xlib code
    rubbergl.c GL code
    Rubber.java Java code
    
    Next the code is augmented to draw rectangles and do
    selections. Now the code leaves a red rectangle when the
    mouse button comes up. Note: "select" is also available.
    With multiple rectangles on the scene, left click in one
    rectangle, then another. Note that the selected "object" is
    changed to green color.
    rubber1.c Motif code
    rubber1gl.c GL code
    Rubber1.java Java code
    
    An option is to have a grid and snap to grid.
    The grid is always on in this example, yet should be under menu
    control (grid spacing, snap, hide, etc. as shown in "draw" demo.)
    I consider a grid essential on a mouse input GUI.
    rubber2.c Motif code
    rubber2gl.c GL code
    Rubber2.java Java code
    
    
    

    Visual Effects

    Visual Effects, visual understanding

    The program split_cube.c shows a solid cube that is made up of five (5) tetrahedrons. This would be hard to visualize without some considerations: 1) In order to see how the cube is constructed, an offset is provided. ("O" for larger offset, "o" for smaller offset, down to zero) Note: at very small or zero offset, it is hard to understand how the cube is built. 2) In order to see how the cube is constructed, the viewer may change the axis of rotation (from the present orientation). (Mouse press left, mouse press right, switches axis of rotation. If there is a middle mouse button, that also switches the axis of rotation.) Note: In this example, almost every axis of rotation provides a lot of information. 3) In order to see how the cube is constructed, the color of adjacent faces are made unequal. This is accomplished by slightly changing the color of the vertices of the triangles that make up the faces of the tetrahedrons. ("C" for larger contrast, "c" for smaller contrast, down to zero) Note: at very small or zero color contrast, it is hard to understand the shape of the rotating objects. 4) In order to see how the cube is constructed, the speed of rotation must be reasonable for the viewer. A static image does not convey all the information about how the cube is constructed. ("F" for faster rotation, "f" for slower, down to zero) Note: at very small or zero rotation, it is hard to understand the shape of the rotating objects. 5) In order to see how the cube is constructed, a wireframe can be displayed for the viewer. The wireframe shows edges of polyhedrons. It this case, the five tetrahedrons, each with unique color edges. ("W" for wireframe, "w" for solid) Note: That the edges merge and only one color is displayed with the offset goes to zero. Experiment with rotations (speed and direction), color shade, offsets, and wireframe vs solid. Consider what information your viewers need from your application. Provide the appropriate user interface. Then try split_cube6.c run from the command line with split_cube6 -x Unrecognizable, thus slow it down with f's. Change rotation with mouse and open it up with uppercase O's. Deepen colors with uppercase C. Two dimensional static pictures do not have the visualization capability of user movable and colorable objects. A classic demonstration, that measures frames per second, is gears.c Compile and run this demonstration. Note use of either letter keys 'x' 'y' 'z' or arrow keys.

    Human Factors, timing

    Human Factors considerations

    These are very loose time estimates and there is significant variation from person to person, yet the concepts are worth covering. Human beings are very slow compared to computers in many situations. But, human beings get very impatient if the computer does not respond in a timely manner. What is timely? A person sees an event and must take action. Here is the approximate time line: 1/10 second to "see" or recognize the event. 1/10 second to make a decision to take action 1/10 second to physically move a finger (e.g. press a key) Thus, the fastest a person can respond to a "message" on a computer screen is three tenths of a second. A person presses a key and expects a response from the computer. The person needs at least 1/10 second to "see" that there is a response. Another 1/10 second to "understand" the response. There seems to be some dead time between the key press and expecting to "see" the response. Experiments have been conducted and found, on average, that a computer response within one-half second did not slow down most users. A few users could tell the difference between two tenths of a second response and three tenths of a second response. On a modern computer with multiple pipelines and a 3GHz clock, about one billion instructions can be executed in one tenth of a second. There is a tradeoff that the GUI programmer has to make. For rapid response activities, low quality images may be needed and may be acceptable. For activities where the user is creating, more quality may be needed and slower response may be acceptable. For example, OpenGL lines are limited to square ends while basic X Windows and Microsoft Windows allow options for round ends and lengthen by one-half line width in order to provide a smooth sequence of connected lines. Consider a fast typist. Assume a person who can type 50 words per minute. The definition of a word is five characters and a space. Thus, 300 key presses per minute or 5 key presses per second. But, that only allows two 1/10 second time periods per character. Thus, the typist is multiplexing, reading ahead, selecting keys, and pressing keys overlapped in time. Color is in the category of "in the eyes of the beholder". There is a good reason why American traffic lights have red on top, yellow in middle and green on bottom as a standard. There are many forms of "color blind" and thus the standard position with each color emitting light is the "event" that a driver senses. For GUI programming, file menu on the left and help menu on the right is a defacto standard for the same reason. Users are more efficient, and happy, when they spend less time hunting for what they need. Common color issues are red appearing as grey, green and blue indistinguishable, etc. The GUI programmer can avoid these concerns by using intensity to create contrast. Rerun split_cube using "c" held down, then "C" held down, repeat, to see the visual effect. User interface speed comparing MAC OSX and Windows XP was measured and reported in UIF_Report.pdf The term "User Interface Friction" means friction that slows down the user. This varies with user capability. I call it fluff vs. function. On line are many helpful hints on user interface design. I like JJ Garrett's wisdom as given in his nine pillars of successful web teams: It is competent people in each of these nine areas that are more important than rolls, job descriptions, tools or process. Then, in his elements of user experience where he asks: "What do you expect to happen if you click there." "Think visually." Does the user get positive feedback to know the expected action happened? Consider a person setting a new alarm clock for the first time. Is it really set? Might I miss my important meeting tomorrow morning?

    Lecture 3 Color

    With pigment paint, the "primary colors" are red, blue and yellow.
    With electronic displays the "primary colors" are red, green and blue.
    
    The program Jcolor.java uses the built in names for colors and
    lists the numeric values that correspond to the red, green and blue
    color components. The output of Jcolor.java is:
    
    
    
    Notice that each color has a group of three numbers that represent
    the amount of red, green and blue, hereafter referred to as RGB.
    
    RGB = 0,0,0         is black, no color.
    RGB = 255, 255, 255 is white, all color.
    RGB = 255,0,0       is red.
    RGB = 0,255,0       is green.
    RGB = 0,0,255       is blue.
    
    
    A more complicated Java program consists of three files that need
    to be compiled, gives the user "sliders" to choose a color.
    The Red, Green and Blue components can be selected independently.
    
    MyColorChooser.java 
    DrawPanel.java 
    PaletteFrame.java 
    
    an optional Java applet is:
    PaletteApp.java 
    PaletteApp.html 
    
    A sample of PaletteFrame output is:
    
    
    
    
    In programming there is usually an alternative floating point
    RGB with the color components in the range 0.0 to 1.0 equivalent
    to 0 to 255. A fourth component "Alpha", A, opacity can be
    present making the RGBA of a pixel.
    
    
    
    A sample of X Windows coding of a colorwheel is colorw.c uses calculated values for colors. The output is
    
    
    
    A sample of OpenGL coding of a colorwheel is colorw_gl.c uses calculated values for colors. The output is
    
    
    
    X Windows defines names for many more color names than Java,
    these are available in rgb.txt
    
    Colors are used in combination with lighting to fool the eye into
    seeing various textures. teapots.c renders the
    Utah Teapot with various colors and surfaces to provide the image.
    10 values are used for each surface: Ambient RGB, Diffuse RGB,
    Specular RBG and shine. See numeric values below renderTrapot.
    
    
    
    There are many formats for graphics files. Two of the most common used
    on the WWW are  .gif  and  .jpg, Gif and Jpeg image files. Most graphics
    formats can be converted to most other graphics formats. A common program
    used for modifying images and changing formats is Paint Shop Pro. A free
    version of this program may be downloaded form the WWW for MS Windows.
    A similar program for Linux is Gimp which comes with many Linux
    distributions and may also be freely downloaded.
    
    Images may be scanned, captured from the WWW and created using a graphics
    editor. In order to use graphics in your application program, you need
    to be able to read the specific file format. Two demonstration programs
    alpha_fade.c and alpha_fade2.c
    are provided with respective files gifread.c and
    jpegread.c 
    These demonstration programs read four  .gif  or  .jpg  files and also
    demonstrate the use of "Alpha" to fade from one image to the next.
    
    An example deck of cards as .gif files with an OpenGL display program
    is in the directory download/cards_gif
    The program card_gl.c that uses gif.h and 
    gifread.c displays and shuffles the deck to display card_gl.jpg
    
    An example deck of cards as .xbm files with an OpenGL display program
    is in the directory download/cards_xbm
    The program cards_gl.c that uses 
    xbmread.c displays and shuffles the deck to display cards_gl.jpg
    
    An example Java program to display  .gif  .jpg  and  .png  files is
    ImageDisplay.java
    
    
    Many other graphics formats can be read. Some have code available on the WWW
    but some you may have to write your own code to read the format. The basic
    structure of graphic image files is a header with information about the
    image such as height and width in pixels. Then there is generally a
    Color Table, often coded as "ct". The basic idea is to have a set of colors,
    a set of RGB's, stored in a table and then use one unsigned byte for
    each pixel. The value in the unsigned byte is an index into the Color Table.
    The terminology is that a color table with RGB components of eight bits
    has 24 bits for each color or 2^24, over 16 million, possible colors.
    The Color Table may have a maximum of 256 entries, called the pallet,
    for this particular image. An unsigned byte can index from 0 to 255 thus
    selecting one of the 256 colors in the pallet for each pixel.
    
    Some graphics image formats allow compression such that the original
    image is not exactly reproduced yet can look acceptable. This saves on
    disk space and computer input/output time yet uses more CPU time.
    But, in your application program, each pixel is usually stored as
    a 32 bit word, RGBA. Note that OpenGL texture mapping files are stored
    just as they would appear in RAM in your application. X Windows
    bitmap files, d13.xbm ,
    are actually "C" header files d13.xbm as text with the bits
    encoded as hexadecimal. The .xbm files can be read at execution time
    or included with  "#include". For use in OpenGL use xbmread.c as
    tested in xbm_to_gl.c
    Each pixel in the  .xbm  file is on or off. The user specifies the
    foreground and background color.
    
    Just basic colors are not enough to get good looking graphics.
    Shading across each, usually small, polygon provides the finishing
    touch.
    
    The subject of "lighting" will be covered in a future lecture.
    
    Gouraud shading interpolates the colors at the vertices across the polygon.
    
    Phong specular shading interpolates the normal vector at the vertices
    across the polygon. More will be discussed on lighting in a later lecture.
    
    If you have a color image and need to get a gray scale image,
    the standard conversion is to make each RGB color have the value
       0.299 * R  +  0.587 * G  + 0.114 * B
    Remember 1.0 is white and 0.0 is black. When R equals G equals B then
    you have a shade of gray.
    
    The "visible" spectrum, that which can be seen by average people,
    is roughly given by wavelength in nm = nanometer or 10^(-9) meter.
    
    Violet  390-455nm    
    Blue    455-492nm
    Green   492-577nm
    Yellow  577-597nm
    Orange  597-622nm
    Red     622-770nm
    
     100nm wavelength = about 1,500,000 GHz frequency
    1000nm wavelength = about   150,000 GHz frequency
    
    The RGB color space is called an "additive color space."
    The CMYK, Cyan, Magenta, Yellow, black, color space is used for
    printing and is called a "subtractive color space."
    An approximate conversion, because every ink is unique, is
      C1 = 1.0-R
      M1 = 1.0-G
      y1 = 1.0-B
      K = min(C1, M1, Y1);
      C = C1-K
      M = M1-K
      Y = Y1-K
    
    TV uses an YIQ, luminance, inphase, quadrature, color space.
    The matrix conversion is
       |Y|   |0.299  0.587  0.114|   |R|
       |I| = |0.596 -0.275 -0.321| * |G|
       |Q|   |0.212 -0.528  0.311|   |B|
    
    Notice that Y, luminance, is the gray scale formula, for black and
    white TV. The IQ provide the color for color TV.
    The CMYK and YIQ are smaller color spaces than RGB, some RGB
    combinations are not representable.
    
    Action and music enhance interest
    
    For adding sound into your project, search Google.
    A sample for java is ClipPlayer.java
    and driver program  ClipPlayerTest.java . Record your own sound clips with a microphone and possibly
    free download software.
    
    Color may be used to provide value information to a user. This is
    typically called a "color scale" as shown on the link below.
    This link also has a python colourchooser example.
    Color Scale
    
    

    Lecture 4, multiple windows and motion

    Motion can be useful and impressive.
    
    If your program must do a lot of computation for each movement,
    you will need to "double buffer". With double buffering your
    program is building the next screen in RAM while the previous
    screen is seen by the user. Then the buffers are swapped and the
    user sees the new screen and your program builds the next
    screen in the other RAM buffer.
    
    Examples to be demonstrated:
    
      2D
        single_double.c - buffers in OpenGL (motion)
                          (also multiple windows)
      3D
        split_cube.c    - speed control (motion)
        split_cube6.c   - speed control (motion)
        robot2.c        - connected limbs movement (manual motion)
        robot3.c        - connected limbs movement (data driven motion)
                 robot3 robot3.dat
        pilot.c         - game, exercise (motion)
        planets.c       - education, more on lighting later (motion)
        SphereMotion.java       - moving 3D lights (motion)
        trackball.c       - user control of view
        skyfly                  - game, training, demo (motion)
        draw3D1.java    - evolving 3D data entry (multiple windows)
                          threads, manual menu
        draw3D2.java    - evolving
                          solid and wireframe, flipping, read/write
        draw3D3.java    - evolving
        test.draw3d test data
        RunThread.java   Four windows, possible multi core
    
    
    
        four_windows.c  - display multiple windows in OpenGL four_windows.gif
    
    
    Techniques for developing interactive graphics applications
    
    robot.c  I considered not much to talk about robot.jpg
    dynamic.c A follow-on is some way, of robot.c was hard to read. dynamic.jpg
    robot2.c was an interesting exercise for me to develop. robot2.jpg
    
    My approach was to copy dynamic.c to robot2.c and make the following
    changes, in order, compiling (fixing) and running (fixing) each change.
    
    I could not see the lower leg from the upper leg, thus I changed the
    colors for various body parts. Since this was a 'lighting' scene,
    it was a matter of changing the emitted light to white and covering
    the various limbs with material of various colors.
    
    Now that I could see the motion better, I wanted to make the robot
    bend, not just turn. Yuk! The code used numbers, 1, 2, 3 ... rather
    than named numbers for the angles. Thus I went through and changed
    all references, menu, angle[?] and a few others to names, #define's.
    This really helped me understand the code because I had to look
    at every section.
    
    With menu and angles and rotations named, it was easy to add two
    menu items, one to increase motion per click, another to decrease
    motion per click.
    
    Now it was easy to add bend to the torso because I had seen that
    the head could both rotate and bend, just cut-and-paste with some
    name changing.
    
    When I lifted both legs, the robot did not lower itself, unreal.
    Thus I added keyboard function for 'x', 'X', 'y' and 'Y' so the
    robot could be moved.
    
    Future ideas are to "fix" the upper limbs, shoulder hip, to both
    rotate up and down and sideways like real limbs. Then add "hands"
    with some kind of grip. Texture map the face. Change cylinders
    to ellipsoids. Be able to read and save a script of a sequence
    of motions. Oh! But if I did that, students could not use it
    as a project. 
    
    P.S. somewhere along the way I added + and - so the "repeat" function
    of the keyboard would do what the mouse clicks would do, only faster.
    Thus there became a 'move' function, which now should be stripped
    of the cases and all of it executed every time.
    
    robot2.c is an example of why there are many lines in an
    interactive program. Much code is repeated yet is not suitable
    for putting in loops. I expect this program would become more
    unreadable and unmaintainable using loops.
    
    A possible project is to implement a "record" mode where a user
    moves the robots limbs to make the robot walk, run, dance, jump etc.
    Then a "play" mode where the robot performs the recorded motions.
    
    robot3.c Then, finally time to add data driven.
    
    A typical data structure for each move might have:
    sequence number
    delta time for move
    mode (just move, interpolate, repeat sequence)
    x coordinate
    y coordinate
    z coordinate
    number of joints to move
       joint angle
       joint angle
       ...
    
    or an optional repeat sequence
    sequence number
    delta time for move
    mode repeat sequence
    from sequence number
    to sequence number
    
    robot3.dat is my first implementation
    
    If the "record" kept an ASCII text file, the user could edit
    the action and potentially have a computer program generate
    the motions.
    
    User interface buttons similar to those found on VCR or DVD
    recorders would seem appropriate.
    
    The robot could be replaced by a more human figure, an animal
    or some pseudo figure like a car, truck or machine that could
    do non characteristic actions. e.g. cartoon characters.
    
    
    Double buffering in Java takes some effort. The code below
    shows a reasonably small example that could be copied if your
    project is in Java and has any fast moving objects.
    double_buffer.java
    Compile and run this program, click left mouse many times to
    get a very fast moving red ball. 
    
    
    
    An application of the above double_buffer.java is Springdb.java
    
    
    Professional movie makers use sophisticated software that has
    many motions preprogrammed. A technique for getting realistic
    motion is to dress a person in clothing that has colored dots
    placed at "control points" on the body. The person is then
    recorded doing the desired actions. The coordinates of the dots
    are extracted at each time step. The coordinates are then
    entered into a data file for future use in animating figures.
    The result is movies such as "Toy Story" , "Madagascar" and
    "Over the Hedge" to name just a few.
    
    

    Lecture 5, Menu Design and Implementation

    The "Menu Bar" and drop down menus are the most common today.
    
    You could do your own menus, yet you will probably want to use
    the large amount of code provided by a GUI tool kit.
    
    This lecture will cover the details often hidden by most GUI tool
    kits. You may need to understand how menus are created in case
    you have to work around a bug or problem in the tool kit you are using.
    
    The richest toolkit for menus is Motif. (Linux/Unix/macOS)
    Close behind is proprietary Microsoft Windows C++ classes.
    Next comes Java Swing/Swing2.
    The weakest we will look at is OpenGL with GLUT. Yet, strong by getting FLTK,
    the Fast Light ToolKit from www.fltk.org
    
    Defacto standardization makes some design issues obvious.
    The "File" is on the left of the "Menu Bar".
    The "Help" is on the right, or rightmost, of the "Menu Bar".
    
    Using defacto standard names helps average users.
    Using names that mean something to you are best for an application
    you write for your own use.
    
    Example programs to be covered are:
    
    In X Windows using Motif, observe windows, widgets and buttons
    being created, callbacks assigned and functions to handle callbacks.
    The executable is  w4 .
    w4a.c
    
    
    
    
    
    In OpenGL, a mouse click is used to popdown the menu.
    Note that OpenGL requires sub menus to be created before
    the main menu, the opposite order of Motif or Java.
    w4gl.c
    
    Not able to capture open menu and get graphic.
    
    In Java using Swing, observe menu creation then menu item creation,
    action listeners and functions to handle actions.
    W4frame.java
    
    
    
    For the more complex example, Spline Tutorial, download and
    compile: (note package myjava; and import myjava.*; fix to suit)
    I have this in my 'myjava' directory and use  java myjava.SplineFrame
    
    Note that other windows are opened for tutorial information.
    The 'parameter' pull down menu uses radio buttons.
    The mouse is used for both menu selection and graphics.
    
    Spline.java
    SplineFrame.java
    
    Then you need the *.txt files that are read at execution time:
    SplineHelp.txt
    SplineAbout.txt
    SplineAlgorithm.txt
    SplineEvaluate.txt
    SplineIntegrate.txt
    
    
    
    
    Clicking on menu bar 'Algorithm' (no 'File' items needed)
    
    
    
    Clicking on menu bar 'Help' (Note that pull down menu can go outside
                                 the main window in Java.)
    
    To run demo I have my flash drive in the USB port and do commands:
    F:
    setup      # runs setup.bat to set path and classpath
    cd myjava  # where this demo is located
    java myjava.SplineFrame  # I used 'package'
    
    
    The Lecture outline was:
    Show demo's.
    Quickly survey code.
    Explain how menubar or other features are created.
    Explain how menus are created in menubars.
    Explain how menu items are created in menus.
    Explain how callbacks are coded to act when a menu item is selected.
    Show where to put code that responds to a menu item select.
       Can be in-line code if short and simple.
       Use function call to handle long or complex actions.
    Very repetitive, much to remember, copy, cut and paste to suit.
    
    HW2 is assigned
    

    Lecture 6, Getting user input

    In GUI applications, the code to get user input is much more
    complex than the code for a command line program.
    
    Much user input is via the mouse, button press or motion.
    Some user input is from the keyboard.
    
    You have the power to really mess up the user.
    Make the user click the mouse then type on the keyboard then
    click the mouse then type on the keyboard then click the
    mouse then type on the keyboard, etc. etc. etc.
    
    A user friendly interface has menus, buttons, graphics, etc
    to allow the user many steps with the mouse before touching
    the keyboard. Then when the keyboard is needed, allow the user
    to perform many steps before having to go back to the mouse.
    
    Mouse button press input in examples:
    w2.c  X Windows
    
    w2gl.c  OpenGL
    
    W2frame.java  Java
    
    Getting input data, text, into a graphical user interface program
    is much more difficult. The input of numbers is accomplished by
    inputting a character string and converting the character string
    to a number inside the program.
    
    The X Windows Motif program w5a has one pull-down menu on the menu bar,
    "Set Values". On the pull-down there are five menu items:
      "Number"
      "View Angle"
      "Name"
      "Apply"
      "Quit"
    
    The selecting one of the first three causes a popup dialog box to
    appear. The dialog box is where the user enters the data.
    
    
    
    
    
    
    
    
    The source code is:
    w5a.c  X Windows
    w5.h 
    
    In OpenGL and GLUT I wrote my own data entry in fixed windows.
    These could be made into separate windows and could be
    selected by a menu.
    test_text_in.c  OpenGL
    demo_text_in.c
    text_in.h
    text_in.c
    
    Now, add a popup dialog window for user data entry.
    w5gl.c
    
    
    The Java implementation is the shortest.
    Similar "toolkit" classes should be available for
    Microsoft C++ and C#.
    
    W5frame.java  Java
    
    
    
    
    
    
    
    
    Another simple screen input/output Java program is Fahrenheit.java
    
    
    For games or interactive keyboard use, you will need a key listener.
    The events are key pressed, key typed, and key released.
    You probably only want key released and a switch on "keyCode"
    TestKeyCode.java
    with output for key sequence  a A 0 space right left up down ctrl enter 
    TestKeyCode.out
    
    In Python, to get keysyms, catch an event:
    test_keysym.py
    test_keysym_py.out
    
    
    When you can input text, a character string, then you can
    use your programming language to open and read and write files.
    You can get numeric data when needed but do not use this as
    a substitute for mouse input for numeric data,
    with possible use a grid for accuracy.
    
    A sample Java Swing  File-Open  then select a file is:
    W4frame.java  that uses
    ExampleFileFilter.java
    
    A crude sample of reading a directory in C is dirprt.c
    This could be used in an OpenGL application with a display of the
    file names, selectable by using the mouse. Basically, a do-it-yourself
    file open dialog box.
    
    The File-open is handled by a widget in Motif as shown in
    the callback function DoOpen XmOpen.c
    
    

    Lecture 7, Lighting in 3D

    Chapter 6 of our Textbook: Interactive Computer Graphics, gives the
    definitions and equations for doing lighting in any language on
    any graphics platform. Programming these yourself is often a project
    in CMSC 435, Computer Graphics. Many graphics toolkits implement
    the lighting models for reasonably convenient use.
    
    The physics:
      Light is electro magnetic radiation. Each color has a wavelength.
      We are interested in the visible spectrum between infrared
      and ultraviolet. From long ago, Roy G Biv, Red, orange, yellow,
      Green, Blue, indigo, violet. RGB are the electronic primary colors.
      The human eye can detect the intensity and wavelength of light.
    
      White light is all colors, black is no colors.
      In ambient white light, an object looks red because the object
      is reflecting light with wavelengths near red and absorbing light
      at other wavelengths
    
    Graphics definitions:
      Ambient light: comes from no specific source, exists in all directions.
      Diffuse light: has a point source, strikes the surface of an object at
                     some angle, reflects or is absorbed by an object, the 
                     amount of reflected light depends on the incident angle
                     and the normal to the surface.
      Specular reflection: comes from point source light reflected to a pixel
                           based on the angle of incidence and angle of
                           reflection, and takes into account the shininess
                           of an object. This produces a highlight or bright spot.
    
      An object is said to have a surface material and that material can
      have Ambient, Diffuse and Specular properties (for each primary color).
    
    Example programs covered: (execute and observe lighting)
    planets.c
    SphereMotion.java
    SphereMotion.jpg
    SphereMotion.html
    teapots.c
    teapots.jpg
    
    The lighting environment is the physical objects in the truncated
    tetrahedron plus the light(s) that may be outside this volume.
    (also see textbook  5.5)
    
    
    
    The components of light that the user sees is intensity, I, of
    the primary colors RGB.
      Irgb = Iambient + Idiffuse + Ispecular   [clamped to 1.0 maximum each color]
    (see text book 6.1-6.5)
    
    The intensity of a pixel on the display is computed independently
    for each primary color. Each intensity is the result of light on
    the material of the object being reflected to the pixel on the
    display screen. For the following we assume the material on the
    object has been defined to provide the reflectivity of each primary
    color for ambient reflection, diffuse reflection, specular reflection
    and shininess. We assume that ambient light has been defined with
    the amount of light for each primary color. We assume that one or more
    point lights have been defined at some position with the amount of
    light for each primary color. All lights and reflectivities are
    assumed converted to the range 0.0 to 1.0. Any undefined value is
    considered to be 0.0.
    
    The intensity for each color is computer by the formulas:
    
     Iambient = Kambient * Lambient 
    
                Kambient is the materials reflectivity to each color
                Lambient is the amount of ambient light for each color
    
     Idiffuse = Kdiffuse (Lvector dot Nvector) Ldiffuse
    
                Kdiffuse is the materials reflectivity to each color
                Ldiffuse is the amount of one point light for each color
                Lvector is the vector from the point light to the surface
                Nvector is the normal vector at the surface
                the dot product computes the cosine of the angle between vectors
    
     Ispectral = Kspecular (Rvector dot Vvector)^alpha  Lspecular
    
                Kspecular is the materials reflectivity to each color
                Lspecular is the amount of one point light for each color
                alpha is the exponent of the dot product, typically 20 to 100
                alpha can be derived from the amount of shininess of the object
                Rvector is the reflection vector
                Vvector is the vector to the eye
                (actual computation uses a transformation, Hvector)
    
    
    A few examples:
      red light amount   red reflectivity    result intensity
            0.0              0.0                 0.0
            0.0              1.0                 0.0
            1.0              0.0                 0.0
            1.0              1.0                 1.0
            0.5              0.5                 0.25
    
       1.00^50 = 1.0
       0.99^20 = 0.8     alpha = 20  at angle T, 0.99 = cos(T)
       0.95^20 = 0.35
       0.99^50 = 0.6     alpha = 50
       0.95^50 = 0.076
    
    teapots  includes both lighting and texturing, which
    are both closely related to how people interpret,
    visualize,  the display of graphical objects.
    Texturing is covered more in the next lecture.
    
    light_dat.c
    light_dat2.c show faces
    light_dat3.c show vertices
    datread.c  reads .dat and .det files
    datread.h
    drop.dat Utah .dat or .det formats
    skull.dat example
    skull.jpg rendered as brass
    bull.dat example  many vertices, surfaces
    bull.jpg rendered as brass
    
    
    There are many 3D graphical images available from the Utah project(s).
    The  .det  format uses binary IEEE floating point and binary "C"
    integers for fast input. The  .dat  format is exactly the same
    numeric values encoded as ASCII text readable by "C" fscanf or
    equivalent.
    
    When you can see the object on the screen with lighting,
    there has been a z-plane rendering or ray trace rendering
    to convert the vertices and faces to a smooth looking object.
    
    planets.c Lighted extension of planet.c
    This demonstrates putting a light inside an object to give somewhat an
    illusion of a glowing object.
    
    Compare above to planet.c
     
    

    Lecture 8, Texture Mapping in 3D

    Texture mapping and bump mapping are computer techniques to make
    images seem more realistic to observers. There is not enough
    computer power to model a wall in a house, with its irregularities
    and discolorizations, to make it appear "real" on a computer screen.
    Thus, the technique of texture mapping or bump mapping is applied
    to the graphics rendering of the wall to make it look more realistic.
    
    Examples include:
    earth.c
    readtex.c
    earth_small.rgb a binary file
    
    The earth_small is stored as a flat 2D colored image is wrapped around
    a sphere using texture mapping.
    
    checker.c
    An internally computer checker board pattern is texture mapped onto
    a cube and the cube is shown from two views.
    
    
    
    
    
    teapots.c
    teapots.jpg
    
    teapots  includes both lighting and texturing, which
    are both closely related to how people interpret,
    visualize,  the display of graphical objects.
    
    Some times you may need terrain or a forest.
    See the skyfly subdirectory on the distributed CD. The authors
    created a file with the terrain of mountains and valleys.
    
    Some scenes are best created using fractals. An example of
    one tree, one of many shapes based on numeric parameters:
    
    fractal.c  X Windows
    fractalgl.c  OpenGL
    Fractal.java  Java
    
    The above can be used with a random number generator on position
    and parameters to compute a forest background.
    
    Other technoques that can create interesting designs are
    from chaos theory.
    
    chaos1.c  OpenGL version
    
    
    
    Mr. Voronoi has an interesting way of coloring the closest:
    
    voronoi.c  OpenGL version
    
    
    
    

    Lecture 9, review 1

    Cover some loose ends.
    Get your term project discussed. Start your project!
    Review lectures and homework.
    
    Quiz 1 will be: Open Book, Open Note, Open Computer.
           (You may bring your own laptop)
           (Not the "Study Guide" or copies thereof.)
    
    Some questions on concepts. e.g. mouse events, keyboard events, color,
                                rendering, lighting
    
    Some questions on code. Based on code displayed on course WEB pages.
    
    Questions on color, know the following:
    Primary colors for pigment paint, water and oil, are Red, Blue, Yellow.
    These are subtractive colors applied to a white background.
    
    Primary colors for computer displays are Red, Green, Blue.
    These are additive colors, each may be 0.0 to 1.0 floating point,
    or 0 to 255 integer, typically an 8 bit byte.
    RGB 0,0,0 is black,  255,255,255 is white, 255,0,0 is red
    
    
    Primary colors for color printers are Cyan, Magenta, Yellow.
    These are subtractive colors applied to a white background.
    There is also typically Black.
    
    Color TV uses a very different method, YIQ that has
    intensity Y, and uses phase angle IQ for color.
    Not all RGB colors can be converted to YIQ.
    
    An RGB image can be shown as gray scale, 0.0 to 1.0,
    using 0.299 *R + 0.587 *G + 0.114 *B
    
    A fourth byte may be used to get 32 bit color, RGBA,
    the A is alpha, 0 is transparent, 255 is opaque,
    128 or 0.5 allows some of another image to come through.
    
    Toolkits such as OpenGL with GLUT are available on
    all operating systems.
    Graphics in Java, Python and other languages are
    very portable to all operating systems.
    
    Motif is specific to systems with XWindows being
    available, including all versions of Unix, Linux, MacOSX.
    
    No Email or instant messaging during the exam.
    
    The exam has not been written, thus number of questions unknown,
    type of questions unknown. (Typically 40 to 50 questions, many
    multiple choice.)
    
    
    

    Lecture 10, Quiz 1

    Based on Lectures 1 through 9.
    Based on completed Homework.
    See Review 1 for more information
    
    

    Lecture 11, Painters Algorithm, Selecting Objects

    Simply stated, "The Painters Algorithm" draws the farthest away objects first.
    More technically, the farthest away front facing surface is rendered first.
    At an even more detailed level consider the individual pixel that
    is farthest away drawn to the display first, then the next closest, etc.
    
    In a two dimensional object oriented GUI program, the objects are
    typically pointed to by a linked list.  This is typically called
    the display list. If two objects overlap, the object later on the
    linked list is drawn over the object earlier on the linked list.
    
    A typical user menu item is "move to front", that is easily
    implemented by unlinking the object from its present position and
    relinking the object at the end of the linked list. "move behind" would
    unlink the object and relink the object on the front of the linked list.
    
    
    One 3D implementation works from a different concept.
    The basic Z plane algorithm allows objects and surfaces of objects
    to be rendered in any order. Each pixel is recorded with RGBA and
    the Z coordinate. When a pixel is about to be rendered, the Z coordinate
    of the new pixel is compared to the existing Z coordinate. The pixel is
    replaced only if the new pixel is closer to the viewer, e.g. has a
    larger Z coordinate.
    
    In OpenGL:
    
    A simple program that you must edit to change 3D objects is
    object.c
    
    A more complete program to display the wireframe objects that
    are in GLU and GLUT is objects.c
    
    You have control of where the eye is positioned and where the eye
    is looking, six degrees of freedom.
    
    Note that for every wire frame you can render the object as a
    solid object. Solid objects look best when rendered with lighting.
    Hopefully the objects can produce normal vectors so that smooth
    shading can be computed.
    
    Consider the problem of having the user select an object with
    the mouse. What the user will do with the selected object depends
    on the application.
    
    In the 2D world a given screen i,j coordinate may be over no object,
    one object or many objects. When the user attempts to select an
    object the user must be given a visual clue to know which object
    (or point) was selected. The visual clue may be a color or intensity
    change, outline, bounding markers, etc.
    
    A poor example pick.c, needs to be run.
    A better example pick2.c, needs to be run.
    
    A java AWT version Select.java, needs to be run.
    A java swing version Select2.java, needs to be run.
     
    A simpler example is rubber2gl.c, needs to be run.
    
    In order for a user to pick one object out of overlapping objects,
    the user is given the "front" object. If this is not the desired
    object, the user moves this object to the back and re-selects.
    
    Example: draw program.
    
    In 3D it is more complex and the user may have to be given controls
    to rotate the object, as you might turn it in your hand, to see
    a specific place unambiguously. Eventually the user is just selecting
    an i,j coordinate on the display screen. To get back to find the
    object or specific vertex in world coordinates, the program has to
    "un-project". That is, go from screen coordinates back to world
    coordinates.
    
    The following sequence of programs shows the development of
    selecting a specific vertex in 3D world coordinates from a mouse click.
    
    unproject.c OpenGL color change
    
    unproject2.c extensions to find distance to vertex
    
    
    A possible project is editing 3D objects found in existing files.
    Applying 3D unproject to modify 3D images is difficult. It would
    probably be applied to the wireframe view.
    
    light_dat2.c application to Utah files
    datread.c for read and write of Utah files
    datread.h for read and write of Utah files
    on cube.dat, drop.dat,
    skull.dat, bull.dat
    
    Choices used for this program:
    1) automatic scaling of input
    2) user option of solid, wire frame or just vertices
    3) left to a next version for moving vertices and outputting.
       (the code to output the data structure to a file is included)
       left to the next version for coloring in the Z direction.
       left to the next version for only displaying front half vertices
    
    The next version highlights the selected object.
    (reading and writing the .dat file are now in datread.h, datread.c )
    Keyboard 's' writes changed object when second file name is selected.
    Trimming approximately the back half of the points, 't', was added.
    The changing of the object has not been coded in this version. Future
    mouse actions would do this.
    
    light_dat3.c application to Utah files
    datread.c for read and write of Utah files
    datread.h for read and write of Utah files
    on cube.dat, drop.dat,
    skull.dat, bull.dat pot7.dat
    
    mandelbrotgl.c Traditional Mandelbrot with
    user selected point to zoom in. Watch "size" at about 10^-15 the floating
    point computation collapses and color becomes constant.
    
    

    Lecture 12, Pan and Zoom, Scroll Bars

    "Pan" means move the viewport left, right, up, or down. The image
    stays in the same place in world coordinates.
    
    "Zoom" in or out by moving the viewer closer to, or farther from the
    object or scene. The object or scene stays in the same place in world
    coordinates.
    
    The implementations vary depending on the toolkit being used.
    The basic user interface is usually called a "slider". The user
    places the mouse on the slide bar and drags the slide bar to
    get the desired movement (pan, zoom, scroll, etc).
    
    The GUI programmer must keep the object or scene world coordinates
    unmoved and compute the new display requested by the user.
    
    The Motif toolkit provides an option when a drawing area is created
    to add horizontal and/or vertical scroll bars. When the user changes
    the position of the slider in the scroll bar, the program gets an
    event and receives a value that indicates the latest position of
    the slide bar. The program must compute the display based on the input.
    The computation is not automatic. Java provides a slider that can
    be used for a scroll bar. OpenGL can be programmed to display and sense
    the position of a slider.
    
    The "look and feel" of Motif scroll bars and zoom slider are shown
    in the following screen capture. The user drawing area is empty.
    
    
    
    draw_gui.c Motif window setup, big!
    
    
    Assume the values are from 'smin' to 'smax' on all the slide bars with
    the user placing the slide bar at 'spos'. The actual values of 'smin'
    and 'smax' are usually settable by the application program.
    
    
    Consider some point in 2D world coordinates  x,y  that is mapped to
    screen pixel coordinates i,j by:
       i = a*x + b*y + c  (any complex mapping could be reduced to
       j = d*x + e*y + f   the six values a, b, c, d, e, and f)
    
    This would be the nominal with all slide bars centered.
    Assume all quantities floating point even though pixel coordinates
    must eventually rounded to integers (or the intensity of the pixel
    is computed based on the pixel coordinates).
    
    
    The case where the user indicates scroll left, assume 'spos' as a value,
    would result in:
    
        new_i = i + (width*(spos-smin)/(smax-smin)-width/2)
    
    More scrolling can be provided by an additional multiplicative constant
    times the width. Generally there must be a fixed limit to how far the
    user can scroll. Using this simple equation gives the user a double width
    working area. To get a four width and height working area:
    
      new_i = i + 2 * (width*(sposx-sminx)/(smaxx-sminx)-width/2)
      new_j = j + 2 * (height*(sposy-sminy)/(smaxy-sminy)-height/2)
    
    The case where the user can zoom in to see a larger version of
    a smaller part of the working area, assume 'smin', 'smax' and 'spos'
    are the slider values and the zoom factor is to be from 'zmin' to 'zmax'.
    (you must limit both largest and smallest zoom, always positive)
    
    The 'zval' zoom value is then:
    
      zval = (zmax-zmin)*(spos-smin)/(smax-smin)+zmin
    
      new_new_i = (new_i-width/2) *zval + width/2
      new_new_j = (new_j-height/2)*zval + height/2
    
    Note: In order to zoom, the i,j is translated to the center of
    the screen, scaled, then translated back. If this is not performed,
    then the zooming would also move the screen up and to the left.
    
    The simple equations shown above become much more complex in 3D.
    Yet, with a graphics tool kit, it reduces to the following:
      To scroll left, move the position of the eye left while keeping
      the direction vector unchanged.
      To zoom in, move the eye closer to the object or scene.
    The next lecture will cover the perspective and model transformations
    in more detail, but for now it is sufficient to know that there
    are two distinct transformations to get a point on a object in
    world coordinates onto the display screen.
    
    There is a perspective matrix that implements the frustum shown
    in a previous lecture. This matrix is based on the location of the
    eye relative to the scene, the direction the eye is looking, the
    field of view, angle, the eye is viewing. The pan and zoom can
    be accomplished in this matrix.
    
    The model matrix implements the rotations, scaling and translations
    of world coordinates into how the user views the scene. This does
    not need to change with pan and zoom.
    
    The scene itself is constructed in world coordinates. Any units of
    measure may be used as long as all distances are in the same units.
    e.g. microns, feet, kilometers, etc.
    
    The example pilot.c is the basic
    demonstration of moving the eye, pilot in this case, through all
    six degrees of freedom. X, Y, Z, roll, pitch, heading.
    Typically users are not given roll, pitch and heading so that
    the horizontal scroll is X, the vertical scroll is Y and zoom is Z.
    
    The Java program PaletteFrame.java calls
    MyColorChooser.java that uses JSliders and looks like the image below.
    
    
    
    ScrollDemo2.java looks like the image below.
    
    Java automatic pop-into-existance scroll bars is demonstrated by
    ScrollDemo2.java looks like the image below.
    I personally prefer the scroll bars to be displayed all the time.
    It is distracting to me when widgets such as scroll bars pop into
    existance then pop out of existance.
    
    
    
    

    Lecture 13, Text Sizes and Fonts

    Text size is measured in "points".
    One "point" is 1/72 of an inch.
    Thus text drawn at 72pt would be about one inch high.
    (On paper!, it may be almost any size on a computer screen.)
    
    On a computer screen, a 5 by 7 size means each letter of text
    fits in a box:  5 pixels wide by 7 pixels high.
    
    Text such as lower case letters 'p' and 'q' extend below
    the baseline for placing text. Upper case letters and language
    marks may extend above the normal character height.
    A letter or symbol in a font is called a glyph.
    
    The bad news about fonts is that they require a lot of work
    to create and thus are almost always copyrighted.
    
    The good news is that your computer probably has many fonts available
    for your program to use.
    
    Fonts may have casual names such as Times Roman 12pt or
    Courier 10pt. The "official" computer name is presented later.
    
    Fonts may have proportional spacing, e.g. Times Roman,
    where 'm' takes more space than 'i', and additionally
    may be rendered using kerning that may place "AT" closer
    together than 'A' 'T'.
    
    Fonts may have fixed spacing, e.g. Courier, where every letter,
    glyph, takes the same width.
    
    Most people prefer proportional kerned spacing when reading
    a newspaper or book, yet looking at computer source code
    most prefer fixed width spacing.
    
    TestFonts.java shows Courier New and Times New Roman
    
    
    
    and writes out the available fonts TestFonts.outs
    
    If you application needs the user to select a font, a style and a size,
    then a Font Selection Box may be the most user friendly. Below is the
    Word Perfect and Microsoft Word font selection windows.
    
    
    
    
    
    Using X Windows you can experiment with creating or modifying
    a font using the X Font Editor, xfed.c
    on font timr24.bdf or font courr24.bdf
    "bdf" indicates Berkeley Distribution Font IIRC.
    Note the line starting "FONT" that has the official name of the font.
    Fonts are registered so that every font has a unique official
    designation.
    
    To find the fonts available on your X Windows system:
    In X Windows use font_list.c and
    font_show.c
    Note the font designation format in these two programs.
    
    font_list.out shows over 500 fonts
    on one system where font_list.c was run.
    
    On Microsoft Windows, the most common font format is True Type Font.
    In C:\  the command    dir /s *.ttf    will show the available fonts.
    An example of one PC shows over 1300 font files, yet there is a
    lot of duplication in the 92MB of disk space used. pc_ttf.fonts
    
    There are a number of programs for converting from one font format
    to another font format. ttf2pt1 is one example.
    
    Windows-based applications can use three different kinds of font technologies
    to display and print text: raster, vector, and TrueType. 
                               ------  ------      --------
    
    The differences between these fonts reflect the way that the glyph for
    each character or symbol is stored in the respective font file.
    
    In raster fonts, a glyph is a bitmap that application programs
    use to draw a single character or symbol in the font. 
    
    In vector fonts, a glyph is a collection of line endpoints that define
    the line segments that application programs  use to draw a character
    or symbol in the font.
    
    In TrueType fonts, a glyph is a collection of line and curve commands
    as well as a collection of hints. The line and curve commands are used
    to define the outline of the bitmap for a character or symbol in the
    TrueType font. The hints are used to adjust the length of the lines and
    shapes of the curves used to draw the character or symbol. These hints and
    the respective adjustments are based on the amount of scaling used to reduce
    or increase the size of the glyph.
    
    Because the bitmaps for each glyph in a raster font are designed for a specific
    resolution of device, raster fonts are generally considered to be device
    dependent. Vector fonts, on the other hand, are not device dependent, because
    each glyph is stored as a collection of scalable lines. However, vector fonts
    are generally drawn more slowly than raster or TrueType fonts. TrueType fonts
    provide both relatively fast drawing speed and true device independence. By
    using the hints associated with a glyph, a developer can scale the characters
    from a TrueType font up or down and still maintain their original shape. As
    previously mentioned, the glyphs for a font are stored in a font file.
    
    For raster and vector fonts, the font data is divided into two
    parts: a header describing the font's metrics and the glyph data. A
    font file for a raster or vector font is identified by the .FON
    filename extension. For TrueType fonts, there are two files for each font.
    The first file contains a relatively short header and the second contains
    the actual font data. The first file is identified by a .FOT extension
    and the second is identified by a .TTF extension.
    
    The OpenType font format is an extension of the TrueType font format,
    adding support for PostScript font data. The OpenType font format was
    developed jointly by Microsoft and Adobe. OpenType fonts and the operating
    system services which support OpenType fonts provide users with a simple
    way to install and use fonts, whether the fonts contain TrueType outlines
    or CFF (PostScript) outlines.
    
    The OpenType font format addresses the following goals:
      broader multi-platform support
      better support for international character sets
      better protection for font data
      smaller file sizes to make font distribution more efficient
      broader support for advanced typographic control
      
    OpenType fonts are also referred to as TrueType Open v.2.0 fonts, because they
    use the TrueType 'sfnt' font file format. PostScript data included in OpenType
    fonts may be directly rasterized or converted to the TrueType outline format
    for rendering, depending on which rasterizers have been installed in the host
    operating system. But the user model is the same: OpenType fonts just work.
    Users will not need to be aware of the type of outline data in OpenType fonts.
    And font creators can use whichever outline format they feel provides the best
    set of features for their work, without worrying about limiting a font's
    usability
    
    OpenType fonts can include the OpenType Layout tables, which allow font
    creators to design better international and high-end typographic fonts.
    The OpenType Layout tables contain information on glyph substitution, glyph
    positioning, justification, and baseline positioning, enabling text processing
    applications to improve text layout.
    
    As with TrueType fonts, OpenType fonts allow the handling of large glyph sets
    using Unicode encoding. Such encoding allows broad international support,
    as well as support for typographic glyph variants.
    
    
    In OpenGL using GLUT the following bitmap fonts are available:
      GLUT_BITMAP_HELVETICA_10
      GLUT_BITMAP_HELVETICA_12
      GLUT_BITMAP_HELVETICA_18
      GLUT_BITMAP_TIMES_ROMAN_10
      GLUT_BITMAP_TIMES_ROMAN_24
      GLUT_BITMAP_9_BY_15
      GLUT_BITMAP_8_BY_13
    
    Bitmap fonts do not move with the scene and do not scale
    when the window size changes.
    
    These are rendered using code such as 'show_text' from
    text_in.c
    
    void show_text(GLfloat x, GLfloat y, char msg[])
    {
      int len, i;
    
      glPushMatrix();
        glRasterPos2f(x, y);
        len = strlen(msg);
        for (i = 0; i<len; i++)
          glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, msg[i]);
      glPopMatrix();
    } /* end show_text */
    
    Then in 'display' set the color or material and render the text:
    
      glLoadIdentity();
      glColor3f(0.0, 0.0, 0.0); /* black */
      show_text(-0.5, -1.0, "user input, file name");
    
    If you do not see your text:
    If using lighting, be sure material is applied to the text.
    If using lighting, be sure the 'Z' coordinate is correct to
    receive the light on the front of the text.
    In various perspective views, it may be hard to figure out
    where to place the text. One extreme measure is to use
    the second projection as in:
    
    static void drawText(int x, int y, char * msg)
    {
      int   i, len;
    
      glMatrixMode(GL_PROJECTION);
      glPushMatrix();
        glLoadIdentity();
        glOrtho(0, winWidth, 0, winHeight, -1, 1);
        glMatrixMode(GL_MODELVIEW);
        glPushMatrix();
          glLoadIdentity();
          glColor3f(1.0f, 1.0f, 0.0f);
          glRasterPos2i(x, y);
          len = strlen(msg);
          for (i=0; i<len; i++)
            glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, msg[i]);
        glPopMatrix();
      glPopMatrix();
    }
    
    In OpenGL there are stroke fonts that move with objects and
    scale when the window size changes. These fonts include:
    
      GLUT_STROKE_ROMAN
      GLUT_STROKE_MONO_ROMAN
    
    static void drawText(GLfloat x, GLfloat y, char text[])
    {
      char *p;
    
      glPushMatrix();
        glLoadIdentity();
        glTranslatef(x, y, 0.0);
        glScalef(0.01, 0.01, 0.0); /* 0.1 to 0.001 as required */
        for(p=text; *p; p++)
          glutStrokeCharacter(GLUT_STROKE_ROMAN, *p);
      glPopMatrix();
    }
    
    Then in 'display' call the 'drawText' function using:
    
      glLoadIdentity ();
      glEnable(GL_LINE_SMOOTH);
      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
      glEnable(GL_BLEND);
      glLineWidth(1.0);
      /* glColor3f or material set here */
      drawText(3.0, 3.0, "Roman_stroke");
      glLineWidth(2.0);
      drawText(2.0, 6.0, "width 2 Roman_stroke");
    
    
    What can happen if your GUI program is executed on a system different
    from the development system?  Assuming the program runs and uses some
    neat fonts, what can happen?  Well two common approaches are to just
    show a blob if a font is not available on the users system or choose
    a default font to try to give the user a workable system. Note that
    fonts are typically installed on a specific computer. Not all users
    have large numbers of fonts.  Some GUI applications carry along
    their own set of fonts, as was shown  pc_ttf.fonts
    in various directories.
    
    

    Lecture 14, Perspective Viewing

    Perspective Viewing, Resize Choices and Transformation Matrices.
    This lecture covers the technical details and mathematics that
    makes a 2D screen look like a 3D scene.
    
    In the simplest case, computing the i,j screen position of
    a vertex at world coordinates x,y,z is accomplished by
    multiplying a 4 by 4 perspective matrix by a 4 by 4 model matrix
    times the x,y,z,w vertex vector, then placing the i,j in
    the viewport.
    
    
    
    Shows the frustum that contains the 3D "World" that is to be
    presented to the user. Any objects with more positive Z than "near"
    are clipped, any objects with more negative values of Z than "far"
    are clipped. Any objects outside of the X or Y of the frustum
    are clipped. The positive Z axis is considered to come
    out of the screen toward the viewer.
    
    Name the vertices on the diagram as:
    On the 'near' rectangle, the lower left is  'xmin' 'ymin'
                             the upper left is  'xmin' 'ymax'
                             the lower right is 'xmax' 'ymin'
                             the upper right is 'xmax' 'ymax'
    The distance from the eye to near is 'near' a positive number
    The distance from the eye to far  is 'far'  a positive number
    
    The 4 by 4 perspective matrix is
    
    
    |2*near/(xmax-xmin)  0.0          (xmax+xmin)/(xmax-xmin)         0.0         |
    |                                                                             |
    |      0.0    2*near/(ymax-ymin)  (ymax+ymin)/(ymax-ymin)         0.0         |
    |                                                                             |
    |      0.0           0.0        -(far+near)/(far-near)  -2*far*near/(far-near)|
    |                                                                             |
    |      0.0           0.0                -1.0                      0.0         |
    
    The OpenGL call to create this perspective matrix is:
    
       glFrustum(xmin, xmax, ymin, ymax, near, far);
    
    An alternate call uses the vertical the eye position, looking at
    the center of interest, + on 'far', and Y up=1, X up=0, Z up=0 is:
    
       gluLookAt(eyex, eyey, eyez, coix, coiy, coiz, Xup, Yup, Zup);
    
    Yet another alternative using the angle, field of view, and
    w/h aspect ratio is:
    
       gluPerspective(angle, w/h, near, far);
    
    The model view matrix begins as the identity matrix and is multiplied
    by the users rotations, scaling and translations. The world coordinates
    may be in any system of physical units, yet all coordinates must
    be in the same units.  The six degrees of freedom for a solid 3D object
    are to to translate in three dimensions and rotate about three axis.
    
    The translation matrix to translate 0,0,0 to x,y,z is
    | 1.0  0.0  0.0   x  |
    | 0.0  1.0  0.0   y  |    unused translations are 0.0
    | 0.0  0.0  1.0   z  |
    | 0.0  0.0  0.0  1.0 |
    
      glTranslatef(x, y, z); 
    
    
    The scaling matrix to scale x by sx, y by sy and z by sz is
    |  sx  0.0  0.0  0.0 |
    | 0.0   sy  0.0  0.0 |    unused scales are 1.0
    | 0.0  0.0   sz  0.0 |
    | 0.0  0.0  0.0  1.0 |
    
      glScalef(sx, sy, sz);
    
    
    The rotation matrix by angle a about the X axis is
    | 1.0    0.0    0.0     0.0 |
    | 0.0    cos a  -sin a  0.0 |
    | 0.0    sin a  cos a   0.0 |
    | 0.0    0.0    0.0     1.0 |
    
      glRotatef(a, 1.0, 0.0, 0.0);
    
    
    The rotation matrix by angle a about the Y axis is
    | cos a   0.0    sin a  0.0 |
    | 0.0     1.0    0.0    0.0 |
    | -sin a  0.0    cos a  0.0 |
    | 0.0     0.0    0.0    1.0 |
    
      glRotatef(a, 0.0, 1.0, 0.0);
    
    
    The rotation matrix by angle a about the Z axis is
    | cos a  -sin a  0.0    0.0 |
    | sin a  cos a   0.0    0.0 |
    | 0.0    0.0     1.0    0.0 |
    | 0.0    0.0     0.0    1.0 |
    
      glRotatef(a, 0.0, 0.0, 1.0);
    
    
    A user world coordinate vertex p = x, y, z, w  (w=1.0)
    is transformed into  pp  by
    
    perspective matrix times model view matrix times p is pp
    
    To get screen coordinates, given the screen width w, and
    screen height h,
    
    screen x = w * ((pp.x/pp.z)-xmin)/(xmax-xmin)
    screen y = h * ((pp.y/pp.z)-ymin)/(ymax-ymin)
    
    Trying to check that the equations are correct,
    the program demo_mat.c writes out OpenGL matrices.
    The output is demo_mat.out
    
    The equations are coded in check_mat.c
    The output is check_mat.out
    
    It seems that OpenGL stores the matrix column major (Fortran style)
    while the "C" program stores the matrix row major, causing the
    printout to appear to be the transpose.
    
    The same geometry and same data were used in both programs.
    The final result from both is essentially the same.
    
    output from demo_mat.c OpenGL
    
     0.5, 1.5, 2.5 at win x=25.798641, y=345.927915, z=0.827098
    
    
    output from check_mat.c 
    
      x scr, y scr=25.798841, 345.927778  at relative z=0.827098)
    width, height =300.000000, 400.000000 
    
    
    In OpenGL or equivalently in your code, you can save the present matrix
    and start with a new identity matrix, do transformations, cause actions,
    then revert back the the prior matrix.
    
      glPushMatrix();
        glLoadIdentity();
        glRotatef(theta[0], 1.0, 0.0, 0.0);
        glRotatef(theta[1], 0.0, 1.0, 0.0);
        glRotatef(theta[2], 0.0, 0.0, 1.0);
        glTranslatef(pos[0], pos[1], pos[2]);
        /* use the Model view matrix to do something */
      glPopMatrix();
    
    
      /* a possible Reshape, it happens on first expose and every change */
      glViewport(0, 0, w, h);
    
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      if(w <= h)  /* e.g size = 2.0, x in -2.0 .. 2.0 */
        glOrtho(-size, size, /* xmin, xmax */
                -size*(GLfloat)h/(GLfloat)w, size*(GLfloat)h/(GLfloat)w,
                                              /* ymin, ymax */
                -10.0, 10.0); /* near in real Z value, far as real Z value */
      else
          glOrtho(-size*(GLfloat)w/(GLfloat)h, size*(GLfloat)w/(GLfloat)h,
                  -size, size, /* Y is size, w/h for X */
                  -10.0, 10.0);
    
      glMatrixMode(GL_MODELVIEW);
      glLoadIdentity();
      /* go do Display or something */  
    
    
    
    
    The simplest equations for orthographic projection are given by:
    Xs, Ys are 2D screen coordinates. Assume 0,0 at lower left.
    X,Y,Z are 3D world coordinates. Assume 0,0,0 at lower left.
    
      Xs = X + cos(theta)*Z
      Ys = Y + sin(theta)*Z
    
    Scaling and offsets may be provided as required.
    Theta is the angle up from the Xp axis to the where the 3D Z axis is drawn
    
    Doing your own 3D projection may be easiest as orthographic.
    For example, in this simple 3D shape entry program, the entry is
    in XY (front view), XZ (top view), or YZ (side view) plane then
    shown in three views and as orthographic.
    
    The source is draw3D3.java
    
    with output:
    
    
    
    

    Lecture 15, Capturing Screen

    
    The Java 3D code SphereMotion.java
    keeps moving. Yet, it can be captured, as seen by the file
    SphereMotion.jpg
    
    
    
    Note that the red and green dots are not planets but are the
    position of the lights that are moving.
    
    
    The method of capturing using external tools is operating system
    dependent. There are many tools and methods for every operating
    system, only one method is presented for each operating system.
    
    On Microsoft Windows I make the window to be captured active by
    clicking in the blue bar at the top of the window. Then I press
    and hold the "alt" key while pressing and releasing the
    "print scr" key. This captures the active window in the Microsoft
    cut-and-paste buffer.
    
    Now I execute PaintShopPro and click on the "edit" menu and drag
    to "paste as new image" then release. At this point I may change
    the size of the image or crop to a selected area or make other
    modifications. To save the, possibly modified, image I use
    "save as" and select the saved format, e.g. .jpg, .gif or other.
    Then select the directory where the image is to be saved and
    save the file.
    
    On X Windows systems which include Unix, Linux and others,
    I open a shell window and make it small in the lower right hand
    corner of the screen. I "cd" to the directory where the file
    containing the image is to be stored.
    
    I then move the window to be captured to the upper left hand corner
    of the screen so there is no overlap.
    
    In the shell window I type  "import name.jpg" and then left click
    in the window to be captured. If sound is turned on there is one beep
    when the capture starts and a second beep when capture is finished.
    File types of at least .jpg, .png and .gif are recognized.
    
    The program "xv" can be used to display many image formats.
    The command  "xv name.jpg" will display the image captured by the
    procedure above. The program "gimp" may be used to modify the
    image.
    
    Image file formats provide a range of compressions and thus a range
    of sizes. The quality of the program writing the image file format
    can also make a big difference. For example, to write a fully compressed
     .gif file requires a license whereas a program can write a .gif file
    that can be read by other applications and not use the proprietary
    part of the compression.
    
    Below is the same, large, image captured by "import" as .jpg, .png and
    .gif. The sizes in bytes are respectively 39,098 , 11,490 and 329,115 .
    
    These take a while to display, thus only the .jpg is shown:
    
    
     
    
    The source code that you may get and put inside your application
    includes:
    
    www.ijg.org  Independent Jpeg Group   /files  get jpegsrc.v6b.tar.gz
    
    www.filelibrary.com/Contents/DOCS/101/new.html  get  jpeg6b.zip
    
    libpng.sourceforge.net links to download
    
    www.libpng.org/pub/png  send you to sourceforge
    
    
    Next: For the real GUI programmer, you want to build into your
    application the ability to directly write out some image file
    format. The code needed to capture the pixels from the screen
    in your program depend on language and toolkit, not on operating
    system. Thus, you can write portable code that outputs various
    image file formats.
    
    The following demonstrates basic capturing pixels, formating and
    writing the file. Modify to suit your needs. The examples cover
    OpenGL, Java and X Windows. These happen to use the legal code
    to do .gif output. Substitute .jpg, .png or other as you desire.
    Note that the "decorations" put on by the window manager are not
    part of your window. You only get out the pixels your application
    writes.
    
    
    w1gif.c w1.c with .gif output writes w1gif.gif
    
    
    
    Hex dump of the above file.
    Note readable file type, GIF89a, width and height, little endian
    hexadecimal  00C5 by 007A, mostly unused color table.
    
    A color table is an indexed list of colors, e.g.
    
    color
    index  R   G   B
      0   255  0   0
      1    0  255  0
      2    0   0  255
      3   200 200 200
    
    Image byte values  0 0 1 3 2 2 2
    would give pixels red, red, green, grey, blue, blue blue.
    Note that in this simple case, only 256 colors are available for
    any specific image. 8-bits replaces 24-bits for a 3-to-1 compression.
    The image byte values may be further compressed by run length
    encoding or other methods. 
    
    Ugh, this version does not build the color table, it basically tests
    background, that will come out white, and other that will come out black.
    
    w1glgif.c w1gl.c with .gif output writes w1glgif.gif
    
    
    
    Hex dump of the above file.
    
    color tables
    
    

    Lecture 16, More Graphics Math

    
    Some mathematical techniques have multiple uses in graphics.
    The understanding of the development may be more important
    than a specific chunk of code because your specific need may
    be slightly different.
    
    In order to not loose everyone in notation, we start with one
    dimension, then we wave our hands and say it now should be obvious
    in three dimensions. :)
    
    Our goal is to do interesting manipulations of 3D patches.
    The smallest useful patch is 16 3D points forming a 4 by 4 mesh.
    
    Starting easy, consider four values of x, e.g. x0, x1, x2, x3
    that can also be represented as a vector X.
    
    Given that the x's are evenly spaced, we want to find an easy and
    efficient way to compute intermediate values. This is called
    interpolation.
    
    The solution is to create a polynomial, P(u), with an independent
    variable u that goes from 0.0 to 1.0 such that:
      P(0)   = x0
      P(1/3) = x1
      P(2/3) = x2
      P(1)   = x3
      and any value of u between 0.0 and 1.0 gives a reasonable value for x.
      (Note the equal spacing, 0 to 1/3, 1/3 to 2/3, 2/3 to 1)
    
    There are various approximations that can be used if we do not need
    exact equality at every point. For example, see the GUI tutorial on
    spline fit. For the purpose of understanding, we use the exact fit by
    a third order polynomial.
    
      P(u) = c0 + c1*u + c2*u^2 + c3*u^3 
    
    A side note is that we use Horner's rule for the actual computation
      P(u) = c0 +u*(c1 + u*(c2 + u*c3))
    using three multiplications and three additions.
    In vector notation, C represents the four values c0, c1, c2, c3.
    
    Now, combining what we have so far, e.g. p(1/3) = x1 and P(u), in a
    neat form we can see the matrix-vector version of our problem.
    
      P(0)   = c0 + c1*(0)   + c2*(0)^2   + c3*(0)^3   = x0
      P(1/3) = c0 + c1*(1/3) + c2*(1/3)^2 + c3*(1/3)^3 = x1
      P(2/3) = c0 + c1*(2/3) + c2*(2/3)^2 + c3*(2/3)^3 = x2
      P(1)   = c0 + c1*(1)   + c2*(1)^2   + c3*(1)^3   = x3
    
    
    Noting that this is a set of simultaneous equations,
    define the constant matrix A from the equations above
    
           | 1   0    0    0   |
       A = | 1  1/3  1/9  1/27 |
           | 1  2/3  4/9  8/27 |
           | 1   1    1    1   |
    
    and writing the matrix vector equation (ignoring row vs column vectors)
    
       C * A = X
    
    We know the values of X and A, thus we directly compute C using
    
       C = A^(-1) * X
    
    compute the inverse of matrix A and multiply by vector X to get vector C.
    
    For computational efficiency, the inverse of A is computed at most once
    and can be used for many different X vectors. Having the C vector,
    Horner's method is used to compute the intermediate values at the
    u needed by our graphics application.
    
    simeq.c Solves simultaneous equations and computes inverse.
    
    Now for the hand waving. Using the method described above and considering
    a 3D point having x,y and z, we can compute three C vectors, Cx, Cy and Cz
    by using X, Y, and Z vectors, thus getting three polynomials
    Px(u), Py(u) and Pz(u) that interpolate and produce an x, y and z for
    each value of u in the range 0.0 to 1.0. 'u' is known as the parameter
    and the equations are called parametric equations for x, y, z.
    
    What is usually needed is interpolation in two dimensions, say u and v,
    for a two dimensional mesh of three dimensional points. Thus we have
    16 points and this would need 16 c's for an exact fit, needing
    16 by 16 matrices. In order to get better computational speed, smoothing
    is applied and Bezier or cubic B-Splines are typically used.
    To really get deep into surface patches, check out Non Uniform Rational
    B-Splines, NURBS.
    
    The use of "patches" allows complex surfaces to be drawn with a few
    pixels when far away and many pixels when close up. Thus uniformly
    good quality images may be displayed with only as many computations
    as are needed.
    
    For example, bteapot.c displays the wireframe.
    bteapot uses vertices.h
    teapot.c has the data internal, and has a
    bug in the data that creates a crack in the pot. Cracked pot?
    
    
    Modeling techniques.
    
    Suppose you want to model characters that are going to move and perform
    actions. In 2D the character would be drawn by the creative artist in
    a number of situations. An author would create the story line. An
    animator would draw the character at various stages in the story.
    Other people would fill in the frames between the stages. Other people
    would "ink and paint" the frames so that every 1/24 of a second a
    frame could be displayed and the viewer would see smooth natural
    motion as the character went about doing the story line. This is
    still being performed and computers are helping some, but it is still
    a lot of work.
    
    In 3D modeling such as the movies Toy Story and Finding Nemo the
    effort is even greater. Typically each frame must exists in terms
    of geometry of objects, texture mapping, coloring, materials and
    lighting. Out takes of many animations have been shown. One from
    Shrek presented a dress moving one way and the princess moving
    the other way, oops, the texture mapping coordinates were wrong.
    In movies such as Madagascar and Over The Hedge there was a
    line of code for every hair in some closeups.
    
    Thus additional math is needed and more is being used. Once the
    character is modeled in 3D, the motion can be computed for
    actions such as walking and running. Once the motion is computable
    then all the joint movements can be computed. Some of the motion
    is captured by placing "dots" on human subjects and recording the
    position and angle of body parts. Using human motions can make the
    characters more "life like", more pleasing to the eye.
    
    Complex figures, such as The Incredibles and Robots, seem to be using
    a technique where the body is modeled by limbs as lines, then
    ellipsoids are placed on the limbs. The actual appearance of skin is
    computed based on an elastic mesh that covers the ellipsoids.
    Not quite the exact physics of skin because the tension on the
    mesh has to be adjusted on various parts of the body. Actions
    such as taking a punch in the stomach are computed by deformation
    of the mesh.
    
    The creative talent of artists, authors and animators
    is still needed. Much of the other work may be assisted by
    mathematical computations.
    
    

    Lecture 17, Writing and restoring users work

    Have you ever been editing for a long time, then suddenly, crash?
    Were you able to recover most if not all of your work?
    
    A user may spend many hours on a GUI program and expects reasonable
    protection.
    
    As appropriate, some applications save automatically as
    at some time interval, after some amount of input or at some key
    place in program execution.
    
    Other applications save only when the user specifically chooses
    to save. Think about what is appropriate for your application.
    
    The technical process of saving user data can depend on programming
    language and operating system. A few applications have a lot of
    data and complex structure in the data and thus use a full
    relational database. Most application use a simple file for saving
    and restoring user data.
    
    Even though operating system crashes are much less common, there
    are still occasional power outages, network outages, network
    disconnects or your pet terminating you application.
    (One of my cats likes to jump six feet onto my keyboard while
     I am typing. This causes random chaos until the cat is
     safely on my lap.)
    Thus, the programmer must consider all places the application may
    be abruptly terminated and protect the users data from loss.
    
    The "bad method":
    Read in the users previous work, save the users present work by
    writing the new data into the old file. Consider what remains if
    the application is abruptly terminated just as the first record
    is being written: The old data is lost, the new data is not saved,
    the user has lost everything.
    
    A "better method":
    Read in the users previous work from a permanent file, close the file.
    When a save is to be executed, create a new file with a
    backup temporary name, write the users new work to the new file.
    Flush and close the new file. Open the permanent users file for
    writing, open the backup temporary file read-only, copy the
    backup temporary file to the permanent file, flush and close.
    Then, delete the backup temporary file. This method at worse has
    preserved the users original work. Upon startup the application
    should look for the backup temporary file name first, (it will
    always be the latest user work) and if not found, look for the
    users permanent file, and if not found create an initialized
    user permanent file.
    
    Other versions of A "better method":
    If provided by your programming language and operating system,
    once the backup temporary file is closed, rename or "move" the
    backup temporary name to the permanent file name. Both files should
    be in the same directory and thus only a directory update is
    performed. At least one of the files should be available even when
    there is an abrupt termination during the rename.
    
    For a game, please provide a "pause." It may be a phone
    interruption or a biologically urgent need. Then, there
    needs to be a "resume." Since the game does not know how
    long the pause will be, the state information should be
    written to a file. The computer could shut itself off or
    some other activity may kill the game. The "resume" may
    test if the state is still in RAM and quickly continue,
    or determine the state must be restored from a file.
    
    What file format should be used for saving?
    That depends on the application. My first choice is always an
    plain text ASCII file that I can look at (and fix if necessary)
    with any text editor (or word processor).
    
    For a large amount of numeric data, that is saved and restored often,
    an unformatted binary file may be more appropriate. It turns out
    that formatting binary data to ASCII numbers and formatting back is
    a very CPU intensive process. The ASCII form usually makes the
    file larger and thus also increases the disk read and write time.
    
    The amount and type of data varies according to the application.
    For a game or puzzle or lesson you would keep some statistics and
    possible user identification. For example, arcade game style is
    to have the highest scores displayed with the players initials.
    At the end of each game the permanent file is read and the new
    score inserted, in order, if it is higher than the lowest score.
    Usually the maximum number of saved scores is limited.
    
    For a one user game, the save file and present status, might be
    presented similar to FreeCell statistics:
    
    
    
    
    For an object oriented graphics editor the save file might look like
    
    rectangle  10.3  12.5  4.0  3.0  filled  255 0 0  0 255 0
    circle      5.7  19.2  5.0  outline  128 128 128
    line       22.7  39.4  22.7  59.4  3  0 0 255
    text       14.6  50.2  courier 14  "this is my text"  0 0 0
    
    It is the application programmers choice to use fixed fields
    or just a sequence with the interpretation based in the first field.
    
    Above, the rectangle has a lower left x,y at  10.3  12.5,
    a width and height of 4.0 and 3.0, it is filled with red and
    outlined in green.
    
    The circle has center at x,y  5.7  19.2, radius 5.0 and is
    just outlined in medium gray color.
    
    The line goes from x1,y1 to x2,y2 with line width 3 and color blue.
    
    The text has a lower left at x,y  14.6 50.2, using courier font 14
    point and black.
    
    The words might be replaced with code numbers for more convenient
    programming but less convenient editing to fix problems (user
    or program). Beware, only add larger code numbers when modifying
    your application. Otherwise, getting an old saved file can be
    a real surprise. The voice of experience.
    
    In many programming languages it is more convenient to use space
    as a separator than to use comma. Fixed fields or just sequential
    may depend on a particular programming language.
    
    For an application where the user was creating 3D objects, like
    teapots or skulls, the  .dat  file is convenient.
    This file starts with two numbers, the number of points and the number
    of polygons. Then the x,y,z of the points followed by the polygons.
    Each polygon has a count of the number of points followed by that
    number of indices of points, the first point being point 1.
    The files datread.h and datread.c provide reading and writing this file type.
    
    For a graphics scene editor that places objects, the users work might be
    saved as a file such as:
    
    device: lab6_input1.rle
    postscript: lab6_input1.ps
    jpeg: input1.jpg
    debug: 5
    
    viewport: 400 400
    coi: 0 0 0
    hither_yon: 1 100
    observer: 4 1 20
    angle: 8.0
    
    light_position: 10 30 30
    light_color:    1 1 1
    
    object: drop.dat
    color_type: 1 1 0 0
    illumination_parameters: .2 .8 1.0 50
    shading: phong
    rotate: 45 30 60
    scale: 1 1 1
    translate: .25 -.36 0
    
    object: drop.dat
    color_type: 1 1 1 0
    illumination_parameters: .25 .75 1.0 10
    shading: phong
    rotate: 0 0 180
    scale: 1 1 1
    translate: 0 .6 0
    
    object: cube.dat
    illumination_parameters: .3 .70 0.0 10
    shading: phong
    color_type: 1 1 .5 .5
    scale: 2 2 .1
    translate: 0 0 -.5
    
    object: cube.dat
    shading: phong
    color_type: 1 .2 .9 1
    illumination_parameters: .25 .75 1.0 100
    scale: 2.0 .2 2.0
    translate: 0 -1.0 .5
    
    end
    
    
    Note that the type of input ends with a colon.
    An object in .dat format is placed in the scene with rotations,
    scaling and translations that are simple matrices as
    covered in an earlier lecture. Shading may be faceted,
    phong or none. Color is ARGB and illumination parameters
    are ambient, diffuse, specular and shiny. Each covered in an
    earlier lecture. The above scene when rendered appears as:
    
    
    
    The shapes of objects are stored in .dat files for this "run6"
    renderer. The cube.dat is
    
     8 6
            -0.5          0.5          0.5
             0.5          0.5          0.5
             0.5         -0.5          0.5
            -0.5         -0.5          0.5
            -0.5          0.5         -0.5
             0.5          0.5         -0.5
             0.5         -0.5         -0.5
            -0.5         -0.5         -0.5
    4	     1     2     3     4
    4	     5     6     2     1
    4	     8     7     6     5
    4	     4     3     7     8
    4	     2     6     7     3
    4	     5     1     4     8
    0.0 0.0 0.0  0.0 0.0 1.0  0.0 1.0 0.0  4.0 6.0 9.0 1.0 -1.0  -1.0 1.0 -1.0 1.0 100.0 100.0 100.0
    |---VRP---| |--VPN-------||--VUP----| |----COP---| hith yon  |--- window------|
      |------Light----|
    
    
    

    Lecture 18, Rendering Survey

    
    Rendering a static scene with lighting and shading is a complex
    program. I have written one as have some of you.
    
    The basic input is a 3D model.
    The model may have points, lines, polygons and more complex
    shapes and imported objects. There may be colors, lighting
    and texture mapping. A number of programs are available to
    allow a person to create or enter a model.
    
    One primitive input, to a renderer named "run6" looks like  lab6_input1
    
    The model is your "world" that is to be rendered.
    The world does not move, the point of view, your eye, moves.
    
    OpenGL is a 3D rendering system. It uses what is called a
    "rendering pipeline" to present the modeled scene as a 2D
    image on the computer screen. 
    
    Graphics cards may have some to very sophisticated rendering
    built into hardware and software.
    
    
    Covered in the textbook, Chapter 12, is Advanced Rendering.
    This covers ray tracing and other advanced techniques.
    
    For download of a ray trace renderer, the one I like best is
    
    www.povray.org and    www.povray.org/download
    
    Available for MS Windows, Linux, MacOS in both binary and source.
    Example outputs:
    
    
    
    
    
    
    
    features
    
    scene description
    
    
    Typically, this lecture includes a video demonstrating rendering.
    
    The next level of complexity and sophistication is rendering
    animation. This is typically done off line by massive computing
    power. We have seen some trailers of some 3D cartoon movies.
    
    Technical activities also need animation.
    
    
    Dynamic rendering, international space station assembly
    
    See Google  Sketchup  for 3D object and scene input.
    
    

    Lecture 19, Review 2

    Some small special topics.
    Review lectures 11 through 17 and homework 3.
    
    Same type of quiz as Quiz 1.
    Open book, open note, open computer.
    Based on WEB pages and lectures 11 through 17.
    
    Key items:
    
    A "point" is 1/72 of an inch on paper,
    it may be any size on a computer screen.
    
    Currier font is uniformly spaced, w and i take the same space.
    Times Roman font is proportionally spaced, w requires more
    space, width, than i. Newspapers get more on a page with
    Times Roman font.
    
    Fonts may be normal, regular, bold, italic, shadow, filled, etc.
    It requires a lot of work to create a font, thus they are
    usually copyrighted. There are typically many fonts available
    on your computer. Any program can use any of these fonts that
    are a file format the program can read.
    
    True Type Fonts use both line segments and arcs for each glyph.
    XWindows fonts, .xbm, are bit mapped fonts provided as "C"
    header files.
    
    3D rendering may use Z-plane or Ray Trace or other methods.
    Povray is one free Ray Trace renderer.
    The rendering may use a frustum volume or a cube volume or other.
    The closest surface of the rendered volume is sometimes called
    "hither" and the farthest surface "yon". Any physical units
    with any scaling may be used in the "world coordinate" volume.
    
    Rendering may show shading, plane faces, wireframe or vertices.
    Each may be useful to a user or developer for various purposes.
    
    OpenGL takes a world coordinate, also called the
    model coordinate, and multiplies by the 4 by 4 model view matrix.
    The resulting translated and rotated homogeneous coordinate [x, y, z, w]
    is multipled by the 4 by 4 perspective matrix. The result is
    scaled to the screen. The model view matrix is initialized
    to the identity matrix and the perspective matrix is
    initialized based on the frustum with eye typically at 0,0,0.
    
    Another way to render 3D is an orthographic projection that
    has much easier computation.  
    
    Scroll Bars are typically used to "pan" across an image.
    Typically scroll bars are on the bottom and right.
    Some application allow a user to "zoom" in or out.
    
    Menu bars are created before menu items in most tool kits except
    OpenGL with GLUT. Typical menus have the file menu on the
    right and help menu on the left.
    
    When editing or changing an existing user file, either make
    a copy and edit the original or edit a copy. Then move or
    rename, atomic operation, as a final step.
    
    The "Painters Algorithm" renders the farthest away surfaces first.
    Typically this uses a linked list for 2D graphics and objects may
    be hidden by other objects. By moving the object to the front or
    back of the linked list, the hidden object may be seen.
      
    
    

    Lecture 20, Quiz 2

    Based on Lectures 11 through 19.
    Based on all completed homework.
    
    See Lecture 19, Review 2 for more information
    
    

    Lecture 21, Curves and Surfaces

    There are many interesting curves and surfaces that are represented
    by parametric equations. These may be used in GUI applications.
    
    My reference book is: "CRC Standard Curves and Surfaces" by
    David von Seggern, CRC Press, ISBN 0-8493-0196-3.
    
    The uses include defining motion such as the cycloid for
    making the robot walk or 3D objects that may be useful or
    just interesting.
    
    To understand the examples below, you will have to run the program
    read the code. The screen shots are just small samples.
    
    curv_surf.c
    
    The basic idea is to have a standard way to size and parameterize
    curves and surfaces. Then a standard set of points can be generated
    and these points used either for static drawing or for dynamic
    movement, as in a target for a game.
    
    
    3D surfaces are a bit more complicated.
    I tend to write a specific program to generate the 3D surface in
    some standard format, I use .dat, then I can combine the 3D objects
    into a scene.
    
    make_spiral_635.c is a typical
    program to generate a 3D object.
    
    The output is spiral_635.dat which is
    not much to look at. The image drawn by light_dat.c is:
    
    
    
    A second example, to see the great similarity, is:
    make_helix_635.c is a typical
    program to generate a 3D object.
    
    The output is helix_635.dat which is
    not much to look at. The image drawn by light_dat.c is:
    
    
    
    Note that light_dat.c uses datread.h and datread.c
    Thus you can read, write and clean the .dat files. Cleaning, removing
    redundant vertices, is necessary for good quality rendering when normals
    are going to be interpolated.
    
    
    From the book "Curves and Surfaces" a cylindrical spiral was easily
    generated as shown in make_cyl_spiral_635.c
    that made the file cyl_spiral_635.dat file displayable in light_dat as:
    
    
    
    The same code was dropped into an OpenGL program to create surf3d.c showing the object as a wireframe.
    
    RIA, Rich Internet Applications, fully interactive that can have
    fancy graphics use databases commonly use AJAX, Asynchronous JavaScript
    And Xml, Flash (or Microsofts competing Silverlight) in you browser.
    
    Now, groups are working on the equivalent of AppletViewer that runs
    Java Applets without a browser. Mozilla Prism is one of the new
    RIA Platforms, for Windows, Linux and MacOSX.
     
    
    
    RIA War Is Brewing
     
    

    Lecture 22, Windowing systems

    Now that the class has been using one or more windowing systems
    to do homework and their project, let us peek under the cover
    and learn some fundamentals that are hidden by tool kits.
    
    The facilities and functions presented in this lecture are
    available for everyone to use. Yet, typically these "low level"
    facilities and functions are called by higher level tool kits.
    
    Both Microsoft Windows windowing and X Windows windowing will
    be covered. The names may be changed yet the observant student
    will see great similarity at the basic capability level.
    
    A first look at Microsoft Windows starts with the "C" header
    file Windows.h and the header
    files that are included:
    WinDef.h
    WinBase.h
    WinGDI.h
    WinUser.h
    ShellAPI.h
    and
    WindowsX.h
    
    A higher level Microsoft toolkit is the Microsoft Foundation Classes,
    MFC, for C++. Within this toolkit the top level files are:
    StdAfx.h and StdAfx.cpp
    An example use is:
    vc_plotd.h and vc_plotd.cpp
    Then, the Windows make file and a use of vc_plotd (one of many plotd's)
    hw7.mak and hw7vc.cpp
    
    Hopefully, you are using a higher level graphics tool kit than this
    for your project.
    
    
    
    To help understand some of the function calls, "h" as a first
    letter of a type usually means "handle" that means a "C" pointer.
    Thus, hwnd, is a handle to a specific window. hdc, is a handle to a
    device context, drawing context, that contains drawing parameters
    such as colors and pixels.
    
    
    
    The X Windows System considers the top level entity to be a "display"
    typically named "dpy". A display may have one or more "screens".
    Within each screen is a top level window that covers the entire
    screen. Within the top level window there can be any number of
    windows, some with the top level window being the parent and others
    nested, children, to any nesting depth. For each window that may be
    one or more graphics context, "gc" that contain drawing parameters.
    
    The basic header file for X Windows is Xlib.h
        XDrawArc and many other functions and data structures
    The next level header file is Intrinsic.h
        XtAddCallback and many other functions and data structures
    The Motif tool kit main header file is Xm.h
        XmCreateSimpleMenuBas and many other functions and data structures
    Note that the library names for linking are  -lXm -lXt -lX11 for
        Xm.h Intrinsic.h and Xlib.h respectively.
    
    man X  as a text file
    
    An example basic X Windows program is w1.c
    
    There are an amazing number of windows on a desktop.
    The program treewalk.c shows 465 windows
    for a Linux KDE desktop treewalk.out
    Note that some windows have names, some do not.
    Child windows are shown indented. Coordinates and sizes are shown.
    
    X Windows and Microsoft Windows give the user some control over
    what seem to be unchangeable programs. For X Windows check out
    /usr/X11R6/lib/X11/app-defaults directory,
    or /etc/X11/app-defaults,
    or /usr/lib/X11/app-defaults. "a rose by any other name ..."
    
    For example XCalc.ad
    used to produce GUI 
    
    A user may modify one of these files, typically with
    an ".ad" extension meaning "application default".
    This particular .ad file defines almost the entire GUI
    of the calculator.
    
    For Microsoft Windows there is a resource file, typically with extension
    ".rc" that gets compiled by the resource compiler into a binary file.
    For example  hw7.rc
    
    Application default or resource files can set simple items such as
    colors and sizes, can provide additional key bindings and in some cases
    can change the names of menu items or behavior of the application.
    
    
    Some blog comments are at blog
    
    

    Lecture 23, Motion and movement

    
    When using motion, dynamics, in your GUI, think about what
    you want to convey.
    
    Two choices are cartoon or realism.
    
    The choice of cartoon allows you to violate the laws of
    physics. You can squash, stretch and make objects fly
    and stop instantaneously. This can be very effective
    to impress the viewer.
    
    In order to get realism, the motion needs to approximate
    the real world laws of physics. In the simplest terms:
       dt is the time for one screen update
       ds is the distance moved for one screen update
       dv is the change in velocity for one screen update
    
       s is the objects position (may have 1, 2 or 3 components)
       v is the objects velocity (may have 1, 2 0r 3 components)
       a is the acceleration of the object        ( " )
       m is the mass of the object
       f is the force being applied to the object ( " )
    
    Then, given a force, f, compute for each screen:
    
       a  = f / m     (may have 1, 2 or 3 components)
       dv = a * dt
       v  = v + dv
       ds = v * dt
       s  = s + ds
    
    For a complete set of physics equations and related information
    see click on last item, Physics Equations
    
    
    
    The short clip, Flatland, is intended to get you thinking about how
    people will view your GUI.
    Put yourself in the local characters position - what do you see?
    Put yourself in the outside observers position - what do you see?
    
    Notice have Flatlanders move around. like us, they face front
    when walking, running, driving.
    
    
    
    Observe the trailers. Do you notice any violations of the laws
    of physics? This will be intuitive from your life experience,
    not from trying to mentally compute equations.
    
    www.apple.com/trailers/disney/the_incredibles/trailer1_large.html
    
    www.apple.com/trailers/disney/the_incredibles/trailer2_large.html
    
    www.pixar.com/featurefilms/index.html
    Toy Story etc.
    
    Your project should have either manual, user, speed control or
    automatic speed control using clock or some other timing.
    
    
    

    Lecture 24, Data Structures for Rendering

    
    Why did I choose to use triangles in Lecture 21,
    3 point surface, rather than 4 point surface? 
    Answer: For efficiency and ease of coding for some renderer's.
    
    There are many types of renderer's as covered in Lecture 18.
    For this lecture I am focusing on a renderer that will use
    Phong Specular Lighting and thus requires normals to surfaces
    that are interpolated across the surface.
    
    To understand relative efficiency, in this case twice as many
    3 point surfaces as four point surfaces for the same object,
    both the data structures and the processing must be analyzed.
    
    The data structures