};
struct erb_rend {
- int fb_width, fb_height, fb_npix;
+ int fb_width, fb_height, fb_size;
float *fb_pixels;
- int *fb_nsamples;
};
static void proc_render_job(void *cls);
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)
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; i<erb->fb_npix; i++) {
- n = *nptr;
- if(n > 1) {
- s = 1.0f / n;
+ for(i=0; i<npix; i++) {
+ if(pptr[3] > 1) {
+ s = 1.0f / pptr[3];
*pptr++ *= s;
*pptr++ *= s;
*pptr++ *= s;
- *nptr++ = 1;
+ *pptr++ = 1.0f;
} else {
- pptr += 3;
- nptr++;
+ pptr += 4;
}
}
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;
+ fbptr = erb->fb_pixels + fboffs * 4;
for(i=0; i<job->height; i++) {
for(j=0; j<job->width; j++) {
- erb_primary_ray(erb, &ray, *nsptr++);
+ erb_primary_ray(erb, &ray, (int)fbptr[3]);
erb_sample_ray(erb, &ray, fbptr);
- fbptr += 3;
+ fbptr += 4;
}
+ fbptr += (erb->fb_width - job->width) * 4;
}
free_job(job);
}
static int win_width, win_height;
static float win_aspect;
+static int reshape_pending;
static struct erb_rend *erb;
static int drag_x, drag_y;
static int drag;
+static unsigned int fbtex;
int main(int argc, char **argv)
{
}
reshape_pending = 1;
+ glGenTextures(1, &fbtex);
+ glBindTexture(GL_TEXTURE_2D, fbtex);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glEnable(GL_TEXTURE_2D);
+
glutMainLoop();
erb_destroy(erb);
return 0;
if(reshape_pending) {
reshape_pending = 0;
- erb_allocframe(erb, x, y);
+ erb_allocframe(erb, win_width, win_height);
erb_begin(erb);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, win_width, win_height, 0,
- GL_RGB, GL_FLOAT, erb_getframe(erb));
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, win_width, win_height, 0,
+ GL_RGBA, GL_FLOAT, erb_getframe(erb));
+ } else {
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, win_width, win_height,
+ GL_RGBA, GL_FLOAT, erb_getframe(erb));
}
/* TODO: continue with getting notified when a block is done rendering */
+
glClear(GL_COLOR_BUFFER_BIT);
+ glBegin(GL_QUADS);
+ glColor3f(1, 1, 1);
+ glTexCoord2f(0, 0);
+ glVertex2f(0, 0);
+ glTexCoord2f(1, 0);
+ glVertex2f(win_width, 0);
+ glTexCoord2f(1, 1);
+ glVertex2f(win_width, win_height);
+ glTexCoord2f(0, 1);
+ glVertex2f(0, win_height);
+ glEnd();
+
if(drag) {
+ glPushAttrib(GL_ENABLE_BIT);
+ glDisable(GL_TEXTURE_2D);
glEnable(GL_LOGIC_OP);
glLogicOp(GL_XOR);
glVertex2f(drag_x, mouse_y);
glEnd();
- glDisable(GL_LOGIC_OP);
+ glPopAttrib();
}
glutSwapBuffers();
if(key == 27) {
glutExit();
}
+ glutPostRedisplay();
}
static void mouse(int bn, int st, int x, int y)
rect[1] = y < drag_y ? y : drag_y;
rect[2] = abs(x - drag_x);
rect[3] = abs(y - drag_y);
+
+ erb_queue_block(erb, rect[0], rect[1], rect[2], rect[3]);
printf("rect: %d,%d %dx%d\n", rect[0], rect[1], rect[2], rect[3]);
}