Files
batomorph/demo.c
Camden Dixie O'Brien 8482373b4c Add "ground" to demo scene
2025-09-22 19:49:13 +01:00

83 lines
1.8 KiB
C

#include "camera.h"
#include "ff.h"
#include "obj.h"
#include "ray.h"
#include "vec3.h"
#include <float.h>
#include <limits.h>
#include <math.h>
#include <stdio.h>
#include <unistd.h>
#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),
SPHERE(0.0, -1001.0, 0.0, 1000.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, 0.0, DBL_MAX))
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;
}