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 "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);
|
||||||
|
|||||||
@ -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
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 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 */
|
||||||
|
|||||||
23
material.c
23
material.c
@ -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;
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user