diff options
-rw-r--r-- | main.c | 38 | ||||
-rw-r--r-- | pgm.c | 16 | ||||
-rw-r--r-- | ray.c | 21 | ||||
-rw-r--r-- | scene.c | 37 | ||||
-rw-r--r-- | scene.h | 19 | ||||
-rw-r--r-- | test.png | bin | 693556 -> 693556 bytes | |||
-rw-r--r-- | vector.c | 7 | ||||
-rw-r--r-- | vector.h | 3 |
8 files changed, 57 insertions, 84 deletions
@@ -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); @@ -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; @@ -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) { @@ -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; } @@ -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); Binary files differ@@ -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 @@ -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 |