diff options
-rw-r--r-- | libdimension/color.c | 6 | ||||
-rw-r--r-- | libdimension/dimension/color.h | 3 | ||||
-rw-r--r-- | libdimension/dimension/scene.h | 1 | ||||
-rw-r--r-- | libdimension/raytrace.c | 46 | ||||
-rw-r--r-- | libdimension/scene.c | 2 | ||||
-rw-r--r-- | tests/tests.c | 29 | ||||
-rw-r--r-- | tests/testsxx.cpp | 3 |
7 files changed, 71 insertions, 19 deletions
diff --git a/libdimension/color.c b/libdimension/color.c index c9a421e..7fb73ed 100644 --- a/libdimension/color.c +++ b/libdimension/color.c @@ -26,6 +26,12 @@ const dmnsn_CIE_XYZ dmnsn_whitepoint = { .X = 0.9504060171449392, .Y = 0.9999085943425312, .Z = 1.089062231497274 }; +/* Standard colors */ +const dmnsn_color dmnsn_black = { .X = 0.0, .Y = 0.0, .Z = 0.0 }; +const dmnsn_color dmnsn_white = { .X = 0.9504060171449392, + .Y = 0.9999085943425312, + .Z = 1.089062231497274 }; + /* Convert a CIE XYZ color to a dmnsn_color (actually a no-op) */ dmnsn_color dmnsn_color_from_XYZ(dmnsn_CIE_XYZ XYZ) diff --git a/libdimension/dimension/color.h b/libdimension/dimension/color.h index 8b78eea..ab2ea04 100644 --- a/libdimension/dimension/color.h +++ b/libdimension/dimension/color.h @@ -60,6 +60,9 @@ typedef struct { double R, G, B; /* sRGB R, G, and B values */ } dmnsn_sRGB; +/* Standard colors */ +extern const dmnsn_color dmnsn_black, dmnsn_white; + /* Standard whitepoint, determined by the conversion of sRGB white to CIE XYZ */ extern const dmnsn_CIE_XYZ dmnsn_whitepoint; diff --git a/libdimension/dimension/scene.h b/libdimension/dimension/scene.h index 8104917..aa216f4 100644 --- a/libdimension/dimension/scene.h +++ b/libdimension/dimension/scene.h @@ -28,6 +28,7 @@ typedef enum { DMNSN_RENDER_NONE, DMNSN_RENDER_OBJECTS, + DMNSN_RENDER_PIGMENT, DMNSN_RENDER_FULL } dmnsn_quality; diff --git a/libdimension/raytrace.c b/libdimension/raytrace.c index 10f400d..c9217ca 100644 --- a/libdimension/raytrace.c +++ b/libdimension/raytrace.c @@ -185,7 +185,7 @@ dmnsn_raytrace_scene_multithread_thread(void *ptr) /* 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); + dmnsn_line ray); /* * Actually raytrace a scene @@ -196,6 +196,7 @@ dmnsn_raytrace_scene_impl(dmnsn_progress *progress, dmnsn_scene *scene, { unsigned int x, y; unsigned int width, height; + dmnsn_line ray; dmnsn_color color; width = scene->canvas->x; @@ -211,7 +212,10 @@ dmnsn_raytrace_scene_impl(dmnsn_progress *progress, dmnsn_scene *scene, color = scene->background; if (scene->quality >= DMNSN_RENDER_OBJECTS) { - color = dmnsn_raytrace_shoot(scene, color, x, y); + /* Get the ray corresponding to the (x,y)'th pixel */ + ray = (*scene->camera->ray_fn)(scene->camera, scene->canvas, x, y); + /* Shoot a ray */ + color = dmnsn_raytrace_shoot(scene, color, ray); } dmnsn_set_pixel(scene->canvas, x, y, color); @@ -225,17 +229,13 @@ dmnsn_raytrace_scene_impl(dmnsn_progress *progress, dmnsn_scene *scene, /* 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_raytrace_shoot(dmnsn_scene *scene, dmnsn_color color, dmnsn_line ray) { - dmnsn_line ray, ray_trans; + dmnsn_line ray_trans; dmnsn_object *object; - dmnsn_intersection *intersection; + dmnsn_intersection *intersection = NULL, *intersection_temp; unsigned int i; - /* Get the ray corresponding to the (x,y)'th pixel */ - ray = (*scene->camera->ray_fn)(scene->camera, scene->canvas, x, y); - for (i = 0; i < dmnsn_array_size(scene->objects); ++i) { dmnsn_array_get(scene->objects, i, &object); @@ -243,13 +243,33 @@ dmnsn_raytrace_shoot(dmnsn_scene *scene, dmnsn_color color, ray_trans = dmnsn_matrix_line_mul(object->trans, ray); /* Test for intersections with objects */ - intersection = (*object->intersection_fn)(object, ray_trans); + intersection_temp = (*object->intersection_fn)(object, ray_trans); + + if (intersection_temp && + (!intersection || intersection_temp->t < intersection->t)) { + dmnsn_delete_intersection(intersection); + intersection = intersection_temp; + } + } - if (intersection) { - color = dmnsn_color_from_XYZ(dmnsn_whitepoint); + if (intersection) { + if (scene->quality >= DMNSN_RENDER_PIGMENT) { + if (intersection->texture) { + if (intersection->texture->pigment) { + color = (*intersection->texture->pigment->pigment_fn)( + intersection->texture->pigment, + dmnsn_line_point(intersection->ray, intersection->t) + ); + } else { + color = dmnsn_black; + } + } else { + color = dmnsn_black; + } + } else { + color = dmnsn_white; } - /* Delete the intersection */ dmnsn_delete_intersection(intersection); } diff --git a/libdimension/scene.c b/libdimension/scene.c index 12bab73..7e24403 100644 --- a/libdimension/scene.c +++ b/libdimension/scene.c @@ -28,7 +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; + scene->quality = DMNSN_RENDER_FULL; } return scene; } diff --git a/tests/tests.c b/tests/tests.c index 218fcfd..ed00b64 100644 --- a/tests/tests.c +++ b/tests/tests.c @@ -82,6 +82,25 @@ dmnsn_new_default_scene() return NULL; } + sphere->texture = dmnsn_new_texture(); + if (!sphere->texture) { + dmnsn_delete_object(sphere); + dmnsn_delete_camera(scene->camera); + dmnsn_delete_canvas(scene->canvas); + dmnsn_delete_scene(scene); + return NULL; + } + + sphere->texture->pigment = dmnsn_new_solid_pigment(dmnsn_white); + if (!sphere->texture->pigment) { + dmnsn_delete_texture(sphere->texture); + dmnsn_delete_object(sphere); + dmnsn_delete_camera(scene->camera); + dmnsn_delete_canvas(scene->canvas); + dmnsn_delete_scene(scene); + return NULL; + } + sphere->trans = dmnsn_matrix_inverse( dmnsn_scale_matrix(dmnsn_vector_construct(1.25, 1.25, 1.25)) ); @@ -89,6 +108,8 @@ dmnsn_new_default_scene() cube = dmnsn_new_cube(); if (!cube) { + dmnsn_delete_pigment(sphere->texture->pigment); + dmnsn_delete_texture(sphere->texture); dmnsn_delete_object(sphere); dmnsn_delete_camera(scene->camera); dmnsn_delete_canvas(scene->canvas); @@ -101,8 +122,6 @@ dmnsn_new_default_scene() ); dmnsn_array_push(scene->objects, &cube); - scene->quality = DMNSN_RENDER_FULL; - return scene; } @@ -113,8 +132,14 @@ dmnsn_delete_default_scene(dmnsn_scene *scene) dmnsn_array_get(scene->objects, 0, &sphere); dmnsn_array_get(scene->objects, 1, &cube); +// dmnsn_delete_pigment(cube->texture->pigment); + dmnsn_delete_texture(cube->texture); dmnsn_delete_object(cube); + + dmnsn_delete_pigment(sphere->texture->pigment); + dmnsn_delete_texture(sphere->texture); dmnsn_delete_object(sphere); + dmnsn_delete_camera(scene->camera); dmnsn_delete_canvas(scene->canvas); dmnsn_delete_scene(scene); diff --git a/tests/testsxx.cpp b/tests/testsxx.cpp index 114fb4a..a8fa762 100644 --- a/tests/testsxx.cpp +++ b/tests/testsxx.cpp @@ -58,9 +58,6 @@ namespace Dimension background.filter(0.1); scene.background(background); - // Quality - scene.quality(RENDER_FULL); - return scene; } |