diff options
Diffstat (limited to 'libdimension')
-rw-r--r-- | libdimension/dimension/scene.h | 7 | ||||
-rw-r--r-- | libdimension/raytrace.c | 76 | ||||
-rw-r--r-- | libdimension/scene.c | 1 |
3 files changed, 47 insertions, 37 deletions
diff --git a/libdimension/dimension/scene.h b/libdimension/dimension/scene.h index e76aef3..8104917 100644 --- a/libdimension/dimension/scene.h +++ b/libdimension/dimension/scene.h @@ -25,11 +25,18 @@ #ifndef DIMENSION_SCENE_H #define DIMENSION_SCENE_H +typedef enum { + DMNSN_RENDER_NONE, + DMNSN_RENDER_OBJECTS, + DMNSN_RENDER_FULL +} dmnsn_quality; + typedef struct { dmnsn_color background; dmnsn_array *objects; dmnsn_camera *camera; dmnsn_canvas *canvas; + dmnsn_quality quality; } dmnsn_scene; /* Create a scene, initializing only the ->objects field */ diff --git a/libdimension/raytrace.c b/libdimension/raytrace.c index 7c3637e..03dcbab 100644 --- a/libdimension/raytrace.c +++ b/libdimension/raytrace.c @@ -183,6 +183,10 @@ dmnsn_raytrace_scene_multithread_thread(void *ptr) return retval; } +/* Helper for dmnsn_raytrace_scene_impl - shoot a ray */ +static dmnsn_color dmnsn_raytrace_shoot(dmnsn_scene *scene, dmnsn_color color, + unsigned int x, unsigned int y); + /* * Actually raytrace a scene */ @@ -190,14 +194,9 @@ static int dmnsn_raytrace_scene_impl(dmnsn_progress *progress, dmnsn_scene *scene, unsigned int index, unsigned int threads) { - unsigned int x, y, i, j; + unsigned int x, y; unsigned int width, height; - double t, t_temp; - dmnsn_object *object; - dmnsn_line ray, ray_trans; - dmnsn_array *intersections; dmnsn_color color; - dmnsn_CIE_Lab Lab = { 0.0, 0.0, 0.0 }; /* Shut up uninitialized use warning */ width = scene->canvas->x; height = scene->canvas->y; @@ -210,46 +209,49 @@ dmnsn_raytrace_scene_impl(dmnsn_progress *progress, dmnsn_scene *scene, for (x -= width; x < width; x += threads) { /* Set the pixel to the background color */ color = scene->background; - t = -1.0; - /* Get the ray corresponding to the (x,y)'th pixel */ - ray = (*scene->camera->ray_fn)(scene->camera, scene->canvas, x, y); + if (scene->quality >= DMNSN_RENDER_OBJECTS) { + color = dmnsn_raytrace_shoot(scene, color, x, y); + } - for (i = 0; i < dmnsn_array_size(scene->objects); ++i) { - dmnsn_array_get(scene->objects, i, &object); + dmnsn_set_pixel(scene->canvas, x, y, color); + } - /* Transform the ray according to the object */ - ray_trans = dmnsn_matrix_line_mul(object->trans, ray); + dmnsn_increment_progress(progress); + } - /* Test for intersections with objects */ - intersections = (*object->intersections_fn)(object, ray_trans); - /* Find the closest intersection */ - for (j = 0; j < dmnsn_array_size(intersections); ++j) { - dmnsn_array_get(intersections, j, &t_temp); - if ((t_temp < t && t_temp >= 0.0) || t < 0.0) { - t = t_temp; + return 0; +} - /* Color each object differently */ - Lab.a = sin((double)(i + 8)); - Lab.b = cos((double)(i + 8)); - } - } - dmnsn_delete_array(intersections); - } +/* Shoot a ray, and calculate the color, using `color' as the background */ +static dmnsn_color +dmnsn_raytrace_shoot(dmnsn_scene *scene, dmnsn_color color, + unsigned int x, unsigned int y) +{ + dmnsn_line ray, ray_trans; + dmnsn_object *object; + dmnsn_array *intersections; + unsigned int i; - /* Shade according to distance from camera */ - if (t >= 0.0) { - Lab.L = 100.0*(1.0 - (t - 2.25)/2.25); - Lab.a *= Lab.L/1.1; - Lab.b *= Lab.L/1.1; - color = dmnsn_color_from_Lab(Lab, dmnsn_whitepoint); - } + /* Get the ray corresponding to the (x,y)'th pixel */ + ray = (*scene->camera->ray_fn)(scene->camera, scene->canvas, x, y); - dmnsn_set_pixel(scene->canvas, x, y, color); + for (i = 0; i < dmnsn_array_size(scene->objects); ++i) { + dmnsn_array_get(scene->objects, i, &object); + + /* Transform the ray according to the object */ + ray_trans = dmnsn_matrix_line_mul(object->trans, ray); + + /* Test for intersections with objects */ + intersections = (*object->intersections_fn)(object, ray_trans); + + if (dmnsn_array_size(intersections) > 0) { + color = dmnsn_color_from_XYZ(dmnsn_whitepoint); } - dmnsn_increment_progress(progress); + /* Delete the intersections array */ + dmnsn_delete_array(intersections); } - return 0; + return color; } diff --git a/libdimension/scene.c b/libdimension/scene.c index afda2ce..12bab73 100644 --- a/libdimension/scene.c +++ b/libdimension/scene.c @@ -28,6 +28,7 @@ dmnsn_new_scene() dmnsn_scene *scene = malloc(sizeof(dmnsn_scene)); if (scene) { scene->objects = dmnsn_new_array(sizeof(dmnsn_object*)); + scene->quality = DMNSN_RENDER_NONE; } return scene; } |