8 int x, y, width, height;
13 struct framebuffer fb;
14 struct thread_pool *tpool;
16 float vfov = M_PI / 4;
19 static struct tile *tiles;
22 static void render_tile(struct tile *tile);
23 static void ray_trace(cgm_vec3 *color, cgm_ray *ray);
24 static void bgcolor(cgm_vec3 *color, cgm_ray *ray);
25 static void primary_ray(cgm_ray *ray, int x, int y, int sample);
27 int fbsize(int width, int height)
29 int i, j, x, y, xtiles, ytiles;
33 if(!(fbptr = malloc(width * height * sizeof *fb.pixels))) {
36 xtiles = (width + TILESZ - 1) / TILESZ;
37 ytiles = (height + TILESZ - 1) / TILESZ;
38 if(!(tileptr = malloc(xtiles * ytiles * sizeof *tiles))) {
50 num_tiles = xtiles * ytiles;
52 aspect = (float)fb.width / (float)fb.height;
55 for(i=0; i<ytiles; i++) {
57 for(j=0; j<xtiles; j++) {
60 tileptr->width = width - x < TILESZ ? width - x : TILESZ;
61 tileptr->height = height - y < TILESZ ? height - y : TILESZ;
62 tileptr->fbptr = fbptr + x;
67 fbptr += width * TILESZ;
78 for(i=0; i<num_tiles; i++) {
79 tpool_enqueue(tpool, tiles + i, (tpool_callback)render_tile, 0);
84 static void render_tile(struct tile *tile)
88 cgm_vec3 *fbptr = tile->fbptr;
90 for(i=0; i<tile->height; i++) {
91 for(j=0; j<tile->width; j++) {
92 primary_ray(&ray, tile->x + j, tile->y + i, tile->sample);
93 ray_trace(fbptr + j, &ray);
99 static void ray_trace(cgm_vec3 *color, cgm_ray *ray)
103 if(ray_level(ray, &lvl, FLT_MAX, &hit)) {
104 color->x = hit.v.norm.x * 0.5 + 0.5;
105 color->y = hit.v.norm.y * 0.5 + 0.5;
106 color->z = hit.v.norm.z * 0.5 + 0.5;
112 static void bgcolor(cgm_vec3 *color, cgm_ray *ray)
114 color->x = color->y = color->z = 1.0f;
117 static void primary_ray(cgm_ray *ray, int x, int y, int sample)
119 ray->origin.x = ray->origin.y = ray->origin.z = 0.0f;
120 ray->dir.x = (2.0f * (float)x / (float)fb.width - 1.0f) * aspect;
121 ray->dir.y = 1.0f - 2.0f * (float)y / (float)fb.height;
122 ray->dir.z = -1.0f / tan(vfov / 2.0f);
123 cgm_vnormalize(&ray->dir);
127 cgm_rmul_mr(ray, view_xform);