From c49b9d37ea873115a9995d012564ab3d3e809e4a Mon Sep 17 00:00:00 2001 From: zongor Date: Sat, 3 Sep 2022 23:30:01 -0400 Subject: [PATCH] initial push --- 9ray.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 3 +- mkfile | 15 ++++++++ ray.h | 19 ++++++++++ vec3.h | 91 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 237 insertions(+), 1 deletion(-) create mode 100755 9ray.c mode change 100644 => 100755 README.md create mode 100755 mkfile create mode 100755 ray.h create mode 100755 vec3.h diff --git a/9ray.c b/9ray.c new file mode 100755 index 0000000..da87412 --- /dev/null +++ b/9ray.c @@ -0,0 +1,110 @@ +#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; + } +} diff --git a/README.md b/README.md old mode 100644 new mode 100755 index 1575d6d..8462548 --- a/README.md +++ b/README.md @@ -1,2 +1,3 @@ -# 9ray +This is a raytracer implemented from the book [Ray Tracing In One Weekend](https://raytracing.github.io/books/RayTracingInOneWeekend.html) for the plan9 operating system. +It uses the plan9 dialect of C as well as the plan9 make system diff --git a/mkfile b/mkfile new file mode 100755 index 0000000..e50a928 --- /dev/null +++ b/mkfile @@ -0,0 +1,15 @@ + +#include + +typedef struct vec3 vec3; +struct vec3 +{ + double e[3]; +}; + + +inline double +length_sq(vec3 v) +{ + return v.e[0]*v.e[0] + v.e[1]*v.e[1] + v.e[2]*v.e[2]; +} + +inline double +length(vec3 v) +{ + return sqrt(length_sq(v)); +} + +inline vec3 +vecscale(double t, vec3 v) +{ + vec3 o = {t*v.e[0], t*v.e[1], t*v.e[2]}; + return o; +} + +inline vec3 +vecadd(vec3 v1, vec3 v2) +{ + vec3 o = {v1.e[0] + v2.e[0], v1.e[1] + v2.e[1], v1.e[2] + v2.e[2]}; + return o; +} + + +inline vec3 +vecsub(vec3 v1, vec3 v2) +{ + vec3 o = {v1.e[0] - v2.e[0], v1.e[1] - v2.e[1], v1.e[2] - v2.e[2]}; + return o; +} + +inline vec3 +vecmul(vec3 v1, vec3 v2) +{ + vec3 o = {v1.e[0] * v2.e[0], v1.e[1] * v2.e[1], v1.e[2] * v2.e[2]}; + return o; +} + +inline double +dot(vec3 u, vec3 v) +{ + return u.e[0] * v.e[0] + u.e[1] * v.e[1] + u.e[2] * v.e[2]; +} + +inline vec3 +cross(vec3 u, vec3 v) +{ + vec3 o = {(u.e[1] * v.e[2] - u.e[2] * v.e[1]), + (u.e[2] * v.e[0] - u.e[0] * v.e[2]), + (u.e[0] * v.e[1] - u.e[1] * v.e[0])}; + return o; +} + +inline vec3 +unit_vector(vec3 v) +{ + double len = length(v); + return vecscale((1/len), v); +} + +inline vec3 +color(double r, double g, double b) +{ + vec3 o = {r, g, b}; + return o; +} + +inline vec3 +point3(double x, double y, double z) +{ + vec3 o = color(x, y, z); + return o; +} + +#endif