# HG changeset patch # User John Tsiombikas # Date 1283215647 -3600 # Node ID 30bf848815530e44f56fe4f95ec5d8f319732820 # Parent b5eb404af481239af703b4425472a3a873c28217 added interactive controls for turning shadows/reflections on and off as well as selecting maximum ray tracing iterations diff -r b5eb404af481 -r 30bf84881553 rt.cl --- a/rt.cl Sun Aug 29 14:02:37 2010 +0100 +++ b/rt.cl Tue Aug 31 01:47:27 2010 +0100 @@ -6,7 +6,7 @@ int xsz, ysz; int num_faces, num_lights; int max_iter; - int kd_depth; + int cast_shadows; }; struct Vertex { @@ -53,6 +53,7 @@ int num_lights; global const struct Material *matlib; //global const struct KDNode *kdtree; + bool cast_shadows; }; struct AABBox { @@ -104,7 +105,7 @@ scn.lights = lights; scn.num_lights = rinf->num_lights; scn.matlib = matlib; - //scn.kdtree_img = kdtree_img; + scn.cast_shadows = rinf->cast_shadows; struct Ray ray = primrays[idx]; transform_ray(&ray, xform, invtrans); @@ -113,7 +114,7 @@ float4 energy = (float4)(1.0, 1.0, 1.0, 0.0); int iter = 0; - while(iter++ < rinf->max_iter && mean(energy) > MIN_ENERGY) { + while(iter++ <= rinf->max_iter && mean(energy) > MIN_ENERGY) { struct SurfPoint sp; if(find_intersection(ray, &scn, &sp, kdtree_img)) { pixel += shade(ray, &scn, &sp, kdtree_img) * energy; @@ -156,7 +157,7 @@ shadowray.origin = sp->pos; shadowray.dir = ldir; - if(!find_intersection(shadowray, scn, 0, kdimg)) { + if(!scn->cast_shadows || !find_intersection(shadowray, scn, 0, kdimg)) { ldir = normalize(ldir); float4 vdir = -ray.dir; vdir.x = native_divide(vdir.x, RAY_MAG); diff -r b5eb404af481 -r 30bf84881553 src/clray.cc --- a/src/clray.cc Sun Aug 29 14:02:37 2010 +0100 +++ b/src/clray.cc Tue Aug 31 01:47:27 2010 +0100 @@ -19,6 +19,7 @@ void keyb(unsigned char key, int x, int y); void mouse(int bn, int status, int x, int y); void motion(int x, int y); +bool capture(const char *namefmt); bool write_ppm(const char *fname, float *fb, int xsz, int ysz); static int xsz, ysz; @@ -218,15 +219,26 @@ set_framebuffer(fb, x, y);*/ } +void idle() +{ + need_update = true; + glutPostRedisplay(); +} + void keyb(unsigned char key, int x, int y) { switch(key) { case 27: exit(0); - case 'r': - need_update = true; - glutPostRedisplay(); + case '\b': + { + static bool busyloop; + + busyloop = !busyloop; + printf("%s busy-looping\n", busyloop ? "WARNING: enabling" : "disabling"); + glutIdleFunc(busyloop ? idle : 0); + } break; case 'd': @@ -253,6 +265,54 @@ } break; + case 's': + { + bool shadows = get_render_option_bool(ROPT_SHAD); + shadows = !shadows; + printf("%s shadows\n", shadows ? "enabling" : "disabling"); + set_render_option(ROPT_SHAD, shadows); + need_update = true; + glutPostRedisplay(); + } + break; + + case 'r': + { + bool refl = get_render_option_bool(ROPT_REFL); + refl = !refl; + printf("%s reflections\n", refl ? "enabling" : "disabling"); + set_render_option(ROPT_REFL, refl); + need_update = true; + glutPostRedisplay(); + } + break; + + case ']': + { + int iter = get_render_option_int(ROPT_ITER); + printf("setting max iterations: %d\n", iter + 1); + set_render_option(ROPT_ITER, iter + 1); + need_update = true; + glutPostRedisplay(); + } + break; + + case '[': + { + int iter = get_render_option_int(ROPT_ITER); + if(iter-- > 0) { + printf("setting max iterations: %d\n", iter); + set_render_option(ROPT_ITER, iter); + need_update = true; + glutPostRedisplay(); + } + } + break; + + case '`': + capture("shot%03d.ppm"); + break; + default: break; } @@ -301,6 +361,26 @@ } } +bool capture(const char *namefmt) +{ + static int num; + char fname[256]; + + num++; + snprintf(fname, sizeof fname, namefmt, num); + printf("saving image %s\n", fname); + + float *pixels = new float[4 * xsz * ysz]; + glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, pixels); + + bool res = write_ppm("shot.ppm", pixels, xsz, ysz); + if(!res) { + num--; + } + delete [] pixels; + return res; +} + bool write_ppm(const char *fname, float *fb, int xsz, int ysz) { FILE *fp; diff -r b5eb404af481 -r 30bf84881553 src/rt.cc --- a/src/rt.cc Sun Aug 29 14:02:37 2010 +0100 +++ b/src/rt.cc Tue Aug 31 01:47:27 2010 +0100 @@ -2,6 +2,7 @@ #include #include #include +#include "rt.h" #include "ogl.h" #include "ocl.h" #include "scene.h" @@ -28,7 +29,7 @@ int xsz, ysz; int num_faces, num_lights; int max_iter; - int kd_depth; + int cast_shadows; }; struct Ray { @@ -39,6 +40,7 @@ float pos[4], color[4]; }; +static void update_render_info(); static Ray get_primary_ray(int x, int y, int w, int h, float vfov_deg); static float *create_kdimage(const KDNodeGPU *kdtree, int num_nodes, int *xsz_ret, int *ysz_ret); @@ -53,6 +55,7 @@ static RendInfo rinf; +static int saved_iter_val; static long timing_sample_sum; static long num_timing_samples; @@ -68,8 +71,8 @@ rinf.ysz = ysz; rinf.num_faces = scn->get_num_faces(); rinf.num_lights = sizeof lightlist / sizeof *lightlist; - rinf.max_iter = 6; - rinf.kd_depth = kdtree_depth(scn->kdtree); + rinf.max_iter = saved_iter_val = 6; + rinf.cast_shadows = true; /* calculate primary rays */ prim_rays = new Ray[xsz * ysz]; @@ -279,6 +282,101 @@ unmap_mem_buffer(mbuf_invtrans); } +void set_render_option(int opt, bool val) +{ + switch(opt) { + case ROPT_ITER: + case ROPT_REFL: + rinf.max_iter = val ? saved_iter_val : 0; + break; + + case ROPT_SHAD: + rinf.cast_shadows = val; + break; + + default: + return; + } + + update_render_info(); +} + +void set_render_option(int opt, int val) +{ + switch(opt) { + case ROPT_ITER: + rinf.max_iter = saved_iter_val = val; + break; + + case ROPT_SHAD: + rinf.cast_shadows = val; + break; + + case ROPT_REFL: + rinf.max_iter = val ? saved_iter_val : 0; + break; + + default: + return; + } + + update_render_info(); +} + +void set_render_option(int opt, float val) +{ + set_render_option(opt, (int)val); +} + +bool get_render_option_bool(int opt) +{ + switch(opt) { + case ROPT_ITER: + return rinf.max_iter; + case ROPT_SHAD: + return rinf.cast_shadows; + case ROPT_REFL: + return rinf.max_iter == saved_iter_val; + default: + break; + } + return false; +} + +int get_render_option_int(int opt) +{ + switch(opt) { + case ROPT_ITER: + return rinf.max_iter; + case ROPT_SHAD: + return rinf.cast_shadows ? 1 : 0; + case ROPT_REFL: + return rinf.max_iter == saved_iter_val ? 1 : 0; + default: + break; + } + return -1; +} + +float get_render_option_float(int opt) +{ + return (float)get_render_option_int(opt); +} + +static void update_render_info() +{ + if(!prog) { + return; + } + + CLMemBuffer *mbuf = prog->get_arg_buffer(KARG_RENDER_INFO); + assert(mbuf); + + RendInfo *rinf_ptr = (RendInfo*)map_mem_buffer(mbuf, MAP_WR); + *rinf_ptr = rinf; + unmap_mem_buffer(mbuf); +} + static Ray get_primary_ray(int x, int y, int w, int h, float vfov_deg) { float vfov = M_PI * vfov_deg / 180.0; diff -r b5eb404af481 -r 30bf84881553 src/rt.h --- a/src/rt.h Sun Aug 29 14:02:37 2010 +0100 +++ b/src/rt.h Tue Aug 31 01:47:27 2010 +0100 @@ -3,11 +3,27 @@ #include "scene.h" +enum { + ROPT_ITER, + ROPT_SHAD, + ROPT_REFL, + + NUM_RENDER_OPTIONS +}; + bool init_renderer(int xsz, int ysz, Scene *scn, unsigned int tex); void destroy_renderer(); bool render(); void set_xform(float *matrix, float *invtrans); +void set_render_option(int opt, bool val); +void set_render_option(int opt, int val); +void set_render_option(int opt, float val); + +bool get_render_option_bool(int opt); +int get_render_option_int(int opt); +float get_render_option_float(int opt); + void dbg_render_gl(Scene *scn, bool show_tree = false, bool show_obj = true); #endif /* RT_H_ */