131 lines
4.5 KiB
C
131 lines
4.5 KiB
C
#define CANVAS_MAX 2048
|
|
|
|
#include "tuples.h"
|
|
#include "canvas.h"
|
|
#include "rays.h"
|
|
#include "spheres.h"
|
|
#include "intersections.h"
|
|
#include "transformations.h"
|
|
#include "materials.h"
|
|
#include "world.h"
|
|
#include "camera.h"
|
|
|
|
static struct canvas _canvas;
|
|
|
|
int main()
|
|
{
|
|
struct tuple ray_origin = point(0.0f, 0.0f, -5.0f);
|
|
|
|
float wall_z = 10.0f;
|
|
float wall_size = 7.0f;
|
|
int canvas_pixels = 100;
|
|
float pixel_size = wall_size / (float)canvas_pixels;
|
|
float half = wall_size / 2.0f;
|
|
|
|
struct sphere floor = sphere();
|
|
floor.transform = scaling(10.0f, 0.01f, 10.0f);
|
|
floor.material.color = color(1.0f, 0.9f, 0.9f);
|
|
floor.material.specular = 0.0f;
|
|
|
|
struct sphere left_wall = sphere();
|
|
{
|
|
struct mat4x4 _translation = translation(0.0f, 0.0f, 5.0f);
|
|
struct mat4x4 _rotation_y = rotation_y(-pi / 4.0f);
|
|
struct mat4x4 _rotation_x = rotation_x(pi / 2.0f);
|
|
struct mat4x4 _scaling = scaling(10.0f, 0.05f, 10.0f);
|
|
|
|
struct mat4x4 t0 = mat4x4_mul_m(&_rotation_x, &_scaling);
|
|
struct mat4x4 t1 = mat4x4_mul_m(&_rotation_y, &t0);
|
|
struct mat4x4 t2 = mat4x4_mul_m(&_translation, &t1);
|
|
|
|
left_wall.transform = t2;
|
|
}
|
|
left_wall.material = floor.material;
|
|
|
|
struct sphere right_wall = sphere();
|
|
{
|
|
struct mat4x4 _translation = translation(0.0f, 0.0f, 5.0f);
|
|
struct mat4x4 _rotation_y = rotation_y(pi / 4.0f);
|
|
struct mat4x4 _rotation_x = rotation_x(pi / 2.0f);
|
|
struct mat4x4 _scaling = scaling(10.0f, 0.05f, 10.0f);
|
|
|
|
struct mat4x4 t0 = mat4x4_mul_m(&_rotation_x, &_scaling);
|
|
struct mat4x4 t1 = mat4x4_mul_m(&_rotation_y, &t0);
|
|
struct mat4x4 t2 = mat4x4_mul_m(&_translation, &t1);
|
|
|
|
right_wall.transform = t2;
|
|
}
|
|
right_wall.material = floor.material;
|
|
|
|
struct sphere middle = sphere();
|
|
middle.transform = translation(-0.5f, 1.0f, 0.5f);
|
|
middle.material.color = color((float)0xfc / 255.f , (float)0x6d / 255.f, (float)0x09 / 255.f);
|
|
middle.material.diffuse = 0.7;
|
|
middle.material.specular = 0.3;
|
|
|
|
struct sphere right = sphere();
|
|
struct mat4x4 right_t = translation(1.5f, 0.5f, -0.5f);
|
|
struct mat4x4 right_s = scaling(0.5f, 0.5f, 0.5f);
|
|
right.transform = mat4x4_mul_m(&right_t, &right_s);
|
|
right.material.color = color(0.5f, 1.0f, 0.1f);
|
|
right.material.diffuse = 0.7;
|
|
right.material.specular = 0.3;
|
|
|
|
struct sphere left = sphere();
|
|
struct mat4x4 left_t = translation(-1.5f, 0.33f, -0.75f);
|
|
struct mat4x4 left_s = scaling(0.33f, 0.33f, 0.33f);
|
|
left.transform = mat4x4_mul_m(&left_t, &left_s);
|
|
left.material.color = color((float)0x12 / 255.f, (float)0xc9 / 255.f, (float)0xcc / 255.f);
|
|
left.material.diffuse = 0.7;
|
|
left.material.specular = 0.3;
|
|
|
|
struct tuple light_position = point(-10.0f, 10.0f, -10.0f);
|
|
struct tuple light_color = color(1.0f, 1.0f, 1.0f);
|
|
struct light light = point_light(light_position, light_color);
|
|
|
|
struct world world;
|
|
world.light = light;
|
|
world.object_count = 6;
|
|
world.objects[0] = floor;
|
|
world.objects[1] = left_wall;
|
|
world.objects[2] = right_wall;
|
|
world.objects[3] = middle;
|
|
world.objects[4] = right;
|
|
world.objects[5] = left;
|
|
|
|
struct camera _camera = camera(1600.0f, 800.0f, pi / 3.0f);
|
|
_camera.transform = view_transform(point(0.0f, 1.5f, -5.0f),
|
|
point(0.0f, 1.0f, 0.0f),
|
|
vector(0.0f, 1.0f, 0.0f));
|
|
|
|
struct mat4x4 middle_t = world.objects[3].transform;
|
|
|
|
for (int i = 0; i < 360; i++) {
|
|
|
|
_camera.transform = view_transform(point(5.0f * cosf(pi / 360 * (float)i / 10),
|
|
1.5f,
|
|
-5.0f * sinf(pi / 360 * (float)i / 10)),
|
|
point(0.0f, 1.0f, 0.0f),
|
|
vector(0.0f, 1.0f, 0.0f));
|
|
|
|
struct tuple light_position = point(-10.0f * cosf(pi / 360 * (float)i),
|
|
10.0f,
|
|
-10.0f * sinf(pi / 360 * (float)i));
|
|
world.light.position = light_position;
|
|
|
|
struct mat4x4 middle_s = scaling(1.0f, 0.4f, 1.0f);
|
|
struct mat4x4 middle_rz = rotation_z(tau / 360.f * (float)i);
|
|
struct mat4x4 middle_ry = rotation_y(tau / 360.f * (float)i);
|
|
struct mat4x4 middle_r = mat4x4_mul_m(&middle_rz, &middle_ry);
|
|
struct mat4x4 middle_transform = mat4x4_mul_m(&middle_r, &middle_s);
|
|
world.objects[3].transform = mat4x4_mul_m(&middle_t, &middle_transform);
|
|
|
|
camera_render(&_camera, &world, &_canvas);
|
|
|
|
char s[128];
|
|
snprintf(s, 128, "test%03d.ppm", i);
|
|
printf("%s\n", s);
|
|
canvas_to_ppm(&_canvas, s);
|
|
}
|
|
}
|