From a76d4f1fb96633e7f348ba6aa0c14b726e15e28e Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Mon, 8 Nov 2010 16:10:40 -0500 Subject: Add quick_color to pigments. --- dimension/common.rules | 6 ++++++ dimension/common.terminals | 2 +- dimension/directives.declarations | 2 +- dimension/grammar.declarations | 2 +- dimension/grammar.epilogue | 1 + dimension/lexer.l | 2 ++ dimension/parse.h | 1 + dimension/realize.c | 8 ++++++++ libdimension/dimension/texture.h | 3 +++ libdimension/raytrace.c | 25 ++++++++++++++++++------- libdimension/solid_pigment.c | 21 +-------------------- libdimension/texture.c | 8 +++++--- tests/dimension/demo.pov | 1 + tests/dimension/demo.sh | 3 +++ tests/libdimension/render.c | 2 ++ 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 -/* 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; -- cgit v1.2.3