erebus
changeset 41:2e817711d0f6
console: proper input line windowing and clipping
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Tue, 10 Jun 2014 12:28:56 +0300 |
parents | 9d6368850fe1 |
children | b9294cd6b9dc |
files | liberebus/src/geomobj.cc liberebus/src/geomobj.h liberebus/src/scene.h src/console.cc src/console.h src/main.cc |
diffstat | 6 files changed, 170 insertions(+), 53 deletions(-) [+] |
line diff
1.1 --- a/liberebus/src/geomobj.cc Tue Jun 10 10:53:19 2014 +0300 1.2 +++ b/liberebus/src/geomobj.cc Tue Jun 10 12:28:56 2014 +0300 1.3 @@ -1,6 +1,8 @@ 1.4 #include <math.h> 1.5 #include <float.h> 1.6 +#include <vmath/vmath.h> 1.7 #include "geomobj.h" 1.8 +#include "erebus_impl.h" 1.9 1.10 static LambertRefl lambert; 1.11 1.12 @@ -19,6 +21,11 @@ 1.13 return false; 1.14 } 1.15 1.16 +Vector3 GeomObject::gen_surface_point() const 1.17 +{ 1.18 + return Vector3(0, 0, 0); 1.19 +} 1.20 + 1.21 Vector3 GeomObject::calc_normal(const RayHit &hit) const 1.22 { 1.23 // when you look at singularities, the singularities always look back at you :) 1.24 @@ -64,6 +71,11 @@ 1.25 return true; 1.26 } 1.27 1.28 +Vector3 Sphere::gen_surface_point() const 1.29 +{ 1.30 + return sphrand(1.0); 1.31 +} 1.32 + 1.33 Vector3 Sphere::calc_normal(const RayHit &hit) const 1.34 { 1.35 Vector3 pt = hit.local_ray.origin + hit.local_ray.dir * hit.dist; 1.36 @@ -143,7 +155,27 @@ 1.37 return true; 1.38 } 1.39 return false; 1.40 +} 1.41 1.42 +#define SIGN(x) (x >= 0.0 ? 1.0 : -1.0) 1.43 + 1.44 +Vector3 Box::gen_surface_point() const 1.45 +{ 1.46 + Vector3 rnd{randf(-1, 1), randf(-1, 1), randf(-1, 1)}; 1.47 + float absrnd[3]; 1.48 + 1.49 + absrnd[0] = fabs(rnd.x); 1.50 + absrnd[1] = fabs(rnd.y); 1.51 + absrnd[2] = fabs(rnd.z); 1.52 + 1.53 + int major = 0; 1.54 + for(int i=1; i<3; i++) { 1.55 + if(absrnd[i] > absrnd[major]) { 1.56 + major = i; 1.57 + } 1.58 + } 1.59 + rnd[major] = SIGN(rnd[major]); 1.60 + return rnd; 1.61 } 1.62 1.63 #define BOX_EXT 0.499999 1.64 @@ -176,6 +208,15 @@ 1.65 return false; 1.66 } 1.67 1.68 +Vector3 Triangle::gen_surface_point() const 1.69 +{ 1.70 + float bu = randf(); 1.71 + float bv = randf(); 1.72 + float bw = 1.0 - (bu + bv); 1.73 + 1.74 + return v[0] * bu + v[1] * bv + v[2] * bw; 1.75 +} 1.76 + 1.77 // --- class Mesh --- 1.78 1.79 bool Mesh::intersect(const Ray &ray, RayHit *hit) const 1.80 @@ -200,3 +241,9 @@ 1.81 } 1.82 return false; 1.83 } 1.84 + 1.85 +Vector3 Mesh::gen_surface_point() const 1.86 +{ 1.87 + // this needs some precalculation... 1.88 + return Vector3(0, 0, 0); // TODO 1.89 +}
2.1 --- a/liberebus/src/geomobj.h Tue Jun 10 10:53:19 2014 +0300 2.2 +++ b/liberebus/src/geomobj.h Tue Jun 10 12:28:56 2014 +0300 2.3 @@ -17,6 +17,8 @@ 2.4 2.5 bool intersect(const Ray &ray, RayHit *hit = 0) const override; 2.6 2.7 + virtual Vector3 gen_surface_point() const; 2.8 + 2.9 virtual Vector3 calc_normal(const RayHit &hit) const; 2.10 virtual Vector3 calc_tangent(const RayHit &hit) const; 2.11 virtual Vector2 calc_texcoords(const RayHit &hit) const; 2.12 @@ -26,6 +28,8 @@ 2.13 public: 2.14 bool intersect(const Ray &ray, RayHit *hit = 0) const override; 2.15 2.16 + Vector3 gen_surface_point() const override; 2.17 + 2.18 Vector3 calc_normal(const RayHit &hit) const override; 2.19 Vector3 calc_tangent(const RayHit &hit) const override; 2.20 Vector2 calc_texcoords(const RayHit &hit) const override; 2.21 @@ -35,6 +39,8 @@ 2.22 public: 2.23 bool intersect(const Ray &ray, RayHit *hit = 0) const override; 2.24 2.25 + Vector3 gen_surface_point() const override; 2.26 + 2.27 Vector3 calc_normal(const RayHit &hit) const override; 2.28 Vector3 calc_tangent(const RayHit &hit) const override; 2.29 Vector2 calc_texcoords(const RayHit &hit) const override; 2.30 @@ -48,6 +54,8 @@ 2.31 Vector2 vtex[3]; 2.32 2.33 bool intersect(const Ray &ray, RayHit *hit = 0) const override; 2.34 + 2.35 + Vector3 gen_surface_point() const override; 2.36 }; 2.37 2.38 class Mesh : public GeomObject { 2.39 @@ -62,6 +70,8 @@ 2.40 void end(); 2.41 2.42 bool intersect(const Ray &ray, RayHit *hit = 0) const override; 2.43 + 2.44 + Vector3 gen_surface_point() const override; 2.45 }; 2.46 2.47 #endif // GEOMOBJ_H_
3.1 --- a/liberebus/src/scene.h Tue Jun 10 10:53:19 2014 +0300 3.2 +++ b/liberebus/src/scene.h Tue Jun 10 12:28:56 2014 +0300 3.3 @@ -3,6 +3,7 @@ 3.4 3.5 #include <stdio.h> 3.6 #include <vector> 3.7 +#include <list> 3.8 #include "snode.h" 3.9 #include "camera.h" 3.10 #include "color.h" 3.11 @@ -15,6 +16,11 @@ 3.12 Environment(); 3.13 }; 3.14 3.15 +struct ObjectInstance { 3.16 + Object *obj; 3.17 + SceneNode *node; 3.18 +}; 3.19 + 3.20 class Scene { 3.21 private: 3.22 Environment env;
4.1 --- a/src/console.cc Tue Jun 10 10:53:19 2014 +0300 4.2 +++ b/src/console.cc Tue Jun 10 12:28:56 2014 +0300 4.3 @@ -8,6 +8,7 @@ 4.4 #include "console.h" 4.5 4.6 Console::Console() 4.7 + : prompt("> ") 4.8 { 4.9 visible = false; 4.10 nlines = 16; 4.11 @@ -23,6 +24,28 @@ 4.12 font_size = 0; 4.13 4.14 cursor = 0; 4.15 + input_win = 0; 4.16 +} 4.17 + 4.18 +void Console::set_cursor(int x) 4.19 +{ 4.20 + if(x < 0 || x > (int)input.size()) { 4.21 + return; 4.22 + } 4.23 + cursor = x; 4.24 + 4.25 + int max_chars = ncolumns - (int)prompt.size() - 1; 4.26 + 4.27 + if(cursor < input_win) { 4.28 + input_win = cursor; 4.29 + } else if(cursor > input_win + max_chars) { 4.30 + input_win = std::max(cursor - max_chars, 0); 4.31 + } 4.32 +} 4.33 + 4.34 +int Console::get_cursor() const 4.35 +{ 4.36 + return cursor; 4.37 } 4.38 4.39 void Console::set_font(dtx_font *font, int sz) 4.40 @@ -107,20 +130,19 @@ 4.41 switch(c) { 4.42 case '\n': 4.43 case '\r': 4.44 - if(!input.empty() && cmd_handler) { 4.45 - cmd_handler(input.c_str()); 4.46 - } 4.47 - 4.48 if(echo) { 4.49 puts(input.c_str()); 4.50 putchar('\n'); 4.51 } 4.52 + if(!input.empty() && cmd_handler) { 4.53 + cmd_handler(input.c_str()); 4.54 + } 4.55 4.56 hist.push_back(std::move(input)); // move the input string into the history buffer 4.57 if((int)hist.size() > max_hist_lines) { 4.58 hist.pop_front(); 4.59 } 4.60 - cursor = 0; 4.61 + set_cursor(0); 4.62 must_redraw = true; 4.63 break; 4.64 4.65 @@ -132,11 +154,11 @@ 4.66 if(!input.empty()) { 4.67 if(cursor == (int)input.size()) { 4.68 input.pop_back(); 4.69 - --cursor; 4.70 + set_cursor(get_cursor() - 1); 4.71 must_redraw = true; 4.72 } else if(cursor > 0) { 4.73 input.erase(cursor - 1, 1); 4.74 - --cursor; 4.75 + set_cursor(get_cursor() - 1); 4.76 must_redraw = true; 4.77 } 4.78 } 4.79 @@ -144,25 +166,25 @@ 4.80 4.81 case KEY_LEFT: 4.82 if(cursor > 0) { 4.83 - --cursor; 4.84 + set_cursor(get_cursor() - 1); 4.85 must_redraw = true; 4.86 } 4.87 break; 4.88 4.89 case KEY_RIGHT: 4.90 if(cursor < (int)input.size()) { 4.91 - ++cursor; 4.92 + set_cursor(get_cursor() + 1); 4.93 must_redraw = true; 4.94 } 4.95 break; 4.96 4.97 case KEY_HOME: 4.98 - cursor = 0; 4.99 + set_cursor(0); 4.100 must_redraw = true; 4.101 break; 4.102 4.103 case KEY_END: 4.104 - cursor = input.size(); 4.105 + set_cursor(input.size()); 4.106 must_redraw = true; 4.107 break; 4.108 4.109 @@ -178,7 +200,7 @@ 4.110 } else { 4.111 input.insert(cursor, 1, c); 4.112 } 4.113 - ++cursor; 4.114 + set_cursor(get_cursor() + 1); 4.115 must_redraw = true; 4.116 } 4.117 } 4.118 @@ -202,7 +224,7 @@ 4.119 glMatrixMode(GL_MODELVIEW); 4.120 glPushMatrix(); 4.121 glLoadIdentity(); 4.122 - glTranslatef(0, vp[3] - vp[1], 0); 4.123 + glTranslatef(0, vp[3], 0); 4.124 4.125 std::string buflines; 4.126 4.127 @@ -215,18 +237,22 @@ 4.128 const std::string &line = *it++; 4.129 buflines += line + std::string("\n"); 4.130 4.131 - max_width = std::max(max_width, dtx_string_width(line.c_str())); 4.132 + //max_width = std::max(max_width, dtx_string_width(line.c_str())); 4.133 } 4.134 4.135 // draw the output box 4.136 float line_height = dtx_line_height(); 4.137 float outbox_height = nlines * line_height; 4.138 + float console_height = outbox_height + line_height * 1.5; 4.139 4.140 glPushAttrib(GL_ENABLE_BIT); 4.141 glEnable(GL_BLEND); 4.142 glDisable(GL_TEXTURE_2D); 4.143 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 4.144 4.145 + glEnable(GL_SCISSOR_TEST); 4.146 + glScissor(0, vp[3] - console_height, max_width, console_height); 4.147 + 4.148 glBegin(GL_QUADS); 4.149 glColor4f(0.1, 0.2, 0.5, 0.7); 4.150 glVertex2f(0, -outbox_height); 4.151 @@ -235,8 +261,8 @@ 4.152 glVertex2f(0, 0); 4.153 4.154 glColor4f(0.5, 0.2, 0.1, 0.7); 4.155 - glVertex2f(0, -(outbox_height + line_height * 1.5)); 4.156 - glVertex2f(max_width, -(outbox_height + line_height * 1.5)); 4.157 + glVertex2f(0, -console_height); 4.158 + glVertex2f(max_width, -console_height); 4.159 glVertex2f(max_width, -outbox_height); 4.160 glVertex2f(0, -outbox_height); 4.161 glEnd(); 4.162 @@ -251,11 +277,11 @@ 4.163 // draw the input line 4.164 glTranslatef(0, -outbox_height - line_height, 0); 4.165 4.166 - std::string inpline = std::string("> ") + input; 4.167 + std::string inpline = prompt + input.substr(input_win); 4.168 dtx_string(inpline.c_str()); 4.169 glDisable(GL_TEXTURE_2D); 4.170 4.171 - float cursor_x = dtx_char_pos(inpline.c_str(), cursor + 2); 4.172 + float cursor_x = dtx_char_pos(inpline.c_str(), cursor - input_win + prompt.size()); 4.173 glBegin(GL_QUADS); 4.174 glColor4f(1, 1, 1, 0.7); 4.175 glVertex2f(cursor_x, 0);
5.1 --- a/src/console.h Tue Jun 10 10:53:19 2014 +0300 5.2 +++ b/src/console.h Tue Jun 10 12:28:56 2014 +0300 5.3 @@ -17,8 +17,10 @@ 5.4 int inpq_front, inpq_back; 5.5 int keybuf[INPUTQ_SIZE]; 5.6 5.7 + std::string prompt; 5.8 std::string input; // current input line 5.9 int cursor; 5.10 + int input_win; // first character to show in the input "window" 5.11 5.12 // input history 5.13 int max_hist_lines; 5.14 @@ -34,6 +36,9 @@ 5.15 int font_size; 5.16 dtx_font *font; 5.17 5.18 + void set_cursor(int x); 5.19 + int get_cursor() const; 5.20 + 5.21 public: 5.22 enum { 5.23 KEY_LEFT = 256,
6.1 --- a/src/main.cc Tue Jun 10 10:53:19 2014 +0300 6.2 +++ b/src/main.cc Tue Jun 10 12:28:56 2014 +0300 6.3 @@ -148,8 +148,7 @@ 6.4 6.5 static void begin_frame(long tm) 6.6 { 6.7 - printf("rendering frame (t=%ld) ... ", tm); 6.8 - fflush(stdout); 6.9 + printf("rendering frame (t=%ld) ...\n", tm); 6.10 6.11 render_pending = true; 6.12 glutIdleFunc(idle); 6.13 @@ -167,7 +166,7 @@ 6.14 long msec, sec, min, hr, days; 6.15 6.16 msec = full_msec; 6.17 - printf("done in "); 6.18 + con.printf("done in "); 6.19 if((sec = msec / 1000) > 0) { 6.20 msec %= 1000; 6.21 if((min = sec / 60) > 0) { 6.22 @@ -176,15 +175,15 @@ 6.23 min %= 60; 6.24 if((days = hr / 24) > 0) { 6.25 hr %= 24; 6.26 - printf("%ld days ", days); 6.27 + con.printf("%ld days ", days); 6.28 } 6.29 - printf("%ld hours ", hr); 6.30 + con.printf("%ld hours ", hr); 6.31 } 6.32 - printf("%ld min ", min); 6.33 + con.printf("%ld min ", min); 6.34 } 6.35 - printf("%ld sec ", sec); 6.36 + con.printf("%ld sec ", sec); 6.37 } 6.38 - printf("%ld ms (%ld total msec)\n", msec, full_msec); 6.39 + con.printf("%ld ms (%ld total msec)\n", msec, full_msec); 6.40 6.41 render_pending = false; 6.42 glutIdleFunc(0); 6.43 @@ -194,44 +193,51 @@ 6.44 { 6.45 static unsigned char *defpix; 6.46 6.47 + if(render_pending) { 6.48 + erb_end_frame(erb); 6.49 + } 6.50 + 6.51 win_width = xsz; 6.52 win_height = ysz; 6.53 6.54 width = xsz / opt_imgscale; 6.55 height = ysz / opt_imgscale; 6.56 6.57 - if(width <= rtex_width && height <= rtex_height) { 6.58 - return; 6.59 - } 6.60 - rtex_width = next_pow2(width); 6.61 - rtex_height = next_pow2(height); 6.62 + if(width > rtex_width || height > rtex_height) { 6.63 + rtex_width = next_pow2(width); 6.64 + rtex_height = next_pow2(height); 6.65 6.66 - printf("resizing framebuffer texture: %dx%d\n", rtex_width, rtex_height); 6.67 + printf("resizing framebuffer texture: %dx%d\n", rtex_width, rtex_height); 6.68 6.69 - if(!rtex) { 6.70 - glGenTextures(1, &rtex); 6.71 + if(!rtex) { 6.72 + glGenTextures(1, &rtex); 6.73 + } 6.74 + 6.75 + delete [] defpix; 6.76 + defpix = new unsigned char[rtex_width * rtex_height * 4]; 6.77 + unsigned char *ptr = defpix; 6.78 + for(int i=0; i<rtex_height; i++) { 6.79 + for(int j=0; j<rtex_width; j++) { 6.80 + bool chess = ((i >> 4) & 1) == ((j >> 4) & 1); 6.81 + 6.82 + int val = chess ? 64 : 48; 6.83 + 6.84 + *ptr++ = val; 6.85 + *ptr++ = val; 6.86 + *ptr++ = val; 6.87 + *ptr++ = 255; 6.88 + } 6.89 + } 6.90 + 6.91 + glBindTexture(GL_TEXTURE_2D, rtex); 6.92 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 6.93 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 6.94 + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, rtex_width, rtex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, defpix); 6.95 } 6.96 6.97 - delete [] defpix; 6.98 - defpix = new unsigned char[rtex_width * rtex_height * 4]; 6.99 - unsigned char *ptr = defpix; 6.100 - for(int i=0; i<rtex_height; i++) { 6.101 - for(int j=0; j<rtex_width; j++) { 6.102 - bool chess = ((i >> 4) & 1) == ((j >> 4) & 1); 6.103 - 6.104 - int val = chess ? 64 : 48; 6.105 - 6.106 - *ptr++ = val; 6.107 - *ptr++ = val; 6.108 - *ptr++ = val; 6.109 - *ptr++ = 255; 6.110 - } 6.111 + if(render_pending) { 6.112 + begin_frame(0); 6.113 } 6.114 - 6.115 - glBindTexture(GL_TEXTURE_2D, rtex); 6.116 - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 6.117 - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 6.118 - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, rtex_width, rtex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, defpix); 6.119 } 6.120 6.121 static void update_rect(int x, int y, int xsz, int ysz, float *pixels) 6.122 @@ -613,6 +619,14 @@ 6.123 } 6.124 begin_frame(tm); 6.125 6.126 + } else if(strcmp(args[0], "samples") == 0) { 6.127 + if(args[1] && (opt_samples = atoi(args[1]))) { 6.128 + erb_setopti(erb, ERB_OPT_MAX_SAMPLES, opt_samples); 6.129 + con.printf("max samples is now %d\n", opt_samples); 6.130 + } else { 6.131 + con.printf("invalid samples command: %s\n", line); 6.132 + } 6.133 + 6.134 } else if(strcmp(args[0], "load") == 0) { 6.135 for(int i=1; i<argc; i++) { 6.136 if(erb_load_scene(erb, args[i]) == -1) { 6.137 @@ -629,6 +643,15 @@ 6.138 begin_frame(0); 6.139 } 6.140 6.141 + } else if(strcmp(args[0], "help") == 0) { 6.142 + con.printf("Available commands:\n"); 6.143 + con.printf("render [anim time] begins rendering a frame with the given time (default: 0)\n"); 6.144 + con.printf("stop stops rendering\n"); 6.145 + con.printf("samples <count> sets the maximum number of samples per pixel\n"); 6.146 + con.printf("iter <count> sets the maximum number of ray bounces\n"); 6.147 + con.printf("load <filename> loads a scene file\n"); 6.148 + con.printf("add <object command> adds another object to the scene. For valid object commands see test/scene\n"); 6.149 + 6.150 } else { 6.151 con.printf("unrecognized command: %s\n", args[0]); 6.152 }