summaryrefslogtreecommitdiffstats
path: root/libdimension
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@gmail.com>2010-11-19 20:30:14 -0500
committerTavian Barnes <tavianator@gmail.com>2010-11-19 20:31:06 -0500
commitd47af986a7832add1c149235f44fa8f57b56e6d8 (patch)
tree40fbd4a5e84afa188c2f23a7727d3d9d2acb6840 /libdimension
parent6137aed0179476eaa626660885f01ea3f04f988a (diff)
downloaddimension-d47af986a7832add1c149235f44fa8f57b56e6d8.tar.xz
Implement sky spheres.
Diffstat (limited to 'libdimension')
-rw-r--r--libdimension/Makefile.am2
-rw-r--r--libdimension/color.c7
-rw-r--r--libdimension/dimension.h1
-rw-r--r--libdimension/dimension/color.h1
-rw-r--r--libdimension/dimension/scene.h7
-rw-r--r--libdimension/dimension/sky_sphere.h63
-rw-r--r--libdimension/raytrace.c56
-rw-r--r--libdimension/scene.c14
-rw-r--r--libdimension/sky_sphere.c72
9 files changed, 199 insertions, 24 deletions
diff --git a/libdimension/Makefile.am b/libdimension/Makefile.am
index 542e684..86caa57 100644
--- a/libdimension/Makefile.am
+++ b/libdimension/Makefile.am
@@ -47,6 +47,7 @@ nobase_include_HEADERS = dimension.h \
dimension/progress.h \
dimension/raytrace.h \
dimension/scene.h \
+ dimension/sky_sphere.h \
dimension/texture.h \
dimension/timer.h
@@ -90,6 +91,7 @@ libdimension_la_SOURCES = $(nobase_include_HEADERS) \
raytrace.c \
reflective.c \
scene.c \
+ sky_sphere.c \
solid_pigment.c \
sphere.c \
texture.c \
diff --git a/libdimension/color.c b/libdimension/color.c
index e91ebc1..6d2078f 100644
--- a/libdimension/color.c
+++ b/libdimension/color.c
@@ -46,6 +46,13 @@ const dmnsn_color dmnsn_white = {
.filter = 0.0,
.trans = 0.0
};
+const dmnsn_color dmnsn_clear = {
+ .R = 0.0,
+ .G = 0.0,
+ .B = 0.0,
+ .filter = 0.0,
+ .trans = 1.0
+};
const dmnsn_color dmnsn_red = {
.R = 1.0,
.G = 0.0,
diff --git a/libdimension/dimension.h b/libdimension/dimension.h
index 55b3b87..d4ce61e 100644
--- a/libdimension/dimension.h
+++ b/libdimension/dimension.h
@@ -79,6 +79,7 @@ typedef void dmnsn_free_fn(void *ptr);
#include <dimension/lights.h>
#include <dimension/camera.h>
#include <dimension/cameras.h>
+#include <dimension/sky_sphere.h>
#include <dimension/scene.h>
#include <dimension/raytrace.h>
diff --git a/libdimension/dimension/color.h b/libdimension/dimension/color.h
index 26ab4bb..e214b66 100644
--- a/libdimension/dimension/color.h
+++ b/libdimension/dimension/color.h
@@ -79,6 +79,7 @@ typedef struct {
/* Standard colors */
extern const dmnsn_color dmnsn_black; /**< Black. */
extern const dmnsn_color dmnsn_white; /**< White. */
+extern const dmnsn_color dmnsn_clear; /**< Clear. */
extern const dmnsn_color dmnsn_red; /**< Red. */
extern const dmnsn_color dmnsn_green; /**< Green. */
extern const dmnsn_color dmnsn_blue; /**< Blue. */
diff --git a/libdimension/dimension/scene.h b/libdimension/dimension/scene.h
index 489e4e5..0889359 100644
--- a/libdimension/dimension/scene.h
+++ b/libdimension/dimension/scene.h
@@ -45,6 +45,7 @@ typedef struct dmnsn_scene {
/* World attributes */
dmnsn_color background; /**< Background color. */
dmnsn_color ambient; /**< Global ambient color. */
+ dmnsn_sky_sphere *sky_sphere; /**< Sky sphere. */
dmnsn_texture *default_texture; /**< Default object texture. */
/** Camera. */
@@ -85,4 +86,10 @@ dmnsn_scene *dmnsn_new_scene(void);
*/
void dmnsn_delete_scene(dmnsn_scene *scene);
+/**
+ * Initialize a scene.
+ * @param[in,out] scene The scene to initalize.
+ */
+void dmnsn_scene_init(dmnsn_scene *scene);
+
#endif /* DIMENSION_SCENE_H */
diff --git a/libdimension/dimension/sky_sphere.h b/libdimension/dimension/sky_sphere.h
new file mode 100644
index 0000000..5edacb0
--- /dev/null
+++ b/libdimension/dimension/sky_sphere.h
@@ -0,0 +1,63 @@
+/*************************************************************************
+ * Copyright (C) 2010 Tavian Barnes <tavianator@gmail.com> *
+ * *
+ * This file is part of The Dimension Library. *
+ * *
+ * The Dimension Library is free software; you can redistribute it and/ *
+ * or modify it under the terms of the GNU Lesser General Public License *
+ * as published by the Free Software Foundation; either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * The Dimension Library is distributed in the hope that it will be *
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty *
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this program. If not, see *
+ * <http://www.gnu.org/licenses/>. *
+ *************************************************************************/
+
+/**
+ * @file
+ * Sky spheres.
+ */
+
+#ifndef DIMENSION_SKY_SPHERE_H
+#define DIMENSION_SKY_SPHERE_H
+
+/** A sky sphere. */
+typedef struct dmnsn_sky_sphere {
+ /** An array of pigments in inside-to-outside order. */
+ dmnsn_array *pigments;
+ dmnsn_matrix trans;
+} dmnsn_sky_sphere;
+
+/**
+ * Create a sky sphere.
+ * @return A new blank sky sphere.
+ */
+dmnsn_sky_sphere *dmnsn_new_sky_sphere();
+
+/**
+ * Delete a sky sphere.
+ * @param[in,out] sky_sphere The sky sphere to delete.
+ */
+void dmnsn_delete_sky_sphere(dmnsn_sky_sphere *sky_sphere);
+
+/**
+ * Initialize a sky sphere.
+ * @param[in,out] sky_sphere The sky sphere to initialize.
+ */
+void dmnsn_sky_sphere_init(dmnsn_sky_sphere *sky_sphere);
+
+/**
+ * Evaluate the color of the sky sphere.
+ * @param[in] sky_sphere The sky sphere to evaluate.
+ * @param[in] d The direction to look.
+ * @return The color of the sky in the direction of \p d.
+ */
+dmnsn_color dmnsn_sky_sphere_color(const dmnsn_sky_sphere *sky_sphere,
+ dmnsn_vector d);
+
+#endif /* DIMENSION_SKY_SPHERE_H */
diff --git a/libdimension/raytrace.c b/libdimension/raytrace.c
index e6596e4..3534331 100644
--- a/libdimension/raytrace.c
+++ b/libdimension/raytrace.c
@@ -77,13 +77,11 @@ dmnsn_raytrace_scene_thread(void *ptr)
{
dmnsn_raytrace_payload *payload = ptr;
+ /* Pre-calculate bounding box transformations, etc. */
+ dmnsn_scene_init(payload->scene);
+
/* Time the bounding tree construction */
payload->scene->bounding_timer = dmnsn_new_timer();
- /* Pre-calculate bounding box transformations, etc. */
- DMNSN_ARRAY_FOREACH (dmnsn_object **, object, payload->scene->objects) {
- dmnsn_object_init(*object);
- }
-
payload->prtree = dmnsn_new_prtree(payload->scene->objects);
dmnsn_complete_timer(payload->scene->bounding_timer);
@@ -210,21 +208,16 @@ dmnsn_raytrace_scene_impl(dmnsn_progress *progress, dmnsn_scene *scene,
/* Iterate through each pixel */
for (size_t y = index; y < scene->canvas->height; y += threads) {
for (size_t x = 0; x < scene->canvas->width; ++x) {
- /* Set the pixel to the background color */
- dmnsn_color color = scene->background;
-
- if (scene->quality) {
- /* Get the ray corresponding to the (x,y)'th pixel */
- dmnsn_line ray = dmnsn_camera_ray(
- scene->camera,
- ((double)x)/(scene->canvas->width - 1),
- ((double)y)/(scene->canvas->height - 1)
- );
+ /* Get the ray corresponding to the (x,y)'th pixel */
+ dmnsn_line ray = dmnsn_camera_ray(
+ scene->camera,
+ ((double)x)/(scene->canvas->width - 1),
+ ((double)y)/(scene->canvas->height - 1)
+ );
- /* Shoot a ray */
- state.reclevel = scene->reclimit;
- color = dmnsn_raytrace_shoot(&state, ray);
- }
+ /* Shoot a ray */
+ state.reclevel = scene->reclimit;
+ dmnsn_color color = dmnsn_raytrace_shoot(&state, ray);
dmnsn_set_pixel(scene->canvas, x, y, color);
}
@@ -272,6 +265,22 @@ dmnsn_raytrace_scene_impl(dmnsn_progress *progress, dmnsn_scene *scene,
? (state)->intersection->interior->ior \
: 1.0)
+/** Calculate the background color. */
+static dmnsn_color
+dmnsn_raytrace_background(dmnsn_raytrace_state *state, dmnsn_line ray)
+{
+ dmnsn_color color = state->scene->background;
+ if (state->scene->sky_sphere
+ && (state->scene->quality & DMNSN_RENDER_PIGMENT))
+ {
+ dmnsn_color sky = dmnsn_sky_sphere_color(state->scene->sky_sphere,
+ dmnsn_vector_normalize(ray.n));
+ color = dmnsn_color_add(dmnsn_color_filter(color, sky), sky);
+ }
+
+ return color;
+}
+
/** Calculate the base pigment at the intersection. */
static void
dmnsn_raytrace_pigment(dmnsn_raytrace_state *state)
@@ -465,12 +474,11 @@ dmnsn_raytrace_shoot(dmnsn_raytrace_state *state, dmnsn_line ray)
return dmnsn_black;
--state->reclevel;
- dmnsn_intersection intersection;
- bool intersected
- = dmnsn_prtree_intersection(state->prtree, ray, &intersection);
+ /* Calculate the background color */
+ dmnsn_color color = dmnsn_raytrace_background(state, ray);
- dmnsn_color color = state->scene->background;
- if (intersected) {
+ dmnsn_intersection intersection;
+ if (dmnsn_prtree_intersection(state->prtree, ray, &intersection)) {
state->intersection = &intersection;
state->r = dmnsn_line_point(state->intersection->ray,
state->intersection->t);
diff --git a/libdimension/scene.c b/libdimension/scene.c
index 9eca7b7..c43a93a 100644
--- a/libdimension/scene.c
+++ b/libdimension/scene.c
@@ -34,6 +34,7 @@ dmnsn_new_scene()
scene->background = dmnsn_black;
scene->ambient = dmnsn_white;
+ scene->sky_sphere = NULL;
scene->default_texture = dmnsn_new_texture();
scene->camera = NULL;
scene->canvas = NULL;
@@ -68,6 +69,19 @@ dmnsn_delete_scene(dmnsn_scene *scene)
dmnsn_delete_canvas(scene->canvas);
dmnsn_delete_camera(scene->camera);
dmnsn_delete_texture(scene->default_texture);
+ dmnsn_delete_sky_sphere(scene->sky_sphere);
dmnsn_free(scene);
}
}
+
+void
+dmnsn_scene_init(dmnsn_scene *scene)
+{
+ if (scene->sky_sphere) {
+ dmnsn_sky_sphere_init(scene->sky_sphere);
+ }
+
+ DMNSN_ARRAY_FOREACH (dmnsn_object **, object, scene->objects) {
+ dmnsn_object_init(*object);
+ }
+}
diff --git a/libdimension/sky_sphere.c b/libdimension/sky_sphere.c
new file mode 100644
index 0000000..bb38c16
--- /dev/null
+++ b/libdimension/sky_sphere.c
@@ -0,0 +1,72 @@
+/*************************************************************************
+ * Copyright (C) 2009-2010 Tavian Barnes <tavianator@gmail.com> *
+ * *
+ * This file is part of The Dimension Library. *
+ * *
+ * The Dimension Library is free software; you can redistribute it and/ *
+ * or modify it under the terms of the GNU Lesser General Public License *
+ * as published by the Free Software Foundation; either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * The Dimension Library is distributed in the hope that it will be *
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty *
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this program. If not, see *
+ * <http://www.gnu.org/licenses/>. *
+ *************************************************************************/
+
+/**
+ * @file
+ * Sky spheres.
+ */
+
+#include "dimension.h"
+
+dmnsn_sky_sphere *
+dmnsn_new_sky_sphere()
+{
+ dmnsn_sky_sphere *sky_sphere = dmnsn_malloc(sizeof(dmnsn_sky_sphere));
+ sky_sphere->pigments = dmnsn_new_array(sizeof(dmnsn_pigment *));
+ sky_sphere->trans = dmnsn_identity_matrix();
+ return sky_sphere;
+}
+
+void
+dmnsn_delete_sky_sphere(dmnsn_sky_sphere *sky_sphere)
+{
+ if (sky_sphere) {
+ DMNSN_ARRAY_FOREACH (dmnsn_pigment **, pigment, sky_sphere->pigments) {
+ dmnsn_delete_pigment(*pigment);
+ }
+ dmnsn_free(sky_sphere);
+ }
+}
+
+void
+dmnsn_sky_sphere_init(dmnsn_sky_sphere *sky_sphere)
+{
+ DMNSN_ARRAY_FOREACH (dmnsn_pigment **, pigment, sky_sphere->pigments) {
+ (*pigment)->trans = dmnsn_matrix_mul(sky_sphere->trans, (*pigment)->trans);
+ dmnsn_pigment_init(*pigment);
+ }
+}
+
+dmnsn_color
+dmnsn_sky_sphere_color(const dmnsn_sky_sphere *sky_sphere, dmnsn_vector d)
+{
+ dmnsn_color color = dmnsn_black;
+ color.trans = 1.0;
+
+ DMNSN_ARRAY_FOREACH (const dmnsn_pigment **, pigment, sky_sphere->pigments) {
+ dmnsn_pigment_fn *pigment_fn = (*pigment)->pigment_fn;
+ if (pigment_fn) {
+ dmnsn_color sky = (*pigment_fn)(*pigment, d);
+ color = dmnsn_color_add(dmnsn_color_filter(color, sky), sky);
+ }
+ }
+
+ return color;
+}