X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=liberebus%2Fsrc%2Ferebus.c;h=de8598fb845cd2c053595cdc05587d35238127ba;hb=HEAD;hp=32af87be9a749f512208a3143f48cb905610c87a;hpb=c70b7e63be9882e589a17b457900b05aca96ebb9;p=erebus2020 diff --git a/liberebus/src/erebus.c b/liberebus/src/erebus.c index 32af87b..de8598f 100644 --- a/liberebus/src/erebus.c +++ b/liberebus/src/erebus.c @@ -5,17 +5,23 @@ 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_npix; + int fb_width, fb_height, fb_size; float *fb_pixels; - int *fb_nsamples; + + 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); @@ -36,6 +42,9 @@ struct erb_rend *erb_create(void) if(!(erb = calloc(1, sizeof *erb))) { return 0; } + + erb->vfov = cgm_deg_to_rad(50.0f); + return erb; } @@ -49,36 +58,25 @@ void erb_destroy(struct erb_rend *erb) int erb_allocframe(struct erb_rend *erb, int width, int height) { float *newfb; - int *newns; - int npix; + int sz; if(width == erb->fb_width && height == erb->fb_height) { return 0; } - npix = width * height; - - if(!(newfb = malloc(npix * 3 * sizeof *erb->fb_pixels))) { - goto err; - } - if(!(newns = malloc(npix * sizeof *erb->fb_nsamples))) { - free(newfb); - goto err; + sz = width * height * 4 * sizeof *erb->fb_pixels; + if(!(newfb = malloc(sz))) { + fprintf(stderr, "erb_allocframe: failed to allocate %dx%d framebuffer\n", width, height); + return -1; } free(erb->fb_pixels); - free(erb->fb_nsamples); erb->fb_pixels = newfb; - erb->fb_nsamples = newns; erb->fb_width = width; erb->fb_height = height; - erb->fb_npix = npix; + erb->fb_size = sz; return 0; - -err: - fprintf(stderr, "erb_allocframe: failed to allocate %dx%d framebuffer\n", width, height); - return -1; } float *erb_getframe(struct erb_rend *erb) @@ -86,42 +84,50 @@ float *erb_getframe(struct erb_rend *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_npix * 3 * sizeof *erb->fb_pixels); - memset(erb->fb_nsamples, 0, erb->fb_npix * sizeof *erb->fb_nsamples); + memset(erb->fb_pixels, 0, erb->fb_size); } float *erb_end(struct erb_rend *erb) { - int i, n; + int i, npix = erb->fb_width * erb->fb_height; float s; float *pptr = erb->fb_pixels; - int *nptr = erb->fb_nsamples; - for(i=0; ifb_npix; i++) { - n = *nptr; - if(n > 1) { - s = 1.0f / n; + for(i=0; i 1) { + s = 1.0f / pptr[3]; *pptr++ *= s; *pptr++ *= s; *pptr++ *= s; - *nptr++ = 1; + *pptr++ = 1.0f; } else { - pptr += 3; - nptr++; + pptr += 4; } } 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; @@ -131,12 +137,13 @@ void erb_queue_block(struct erb_rend *erb, int x, int y, int width, int height) } 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) @@ -163,21 +170,32 @@ static void proc_render_job(void *cls) struct erb_rend *erb; struct render_job *job = cls; float *fbptr; - int *nsptr; struct erb_ray ray; erb = job->erb; - fboffs = job->y * erb->fb_width + job->x; - fbptr = erb->fb_pixels + fboffs * 3; - nsptr = erb->fb_nsamples + fboffs; + fboffs = job->rect.y * erb->fb_width + job->rect.x; + fbptr = erb->fb_pixels + fboffs * 4; - for(i=0; iheight; i++) { - for(j=0; jwidth; j++) { - erb_primary_ray(erb, &ray, *nsptr++); + for(i=0; irect.h; i++) { + for(j=0; jrect.w; j++) { + erb_primary_ray(erb, &ray, (int)fbptr[3]); erb_sample_ray(erb, &ray, fbptr); - fbptr += 3; + fbptr += 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); }