From 7acd8ea6673b7a90ed4041408ccf1b024b8a007a Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Sun, 12 Jun 2011 02:37:51 -0600 Subject: Vast libdimension API and internals improvements. Couldn't really do these while I was trying to be POV-Ray compatible, 'cause they would've broken compatibility. --- libdimension/finish.c | 130 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 115 insertions(+), 15 deletions(-) (limited to 'libdimension/finish.c') diff --git a/libdimension/finish.c b/libdimension/finish.c index e647152..d356676 100644 --- a/libdimension/finish.c +++ b/libdimension/finish.c @@ -25,27 +25,127 @@ #include "dimension.h" -/* Allocate a dummy finish */ -dmnsn_finish * +dmnsn_ambient * +dmnsn_new_ambient(void) +{ + dmnsn_ambient *ambient = dmnsn_malloc(sizeof(dmnsn_ambient)); + ambient->free_fn = NULL; + ambient->ptr = NULL; + ambient->refcount = 1; + return ambient; +} + +void +dmnsn_delete_ambient(dmnsn_ambient *ambient) +{ + if (DMNSN_DECREF(ambient)) { + if (ambient->free_fn) { + ambient->free_fn(ambient->ptr); + } + dmnsn_free(ambient); + } +} + +dmnsn_diffuse * +dmnsn_new_diffuse(void) +{ + dmnsn_diffuse *diffuse = dmnsn_malloc(sizeof(dmnsn_diffuse)); + diffuse->free_fn = NULL; + diffuse->ptr = NULL; + diffuse->refcount = 1; + return diffuse; +} + +void +dmnsn_delete_diffuse(dmnsn_diffuse *diffuse) +{ + if (DMNSN_DECREF(diffuse)) { + if (diffuse->free_fn) { + diffuse->free_fn(diffuse->ptr); + } + dmnsn_free(diffuse); + } +} + +dmnsn_specular * +dmnsn_new_specular(void) +{ + dmnsn_specular *specular = dmnsn_malloc(sizeof(dmnsn_specular)); + specular->free_fn = NULL; + specular->ptr = NULL; + specular->refcount = 1; + return specular; +} + +void +dmnsn_delete_specular(dmnsn_specular *specular) +{ + if (DMNSN_DECREF(specular)) { + if (specular->free_fn) { + specular->free_fn(specular->ptr); + } + dmnsn_free(specular); + } +} + +dmnsn_reflection * +dmnsn_new_reflection(void) +{ + dmnsn_reflection *reflection = dmnsn_malloc(sizeof(dmnsn_reflection)); + reflection->free_fn = NULL; + reflection->ptr = NULL; + reflection->refcount = 1; + return reflection; +} + +void +dmnsn_delete_reflection(dmnsn_reflection *reflection) +{ + if (DMNSN_DECREF(reflection)) { + if (reflection->free_fn) { + reflection->free_fn(reflection->ptr); + } + dmnsn_free(reflection); + } +} + +dmnsn_finish dmnsn_new_finish(void) { - dmnsn_finish *finish = dmnsn_malloc(sizeof(dmnsn_finish)); - finish->diffuse_fn = NULL; - finish->specular_fn = NULL; - finish->ambient_fn = NULL; - finish->reflection_fn = NULL; - finish->free_fn = NULL; + dmnsn_finish finish; + finish.ambient = NULL; + finish.diffuse = NULL; + finish.specular = NULL; + finish.reflection = NULL; return finish; } -/* Free a finish */ void -dmnsn_delete_finish(dmnsn_finish *finish) +dmnsn_delete_finish(dmnsn_finish finish) { - if (finish) { - if (finish->free_fn) { - finish->free_fn(finish->ptr); - } - dmnsn_free(finish); + dmnsn_delete_reflection(finish.reflection); + dmnsn_delete_specular(finish.specular); + dmnsn_delete_diffuse(finish.diffuse); + dmnsn_delete_ambient(finish.ambient); +} + +void +dmnsn_finish_cascade(const dmnsn_finish *default_finish, dmnsn_finish *finish) +{ + if (!finish->ambient) { + finish->ambient = default_finish->ambient; + DMNSN_INCREF(finish->ambient); + } + if (!finish->diffuse) { + finish->diffuse = default_finish->diffuse; + DMNSN_INCREF(finish->diffuse); + } + if (!finish->specular) { + finish->specular = default_finish->specular; + DMNSN_INCREF(finish->specular); + } + if (!finish->reflection) { + finish->reflection = default_finish->reflection; + DMNSN_INCREF(finish->reflection); } } -- cgit v1.2.3