nuclear@0: #include nuclear@8: #include nuclear@2: #include nuclear@0: #include nuclear@12: nuclear@12: #ifndef __APPLE__ nuclear@12: #include nuclear@12: #include nuclear@12: #else nuclear@12: #include nuclear@12: #include nuclear@12: #endif nuclear@12: nuclear@0: #include "ocl.h" nuclear@9: #include "mesh.h" nuclear@0: nuclear@12: // kernel arguments nuclear@12: enum { nuclear@12: KARG_FRAMEBUFFER, nuclear@12: KARG_RENDER_INFO, nuclear@12: KARG_FACES, nuclear@12: KARG_MATLIB, nuclear@12: KARG_LIGHTS, nuclear@12: KARG_PRIM_RAYS, nuclear@12: KARG_XFORM, nuclear@12: KARG_INVTRANS_XFORM nuclear@12: }; John@11: nuclear@2: struct RendInfo { nuclear@2: int xsz, ysz; nuclear@9: int num_faces, num_lights; nuclear@2: int max_iter; nuclear@12: }; nuclear@2: nuclear@1: struct Ray { nuclear@8: float origin[4], dir[4]; nuclear@12: }; nuclear@1: nuclear@3: struct Light { nuclear@8: float pos[4], color[4]; nuclear@12: }; nuclear@1: nuclear@3: static Ray get_primary_ray(int x, int y, int w, int h, float vfov_deg); nuclear@3: nuclear@3: static Ray *prim_rays; nuclear@3: static CLProgram *prog; nuclear@3: static int global_size; nuclear@3: nuclear@9: static Face faces[] = { nuclear@9: {/* face0 */ nuclear@9: { nuclear@12: {{-1, 0, 0, 0}, {0, 0, -1, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, nuclear@12: {{0, 1, 0, 0}, {0, 0, -1, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, nuclear@12: {{1, 0, 0, 0}, {0, 0, -1, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}} nuclear@9: }, nuclear@12: {0, 0, -1, 0}, 0, {0, 0, 0} nuclear@9: }, nuclear@9: {/* face1 */ nuclear@9: { nuclear@12: {{-5, 0, -3, 0}, {0, 1, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, nuclear@12: {{0, 0, 3, 0}, {0, 1, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, nuclear@12: {{5, 0, -3, 0}, {0, 1, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}} nuclear@9: }, nuclear@12: {0, 1, 0, 0}, 1, {0, 0, 0} nuclear@9: } nuclear@9: }; nuclear@9: nuclear@9: static Material matlib[] = { nuclear@12: {{1, 0, 0, 1}, {1, 1, 1, 1}, 0, 0, 60.0, 0}, nuclear@12: {{0.2, 0.8, 0.3, 1}, {0, 0, 0, 0}, 0, 0, 0, 0} nuclear@4: }; nuclear@4: nuclear@4: static Light lightlist[] = { nuclear@12: {{-10, 10, -20, 0}, {1, 1, 1, 1}} nuclear@4: }; nuclear@4: nuclear@7: nuclear@4: static RendInfo rinf; nuclear@4: nuclear@4: nuclear@12: bool init_renderer(int xsz, int ysz) nuclear@0: { nuclear@4: // render info nuclear@4: rinf.xsz = xsz; nuclear@4: rinf.ysz = ysz; nuclear@9: rinf.num_faces = sizeof faces / sizeof *faces; nuclear@4: rinf.num_lights = sizeof lightlist / sizeof *lightlist; nuclear@4: rinf.max_iter = 6; nuclear@4: nuclear@3: /* calculate primary rays */ nuclear@3: prim_rays = new Ray[xsz * ysz]; nuclear@2: nuclear@2: for(int i=0; iload("rt.cl")) { nuclear@8: return false; nuclear@0: } nuclear@0: nuclear@3: /* setup argument buffers */ nuclear@12: prog->set_arg_buffer(KARG_FRAMEBUFFER, ARG_WR, xsz * ysz * 4 * sizeof(float)); nuclear@12: prog->set_arg_buffer(KARG_RENDER_INFO, ARG_RD, sizeof rinf, &rinf); nuclear@12: prog->set_arg_buffer(KARG_FACES, ARG_RD, sizeof faces, faces); nuclear@12: prog->set_arg_buffer(KARG_MATLIB, ARG_RD, sizeof matlib, matlib); nuclear@12: prog->set_arg_buffer(KARG_LIGHTS, ARG_RD, sizeof lightlist, lightlist); nuclear@12: prog->set_arg_buffer(KARG_PRIM_RAYS, ARG_RD, xsz * ysz * sizeof *prim_rays, prim_rays); nuclear@12: prog->set_arg_buffer(KARG_XFORM, ARG_RD, 16 * sizeof(float)); nuclear@12: prog->set_arg_buffer(KARG_INVTRANS_XFORM, ARG_RD, 16 * sizeof(float)); nuclear@12: nuclear@12: delete [] prim_rays; nuclear@2: nuclear@3: global_size = xsz * ysz; nuclear@3: return true; nuclear@3: } nuclear@3: nuclear@3: void destroy_renderer() nuclear@3: { nuclear@3: delete prog; nuclear@3: } nuclear@3: nuclear@3: bool render() nuclear@3: { nuclear@3: if(!prog->run(1, global_size)) { nuclear@3: return false; nuclear@0: } nuclear@0: nuclear@3: CLMemBuffer *mbuf = prog->get_arg_buffer(0); nuclear@12: void *fb = map_mem_buffer(mbuf, MAP_RD); nuclear@12: glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, rinf.xsz, rinf.ysz, GL_RGBA, GL_FLOAT, fb); nuclear@2: unmap_mem_buffer(mbuf); nuclear@3: return true; nuclear@0: } nuclear@2: nuclear@12: void dbg_render_gl() nuclear@8: { nuclear@12: glPushAttrib(GL_ENABLE_BIT | GL_TRANSFORM_BIT); nuclear@8: nuclear@12: glDisable(GL_TEXTURE_2D); nuclear@12: glEnable(GL_DEPTH_TEST); nuclear@12: nuclear@12: glMatrixMode(GL_PROJECTION); nuclear@12: glPushMatrix(); nuclear@12: glLoadIdentity(); nuclear@12: gluPerspective(45.0, (float)rinf.xsz / (float)rinf.ysz, 0.5, 1000.0); nuclear@12: nuclear@12: glBegin(GL_TRIANGLES); nuclear@12: for(int i=0; ikd[0], mat->kd[1], mat->kd[2]); nuclear@12: nuclear@12: for(int j=0; j<3; j++) { nuclear@12: float *pos = faces[i].v[j].pos; nuclear@12: glVertex3f(pos[0], pos[1], pos[2]); nuclear@12: } nuclear@12: } nuclear@12: glEnd(); nuclear@12: nuclear@12: glPopMatrix(); nuclear@12: glPopAttrib(); nuclear@12: } nuclear@12: nuclear@12: void set_xform(float *matrix, float *invtrans) nuclear@12: { nuclear@12: CLMemBuffer *mbuf_xform = prog->get_arg_buffer(KARG_XFORM); nuclear@12: CLMemBuffer *mbuf_invtrans = prog->get_arg_buffer(KARG_INVTRANS_XFORM); nuclear@12: assert(mbuf_xform && mbuf_invtrans); nuclear@12: nuclear@12: float *mem = (float*)map_mem_buffer(mbuf_xform, MAP_WR); nuclear@12: memcpy(mem, matrix, 16 * sizeof *mem); nuclear@12: printf("-- xform:\n"); nuclear@12: for(int i=0; i<16; i++) { nuclear@12: printf("%2.3f\t", mem[i]); nuclear@12: if(i % 4 == 3) putchar('\n'); nuclear@12: } nuclear@12: unmap_mem_buffer(mbuf_xform); nuclear@12: nuclear@12: mem = (float*)map_mem_buffer(mbuf_invtrans, MAP_WR); nuclear@12: memcpy(mem, invtrans, 16 * sizeof *mem); nuclear@12: printf("-- inverse-transpose:\n"); nuclear@12: for(int i=0; i<16; i++) { nuclear@12: printf("%2.3f\t", mem[i]); nuclear@12: if(i % 4 == 3) putchar('\n'); nuclear@12: } nuclear@12: unmap_mem_buffer(mbuf_invtrans); nuclear@8: } nuclear@8: nuclear@3: static Ray get_primary_ray(int x, int y, int w, int h, float vfov_deg) nuclear@2: { nuclear@2: float vfov = M_PI * vfov_deg / 180.0; nuclear@2: float aspect = (float)w / (float)h; nuclear@2: nuclear@2: float ysz = 2.0; nuclear@2: float xsz = aspect * ysz; nuclear@2: nuclear@2: float px = ((float)x / (float)w) * xsz - xsz / 2.0; nuclear@2: float py = 1.0 - ((float)y / (float)h) * ysz; nuclear@2: float pz = 1.0 / tan(0.5 * vfov); nuclear@2: nuclear@4: px *= 100.0; nuclear@4: py *= 100.0; nuclear@4: pz *= 100.0; nuclear@2: nuclear@12: Ray ray = {{0, 0, 0, 1}, {px, py, -pz, 1}}; nuclear@2: return ray; nuclear@2: }