diff --git a/build.sh b/build.sh index 0b2e497..9b7ac8d 100755 --- a/build.sh +++ b/build.sh @@ -1,7 +1,7 @@ #!/bin/bash CC=${CC:-"gcc"} -CFLAGS=${CFLAGS:-"-Wall -Wextra -std=gnu18 -g -fsanitize=address"} +CFLAGS=${CFLAGS:-"-Wall -Wextra -std=gnu18 -fno-strict-aliasing -g"} LDFLAGS=${LDFLAGS:-"-lm"} MAIN_FILE=${MAIN_FILE:-"main.c"} diff --git a/hittable.c b/hittable.c index d5d9cdf..014256d 100644 --- a/hittable.c +++ b/hittable.c @@ -15,25 +15,22 @@ bool hittable_hit(const Hittable *hittable, Ray r, double t_min, double t_max, HitRecord *record) { switch (hittable->type) { case HITTABLE_LIST: - return hittable_list_hit(hittable->data, r, t_min, t_max, record); + return hittable_list_hit((const HittableList *)hittable, r, t_min, t_max, + record); case HITTABLE_SPHERE: - return sphere_hit(hittable->data, r, t_min, t_max, record); + return sphere_hit((const Sphere *)hittable, r, t_min, t_max, record); } return false; } -Hittable make_hittable_list(const HittableList *list) { - return (Hittable){.type = HITTABLE_LIST, .data = list}; -} - static void hittable_list_grow(HittableList *list, size_t n) { if (list->objects) { - list->objects = realloc(list->objects, n); + list->objects = realloc(list->objects, n * sizeof(Hittable *)); if (!list->objects) abort(); list->capacity = n; } else { - list->objects = malloc(n * sizeof(Hittable)); + list->objects = malloc(n * sizeof(Hittable *)); if (!list->objects) abort(); list->capacity = n; @@ -41,7 +38,7 @@ static void hittable_list_grow(HittableList *list, size_t n) { } } -void hittable_list_add(HittableList *list, Hittable hittable) { +void hittable_list_add(HittableList *list, const Hittable *hittable) { if (list->capacity == list->size) hittable_list_grow(list, list->capacity == 0 ? 16 : list->capacity); list->objects[list->size++] = hittable; @@ -53,7 +50,7 @@ bool hittable_list_hit(const HittableList *list, Ray r, double t_min, double closest_so_far = t_max; for (size_t i = 0; i < list->size; ++i) { - if (hittable_hit(&list->objects[i], r, t_min, closest_so_far, record)) { + if (hittable_hit(list->objects[i], r, t_min, closest_so_far, record)) { hit_anything = true; closest_so_far = record->t; } @@ -67,10 +64,6 @@ void hittable_list_free(HittableList *list) { list->objects = 0; } -Hittable make_hittable_sphere(const Sphere *sphere) { - return (Hittable){.type = HITTABLE_SPHERE, sphere}; -} - bool sphere_hit(const Sphere *sphere, Ray r, double t_min, double t_max, HitRecord *record) { Vec3 oc = point3_sub(r.origin, sphere->center); diff --git a/hittable.h b/hittable.h index cbced23..7ada7e6 100644 --- a/hittable.h +++ b/hittable.h @@ -24,32 +24,29 @@ typedef enum HittableType { typedef struct Hittable { HittableType type; - const void *data; } Hittable; bool hittable_hit(const Hittable *hittable, Ray r, double t_min, double t_max, HitRecord *record); typedef struct HittableList { - Hittable *objects; + HittableType type; + const Hittable **objects; size_t size; size_t capacity; } HittableList; -Hittable make_hittable_list(const HittableList *list); - -void hittable_list_add(HittableList *list, Hittable hittable); +void hittable_list_add(HittableList *list, const Hittable *hittable); bool hittable_list_hit(const HittableList *list, Ray r, double t_min, double t_max, HitRecord *record); - void hittable_list_free(HittableList *list); +void hittable_list_free(HittableList *list); typedef struct Sphere { + HittableType type; Point3 center; double radius; } Sphere; -Hittable make_hittable_sphere(const Sphere *sphere); - bool sphere_hit(const Sphere *sphere, Ray r, double t_min, double t_max, HitRecord *record); diff --git a/main.c b/main.c index d78b555..90f1b6e 100644 --- a/main.c +++ b/main.c @@ -11,12 +11,12 @@ #include "utils.h" #include "vec3.h" -Color ray_color(Ray r, Hittable world, int depth) { +Color ray_color(Ray r, const Hittable *world, int depth) { if (depth <= 0) return (Color){0, 0, 0}; HitRecord record; - if (hittable_hit(&world, r, 0.001, DBL_MAX, &record)) { + if (hittable_hit(world, r, 0.001, DBL_MAX, &record)) { Point3 target = point3_add( record.p, vec3_add(record.normal, vec3_random_unit_vector())); return color_mul(0.5, @@ -39,16 +39,19 @@ int main(void) { const int max_depth = 50; /* World */ - HittableList object_list = {0}; - hittable_list_add(&object_list, make_hittable_sphere(&(Sphere){ - .center = (Point3){0, 0, -1}, - .radius = 0.5, - })); - hittable_list_add(&object_list, make_hittable_sphere(&(Sphere){ - .center = (Point3){0, -100.5, -1}, - .radius = 100, - })); - Hittable world = make_hittable_list(&object_list); + HittableList world = {.type = HITTABLE_LIST}; + Sphere sphere1 = { + .type = HITTABLE_SPHERE, + .center = (Point3){0, 0, -1}, + .radius = 0.5, + }; + Sphere sphere2 = { + .type = HITTABLE_SPHERE, + .center = (Point3){0, -100.5, -1}, + .radius = 100, + }; + hittable_list_add(&world, (const Hittable *)&sphere1); + hittable_list_add(&world, (const Hittable *)&sphere2); /* Camera */ Camera camera; @@ -64,7 +67,8 @@ int main(void) { double u = (i + random_double()) / (image_width - 1); double v = (j + random_double()) / (image_height - 1); Ray r = camera_get_ray(&camera, u, v); - pixel_color = color_add(pixel_color, ray_color(r, world, max_depth)); + pixel_color = color_add( + pixel_color, ray_color(r, (const Hittable *)&world, max_depth)); } color_write(stdout, pixel_color, samples_per_pixel); } @@ -72,7 +76,7 @@ int main(void) { fprintf(stderr, "\nDone.\n"); - hittable_list_free(&object_list); + hittable_list_free(&world); return 0; }