#include "vec3.h" #include "ray.h" #include #include void eresized(int new) { if(new&& getwindow(display, Refnone) < 0) sysfatal("can't reattach to window"); } double hit_sphere(vec3 centr, double rad, ray r) { vec3 oc = vecsub(r.origin, centr); double a = length_sq(r.direction); double h_b = dot(oc, r.direction); double c = length_sq(oc) - rad*rad; double dis = h_b*h_b - a*c; if (dis < 0) { return -1.0; } else { return (-h_b - sqrt(dis) ) / a; } } vec3 ray_color(ray r) { double t = hit_sphere(point3(0,0,-1), 0.5, r); if (t > 0.0) { vec3 N = unit_vector(vecsub(at(r, t), point3(0,0,-1))); N.e[0] += 1; N.e[1] += 1; N.e[2] += 1; vec3 col = vecscale(0.5, N); return col; } vec3 u_dir = unit_vector(r.direction); t = 0.5 * (u_dir.e[1] + 1.0); vec3 o = vecadd(vecscale((1.0-t), color(1.0, 1.0, 1.0)), vecscale(t, color(0.5, 0.7, 1.0))); return o; } void main(int argc, char* argv[]) { USED(argc, argv); Mouse m; Image *color; Point min, max; int i, j; unsigned int ir, ig, ib, rgb; double u, v; // Camera vec3 llc = {-2.0, -1.0, -1.0}; vec3 hor = {4.0, 0.0, 0.0}; vec3 ver = {0.0, 2.0, 0.0}; vec3 ori = {0.0, 0.0, 0.0}; vec3 dir = {0.0, 0.0, 0.0}; ray r; r.origin = ori; r.direction = dir; initdraw(0, 0, "Plan9 Raytracer"); eresized(0); einit(Emouse); min = screen->r.min; max = screen->r.max; for(j = max.y; j >= min.y; --j) { for(i = min.x; i < max.x; ++i) { u = (double)(i - min.x)/(double)(max.x - min.x); v = (double)(j - min.y)/(double)(max.y - min.y); r.origin = ori; r.direction = vecsub(vecadd(vecadd(llc, vecscale(u,hor)), vecscale(v,ver)), ori); vec3 rc = ray_color(r); ir = (unsigned char)255.99*rc.e[0]; ig = (unsigned char)255.99*rc.e[1]; ib = (unsigned char)255.99*rc.e[2]; rgb = ((ir & 0xFF) << 24) + ((ig & 0xFF) << 16) + ((ib & 0xFF) << 8) + (255 & 0xFF); color = allocimage(display, Rect(0,0,1,1), RGBA32, 1, rgb); draw(screen, Rect(i, j, i+1, j+1), color, nil, ZP); freeimage(color); } } flushimage(display, Refnone); /* Main loop */ for(;;) { m = emouse(); if(m.buttons & 4) break; } }