#include "camera.h" #include "ff.h" #include "obj.h" #include "ray.h" #include "vec3.h" #include #include #include #include #define W 800 #define H 600 #define FOCAL_LEN 1.0 #define VIEWPORT_H 2.0 #define NELEMS(arr) (sizeof(arr) / sizeof(arr[0])) static const vec3_t lightblue = { 0.4, 0.6, 1.0 }; static const vec3_t white = { 1.0, 1.0, 1.0 }; static const vec3_t red = { 1.0, 0.1, 0.2 }; static const vec3_t camera_pos = { 0.0, 0.0, 0.0 }; static const obj_t scene[] = { SPHERE(1.0, 0.0, -3.0, 1.0), SPHERE(-2.0, 0.0, -5.0, 1.0), }; static pix_t pixbuf[W * H]; static vec3_t raycol(ray_t ray) { hit_t hit; for (unsigned i = 0; i < NELEMS(scene); ++i) { if (scene[i].intersect(scene[i].params, ray, &hit)) return vec3_scale(vec3_add(hit.normal, white), 0.5); } const double a = (ray.dir.y + 1.0) / 2.0; return vec3_add(vec3_scale(lightblue, a), vec3_scale(white, 1 - a)); } static void setpix(vec3_t col, pix_t *out) { out->r = UINT16_MAX * col.x; out->g = UINT16_MAX * col.y; out->b = UINT16_MAX * col.z; out->a = UINT16_MAX; } int main() { img_t img = { .w = W, .h = H, .pix = pixbuf }; camera_t camera = camera_init(camera_pos, FOCAL_LEN, VIEWPORT_H, W, H); for (unsigned y = 0; y < H; ++y) { fprintf(stderr, "\r[%3d/%3d]", y, H); fflush(stderr); const vec3_t row = vec3_add(camera.pix_origin, vec3_scale(camera.y_step, y)); for (unsigned x = 0; x < W; ++x) { const vec3_t pix = vec3_add(row, vec3_scale(camera.x_step, x)); const ray_t ray = { .orig = camera.pos, .dir = vec3_unit(pix), }; const vec3_t col = raycol(ray); setpix(col, img.pix + (W * y + x)); } } fprintf(stderr, "\r[%3d/%3d]\n", H, H); ff_write(STDOUT_FILENO, img); return 0; }