nuclear@0: #include nuclear@8: #include nuclear@2: #include nuclear@0: #include nuclear@0: #include "ocl.h" nuclear@9: #include "mesh.h" nuclear@0: nuclear@2: struct RendInfo { nuclear@2: int xsz, ysz; nuclear@9: int num_faces, num_lights; nuclear@2: int max_iter; nuclear@2: } __attribute__((packed)); nuclear@2: nuclear@1: struct Ray { nuclear@8: float origin[4], dir[4]; nuclear@1: } __attribute__((packed)); nuclear@1: nuclear@3: struct Light { nuclear@8: float pos[4], color[4]; nuclear@3: } __attribute__((packed)); 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@9: {{-1, 0, 0, 1}, {0, 0, -1, 1}, {0, 0}}, nuclear@9: {{0, 1, 0, 1}, {0, 0, -1, 1}, {0, 0}}, nuclear@9: {{1, 0, 0, 1}, {0, 0, -1, 1}, {0, 0}} nuclear@9: }, nuclear@9: {0, 0, -1, 1}, 0 nuclear@9: }, nuclear@9: {/* face1 */ nuclear@9: { nuclear@9: {{-5, 0, -3, 1}, {0, 0, -1, 1}, {0, 0}}, nuclear@9: {{0, 0, 3, 1}, {0, 0, -1, 1}, {0, 0}}, nuclear@9: {{5, 0, -3, 1}, {0, 0, -1, 1}, {0, 0}} nuclear@9: }, nuclear@9: {0, 0, -1, 1}, 1 nuclear@9: } nuclear@9: }; nuclear@9: nuclear@9: static Material matlib[] = { nuclear@9: {{1, 0, 0, 1}, {1, 1, 1, 1}, 0, 0, 60.0}, nuclear@9: {{0.2, 0.8, 0.3, 1}, {0, 0, 0, 0}, 0, 0, 0} nuclear@4: }; nuclear@4: nuclear@4: static Light lightlist[] = { nuclear@4: {{-10, 10, -20, 1}, {1, 1, 1, 1}} nuclear@4: }; nuclear@4: nuclear@8: static float xform[16] = { nuclear@8: 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 nuclear@7: }; nuclear@7: nuclear@4: static RendInfo rinf; nuclear@4: nuclear@4: nuclear@3: bool init_renderer(int xsz, int ysz, float *fb) 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@3: prog->set_arg_buffer(0, ARG_WR, xsz * ysz * 4 * sizeof(float), fb); nuclear@3: prog->set_arg_buffer(1, ARG_RD, sizeof rinf, &rinf); nuclear@9: prog->set_arg_buffer(2, ARG_RD, sizeof faces, faces); nuclear@9: prog->set_arg_buffer(3, ARG_RD, sizeof matlib, matlib); nuclear@9: prog->set_arg_buffer(4, ARG_RD, sizeof lightlist, lightlist); nuclear@9: prog->set_arg_buffer(5, ARG_RD, xsz * ysz * sizeof *prim_rays, prim_rays); nuclear@9: prog->set_arg_buffer(6, ARG_RD, sizeof xform, &xform); 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 [] prim_rays; 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@0: map_mem_buffer(mbuf, MAP_RD); nuclear@2: unmap_mem_buffer(mbuf); nuclear@3: return true; nuclear@0: } nuclear@2: nuclear@8: void set_xform(float *matrix) nuclear@8: { nuclear@9: CLMemBuffer *mbuf = prog->get_arg_buffer(6); nuclear@8: assert(mbuf); nuclear@8: nuclear@8: assert(map_mem_buffer(mbuf, MAP_WR) == xform); nuclear@8: memcpy(xform, matrix, sizeof xform); nuclear@8: unmap_mem_buffer(mbuf); 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@2: Ray ray = {{0, 0, 0, 1}, {px, py, pz, 1}}; nuclear@2: return ray; nuclear@2: }