+ int i, j;
+ float aspect = (float)width / (float)height;
+
+ for(i=0; i<height; i++) {
+ for(j=0; j<width; j++) {
+ csg_render_pixel(j, i, width, height, aspect, pixels);
+ pixels += 3;
+ }
+ }
+}
+
+static void calc_primary_ray(struct ray *ray, int x, int y, int w, int h, float aspect)
+{
+ float px, py;
+
+ px = aspect * ((float)x / (float)w * 2.0f - 1.0f);
+ py = 1.0f - (float)y / (float)h * 2.0f;
+
+ ray->x = px;
+ ray->y = py;
+ ray->z = cam.z;
+
+ ray->dx = ray->dy = 0.0f;
+ ray->dz = -1.0f;
+}
+
+static int ray_trace(struct ray *ray, float *col)
+{
+ struct hit hit;
+
+ if(!find_intersection(ray, &hit)) {
+ background(col, ray);
+ return 0;
+ }
+
+ shade(col, ray, &hit);
+ return 1;
+}
+
+static void shade(float *col, struct ray *ray, struct hit *hit)
+{
+ col[0] = 1.0f;
+ col[1] = col[2] = 0.0f;
+}
+
+static void background(float *col, struct ray *ray)
+{
+ col[0] = col[1] = col[2] = 0.0f;
+}
+
+static int find_intersection(struct ray *ray, struct hit *best)
+{
+ csg_object *o;
+ struct hit *hit;
+
+ best->t = 1e-6f;
+ best->o = 0;
+
+ o = oblist;
+ while(o) {
+ if((hit = ray_intersect(ray, o)) && hit->t < best->t) {
+ *best = *hit;
+ }
+ free_hit(hit);
+ o = o->ob.next;
+ }
+
+ return best->o != 0;