Cleanup the API

This commit is contained in:
Jean-Michel Gorius 2022-11-12 16:17:42 +01:00
parent 67cf29b684
commit 2abc2ba697
5 changed files with 68 additions and 55 deletions

View File

@ -1,4 +1,5 @@
#include "hittable.h" #include "hittable.h"
#include "arena.h"
#include "point3.h" #include "point3.h"
#include "vec3.h" #include "vec3.h"
@ -60,6 +61,16 @@ bool hittable_list_hit(const HittableList *list, Ray r, double t_min,
return hit_anything; return hit_anything;
} }
Sphere *sphere_create(Point3 center, double radius, const Material *material,
Arena *arena) {
Sphere *sphere = arena_alloc(arena, sizeof(Sphere));
sphere->type = HITTABLE_SPHERE;
sphere->center = center;
sphere->radius = radius;
sphere->material = material;
return sphere;
}
bool sphere_hit(const Sphere *sphere, Ray r, double t_min, double t_max, bool sphere_hit(const Sphere *sphere, Ray r, double t_min, double t_max,
HitRecord *record) { HitRecord *record) {
Vec3 oc = point3_sub(r.origin, sphere->center); Vec3 oc = point3_sub(r.origin, sphere->center);

View File

@ -51,6 +51,8 @@ typedef struct Sphere {
double radius; double radius;
} Sphere; } Sphere;
Sphere *sphere_create(Point3 center, double radius, const Material *material,
Arena *arena);
bool sphere_hit(const Sphere *sphere, Ray r, double t_min, double t_max, bool sphere_hit(const Sphere *sphere, Ray r, double t_min, double t_max,
HitRecord *record); HitRecord *record);

83
main.c
View File

@ -37,20 +37,14 @@ static Color ray_color(Ray r, const Hittable *world, int depth) {
static const Hittable *generate_random_scene(Arena *arena) { static const Hittable *generate_random_scene(Arena *arena) {
static HittableList world = {.type = HITTABLE_LIST}; static HittableList world = {.type = HITTABLE_LIST};
static Lambertian ground_material = {.type = MATERIAL_LAMBERTIAN, const Lambertian *ground_material =
.albedo = (Color){0.5, 0.5, 0.5}}; lambertian_create((Color){0.5, 0.5, 0.5}, arena);
Sphere *ground_sphere = arena_alloc(arena, sizeof(Sphere)); const Sphere *ground_sphere =
ground_sphere->type = HITTABLE_SPHERE; sphere_create((Point3){0.0, -1000.0, 0.0}, 1000.0,
ground_sphere->center = (Point3){0.0, -1000.0, 0.0}; (const Material *)ground_material, arena);
ground_sphere->radius = 1000.0;
ground_sphere->material = (const Material *)&ground_material;
hittable_list_add(&world, (const Hittable *)ground_sphere, arena); hittable_list_add(&world, (const Hittable *)ground_sphere, arena);
static Lambertian lambertian = {.type = MATERIAL_LAMBERTIAN, const Dielectric *glass = dielectric_create(1.5, arena);
.albedo = {0.4, 0.2, 0.1}};
static Metal metal = {
.type = MATERIAL_METAL, .albedo = {0.7, 0.6, 0.5}, .fuzziness = 0.0};
static Dielectric glass = {.type = MATERIAL_DIELECTRIC, .eta = 1.5};
for (int a = -11; a < 11; ++a) { for (int a = -11; a < 11; ++a) {
for (int b = -11; b < 11; ++b) { for (int b = -11; b < 11; ++b) {
@ -60,60 +54,39 @@ static const Hittable *generate_random_scene(Arena *arena) {
if (vec3_length(point3_sub(center, (Point3){4.0, 0.2, 0.0})) > 0.9) { if (vec3_length(point3_sub(center, (Point3){4.0, 0.2, 0.0})) > 0.9) {
if (choose_material < 0.8) { if (choose_material < 0.8) {
Color albedo = color_mul(color_random(), color_random()); const Lambertian *material = lambertian_create(
Lambertian *material = arena_alloc(arena, sizeof(Lambertian)); color_mul(color_random(), color_random()), arena);
material->type = MATERIAL_LAMBERTIAN; const Sphere *sphere =
material->albedo = albedo; sphere_create(center, 0.2, (const Material *)material, arena);
Sphere *sphere = arena_alloc(arena, sizeof(Sphere));
sphere->type = HITTABLE_SPHERE;
sphere->center = center;
sphere->radius = 0.2;
sphere->material = (const Material *)material;
hittable_list_add(&world, (const Hittable *)sphere, arena); hittable_list_add(&world, (const Hittable *)sphere, arena);
} else if (choose_material < 0.95) { } else if (choose_material < 0.95) {
Color albedo = color_random_in_range(0.5, 1); const Metal *material =
double fuzziness = random_double_in_range(0.5, 1.0); metal_create(color_random_in_range(0.5, 1),
Metal *material = arena_alloc(arena, sizeof(Metal)); random_double_in_range(0.5, 1.0), arena);
material->type = MATERIAL_METAL; const Sphere *sphere =
material->albedo = albedo; sphere_create(center, 0.2, (const Material *)material, arena);
material->fuzziness = fuzziness;
Sphere *sphere = arena_alloc(arena, sizeof(Sphere));
sphere->type = HITTABLE_SPHERE;
sphere->center = center;
sphere->radius = 0.2;
sphere->material = (const Material *)material;
hittable_list_add(&world, (const Hittable *)sphere, arena); hittable_list_add(&world, (const Hittable *)sphere, arena);
} else { } else {
Sphere *sphere = arena_alloc(arena, sizeof(Sphere)); const Sphere *sphere =
sphere->type = HITTABLE_SPHERE; sphere_create(center, 0.2, (const Material *)glass, arena);
sphere->center = center;
sphere->radius = 0.2;
sphere->material = (const Material *)&glass;
hittable_list_add(&world, (const Hittable *)sphere, arena); hittable_list_add(&world, (const Hittable *)sphere, arena);
} }
} }
} }
} }
Sphere *sphere1 = arena_alloc(arena, sizeof(Sphere)); const Lambertian *lambertian =
sphere1->type = HITTABLE_SPHERE; lambertian_create((Color){0.4, 0.2, 0.1}, arena);
sphere1->center = (Point3){0.0, 1.0, 0.0}; const Metal *metal = metal_create((Color){0.7, 0.6, 0.5}, 0.0, arena);
sphere1->radius = 1.0;
sphere1->material = (const Material *)&glass; const Sphere *sphere1 = sphere_create((Point3){0.0, 1.0, 0.0}, 1.0,
(const Material *)glass, arena);
hittable_list_add(&world, (const Hittable *)sphere1, arena); hittable_list_add(&world, (const Hittable *)sphere1, arena);
Sphere *sphere2 = arena_alloc(arena, sizeof(Sphere)); const Sphere *sphere2 = sphere_create((Point3){-4.0, 1.0, 0.0}, 1.0,
sphere2->type = HITTABLE_SPHERE; (const Material *)lambertian, arena);
sphere2->center = (Point3){-4.0, 1.0, 0.0};
sphere2->radius = 1.0;
sphere2->material = (const Material *)&lambertian;
hittable_list_add(&world, (const Hittable *)sphere2, arena); hittable_list_add(&world, (const Hittable *)sphere2, arena);
Sphere *sphere3 = arena_alloc(arena, sizeof(Sphere)); const Sphere *sphere3 = sphere_create((Point3){4.0, 1.0, 0.0}, 1.0,
sphere3->type = HITTABLE_SPHERE; (const Material *)metal, arena);
sphere3->center = (Point3){4.0, 1.0, 0.0};
sphere3->radius = 1.0;
sphere3->material = (const Material *)&metal;
hittable_list_add(&world, (const Hittable *)sphere3, arena); hittable_list_add(&world, (const Hittable *)sphere3, arena);
return (const Hittable *)&world; return (const Hittable *)&world;
@ -134,7 +107,7 @@ int main(void) {
const double aspect_ratio = 3.0 / 2.0; const double aspect_ratio = 3.0 / 2.0;
const int image_width = 1200; const int image_width = 1200;
const int image_height = (int)(image_width / aspect_ratio); const int image_height = (int)(image_width / aspect_ratio);
const int samples_per_pixel = 500; const int samples_per_pixel = 2;
const int max_depth = 50; const int max_depth = 50;
/* World */ /* World */

View File

@ -1,4 +1,5 @@
#include "material.h" #include "material.h"
#include "arena.h"
#include "hittable.h" #include "hittable.h"
#include "utils.h" #include "utils.h"
#include "vec3.h" #include "vec3.h"
@ -23,6 +24,13 @@ bool material_scatter(const Material *material, Ray r,
return false; return false;
} }
Lambertian *lambertian_create(Color albedo, Arena *arena) {
Lambertian *lambertian = arena_alloc(arena, sizeof(Lambertian));
lambertian->type = MATERIAL_LAMBERTIAN;
lambertian->albedo = albedo;
return lambertian;
}
bool lambertian_scatter(const Lambertian *lambertian, Ray r, bool lambertian_scatter(const Lambertian *lambertian, Ray r,
const HitRecord *record, Color *attenuation, const HitRecord *record, Color *attenuation,
Ray *scattered) { Ray *scattered) {
@ -38,6 +46,14 @@ bool lambertian_scatter(const Lambertian *lambertian, Ray r,
return true; return true;
} }
Metal *metal_create(Color albedo, double fuzziness, Arena *arena) {
Metal *metal = arena_alloc(arena, sizeof(Metal));
metal->type = MATERIAL_METAL;
metal->albedo = albedo;
metal->fuzziness = fuzziness;
return metal;
}
bool metal_scatter(const Metal *metal, Ray r, const struct HitRecord *record, bool metal_scatter(const Metal *metal, Ray r, const struct HitRecord *record,
Color *attenuation, Ray *scattered) { Color *attenuation, Ray *scattered) {
Vec3 reflected = vec3_reflect(vec3_normalize(r.direction), record->normal); Vec3 reflected = vec3_reflect(vec3_normalize(r.direction), record->normal);
@ -51,6 +67,13 @@ bool metal_scatter(const Metal *metal, Ray r, const struct HitRecord *record,
return vec3_dot(scattered->direction, record->normal) > 0; return vec3_dot(scattered->direction, record->normal) > 0;
} }
Dielectric *dielectric_create(double eta, Arena *arena) {
Dielectric *dielectric = arena_alloc(arena, sizeof(Dielectric));
dielectric->type = MATERIAL_DIELECTRIC;
dielectric->eta = eta;
return dielectric;
}
static double schlick_reflectance(double cosine, double eta) { static double schlick_reflectance(double cosine, double eta) {
double r0 = (1 - eta) / (1 + eta); double r0 = (1 - eta) / (1 + eta);
r0 *= r0; r0 *= r0;

View File

@ -1,6 +1,7 @@
#ifndef INCLUDED_MATERIAL_H #ifndef INCLUDED_MATERIAL_H
#define INCLUDED_MATERIAL_H #define INCLUDED_MATERIAL_H
#include "arena.h"
#include "color.h" #include "color.h"
#include "ray.h" #include "ray.h"
@ -27,6 +28,7 @@ typedef struct Lambertian {
Color albedo; Color albedo;
} Lambertian; } Lambertian;
Lambertian *lambertian_create(Color albedo, Arena *arena);
bool lambertian_scatter(const Lambertian *lambertian, Ray r, bool lambertian_scatter(const Lambertian *lambertian, Ray r,
const struct HitRecord *record, Color *attenuation, const struct HitRecord *record, Color *attenuation,
Ray *scattered); Ray *scattered);
@ -37,6 +39,7 @@ typedef struct Metal {
double fuzziness; double fuzziness;
} Metal; } Metal;
Metal *metal_create(Color albedo, double fuzziness, Arena *arena);
bool metal_scatter(const Metal *metal, Ray r, const struct HitRecord *record, bool metal_scatter(const Metal *metal, Ray r, const struct HitRecord *record,
Color *attenuation, Ray *scattered); Color *attenuation, Ray *scattered);
@ -45,6 +48,7 @@ typedef struct Dielectric {
double eta; double eta;
} Dielectric; } Dielectric;
Dielectric *dielectric_create(double eta, Arena *arena);
bool dielectric_scatter(const Dielectric *dielectric, Ray r, bool dielectric_scatter(const Dielectric *dielectric, Ray r,
const struct HitRecord *record, Color *attenuation, const struct HitRecord *record, Color *attenuation,
Ray *scattered); Ray *scattered);