nuclear@0: #include nuclear@2: #include nuclear@0: #include nuclear@0: #include "ocl.h" nuclear@0: nuclear@2: struct RendInfo { nuclear@2: int xsz, ysz; nuclear@3: int num_sph, num_lights; nuclear@2: int max_iter; nuclear@2: } __attribute__((packed)); nuclear@2: nuclear@1: struct Sphere { nuclear@1: cl_float4 pos; nuclear@5: cl_float4 kd, ks; nuclear@1: cl_float radius; nuclear@4: cl_float spow; nuclear@4: cl_float kr, kt; nuclear@1: } __attribute__((packed)); nuclear@1: nuclear@1: struct Ray { nuclear@1: cl_float4 origin, dir; nuclear@1: } __attribute__((packed)); nuclear@1: nuclear@3: struct Light { nuclear@3: cl_float4 pos, color; nuclear@3: } __attribute__((packed)); nuclear@1: nuclear@2: 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@4: static Sphere sphlist[] = { nuclear@5: {{0, 0, 8, 1}, {0.7, 0.2, 0.15, 1}, {1, 1, 1, 1}, 1.0, 60, 0, 0}, nuclear@5: {{-0.2, 0.4, 5, 1}, {0.2, 0.9, 0.3, 1}, {1, 1, 1, 1}, 0.25, 40, 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@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@4: rinf.num_sph = sizeof sphlist / sizeof *sphlist; 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@0: return 1; 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@3: prog->set_arg_buffer(2, ARG_RD, sizeof sphlist, sphlist); nuclear@3: prog->set_arg_buffer(3, ARG_RD, sizeof lightlist, lightlist); nuclear@3: prog->set_arg_buffer(4, ARG_RD, xsz * ysz * sizeof *prim_rays, 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 [] 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@3: /*if(!write_ppm("out.ppm", fb, xsz, ysz)) { nuclear@2: return 1; nuclear@3: }*/ nuclear@2: unmap_mem_buffer(mbuf); nuclear@3: return true; nuclear@0: } nuclear@2: 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: }