I was looking through my inbox and I stumbled across an old ray tracing program (C++) I created for a homework assignment. I managed to get the 6+ year old project to compile and here's what it looks like:

Here is the source code. Compiles with g++ and SDL library
 #include <stdlib.h>  
 #if defined(_MSC_VER)  
 #include "SDL.h"  
 #else  
 #include "SDL/SDL.h"  
 #endif  
   
   
 #include <math.h>  
 #include <queue>  
 #include <iostream>  
 #include <stack>  
 #include <vector>  
 using namespace std;  
 bool rayTracingEnabled = true;  
 bool bidirectionalLighting = false;  
 bool tumblingEnabled = true;  
 bool revolvingLight = false;  
   
 SDL_Surface *screen;  
 SDL_Surface *ship;  
 int SHIP_HEIGHT;  
 int SHIP_WIDTH;  
 #define S_WIDTH 640  
 #define S_HEIGHT 480  
 void draw_spaceship(int x, int y);  
 void render();  
   
 double lighting_mix = .3;  
 double zbuffer[640][480];  
   
   
   
 inline int roundDouble(double x)  
 {  
      return ((int)floor(x+.5));  
 }  
 struct vector3  
 {  
        
      double x;  
      double y;  
      double z;  
      vector3()  
      {  
           x = y = z = 0;  
      }  
      vector3(double x1, double y1, double z1)  
      {  
           x = x1;  
           y = y1;  
           z = z1;  
      }  
      double mag()  
      {  
           double sum = x*x + y*y + z*z;  
           return sqrt(sum);  
      }  
      void makeUnitVector()  
      {  
           double magOfThisShit = mag();  
           x = x/magOfThisShit;  
           y = y/magOfThisShit;  
           z = z/magOfThisShit;  
      }  
 };  
 struct sphere  
 {  
      vector3 center;  
      double radius;  
      unsigned int color;  
      sphere()  
      {  
           center = vector3(0,0,0);  
           radius = 0;  
           color = 0;  
      }  
      sphere(double x, double y, double z, double r, unsigned int c)  
      {  
           center.x = x;  
           center.y = y;  
           center.z = z;  
           radius = r;  
           color = c;  
      }  
      sphere (vector3 c, double rad, unsigned int co)  
      {  
           center = c;  
           radius = rad;  
           color = co;  
      }  
 };  
 vector<sphere> scene_sphere;  
 double scalarProduct(vector3 a, vector3 b)  
 {  
      return (a.x*b.x + a.y*b.y + a.z*b.z);  
 }  
   
 vector3 light_dir(-.25/sqrt(1.5),-.25/sqrt(1.5),-1/sqrt(1.5));  
   
   
 /** Subtracts 2 vectors, returning the difference */  
 vector3 vectorMinus(vector3 &v1, vector3 &v2) {  
  return vector3(v1.x - v2.x,  
            v1.y - v2.y,  
            v1.z - v2.z);  
 }  
   
 vector3 vectorScale(vector3 &v, double a)  
 {  
      return vector3(a*v.x, a*v.y, a*v.z);  
 }  
 vector3 vectorCross(vector3 a, vector3 b) {  
  // From Shirley p.27: a x b = (ay*bz - az*by, az*bx - ax*zb, ax*by-ay*bx)  
  return vector3(a.y*b.z - a.z*b.y,  
            a.z*b.x - a.x*b.z,   
            a.x*b.y - a.y*b.x);  
 }  
   
   
 void printVector(vector3 a)  
 {  
      cout << a.x << " " << a.y << " " << a.z << endl;  
 }  
 struct triangle  
 {  
      vector3 v1;  
      vector3 v2;  
      vector3 v3;  
      unsigned int color;  
      bool textured;  
      triangle()  
      {  
           color = 0;  
      }  
      triangle(vector3 a, vector3 b, vector3 c, unsigned int color1)  
      {  
           v1 = a;  
           v2 = b;  
           v3 = c;  
           color = color1;  
      }  
      triangle(vector3 a, vector3 b, vector3 c, unsigned int color1, bool istex)  
      {  
           textured = istex;  
           v1 = a;  
           v2 = b;  
           v3 = c;  
           color = color1;  
      }  
      void flipNormal()  
      {  
           vector3 temp = v2;  
           v2 = v1;  
           v1 = temp;  
      }  
      vector3 getNormalVector()  
      {  
           vector3 a = vectorMinus(v2,v1);  
           vector3 b = vectorMinus(v3,v1);  
           vector3 normal = vectorCross(a,b);  
           normal.makeUnitVector();  
           return normal;  
      }  
        
      double signedAreaXY()  
      {  
           double x1 = v3.x - v1.x;  
           double y1 = v3.y - v1.y;  
           double x2 = v2.x - v1.x;  
           double y2 = v2.y - v1.y;  
             
           double crossProd = x2*y1 - x1*y2;  
           return (crossProd*.5);   
      }  
        
      void baryXY(vector3 v, double &alpha, double &beta, double &gamma)  
      {  
           double x1;  
           double y1;  
           double x2;  
           double y2;  
             
           // get areaA  
           double areaB;  
           x1 = v2.x - v1.x;  
           y1 = v2.y - v1.y;  
           x2 = v.x - v1.x;  
           y2 = v.y - v1.y;  
   
           areaB = .5*(x1*y2 - x2*y1);  
        
           //get areaB  
           double areaA;  
           x1 = v2.x - v.x;   
           y1 = v2.y - v.y;  
           x2 = v3.x - v.x;  
           y2 = v3.y - v.y;  
           areaA = .5*(x1*y2 - x2*y1);  
             
           //get areaY  
           double areaY;  
           x1 = v3.x - v.x;  
           y1 = v3.y - v.y;  
           x2 = v1.x - v.x;  
           y2 = v1.y - v.y;  
           areaY = .5*(x1*y2 - x2*y1);  
             
           // get Total area;  
           double totalArea = signedAreaXY();  
             
           alpha = areaA/totalArea;  
           beta = areaB/totalArea;  
           gamma = areaY/totalArea;  
      }  
        
      void rasterize()  
      {  
           vector3 a[3];  
           a[0] = v1;  
           a[1] = v2;  
           a[2] = v3;  
             
           double minx = a[0].x;  
           double maxx = a[0].x;  
           double miny = a[0].y;  
           double maxy = a[0].y;  
           // get min and max  
           for (int i = 0; i < 3; i++)  
           {  
                if (a[i].x < minx)  
                {  
                     minx = a[i].x;  
                }  
                if (a[i].x > maxx)  
                {  
                     maxx = a[i].x;  
                }  
                  
                if(a[i].y < miny)  
                {  
                     miny = a[i].y;  
                }  
                if (a[i].y > maxy)  
                {  
                     maxy = a[i].y;  
                }  
           }  
             
           int min_x = roundDouble(minx);   
           int max_x = roundDouble(maxx);  
           int min_y = roundDouble(miny);  
           int max_y = roundDouble(maxy);  
           // make sure within screen bounds  
           if (min_x < 0)  
           {  
                min_x = 0;  
           }  
           if (max_x >= S_WIDTH)  
           {  
                max_x = S_WIDTH -1;  
           }  
           if (min_y < 0 )  
           {  
                min_y = 0;  
           }  
           if (max_y >= S_HEIGHT )  
           {  
                max_y = S_HEIGHT - 1;  
           }  
             
           //iterate over screenbounds  
   
           bool printed = false;  
           for (int i = min_x; i <= max_x; i++)  
           {  
                for (int j = min_y; j <= max_y; j++)  
                {  
                     //get bary coord  
                     double alpha;  
                     double beta;  
                     double gamma;  
                     baryXY(vector3(i,j,0),alpha,beta,gamma);  
                       
                     if ((alpha <= 1 && alpha >= 0)  
                          && (beta <= 1 && beta >= 0)  
                          && (gamma <= 1 && gamma >= 0)  
                          )  
                     {  
                            
                           double zcoord = alpha*v1.z + gamma*v2.z + beta*v3.z;  
                          if (zbuffer[i][j] > zcoord )  
                          {  
                               vector3 normalHEH = getNormalVector();  
                               double angleBetweenNormalAndLight = scalarProduct(normalHEH,light_dir);  
                            
                                 
                               if (angleBetweenNormalAndLight < 0)  
                               {  
                                    if (bidirectionalLighting)  
                                    {  
                                         angleBetweenNormalAndLight = fabs(angleBetweenNormalAndLight);  
                                    }  
                                    else  
                                    {  
                                         angleBetweenNormalAndLight = 0;  
                                    }  
                               }  
                                 
                               double colorscalar = lighting_mix + (1 - lighting_mix)*angleBetweenNormalAndLight;  
                       
                               zbuffer[i][j] = zcoord;  
                               unsigned int mask = 0x00FFFFFF;  
                            
                               unsigned int redChannel = color & mask;  
                               redChannel = redChannel >> 16;  
                                mask = 0x0000FF00;  
                               unsigned int greenChannel = color & mask;  
                            
                               greenChannel = greenChannel >> 8;  
                               mask = 0x000000FF;  
                               unsigned int blueChannel = color & mask;  
                               double nRed = colorscalar*((double)redChannel);  
                               double nGreen = colorscalar*((double)greenChannel);  
                               double nBlue = colorscalar*((double)blueChannel);  
                                 
                                redChannel = (unsigned int) nRed;  
                               greenChannel = (unsigned int) nGreen;  
                               blueChannel = (unsigned int) nBlue;  
                                 
                               redChannel = redChannel << 16;  
                               greenChannel = greenChannel << 8;  
                                 
                               unsigned int colorToAssign = redChannel + greenChannel + blueChannel;  
                                 
                               ((unsigned int *) screen->pixels)[j*S_WIDTH+i]=colorToAssign;  
                          }  
                     }  
                }  
           }  
      }  
 };  
   
 struct mat3h  
 {  
      double matrix[4][4];  
      mat3h()  
      {  
      }  
      void zero()  
      {  
           for (int i = 0; i < 4; i++)  
           {  
                for (int j = 0; j < 4; j++)  
                {  
                     matrix[i][j] = 0;  
                }  
           }  
      }  
      void identity()  
      {  
           zero();  
           for(int i = 0; i < 4; i++)  
           {  
                matrix[i][i] = 1;  
           }  
      }  
 };  
   
 mat3h mat3hMult(mat3h a, mat3h b)  
 {  
      mat3h result;  
      for (int i = 0; i < 4; i++)  
      {  
           for (int j = 0; j < 4; j++)  
           {  
                double sum = 0;  
                for (int k = 0; k < 4; k++)  
                {  
                     sum = sum + a.matrix[k][j]*b.matrix[i][k];  
                }  
                result.matrix[i][j] = sum;  
           }  
      }  
      return result;  
 }  
   
 vector3 matMult(mat3h a, vector3 v)  
 {  
      double result[3];  
      double homovector[4];  
      homovector[0] = v.x;  
      homovector[1] = v.y;  
      homovector[2] = v.z;  
      homovector[3] = 1;  
        
      for (int i = 0; i < 3; i++)  
      {  
           double sum = 0;  
           for (int j = 0; j < 4; j++)  
           {  
                sum = sum + homovector[j]*a.matrix[i][j];  
           }  
           result[i] = sum;  
      }  
      vector3 res(result[0], result[1], result[2]);  
      return res;  
 }  
   
 mat3h rot3hX(double theta)  
 {  
      mat3h result;  
      result.identity();  
      result.matrix[1][1] = cos(theta);  
      result.matrix[1][2] = -sin(theta);  
      result.matrix[2][1] = sin(theta);  
      result.matrix[2][2] = cos(theta);  
      return result;  
 }  
 mat3h rot3hY(double theta)  
 {  
      mat3h result;  
      result.identity();  
      result.matrix[0][0] = cos(theta);  
      result.matrix[0][2] = sin(theta);  
      result.matrix[2][0] = -sin(theta);  
      result.matrix[2][2] = cos(theta);  
           return result;  
        
 }  
 mat3h rot3hZ(double theta)  
 {  
      mat3h result;  
      result.identity();  
      result.matrix[0][0] = cos(theta);  
      result.matrix[0][1] = -sin(theta);  
      result.matrix[1][0] = sin(theta);  
      result.matrix[1][1] = cos(theta);  
           return result;  
 }  
 inline bool checkBounds(int x, int y)  
 {  
      if (x >= 0 && x < S_WIDTH && y >=0 && y < S_HEIGHT)  
           return true;  
      else  
           return false;  
 }  
 // no comment  
 void render()  
 {    
        
      // Ask SDL for the time in milliseconds  
  //int tick = SDL_GetTicks();  
    
  // Lock surface if needed  
  if (SDL_MUSTLOCK(screen))   
   if (SDL_LockSurface(screen) < 0)   
    return;  
   
  // Unlock if needed  
  if (SDL_MUSTLOCK(screen))   
   SDL_UnlockSurface(screen);  
   
  // Tell SDL to update the whole screen  
  SDL_UpdateRect(screen, 0, 0, 640, 480);    
 }  
   
 vector<triangle> scene;  
 vector3 eyePosition(0,0,-2);  
 vector3 screenPosition(0,0,-1);  
 double screenxwidth = 2;  
 double screenywidth = 1.5;  
 unsigned int backgroundcolor = 0;   
   
   
 // RAY TRACING FUNCTIONS  
 bool ray_sphere_intersect(vector3 &eye, vector3 &dir, sphere &S, double t0, double t1, double &new_t)  
 {  
      double dis = scalarProduct(dir, vectorMinus(eye, S.center));  
      dis = dis*dis;  
      dis = dis - scalarProduct(dir,dir)*( scalarProduct(vectorMinus(eye,S.center),vectorMinus(eye,S.center)) - S.radius*S.radius);  
        
      if (dis < 0)  
      {  
             
           return false;  
      }  
      dis = sqrt(dis);  
        
      double shitTerm = scalarProduct(vectorScale(dir, -1), vectorMinus(eye, S.center));  
      double bottomTerm = scalarProduct(dir,dir);  
        
      double time_1 = (shitTerm - dis)/bottomTerm;  
      double time_2 = (shitTerm + dis)/bottomTerm;  
      if (time_1 < 0 && time_2 < 0)  
      {  
           return false;  
      }  
      else if (time_1 < 0)  
      {  
           new_t = time_2;  
      }  
      else if (time_2 < 0)  
      {  
           new_t = time_1;  
      }  
      else  
      {  
           if (time_1 < time_2)  
           {  
                new_t = time_1;  
           }  
           else  
           {  
                new_t = time_2;  
           }  
      }  
      if (new_t < t0 || new_t > t1)  
      {  
           return false;  
      }  
   
      return true;  
 }  
 bool ray_triangle_intersect(vector3 eye, vector3 dir, triangle T, double t0, double t1,  
                                                                       double &new_beta, double &new_gamma,double &new_t)  
 {  
      vector3 v_a = T.v1;  
      vector3 v_b = T.v2;  
      vector3 v_c = T.v3;  
        
      double a = v_a.x - v_b.x;  
      double b = v_a.y - v_b.y;  
      double c = v_a.z - v_b.z;  
      double d = v_a.x - v_c.x;  
      double e = v_a.y - v_c.y;  
      double f = v_a.z - v_c.z;  
      double g = dir.x;  
      double h = dir.y;  
      double i = dir.z;  
        
      double j = v_a.x - eye.x;  
      double k = v_a.y - eye.y;  
      double l = v_a.z - eye.z;  
        
      //compute M  
      double M = a*(e*i - h*f) + b*(g*f -d*i) + c*(d*h - e*g);  
      //compute t  
      double t = (-1*(f*(a*k - j*b) +e*(j*c - a*l) + d*(b*l - k*c)))/M;  
        
      if (t < t0 || t > t1)  
      {  
           return false;  
      }  
        
      //compute gamma  
      double gamma = (i*(a*k - j*b)+ h*(j*c -a*l) + g*(b*l - k*c))/M;  
        
      if (gamma < 0 || gamma > 1)  
      {  
           return false;  
      }  
      //compute beta  
      double beta = (j*(e*i - h*f) + k*(g*f - d*i) + l*(d*h - e*g))/M;  
        
      if (beta < 0 || beta > 1-gamma)  
      {  
           return false;  
      }  
        
      new_t = t;  
      new_gamma = gamma;  
      new_beta = beta;  
      return true;  
   
        
   
 }  
 bool ray_hits_any_shape(bool &isTriangle, triangle &vis_tri, sphere &vis_sphere, vector3 eye, vector3 dir,  
                                                                       double &new_beta, double &new_gamma, double &new_t)  
 {  
      double tempBeta;  
      double tempGamma;  
      double t0 = .0001;  
      double t1 = INT_MAX; //switch this to max float  
      bool hit = false;  
      // check triangles  
      for (int i = 0; i < scene.size(); i++)  
      {  
           if (ray_triangle_intersect(eye, dir, scene[i], t0, t1, tempBeta, tempGamma,new_t))  
           {  
                new_beta = tempBeta;  
                new_gamma = tempGamma;  
                t1 = new_t;  
                hit = true;  
                vis_tri = scene[i];  
                isTriangle = true;  
           }  
      }  
      // check spheres  
      for (int i = 0; i < scene_sphere.size(); i++)  
      {  
           if (ray_sphere_intersect(eye, dir, scene_sphere[i], t0, t1, new_t))  
           {  
                t1 = new_t;  
                hit = true;  
                vis_sphere = scene_sphere[i];  
                isTriangle = false;  
           }  
      }  
      return hit;  
 }  
   
 bool in_shadow(vector3 hitpoint)  
 {  
      triangle vis_tri;  
      sphere vis_sphere;  
      double new_beta;  
      double new_gamma;  
      double new_t;  
      bool isTriangle;  
        
      return ray_hits_any_shape(isTriangle,vis_tri,vis_sphere,hitpoint,light_dir,  
                                                                       new_beta, new_gamma, new_t);  
 }  
 void ray_trace()  
 {  
           vector3 normalish = scene[0].getNormalVector();  
            normalish = scene[1].getNormalVector();  
           double xstart = -1*screenxwidth/2;  
      double xend = screenxwidth/2;  
      double ystart = -1*screenywidth/2;  
      double yend = screenywidth/2;  
      double xincrement = screenxwidth/S_WIDTH;  
      double yincrement = screenywidth/S_HEIGHT;  
        
      for (int x = 0; x < S_WIDTH; x++)  
      {  
           for (int y = 0; y < S_HEIGHT; y++)  
           {  
                vector3 screenpoint(xstart + x*xincrement, ystart + y*yincrement, screenPosition.z);  
                vector3 d = vectorMinus(screenpoint,eyePosition);  
                triangle vis_tri;  
                double beta;  
                double gamma;  
                double t;  
                bool isTriangle;  
                sphere vis_sphere;  
                if (ray_hits_any_shape(isTriangle,vis_tri,vis_sphere,eyePosition, d, beta, gamma, t))  
                {  
                      vector3 intersectLoc(eyePosition.x + t*d.x, eyePosition.y + t*d.y, eyePosition.z + t*d.z);  
                     vector3 normalToShape;  
                     unsigned int color;  
   
                     if (isTriangle)  
                     {  
                          //cout << "triangle" << endl;  
                          color = vis_tri.color;  
                          if (vis_tri.textured == true)  
                          {  
                               int xcoord = (int)intersectLoc.x;  
                               int zcoord = (int)intersectLoc.z;  
                               double d = 15;  
                               int c = (int)ceil(xcoord/d);  
                               if (c %2 == 0)  
                               {  
                                    color = 0;  
                                    c = (int)ceil(zcoord/d);  
                                    if (c %2 == 1)  
                                    {  
                                         color = vis_tri.color;  
                                    }  
                                      
                               }  
                               else  
                               {  
                                    c = (int)ceil(zcoord/d);  
                                    if (c %2 == 1)  
                                    {  
                                         color = 0;  
                                    }  
                               }  
                                 
                                 
                            
                          }  
                          normalToShape = vis_tri.getNormalVector();  
                     }  
                     else  
                     {  
                          color = vis_sphere.color;  
                            
                      normalToShape = vectorMinus(intersectLoc, vis_sphere.center);  
                      normalToShape.x = normalToShape.x/vis_sphere.radius;  
                      normalToShape.y = normalToShape.y/vis_sphere.radius;  
                      normalToShape.z = normalToShape.z/vis_sphere.radius;  
                     }  
                       
                     double alpha = 1 - beta - gamma;  
                  
                       
                     ////  
                     double angleBetweenNormalAndLight = scalarProduct(normalToShape,light_dir);  
                  
                     if (angleBetweenNormalAndLight < 0)  
                     {  
                          if (bidirectionalLighting)  
                          {  
                               angleBetweenNormalAndLight = fabs(angleBetweenNormalAndLight);  
                          }  
                          else  
                          {  
                               angleBetweenNormalAndLight = 0;  
                          }  
                     }  
                       
                     if (in_shadow(intersectLoc)) //use just ambient light  
                     {  
                          //cout << "in shadow =)" << endl;  
                          //cout << "intersectLoc = " << intersectLoc.x << " " << intersectLoc.y << " " << intersectLoc.z << endl;  
                          angleBetweenNormalAndLight = 0;  
                     }  
                       
                     double colorscalar = lighting_mix + (1 - lighting_mix)*angleBetweenNormalAndLight;  
                       
                     unsigned int mask = 0x00FFFFFF;  
                     unsigned int redChannel = color & mask;  
                     redChannel = redChannel >> 16;  
             
                     mask = 0x0000FF00;  
                     unsigned int greenChannel = color & mask;  
                       
                     greenChannel = greenChannel >> 8;  
             
                     mask = 0x000000FF;  
                     unsigned int blueChannel = color & mask;  
                     //cout << "blue channel " << blueChannel << endl;  
                     double nRed = colorscalar*((double)redChannel);  
                     double nGreen = colorscalar*((double)greenChannel);  
                     double nBlue = colorscalar*((double)blueChannel);  
                       
                     redChannel = (unsigned int) nRed;  
                     greenChannel = (unsigned int) nGreen;  
                     blueChannel = (unsigned int) nBlue;  
                       
                     redChannel = redChannel << 16;  
                     greenChannel = greenChannel << 8;  
                       
                     unsigned int colorToAssign = redChannel + greenChannel + blueChannel;  
                     ((unsigned int *) screen->pixels)[y*S_WIDTH+x]=colorToAssign;  
                }  
                else //color it the background color   
                {  
                     //cout << "  !!!! didnt hit" << endl;  
                          ((unsigned int *) screen->pixels)[y*S_WIDTH+x]=backgroundcolor;  
                }  
           }  
      }  
 }  
   
 // Entry point  
 int main(int argc, char *argv[])  
 {  
        
 vector3 v1(1,2,3);  
 vector3 v2(3,2,1);  
 vector3 v3 = vectorMinus(v1,v2);  
      srand(static_cast<unsigned>(time(0)));  
      mat3h mat1;  
      mat3h mat2;  
      mat1.identity();  
      mat2.identity();  
      mat3h mat3 = mat3hMult(mat1,mat2);  
      for (int i = 0; i < 4; i++)  
      {  
           for (int j = 0; j < 4; j++)  
           {  
                cout << mat3.matrix[i][j] << " ";   
           }  
           cout << endl;  
      }  
      vector3 haha = matMult(mat3, vector3(1,2,3));  
      cout << "test = " << haha.x << " " << haha.y << " " << haha.z << endl;  
        
        
      // test this shit  
      vector3 c(0,0,20);  
      vector3 b(100,0,20);  
      vector3 a(50,100,0);  
        
      vector3 c1(0,100,20);  
      vector3 b1(100,100,20);  
      vector3 a1(50,0,0);  
   
        
      vector3 output = vectorCross(a,b);  
      //cout << "output is: " << output.x << " " << output.y << " " << output.z << endl;  
        
      triangle crap(c,b,a,0xffffff);  
        
      triangle crapass(c1,b1,a1,0xffff00);  
      cout << "area = " << crapass.signedAreaXY() << endl;  
      double alpha;  
      double beta;  
      double gamma;  
      vector3 v(50,50,0);  
      crapass.baryXY(v, alpha, beta, gamma);  
      cout << "printing bary coords: " << endl;  
      cout << "a = " << alpha << " b = " << beta << " y = " << gamma << endl;  
        
        
        
  // Initialize SDL's subsystems - in this case, only video.  
  if ( SDL_Init(SDL_INIT_VIDEO) < 0 )   
   {  
    fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());  
    exit(1);  
   }  
   
  // Register SDL_Quit to be called at exit; makes sure things are  
  // cleaned up when we quit.  
  atexit(SDL_Quit);  
     
  // Attempt to create a 640x480 window with 32bit pixels.  
  screen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE);  
    
  // If we fail, return error.  
  if ( screen == NULL )   
   {  
    fprintf(stderr, "Unable to set 640x480 video: %s\n", SDL_GetError());  
    exit(1);  
   }  
    
   
             
                     vector3 cubeLocation(0,0,50);  
   
        
             
           // define icosahedron  
           vector3 figurepoints[12];  
           figurepoints[0] = vector3(-0.692,0,0.427);  
           figurepoints[1] = vector3(0.0,0.427,-0.692);  
           figurepoints[2] = vector3(0.0,0.427,0.692);  
           figurepoints[3] = vector3(0.692,0.0,-0.427);  
           figurepoints[4] = vector3(-0.427,-0.692,0.0);  
           figurepoints[5] = vector3(-0.427,0.692,0.0);  
           figurepoints[6] = vector3(0.0,-0.427,0.692);  
           figurepoints[7] = vector3(0.427,0.692,0.0);  
           figurepoints[8] = vector3(0.0,-0.427,-0.692);  
           figurepoints[9] = vector3(0.692,0.0,0.427);  
           figurepoints[10] = vector3(0.427,-0.692,0.0);  
           figurepoints[11] = vector3(-0.692,0.0,-0.427);  
           double scaleFactor = 20;  
           for (int i = 0 ; i < 12; i++)  
           {  
                     figurepoints[i].x = figurepoints[i].x * scaleFactor;  
                     figurepoints[i].y = figurepoints[i].y * scaleFactor;  
                     figurepoints[i].z = figurepoints[i].z * scaleFactor;  
           }  
        
           unsigned int tempcolor = 0x8a4b2c;  
           scene.push_back(triangle(figurepoints[9],figurepoints[2],figurepoints[6],tempcolor));  
           scene.push_back(triangle(figurepoints[1],figurepoints[5],figurepoints[11],tempcolor));  
           scene.push_back(triangle(figurepoints[11],figurepoints[1],figurepoints[8],tempcolor));  
           scene.push_back(triangle(figurepoints[0],figurepoints[11],figurepoints[4],tempcolor));  
           scene.push_back(triangle(figurepoints[3],figurepoints[7],figurepoints[1],tempcolor));  
           scene.push_back(triangle(figurepoints[3],figurepoints[1],figurepoints[8],tempcolor));  
           scene.push_back(triangle(figurepoints[9],figurepoints[3],figurepoints[7],tempcolor));  
           scene.push_back(triangle(figurepoints[0],figurepoints[2],figurepoints[6],tempcolor));  
           scene.push_back(triangle(figurepoints[4],figurepoints[6],figurepoints[10],tempcolor));  
           scene.push_back(triangle(figurepoints[1],figurepoints[7],figurepoints[5],tempcolor));  
           scene.push_back(triangle(figurepoints[7],figurepoints[2],figurepoints[5],tempcolor));  
           scene.push_back(triangle(figurepoints[8],figurepoints[10],figurepoints[3],tempcolor));  
        
           scene.push_back(triangle(figurepoints[4],figurepoints[11],figurepoints[8],tempcolor));  
           scene.push_back(triangle(figurepoints[9],figurepoints[2],figurepoints[7],tempcolor));  
           scene.push_back(triangle(figurepoints[10],figurepoints[6],figurepoints[9],tempcolor));  
           scene.push_back(triangle(figurepoints[0],figurepoints[11],figurepoints[5],tempcolor));  
           scene.push_back(triangle(figurepoints[0],figurepoints[2],figurepoints[5],tempcolor));  
           scene.push_back(triangle(figurepoints[8],figurepoints[10],figurepoints[4],tempcolor));  
           scene.push_back(triangle(figurepoints[3],figurepoints[9],figurepoints[10],tempcolor));  
           scene.push_back(triangle(figurepoints[6],figurepoints[4],figurepoints[0],tempcolor));  
   
 //get normals to point in right direction  
 for (int i = 0; i < scene.size(); i++)  
 {  
      vector3 fromOriginToTriangle = scene[i].v1;  
      fromOriginToTriangle.makeUnitVector();  
      vector3 normal = scene[i].getNormalVector();  
      if (scalarProduct(normal,fromOriginToTriangle) < 0)  
      {  
           //flip two verticies;  
           vector3 temp = scene[i].v1;  
           scene[i].v1 = scene[i].v2;  
           scene[i].v2 = temp;  
      }  
 }  
   
 // add spheres  
 scene_sphere.push_back(sphere(0,0,25,5,0x8aafded));  
   
   
 // move objects to center of screen  
 mat3h moveToCenter;  
 mat3h moveToOrigin;  
 moveToCenter.identity();  
 moveToCenter.matrix[0][3] = cubeLocation.x;  
 moveToCenter.matrix[1][3] = cubeLocation.y;  
 moveToCenter.matrix[2][3] = cubeLocation.z;  
 for (int i = 0; i < scene.size(); i++)  
 {  
      //move cube out to screen  
      scene[i].v1 = matMult(moveToCenter,scene[i].v1);  
      scene[i].v2 = matMult(moveToCenter,scene[i].v2);  
      scene[i].v3 = matMult(moveToCenter,scene[i].v3);  
 }  
             
 // add bottom plane  
 triangle bottom1 = triangle(vector3(-INT_MAX,30,-INT_MAX),vector3(-INT_MAX,30,INT_MAX),vector3(INT_MAX,30,-INT_MAX),0x105C1C, true);  
 bottom1.flipNormal();  
   
 triangle bottom2 = triangle(vector3(INT_MAX,30,-INT_MAX),vector3(-INT_MAX,30,INT_MAX),vector3(INT_MAX,30,INT_MAX),0x105C1C,true);  
 bottom2.flipNormal();  
        
      
 scene.push_back(bottom1);  
 scene.push_back(bottom2);  
   
 vector3 hitcrap(0,30,25);  
 if (in_shadow(hitcrap))  
 {  
      cout << "hehe hit" << endl;  
 }  
   
             
   
           double xMaxIncrement = .01;  
           double yMaxIncrement = .05;  
           double zMaxIncrement = .05;  
             
                  
                ray_trace();  
           while (1)  
           {  
           /*     //paint screen black  
                for (int i = 0; i < S_WIDTH; i++)  
                {  
                     for (int j = 0; j < S_HEIGHT; j++)  
                     {  
                          ((unsigned int *) screen->pixels)[j*S_WIDTH+i]=0;  
                     }  
                }  
                //initialize zbuffer  
                for (int i = 0; i < 640; i++)  
                {  
                     for (int j = 0; j < 480; j++)  
                     {  
                          zbuffer[i][j] = INT_MAX;  
                     }  
                }  
                  
                mat3h rotateX;  
                mat3h rotateY;  
                mat3h rotateZ;  
                rotateX.identity();  
                rotateY.identity();  
                rotateZ.identity();  
                if (tumblingEnabled)  
                {  
                // update rotations  
                     double xIncrement = ((double)rand()/RAND_MAX)*xMaxIncrement;  
                     double yIncrement = ((double)rand()/RAND_MAX)*yMaxIncrement;  
                     double zIncrement = ((double)rand()/RAND_MAX)*zMaxIncrement;  
                // get rotation matricies  
                rotateX = rot3hX(xIncrement);  
                rotateY = rot3hY(yIncrement);  
                rotateZ = rot3hZ(zIncrement);  
           }  
                  
                     double xMaxLightIncrement = 0;  
                double yMaxLightIncrement = 0;  
                double zMaxLightIncrement = 0;  
                // update rotations  
                     double xlIncrement = ((double)rand()/RAND_MAX)*xMaxLightIncrement;  
                     double ylIncrement = ((double)rand()/RAND_MAX)*yMaxLightIncrement;  
                     double zlIncrement = ((double)rand()/RAND_MAX)*zMaxLightIncrement;  
                       
                       
                mat3h rotateLightX = rot3hX(xlIncrement);  
                mat3h rotateLightY = rot3hY(ylIncrement);  
                mat3h rotateLightZ = rot3hZ(zlIncrement);  
             
                  
                if (revolvingLight)  
                {  
                     light_dir = matMult(rotateLightX, light_dir);  
                     light_dir = matMult(rotateLightY, light_dir);  
                     light_dir = matMult(rotateLightZ, light_dir);  
                }  
        
                // rotate, transpose, and rasterize  
                for (int i = 0; i < scene.size(); i++)  
                {  
                     //create bring to origin matrix  
                     moveToOrigin.identity();  
                     moveToOrigin.matrix[0][3] = -1*cubeLocation.x;  
                     moveToOrigin.matrix[1][3] = -1*cubeLocation.y;  
                     moveToOrigin.matrix[2][3] = -1*cubeLocation.z;  
                       
                     //bring to origin  
                     scene[i].v1 = matMult(moveToOrigin,scene[i].v1);  
                     scene[i].v2 = matMult(moveToOrigin,scene[i].v2);  
                     scene[i].v3 = matMult(moveToOrigin,scene[i].v3);  
                  
                     //rotate x  
                     scene[i].v1 = matMult(rotateX,scene[i].v1);  
                     scene[i].v2 = matMult(rotateX,scene[i].v2);  
                     scene[i].v3 = matMult(rotateX,scene[i].v3);  
                       
                     // rotate y  
                     scene[i].v1 = matMult(rotateY,scene[i].v1);  
                     scene[i].v2 = matMult(rotateY,scene[i].v2);  
                     scene[i].v3 = matMult(rotateY,scene[i].v3);  
                       
                     // rotate z  
                     scene[i].v1 = matMult(rotateZ,scene[i].v1);  
                     scene[i].v2 = matMult(rotateZ,scene[i].v2);  
                     scene[i].v3 = matMult(rotateZ,scene[i].v3);   
                       
                     // create move to center matrix  
                     moveToCenter.identity();  
                     moveToCenter.matrix[0][3] = cubeLocation.x;  
                     moveToCenter.matrix[1][3] = cubeLocation.y;  
                     moveToCenter.matrix[2][3] = cubeLocation.z;  
                       
                     //move cube out to screen  
                     scene[i].v1 = matMult(moveToCenter,scene[i].v1);  
                     scene[i].v2 = matMult(moveToCenter,scene[i].v2);  
                     scene[i].v3 = matMult(moveToCenter,scene[i].v3);  
                       
                       
                     if (!rayTracingEnabled)  
                     {  
                          scene[i].rasterize();  
                     }  
        
                }  
              
                // Render shit  
             
                if (rayTracingEnabled)  
                {  
                     ray_trace();  
                }*/  
                render();  
   
                //set lighting if revolvingLight is on  
                  
                  
                       
                     //temp fix  
                     //xIncrement = 0;  
                     //yIncrement = 0;  
                     //zIncrement = 0;  
             
             
            // Poll for events, and handle the ones we care about.  
              
            SDL_Event event;  
            while (SDL_PollEvent(&event))   
            {  
        switch (event.type) {  
   
    case SDL_KEYUP:  
     // determine which key is released  
     switch (event.key.keysym.sym) {  
     // If escape is pressed, quit  
      case SDLK_ESCAPE:  
     exit(0);  
     break;  
      case SDLK_BACKQUOTE:  
     lighting_mix = .0;  
     break;  
      case SDLK_1:  
     lighting_mix = .1;  
     break;  
      case SDLK_2:  
     lighting_mix = .2;  
     break;  
      case SDLK_3:  
     lighting_mix = .3;  
     break;  
      case SDLK_4:  
     lighting_mix = .4;  
     break;  
      case SDLK_5:  
     lighting_mix = .5;  
     break;  
      case SDLK_6:  
     lighting_mix = .6;  
     break;  
      case SDLK_7:  
     lighting_mix = .7;  
     break;  
      case SDLK_8:  
     lighting_mix = .8;  
     break;  
      case SDLK_9:  
     lighting_mix = .9;  
     break;  
      case SDLK_0:  
     lighting_mix = 1.0;  
     break;  
      case SDLK_RETURN:  
     // toggle between the figure rotating and the light revolving  
     // (extra credit)  
     revolvingLight = !revolvingLight;  
     break;   
      case SDLK_TAB:  
     // toggle between bidirectional and unidirectional lighting  
     bidirectionalLighting = !bidirectionalLighting;  
     break;  
      case SDLK_SPACE:  
     // toggle tumbling  
     tumblingEnabled = !tumblingEnabled;  
     break;  
       }  
       break;  
    case SDL_QUIT:  
     exit(0);  
    }   
   }  
              
            /* while (SDL_PollEvent(&event))   
                {  
             
                     switch (event.type)   
                 {  
                 case SDL_KEYDOWN:  
             break;  
            case SDL_KEYUP:  
             // If escape is pressed, return (and thus, quit)  
             if (event.key.keysym.sym == SDLK_ESCAPE)  
           return 0;  
             break;  
            case SDL_QUIT:  
             return(0);  
            }  
           }*/  
           }  
           return 0;  
 }