aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian T <julian@jtle.dk>2020-03-22 18:44:26 +0100
committerJulian T <julian@jtle.dk>2020-03-22 18:44:26 +0100
commit6ca75e5d27980e082d977ffdb9a93589b55961ce (patch)
treec927280265129459fbcb0ac9b5ab2dd9eccbac42
parent66e3fe20bdd09ef431f612e02ffe0ce9809b5cc2 (diff)
Added container allowing scatic allocation of all the scene data.
This will make porting to arduino alot easier
-rw-r--r--main.c111
-rw-r--r--scene.c99
-rw-r--r--scene.h38
-rw-r--r--test.pngbin467637 -> 696052 bytes
4 files changed, 185 insertions, 63 deletions
diff --git a/main.c b/main.c
index 78117d5..1ea89fa 100644
--- a/main.c
+++ b/main.c
@@ -10,63 +10,70 @@
#define TESTW 1000
#define TESTH 1000
+char container[ CONTAINER_SIZE(5, 4, 1) ];
+
int main()
{
- //printf("Starting\n");
- space_t s;
- s.objects = NULL;
- s.lights = NULL;
- color_set(&s.ambient, 0.09, 0.09, 0.09);
- // Currently havin issues with white background
- // color_set(&s.back, 255, 255, 255);
- color_set(&s.back, 0.8, 0.8, 0.8);
- color_set(&s.env_color, 0.13, 0.13, 0.13);
- s.env_samples = 256;
-
- material_t m;
- vector_set(&m.color, 0.4, 0.4, 1);
- m.defuse = 1;
- m.specular = 0.0;
- m.shine = 80;
- m.reflective = 0.0;
-
- material_t m3;
- vector_set(&m3.color, 1, 0.3, 0.1);
- m3.defuse = 0.95;
- m3.specular = 0.0;
- m3.shine = 80;
- m3.reflective = 0.05;
-
- material_t m2;
- vector_set(&m2.color, 1, 1, 1);
- m2.defuse = 0.0;
- m2.specular = 0.5;
- m2.shine = 80;
- m2.reflective = 1;
-
- material_t mpl;
+
+ container_t *cont = (container_t *) container;
+ container_init(cont, 5, 4, 1);
+
+ // Init space_t
+ space_t *s = container_prepare_space(cont);;
+
+ // Set space options
+ color_set(&s->ambient, 0.09, 0.09, 0.09);
+ color_set(&s->back, 0.8, 0.8, 0.8);
+ color_set(&s->env_color, 0.13, 0.13, 0.13);
+ s->env_samples = 16;
+
+ // Set viewpoint options
+ vector_set(&s->view.position, 0, 16, 6);
+ vector_set(&s->view.target, 0, 0, 6);
+ s->view.width = TESTW;
+ s->view.height = TESTH;
+
+ // Create materials
+ material_t *m = add_material(cont);
+ vector_set(&m->color, 0.4, 0.4, 1);
+ m->defuse = 1;
+ m->specular = 0.0;
+ m->shine = 80;
+ m->reflective = 0.0;
+
+ material_t *m3 = add_material(cont);
+ vector_set(&m3->color, 1, 0.3, 0.1);
+ m3->defuse = 0.95;
+ m3->specular = 0.0;
+ m3->shine = 80;
+ m3->reflective = 0.05;
+
+ material_t *m2 = add_material(cont);
+ vector_set(&m2->color, 1, 1, 1);
+ m2->defuse = 0.0;
+ m2->specular = 0.5;
+ m2->shine = 80;
+ m2->reflective = 1;
+
+ material_t *mpl = add_material(cont);
//vector_set(&mpl.color, 0, 0.396, 0.7019);
- vector_set(&mpl.color, 1, 1, 1);
- mpl.defuse = 1;
- mpl.specular = 0.0;
- mpl.shine = 50;
- mpl.reflective = 0.0;
-
- vector_set(&s.view.position, 0, 16, 6);
- vector_set(&s.view.target, 0, 0, 6);
- s.view.width = TESTW;
- s.view.height = TESTH;
-
- viewpoint_init(&s.view);
+ vector_set(&mpl->color, 1, 1, 1);
+ mpl->defuse = 1;
+ mpl->specular = 0.0;
+ mpl->shine = 50;
+ mpl->reflective = 0.0;
+
+
+ viewpoint_init(&s->view);
// Setup plane
- add_sphere(&s, vector_set(NULL, 0, 4, 7), 5, &m2);
- add_sphere(&s, vector_set(NULL, 8, 8, 4), 2, &m3);
- add_sphere(&s, vector_set(NULL, -10, 9, 5), 3, &m);
- add_sphere(&s, vector_set(NULL, -10, -5, 5), 3, &m);
- add_plane(&s, vector_set(NULL, 0, 0, 2), vector_set(NULL, 0, 0, 1), &mpl);
+ add_sphere(cont, vector_set(NULL, 0, 4, 7), 5, m2);
+ add_sphere(cont, vector_set(NULL, 8, 8, 4), 2, m3);
+ add_sphere(cont, vector_set(NULL, -10, 9, 5), 3, m);
+ add_sphere(cont, vector_set(NULL, -10, -5, 5), 3, m);
+ add_plane(cont, vector_set(NULL, 0, 0, 2), vector_set(NULL, 0, 0, 1), mpl);
//add_plane(&s, vector_set(NULL, 0, -20, 0), vector_set(NULL, 0, 1, 0), &mpl);
- add_light(&s, vector_set(NULL, 20, 10, 30), color_set(NULL, 0.3, 0.3, 0.3), color_set(NULL, 0.5, 0.5, 0.5));
+ add_light(cont, vector_set(NULL, 20, 10, 30), color_set(NULL, 0.3, 0.3, 0.3), color_set(NULL, 0.5, 0.5, 0.5));
//add_light(&s, vector_set(NULL, 0, 10, 20), color_set(NULL, 0.5, 0.5, 0.5), color_set(NULL, 0.5, 0.5, 0.5));
pgm_write_header(stdout, TESTW, TESTH);
@@ -77,7 +84,7 @@ int main()
for (int y = TESTH; y; y--) {
for (int x = TESTW; x; x--) {
- color_t *c = ray_trace(&s, x, y, 2);
+ color_t *c = ray_trace(&cont->space, x, y, 2);
if (c) {
pgm_write_pixel(stdout, c);
diff --git a/scene.c b/scene.c
index 5a41041..331cd30 100644
--- a/scene.c
+++ b/scene.c
@@ -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) {
diff --git a/scene.h b/scene.h
index 062f80f..cc55941 100644
--- a/scene.h
+++ b/scene.h
@@ -11,6 +11,8 @@
#define TYPE_SPHERE 1
#define TYPE_PLANE 2
+#define CONTAINER_SIZE(objs, mats, ligs) (sizeof(container_t) + objs * sizeof(object_t) + ligs * sizeof(light_t))
+
typedef struct {
vector_t *center;
COORD_T radius;
@@ -57,6 +59,7 @@ typedef struct object_s{
typedef struct {
viewpoint_t view;
+
object_t *objects;
light_t *lights;
@@ -70,9 +73,38 @@ typedef struct {
color_t env_color;
} space_t;
-object_t *add_sphere(space_t *s, vector_t *c, COORD_T r, material_t *m);
-object_t *add_plane(space_t *s, vector_t *start, vector_t *dir, material_t *m);
-light_t *add_light(space_t *s, vector_t *pos, color_t *defuse, color_t *specular);
+// Contains materials, space, objects and lights. Made to keep it all together.
+// They will still be linked list, but close together.
+typedef struct {
+ space_t space;
+
+ // Number of objects
+ unsigned obj_index;
+ unsigned mat_index;
+ unsigned lig_index;
+
+ // Number of objects that will fit.
+ unsigned obj_cap;
+ unsigned mat_cap;
+ unsigned lig_cap;
+
+ // Memory blob
+ // Contains objects -> materials -> lights
+ uint8_t content[0];
+} container_t;
+
+
+// Initialice container in buffer c. Should be big enough for the whole scene.
+// Use the container_size to calculate the needed space.
+// Leave c at NULL to allocate container
+container_t *container_init(container_t *c, unsigned objs, unsigned mats, unsigned ligs);
+
+space_t *container_prepare_space(container_t *c);
+
+object_t *add_sphere(container_t *cont, vector_t *c, COORD_T r, material_t *m);
+object_t *add_plane(container_t *cont, vector_t *start, vector_t *dir, material_t *m);
+light_t *add_light(container_t *cont, vector_t *pos, color_t *defuse, color_t *specular);
+material_t *add_material(container_t *cont);
void obj_norm_at(object_t *o, vector_t *dest, vector_t *point);
diff --git a/test.png b/test.png
index ebf847f..70122a6 100644
--- a/test.png
+++ b/test.png
Binary files differ