diff --git a/color.c b/color.c index 60d97bc..a52b93a 100644 --- a/color.c +++ b/color.c @@ -1,6 +1,14 @@ #include "color.h" #include +color color_lerp(color c1, color c2, double t) { + return (color){ + (1.0 - t) * c1.r + t * c2.r, + (1.0 - t) * c1.g + t * c2.g, + (1.0 - t) * c1.b + t * c2.b, + }; +} + void color_write(FILE *out, color c) { fprintf(out, "%d %d %d\n", (int)(255.999 * c.r), (int)(255.999 * c.g), (int)(255.999 * c.b)); diff --git a/color.h b/color.h index 15a4199..55b47b6 100644 --- a/color.h +++ b/color.h @@ -7,6 +7,8 @@ typedef struct color { double r, g, b; } color; +color color_lerp(color c1, color c2, double t); + void color_write(FILE *out, color c); #endif /* INCLUDED_COLOR_H */ diff --git a/main.c b/main.c index ee8553e..5c74511 100644 --- a/main.c +++ b/main.c @@ -1,21 +1,49 @@ #include #include "color.h" +#include "point3.h" +#include "ray.h" +#include "vec3.h" + +color ray_color(ray r) { + vec3 unit_direction = vec3_normalize(r.direction); + double t = 0.5 * (unit_direction.y + 1.0); + color gradient1 = {1.0, 1.0, 1.0}; + color gradient2 = {0.5, 0.7, 1.0}; + return color_lerp(gradient1, gradient2, t); +} int main(void) { + /* Image parameters */ + const double aspect_ratio = 16.0 / 9.0; const int image_width = 256; - const int image_height = 256; + const int image_height = (int)(image_width / aspect_ratio); + + /* Camera parameters */ + double viewport_height = 2; + double viewport_width = aspect_ratio * viewport_height; + double focal_length = 1.0; + + point3 origin = {0}; + vec3 horizontal = {viewport_width, 0, 0}; + vec3 vertical = {0, viewport_height, 0}; + vec3 offset = vec3_add(vec3_div(horizontal, 2), vec3_div(vertical, 2)); + offset = vec3_add(offset, (vec3){0, 0, focal_length}); + point3 lower_left_corner = point3_add(origin, vec3_neg(offset)); printf("P3\n%u %u\n255\n", image_width, image_height); for (int j = image_height - 1; j >= 0; --j) { fprintf(stderr, "\rScanlines remaining: %d ", j); for (int i = 0; i < image_width; ++i) { - color pixel_color = { - .r = (double)(i) / (image_width - 1), - .g = (double)(j) / (image_height - 1), - .b = 0.25, - }; + double u = (double)i / (image_width - 1); + double v = (double)j / (image_height - 1); + point3 screen_point = + point3_add(lower_left_corner, + vec3_add(vec3_mul(u, horizontal), vec3_mul(v, vertical))); + vec3 direction = point3_sub(screen_point, origin); + ray r = {origin, direction}; + color pixel_color = ray_color(r); color_write(stdout, pixel_color); } } @@ -27,4 +55,5 @@ int main(void) { #include "color.c" #include "point3.c" +#include "ray.c" #include "vec3.c" diff --git a/ray.c b/ray.c new file mode 100644 index 0000000..cb67376 --- /dev/null +++ b/ray.c @@ -0,0 +1,6 @@ +#include "ray.h" +#include "point3.h" + +point3 ray_at(ray r, double t) { + return point3_add(r.origin, vec3_mul(t, r.direction)); +} diff --git a/ray.h b/ray.h new file mode 100644 index 0000000..a905f46 --- /dev/null +++ b/ray.h @@ -0,0 +1,14 @@ +#ifndef INCLUDED_RAY_H +#define INCLUDED_RAY_H + +#include "point3.h" +#include "vec3.h" + +typedef struct ray { + point3 origin; + vec3 direction; +} ray; + +point3 ray_at(ray r, double t); + +#endif /* INCLUDED_RAY_H */