/******************************************************************/ /* Main raytracer file, Project 6, CS345 */ /* By: (Your name here) */ /******************************************************************/ #include #include #include #include #include #include #include #include #include "lowlevel.h" #include "raytrace.h" /* local functions */ void initScene(void); void initCamera (int, int); void display(void); void init(int, int); void traceRay(ray*,color*); void drawScene(void); void firstHit(ray*,point*,vector*,material**); /* local data */ /* parameters defining the camera */ point* viewpoint; GLfloat pnear; /* distance from viewpoint to image plane */ GLfloat fovx; /* x-angle of view frustum */ int width; /* width of window in pixels */ int height; /* height of window in pixels */ /* some geometry functions */ point* makePoint(GLfloat x, GLfloat y, GLfloat z, GLfloat w) { point* p; /* allocate memory */ p = (point*) malloc(sizeof(point)); /* put stuff in it */ p->x = x; p->y = y; p->z = z; p->w = w; return (p); } sphere* makeSphere(GLfloat x, GLfloat y, GLfloat z, GLfloat r) { sphere* s; /* allocate memory */ s = (sphere*) malloc(sizeof(sphere)); /* put stuff in it */ s->c = makePoint(x,y,z,1.0); /* center */ s->r = r; /* radius */ s->m = NULL; /* material */ return(s); } /* returns the color seen by ray r in parameter c */ void rayColor(ray* r, color* c) { point p; /* first intersection point */ vector n; material* m; p.w = 0.0; /* inialize to "no intersection" */ trace(r,&p,&n,&m); if (p.w != 0.0) { shade(&p,&n,m,c); /* do the lighting calculations */ } else { /* nothing was hit */ c->r = 0.0; c->g = 0.0; c->b = 0.0; } } /* vector from point p to point q is returned in v */ void calculateDirection(point* p, point* q, point* v) { float length; v->x = q->x - p->x; v->y = q->y - p->y; v->z = q->z - p->z; /* a direction is a point at infinity */ v->w = 0.0; } /* The main program */ /* Just sets up window and display callback */ int main (int argc, char** argv) { int win; glutInit(&argc,argv); glutInitWindowSize(500,350); glutInitWindowPosition(100,100); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); win = glutCreateWindow("raytrace"); glutSetWindow(win); init(500,350); glutDisplayFunc(display); glutMainLoop(); return 0; } void init(w,h) { /* OpenGL setup */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0); glClearColor(0.0, 0.0, 0.0, 1.0); /* low-level graphics setup */ initCanvas(w,h); /* raytracer setup */ initCamera(w,h); initScene(); } void display() { glClear(GL_COLOR_BUFFER_BIT); drawScene(); /* draws the picture in the canvas */ flushCanvas(); /* draw the canvas to the OpenGL window */ glFlush(); } /* Camera placement. NOTE: The placement of the image rectangle is hard-coded to be parallel to the x-y plane, in the plane z=(viewpoint.z = - pnear) (that is, looking down the negative z axis, just like OpenGL), with the viewpoint centered with respect to x,y. */ void initCamera (int w, int h) { viewpoint = makePoint(0.0,0.0,0.0,1.0); pnear = -1.0; fovx = M_PI/6; /* window dimensions */ width = w; height = h; } void initScene () { s1 = makeSphere(0.0,0.0,-2.0,0.25); s1->m = makeMaterial(0.8,0.1,0.15,0.3); } void drawScene () { int i,j; GLfloat imageWidth; /* declare data structures on stack to avoid malloc & free */ point worldPix; /* current pixel in world coordinates */ point direction; ray r; color c; /* z and w are constant for all pixels */ worldPix.w = 1.0; worldPix.z = pnear; r.start = &worldPix; r.end = &direction; imageWidth = 2*pnear*tan(fovx/2); /* trace a ray for every pixel */ for (i=0; i