summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libdimension/color.c6
-rw-r--r--libdimension/dimension/color.h3
-rw-r--r--libdimension/dimension/scene.h1
-rw-r--r--libdimension/raytrace.c46
-rw-r--r--libdimension/scene.c2
-rw-r--r--tests/tests.c29
-rw-r--r--tests/testsxx.cpp3
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;
}