Cleanup the API
This commit is contained in:
parent
67cf29b684
commit
2abc2ba697
11
hittable.c
11
hittable.c
@ -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);
|
||||
|
||||
@ -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
83
main.c
@ -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 */
|
||||
|
||||
23
material.c
23
material.c
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user