From 32f46ae1ccdb01533ea61265e4c977b9307c710d Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Wed, 25 Nov 2009 14:09:06 -0500 Subject: Support solid-color pigments. --- dimension/grammar.y | 12 ++--- dimension/lexer.l | 6 +++ dimension/parse.h | 2 - dimension/realize.c | 134 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 145 insertions(+), 9 deletions(-) (limited to 'dimension') diff --git a/dimension/grammar.y b/dimension/grammar.y index 2950941..5a271cc 100644 --- a/dimension/grammar.y +++ b/dimension/grammar.y @@ -505,7 +505,7 @@ yyerror(YYLTYPE *locp, dmnsn_array *astree, dmnsn_token_iterator *iterator, %token DMNSN_T_PHONG_SIZE %token DMNSN_T_PHOTONS %token DMNSN_T_PI -%token DMNSN_T_PIGMENT +%token DMNSN_T_PIGMENT "pigment" %token DMNSN_T_PIGMENT_MAP %token DMNSN_T_PIGMENT_PATTERN %token DMNSN_T_PLANAR @@ -547,10 +547,10 @@ yyerror(YYLTYPE *locp, dmnsn_array *astree, dmnsn_token_iterator *iterator, %token DMNSN_T_REFLECTION_EXPONENT %token DMNSN_T_REFRACTION %token DMNSN_T_REPEAT -%token DMNSN_T_RGB -%token DMNSN_T_RGBF -%token DMNSN_T_RGBFT -%token DMNSN_T_RGBT +%token DMNSN_T_RGB "rgb" +%token DMNSN_T_RGBF "rgbf" +%token DMNSN_T_RGBFT "rgbft" +%token DMNSN_T_RGBT "rgbt" %token DMNSN_T_RIGHT %token DMNSN_T_RIPPLES %token DMNSN_T_ROTATE "rotate" @@ -1464,8 +1464,6 @@ dmnsn_astnode_string(dmnsn_astnode_type astnode_type) dmnsn_astnode_map(DMNSN_AST_VECTOR, "vector"); - dmnsn_astnode_map(DMNSN_AST_COLOR, "color"); - dmnsn_astnode_map(DMNSN_AST_NEGATE, "-"); dmnsn_astnode_map(DMNSN_AST_ADD, "+"); dmnsn_astnode_map(DMNSN_AST_SUB, "-"); diff --git a/dimension/lexer.l b/dimension/lexer.l index 618bb7b..942a89f 100644 --- a/dimension/lexer.l +++ b/dimension/lexer.l @@ -159,10 +159,16 @@ unsigned long wchar; "gray" PUSH_TOKEN(DMNSN_T_GRAY); "grey" PUSH_TOKEN(DMNSN_T_GRAY); "green" PUSH_TOKEN(DMNSN_T_GREEN); +"pigment" PUSH_TOKEN(DMNSN_T_PIGMENT); "red" PUSH_TOKEN(DMNSN_T_RED); +"rgb" PUSH_TOKEN(DMNSN_T_RGB); +"rgbf" PUSH_TOKEN(DMNSN_T_RGBF); +"rgbft" PUSH_TOKEN(DMNSN_T_RGBFT); +"rgbt" PUSH_TOKEN(DMNSN_T_RGBT); "rotate" PUSH_TOKEN(DMNSN_T_ROTATE); "sphere" PUSH_TOKEN(DMNSN_T_SPHERE); "t" PUSH_TOKEN(DMNSN_T_T); +"texture" PUSH_TOKEN(DMNSN_T_TEXTURE); "transmit" PUSH_TOKEN(DMNSN_T_TRANSMIT); "u" PUSH_TOKEN(DMNSN_T_U); "v" PUSH_TOKEN(DMNSN_T_V); diff --git a/dimension/parse.h b/dimension/parse.h index f9d1dc9..eeb4492 100644 --- a/dimension/parse.h +++ b/dimension/parse.h @@ -42,8 +42,6 @@ typedef enum { DMNSN_AST_VECTOR, - DMNSN_AST_COLOR, - DMNSN_AST_NEGATE, DMNSN_AST_ADD, DMNSN_AST_SUB, diff --git a/dimension/realize.c b/dimension/realize.c index 3b1d327..84d04c6 100644 --- a/dimension/realize.c +++ b/dimension/realize.c @@ -56,9 +56,42 @@ dmnsn_realize_vector(dmnsn_astnode astnode) return dmnsn_new_vector(x, y, z); } +static dmnsn_color +dmnsn_realize_color(dmnsn_astnode astnode) +{ + if (astnode.type != DMNSN_AST_VECTOR) { + dmnsn_error(DMNSN_SEVERITY_HIGH, "Expected a color."); + } + + + dmnsn_astnode rnode, gnode, bnode, fnode, tnode; + dmnsn_array_get(astnode.children, 0, &rnode); + dmnsn_array_get(astnode.children, 1, &gnode); + dmnsn_array_get(astnode.children, 2, &bnode); + dmnsn_array_get(astnode.children, 3, &fnode); + dmnsn_array_get(astnode.children, 4, &tnode); + + double r = dmnsn_realize_float(rnode), + g = dmnsn_realize_float(gnode), + b = dmnsn_realize_float(bnode), + f = dmnsn_realize_float(fnode), + t = dmnsn_realize_float(tnode); + + dmnsn_sRGB sRGB = { .R = r, .G = g, .B = b }; + dmnsn_color color = dmnsn_color_from_sRGB(sRGB); + color.filter = f; + color.trans = t; + + return color; +} + static dmnsn_object * dmnsn_realize_rotation(dmnsn_astnode astnode, dmnsn_object *object) { + if (astnode.type != DMNSN_AST_ROTATION) { + dmnsn_error(DMNSN_SEVERITY_HIGH, "Expected a rotation."); + } + const double deg2rad = atan(1.0)/45.0; dmnsn_astnode angle_node; @@ -89,6 +122,10 @@ dmnsn_realize_rotation(dmnsn_astnode astnode, dmnsn_object *object) static dmnsn_object * dmnsn_realize_scale(dmnsn_astnode astnode, dmnsn_object *object) { + if (astnode.type != DMNSN_AST_SCALE) { + dmnsn_error(DMNSN_SEVERITY_HIGH, "Expected a scale."); + } + dmnsn_astnode scale_node; dmnsn_array_get(astnode.children, 0, &scale_node); dmnsn_vector scale = dmnsn_realize_vector(scale_node); @@ -100,6 +137,10 @@ dmnsn_realize_scale(dmnsn_astnode astnode, dmnsn_object *object) static dmnsn_object * dmnsn_realize_translation(dmnsn_astnode astnode, dmnsn_object *object) { + if (astnode.type != DMNSN_AST_TRANSLATION) { + dmnsn_error(DMNSN_SEVERITY_HIGH, "Expected a translation."); + } + dmnsn_astnode trans_node; dmnsn_array_get(astnode.children, 0, &trans_node); dmnsn_vector trans = dmnsn_realize_vector(trans_node); @@ -111,9 +152,78 @@ dmnsn_realize_translation(dmnsn_astnode astnode, dmnsn_object *object) return object; } +static dmnsn_object * +dmnsn_realize_pigment(dmnsn_astnode astnode, dmnsn_object *object) +{ + if (astnode.type != DMNSN_AST_PIGMENT) { + dmnsn_error(DMNSN_SEVERITY_HIGH, "Expected a pigment."); + } + + if (!object->texture) { + object->texture = dmnsn_new_texture(); + if (!object->texture) { + dmnsn_delete_object(object); + return NULL; + } + } + dmnsn_delete_pigment(object->texture->pigment); + + dmnsn_astnode color_node; + dmnsn_array_get(astnode.children, 0, &color_node); + + dmnsn_color color; + switch (color_node.type) { + case DMNSN_AST_NONE: + break; + + case DMNSN_AST_VECTOR: + color = dmnsn_realize_color(color_node); + object->texture->pigment = dmnsn_new_solid_pigment(color); + if (!object->texture->pigment) { + dmnsn_delete_object(object); + return NULL; + } + break; + + default: + dmnsn_error(DMNSN_SEVERITY_HIGH, "Invalid pigment color."); + } + + return object; +} + +static dmnsn_object * +dmnsn_realize_texture(dmnsn_astnode astnode, dmnsn_object *object) +{ + if (astnode.type != DMNSN_AST_TEXTURE) { + dmnsn_error(DMNSN_SEVERITY_HIGH, "Expected a texture."); + } + + unsigned int i; + for (i = 0; i < dmnsn_array_size(astnode.children); ++i) { + dmnsn_astnode modifier; + dmnsn_array_get(astnode.children, i, &modifier); + + switch (modifier.type) { + case DMNSN_AST_PIGMENT: + object = dmnsn_realize_pigment(modifier, object); + break; + + default: + dmnsn_error(DMNSN_SEVERITY_HIGH, "Invalid texture item."); + } + } + + return object; +} + static dmnsn_object * dmnsn_realize_object_modifiers(dmnsn_astnode astnode, dmnsn_object *object) { + if (astnode.type != DMNSN_AST_OBJECT_MODIFIERS) { + dmnsn_error(DMNSN_SEVERITY_HIGH, "Expected object modifiers."); + } + unsigned int i; for (i = 0; i < dmnsn_array_size(astnode.children); ++i) { dmnsn_astnode modifier; @@ -130,6 +240,10 @@ dmnsn_realize_object_modifiers(dmnsn_astnode astnode, dmnsn_object *object) object = dmnsn_realize_translation(modifier, object); break; + case DMNSN_AST_TEXTURE: + object = dmnsn_realize_texture(modifier, object); + break; + default: dmnsn_error(DMNSN_SEVERITY_HIGH, "Invalid object modifier."); } @@ -225,6 +339,14 @@ dmnsn_realize(const dmnsn_array *astree) return NULL; } + /* Default finish */ + scene->default_texture->finish = dmnsn_new_phong_finish(1.0, 0.5, 50.0); + if (!scene->default_texture->finish) { + dmnsn_delete_scene(scene); + return NULL; + } + scene->default_texture->finish->ambient = 0.1; + /* Background color */ dmnsn_sRGB background_sRGB = { .R = 0.0, .G = 0.0, .B = 0.1 }; scene->background = dmnsn_color_from_sRGB(background_sRGB); @@ -260,6 +382,18 @@ 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 */ -- cgit v1.2.3