Simplify the Hittable API

We need to disable strict aliasing, but it is weird anyways:
https://blog.regehr.org/archives/1307
This commit is contained in:
Jean-Michel Gorius 2022-11-11 11:27:00 +01:00
parent e397ee9ad9
commit f6278ce63e
4 changed files with 31 additions and 37 deletions

View File

@ -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"}

View File

@ -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);

View File

@ -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);

24
main.c
View File

@ -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){
HittableList world = {.type = HITTABLE_LIST};
Sphere sphere1 = {
.type = HITTABLE_SPHERE,
.center = (Point3){0, 0, -1},
.radius = 0.5,
}));
hittable_list_add(&object_list, make_hittable_sphere(&(Sphere){
};
Sphere sphere2 = {
.type = HITTABLE_SPHERE,
.center = (Point3){0, -100.5, -1},
.radius = 100,
}));
Hittable world = make_hittable_list(&object_list);
};
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;
}