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 ++++++++++++++++++++++++++--------------------------- 4 files changed, 47 insertions(+), 35 deletions(-) (limited to 'dimension') 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."); } } -- cgit v1.2.3