struct render_job {
struct erb_rend *erb;
- int x, y, width, height;
+ unsigned int id;
+ struct erb_rect rect;
struct render_job *next;
};
struct erb_rend {
int fb_width, fb_height, fb_size;
float *fb_pixels;
+
+ erb_done_func donecb;
+ void *donecls;
+
+ float vfov;
};
static void proc_render_job(void *cls);
+static void done_render_job(void *cls);
static struct render_job *alloc_job(void);
static void free_job(struct render_job *job);
if(!(erb = calloc(1, sizeof *erb))) {
return 0;
}
+
+ erb->vfov = cgm_deg_to_rad(50.0f);
+
return erb;
}
return erb->fb_pixels;
}
+void erb_setfov(struct erb_rend *erb, float vfov_deg)
+{
+ erb->vfov = cgm_deg_to_rad(vfov_deg);
+}
+
void erb_begin(struct erb_rend *erb)
{
memset(erb->fb_pixels, 0, erb->fb_size);
return erb->fb_pixels;
}
-void erb_queue_frame(struct erb_rend *erb)
+void erb_set_done_callback(struct erb_rend *erb, erb_done_func donecb, void *cls)
+{
+ erb->donecb = donecb;
+ erb->donecls = cls;
+}
+
+void erb_queue_frame(struct erb_rend *erb, unsigned int job_id)
{
- erb_queue_block(erb, 0, 0, erb->fb_width, erb->fb_height);
+ erb_queue_block(erb, job_id, 0, 0, erb->fb_width, erb->fb_height);
}
-void erb_queue_block(struct erb_rend *erb, int x, int y, int width, int height)
+void erb_queue_block(struct erb_rend *erb, unsigned int job_id, int x, int y,
+ int width, int height)
{
struct render_job *job;
}
job->erb = erb;
- job->x = x;
- job->y = y;
- job->width = width;
- job->height = height;
+ job->id = job_id;
+ job->rect.x = x;
+ job->rect.y = y;
+ job->rect.w = width;
+ job->rect.h = height;
- tpool_enqueue(tpool, job, proc_render_job, 0);
+ tpool_enqueue(tpool, job, proc_render_job, done_render_job);
}
void erb_wait(struct erb_rend *erb)
struct erb_ray ray;
erb = job->erb;
- fboffs = job->y * erb->fb_width + job->x;
+ fboffs = job->rect.y * erb->fb_width + job->rect.x;
fbptr = erb->fb_pixels + fboffs * 4;
- for(i=0; i<job->height; i++) {
- for(j=0; j<job->width; j++) {
+ for(i=0; i<job->rect.h; i++) {
+ for(j=0; j<job->rect.w; j++) {
erb_primary_ray(erb, &ray, (int)fbptr[3]);
erb_sample_ray(erb, &ray, fbptr);
fbptr += 4;
}
- fbptr += (erb->fb_width - job->width) * 4;
+ fbptr += (erb->fb_width - job->rect.w) * 4;
}
+}
+
+static void done_render_job(void *cls)
+{
+ struct erb_rend *erb;
+ struct render_job *job = cls;
+
+ erb = job->erb;
+ if(erb->donecb) {
+ erb->donecb(job->id, &job->rect, erb->donecls);
+ }
+
free_job(job);
}