diff options
Diffstat (limited to 'scene.c')
-rw-r--r-- | scene.c | 99 |
1 files changed, 91 insertions, 8 deletions
@@ -1,6 +1,7 @@ #include "scene.h" #include <stdlib.h> +#include <string.h> static inline void link_object(space_t *s, object_t *o) { @@ -12,24 +13,94 @@ static inline void link_object(space_t *s, object_t *o) } } -object_t *add_sphere(space_t *s, vector_t *c, COORD_T r, material_t *m) +container_t *container_init(container_t *c, unsigned objs, unsigned mats, unsigned ligs) { - object_t *o = (object_t *) malloc(sizeof(object_t)); + c->obj_index = c->mat_index = c->lig_index = 0; + c->obj_cap = objs; + c->mat_cap = mats; + c->lig_cap = ligs; + + return c; +} + +space_t *container_prepare_space(container_t *c) +{ + memset(&c->space, 0, sizeof(space_t)); +} + +// Finds the next empty object_t space +// Return NULL if full +static inline object_t *container_obj_space(container_t *cont) +{ + if (cont->obj_index >= cont->obj_cap) { + fprintf(stderr, "Could not create object, because container is full\n"); + return NULL; + } + + // Find a nice spot in the content blob + return &((object_t *) cont->content)[cont->obj_index++]; +} + +static inline material_t *container_mat_space(container_t *cont) +{ + if (cont->mat_index >= cont->mat_cap) { + fprintf(stderr, "Could not create material, because container is full\n"); + return NULL; + } + + // Find a nice spot in the content blob. + // Remember to jump over objects + return &((material_t *) ( + cont->content + + sizeof(object_t) * cont->obj_cap + ))[cont->mat_index++]; +} + +static inline light_t *container_lig_space(container_t *cont) +{ + if (cont->lig_index >= cont->lig_cap) { + fprintf(stderr, "Could not create light, because container is full\n"); + return NULL; + } + + // Find a nice spot in the content blob. + // Remember to jump over objects and materials + return &((light_t *) ( + cont->content + + sizeof(object_t) * cont->obj_cap + + sizeof(material_t) * cont->mat_cap + ))[cont->lig_index++]; +} + +object_t *add_sphere(container_t *cont, vector_t *c, COORD_T r, material_t *m) +{ + + object_t *o = container_obj_space(cont); + if (!o) { + return NULL; + } + + // Fill out the data o->type = TYPE_SPHERE; o->m = m; o->sph.center = c; o->sph.radius = r; - link_object(s, o); + // Link to the linked list + link_object(&cont->space, o); return o; } -object_t *add_plane(space_t *s, vector_t *start, vector_t *dir, material_t *m) +object_t *add_plane(container_t *cont, vector_t *start, vector_t *dir, material_t *m) { - object_t *o = (object_t *) malloc(sizeof(object_t)); + + object_t *o = container_obj_space(cont); + if (!o) { + return NULL; + } o->type = TYPE_PLANE; o->m = m; @@ -37,19 +108,23 @@ object_t *add_plane(space_t *s, vector_t *start, vector_t *dir, material_t *m) o->pl.start = start; o->pl.norm = dir; - link_object(s, o); + link_object(&cont->space, o); return o; } -light_t *add_light(space_t *s, vector_t *pos, color_t *defuse, color_t *specular) +light_t *add_light(container_t *cont, vector_t *pos, color_t *defuse, color_t *specular) { - light_t *o = (light_t *) malloc(sizeof(light_t)); + light_t *o = container_lig_space(cont); + if (!o) { + return NULL; + } o->pos = pos; o->defuse = defuse; o->specular = specular; + space_t *s = &cont->space; if (s) { o->next = s->lights; s->lights = o; @@ -60,6 +135,14 @@ light_t *add_light(space_t *s, vector_t *pos, color_t *defuse, color_t *specular return o; } +// It's alot easier to set the stuff outside of this function +material_t *add_material(container_t *cont) +{ + material_t *m = container_mat_space(cont); + + return m; +} + void obj_norm_at(object_t *o, vector_t *dest, vector_t *point) { switch(o->type) { |