summaryrefslogtreecommitdiffstats
path: root/libdimension/finish.c
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@gmail.com>2011-06-12 02:37:51 -0600
committerTavian Barnes <tavianator@gmail.com>2011-06-13 00:16:06 -0600
commit7acd8ea6673b7a90ed4041408ccf1b024b8a007a (patch)
treed52199dd7c58e0217bfd1a74e7601d739ad333f5 /libdimension/finish.c
parent066261810c2fca192677c5c1c01c91d6ecec65a0 (diff)
downloaddimension-7acd8ea6673b7a90ed4041408ccf1b024b8a007a.tar.xz
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.
Diffstat (limited to 'libdimension/finish.c')
-rw-r--r--libdimension/finish.c130
1 files changed, 115 insertions, 15 deletions
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);
}
}