summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@gmail.com>2010-01-13 15:32:01 -0500
committerTavian Barnes <tavianator@gmail.com>2010-01-13 15:32:01 -0500
commitc552664a8371a55f2e082507998f78228308672c (patch)
tree93464a9820630ec2e63a2e53b8f7fab6ff6b28cd
parent6787a9219748575cd63aaadd483f49a4fd83b543 (diff)
downloaddimension-c552664a8371a55f2e082507998f78228308672c.tar.xz
Split finish_fn into diffuse_fn and specular_fn.
-rw-r--r--libdimension/diffuse.c9
-rw-r--r--libdimension/dimension/texture.h16
-rw-r--r--libdimension/finish_combination.c55
-rw-r--r--libdimension/phong.c14
-rw-r--r--libdimension/raytrace.c19
-rw-r--r--libdimension/texture.c3
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;