summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@gmail.com>2009-11-25 20:10:13 -0500
committerTavian Barnes <tavianator@gmail.com>2009-11-25 20:10:13 -0500
commit48ded3e40b77d2c072429854e2ebf81744c3e552 (patch)
treeff693e40dd3185c9e89ca07bef468e9b2a294d0e
parentcc79ac6130baca3179de24004420ce1d0199a140 (diff)
downloaddimension-48ded3e40b77d2c072429854e2ebf81744c3e552.tar.xz
Implement point lights.
-rw-r--r--dimension/grammar.y15
-rw-r--r--dimension/lexer.l1
-rw-r--r--dimension/parse.h1
-rw-r--r--dimension/realize.c65
-rw-r--r--tests/dimension/demo.pov8
-rwxr-xr-xtests/dimension/demo.sh17
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 <astnode> OBJECT
%type <astnode> FINITE_SOLID_OBJECT
%type <astnode> BOX
+%type <astnode> LIGHT_SOURCE
%type <astnode> 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