Add solid textures
This commit is contained in:
parent
9b0abbc5bb
commit
20a77499bc
2
arena.c
2
arena.c
@ -1,6 +1,7 @@
|
|||||||
#include "arena.h"
|
#include "arena.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -46,6 +47,7 @@ void *arena_alloc_align(Arena *arena, size_t size, size_t alignment) {
|
|||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "Arena is out of memory");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
11
hittable.c
11
hittable.c
@ -191,6 +191,13 @@ bool hittable_list_bounding_box(const HittableList *list, double time_start,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void get_sphere_uv(Point3 p, double *u, double *v) {
|
||||||
|
double theta = acos(-p.x);
|
||||||
|
double phi = atan2(-p.z, p.x) + M_PI;
|
||||||
|
*u = phi / (2 * M_PI);
|
||||||
|
*v = theta / M_PI;
|
||||||
|
}
|
||||||
|
|
||||||
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);
|
||||||
@ -214,6 +221,8 @@ bool sphere_hit(const Sphere *sphere, Ray r, double t_min, double t_max,
|
|||||||
Vec3 outward_normal =
|
Vec3 outward_normal =
|
||||||
vec3_div(point3_sub(record->p, sphere->center), sphere->radius);
|
vec3_div(point3_sub(record->p, sphere->center), sphere->radius);
|
||||||
hit_record_set_face_normal(record, r, outward_normal);
|
hit_record_set_face_normal(record, r, outward_normal);
|
||||||
|
get_sphere_uv((Point3){outward_normal.x, outward_normal.y, outward_normal.z},
|
||||||
|
&record->u, &record->v);
|
||||||
record->material = sphere->material;
|
record->material = sphere->material;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -270,6 +279,8 @@ bool moving_sphere_hit(const MovingSphere *sphere, Ray r, double t_min,
|
|||||||
vec3_div(point3_sub(record->p, moving_sphere_center(sphere, r.time)),
|
vec3_div(point3_sub(record->p, moving_sphere_center(sphere, r.time)),
|
||||||
sphere->radius);
|
sphere->radius);
|
||||||
hit_record_set_face_normal(record, r, outward_normal);
|
hit_record_set_face_normal(record, r, outward_normal);
|
||||||
|
get_sphere_uv((Point3){outward_normal.x, outward_normal.y, outward_normal.z},
|
||||||
|
&record->u, &record->v);
|
||||||
record->material = sphere->material;
|
record->material = sphere->material;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,6 +15,7 @@ typedef struct HitRecord {
|
|||||||
const Material *material;
|
const Material *material;
|
||||||
Point3 p;
|
Point3 p;
|
||||||
Vec3 normal;
|
Vec3 normal;
|
||||||
|
double u, v;
|
||||||
double t;
|
double t;
|
||||||
bool front_face;
|
bool front_face;
|
||||||
} HitRecord;
|
} HitRecord;
|
||||||
|
|||||||
90
main.c
90
main.c
@ -11,9 +11,15 @@
|
|||||||
#include "material.h"
|
#include "material.h"
|
||||||
#include "point3.h"
|
#include "point3.h"
|
||||||
#include "ray.h"
|
#include "ray.h"
|
||||||
|
#include "texture.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "vec3.h"
|
#include "vec3.h"
|
||||||
|
|
||||||
|
#define SCENE_RANDOM 0
|
||||||
|
#define SCENE_TWO_SPHERES 1
|
||||||
|
|
||||||
|
#define SCENE_SELECT SCENE_TWO_SPHERES
|
||||||
|
|
||||||
static Color ray_color(Ray r, const Hittable *world, int depth) {
|
static Color ray_color(Ray r, const Hittable *world, int depth) {
|
||||||
if (depth <= 0)
|
if (depth <= 0)
|
||||||
return (Color){0, 0, 0};
|
return (Color){0, 0, 0};
|
||||||
@ -37,10 +43,11 @@ 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) {
|
||||||
Hittable *world = hittable_create_hittable_list(arena);
|
Hittable *world = hittable_create_hittable_list(arena);
|
||||||
|
|
||||||
const Material *ground_material =
|
const Texture *checker = texture_create_checker_solid_color(
|
||||||
material_create_lambertian((Color){0.5, 0.5, 0.5}, arena);
|
(Color){0.2, 0.3, 0.1}, (Color){0.9, 0.9, 0.9}, 10.0, arena);
|
||||||
const Hittable *ground_sphere = hittable_create_sphere((Point3){0.0, -1000.0, 0.0},
|
const Material *ground_material = material_create_lambertian(checker, arena);
|
||||||
1000.0, ground_material, arena);
|
const Hittable *ground_sphere = hittable_create_sphere(
|
||||||
|
(Point3){0.0, -1000.0, 0.0}, 1000.0, ground_material, arena);
|
||||||
hittable_list_add(&world->list, ground_sphere, arena);
|
hittable_list_add(&world->list, ground_sphere, arena);
|
||||||
|
|
||||||
const Material *glass = material_create_dielectric(1.5, arena);
|
const Material *glass = material_create_dielectric(1.5, arena);
|
||||||
@ -53,21 +60,21 @@ 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) {
|
||||||
const Material *material = material_create_lambertian(
|
const Material *material = material_create_lambertian_color(
|
||||||
color_mul(color_random(), color_random()), arena);
|
color_mul(color_random(), color_random()), arena);
|
||||||
Point3 center2 = point3_add(
|
const Hittable *sphere =
|
||||||
center, (Vec3){0, random_double_in_range(0.0, 0.5), 0});
|
hittable_create_sphere(center, 0.2, material, arena);
|
||||||
const Hittable *sphere = hittable_create_moving_sphere(
|
|
||||||
center, center2, 0.0, 1.0, 0.2, material, arena);
|
|
||||||
hittable_list_add(&world->list, sphere, arena);
|
hittable_list_add(&world->list, sphere, arena);
|
||||||
} else if (choose_material < 0.95) {
|
} else if (choose_material < 0.95) {
|
||||||
const Material *material =
|
const Material *material = material_create_metal_color(
|
||||||
material_create_metal(color_random_in_range(0.5, 1),
|
color_random_in_range(0.5, 1), random_double_in_range(0.5, 1.0),
|
||||||
random_double_in_range(0.5, 1.0), arena);
|
arena);
|
||||||
const Hittable *sphere = hittable_create_sphere(center, 0.2, material, arena);
|
const Hittable *sphere =
|
||||||
|
hittable_create_sphere(center, 0.2, material, arena);
|
||||||
hittable_list_add(&world->list, sphere, arena);
|
hittable_list_add(&world->list, sphere, arena);
|
||||||
} else {
|
} else {
|
||||||
const Hittable *sphere = hittable_create_sphere(center, 0.2, glass, arena);
|
const Hittable *sphere =
|
||||||
|
hittable_create_sphere(center, 0.2, glass, arena);
|
||||||
hittable_list_add(&world->list, sphere, arena);
|
hittable_list_add(&world->list, sphere, arena);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,9 +82,9 @@ static const Hittable *generate_random_scene(Arena *arena) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const Material *lambertian =
|
const Material *lambertian =
|
||||||
material_create_lambertian((Color){0.4, 0.2, 0.1}, arena);
|
material_create_lambertian_color((Color){0.4, 0.2, 0.1}, arena);
|
||||||
const Material *metal =
|
const Material *metal =
|
||||||
material_create_metal((Color){0.7, 0.6, 0.5}, 0.0, arena);
|
material_create_metal_color((Color){0.7, 0.6, 0.5}, 0.0, arena);
|
||||||
|
|
||||||
const Hittable *sphere1 =
|
const Hittable *sphere1 =
|
||||||
hittable_create_sphere((Point3){0.0, 1.0, 0.0}, 1.0, glass, arena);
|
hittable_create_sphere((Point3){0.0, 1.0, 0.0}, 1.0, glass, arena);
|
||||||
@ -89,11 +96,30 @@ static const Hittable *generate_random_scene(Arena *arena) {
|
|||||||
hittable_create_sphere((Point3){4.0, 1.0, 0.0}, 1.0, metal, arena);
|
hittable_create_sphere((Point3){4.0, 1.0, 0.0}, 1.0, metal, arena);
|
||||||
hittable_list_add(&world->list, sphere3, arena);
|
hittable_list_add(&world->list, sphere3, arena);
|
||||||
|
|
||||||
Hittable *bvh_root = hittable_create_bvh_node(world->list.objects, 0, world->list.size,
|
Hittable *bvh_root = hittable_create_bvh_node(
|
||||||
0.0, 1.0, arena);
|
world->list.objects, 0, world->list.size, 0.0, 1.0, arena);
|
||||||
return bvh_root;
|
return bvh_root;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Hittable *two_spheres(Arena *arena) {
|
||||||
|
Hittable *world = hittable_create_hittable_list(arena);
|
||||||
|
|
||||||
|
Texture *checker = texture_create_checker_solid_color(
|
||||||
|
(Color){0.2, 0.3, 0.1}, (Color){0.9, 0.9, 0.9}, 10.0, arena);
|
||||||
|
hittable_list_add(
|
||||||
|
&world->list,
|
||||||
|
hittable_create_sphere((Point3){0.0, -10.0, 0.0}, 10.0,
|
||||||
|
material_create_lambertian(checker, arena), arena),
|
||||||
|
arena);
|
||||||
|
hittable_list_add(
|
||||||
|
&world->list,
|
||||||
|
hittable_create_sphere((Point3){0.0, 10.0, 0.0}, 10.0,
|
||||||
|
material_create_lambertian(checker, arena), arena),
|
||||||
|
arena);
|
||||||
|
|
||||||
|
return world;
|
||||||
|
}
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
srand(42);
|
srand(42);
|
||||||
|
|
||||||
@ -116,18 +142,31 @@ int main(void) {
|
|||||||
|
|
||||||
/* World */
|
/* World */
|
||||||
|
|
||||||
const Hittable *world = generate_random_scene(&arena);
|
|
||||||
|
|
||||||
/* Camera */
|
|
||||||
|
|
||||||
Point3 look_from = {13.0, 2.0, 3.0};
|
Point3 look_from = {13.0, 2.0, 3.0};
|
||||||
Point3 look_at = {0.0, 0.0, 0.0};
|
Point3 look_at = {0.0, 0.0, 0.0};
|
||||||
Vec3 up = {0.0, 1.0, 0.0};
|
double vfov = 40.0;
|
||||||
|
double aperture = 0.0;
|
||||||
double dist_to_focus = 10.0;
|
double dist_to_focus = 10.0;
|
||||||
double aperture = 0.1;
|
|
||||||
|
const Hittable *world = 0;
|
||||||
|
|
||||||
|
#if SCENE_SELECT == SCENE_RANDOM
|
||||||
|
world = generate_random_scene(&arena);
|
||||||
|
look_from = (Point3){13.0, 2.0, 3.0};
|
||||||
|
look_at = (Point3){0.0, 0.0, 0.0};
|
||||||
|
vfov = 20.0;
|
||||||
|
aperture = 0.1;
|
||||||
|
#elif SCENE_SELECT == SCENE_TWO_SPHERES
|
||||||
|
world = two_spheres(&arena);
|
||||||
|
look_from = (Point3){13.0, 2.0, 3.0};
|
||||||
|
look_at = (Point3){0.0, 0.0, 0.0};
|
||||||
|
vfov = 20.0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Vec3 up = {0.0, 1.0, 0.0};
|
||||||
|
|
||||||
Camera camera;
|
Camera camera;
|
||||||
camera_init(&camera, look_from, look_at, up, 20, aspect_ratio, aperture,
|
camera_init(&camera, look_from, look_at, up, vfov, aspect_ratio, aperture,
|
||||||
dist_to_focus, 0.0, 1.0);
|
dist_to_focus, 0.0, 1.0);
|
||||||
|
|
||||||
printf("P3\n%u %u\n255\n", image_width, image_height);
|
printf("P3\n%u %u\n255\n", image_width, image_height);
|
||||||
@ -161,5 +200,6 @@ int main(void) {
|
|||||||
#include "material.c"
|
#include "material.c"
|
||||||
#include "point3.c"
|
#include "point3.c"
|
||||||
#include "ray.c"
|
#include "ray.c"
|
||||||
|
#include "texture.c"
|
||||||
#include "utils.c"
|
#include "utils.c"
|
||||||
#include "vec3.c"
|
#include "vec3.c"
|
||||||
|
|||||||
21
material.c
21
material.c
@ -23,13 +23,18 @@ bool material_scatter(const Material *material, Ray r,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Material *material_create_lambertian(Color albedo, Arena *arena) {
|
Material *material_create_lambertian(const Texture *albedo, Arena *arena) {
|
||||||
Material *result = arena_alloc(arena, sizeof(Material));
|
Material *result = arena_alloc(arena, sizeof(Material));
|
||||||
result->type = MATERIAL_LAMBERTIAN;
|
result->type = MATERIAL_LAMBERTIAN;
|
||||||
result->lambertian.albedo = albedo;
|
result->lambertian.albedo = albedo;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Material *material_create_lambertian_color(Color albedo, Arena *arena) {
|
||||||
|
return material_create_lambertian(texture_create_solid_color(albedo, arena),
|
||||||
|
arena);
|
||||||
|
}
|
||||||
|
|
||||||
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) {
|
||||||
@ -41,11 +46,13 @@ bool lambertian_scatter(const Lambertian *lambertian, Ray r,
|
|||||||
scatter_direction = record->normal;
|
scatter_direction = record->normal;
|
||||||
|
|
||||||
*scattered = (Ray){record->p, scatter_direction, r.time};
|
*scattered = (Ray){record->p, scatter_direction, r.time};
|
||||||
*attenuation = lambertian->albedo;
|
*attenuation =
|
||||||
|
texture_value(lambertian->albedo, record->u, record->v, record->p);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Material *material_create_metal(Color albedo, double fuzziness, Arena *arena) {
|
Material *material_create_metal(const Texture *albedo, double fuzziness,
|
||||||
|
Arena *arena) {
|
||||||
Material *result = arena_alloc(arena, sizeof(Material));
|
Material *result = arena_alloc(arena, sizeof(Material));
|
||||||
result->type = MATERIAL_METAL;
|
result->type = MATERIAL_METAL;
|
||||||
result->metal.albedo = albedo;
|
result->metal.albedo = albedo;
|
||||||
@ -53,6 +60,12 @@ Material *material_create_metal(Color albedo, double fuzziness, Arena *arena) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Material *material_create_metal_color(Color albedo, double fuzziness,
|
||||||
|
Arena *arena) {
|
||||||
|
return material_create_metal(texture_create_solid_color(albedo, arena),
|
||||||
|
fuzziness, 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) {
|
||||||
Vec3 reflected = vec3_reflect(vec3_normalize(r.direction), record->normal);
|
Vec3 reflected = vec3_reflect(vec3_normalize(r.direction), record->normal);
|
||||||
@ -63,7 +76,7 @@ bool metal_scatter(const Metal *metal, Ray r, const struct HitRecord *record,
|
|||||||
vec3_mul(metal->fuzziness, vec3_random_in_unit_sphere())),
|
vec3_mul(metal->fuzziness, vec3_random_in_unit_sphere())),
|
||||||
r.time,
|
r.time,
|
||||||
};
|
};
|
||||||
*attenuation = metal->albedo;
|
*attenuation = texture_value(metal->albedo, record->u, record->v, record->p);
|
||||||
return vec3_dot(scattered->direction, record->normal) > 0;
|
return vec3_dot(scattered->direction, record->normal) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
14
material.h
14
material.h
@ -2,8 +2,8 @@
|
|||||||
#define INCLUDED_MATERIAL_H
|
#define INCLUDED_MATERIAL_H
|
||||||
|
|
||||||
#include "arena.h"
|
#include "arena.h"
|
||||||
#include "color.h"
|
|
||||||
#include "ray.h"
|
#include "ray.h"
|
||||||
|
#include "texture.h"
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
@ -16,11 +16,11 @@ typedef enum MaterialType {
|
|||||||
} MaterialType;
|
} MaterialType;
|
||||||
|
|
||||||
typedef struct Lambertian {
|
typedef struct Lambertian {
|
||||||
Color albedo;
|
const Texture *albedo;
|
||||||
} Lambertian;
|
} Lambertian;
|
||||||
|
|
||||||
typedef struct Metal {
|
typedef struct Metal {
|
||||||
Color albedo;
|
const Texture *albedo;
|
||||||
double fuzziness;
|
double fuzziness;
|
||||||
} Metal;
|
} Metal;
|
||||||
|
|
||||||
@ -41,12 +41,16 @@ bool material_scatter(const Material *material, Ray r,
|
|||||||
const struct HitRecord *record, Color *attenuation,
|
const struct HitRecord *record, Color *attenuation,
|
||||||
Ray *scattered);
|
Ray *scattered);
|
||||||
|
|
||||||
Material *material_create_lambertian(Color albedo, Arena *arena);
|
Material *material_create_lambertian(const Texture *albedo, Arena *arena);
|
||||||
|
Material *material_create_lambertian_color(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);
|
||||||
|
|
||||||
Material *material_create_metal(Color albedo, double fuzziness, Arena *arena);
|
Material *material_create_metal(const Texture *albedo, double fuzziness,
|
||||||
|
Arena *arena);
|
||||||
|
Material *material_create_metal_color(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);
|
||||||
|
|
||||||
|
|||||||
53
texture.c
Normal file
53
texture.c
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
#include "texture.h"
|
||||||
|
#include "arena.h"
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
Texture *texture_create_solid_color(Color value, Arena *arena) {
|
||||||
|
Texture *result = arena_alloc(arena, sizeof(Texture));
|
||||||
|
result->type = TEXTURE_SOLID_COLOR;
|
||||||
|
result->solid_color.value = value;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Texture *texture_create_checker(const Texture *odd, const Texture *even,
|
||||||
|
double size, Arena *arena) {
|
||||||
|
Texture *result = arena_alloc(arena, sizeof(Texture));
|
||||||
|
result->type = TEXTURE_CHECKER;
|
||||||
|
result->checker.odd = odd;
|
||||||
|
result->checker.even = even;
|
||||||
|
result->checker.size = size;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Texture *texture_create_checker_solid_color(Color odd, Color even, double size,
|
||||||
|
Arena *arena) {
|
||||||
|
Texture *odd_texture = texture_create_solid_color(odd, arena);
|
||||||
|
Texture *even_texture = texture_create_solid_color(even, arena);
|
||||||
|
return texture_create_checker(odd_texture, even_texture, size, arena);
|
||||||
|
}
|
||||||
|
|
||||||
|
Color texture_value(const Texture *texture, double u, double v, Point3 p) {
|
||||||
|
switch (texture->type) {
|
||||||
|
case TEXTURE_SOLID_COLOR:
|
||||||
|
return solid_color_value(&texture->solid_color, u, v, p);
|
||||||
|
case TEXTURE_CHECKER:
|
||||||
|
return checker_value(&texture->checker, u, v, p);
|
||||||
|
}
|
||||||
|
return (Color){0.0, 0.0, 0.0};
|
||||||
|
}
|
||||||
|
|
||||||
|
Color solid_color_value(const SolidColor *solid_color, double u, double v,
|
||||||
|
Point3 p) {
|
||||||
|
(void)u, (void)v, (void)p;
|
||||||
|
return solid_color->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
Color checker_value(const CheckerTexture *checker, double u, double v,
|
||||||
|
Point3 p) {
|
||||||
|
double sines = sin(checker->size * p.x) * sin(checker->size * p.y) *
|
||||||
|
sin(checker->size * p.z);
|
||||||
|
if (sines < 0.0)
|
||||||
|
return texture_value(checker->odd, u, v, p);
|
||||||
|
return texture_value(checker->even, u, v, p);
|
||||||
|
}
|
||||||
47
texture.h
Normal file
47
texture.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#ifndef INCLUDED_TEXTURE_H
|
||||||
|
#define INCLUDED_TEXTURE_H
|
||||||
|
|
||||||
|
#include "arena.h"
|
||||||
|
#include "color.h"
|
||||||
|
#include "point3.h"
|
||||||
|
|
||||||
|
typedef enum TextureType {
|
||||||
|
TEXTURE_SOLID_COLOR,
|
||||||
|
TEXTURE_CHECKER,
|
||||||
|
} TextureType;
|
||||||
|
|
||||||
|
typedef struct Texture Texture;
|
||||||
|
|
||||||
|
typedef struct SolidColor {
|
||||||
|
Color value;
|
||||||
|
} SolidColor;
|
||||||
|
|
||||||
|
typedef struct CheckerTexture {
|
||||||
|
const Texture *odd;
|
||||||
|
const Texture *even;
|
||||||
|
double size;
|
||||||
|
} CheckerTexture;
|
||||||
|
|
||||||
|
struct Texture {
|
||||||
|
TextureType type;
|
||||||
|
union {
|
||||||
|
SolidColor solid_color;
|
||||||
|
CheckerTexture checker;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
Texture *texture_create_solid_color(Color value, Arena *arena);
|
||||||
|
Texture *texture_create_checker(const Texture *odd, const Texture *even,
|
||||||
|
double size, Arena *arena);
|
||||||
|
Texture *texture_create_checker_solid_color(Color odd, Color even, double size,
|
||||||
|
Arena *arena);
|
||||||
|
|
||||||
|
Color texture_value(const Texture *texture, double u, double v, Point3 p);
|
||||||
|
|
||||||
|
Color solid_color_value(const SolidColor *solid_color, double u, double v,
|
||||||
|
Point3 p);
|
||||||
|
|
||||||
|
Color checker_value(const CheckerTexture *checker, double u, double v,
|
||||||
|
Point3 p);
|
||||||
|
|
||||||
|
#endif /* INCLUDED_TEXTURE_H */
|
||||||
Loading…
x
Reference in New Issue
Block a user