  ==========================================================================
  ||                                                                      ||
  ||                            S H A N D Y v1.0                          ||
  ||                      A 3D Studio object file viewer                  ||
  ||                         Andrew Cheung (C) 1996                       ||
  ||                                                                      ||
  ==========================================================================
  
  DISCLAIMER, DISTRIBUTION & USAGE
     I have released Shandy and its source code into the public domain.
  You may use Shandy and its source code in any way you see fit. The
  program, its source code and associated documentation may be freely
  distributed on the condition that no fee is charged and this disclaimer,
  distribution & usage message is included in the distribution. Since
  Shandy and its source code are provided free of charge, there is absolutely
  no warranty or claim as to their quality or fitness for any particular
  purpose. Even though it is very unlikely, I cannot be held responsible for
  any damage caused by Shandy
		      
		      --------------------------------

    Before I begin, I think this is going to be a fairly large file. If
  you just want to run SHANDY, read README.TXT and the section on running
  SHANDY/limitations here.

  CONTENTS
  --------

  1. Intro
  2. Features
  3. Running Shandy
  4. Limitations, Bugs, Bummers etc.
  5. Programming Info
  6. End Stuff...

INTRO  
=====
     
     Shandy is my attempt at a 3D polygon renderer. I never intended to
  release it at the beginning since it was just me finding out about
  graphics programming. Once I'd got texture mapping working, I thought,
  'Hey, it's good enough for something. Since I've got this far, I might
  as well polish it up and release it'
     
     It's taken ages, but that's because it's been a stop and start affair
  lasting a year: I dredged my wireframe code out from 2 years ago, added
  flat shading, stopped a bit, got the flaky Gouraud shading working, stopped
  a bit, added texture mapping, stopped... etc. If you compacted it all
  together, I guess it would have taken less than 2 months.
	  
     I was gonna call it SHADY but SHANDY sounds better and
  stands for Shader by Andy and seems nice after the recent drinks
  names of Java, Java au lait, Cafe and so on.

     I don't claim it to be the fastest or 'best' renderer around
  but rather, it is 'good enough', I've included the full source code
  to it and thirdly, it does have a few more features than some demos I've seen
  (which are really good, but lack the source). It's not a tutorial - I haven't
  explained everything but I think that the code itself is pretty easy to
  understand. If you need more info, I suggest having a browse on the tonnes
  of useful stuff on the Internet. Lots of excellent stuff - the trouble being
  that it's pretty much littered all over the place and it might take some
  perserverance to get what you're looking for. Also check out the 
  comp.graphics.algorithms newsgroup.
  

