summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dimension/common.rules6
-rw-r--r--dimension/common.terminals2
-rw-r--r--dimension/directives.declarations2
-rw-r--r--dimension/grammar.declarations2
-rw-r--r--dimension/grammar.epilogue1
-rw-r--r--dimension/lexer.l2
-rw-r--r--dimension/parse.h1
-rw-r--r--dimension/realize.c8
-rw-r--r--libdimension/dimension/texture.h3
-rw-r--r--libdimension/raytrace.c25
-rw-r--r--libdimension/solid_pigment.c21
-rw-r--r--libdimension/texture.c8
-rw-r--r--tests/dimension/demo.pov1
-rwxr-xr-xtests/dimension/demo.sh3
-rw-r--r--tests/libdimension/render.c2
15 files changed, 54 insertions, 33 deletions
diff --git a/dimension/common.rules b/dimension/common.rules
index 600ef80..74a40e4 100644
--- a/dimension/common.rules
+++ b/dimension/common.rules
@@ -572,6 +572,12 @@ PIGMENT_MODIFIERS: /* empty */ {
$$ = $1;
dmnsn_array_push($$.children, &$2);
}
+ | PIGMENT_MODIFIERS "quick_color" COLOR {
+ dmnsn_astnode quick_color
+ = dmnsn_new_astnode1(DMNSN_AST_QUICK_COLOR, @2, $3);
+ $$ = $1;
+ dmnsn_array_push($$.children, &quick_color);
+ }
;
COLOR_LIST2: /* empty */ {
diff --git a/dimension/common.terminals b/dimension/common.terminals
index 7b19a33..e2df8d1 100644
--- a/dimension/common.terminals
+++ b/dimension/common.terminals
@@ -356,7 +356,7 @@
%token DMNSN_T_QUADRIC
%token DMNSN_T_QUARTIC
%token DMNSN_T_QUATERNION
-%token DMNSN_T_QUICK_COLOR
+%token DMNSN_T_QUICK_COLOR "quick_color"
%token DMNSN_T_QUILTED
%token DMNSN_T_RADIAL
%token DMNSN_T_RADIANS "radians"
diff --git a/dimension/directives.declarations b/dimension/directives.declarations
index b1a984d..9f8c891 100644
--- a/dimension/directives.declarations
+++ b/dimension/directives.declarations
@@ -21,7 +21,7 @@
%name-prefix "dmnsn_ld_yy"
-%expect 15
+%expect 16
%expect-rr 6
%parse-param {const char *filename}
diff --git a/dimension/grammar.declarations b/dimension/grammar.declarations
index 987d9c9..58b995f 100644
--- a/dimension/grammar.declarations
+++ b/dimension/grammar.declarations
@@ -23,7 +23,7 @@
%name-prefix "dmnsn_yy"
-%expect 11
+%expect 12
%parse-param {const char *filename}
%parse-param {void *yyscanner}
diff --git a/dimension/grammar.epilogue b/dimension/grammar.epilogue
index 731d017..3856e1e 100644
--- a/dimension/grammar.epilogue
+++ b/dimension/grammar.epilogue
@@ -158,6 +158,7 @@ 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_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 2f84620..7c06df2 100644
--- a/dimension/lexer.l
+++ b/dimension/lexer.l
@@ -239,6 +239,8 @@ unsigned long wchar;
"plane" RETURN_TOKEN(DMNSN_T_PLANE);
"png" RETURN_TOKEN(DMNSN_T_PNG);
"pow" RETURN_TOKEN(DMNSN_T_POW);
+"quick_color" RETURN_TOKEN(DMNSN_T_QUICK_COLOR);
+"quick_colour" RETURN_TOKEN(DMNSN_T_QUICK_COLOR);
"radians" RETURN_TOKEN(DMNSN_T_RADIANS);
"red" RETURN_TOKEN(DMNSN_T_RED);
"reflection" RETURN_TOKEN(DMNSN_T_REFLECTION);
diff --git a/dimension/parse.h b/dimension/parse.h
index 09ca685..5336d27 100644
--- a/dimension/parse.h
+++ b/dimension/parse.h
@@ -72,6 +72,7 @@ typedef enum {
DMNSN_AST_COLOR_LIST,
DMNSN_AST_COLOR_MAP,
DMNSN_AST_COLOR_MAP_ENTRY,
+ DMNSN_AST_QUICK_COLOR,
DMNSN_AST_IMAGE_MAP,
DMNSN_AST_PNG,
diff --git a/dimension/realize.c b/dimension/realize.c
index ab5f2a0..e6de1a4 100644
--- a/dimension/realize.c
+++ b/dimension/realize.c
@@ -589,6 +589,14 @@ dmnsn_realize_pigment_modifiers(dmnsn_astnode astnode, dmnsn_pigment *pigment)
);
break;
+ case DMNSN_AST_QUICK_COLOR:
+ {
+ dmnsn_astnode quick_color;
+ dmnsn_array_get(modifier->children, 0, &quick_color);
+ pigment->quick_color = dmnsn_realize_color(quick_color);
+ break;
+ }
+
case DMNSN_AST_COLOR_LIST:
case DMNSN_AST_COLOR_MAP:
/* Already handled by dmnsn_realize_pattern_pigment() */
diff --git a/libdimension/dimension/texture.h b/libdimension/dimension/texture.h
index c30b368..5586e24 100644
--- a/libdimension/dimension/texture.h
+++ b/libdimension/dimension/texture.h
@@ -47,6 +47,9 @@ struct dmnsn_pigment {
/* Transformation matrix */
dmnsn_matrix trans, trans_inv;
+ /* Quick color */
+ dmnsn_color quick_color;
+
/* Generic pointer */
void *ptr;
};
diff --git a/libdimension/raytrace.c b/libdimension/raytrace.c
index 950b4f2..89908fa 100644
--- a/libdimension/raytrace.c
+++ b/libdimension/raytrace.c
@@ -224,8 +224,10 @@ dmnsn_raytrace_scene_impl(dmnsn_progress *progress, dmnsn_scene *scene,
#define ITEXTURE(state) (state->intersection->texture)
#define DTEXTURE(state) (state->scene->default_texture)
-#define CAN_CALL(texture, telem, fn) \
- ((texture) && (texture)->telem && (texture)->telem->fn)
+#define CAN_ACCESS(texture, telem) \
+ ((texture) && (texture)->telem)
+#define CAN_CALL(texture, telem, fn) \
+ (CAN_ACCESS(texture, telem) && (texture)->telem->fn)
/* Determine whether a callback may be called */
#define TEXTURE_HAS_CALLBACK(state, telem, fn) \
@@ -240,6 +242,14 @@ dmnsn_raytrace_scene_impl(dmnsn_progress *progress, dmnsn_scene *scene,
? (*DTEXTURE(state)->telem->fn)(DTEXTURE(state)->telem, __VA_ARGS__) \
: def));
+/* Get a property from a texture element */
+#define TEXTURE_PROPERTY(state, telem, prop, def) \
+ (CAN_ACCESS(ITEXTURE(state), telem) \
+ ? ITEXTURE(state)->telem->prop \
+ : (CAN_ACCESS(DTEXTURE(state), telem) \
+ ? DTEXTURE(state)->telem->prop \
+ : def))
+
#define IOR(state) \
((state)->intersection->interior \
? (state)->intersection->interior->ior \
@@ -248,8 +258,11 @@ dmnsn_raytrace_scene_impl(dmnsn_progress *progress, dmnsn_scene *scene,
static void
dmnsn_raytrace_pigment(dmnsn_raytrace_state *state)
{
- state->pigment = TEXTURE_CALLBACK(state, pigment, pigment_fn, dmnsn_black,
- state->r);
+ state->pigment = TEXTURE_PROPERTY(state, pigment, quick_color, dmnsn_black);
+ if (state->scene->quality & DMNSN_RENDER_PIGMENT) {
+ state->pigment = TEXTURE_CALLBACK(state, pigment, pigment_fn,
+ state->pigment, state->r);
+ }
state->diffuse = state->pigment;
}
@@ -453,9 +466,7 @@ dmnsn_raytrace_shoot(dmnsn_raytrace_state *state, dmnsn_line ray)
state->additional = dmnsn_black;
/* Pigment */
- if (state->scene->quality & DMNSN_RENDER_PIGMENT) {
- dmnsn_raytrace_pigment(state);
- }
+ dmnsn_raytrace_pigment(state);
/* Finishes and shadows */
if (state->scene->quality & DMNSN_RENDER_LIGHTS) {
diff --git a/libdimension/solid_pigment.c b/libdimension/solid_pigment.c
index cc8310a..15ea86f 100644
--- a/libdimension/solid_pigment.c
+++ b/libdimension/solid_pigment.c
@@ -21,30 +21,11 @@
#include "dimension.h"
#include <stdlib.h>
-/* Solid color pigment callback */
-static dmnsn_color dmnsn_solid_pigment_fn(const dmnsn_pigment *pigment,
- dmnsn_vector v);
-
/* Create a solid color */
dmnsn_pigment *
dmnsn_new_solid_pigment(dmnsn_color color)
{
dmnsn_pigment *pigment = dmnsn_new_pigment();
-
- dmnsn_color *solid = dmnsn_malloc(sizeof(dmnsn_color));
- *solid = color;
-
- pigment->pigment_fn = &dmnsn_solid_pigment_fn;
- pigment->free_fn = &dmnsn_free;
- pigment->ptr = solid;
-
+ pigment->quick_color = color;
return pigment;
}
-
-/* Solid color callback */
-static dmnsn_color
-dmnsn_solid_pigment_fn(const dmnsn_pigment *pigment, dmnsn_vector v)
-{
- dmnsn_color *color = pigment->ptr;
- return *color;
-}
diff --git a/libdimension/texture.c b/libdimension/texture.c
index 9305f46..00b8682 100644
--- a/libdimension/texture.c
+++ b/libdimension/texture.c
@@ -26,9 +26,11 @@ dmnsn_pigment *
dmnsn_new_pigment()
{
dmnsn_pigment *pigment = dmnsn_malloc(sizeof(dmnsn_pigment));
- pigment->init_fn = NULL;
- pigment->free_fn = NULL;
- pigment->trans = dmnsn_identity_matrix();
+ pigment->pigment_fn = NULL;
+ pigment->init_fn = NULL;
+ pigment->free_fn = NULL;
+ pigment->trans = dmnsn_identity_matrix();
+ pigment->quick_color = dmnsn_black;
return pigment;
}
diff --git a/tests/dimension/demo.pov b/tests/dimension/demo.pov
index 197fe23..0740ecb 100644
--- a/tests/dimension/demo.pov
+++ b/tests/dimension/demo.pov
@@ -123,5 +123,6 @@ plane {
y, -2
pigment {
checker color rgb 0, color rgb 1
+ quick_color rgb <1, 0.5, 0.75>
}
}
diff --git a/tests/dimension/demo.sh b/tests/dimension/demo.sh
index 4e0c206..4e26bdc 100755
--- a/tests/dimension/demo.sh
+++ b/tests/dimension/demo.sh
@@ -171,6 +171,9 @@ demo_exp=$(echo -n \
(pigment
(pattern checker)
(pigment-modifiers
+ (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))
diff --git a/tests/libdimension/render.c b/tests/libdimension/render.c
index 4f8f23e..1de9fba 100644
--- a/tests/libdimension/render.c
+++ b/tests/libdimension/render.c
@@ -174,6 +174,8 @@ dmnsn_new_test_scene(void)
dmnsn_add_color_map_entry(checker_color_map, 1.0, dmnsn_white);
plane->texture->pigment
= dmnsn_new_color_map_pigment(checker, checker_color_map);
+ plane->texture->pigment->quick_color
+ = dmnsn_color_from_sRGB((dmnsn_sRGB){ 1.0, 0.5, 0.75 });
dmnsn_array_push(scene->objects, &plane);
return scene;