Commits

David Jones committed d076a8f

foo.

Comments (0)

Files changed (6)

+#include <assert.h>
+#include <stddef.h>
+
+#include "color.h"
+void
+color_add(Color * a, Color *b, 
+          Color *x)
+{
+  assert(a != NULL);
+  assert(b != NULL);
+  assert(x != NULL);
+  x->r = a->r + b->r;
+  x->g = a->g + b->g;
+  x->b = a->b + b->b;
+}
+
+void
+color_clear(Color * x)
+{
+ assert( x != NULL);
+  x->r = 0;
+  x->g = 0;
+  x->b = 0;
+}
+
+void 
+color_mult(Color * a, float b, Color *x)
+{
+ assert( a != NULL);
+ assert(x  != NULL);
+ x->r = a->r * b;
+ x->g = a->g * b;
+ x->b = a->b * b;
+}
+
+
+void 
+in_range(float *f, float a, float b)
+{
+  if (*f < a) {
+    *f = a;
+  } else if (*f > b) {
+    *f = b;
+  } 
+}
+    
+void 
+color_truncate(Color *a)
+{
+ assert( a != NULL);
+ 
+ in_range(&a->r, 0.0, 1.0);
+ in_range(&a->g, 0.0, 1.0);
+ in_range(&a->b, 0.0, 1.0);
+}
+#ifndef HEADER_GUARD_COLOR_H
+#define HEADER_GUARD_COLOR_H
+
+
+typedef struct
+{
+  float r;
+  float g;
+  float b;
+} Color;
+
+void
+color_add(Color * a, Color *b, 
+          Color *x);
+
+void
+color_clear(Color * x);
+
+
+void 
+color_mult(Color * a, float b, Color *x);
+
+void 
+color_truncate(Color *a);
+
+
+#endif
 tester: all
 #	./test_file
 	# ./test1
-	./ray_trace && display ,output.pgm
+	./ray_trace && display ,output.ppm
 
 all: m_exes
 
 
 
 local_lib := ray_trace.a
