summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dimension/common.nonterminals5
-rw-r--r--dimension/common.rules73
-rw-r--r--dimension/common.terminals2
-rw-r--r--dimension/directives.declarations2
-rw-r--r--dimension/grammar.declarations2
-rw-r--r--dimension/grammar.epilogue3
-rw-r--r--dimension/lexer.l1
-rw-r--r--dimension/parse.h3
-rw-r--r--dimension/realize.c144
-rw-r--r--libdimension/Makefile.am1
-rw-r--r--libdimension/dimension.h6
-rw-r--r--libdimension/dimension/array.h14
-rw-r--r--libdimension/dimension/map.h7
-rw-r--r--libdimension/dimension/pigments.h15
-rw-r--r--libdimension/map.c9
-rw-r--r--tests/dimension/demo.pov9
-rwxr-xr-xtests/dimension/demo.sh22
-rw-r--r--tests/libdimension/render.c13
18 files changed, 265 insertions, 66 deletions
diff --git a/dimension/common.nonterminals b/dimension/common.nonterminals
index c7140b5..3b4e239 100644
--- a/dimension/common.nonterminals
+++ b/dimension/common.nonterminals
@@ -71,12 +71,17 @@
/* Pigments */
%type <astnode> PIGMENT
+%type <astnode> PIGMENT_BODY
%type <astnode> PIGMENT_TYPE
%type <astnode> PIGMENT_MODIFIERS
%type <astnode> COLOR_LIST2
%type <astnode> COLOR_MAP
%type <astnode> COLOR_MAP_ENTRIES
%type <astnode> COLOR_MAP_ENTRY
+%type <astnode> PIGMENT_LIST2
+%type <astnode> PIGMENT_MAP
+%type <astnode> PIGMENT_MAP_ENTRIES
+%type <astnode> PIGMENT_MAP_ENTRY
%type <astnode> BITMAP_TYPE
/* Finishes */
diff --git a/dimension/common.rules b/dimension/common.rules
index b4cf631..32eadc7 100644
--- a/dimension/common.rules
+++ b/dimension/common.rules
@@ -526,25 +526,32 @@ TEXTURE_ITEMS: /* empty */ {
/* Pigments */
PIGMENT: "pigment" "{"
- PIGMENT_TYPE
- PIGMENT_MODIFIERS
+ PIGMENT_BODY
"}"
{
- $$ = dmnsn_new_astnode2(DMNSN_AST_PIGMENT, @$, $3, $4);
- }
- | "pigment" "{"
- "checker" COLOR_LIST2
- PIGMENT_MODIFIERS
- "}"
- {
- dmnsn_astnode checker = dmnsn_new_astnode(DMNSN_AST_CHECKER, @3);
- dmnsn_astnode pattern = dmnsn_new_astnode1(DMNSN_AST_PATTERN, @3,
- checker);
- dmnsn_array_push($5.children, &$4);
- $$ = dmnsn_new_astnode2(DMNSN_AST_PIGMENT, @$, pattern, $5);
+ $$ = $3;
}
;
+PIGMENT_BODY: PIGMENT_TYPE PIGMENT_MODIFIERS {
+ $$ = dmnsn_new_astnode2(DMNSN_AST_PIGMENT, @$, $1, $2);
+ }
+ | "checker" COLOR_LIST2 PIGMENT_MODIFIERS {
+ dmnsn_astnode checker = dmnsn_new_astnode(DMNSN_AST_CHECKER, @1);
+ dmnsn_astnode pattern = dmnsn_new_astnode1(DMNSN_AST_PATTERN, @1,
+ checker);
+ dmnsn_array_push($3.children, &$2);
+ $$ = dmnsn_new_astnode2(DMNSN_AST_PIGMENT, @$, pattern, $3);
+ }
+ | "checker" PIGMENT_LIST2 PIGMENT_MODIFIERS {
+ dmnsn_astnode checker = dmnsn_new_astnode(DMNSN_AST_CHECKER, @1);
+ dmnsn_astnode pattern = dmnsn_new_astnode1(DMNSN_AST_PATTERN, @1,
+ checker);
+ dmnsn_array_push($3.children, &$2);
+ $$ = dmnsn_new_astnode2(DMNSN_AST_PIGMENT, @$, pattern, $3);
+ }
+;
+
PIGMENT_TYPE: COLOR
| CONTINUOUS_PATTERN_TYPE
| "image_map" "{"
@@ -578,6 +585,10 @@ PIGMENT_MODIFIERS: /* empty */ {
$$ = $1;
dmnsn_array_push($$.children, &$2);
}
+ | PIGMENT_MODIFIERS PIGMENT_MAP {
+ $$ = $1;
+ dmnsn_array_push($$.children, &$2);
+ }
| PIGMENT_MODIFIERS "quick_color" COLOR {
dmnsn_astnode quick_color
= dmnsn_new_astnode1(DMNSN_AST_QUICK_COLOR, @2, $3);
@@ -619,6 +630,40 @@ COLOR_MAP_ENTRY: "[" FLOAT "color" COLOR_BODY "]" {
}
;
+PIGMENT_LIST2: PIGMENT {
+ $$ = dmnsn_new_astnode1(DMNSN_AST_PIGMENT_LIST, @$, $1);
+ }
+ | PIGMENT PIGMENT {
+ $$ = dmnsn_new_astnode2(DMNSN_AST_PIGMENT_LIST, @$, $1, $2);
+ }
+ | PIGMENT "," PIGMENT {
+ $$ = dmnsn_new_astnode2(DMNSN_AST_PIGMENT_LIST, @$, $1, $3);
+ }
+;
+
+PIGMENT_MAP: "pigment_map" "{"
+ PIGMENT_MAP_ENTRIES
+ "}"
+ {
+ $$ = $3;
+ }
+;
+
+PIGMENT_MAP_ENTRIES: PIGMENT_MAP_ENTRY {
+ $$ = dmnsn_new_astnode1(DMNSN_AST_PIGMENT_MAP, @$, $1);
+ }
+ | PIGMENT_MAP_ENTRIES PIGMENT_MAP_ENTRY {
+ $$ = $1;
+ dmnsn_array_push($$.children, &$2);
+ }
+;
+
+PIGMENT_MAP_ENTRY: "[" FLOAT PIGMENT_BODY "]" {
+ $$ = dmnsn_new_astnode2(DMNSN_AST_PIGMENT_MAP_ENTRY, @$,
+ $2, $3);
+ }
+;
+
/* Finishes */
FINISH: "finish" "{"
FINISH_ITEMS
diff --git a/dimension/common.terminals b/dimension/common.terminals
index 4e8e6d1..d7ab854 100644
--- a/dimension/common.terminals
+++ b/dimension/common.terminals
@@ -332,7 +332,7 @@
%token DMNSN_T_PHOTONS
%token DMNSN_T_PI "pi"
%token DMNSN_T_PIGMENT "pigment"
-%token DMNSN_T_PIGMENT_MAP
+%token DMNSN_T_PIGMENT_MAP "pigment_map"
%token DMNSN_T_PIGMENT_PATTERN
%token DMNSN_T_PLANAR
%token DMNSN_T_PLANE "plane"
diff --git a/dimension/directives.declarations b/dimension/directives.declarations
index 9f8c891..8867566 100644
--- a/dimension/directives.declarations
+++ b/dimension/directives.declarations
@@ -21,7 +21,7 @@
%name-prefix "dmnsn_ld_yy"
-%expect 16
+%expect 19
%expect-rr 6
%parse-param {const char *filename}
diff --git a/dimension/grammar.declarations b/dimension/grammar.declarations
index ef3f7a2..cf8fcf1 100644
--- a/dimension/grammar.declarations
+++ b/dimension/grammar.declarations
@@ -23,7 +23,7 @@
%name-prefix "dmnsn_yy"
-%expect 13
+%expect 16
%parse-param {const char *filename}
%parse-param {void *yyscanner}
diff --git a/dimension/grammar.epilogue b/dimension/grammar.epilogue
index 77a782a..bd8a89c 100644
--- a/dimension/grammar.epilogue
+++ b/dimension/grammar.epilogue
@@ -165,6 +165,9 @@ dmnsn_astnode_string(dmnsn_astnode_type astnode_type)
dmnsn_astnode_map(DMNSN_AST_COLOR_LIST, "color-list");
dmnsn_astnode_map(DMNSN_AST_COLOR_MAP, "color_map");
dmnsn_astnode_map(DMNSN_AST_COLOR_MAP_ENTRY, "color_map-entry");
+ dmnsn_astnode_map(DMNSN_AST_PIGMENT_LIST, "pigment-list");
+ dmnsn_astnode_map(DMNSN_AST_PIGMENT_MAP, "pigment_map");
+ dmnsn_astnode_map(DMNSN_AST_PIGMENT_MAP_ENTRY, "pigment_map-entry");
dmnsn_astnode_map(DMNSN_AST_QUICK_COLOR, "quick_color");
dmnsn_astnode_map(DMNSN_AST_IMAGE_MAP, "image_map");
dmnsn_astnode_map(DMNSN_AST_PNG, "png");
diff --git a/dimension/lexer.l b/dimension/lexer.l
index c5eeca7..45ba79a 100644
--- a/dimension/lexer.l
+++ b/dimension/lexer.l
@@ -240,6 +240,7 @@ unsigned long wchar;
"phong_size" RETURN_TOKEN(DMNSN_T_PHONG_SIZE);
"pi" RETURN_TOKEN(DMNSN_T_PI);
"pigment" RETURN_TOKEN(DMNSN_T_PIGMENT);
+"pigment_map" RETURN_TOKEN(DMNSN_T_PIGMENT_MAP);
"plane" RETURN_TOKEN(DMNSN_T_PLANE);
"png" RETURN_TOKEN(DMNSN_T_PNG);
"pow" RETURN_TOKEN(DMNSN_T_POW);
diff --git a/dimension/parse.h b/dimension/parse.h
index 7bff5ba..62a0782 100644
--- a/dimension/parse.h
+++ b/dimension/parse.h
@@ -79,6 +79,9 @@ typedef enum {
DMNSN_AST_COLOR_LIST,
DMNSN_AST_COLOR_MAP,
DMNSN_AST_COLOR_MAP_ENTRY,
+ DMNSN_AST_PIGMENT_LIST,
+ DMNSN_AST_PIGMENT_MAP,
+ DMNSN_AST_PIGMENT_MAP_ENTRY,
DMNSN_AST_QUICK_COLOR,
DMNSN_AST_IMAGE_MAP,
DMNSN_AST_PNG,
diff --git a/dimension/realize.c b/dimension/realize.c
index ddccf89..56bd846 100644
--- a/dimension/realize.c
+++ b/dimension/realize.c
@@ -263,6 +263,39 @@ dmnsn_realize_global_settings(dmnsn_astnode astnode, dmnsn_scene *scene)
}
}
+static dmnsn_pigment *dmnsn_realize_pigment(dmnsn_astnode astnode);
+
+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_camera *
dmnsn_realize_camera(dmnsn_astnode astnode)
{
@@ -521,6 +554,49 @@ dmnsn_realize_color_map(dmnsn_astnode astnode)
return color_map;
}
+static dmnsn_map *
+dmnsn_realize_pigment_list(dmnsn_astnode astnode)
+{
+ dmnsn_assert(astnode.type == DMNSN_AST_PIGMENT_LIST,
+ "Expected a pigment list.");
+
+ dmnsn_map *pigment_map = dmnsn_new_pigment_map();
+
+ double n = 0.0, i = 1.0/(dmnsn_array_size(astnode.children) - 1);
+ DMNSN_ARRAY_FOREACH (dmnsn_astnode *, entry, astnode.children) {
+ dmnsn_pigment *pigment = dmnsn_realize_pigment(*entry);
+ dmnsn_add_map_entry(pigment_map, n, &pigment);
+ n += i;
+ }
+
+ return pigment_map;
+}
+
+static dmnsn_map *
+dmnsn_realize_pigment_map(dmnsn_astnode astnode)
+{
+ dmnsn_assert(astnode.type == DMNSN_AST_PIGMENT_MAP,
+ "Expected a pigment_map.");
+
+ dmnsn_map *pigment_map = dmnsn_new_pigment_map();
+
+ DMNSN_ARRAY_FOREACH (dmnsn_astnode *, entry, astnode.children) {
+ dmnsn_assert(entry->type == DMNSN_AST_PIGMENT_MAP_ENTRY,
+ "Expected a pigment_map entry.");
+
+ dmnsn_astnode n_node, pigment_node;
+ dmnsn_array_get(entry->children, 0, &n_node);
+ dmnsn_array_get(entry->children, 1, &pigment_node);
+
+ double n = dmnsn_realize_float(n_node);
+ dmnsn_pigment *pigment = dmnsn_realize_pigment(pigment_node);
+
+ dmnsn_add_map_entry(pigment_map, n, &pigment);
+ }
+
+ return pigment_map;
+}
+
static dmnsn_pigment *
dmnsn_realize_pattern_pigment(dmnsn_astnode type, dmnsn_astnode modifiers)
{
@@ -528,9 +604,9 @@ dmnsn_realize_pattern_pigment(dmnsn_astnode type, dmnsn_astnode modifiers)
"Expected pigment modifiers");
dmnsn_pattern *pattern = dmnsn_realize_pattern(type);
- dmnsn_map *color_map = NULL;
+ dmnsn_map *color_map = NULL, *pigment_map = NULL;
- /* Set up the color_map */
+ /* Set up the map */
DMNSN_ARRAY_FOREACH_REVERSE (dmnsn_astnode *, modifier, modifiers.children) {
switch (modifier->type) {
case DMNSN_AST_COLOR_LIST:
@@ -540,11 +616,18 @@ dmnsn_realize_pattern_pigment(dmnsn_astnode type, dmnsn_astnode modifiers)
color_map = dmnsn_realize_color_map(*modifier);
break;
+ case DMNSN_AST_PIGMENT_LIST:
+ pigment_map = dmnsn_realize_pigment_list(*modifier);
+ break;
+ case DMNSN_AST_PIGMENT_MAP:
+ pigment_map = dmnsn_realize_pigment_map(*modifier);
+ break;
+
default:
break;
}
- if (color_map)
+ if (color_map || pigment_map)
break;
}
@@ -556,17 +639,18 @@ dmnsn_realize_pattern_pigment(dmnsn_astnode type, dmnsn_astnode modifiers)
switch (pattern_type.type) {
case DMNSN_AST_CHECKER:
/* Default checker pattern is blue and green */
- if (!color_map)
+ if (!color_map && !pigment_map) {
color_map = dmnsn_new_color_map();
- if (dmnsn_map_size(color_map) < 1)
- dmnsn_add_map_entry(color_map, 0.0, &dmnsn_blue);
- if (dmnsn_map_size(color_map) < 2)
- dmnsn_add_map_entry(color_map, 1.0, &dmnsn_green);
+ if (dmnsn_map_size(color_map) < 1)
+ dmnsn_add_map_entry(color_map, 0.0, &dmnsn_blue);
+ if (dmnsn_map_size(color_map) < 2)
+ dmnsn_add_map_entry(color_map, 1.0, &dmnsn_green);
+ }
break;
default:
/* Default map is grayscale */
- if (!color_map) {
+ if (!color_map && !pigment_map) {
color_map = dmnsn_new_color_map();
dmnsn_add_map_entry(color_map, 0.0, &dmnsn_black);
dmnsn_add_map_entry(color_map, 1.0, &dmnsn_white);
@@ -574,7 +658,14 @@ dmnsn_realize_pattern_pigment(dmnsn_astnode type, dmnsn_astnode modifiers)
break;
}
- dmnsn_pigment *pigment = dmnsn_new_color_map_pigment(pattern, color_map);
+ dmnsn_pigment *pigment = NULL;
+ if (color_map) {
+ pigment = dmnsn_new_color_map_pigment(pattern, color_map);
+ } else if (pigment_map) {
+ pigment = dmnsn_new_pigment_map_pigment(pattern, pigment_map);
+ } else {
+ dmnsn_assert(false, "No appropriate map constructed.");
+ }
return pigment;
}
@@ -603,6 +694,8 @@ dmnsn_realize_pigment_modifiers(dmnsn_astnode astnode, dmnsn_pigment *pigment)
case DMNSN_AST_COLOR_LIST:
case DMNSN_AST_COLOR_MAP:
+ case DMNSN_AST_PIGMENT_LIST:
+ case DMNSN_AST_PIGMENT_MAP:
/* Already handled by dmnsn_realize_pattern_pigment() */
break;
@@ -680,37 +773,6 @@ 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)
{
diff --git a/libdimension/Makefile.am b/libdimension/Makefile.am
index e56a22b..8b55e64 100644
--- a/libdimension/Makefile.am
+++ b/libdimension/Makefile.am
@@ -81,6 +81,7 @@ libdimension_la_SOURCES = $(nobase_include_HEADERS) \
pattern.c \
perspective.c \
phong.c \
+ pigment_map.c \
plane.c \
platform.c \
platform.h \
diff --git a/libdimension/dimension.h b/libdimension/dimension.h
index fb8efb5..e190de3 100644
--- a/libdimension/dimension.h
+++ b/libdimension/dimension.h
@@ -47,6 +47,12 @@ extern "C" {
/* Common types */
/**
+ * Generic callback type.
+ * @param[in,out] ptr A pointer to an object to act on.
+ */
+typedef void dmnsn_callback_fn(void *ptr);
+
+/**
* Destructor callback type.
* @param[in,out] ptr The pointer to free.
*/
diff --git a/libdimension/dimension/array.h b/libdimension/dimension/array.h
index 10afa9c..c789eed 100644
--- a/libdimension/dimension/array.h
+++ b/libdimension/dimension/array.h
@@ -227,6 +227,20 @@ dmnsn_array_remove(dmnsn_array *array, size_t i)
dmnsn_array_resize(array, size - 1);
}
+/**
+ * Apply a callback to each element of an array.
+ * @param[in,out] array The array.
+ * @param[in] callback The callback to apply to the elements.
+ */
+DMNSN_INLINE void
+dmnsn_array_apply(dmnsn_array *array, dmnsn_callback_fn *callback)
+{
+ char *i, *last = (char *)dmnsn_array_last(array);
+ for (i = (char *)dmnsn_array_first(array); i <= last; i += array->obj_size) {
+ (*callback)((void *)i);
+ }
+}
+
/* Macros to shorten array iteration */
/**
diff --git a/libdimension/dimension/map.h b/libdimension/dimension/map.h
index 1cd0f55..5e7134d 100644
--- a/libdimension/dimension/map.h
+++ b/libdimension/dimension/map.h
@@ -73,4 +73,11 @@ size_t dmnsn_map_size(const dmnsn_map *map);
void dmnsn_evaluate_map(const dmnsn_map *map, double n,
double *val, void *obj1, void *obj2);
+/**
+ * Apply a callback to each element of a map.
+ * @param[in,out] map The map.
+ * @param[in] callback The callback to apply to the elements.
+ */
+void dmnsn_map_apply(dmnsn_map *map, dmnsn_callback_fn *callback);
+
#endif /* DIMENSION_MAP_H */
diff --git a/libdimension/dimension/pigments.h b/libdimension/dimension/pigments.h
index 687080f..aa2c7c3 100644
--- a/libdimension/dimension/pigments.h
+++ b/libdimension/dimension/pigments.h
@@ -56,4 +56,19 @@ dmnsn_map *dmnsn_new_color_map();
dmnsn_pigment *dmnsn_new_color_map_pigment(dmnsn_pattern *pattern,
dmnsn_map *map);
+/**
+ * Construct a pigment map.
+ * @return An empty pigment map.
+ */
+dmnsn_map *dmnsn_new_pigment_map();
+
+/**
+ * A pigment-mapped pigment.
+ * @param[in,out] pattern The pattern of the pigment.
+ * @param[in,out] map The pigment map to apply to the pattern.
+ * @return A pigment mapping the pattern to other pigments.
+ */
+dmnsn_pigment *dmnsn_new_pigment_map_pigment(dmnsn_pattern *pattern,
+ dmnsn_map *map);
+
#endif /* DIMENSION_PIGMENTS_H */
diff --git a/libdimension/map.c b/libdimension/map.c
index 3ea4b0c..ba1adb6 100644
--- a/libdimension/map.c
+++ b/libdimension/map.c
@@ -124,3 +124,12 @@ dmnsn_evaluate_map(const dmnsn_map *map, double n,
memcpy(obj1, o2, map->obj_size);
memcpy(obj2, o2, map->obj_size);
}
+
+void
+dmnsn_map_apply(dmnsn_map *map, dmnsn_callback_fn *callback)
+{
+ for (size_t i = 0; i < dmnsn_array_size(map->array); ++i) {
+ dmnsn_map_entry *entry = dmnsn_array_at(map->array, i);
+ (*callback)(entry->object);
+ }
+}
diff --git a/tests/dimension/demo.pov b/tests/dimension/demo.pov
index 8088f45..c65c842 100644
--- a/tests/dimension/demo.pov
+++ b/tests/dimension/demo.pov
@@ -132,7 +132,14 @@ union {
plane {
y, -2
pigment {
- checker color rgb 0, color rgb 1
+ checker
+ pigment {
+ color rgb 1
+ }
+ pigment {
+ checker color rgb 0, color rgb 1
+ scale 1/3
+ }
quick_color rgb <1, 0.5, 0.75>
}
}
diff --git a/tests/dimension/demo.sh b/tests/dimension/demo.sh
index a741268..80d5ade 100755
--- a/tests/dimension/demo.sh
+++ b/tests/dimension/demo.sh
@@ -189,11 +189,23 @@ demo_exp=$(echo -n \
(quick_color
(vector (integer 1) (float 0.5) (float 0.75)
(integer 0) (integer 0)))
- (color-list
- (vector (integer 0) (integer 0) (integer 0)
- (integer 0) (integer 0))
- (vector (integer 1) (integer 1) (integer 1)
- (integer 0) (integer 0))))))))' \
+ (pigment-list
+ (pigment
+ (vector (integer 1) (integer 1) (integer 1)
+ (integer 0) (integer 0))
+ pigment-modifiers)
+ (pigment
+ (pattern checker)
+ (pigment-modifiers
+ (transformation
+ (scale (vector (float 0.333333) (float 0.333333)
+ (float 0.333333) (float 0.333333)
+ (float 0.333333))))
+ (color-list
+ (vector (integer 0) (integer 0) (integer 0)
+ (integer 0) (integer 0))
+ (vector (integer 1) (integer 1) (integer 1)
+ (integer 0) (integer 0)))))))))))' \
| tr '\n' ' ' | sed -r 's/[[:space:]]+/ /g')
if [ "$demo" != "$demo_exp" ]; then
diff --git a/tests/libdimension/render.c b/tests/libdimension/render.c
index 5ba075d..776fc1c 100644
--- a/tests/libdimension/render.c
+++ b/tests/libdimension/render.c
@@ -179,12 +179,21 @@ dmnsn_new_test_scene(void)
dmnsn_object *plane = dmnsn_new_plane(dmnsn_new_vector(0.0, 1.0, 0.0));
plane->trans = dmnsn_translation_matrix(dmnsn_new_vector(0.0, -2.0, 0.0));
plane->texture = dmnsn_new_texture();
- dmnsn_pattern *checker = dmnsn_new_checker_pattern();
+ dmnsn_pattern *checker1 = dmnsn_new_checker_pattern();
+ dmnsn_pattern *checker2 = dmnsn_new_checker_pattern();
dmnsn_map *checker_color_map = dmnsn_new_color_map();
dmnsn_add_map_entry(checker_color_map, 0.0, &dmnsn_black);
dmnsn_add_map_entry(checker_color_map, 1.0, &dmnsn_white);
+ dmnsn_pigment *pigment1 = dmnsn_new_solid_pigment(dmnsn_white);
+ dmnsn_pigment *pigment2
+ = dmnsn_new_color_map_pigment(checker1, checker_color_map);
+ pigment2->trans
+ = dmnsn_scale_matrix(dmnsn_new_vector(1.0/3.0, 1.0/3.0, 1.0/3.0));
+ dmnsn_map *checker_pigment_map = dmnsn_new_pigment_map();
+ dmnsn_add_map_entry(checker_pigment_map, 0.0, &pigment1);
+ dmnsn_add_map_entry(checker_pigment_map, 1.0, &pigment2);
plane->texture->pigment
- = dmnsn_new_color_map_pigment(checker, checker_color_map);
+ = dmnsn_new_pigment_map_pigment(checker2, checker_pigment_map);
plane->texture->pigment->quick_color
= dmnsn_color_from_sRGB((dmnsn_sRGB){ 1.0, 0.5, 0.75 });
dmnsn_array_push(scene->objects, &plane);