9ray/9ray.c

111 lines
2.1 KiB
C
Raw Normal View History

2022-09-03 23:30:01 -04:00
#include "vec3.h"
#include "ray.h"
#include <draw.h>
#include <event.h>
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;
}
}