-local_objs:= vec3.o sphere.o plane.o
+local_objs:= vec3.o color.o sphere.o plane.o
 include module.mk
 
 
 {
   Vec3 camera_position;
   Vec3 view_center;
-  Light light;
   int view_height;
   int view_width;
+
+
+  int num_lights;
+  Light ** lights;
+
+
   Primitive ** primitives;
   int num_primitives;
 
   int ii, jj;
   unsigned char * buffer;
   FILE * fp = fopen(filename, "w");
-  int max_int = 255;
+  int max_int = 254;
 
   assert(ptr!=NULL);
   assert(fp != NULL);
-  buffer = dmalloc(ptr->width);
-  fprintf(fp, "P5 %i %i %i\n", ptr->width, ptr->height, max_int);
+  buffer = dmalloc(3*ptr->width);
+  fprintf(fp, "P6 %i %i %i\n", ptr->width, ptr->height, max_int);
   
   for(ii = 0; ii < ptr->height; ++ii) {
-    float * tmp = ptr->image + (ii*ptr->height);
+    Color * tmp = ptr->image + (ii*ptr->height);
     for(jj = 0; jj < ptr->width; ++jj) {
-      buffer[jj] = max_int * (tmp[jj]);
+      color_truncate(&tmp[jj]);
+      buffer[3*jj] = tmp[jj].r * max_int;
+      buffer[3*jj + 1] = tmp[jj].g * max_int;
+      buffer[3*jj + 2] = tmp[jj].b * max_int;
+
+
     }
-    fwrite(buffer, 1, ptr->width, fp);
+    fwrite(buffer, 1, 3*ptr->width, fp);
   }
   fclose(fp);
   dfree(buffer);
 
 char log_buffer[1024];
 
+
+Primitive *
+ray_trace(Scene * s, Ray * ray, Color * color, int depth, Vec3 * point)
+{
+  assert(s != NULL);
+  assert(ray != NULL);
+  assert(color != NULL);
+  assert(point != NULL);
+
+
+  Vec3 best_point;
+  float best_dist = 1e38;
+  int best_prim = -1;
+  Primitive * c;
+  int ii = 0;
+
+  for(ii = 0; ii < s->num_primitives; ++ii) {
+    // for each primitive
+    c = s->primitives[ii];
+    int tmp = (c->ops->intersects)(c, ray, point);
+    // find distance
+    if(tmp) {
+      Vec3 dist;
+      vec_subtract(&(ray->origin), point, &dist);
+      float d = vec_dot(&dist, &dist);
+      if(d < best_dist) {
+        best_prim = ii;
+        best_dist = d;
+        best_point = *point;
+      }
+    }
+  }
+  
+  if(best_prim == -1) {
+    return 0;
+  } else {
+    //sprintf(log_buffer,"hit primitive: %d, point: <%f,%f,%f>",
+    //best_prim, best_point.x, best_point.y, best_point.z);
+    //log_message(log_buffer,1,1);
+    c = s->primitives[best_prim];
+
+    int ii = 0;
+    
+    for(ii = 0; ii < s->num_lights; ++ii) {
+      Light * li = s->lights[ii];
+      Vec3 normal;
+      Vec3 to_light;
+      float shade = 1.0;
+      vec_subtract(&(li->position), &best_point, &to_light);
+      float dist_to_light = vec_dot(&to_light, &to_light);
+      float divisor = 1.0/vec_dot(&to_light, &to_light);
+      divisor = sqrt(divisor);
+      vec_mult_scalar(divisor, &to_light, &to_light);
+
+      int jj = 0;
+      {
+        Ray tmp;
+        tmp.origin = best_point;
+        tmp.direction = to_light;
+        Vec3 xx = tmp.direction;
+        vec_mult_scalar(.001, &xx, &xx);
+        vec_add(&tmp.origin, &xx, &tmp.origin);
+
+        for(jj = 0; jj < s->num_primitives; ++jj) {
+          if(jj == best_prim) continue;
+          Primitive * cp = s->primitives[jj];
+          Vec3 np;
+          int r = (cp->ops->intersects)(cp, &tmp, &np);
+
+          if(r) {
+            Vec3 dist;
+            vec_subtract(&np, &(tmp.origin),  &dist);
+            float d = vec_dot(&dist, &dist);
+            if(d < dist_to_light) {
+              //vec_print(stdout, &tmp.origin);
+              //              printf("\n");
+              //              vec_print(stdout, &to_light);
+              //              printf("\n");
+              //              vec_print(stdout, &best_point);
+              //              printf("\n");
+              //vec_print(stdout, &li->position);
+              //printf("\n");
+              //vec_print(stdout, &np);
+              //printf("\n");
+
+              //printf(" best_prim: %d, jj: %d, d: %f, dist_to_light: %f\n",
+              //                     best_prim, jj, d, dist_to_light);
+              shade = 0.0;
+              break;
+            }
+          }          
+        }
+      }
+        
+
+      vec_norm(&to_light,&to_light);
+      (c->ops->get_normal)(c, &best_point, &normal);
+      // log_message("TRACE",1,1);
+
+      float dot = vec_dot(&normal, &to_light);
+      
+      if (dot > 0) {
+        Color prim_color = (c->ops->get_color)(c);
+        color_mult(&prim_color, shade * dot, &prim_color);
+        color_add(color, &prim_color, color);
+      } else {
+      }
+    }
+  }
+  // log_message("TRACE2",1,1);
+}
+
+
 void 
-ray_trace(Scene * s, 
+render(Scene * s, 
           const char * filename) 
 {
   Image im;
   assert(s != NULL);
   im.width = s->view_width;
   im.height = s->view_height;
-  im.image = dmalloc(sizeof(float) * s->view_height * s->view_width);
-  for(i = 0; i < s->view_height; ++i) {
-    for(j = 0; j < s->view_width; ++j) {
-      // Calculate the ray to use.
+  im.image = dmalloc(sizeof(Color) * s->view_height * s->view_width);
+
+  Ray ray;
+  ray.origin = s->camera_position;
+
+  for(j = 0; j < s->view_height; ++j) {
+    for(i = 0; i < s->view_width; ++i) {
       //sprintf(log_buffer, "i: %d, j: %d", i, j);
       //log_message(log_buffer, 1,0);
-      Ray ray;
-      ray.origin = s->camera_position;
       {
         Vec3 a;
-        a.x = -(s->view_height/2) + i;// + 1.0*rand()/RAND_MAX ;
-        a.y = -(s->view_width/2) + j; //+ 1.0*rand()/RAND_MAX ;;
+        a.x = -(s->view_width/2) + j; //+ 1.0*rand()/RAND_MAX ;;
+        a.y = (s->view_height/2) - i;// + 1.0*rand()/RAND_MAX ;
         a.z = -0;
         // printf("point: ");
         // vec_print(stdout, &a);
       //              ray.direction.x, ray.direction.y, ray.direction.z);
       //      log_message(log_buffer, 1,1);
       // Find the first intersection point
+      Color color;
+      color.r = 0;
+      color.g = 0;
+      color.b = 0;
       Vec3 point;
-      Vec3 best_point;
-      float best_dist = 1e38;
-      int best_prim = -1;
-      Primitive * c;
-      int ii = 0;
-      for(ii = 0; ii < s->num_primitives; ++ii) {
-        // for each primitive
-        c = s->primitives[ii];
-        int tmp = (c->ops->intersects)(c, &ray, &point);
-        // find distance
-        if(tmp) {
-          Vec3 dist;
-          vec_subtract(&(ray.origin), &point, &dist);
-          float d = vec_dot(&dist, &dist);
-          if(d < best_dist) {
-            best_prim = ii;
-            best_dist = d;
-            best_point = point;
-          }
-        }
-      }
-
-      if(best_prim == -1) {
-        im.image[i*s->view_width + j] = 0;
-      } else {
-        //sprintf(log_buffer,"hit primitive: %d, point: <%f,%f,%f>",
-        //best_prim, best_point.x, best_point.y, best_point.z);
-        //log_message(log_buffer,1,1);
-        c = s->primitives[best_prim];
-        Vec3 normal;
-        Vec3 to_light;
-        vec_subtract(&(s->light.position), &best_point, &to_light);
-        vec_norm(&to_light,&to_light);
-
-        (c->ops->get_normal)(c, &best_point, &normal);
-        // log_message("TRACE",1,1);
-        float dot = vec_dot(&normal, &to_light);
-        if (dot > 0) {
-          im.image[i*s->view_width + j] = dot * (c->ops->get_color)(c);
-        } else {
-          im.image[i*s->view_width + j] = 0;
-        }
-      }
-      // log_message("TRACE2",1,1);
+      ray_trace(s, &ray, &color, 1, &point);
+      im.image[i*s->view_width + j] = color;
     }
   }
   write_image(&im, filename);
   int bookmark = get_bookmark();
   s.camera_position.x = 0;
   s.camera_position.y = 0;
-  s.camera_position.z = -300;
+  s.camera_position.z = -500;
   s.view_center.x = 0;
   s.view_center.y = 0;
   s.view_center.z = 0;
   
   s.view_height = 400;
   s.view_width = 400;
-  s.light.position.x = -2000;
-  s.light.position.y = 2000;
-  s.light.position.z = -000;
+
+  s.num_lights = 2;
+  s.lights = dmalloc(s.num_lights * sizeof(Light*));
+
+  s.lights[0] = dmalloc(sizeof(Light));
+  s.lights[0]->position.y = 2000;
+  s.lights[0]->position.x =  -20000;
+  s.lights[0]->position.z = -5000;
+
+  s.lights[1] = dmalloc(sizeof(Light));
+  s.lights[1]->position.x = 10000;
+  s.lights[1]->position.y = 10000;
+  s.lights[1]->position.z = 5000;
 
   s.num_primitives = 4;
   s.primitives = dmalloc(s.num_primitives*sizeof(Primitive*));
   sphere_init((Sphere*)s.primitives[0]);
   Sphere * tmps = (Sphere *) s.primitives[0];
 
-  tmps->center.x = 1000;
+  tmps->center.x = 5000;
   tmps->center.y = 2000;
-  tmps->center.z = 10000;
+  tmps->center.z = 15000;
   tmps->radius = 3000.0;
-  tmps->color = .9;
+  tmps->color.r = .2;
+  tmps->color.g = .1;
+  tmps->color.b = .001;
+
 
   s.primitives[1] = dmalloc(sizeof(Sphere));
   sphere_init((Sphere*)s.primitives[1]);
   tmps = (Sphere *) s.primitives[1];
 
-  tmps->center.y = 100;
-  tmps->center.x = 99650000;
-  tmps->center.z = 0;
-  tmps->radius =   99500000;
-  tmps->color = 1.0;
+  tmps->center.y = 1000;
+  tmps->center.x = -3000;
+  tmps->center.z = 15000;
+  tmps->radius =   3000;
+  tmps->color.r = .1;
+  tmps->color.g = .2;
+  tmps->color.b = .1;
+
 
 
   s.primitives[2] = dmalloc(sizeof(Sphere));
   sphere_init((Sphere*)s.primitives[2]);
   tmps = (Sphere *) s.primitives[2];
 
-  tmps->center.y = -800;
-  tmps->center.x = 400;
-  tmps->center.z = 2000;
-  tmps->radius =   100;
-  tmps->color = .2;
+  tmps->center.y = -4800;
+  tmps->center.x = -4000;
+  tmps->center.z = 17000;
+  tmps->radius =   1000;
+  tmps->color.r = .1;
+  tmps->color.g = .2;
+  tmps->color.b = .3;
 
 
 
   Plane * tmpp = (Plane *) s.primitives[3];
 
   tmpp->origin.y = 0;
-  tmpp->origin.x = 2000;
-  tmpp->origin.z = 0;
+  tmpp->origin.x = 0;
+  tmpp->origin.z = 80000;
 
-  tmpp->normal.y = 0;
-  tmpp->normal.x = -1;
-  tmpp->normal.z = 0;
+  tmpp->normal.y = 1;
+  tmpp->normal.x = 0;
+  tmpp->normal.z = -.2;
 
+  tmpp->color.r = .1;
+  tmpp->color.g = .7;
+  tmpp->color.b = .7;
 
-  tmpp->color = 1.0;
 
 
 
-
-  ray_trace(&s, ",output.pgm");
+  render(&s, ",output.ppm");
   /* 
   im.width = 256;
   im.height = 256;
   {
     int i;
     n = im.width * im.height;
-    for(i = 0; i < (im.width * im.height); ++i) {
+,    for(i = 0; i < (im.width * im.height); ++i) {
       im.image[i] = i / n;
       // printf("%f\n", im.image[i]);
     }
 #define HEADER_GUARD_RAY_TYPES_H
 
 #include "vec3.h"
-
+#include "color.h"
 
 typedef struct
 {
 {
   int width;
   int height;
-  float * image;
+  Color * image;
 } Image;
 
-typedef float Color;
 
 typedef struct
 {
   tmpp->normal.z = 1;
 
 
-  tmpp->color = 1.0;
+  tmpp->color.r = 1.0;
+  tmpp->color.g = 1.0;
+  tmpp->color.b = 1.0;
 
   Ray ray;
   ray.origin.x = 10;