summaryrefslogtreecommitdiffstats
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
parent6137aed0179476eaa626660885f01ea3f04f988a (diff)
downloaddimension-d47af986a7832add1c149235f44fa8f57b56e6d8.tar.xz
Implement sky spheres.
-rw-r--r--dimension/common.terminals2
-rw-r--r--dimension/grammar.epilogue1
-rw-r--r--dimension/grammar.nonterminals2
-rw-r--r--dimension/grammar.rules22
-rw-r--r--dimension/lexer.l1
-rw-r--r--dimension/parse.h1
-rw-r--r--dimension/realize.c35
-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
-rw-r--r--tests/dimension/demo.pov12
-rwxr-xr-xtests/dimension/demo.sh17
-rw-r--r--tests/dimension/integer-overflow.pov25
-rwxr-xr-xtests/dimension/integer-overflow.sh35
-rw-r--r--tests/libdimension/render.c15
21 files changed, 362 insertions, 29 deletions
diff --git a/dimension/common.terminals b/dimension/common.terminals
index 5a0d778..4e8e6d1 100644
--- a/dimension/common.terminals
+++ b/dimension/common.terminals
@@ -394,7 +394,7 @@
%token DMNSN_T_SINH "sinh"
%token DMNSN_T_SIZE
%token DMNSN_T_SKY "sky"
-%token DMNSN_T_SKY_SPHERE
+%token DMNSN_T_SKY_SPHERE "sky_sphere"
%token DMNSN_T_SLICE
%token DMNSN_T_SLOPE
%token DMNSN_T_SLOPE_MAP
diff --git a/dimension/grammar.epilogue b/dimension/grammar.epilogue
index 0eace5e..77a782a 100644
--- a/dimension/grammar.epilogue
+++ b/dimension/grammar.epilogue
@@ -126,6 +126,7 @@ dmnsn_astnode_string(dmnsn_astnode_type astnode_type)
dmnsn_astnode_map(DMNSN_AST_MAX_TRACE_LEVEL, "max_trace_level");
dmnsn_astnode_map(DMNSN_AST_BACKGROUND, "background");
+ dmnsn_astnode_map(DMNSN_AST_SKY_SPHERE, "sky_sphere");
dmnsn_astnode_map(DMNSN_AST_CAMERA, "camera");
dmnsn_astnode_map(DMNSN_AST_PERSPECTIVE, "perspective");
diff --git a/dimension/grammar.nonterminals b/dimension/grammar.nonterminals
index 9ab8ee1..912b660 100644
--- a/dimension/grammar.nonterminals
+++ b/dimension/grammar.nonterminals
@@ -31,3 +31,5 @@
/* Atmospheric effects */
%type <astnode> ATMOSPHERIC_EFFECT
%type <astnode> BACKGROUND
+%type <astnode> SKY_SPHERE
+%type <astnode> SKY_SPHERE_ITEMS
diff --git a/dimension/grammar.rules b/dimension/grammar.rules
index 0e9d6f1..8b110c0 100644
--- a/dimension/grammar.rules
+++ b/dimension/grammar.rules
@@ -94,9 +94,31 @@ GLOBAL_CHARSET: "ascii" {
/* Atmospheric effects */
ATMOSPHERIC_EFFECT: BACKGROUND
+ | SKY_SPHERE
;
BACKGROUND: "background" "{" COLOR "}" {
$$ = dmnsn_new_astnode1(DMNSN_AST_BACKGROUND, @$, $3);
}
;
+
+SKY_SPHERE: "sky_sphere" "{"
+ SKY_SPHERE_ITEMS
+ "}"
+ {
+ $$ = $3;
+ }
+;
+
+SKY_SPHERE_ITEMS: /* empty */ {
+ $$ = dmnsn_new_astnode(DMNSN_AST_SKY_SPHERE, @$);
+ }
+ | SKY_SPHERE_ITEMS PIGMENT {
+ $$ = $1;
+ dmnsn_array_push($$.children, &$2);
+ }
+ | SKY_SPHERE_ITEMS TRANSFORMATION {
+ $$ = $1;
+ dmnsn_array_push($$.children, &$2);
+ }
+;
diff --git a/dimension/lexer.l b/dimension/lexer.l
index 5e1afa2..c5eeca7 100644
--- a/dimension/lexer.l
+++ b/dimension/lexer.l
@@ -258,6 +258,7 @@ unsigned long wchar;
"sin" RETURN_TOKEN(DMNSN_T_SIN);
"sinh" RETURN_TOKEN(DMNSN_T_SINH);
"sky" RETURN_TOKEN(DMNSN_T_SKY);
+"sky_sphere" RETURN_TOKEN(DMNSN_T_SKY_SPHERE);
"sphere" RETURN_TOKEN(DMNSN_T_SPHERE);
"sqrt" RETURN_TOKEN(DMNSN_T_SQRT);
"strcmp" RETURN_TOKEN(DMNSN_T_STRCMP);
diff --git a/dimension/parse.h b/dimension/parse.h
index 38e4eef..7bff5ba 100644
--- a/dimension/parse.h
+++ b/dimension/parse.h
@@ -40,6 +40,7 @@ typedef enum {
DMNSN_AST_MAX_INTERSECTIONS,
DMNSN_AST_BACKGROUND,
+ DMNSN_AST_SKY_SPHERE,
DMNSN_AST_CAMERA,
DMNSN_AST_PERSPECTIVE,
diff --git a/dimension/realize.c b/dimension/realize.c
index d4b45cb..2f74ce0 100644
--- a/dimension/realize.c
+++ b/dimension/realize.c
@@ -680,6 +680,37 @@ dmnsn_realize_pigment(dmnsn_astnode astnode)
return pigment;
}
+static dmnsn_sky_sphere *
+dmnsn_realize_sky_sphere(dmnsn_astnode astnode)
+{
+ dmnsn_assert(astnode.type == DMNSN_AST_SKY_SPHERE, "Expected a sky sphere.");
+
+ dmnsn_sky_sphere *sky_sphere = dmnsn_new_sky_sphere();
+
+ DMNSN_ARRAY_FOREACH (dmnsn_astnode *, item, astnode.children) {
+ switch (item->type) {
+ case DMNSN_AST_PIGMENT:
+ {
+ dmnsn_pigment *pigment = dmnsn_realize_pigment(*item);
+ dmnsn_array_push(sky_sphere->pigments, &pigment);
+ break;
+ }
+
+ case DMNSN_AST_TRANSFORMATION:
+ sky_sphere->trans = dmnsn_matrix_mul(
+ dmnsn_realize_transformation(*item),
+ sky_sphere->trans
+ );
+ break;
+
+ default:
+ dmnsn_assert(false, "Invalid sky sphere item.");
+ }
+ }
+
+ return sky_sphere;
+}
+
static dmnsn_finish *
dmnsn_realize_reflection(dmnsn_astnode astnode)
{
@@ -1295,6 +1326,10 @@ dmnsn_realize_astree(const dmnsn_astree *astree)
dmnsn_array_get(astnode->children, 0, &child);
scene->background = dmnsn_realize_color(child);
break;
+ case DMNSN_AST_SKY_SPHERE:
+ dmnsn_delete_sky_sphere(scene->sky_sphere);
+ scene->sky_sphere = dmnsn_realize_sky_sphere(*astnode);
+ break;
case DMNSN_AST_CAMERA:
dmnsn_delete_camera(scene->camera);
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;
+}
diff --git a/tests/dimension/demo.pov b/tests/dimension/demo.pov
index 0740ecb..8088f45 100644
--- a/tests/dimension/demo.pov
+++ b/tests/dimension/demo.pov
@@ -29,7 +29,17 @@ camera {
}
background {
- color rgbf <0, 0.1, 0.2, 0.1>
+ color transmit 1
+}
+
+sky_sphere {
+ pigment {
+ gradient y
+ color_map {
+ [0.0 color rgb <1, 0.5, 0>]
+ [0.35 color rgbf <0, 0.1, 0.2, 0.1>]
+ }
+ }
}
light_source {
diff --git a/tests/dimension/demo.sh b/tests/dimension/demo.sh
index 4e26bdc..a741268 100755
--- a/tests/dimension/demo.sh
+++ b/tests/dimension/demo.sh
@@ -32,7 +32,22 @@ demo_exp=$(echo -n \
(rotation (vector (integer 0) (integer 53) (integer 0)
(integer 0) (integer 0)))))
(background
- (vector (integer 0) (float 0.1) (float 0.2) (float 0.1) (integer 0)))
+ (vector (integer 0) (integer 0) (integer 0) (integer 0) (integer 1)))
+ (sky_sphere
+ (pigment
+ (pattern
+ (gradient (vector (integer 0) (integer 1)
+ (integer 0) (integer 0) (integer 0))))
+ (pigment-modifiers
+ (color_map
+ (color_map-entry
+ (float 0)
+ (vector (integer 1) (float 0.5) (integer 0)
+ (integer 0) (integer 0)))
+ (color_map-entry
+ (float 0.35)
+ (vector (integer 0) (float 0.1) (float 0.2)
+ (float 0.1) (integer 0)))))))
(light_source
(vector (integer -15) (integer 20) (integer 10) (integer 0) (integer 0))
(vector (integer 1) (integer 1) (integer 1) (integer 0) (integer 0))
diff --git a/tests/dimension/integer-overflow.pov b/tests/dimension/integer-overflow.pov
new file mode 100644
index 0000000..670d659
--- /dev/null
+++ b/tests/dimension/integer-overflow.pov
@@ -0,0 +1,25 @@
+/*************************************************************************
+ * Copyright (C) 2009-2010 Tavian Barnes <tavianator@gmail.com> *
+ * *
+ * This file is part of The Dimension Test Suite. *
+ * *
+ * The Dimension Test Suite is free software; you can redistribute it *
+ * and/or modify it under the terms of the GNU 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 Test Suite 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 *
+ * General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. *
+ *************************************************************************/
+
+// Test integer overflow handling -- overflows should convert to floats
+
+torus {
+ 10000000000000000000,
+ abs(-2147483647 - 1)*abs(-9223372036854775807 - 1)*((-2147483647 - 2)*(2147483647 + 1))*((-9223372036854775807.0 - 2)*(9223372036854775807.0 + 1))*(65536*65536)*(4294967296*4294967296.0)
+}
diff --git a/tests/dimension/integer-overflow.sh b/tests/dimension/integer-overflow.sh
new file mode 100755
index 0000000..737c0e2
--- /dev/null
+++ b/tests/dimension/integer-overflow.sh
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+#########################################################################
+# Copyright (C) 2009-2010 Tavian Barnes <tavianator@gmail.com> #
+# #
+# This file is part of The Dimension Test Suite. #
+# #
+# The Dimension Test Suite is free software; you can redistribute it #
+# and/or modify it under the terms of the GNU 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 Test Suite 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 #
+# General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program. If not, see <http://www.gnu.org/licenses/>. #
+#########################################################################
+
+integer_overflow=$(${top_builddir}/dimension/dimension --parse ${srcdir}/integer-overflow.pov)
+integer_overflow_exp="$(echo -n \
+'((object
+ (torus
+ (float 1e+19)
+ (float 6.15656e+113))
+ object-modifiers))' \
+| tr '\n' ' ' | sed -r 's/[[:space:]]+/ /g')"
+
+if [ "$integer_overflow" != "$integer_overflow_exp" ]; then
+ echo "integer-overflow.pov parsed as \"$integer_overflow\"" >&2
+ echo " -- expected \"$integer_overflow_exp\"" >&2
+ exit 1
+fi
diff --git a/tests/libdimension/render.c b/tests/libdimension/render.c
index 440333c..31518bf 100644
--- a/tests/libdimension/render.c
+++ b/tests/libdimension/render.c
@@ -66,8 +66,19 @@ dmnsn_new_test_scene(void)
scene->camera->trans = trans;
/* Background color */
- scene->background = dmnsn_color_from_sRGB((dmnsn_sRGB){ 0.0, 0.1, 0.2 });
- scene->background.filter = 0.1;
+ scene->background = dmnsn_clear;
+
+ /* Sky sphere */
+ scene->sky_sphere = dmnsn_new_sky_sphere();
+ dmnsn_pattern *sky_gradient = dmnsn_new_gradient_pattern(dmnsn_y);
+ dmnsn_color_map *sky_gradient_color_map = dmnsn_new_color_map();
+ dmnsn_add_color_map_entry(sky_gradient_color_map, 0.0, dmnsn_orange);
+ dmnsn_color background = dmnsn_color_from_sRGB((dmnsn_sRGB){ 0.0, 0.1, 0.2 });
+ background.filter = 0.1;
+ dmnsn_add_color_map_entry(sky_gradient_color_map, 0.35, background);
+ dmnsn_pigment *sky_pigment
+ = dmnsn_new_color_map_pigment(sky_gradient, sky_gradient_color_map);
+ dmnsn_array_push(scene->sky_sphere->pigments, &sky_pigment);
/* Light source */
dmnsn_light *light = dmnsn_new_point_light(