aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian T <julian@jtle.dk>2020-03-23 16:55:45 +0100
committerJulian T <julian@jtle.dk>2020-03-23 16:55:45 +0100
commit83b552b622da561de047f798e5d50d59f724b1eb (patch)
tree5255a785b05aba1f4894062c8576bec15d6d3411
parent8fc5b36510c5964873d88069b61b558bc3ef23f6 (diff)
No dynamic allocation
-rw-r--r--main.c38
-rw-r--r--pgm.c16
-rw-r--r--ray.c21
-rw-r--r--scene.c37
-rw-r--r--scene.h19
-rw-r--r--test.pngbin693556 -> 693556 bytes
-rw-r--r--vector.c7
-rw-r--r--vector.h3
8 files changed, 57 insertions, 84 deletions
diff --git a/main.c b/main.c
index 0e529ad..c27096c 100644
--- a/main.c
+++ b/main.c
@@ -72,15 +72,35 @@ int main()
viewpoint_init(&s->view);
- // Setup plane
- 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(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));
+ object_t *o = add_object(cont, TYPE_SPHERE);
+ vector_set(&o->sph.center, 0, 4, 7);
+ o->sph.radius = 5;
+ o->m = m2;
+
+ o = add_object(cont, TYPE_SPHERE);
+ vector_set(&o->sph.center, 8, 8, 4);
+ o->sph.radius = 2;
+ o->m = m3;
+
+ o = add_object(cont, TYPE_SPHERE);
+ vector_set(&o->sph.center, -10, 9, 5);
+ o->sph.radius = 3;
+ o->m = m;
+
+ o = add_object(cont, TYPE_SPHERE);
+ vector_set(&o->sph.center, -10, -5, 5);
+ o->sph.radius = 3;
+ o->m = m;
+
+ o = add_object(cont, TYPE_PLANE);
+ vector_set(&o->pl.start, 0, 0, 2);
+ vector_set(&o->pl.norm, 0, 0, 1);
+ o->m = mpl;
+
+ light_t *l = add_light(cont);
+ vector_set(&l->pos, 20, 10, 30);
+ color_set(&l->defuse, 0.3, 0.3, 0.3);
+ color_set(&l->specular, 0.5, 0.5, 0.5);
pgm_write_header(stdout, TESTW, TESTH);
diff --git a/pgm.c b/pgm.c
index b3f233f..eb0c101 100644
--- a/pgm.c
+++ b/pgm.c
@@ -17,10 +17,6 @@ int pgm_write_pixel(FILE *fp, color_t *c)
color_t *color_set(color_t *c, COORD_T r, COORD_T g, COORD_T b)
{
- if (!c) {
- c = (color_t *) malloc(sizeof(color_t));
- }
-
c->r = r;
c->g = g;
c->b = b;
@@ -30,10 +26,6 @@ color_t *color_set(color_t *c, COORD_T r, COORD_T g, COORD_T b)
color_t *color_add(color_t *dest, color_t *a, color_t *b)
{
- if (!dest) {
- dest = (color_t *) malloc(sizeof(color_t));
- }
-
COORD_T tmp = a->r + b->r;
dest->r = tmp > 1 ? 1 : tmp;
@@ -48,10 +40,6 @@ color_t *color_add(color_t *dest, color_t *a, color_t *b)
color_t *color_scale(color_t *dest, color_t *a, COORD_T b)
{
- if (!dest) {
- dest = (color_t *) malloc(sizeof(color_t));
- }
-
COORD_T tmp = a->r * b;
dest->r = tmp > 1 ? 1 : tmp;
@@ -66,10 +54,6 @@ color_t *color_scale(color_t *dest, color_t *a, COORD_T b)
color_t *color_scale_vector(color_t *dest, color_t *a, vector_t *v)
{
- if (!dest) {
- dest = (color_t *) malloc(sizeof(color_t));
- }
-
dest->r = a->r * v->x;
dest->g = a->g * v->y;
dest->b = a->b * v->z;
diff --git a/ray.c b/ray.c
index 7c86483..a41866c 100644
--- a/ray.c
+++ b/ray.c
@@ -14,7 +14,7 @@ COORD_T ray_intersect_sphere(sphere_t *s, ray_t *ray, bool skip_dist)
{
// Vector between vector start and center of circle
vector_t oc;
- vector_sub(&oc, ray->start, s->center);
+ vector_sub(&oc, ray->start, &s->center);
// Solve quadratic function
// TODO Not sure if this step i neccesary because dir is unit
@@ -62,7 +62,7 @@ COORD_T ray_intersect_sphere(sphere_t *s, ray_t *ray, bool skip_dist)
COORD_T ray_intersect_plane(plane_t *p, ray_t *ray, bool skip_dist)
{
// If zero ray is parralel to plane
- COORD_T nr = vector_dot(p->norm, ray->direction);
+ COORD_T nr = vector_dot(&p->norm, ray->direction);
// Take care of rounding errors
if (nr < ZERO_APROX && nr > -ZERO_APROX) {
@@ -74,10 +74,10 @@ COORD_T ray_intersect_plane(plane_t *p, ray_t *ray, bool skip_dist)
// Calculate distance
vector_t tmp;
- vector_copy(&tmp, p->start);
+ vector_copy(&tmp, &p->start);
vector_sub(&tmp, &tmp, ray->start);
- COORD_T t = vector_dot(&tmp, p->norm) / nr;
+ COORD_T t = vector_dot(&tmp, &p->norm) / nr;
return t;
}
@@ -149,7 +149,7 @@ static void direct_light(space_t *s, color_t *dest, object_t *o, vector_t *N, ve
vector_t l;
// Calculate distance to light
- vector_sub(&l, light->pos, point);
+ vector_sub(&l, &light->pos, point);
COORD_T d = vector_len(&l);
// Normalice
@@ -167,7 +167,7 @@ static void direct_light(space_t *s, color_t *dest, object_t *o, vector_t *N, ve
color_t tmp;
COORD_T cl = vector_dot(&l, N);
if (cl > 0) {
- color_scale(&tmp, light->defuse, cl * o->m->defuse);
+ color_scale(&tmp, &light->defuse, cl * o->m->defuse);
color_add(dest, &tmp, dest);
}
@@ -181,7 +181,7 @@ static void direct_light(space_t *s, color_t *dest, object_t *o, vector_t *N, ve
cl = 1 * vector_dot(&R, &V);
if (cl > 0) {
cl = pow(cl, o->m->shine);
- color_scale(&tmp, light->specular, cl * o->m->specular);
+ color_scale(&tmp, &light->specular, cl * o->m->specular);
color_add(dest, &tmp, dest);
}
@@ -317,7 +317,9 @@ void ray_trace(space_t *s, unsigned int x, unsigned int y, unsigned samples, col
// Setup primary ray
ray_t r;
r.start = &s->view.position;
- r.direction = vector_copy(NULL, NULL);
+
+ vector_t dir;
+ r.direction = vector_set(&dir, 0, 0, 0);
// Multiple samples for antialias
// TODO better distribution of antialias probes
@@ -337,9 +339,6 @@ void ray_trace(space_t *s, unsigned int x, unsigned int y, unsigned samples, col
c->r += ctmp.r; c->g += ctmp.g; c->b += ctmp.b;
}
- //printf("COlor before devide %f, %f, %f\n", c->r, c->g, c->b);
-
- free(r.direction);
// Take the median
if (samples > 1) {
diff --git a/scene.c b/scene.c
index 331cd30..6221fe8 100644
--- a/scene.c
+++ b/scene.c
@@ -73,7 +73,7 @@ static inline light_t *container_lig_space(container_t *cont)
))[cont->lig_index++];
}
-object_t *add_sphere(container_t *cont, vector_t *c, COORD_T r, material_t *m)
+object_t *add_object(container_t *cont, unsigned type)
{
object_t *o = container_obj_space(cont);
@@ -82,11 +82,7 @@ object_t *add_sphere(container_t *cont, vector_t *c, COORD_T r, material_t *m)
}
// Fill out the data
- o->type = TYPE_SPHERE;
- o->m = m;
-
- o->sph.center = c;
- o->sph.radius = r;
+ o->type = type;
// Link to the linked list
link_object(&cont->space, o);
@@ -94,36 +90,13 @@ object_t *add_sphere(container_t *cont, vector_t *c, COORD_T r, material_t *m)
return o;
}
-object_t *add_plane(container_t *cont, vector_t *start, vector_t *dir, material_t *m)
-{
-
- object_t *o = container_obj_space(cont);
- if (!o) {
- return NULL;
- }
-
- o->type = TYPE_PLANE;
- o->m = m;
-
- o->pl.start = start;
- o->pl.norm = dir;
-
- link_object(&cont->space, o);
-
- return o;
-}
-
-light_t *add_light(container_t *cont, vector_t *pos, color_t *defuse, color_t *specular)
+light_t *add_light(container_t *cont)
{
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;
@@ -147,11 +120,11 @@ void obj_norm_at(object_t *o, vector_t *dest, vector_t *point)
{
switch(o->type) {
case TYPE_SPHERE:
- vector_sub(dest, point, o->sph.center);
+ vector_sub(dest, point, &o->sph.center);
vector_scale_inv(dest, dest, vector_len(dest));
break;
case TYPE_PLANE:
- vector_copy(dest, o->pl.norm);
+ vector_copy(dest, &o->pl.norm);
break;
}
diff --git a/scene.h b/scene.h
index cc55941..b311ccc 100644
--- a/scene.h
+++ b/scene.h
@@ -14,19 +14,19 @@
#define CONTAINER_SIZE(objs, mats, ligs) (sizeof(container_t) + objs * sizeof(object_t) + ligs * sizeof(light_t))
typedef struct {
- vector_t *center;
+ vector_t center;
COORD_T radius;
} sphere_t;
typedef struct {
- vector_t *start;
- vector_t *norm;
+ vector_t start;
+ vector_t norm;
} plane_t;
typedef struct light_s{
- vector_t *pos;
- color_t *defuse;
- color_t *specular;
+ vector_t pos;
+ color_t defuse;
+ color_t specular;
struct light_s *next;
} light_t;
@@ -45,7 +45,7 @@ typedef struct {
// General object structure
typedef struct object_s{
- uint8_t type;
+ unsigned type;
struct object_s *next;
// Color and light information
@@ -101,9 +101,8 @@ container_t *container_init(container_t *c, unsigned objs, unsigned mats, unsign
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);
+object_t *add_object(container_t *cont, unsigned type);
+light_t *add_light(container_t *cont);
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 ae894ba..78b7f9f 100644
--- a/test.png
+++ b/test.png
Binary files differ
diff --git a/vector.c b/vector.c
index 87eba37..0bcd1dc 100644
--- a/vector.c
+++ b/vector.c
@@ -4,14 +4,13 @@
#include <string.h>
#include <math.h>
#include <stdio.h>
+#include <assert.h>
static inline vector_t *vector_exists(vector_t *v)
{
- if (v) {
- return v;
- }
+ assert(v);
- return (vector_t *) malloc(sizeof(vector_t));
+ return v;
}
// Overwrites stuff in p. If p is null a new vector is created
diff --git a/vector.h b/vector.h
index e794f05..81b5df1 100644
--- a/vector.h
+++ b/vector.h
@@ -11,10 +11,9 @@ typedef struct {
} vector_t;
// Set vector to specified coordinates
-// If p is NULL it is created
vector_t *vector_set(vector_t *p, COORD_T x, COORD_T y, COORD_T z);
-// Copy vector src. If dest is NULL a vector is allocated
+// Copy vector src
vector_t *vector_copy(vector_t *dest, vector_t *src);
// Calculate the length of v