FEATURES
========
  
  SPEC

     3D object viewer & render program. Interaction is via the keyboard
  (it used to have mouse & joystick interaction as well but I took it away
  since they used a different graphics library - no 16 million colours & it
  wasn't 32 bit. I also wanted to keep code size down)

  DISPLAY OPTIONS

     Supported Resolutions: 320x200 (VGA) & 640x480 (SVGA)
     Supported Colours:     256 colours, 16.8 million colours

  RENDERING OPTIONS
  
     *  DOTS          -   Each point is represented by a pixel
     *  WIREFRAME     -   Edges of objects are represented by lines
			  connecting vertices. No shading.
     *  FLAT SHADED   -   Each facet is shaded according to its orientation
			  with the light source vector(s).
     *  GOURAUD SHADED-   Each facet is shaded by interpolation of the
			  intensity levels at the vertices of the facet
     *  PHONG SHADED  -   Each facet is shaded by interpolation of
			  the direction of the light vectors at the
			  vertices of the facet - not implemented
     *  TEXTURE MAPPED-   DDA Texture mapping is employed


  SPECIAL FEATURES

	  *   Reads 3D Studio .asc files
	  *   Multiple objects
	  *   Display modes from 300x200 - 640x480
	  *   16 million colours SVGA modes
	  *   Portable high level stuff (the main C++ code)
	  *   Different shading models for different faces
	  *   Importable texture maps (.tga file format)
	  *   Keyboard interaction of scenes,objects,cameras & lights
	  *   Full C/C++/ASM source

		      --------------------------------

RUNNING SHANDY
==============
  
  1.   Pkunzip -d Shandy.zip to extract all files with the directory
       structure intact. See the filelist.txt file for more info.

  2.   There are 2 modes of usage: Interactive & Profiling
       Interactive (normal) mode
       ~~~~~~~~~~~~~~~~~~~~~~~~~
       Run SHANDY with:
			
		SHANDY <object_filename.asc> [rendering mode]
		e.g.

		SHANDY shandy.asc 5  ** for Gouraud shading
		SHANDY help.asc      ** for texture mapping

      [rendering mode] can be the numbers 0-9. This chooses the rendering mode       
      If you omit the rendering mode, it defaults to texture mapping if that
      is specified in the object file, otherwise it defaults to Gouraud shading
      Once the scene is loaded, you can use the keyboard to interact with it.

      Profiling
      ~~~~~~~~~
      Run SHANDY with:
			
		SHANDY <object_filename.asc> [rendering mode] [X] [Y] [Z]
		e.g.

		SHANDY objects\cube.asc 5 0 4 0

      [X] [Y] [Z] are numbers between -360 and 360 and rotates the scene
      500 times about the X,Y,Z axes by the degrees specified. So the example
      rotates a Gouraud shaded cube (render mode 5) 500 times about the
      Y axis by 4 degrees each time.
      There is no interaction except quit! I use it for testing performance.

      KEYS
      ----
	
	--- Try moving the cameras & lights around & not only objects ---

	Selecting items to move:  
	    
	 S,O,C,L        :Select a (S)cene,(O)bject,(C)amera or (L)ight  
	 SHIFT + O,C    :Select origin of (O)bject, target of (C)amera   
	 SPACEBAR       :Toggle continuous motion  
	 NUMPAD: +-     :Increase/Decrease step size for translation/rotation   
	 TAB            :Set origin of object to its midpoint  
	 ESC            :Quit   
	
	Transformations:  
	    
	 [UP][DOWN] ARROW                      :Move item forwards|backwards  
	 [LEFT][RIGHT] ARROW                   :Rotate "  left|right  
	 ALT + [UP][DOWN][LEFT][RIGHT] ARROW     :Move   "  up,down,left right  
	 CTRL + [UP][DOWN][LEFT][RIGHT] ARROW    :Rotate "  up,down,anti/clockwise   
	
	Rendering modes:  
	    
	 [1]   DOTS          [6]   GOURAUD (flat shaded)  
	 [2]   WIREFRAME     [7]   GOURAUD (Phong palette)  
	 [3]   FLAT SHADED   [8]   ---  
	 [4]   ---           [9]   TEXTURE MAPPED (flat shaded)  
	 [5]   GOURAUD       [0]   TEXTURE MAPPED  

	[4] was to have been flat shaded with depth values i.e. the object
	    gets darker the further it is from the viewer
	[8] was to have been Phong shading

	(The default step size is 4 units/degrees)

   Notes
   -----

     For texture mapping, you'll need a file called TEXTURES.DAT in the SHANDY
   directory. This file contains material names and the path of the graphics
   file representing that material - make sure the path names are correct,
   otherwise no texture mapping!

     For Gouraud shading with a Phong palette (rendering mode 7) you'll need
   the PHONG.PAL file in the SHANDY directory. All this is is a list of 256
   RGB values for colours in the colour palette.

     The 32-bit version (Shandy.exe) needs DOS4GW.EXE to be present in the
   directory of SHANDY or in a PATHs directory.
   
     Aaaargh! - the 16 bit version (Shandy16.exe) will crash if you load an
   object with more than about 600 polygons, so don't use it on object files
   more than about 68K in size. I've included it since Shandy started off as
   16-bits then moved onto 32-bits.

     The 16 million colour modes do not always set correctly on machines.
   They set OK on my machine, but on some machines might produce:
   "ERROR: Video Mode X did not set correctly"

     The 16 million colour modes produce flickering - I thought it was due to
   my graphics card only having 1MB memory, but then I tried the graphics
   library demo program - it flickered as well!. SHANDY (SVGA) also flickers
   with QEMM???


LIMITATIONS, BUGS, BUMMERS ETC.
===============================
   After all the good bits, here are the not so good bits. This list
   looks bad...but isn't really. They're not showstoppers.
   
   My Stuff:

   -  Looking DIRECTLY up or down i.e. with a direction vector of (0,(-)1,0)
      will cause SHANDY to crash.
      - limitation & not a bug

   -  Cameras have a viewpoint (that's where YOU, the user is at) & a target.
      If you move the camera 'past' the target, then there's lots of flickering
      before you end up looking in a weird direction (often a black screen) -
      BUT it hasn't crashed. Just give it some time and exit.
      - bug?

   -  Loading objects with more than about 600 polygons (approx. 68K?) using
      the Shandy16.exe (the 16-bit version of Shandy) hangs the system. Using
      bitmaps greater than 320x200 in size is OK, but doesn't display correctly
      when texture mapped.
      - limitations: Just don't use Shandy16.exe. I've included it for
	programming purposes for 16 bit compilers.

   -  If some objects in a scene are texture mapped & some not, it displays
      correctly, but if you switch rendering modes to something else, then switch
      back to texture mapping, Shandy crashes
      - bug

   Not my Stuff:

   -  QEMM causes flicker with SVGA modes. I dunno why, sigh.
   -  The SVGAKIT 16 million colour library also causes flicker - on my system
      and other systems. This occurs with their demo program as well.

   Bummers (gripes):
   -  Objects aren't always sorted correctly - Painter's algorithm
   -  Flickering of polygons sometimes
   -  You can't set the origin of the scene, so using TAB sets the origin
      of each object to its own midpoint --> objects rotate about their own
      midpoints and not the scene's midpoint
   -  Texture mapping is REALLY distorted at close distances & acute angles
      I don't have perspective correction, but I didn't expect it to be
      that bad. Only really noticeable on large flat polygons e.g. cube.
      Not really noticeable on a sphere prob. cos all the polys are small
   -  Gouraud shading is calculated incorrectly for discontinuous surfaces
   -  There are no distance calculations for light sources, so the face of
      an object will be at the same brightness whether the light source is
      1 m away or 100 m away. Also, adding lots of light sources will give
      far too much white

PROGRAMMING INFO
================
  
    SHANDY started off as 16 bits large memory model with the SVGACC libs &
  Borland C/C++ 3.1 before moving onto Watcom C/C++ 10.0 with DOS4GW, the
  32-bit flat memory model & SVGAKIT 5.0 libs.

    It's written in C++, but in a better C kinda way. The actual class
  structure (what class structure?) is taken from the 3DTOOLS library by
  Zach Mortensen, so all credit goes to him for that. Actually coding the
  graphics stuff wasn't too bad e.g. texture mapping only took about 3 days.
  What did take AGES wasn't the graphics stuff, it was the interaction stuff
  esp. assembler which I had to learn, loading tga pics, presenting it etc.
  Compacting it all together, I reckon I spent about 3-4 weeks on the
  graphics & 3-4 weeks on video/keyboard assembler routines (standard ones,
  but I had to learn assembler) & presentation.

    Most time was spent fixing a few weird bugs. The best one was a texture
  mapping one: texture mapping was working fine with Borland. Compiling with
  Watcom with EXACTLY the same routine screwed it up. I went through the code
  with a fine tooth comb. No luck. I decided to simplify the loading of images
  from PCX images to TGA (no compression). This didn't help. After I don't
  know how many hours spread over a week or two, I found it:
    In my comments in SHADING.CPP, I'd drawn out a triangle e.g.

    //     / |
    //   /   |
    //   \   |
    //     \ |

    The '\' means continue onto the next line i.e. I'd commented out the
  next line of my code - a crucial one indicating whether a triangle was
  a left pointing one or a right pointing one. Borland didn't continue the
  next line as a comment, but Watcom did!
    
    One more bug: The keyboard interrupt routines kept crashing SHANDY -
  whether it was inline assembler or an external asm file. Again, I spent
  ages figuring this out. I couldn't. I took out the quicksort routine and
  it didn't crash. But why??? Then one day, I was changing code completely
  unrelated to quicksort (which I'd put back in) & the keyboard assembler
  routines and it suddenly stopped crashing. I can't remember what the change
  was but it was completely unrelated. Oops, better get back on track...

    I've stuck with floating point for transformations. I've used fixed
  point for texture mapping. 
    There are no Pentium specific instructions or optimisations. The minimum
  system requirement is a 486.

  PHONG.PAL
  ~~~~~~~~~
    This is a standard PaintShop Pro (JASC) palette file which just lists
  RGB values for colours in the palette
  e.g. 255 255 255  for white.
    Again, you can prob. improve on my Phong palette.

  TEXTURES.DAT
  ~~~~~~~~~~~~
     Material names point to a 256 colour UNCOMPRESSED Targa file. There is
  no maximum size for an image, but there is a maximum 100 textures limit
  in a scene (tried to set it up without a maximum, but couldn't sort the
  crashes out). The format is simple & self-explanatory:

     "MATERIAL NAME"  c:\shandy\texmaps\material.tga
					
  TEXMAPS\*.DAT
  ~~~~~~~~~~~~~
    These are the lightsource tables for texture files. They're binary
  files of 256x32 arrays. Each of the 256 colours in the colour palette
  can have one of 32 light levels (another colour in the palette)
    Each .tga graphics file should have a corresponding .dat file. You can
  use the MAKELITE.EXE program to produce the dat file given a tga file

Compiling                             
~~~~~~~~~
  - All source is included in the source directory.
  - The paths for the source files are:
      
      c:\shandy\source

    If you've installed Shandy in a different drive/directory, then modify
    the project files to point to where you installed it. Note that
    you'll need to move the TEXTURES.DAT, PHONG.PAL, DOS4GW.EXE to the
    directory where the executable is. You'll also have to edit
    TEXTURES.DAT so the texmap directories are correct.

  - Includes the project files for Borland 3.1 & Watcom 10.0. The project
    file for Borland is SHANDY16.PRJ. For Watcom it is SHANDY.WPJ.
    It's currently set to compile with Watcom 32 bit flat protected mode.
    If you want to compile with Borland 16 bit large mode, you'll have to
    comment out the line:

     #define WATCOM32

     in the defines.h file

  -  IMPORTANT: If you don't have the SVGAKIT libraries, remove the 2 of
     them from the Borland or Watcom projects (otherwise Shandy won't link).
     Also comment out the #define SVGAKIT line in defines.h.
     You won't be able to use SVGA modes. Note: only usable with SVGAKIT 5.0
     or 5.1 (function names have changed with 5.2)
  
  -  Remember to change the include/library directories in Borland & Watcom
     (& for SVGAKIT directories  if you have them)

  -  #define _DEBUG in defines.h produces some debug info
  -  #define PROFILE in defines.h doesn't sort objects OR clear the screen  
     so I use for it for performance testing purposes. Since there is no
     screen clearing, there is no flicker in 16 million colour modes!
     I don't know whether this has been fixed in SVGAKIT v5.2 libraries, but
     all the function names have changed there. I don't wanna do recoding!
  -  I've included the SCREEN.OBJ & KEYBRD.OBJ files in case you don't have
     Turbo Assembler in Borland C v4.x, 5.x ? Just link them in with the
     other object files after making. NOTE: These are 16 bit object files
     for Borland, not Watcom. The assembler with Watcom is all in-line.

  Performance
     
     My 486 DX2/66, 8 MB RAM, 1 MB Cirrus Logic graphics card = DX2/66
     Pentium 60MHz, 16 MB RAM, 1MB Diamond Stealth 64 = P60
     Dell Optiplex 100MHz Pentium, 16 MB RAM = P100

     Shandy sphere.asc 9 0 4 0  - in 320x200 VGA, 256 cols
				  (with cam.tga as the texmap)
     This rotates the sphere 500 times around the y-axis at 4 degrees each
     time.
	      DX2/66   P60     P100
     Texture: 27 secs  15.5 s  9 s     \
     Gouraud: 18 secs  9.5  s  6 s     /   Pentium 100 is 3 times faster
  
     The SVGAKIT libraries were still really slow with the Pentiums. I don't
     know why line drawing (even horizontal line drawing) is REALLY slow on
     any kind of machine with SVGAKIT. I haven't done timings for SVGA modes.

  Development system

  486 DX2/66, 8MB RAM, 1MB Cirrus Logic 5428 graphics card, 1.6 Gb hard disk
  Borland 3.1, Watcom 10.0
  
  LIMITATIONS

    Still only convex objects for the shading part, since I still haven't
  looked at other backface elimination methods except for the easy convex
  ones.

    Painter's algorithm for rendering

    No anti-aliasing or perspective correction with the texture mapping

    IF I HAD TIME FOR THE NEXT VERSION... (probably not)

    *   Z-buffering
    *   Optimizations (e.g. less function calling,more assembler & macros)
    *   Fast Phong shading (just testing to see what it looks like)
    *   15,16,24 bit palette
    *   A proper colour model
    *   Anti-aliasing of the texture mapping e.g. mip-mapping
    *   Indexable colours like RED,BLUE etc.
    *   Fixed point math

      There are lots of things to optimize, but I don't have the time since
    I was really looking at learning 3D graphics & doing it for a result
    rather than hacking away. There's some assembler, but there's lots of
    other things that can be done.
      Speeding up the actual screen rendering would speed up the display
    of medium sized objects ( < 1000 polygons) but not objects with more
    polys much. Speeding up matrix calculations e.g. fixed point math would
    speed up the display of large sized objects (>1000 polygons) but not
    medium sized objects much - I've done some profiling. It's also visible
    in the final display: Displaying a large object with dots is similar in
    speed to displaying a large sized object with Gouraud shading etc.
      Optimisations should be carried out where it matters most - Amdahl's
    Law. The 2 main areas for SHANDY are screen display & transformations.

END STUFF
=========

    This was longer than I thought it would be, but at least it's better
    than being too short.
      
      Credits go to Zach Mortensen for his 3DTOOLS library & SCITECH for
    their SVGAKIT libraries, Autodesk for 3D Studio. David Lampton's
    book 'Gardens of Imagination' provided the Targa functions and helped
    with screen/keyboard info. For graphics books, look for Interactive
    Computer Graphics (Addison Wesley) by Gillies & Burger or 3D Graphics
    by Watt (also Addison Wesley). They're good graphics textbooks.
    The Foley, Van Damme Computer Graphics book is the big meaty one - maybe
    too much info for starting out. Also, the Internet has lots of stuff.
    You just have to know where to look. For starters, try the
    ftp site x2ftp.oulu.fi.
    
      Please tell me about any unlisted problems or email me. If you are 
    generous enough then you could send me money, buy me a car, a house?
    - OK, I guess it's not that good. In any case you can drop me a line
    at:

    Mail:  Andrew Po-Wai Cheung
	   DoC
	   180 Queens Gate
	   South Kensington
	   London, SW7 2BZ
	   England

    E-mail : apwc@doc.ic.ac.uk 
    WWW    : http://mkn.co.uk/help/
	     extra/people/andrewcv.html

    See ya!

    Andy C
