erebus
diff liberebus/src/erebus.cc @ 17:e9da2916bc79
fixed the normal bug
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Mon, 26 May 2014 05:41:28 +0300 |
parents | 20d6c05529f1 |
children | 09028848f276 |
line diff
1.1 --- a/liberebus/src/erebus.cc Sun May 25 02:23:39 2014 +0300 1.2 +++ b/liberebus/src/erebus.cc Mon May 26 05:41:28 2014 +0300 1.3 @@ -3,8 +3,7 @@ 1.4 #include <chrono> 1.5 #include <random> 1.6 #include "erebus.h" 1.7 -#include "vmath/vector.h" 1.8 -#include "image.h" 1.9 +#include "erebus_impl.h" 1.10 #include "scene.h" 1.11 #include "geomobj.h" 1.12 #include "rt.h" 1.13 @@ -13,37 +12,8 @@ 1.14 1.15 using namespace std::chrono; 1.16 1.17 -struct Rect { 1.18 - int x, y, width, height; 1.19 - 1.20 - bool operator ==(const Rect &r) { return memcmp(this, &r, sizeof r) == 0; } 1.21 - bool operator !=(const Rect &r) { return memcmp(this, &r, sizeof r) != 0; } 1.22 -}; 1.23 - 1.24 #define INVALID_RECT Rect{0, 0, 0, 0} 1.25 1.26 -struct erebus { 1.27 - Scene *scn; 1.28 - 1.29 - Image<float> fbimg; 1.30 - Image<float> accum; // sample accumulator per pixel 1.31 - Vector4 options[ERB_NUM_OPTIONS]; 1.32 - 1.33 - // render state 1.34 - long cur_time; 1.35 - int cur_pixel_x, cur_pixel_y; 1.36 - Rect cur_rect; 1.37 - int cur_sample; 1.38 - 1.39 - // interactive input 1.40 - std::vector<bool> keystate; 1.41 - std::vector<bool> bnstate; 1.42 - int mouse_pos[2]; 1.43 - 1.44 - // debugging stuff 1.45 - int dbg_nodesel; 1.46 -}; 1.47 - 1.48 static void render_pixel(struct erebus *ctx, int x, int y, int sample); 1.49 1.50 static std::mt19937 rnd_gen; 1.51 @@ -66,7 +36,10 @@ 1.52 ctx->cur_time = 0; 1.53 ctx->cur_rect = INVALID_RECT; 1.54 1.55 - ctx->options[ERB_OPT_MAX_SAMPLES].x = (float)INF_SAMPLES; 1.56 + erb_setoptf(ctx, ERB_OPT_GAMMA, 2.2); 1.57 + erb_setopti(ctx, ERB_OPT_MAX_ITER, 6); 1.58 + erb_setopti(ctx, ERB_OPT_MAX_SAMPLES, INF_SAMPLES); 1.59 + erb_setopti(ctx, ERB_OPT_NUM_THREADS, -1); 1.60 1.61 ctx->dbg_nodesel = -1; 1.62 return ctx; 1.63 @@ -79,30 +52,69 @@ 1.64 1.65 void erb_setopti(struct erebus *ctx, enum erb_option opt, int val) 1.66 { 1.67 - ctx->options[opt].x = val; 1.68 + ctx->options[opt].ival = val; 1.69 + ctx->options[opt].type = Option::Type::INT; 1.70 } 1.71 + 1.72 void erb_setoptf(struct erebus *ctx, enum erb_option opt, float val) 1.73 { 1.74 - ctx->options[opt].x = val; 1.75 + ctx->options[opt].fval = val; 1.76 + ctx->options[opt].type = Option::Type::FLOAT; 1.77 } 1.78 + 1.79 void erb_setoptfv(struct erebus *ctx, enum erb_option opt, float *vec) 1.80 { 1.81 for(int i=0; i<4; i++) { 1.82 - ctx->options[opt][i] = vec[i]; 1.83 + ctx->options[opt].vval[i] = vec[i]; 1.84 } 1.85 + ctx->options[opt].type = Option::Type::VEC; 1.86 } 1.87 1.88 int erb_getopti(struct erebus *ctx, enum erb_option opt) 1.89 { 1.90 - return ctx->options[opt].x; 1.91 + switch(ctx->options[opt].type) { 1.92 + case Option::Type::INT: 1.93 + return ctx->options[opt].ival; 1.94 + case Option::Type::FLOAT: 1.95 + return (int)ctx->options[opt].fval; 1.96 + case Option::Type::VEC: 1.97 + return (int)ctx->options[opt].vval.x; 1.98 + } 1.99 + return 0; // can't happen 1.100 } 1.101 + 1.102 float erb_getoptf(struct erebus *ctx, enum erb_option opt) 1.103 { 1.104 - return ctx->options[opt].x; 1.105 + switch(ctx->options[opt].type) { 1.106 + case Option::Type::INT: 1.107 + return (float)ctx->options[opt].ival; 1.108 + case Option::Type::FLOAT: 1.109 + return ctx->options[opt].fval; 1.110 + case Option::Type::VEC: 1.111 + return ctx->options[opt].vval.x; 1.112 + } 1.113 + return 0.0f; // can't happen 1.114 } 1.115 + 1.116 float *erb_getoptfv(struct erebus *ctx, enum erb_option opt) 1.117 { 1.118 - return &ctx->options[opt].x; 1.119 + switch(ctx->options[opt].type) { 1.120 + case Option::Type::INT: 1.121 + { 1.122 + int ival = ctx->options[opt].ival; 1.123 + ctx->options[opt].vval = Vector4(ival, ival, ival, ival); 1.124 + } 1.125 + break; 1.126 + case Option::Type::FLOAT: 1.127 + { 1.128 + float fval = ctx->options[opt].fval; 1.129 + ctx->options[opt].vval = Vector4(fval, fval, fval, fval); 1.130 + } 1.131 + default: 1.132 + break; 1.133 + } 1.134 + 1.135 + return &ctx->options[opt].vval.x; 1.136 } 1.137 1.138 float *erb_get_framebuffer(struct erebus *ctx) 1.139 @@ -115,13 +127,14 @@ 1.140 printf("starting new frame...\n"); 1.141 ctx->cur_time = ms; 1.142 1.143 - int xsz = ctx->options[ERB_OPT_WIDTH].x; 1.144 - int ysz = ctx->options[ERB_OPT_HEIGHT].x; 1.145 + int xsz = erb_getopti(ctx, ERB_OPT_WIDTH); 1.146 + int ysz = erb_getopti(ctx, ERB_OPT_HEIGHT); 1.147 1.148 ctx->fbimg.create(xsz, ysz); 1.149 ctx->accum.create(xsz, ysz); 1.150 1.151 ctx->cur_rect = INVALID_RECT; 1.152 + ctx->inv_gamma = 1.0f / erb_getoptf(ctx, ERB_OPT_GAMMA); 1.153 } 1.154 1.155 int erb_render(struct erebus *ctx, long timeout) 1.156 @@ -144,7 +157,7 @@ 1.157 1.158 ctx->scn->update(); 1.159 1.160 - int max_samples = ctx->options[ERB_OPT_MAX_SAMPLES].x; 1.161 + int max_samples = erb_getopti(ctx, ERB_OPT_MAX_SAMPLES); 1.162 1.163 if(timeout > 0) { 1.164 auto start_time = steady_clock::now(); 1.165 @@ -165,7 +178,8 @@ 1.166 return 1; 1.167 } 1.168 1.169 - if(ctx->options[ERB_OPT_MAX_SAMPLES].x == (float)INF_SAMPLES) { 1.170 + if(max_samples == INF_SAMPLES) { 1.171 + // don't allow infinite samples when rendering non-progressively 1.172 max_samples = 128; 1.173 } 1.174 1.175 @@ -191,16 +205,16 @@ 1.176 1.177 // XXX for now just create a test scene here 1.178 Sphere *sph = new Sphere; 1.179 - sph->mtl.set_attrib("albedo", Color(1.0, 0.3, 0.2)); 1.180 + sph->mtl.set_attrib("diffuse", Color(1.0, 0.3, 0.2)); 1.181 SceneNode *sph_node = new SceneNode(sph); 1.182 ctx->scn->add_object(sph); 1.183 ctx->scn->add_node(sph_node); 1.184 1.185 sph = new Sphere; 1.186 - sph->mtl.set_attrib("albedo", Color(0.3, 0.4, 1.0)); 1.187 + sph->mtl.set_attrib("diffuse", Color(0.3, 0.4, 1.0)); 1.188 sph_node = new SceneNode(sph); 1.189 - sph_node->set_position(Vector3(0, -3.0, 0)); 1.190 - //sph_node->set_scaling(Vector3(4.0, 4.0, 4.0) * 0.3); 1.191 + sph_node->set_position(Vector3(0, -251.0, 0)); 1.192 + sph_node->set_scaling(Vector3(250.0, 250.0, 250.0)); 1.193 ctx->scn->add_object(sph); 1.194 ctx->scn->add_node(sph_node); 1.195 1.196 @@ -208,7 +222,7 @@ 1.197 lt->mtl.set_attrib("emissive", Color(10, 10, 10)); 1.198 SceneNode *lt_node = new SceneNode(lt); 1.199 lt_node->set_position(Vector3(-15, 15, -10)); 1.200 - lt_node->set_scaling(Vector3(5, 5, 5)); 1.201 + lt_node->set_scaling(Vector3(8, 8, 8)); 1.202 ctx->scn->add_object(lt); 1.203 ctx->scn->add_node(lt_node); 1.204 1.205 @@ -331,15 +345,26 @@ 1.206 float *accum = ctx->accum.get_pixels() + offs; 1.207 1.208 Ray ray = cam->get_primary_ray(x, y, xsz, ysz, sample); 1.209 - Color c = ray_trace(ray, ctx->scn, 0); 1.210 + Color c = ray_trace(ctx, ray, 0); 1.211 accum[0] += c.x; 1.212 accum[1] += c.y; 1.213 accum[2] += c.z; 1.214 accum[3] += c.w; 1.215 1.216 float inv_samples = 1.0f / (float)(sample + 1); 1.217 - pix[0] = accum[0] * inv_samples; 1.218 - pix[1] = accum[1] * inv_samples; 1.219 - pix[2] = accum[2] * inv_samples; 1.220 + pix[0] = pow(accum[0] * inv_samples, ctx->inv_gamma); 1.221 + pix[1] = pow(accum[1] * inv_samples, ctx->inv_gamma); 1.222 + pix[2] = pow(accum[2] * inv_samples, ctx->inv_gamma); 1.223 pix[3] = accum[3] * inv_samples; 1.224 } 1.225 + 1.226 +bool Rect::operator ==(const Rect &r) const 1.227 +{ 1.228 + return memcmp(this, &r, sizeof r) == 0; 1.229 +} 1.230 + 1.231 +bool Rect::operator !=(const Rect &r) const 1.232 +{ 1.233 + return memcmp(this, &r, sizeof r) != 0; 1.234 +} 1.235 +