From 48ded3e40b77d2c072429854e2ebf81744c3e552 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Wed, 25 Nov 2009 20:10:13 -0500 Subject: Implement point lights. --- dimension/grammar.y | 15 +++++++++-- dimension/lexer.l | 1 + dimension/parse.h | 1 + dimension/realize.c | 65 ++++++++++++++++++++++++------------------------ tests/dimension/demo.pov | 8 ++++-- tests/dimension/demo.sh | 17 +++++++++---- 6 files changed, 65 insertions(+), 42 deletions(-) diff --git a/dimension/grammar.y b/dimension/grammar.y index 06260d4..27685b7 100644 --- a/dimension/grammar.y +++ b/dimension/grammar.y @@ -429,7 +429,7 @@ yyerror(YYLTYPE *locp, dmnsn_array *astree, dmnsn_token_iterator *iterator, %token DMNSN_T_LATHE %token DMNSN_T_LEOPARD %token DMNSN_T_LIGHT_GROUP -%token DMNSN_T_LIGHT_SOURCE +%token DMNSN_T_LIGHT_SOURCE "light_source" %token DMNSN_T_LINEAR_SPLINE %token DMNSN_T_LINEAR_SWEEP %token DMNSN_T_LN @@ -687,7 +687,7 @@ yyerror(YYLTYPE *locp, dmnsn_array *astree, dmnsn_token_iterator *iterator, %token DMNSN_T_RANGE %token DMNSN_T_READ %token DMNSN_T_RENDER -%token DMNSN_T_STATISTICS +%token DMNSN_T_STATISTICS %token DMNSN_T_SWITCH %token DMNSN_T_UNDEF %token DMNSN_T_VERSION @@ -711,6 +711,7 @@ yyerror(YYLTYPE *locp, dmnsn_array *astree, dmnsn_token_iterator *iterator, %type OBJECT %type FINITE_SOLID_OBJECT %type BOX +%type LIGHT_SOURCE %type SPHERE /* Object modifiers */ @@ -771,6 +772,7 @@ TRANSFORMATION: "rotate" VECTOR { /* Objects */ OBJECT: FINITE_SOLID_OBJECT + | LIGHT_SOURCE ; FINITE_SOLID_OBJECT: BOX @@ -786,6 +788,14 @@ BOX: "box" "{" } ; +LIGHT_SOURCE: "light_source" "{" + VECTOR "," COLOR + "}" + { + $$ = dmnsn_new_astnode2(DMNSN_AST_LIGHT_SOURCE, @$, $3, $5); + } +; + SPHERE: "sphere" "{" VECTOR "," FLOAT OBJECT_MODIFIERS @@ -1455,6 +1465,7 @@ dmnsn_astnode_string(dmnsn_astnode_type astnode_type) dmnsn_astnode_map(DMNSN_AST_BOX, "box"); dmnsn_astnode_map(DMNSN_AST_SPHERE, "sphere"); + dmnsn_astnode_map(DMNSN_AST_LIGHT_SOURCE, "light_source"); dmnsn_astnode_map(DMNSN_AST_OBJECT_MODIFIERS, "object-modifiers"); diff --git a/dimension/lexer.l b/dimension/lexer.l index ac90d8e..58bdc0e 100644 --- a/dimension/lexer.l +++ b/dimension/lexer.l @@ -159,6 +159,7 @@ unsigned long wchar; "gray" PUSH_TOKEN(DMNSN_T_GRAY); "grey" PUSH_TOKEN(DMNSN_T_GRAY); "green" PUSH_TOKEN(DMNSN_T_GREEN); +"light_source" PUSH_TOKEN(DMNSN_T_LIGHT_SOURCE); "pigment" PUSH_TOKEN(DMNSN_T_PIGMENT); "red" PUSH_TOKEN(DMNSN_T_RED); "rgb" PUSH_TOKEN(DMNSN_T_RGB); diff --git a/dimension/parse.h b/dimension/parse.h index eeb4492..1bf4436 100644 --- a/dimension/parse.h +++ b/dimension/parse.h @@ -30,6 +30,7 @@ typedef enum { DMNSN_AST_TRANSLATION, DMNSN_AST_BOX, + DMNSN_AST_LIGHT_SOURCE, DMNSN_AST_SPHERE, DMNSN_AST_OBJECT_MODIFIERS, diff --git a/dimension/realize.c b/dimension/realize.c index 84d04c6..ac0231b 100644 --- a/dimension/realize.c +++ b/dimension/realize.c @@ -162,8 +162,7 @@ dmnsn_realize_pigment(dmnsn_astnode astnode, dmnsn_object *object) if (!object->texture) { object->texture = dmnsn_new_texture(); if (!object->texture) { - dmnsn_delete_object(object); - return NULL; + dmnsn_error(DMNSN_SEVERITY_HIGH, "Couldn't create texture."); } } dmnsn_delete_pigment(object->texture->pigment); @@ -180,8 +179,7 @@ dmnsn_realize_pigment(dmnsn_astnode astnode, dmnsn_object *object) color = dmnsn_realize_color(color_node); object->texture->pigment = dmnsn_new_solid_pigment(color); if (!object->texture->pigment) { - dmnsn_delete_object(object); - return NULL; + dmnsn_error(DMNSN_SEVERITY_HIGH, "Couldn't create pigment."); } break; @@ -290,6 +288,28 @@ dmnsn_realize_box(dmnsn_astnode astnode) return box; } +static dmnsn_light * +dmnsn_realize_light_source(dmnsn_astnode astnode) +{ + if (astnode.type != DMNSN_AST_LIGHT_SOURCE) { + dmnsn_error(DMNSN_SEVERITY_HIGH, "Expected a light source."); + } + + dmnsn_astnode point, color_node; + dmnsn_array_get(astnode.children, 0, &point); + dmnsn_array_get(astnode.children, 1, &color_node); + + dmnsn_vector x0 = dmnsn_realize_vector(point); + dmnsn_color color = dmnsn_realize_color(color_node); + + dmnsn_light *light = dmnsn_new_point_light(x0, color); + if (!light) { + dmnsn_error(DMNSN_SEVERITY_HIGH, "Couldn't allocate light."); + } + + return light; +} + static dmnsn_object * dmnsn_realize_sphere(dmnsn_astnode astnode) { @@ -309,18 +329,6 @@ dmnsn_realize_sphere(dmnsn_astnode astnode) dmnsn_error(DMNSN_SEVERITY_HIGH, "Couldn't allocate sphere."); } - sphere->texture = dmnsn_new_texture(); - if (!sphere->texture) { - dmnsn_delete_object(sphere); - dmnsn_error(DMNSN_SEVERITY_HIGH, "Couldn't allocate sphere texture."); - } - - sphere->texture->pigment = dmnsn_new_solid_pigment(dmnsn_white); - if (!sphere->texture->pigment) { - dmnsn_delete_object(sphere); - dmnsn_error(DMNSN_SEVERITY_HIGH, "Couldn't allocate sphere pigment."); - } - sphere->trans = dmnsn_scale_matrix(dmnsn_new_vector(r, r, r)); sphere->trans = dmnsn_matrix_mul(dmnsn_translation_matrix(x0), sphere->trans); @@ -340,7 +348,7 @@ dmnsn_realize(const dmnsn_array *astree) } /* Default finish */ - scene->default_texture->finish = dmnsn_new_phong_finish(1.0, 0.5, 50.0); + scene->default_texture->finish = dmnsn_new_phong_finish(1.0, 0.0, 1.0); if (!scene->default_texture->finish) { dmnsn_delete_scene(scene); return NULL; @@ -382,18 +390,6 @@ dmnsn_realize(const dmnsn_array *astree) } dmnsn_set_perspective_camera_trans(scene->camera, trans); - /* Make a light */ - - dmnsn_light *light = dmnsn_new_point_light( - dmnsn_new_vector(-15.0, 20.0, 10.0), - dmnsn_white - ); - if (!light) { - dmnsn_delete_scene(scene); - return NULL; - } - dmnsn_array_push(scene->lights, &light); - /* * Now parse the abstract syntax tree */ @@ -404,6 +400,7 @@ dmnsn_realize(const dmnsn_array *astree) for (i = 0; i < dmnsn_array_size(astree); ++i) { dmnsn_array_get(astree, i, &astnode); + dmnsn_light *light; dmnsn_object *object; switch (astnode.type) { case DMNSN_AST_BOX: @@ -411,16 +408,18 @@ dmnsn_realize(const dmnsn_array *astree) dmnsn_array_push(scene->objects, &object); break; + case DMNSN_AST_LIGHT_SOURCE: + light = dmnsn_realize_light_source(astnode); + dmnsn_array_push(scene->lights, &light); + break; + case DMNSN_AST_SPHERE: object = dmnsn_realize_sphere(astnode); dmnsn_array_push(scene->objects, &object); break; default: - fprintf(stderr, "Unrecognised syntax element '%s'.\n", - dmnsn_astnode_string(astnode.type)); - dmnsn_delete_scene(scene); - return NULL; + dmnsn_error(DMNSN_SEVERITY_HIGH, "Unrecognised syntax element."); } } diff --git a/tests/dimension/demo.pov b/tests/dimension/demo.pov index 5aa044e..b6833bc 100644 --- a/tests/dimension/demo.pov +++ b/tests/dimension/demo.pov @@ -19,17 +19,21 @@ // Render demo scene +light_source { + <-15, 20, 10>, rgb <1, 1, 1> +} + box { <-1, -1, -1>, <1, 1, 1> rotate <45, 0, 0> pigment { - color rgbft <0, 0, 1, 0.25, 0.25> + rgbft <0, 0, 1, 0.25, 0.25> } } sphere { <0, 0, 0>, 1.25 pigment { - color rgb <0, 1, 0> + rgb <0, 1, 0> } } diff --git a/tests/dimension/demo.sh b/tests/dimension/demo.sh index ae65a9d..fbd6fc3 100755 --- a/tests/dimension/demo.sh +++ b/tests/dimension/demo.sh @@ -21,24 +21,31 @@ demo=$(${top_builddir}/dimension/dimension --tokenize --parse ${srcdir}/demo.pov) demo_exp="$(echo -n \ -'(box { +'(light_source { + < - (integer "15") , (integer "20") , (integer "10") > , + rgb < (integer "1") , (integer "1") , (integer "1") > + } + box { < - (integer "1") , - (integer "1") , - (integer "1") > , < (integer "1") , (integer "1") , (integer "1") > rotate < (integer "45") , (integer "0") , (integer "0") > pigment { - color rgbft < (integer "0") , (integer "0") , (integer "1") , - (float "0.25") , (float "0.25") > + rgbft < (integer "0") , (integer "0") , (integer "1") , + (float "0.25") , (float "0.25") > } } sphere { < (integer "0") , (integer "0") , (integer "0") > , (float "1.25") pigment { - color rgb < (integer "0") , (integer "1") , (integer "0") > + rgb < (integer "0") , (integer "1") , (integer "0") > } })' \ | tr '\n' ' ' | sed -r 's/[[:space:]]+/ /g') $(echo -n \ -'((box +'((light_source + (vector (integer -15) (integer 20) (integer 10) (integer 0) (integer 0)) + (vector (integer 1) (integer 1) (integer 1) (integer 0) (integer 0))) + (box (vector (integer -1) (integer -1) (integer -1) (integer 0) (integer 0)) (vector (integer 1) (integer 1) (integer 1) (integer 0) (integer 0)) (object-modifiers -- cgit v1.2.3