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 "arena.h"
#include "point3.h"
#include "vec3.h"
@ -60,6 +61,16 @@ bool hittable_list_hit(const HittableList *list, Ray r, double t_min,
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,
HitRecord *record) {
Vec3 oc = point3_sub(r.origin, sphere->center);

View File

@ -51,6 +51,8 @@ typedef struct Sphere {
double radius;
} 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,
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 HittableList world = {.type = HITTABLE_LIST};
static Lambertian ground_material = {.type = MATERIAL_LAMBERTIAN,
.albedo = (Color){0.5, 0.5, 0.5}};
Sphere *ground_sphere = arena_alloc(arena, sizeof(Sphere));
ground_sphere->type = HITTABLE_SPHERE;
ground_sphere->center = (Point3){0.0, -1000.0, 0.0};
ground_sphere->radius = 1000.0;
ground_sphere->material = (const Material *)&ground_material;
const Lambertian *ground_material =
lambertian_create((Color){0.5, 0.5, 0.5}, arena);
const Sphere *ground_sphere =
sphere_create((Point3){0.0, -1000.0, 0.0}, 1000.0,
(const Material *)ground_material, arena);
hittable_list_add(&world, (const Hittable *)ground_sphere, arena);
static Lambertian lambertian = {.type = MATERIAL_LAMBERTIAN,
.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};
const Dielectric *glass = dielectric_create(1.5, arena);
for (int a = -11; a < 11; ++a) {
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 (choose_material < 0.8) {
Color albedo = color_mul(color_random(), color_random());
Lambertian *material = arena_alloc(arena, sizeof(Lambertian));
material->type = MATERIAL_LAMBERTIAN;
material->albedo = albedo;
Sphere *sphere = arena_alloc(arena, sizeof(Sphere));
sphere->type = HITTABLE_SPHERE;
sphere->center = center;
sphere->radius = 0.2;
sphere->material = (const Material *)material;
const Lambertian *material = lambertian_create(
color_mul(color_random(), color_random()), arena);
const Sphere *sphere =
sphere_create(center, 0.2, (const Material *)material, arena);
hittable_list_add(&world, (const Hittable *)sphere, arena);
} else if (choose_material < 0.95) {
Color albedo = color_random_in_range(0.5, 1);
double fuzziness = random_double_in_range(0.5, 1.0);
Metal *material = arena_alloc(arena, sizeof(Metal));
material->type = MATERIAL_METAL;
material->albedo = albedo;
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;
const Metal *material =
metal_create(color_random_in_range(0.5, 1),
random_double_in_range(0.5, 1.0), arena);
const Sphere *sphere =
sphere_create(center, 0.2, (const Material *)material, arena);
hittable_list_add(&world, (const Hittable *)sphere, arena);
} else {
Sphere *sphere = arena_alloc(arena, sizeof(Sphere));
sphere->type = HITTABLE_SPHERE;
sphere->center = center;
sphere->radius = 0.2;
sphere->material = (const Material *)&glass;
const Sphere *sphere =
sphere_create(center, 0.2, (const Material *)glass, arena);
hittable_list_add(&world, (const Hittable *)sphere, arena);
}
}
}
}
Sphere *sphere1 = arena_alloc(arena, sizeof(Sphere));
sphere1->type = HITTABLE_SPHERE;
sphere1->center = (Point3){0.0, 1.0, 0.0};
sphere1->radius = 1.0;
sphere1->material = (const Material *)&glass;
const Lambertian *lambertian =
lambertian_create((Color){0.4, 0.2, 0.1}, arena);
const Metal *metal = metal_create((Color){0.7, 0.6, 0.5}, 0.0, arena);
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);
Sphere *sphere2 = arena_alloc(arena, sizeof(Sphere));
sphere2->type = HITTABLE_SPHERE;
sphere2->center = (Point3){-4.0, 1.0, 0.0};
sphere2->radius = 1.0;
sphere2->material = (const Material *)&lambertian;
const Sphere *sphere2 = sphere_create((Point3){-4.0, 1.0, 0.0}, 1.0,
(const Material *)lambertian, arena);
hittable_list_add(&world, (const Hittable *)sphere2, arena);
Sphere *sphere3 = arena_alloc(arena, sizeof(Sphere));
sphere3->type = HITTABLE_SPHERE;
sphere3->center = (Point3){4.0, 1.0, 0.0};
sphere3->radius = 1.0;
sphere3->material = (const Material *)&metal;
const Sphere *sphere3 = sphere_create((Point3){4.0, 1.0, 0.0}, 1.0,
(const Material *)metal, arena);
hittable_list_add(&world, (const Hittable *)sphere3, arena);
return (const Hittable *)&world;
@ -134,7 +107,7 @@ int main(void) {
const double aspect_ratio = 3.0 / 2.0;
const int image_width = 1200;
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;
/* World */

View File

@ -1,4 +1,5 @@
#include "material.h"
#include "arena.h"
#include "hittable.h"
#include "utils.h"
#include "vec3.h"
@ -23,6 +24,13 @@ bool material_scatter(const Material *material, Ray r,
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,
const HitRecord *record, Color *attenuation,
Ray *scattered) {
@ -38,6 +46,14 @@ bool lambertian_scatter(const Lambertian *lambertian, Ray r,
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,
Color *attenuation, Ray *scattered) {
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;
}
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) {
double r0 = (1 - eta) / (1 + eta);
r0 *= r0;

View File

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