diff options
-rw-r--r-- | libdimension/diffuse.c | 9 | ||||
-rw-r--r-- | libdimension/dimension/texture.h | 16 | ||||
-rw-r--r-- | libdimension/finish_combination.c | 55 | ||||
-rw-r--r-- | libdimension/phong.c | 14 | ||||
-rw-r--r-- | libdimension/raytrace.c | 19 | ||||
-rw-r--r-- | libdimension/texture.c | 3 |
6 files changed, 76 insertions, 40 deletions
diff --git a/libdimension/diffuse.c b/libdimension/diffuse.c index 4da51ee..895b918 100644 --- a/libdimension/diffuse.c +++ b/libdimension/diffuse.c @@ -29,8 +29,7 @@ static dmnsn_color dmnsn_diffuse_finish_fn(const dmnsn_finish *finish, dmnsn_color light, dmnsn_color color, - dmnsn_vector ray, dmnsn_vector normal, - dmnsn_vector viewer) + dmnsn_vector ray, dmnsn_vector normal) { double *diffuse = finish->ptr; double diffuse_factor = (*diffuse)*dmnsn_vector_dot(ray, normal); @@ -50,9 +49,9 @@ dmnsn_new_diffuse_finish(double diffuse) *param = diffuse; - finish->ptr = param; - finish->finish_fn = &dmnsn_diffuse_finish_fn; - finish->free_fn = &free; + finish->ptr = param; + finish->diffuse_fn = &dmnsn_diffuse_finish_fn; + finish->free_fn = &free; } return finish; } diff --git a/libdimension/dimension/texture.h b/libdimension/dimension/texture.h index 4b14918..0c2b04b 100644 --- a/libdimension/dimension/texture.h +++ b/libdimension/dimension/texture.h @@ -56,11 +56,14 @@ void dmnsn_delete_pigment(dmnsn_pigment *pigment); /* Forward-declare dmnsn_finish */ typedef struct dmnsn_finish dmnsn_finish; -/* Finish callback */ -typedef dmnsn_color dmnsn_finish_fn(const dmnsn_finish *finish, - dmnsn_color light, dmnsn_color color, - dmnsn_vector ray, dmnsn_vector normal, - dmnsn_vector viewer); +/* Finish callbacks */ +typedef dmnsn_color dmnsn_diffuse_fn(const dmnsn_finish *finish, + dmnsn_color light, dmnsn_color color, + dmnsn_vector ray, dmnsn_vector normal); +typedef dmnsn_color dmnsn_specular_fn(const dmnsn_finish *finish, + dmnsn_color light, dmnsn_color color, + dmnsn_vector ray, dmnsn_vector normal, + dmnsn_vector viewer); typedef dmnsn_color dmnsn_ambient_fn(const dmnsn_finish *finish, dmnsn_color pigment); typedef dmnsn_color dmnsn_reflection_fn(const dmnsn_finish *finish, @@ -70,7 +73,8 @@ typedef dmnsn_color dmnsn_reflection_fn(const dmnsn_finish *finish, /* dmnsn_finish definition */ struct dmnsn_finish { /* Callbacks */ - dmnsn_finish_fn *finish_fn; + dmnsn_diffuse_fn *diffuse_fn; + dmnsn_specular_fn *specular_fn; dmnsn_ambient_fn *ambient_fn; dmnsn_reflection_fn *reflection_fn; dmnsn_free_fn *free_fn; diff --git a/libdimension/finish_combination.c b/libdimension/finish_combination.c index bcfc1c9..1996f50 100644 --- a/libdimension/finish_combination.c +++ b/libdimension/finish_combination.c @@ -27,23 +27,43 @@ */ static dmnsn_color -dmnsn_finish_combination_fn(const dmnsn_finish *finish, - dmnsn_color light, dmnsn_color color, - dmnsn_vector ray, dmnsn_vector normal, - dmnsn_vector viewer) +dmnsn_finish_combination_diffuse_fn(const dmnsn_finish *finish, + dmnsn_color light, dmnsn_color color, + dmnsn_vector ray, dmnsn_vector normal) { dmnsn_finish **params = finish->ptr; - if (params[0]->finish_fn && params[1]->finish_fn) { + if (params[0]->diffuse_fn && params[1]->diffuse_fn) { return dmnsn_color_add( - (*params[0]->finish_fn)(params[0], light, color, ray, normal, viewer), - (*params[1]->finish_fn)(params[1], light, color, ray, normal, viewer) + (*params[0]->diffuse_fn)(params[0], light, color, ray, normal), + (*params[1]->diffuse_fn)(params[1], light, color, ray, normal) ); - } else if (params[0]->finish_fn) { - return (*params[0]->finish_fn)(params[0], light, color, ray, - normal, viewer); - } else if (params[1]->finish_fn) { - return (*params[1]->finish_fn)(params[1], light, color, ray, - normal, viewer); + } else if (params[0]->diffuse_fn) { + return (*params[0]->diffuse_fn)(params[0], light, color, ray, normal); + } else if (params[1]->diffuse_fn) { + return (*params[1]->diffuse_fn)(params[1], light, color, ray, normal); + } else { + return dmnsn_black; + } +} + +static dmnsn_color +dmnsn_finish_combination_specular_fn(const dmnsn_finish *finish, + dmnsn_color light, dmnsn_color color, + dmnsn_vector ray, dmnsn_vector normal, + dmnsn_vector viewer) +{ + dmnsn_finish **params = finish->ptr; + if (params[0]->specular_fn && params[1]->specular_fn) { + return dmnsn_color_add( + (*params[0]->specular_fn)(params[0], light, color, ray, normal, viewer), + (*params[1]->specular_fn)(params[1], light, color, ray, normal, viewer) + ); + } else if (params[0]->specular_fn) { + return (*params[0]->specular_fn)(params[0], light, color, ray, + normal, viewer); + } else if (params[1]->specular_fn) { + return (*params[1]->specular_fn)(params[1], light, color, ray, + normal, viewer); } else { return dmnsn_black; } @@ -112,10 +132,13 @@ dmnsn_new_finish_combination(dmnsn_finish *f1, dmnsn_finish *f2) params[0] = f1; params[1] = f2; - finish->ptr = params; + finish->ptr = params; + + if (f1->diffuse_fn || f2->diffuse_fn) + finish->diffuse_fn = &dmnsn_finish_combination_diffuse_fn; - if (f1->finish_fn || f2->finish_fn) - finish->finish_fn = &dmnsn_finish_combination_fn; + if (f1->specular_fn || f2->specular_fn) + finish->specular_fn = &dmnsn_finish_combination_specular_fn; if (f1->ambient_fn || f2->ambient_fn) finish->ambient_fn = &dmnsn_finish_combination_ambient_fn; diff --git a/libdimension/phong.c b/libdimension/phong.c index 637ff52..7ed6356 100644 --- a/libdimension/phong.c +++ b/libdimension/phong.c @@ -27,10 +27,10 @@ */ static dmnsn_color -dmnsn_phong_finish_fn(const dmnsn_finish *finish, - dmnsn_color light, dmnsn_color color, - dmnsn_vector ray, dmnsn_vector normal, - dmnsn_vector viewer) +dmnsn_phong_specular_fn(const dmnsn_finish *finish, + dmnsn_color light, dmnsn_color color, + dmnsn_vector ray, dmnsn_vector normal, + dmnsn_vector viewer) { double *params = finish->ptr; @@ -64,9 +64,9 @@ dmnsn_new_phong_finish(double specular, double exp) params[0] = specular; params[1] = exp; - finish->ptr = params; - finish->finish_fn = &dmnsn_phong_finish_fn; - finish->free_fn = &free; + finish->ptr = params; + finish->specular_fn = &dmnsn_phong_specular_fn; + finish->free_fn = &free; } return finish; } diff --git a/libdimension/raytrace.c b/libdimension/raytrace.c index 9cfb904..0165870 100644 --- a/libdimension/raytrace.c +++ b/libdimension/raytrace.c @@ -413,7 +413,7 @@ dmnsn_raytrace_lighting(const dmnsn_raytrace_state *state) dmnsn_color light_color; if (dmnsn_raytrace_light_ray(state, light, &light_color)) { if (state->scene->quality & DMNSN_RENDER_FINISH - && finish && finish->finish_fn) + && finish && (finish->diffuse_fn || finish->specular_fn)) { dmnsn_vector ray = dmnsn_vector_normalize( dmnsn_vector_sub(light->x0, x0) @@ -424,10 +424,19 @@ dmnsn_raytrace_lighting(const dmnsn_raytrace_state *state) ); /* Get this light's color contribution to the object */ - dmnsn_color contrib = (*finish->finish_fn)(finish, - light_color, state->pigment, - ray, normal, viewer); - illum = dmnsn_color_add(contrib, illum); + if (finish->diffuse_fn) { + dmnsn_color diffuse = (*finish->diffuse_fn)(finish, light_color, + state->pigment, + ray, normal); + illum = dmnsn_color_add(diffuse, illum); + } + + if (finish->specular_fn) { + dmnsn_color specular = (*finish->specular_fn)(finish, light_color, + state->pigment, + ray, normal, viewer); + illum = dmnsn_color_add(specular, illum); + } } else { illum = state->pigment; } diff --git a/libdimension/texture.c b/libdimension/texture.c index 5878a02..d303132 100644 --- a/libdimension/texture.c +++ b/libdimension/texture.c @@ -50,7 +50,8 @@ dmnsn_new_finish() { dmnsn_finish *finish = malloc(sizeof(dmnsn_finish)); if (finish) { - finish->finish_fn = NULL; + finish->diffuse_fn = NULL; + finish->specular_fn = NULL; finish->ambient_fn = NULL; finish->reflection_fn = NULL; finish->free_fn = NULL; |