render.c (2219B)
1 #include <u.h> 2 #include <libc.h> 3 4 #include "render.h" 5 6 #define BSIZE 512 7 #define SQR(X) (X * X) 8 9 double 10 vectmod(Vect d) 11 { 12 return sqrt(SQR(d.x) + SQR(d.y) + SQR(d.z)); 13 } 14 15 Vect 16 vectnorm(Vect d) 17 { 18 double m; 19 m = vectmod(d); 20 return (Vect){d.x/m, d.y/m, d.z/m}; 21 } 22 23 Vect 24 vectxvect(Vect d1, Vect d2) 25 { 26 return (Vect){d1.x * d2.x, d1.y * d2.y, d1.z * d2.z}; 27 } 28 29 30 Vect 31 addvect(Vect d1, Vect d2) 32 { 33 return (Vect){d1.x + d2.x, d1.y + d2.y, d1.z + d2.z}; 34 } 35 36 Vect 37 subvect(Vect d1, Vect d2) 38 { 39 return addvect(d1, (Vect){-d2.x, -d2.y, -d2.z}); 40 } 41 42 Vect 43 todecart(Vect v) 44 { 45 /* TODO: recheck this code, it's probably wrong. 46 * hypot specifically. 47 */ 48 return (Vect) { 49 v.z * sin(v.x), 50 v.z * sin(v.y), 51 hypot(v.z * cos(v.y), v.z * cos(v.x)), 52 }; 53 } 54 55 double 56 vectscalar(Vect d1, Vect d2) 57 { 58 return d1.x * d2.x + d1.y * d2.y + d1.z * d2.z; 59 } 60 61 int 62 spherehit(Ray *v, Sphere s) 63 { 64 double d, old; 65 int i; 66 old = Inf(1); 67 for (i = 0; i < 1024; i++) { 68 d = vectmod(subvect(v->pos, s.pos)) - s.radius; 69 v->pos = addvect(v->pos, 70 vectxvect(vectnorm(v->dir), (Vect){d, d, d})); 71 if (d < 0.001) { 72 v->dir = subvect(s.pos, v->pos); 73 return 1; 74 } 75 if (d > old) return 0; 76 old = d; 77 } 78 return 0; 79 } 80 81 Vect 82 ray(Ray v) 83 { 84 Vect vv; 85 vv = v.pos; 86 Sphere sphere = {{0, 0, }, 1}; 87 Vect light = vectnorm((Vect){10, -10, 10}); 88 Vect p = Pblack; 89 if (spherehit(&v, sphere)) { 90 double f; 91 Vect r; 92 r = vectnorm(v.dir); 93 f = vectscalar(r, light)/(vectmod(light)*vectmod(r)); 94 if (f < 0) f = 0; 95 p = (Vect){f, f, f}; 96 } 97 return p; 98 } 99 100 u32int 101 render(int x, int y) 102 { 103 double fov; 104 Vect p; 105 u32int r, g, b; 106 Ray v; 107 fov = PI/2; 108 v.pos = (Vect) { 0, 0, -3 }; 109 v.dir = todecart((Vect) { 110 fov*((double)x/BSIZE - 0.5), 111 fov*((double)y/BSIZE - 0.5), 112 1}); 113 p = ray(v); 114 r = (u32int)(0xff * p.x)&0xff; 115 g = (u32int)(0xff * p.y)&0xff; 116 b = (u32int)(0xff * p.z)&0xff; 117 return (r<<16)|(g<<8)|b; 118 } 119 120 void 121 main(void) 122 { 123 int i, x, y; 124 u32int buf[SQR(BSIZE)]; 125 write(1, " x8r8g8b8 ", 12); 126 write(1, " 0 ", 12); 127 write(1, " 0 ", 12); 128 fprint(1, "%11d ", BSIZE); 129 fprint(1, "%11d ", BSIZE); 130 for (i = 0; i < SQR(BSIZE); i++) { 131 x = i%BSIZE; 132 y = BSIZE-(i/BSIZE); 133 buf[i] = render(x, y); 134 } 135 write(1, buf, 4 * SQR(BSIZE)); 136 exits(nil); 137 }