rayzor
changeset 14:a9a948809c6f
starting the renderer screen, plus misc stuff
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sun, 13 Apr 2014 08:06:21 +0300 |
parents | 964f8ea5f095 |
children | be616b58df99 |
files | src/dosemu/direct.h src/dosemu/dosemu.c src/main.cc src/modeller.cc src/object.cc src/object.h src/rayzor.h src/renderer.cc src/renderer.h src/scene.cc src/snode.cc src/snode.h src/vmathray.h |
diffstat | 13 files changed, 212 insertions(+), 35 deletions(-) [+] |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/dosemu/direct.h Sun Apr 13 08:06:21 2014 +0300 1.3 @@ -0,0 +1,2 @@ 1.4 +/* watcom has opendir/readdir in direct.h instead of dirent.h for some reason */ 1.5 +#include <dirent.h>
2.1 --- a/src/dosemu/dosemu.c Sat Apr 12 23:37:55 2014 +0300 2.2 +++ b/src/dosemu/dosemu.c Sun Apr 13 08:06:21 2014 +0300 2.3 @@ -508,10 +508,7 @@ 2.4 2.5 static int translate_sdlkey(int sym) 2.6 { 2.7 - if(sym >= 0 && sym < 256) { 2.8 - return sdlkey_tbl[sym]; 2.9 - } 2.10 - return sym; 2.11 + return sdlkey_tbl[sym]; 2.12 } 2.13 2.14 static void update_modkeys(void)
3.1 --- a/src/main.cc Sat Apr 12 23:37:55 2014 +0300 3.2 +++ b/src/main.cc Sun Apr 13 08:06:21 2014 +0300 3.3 @@ -2,6 +2,8 @@ 3.4 #include <stdlib.h> 3.5 #include <string.h> 3.6 #include <signal.h> 3.7 +#include <errno.h> 3.8 +#include <direct.h> 3.9 #include "inttypes.h" 3.10 #include "gfx.h" 3.11 #include "keyb.h" 3.12 @@ -29,6 +31,7 @@ 3.13 static void display(); 3.14 static void swap_buffers(); 3.15 static void draw_cursor(uint32_t *buf, int mx, int my); 3.16 +static void screenshot(); 3.17 static void handle_keyboard(); 3.18 static void handle_mouse(); 3.19 static bool parse_args(int argc, char **argv); 3.20 @@ -50,6 +53,7 @@ 3.21 static bool use_mouse; 3.22 static int mouse_x, mouse_y; 3.23 static bool quit; 3.24 +static bool cap_shot; 3.25 3.26 int main(int argc, char **argv) 3.27 { 3.28 @@ -188,6 +192,11 @@ 3.29 draw_cursor(fb_pixels, mouse_x, mouse_y); 3.30 } 3.31 3.32 + if(cap_shot) { 3.33 + screenshot(); 3.34 + cap_shot = false; 3.35 + } 3.36 + 3.37 if(!novideo) { 3.38 wait_vsync(); 3.39 #ifdef USE_ASM_SWAPBUF 3.40 @@ -279,6 +288,51 @@ 3.41 } 3.42 } 3.43 3.44 +#define PPM_COMMENT "screenshot saved by the rayzor modeller/renderer" 3.45 +static void screenshot() 3.46 +{ 3.47 + static int shotidx = -1; 3.48 + FILE *fp; 3.49 + char fname[PATH_MAX]; 3.50 + 3.51 + if(shotidx == -1) { 3.52 + DIR *dir; 3.53 + struct dirent *dent; 3.54 + 3.55 + shotidx = 0; 3.56 + if((dir = opendir("."))) { 3.57 + while((dent = readdir(dir))) { 3.58 + int i, num; 3.59 + for(i=0; dent->d_name[i]; i++) { 3.60 + fname[i] = tolower(dent->d_name[i]); 3.61 + } 3.62 + fname[i] = 0; 3.63 + 3.64 + if(sscanf(fname, "shot%d.ppm", &num) == 1 && num > shotidx) { 3.65 + shotidx = num; 3.66 + } 3.67 + } 3.68 + closedir(dir); 3.69 + } 3.70 + } 3.71 + 3.72 + sprintf(fname, "shot%04d.ppm", ++shotidx); 3.73 + if(!(fp = fopen(fname, "wb"))) { 3.74 + printlog("failed to save screenshot %s: %s\n", fname, strerror(errno)); 3.75 + return; 3.76 + } 3.77 + 3.78 + fprintf(fp, "P6\n" PPM_COMMENT "\n%d %d\n255\n", fb_width, fb_height); 3.79 + for(int i=0; i<fb_width * fb_height; i++) { 3.80 + uint32_t c = fb_pixels[i]; 3.81 + fputc(UNPACK_RED(c), fp); 3.82 + fputc(UNPACK_GREEN(c), fp); 3.83 + fputc(UNPACK_BLUE(c), fp); 3.84 + } 3.85 + 3.86 + fclose(fp); 3.87 +} 3.88 + 3.89 static void handle_keyboard() 3.90 { 3.91 int key; 3.92 @@ -299,6 +353,11 @@ 3.93 } 3.94 break; 3.95 3.96 + case KB_SYSRQ: 3.97 + case KB_F12: 3.98 + cap_shot = true; 3.99 + break; 3.100 + 3.101 default: 3.102 break; 3.103 }
4.1 --- a/src/modeller.cc Sat Apr 12 23:37:55 2014 +0300 4.2 +++ b/src/modeller.cc Sun Apr 13 08:06:21 2014 +0300 4.3 @@ -6,6 +6,8 @@ 4.4 #include "rayzor.h" 4.5 #include "scene.h" 4.6 #include "keyb.h" 4.7 +#include "scrman.h" 4.8 +#include "logger.h" 4.9 4.10 struct ModellerImpl { 4.11 int mx, my; 4.12 @@ -100,10 +102,10 @@ 4.13 m3d_end(); 4.14 4.15 m3d_begin(M3D_LINES); 4.16 - m3d_color(1.0, 0, 0); 4.17 + m3d_color(0.8, 0, 0); 4.18 m3d_vertex(-dist, 0, 0); 4.19 m3d_vertex(dist, 0, 0); 4.20 - m3d_color(0, 1.0, 0); 4.21 + m3d_color(0.1, 0.3, 0.8); 4.22 m3d_vertex(0, 0, -dist); 4.23 m3d_vertex(0, 0, dist); 4.24 m3d_end(); 4.25 @@ -135,6 +137,18 @@ 4.26 } 4.27 break; 4.28 4.29 + case 'r': 4.30 + case 'R': 4.31 + if(kb_isdown(KB_ALT) || kb_isdown(KB_CTRL)) { 4.32 + Screen *rs = get_screen("renderer"); 4.33 + if(rs) { 4.34 + activate_screen(rs); 4.35 + } else { 4.36 + printlog("failed to find renderer screen!\n"); 4.37 + } 4.38 + } 4.39 + break; 4.40 + 4.41 default: 4.42 break; 4.43 }
5.1 --- a/src/object.cc Sat Apr 12 23:37:55 2014 +0300 5.2 +++ b/src/object.cc Sun Apr 13 08:06:21 2014 +0300 5.3 @@ -1,3 +1,4 @@ 5.4 +#include <math.h> 5.5 #include "object.h" 5.6 #include "vmath.h" 5.7 #include "min3d.h" 5.8 @@ -12,18 +13,6 @@ 5.9 { 5.10 } 5.11 5.12 -void Object::pre_draw() const 5.13 -{ 5.14 - m3d_matrix_mode(M3D_MODELVIEW); 5.15 - m3d_push_matrix(); 5.16 - m3d_mult_matrix(get_matrix()[0]); 5.17 -} 5.18 - 5.19 -void Object::post_draw() const 5.20 -{ 5.21 - m3d_pop_matrix(); 5.22 -} 5.23 - 5.24 // ---- sphere ---- 5.25 Sphere::Sphere() 5.26 { 5.27 @@ -36,7 +25,7 @@ 5.28 #define USUB 12 5.29 #define VSUB 6 5.30 5.31 -void Sphere::draw() const 5.32 +void Sphere::draw(bool emph) const 5.33 { 5.34 static Vector3 *varr; 5.35 static unsigned int *iarr; 5.36 @@ -85,6 +74,7 @@ 5.37 } 5.38 5.39 pre_draw(); 5.40 + SceneNode::draw(emph); 5.41 5.42 m3d_vertex_array(&varr->x); 5.43 m3d_draw_indexed(M3D_QUADS, iarr, num_indices); 5.44 @@ -93,9 +83,36 @@ 5.45 post_draw(); 5.46 } 5.47 5.48 -bool Sphere::intersect(const Ray &ray, float *dist) const 5.49 +bool Sphere::intersect(const Ray &wray, float *dist) const 5.50 { 5.51 - return false; // TODO 5.52 + Ray ray = transform(get_inv_matrix(), wray); 5.53 + 5.54 + // assumes center is 0,0,0, and radius is 1 5.55 + float a = dot(ray.dir, ray.dir); 5.56 + float b = 2.0 * ray.dir.x * ray.origin.x + 5.57 + 2.0 * ray.dir.y * ray.origin.y + 5.58 + 2.0 * ray.dir.z * ray.origin.z; 5.59 + float c = dot(ray.origin, ray.origin) - 1.0; 5.60 + 5.61 + float discr = b * b - 4.0 * a * c; 5.62 + if(discr < 1e-4) 5.63 + return false; 5.64 + 5.65 + float sqrt_discr = sqrt(discr); 5.66 + float t0 = (-b + sqrt_discr) / (2.0 * a); 5.67 + float t1 = (-b - sqrt_discr) / (2.0 * a); 5.68 + 5.69 + if(t0 < 1e-4) 5.70 + t0 = t1; 5.71 + if(t1 < 1e-4) 5.72 + t1 = t0; 5.73 + 5.74 + float t = t0 < t1 ? t0 : t1; 5.75 + if(t < 1e-4) 5.76 + return false; 5.77 + 5.78 + if(dist) *dist = t; 5.79 + return true; 5.80 } 5.81 5.82 // ---- box ---- 5.83 @@ -117,7 +134,7 @@ 5.84 4------------5 5.85 5.86 */ 5.87 -void Box::draw() const 5.88 +void Box::draw(bool emph) const 5.89 { 5.90 static const float verts[] = { 5.91 -1, 1, 1, 5.92 @@ -139,6 +156,7 @@ 5.93 }; 5.94 5.95 pre_draw(); 5.96 + SceneNode::draw(emph); 5.97 5.98 m3d_vertex_array(verts); 5.99 m3d_draw_indexed(M3D_QUADS, indices, sizeof indices / sizeof *indices);
6.1 --- a/src/object.h Sat Apr 12 23:37:55 2014 +0300 6.2 +++ b/src/object.h Sun Apr 13 08:06:21 2014 +0300 6.3 @@ -5,10 +5,6 @@ 6.4 #include "snode.h" 6.5 6.6 class Object : public SceneNode { 6.7 -protected: 6.8 - void pre_draw() const; 6.9 - void post_draw() const; 6.10 - 6.11 public: 6.12 Object(); 6.13 virtual ~Object(); 6.14 @@ -19,7 +15,7 @@ 6.15 Sphere(); 6.16 ~Sphere(); 6.17 6.18 - void draw() const; 6.19 + void draw(bool emph = false) const; 6.20 6.21 bool intersect(const Ray &ray, float *dist = 0) const; 6.22 }; 6.23 @@ -29,7 +25,7 @@ 6.24 Box(); 6.25 ~Box(); 6.26 6.27 - void draw() const; 6.28 + void draw(bool emph = false) const; 6.29 6.30 bool intersect(const Ray &ray, float *dist = 0) const; 6.31 };
7.1 --- a/src/rayzor.h Sat Apr 12 23:37:55 2014 +0300 7.2 +++ b/src/rayzor.h Sun Apr 13 08:06:21 2014 +0300 7.3 @@ -1,6 +1,8 @@ 7.4 #ifndef RAYZOR_H_ 7.5 #define RAYZOR_H_ 7.6 7.7 +#include "inttypes.h" 7.8 + 7.9 // global framebuffer (back buffer) 7.10 extern uint32_t *fb_pixels; 7.11 extern int fb_width, fb_height;
8.1 --- a/src/renderer.cc Sat Apr 12 23:37:55 2014 +0300 8.2 +++ b/src/renderer.cc Sun Apr 13 08:06:21 2014 +0300 8.3 @@ -1,10 +1,46 @@ 8.4 +#include <string.h> 8.5 #include "renderer.h" 8.6 +#include "rayzor.h" 8.7 +#include "keyb.h" 8.8 +#include "scrman.h" 8.9 + 8.10 +struct RendererImpl { 8.11 + bool in_progress; 8.12 + int cur_x, cur_y; // current pixel being rendered 8.13 + int cur_pix; // current pixel (linear) 8.14 +}; 8.15 8.16 Renderer::Renderer() 8.17 { 8.18 set_name("renderer"); 8.19 } 8.20 8.21 +bool Renderer::init() 8.22 +{ 8.23 + rend = new RendererImpl; 8.24 + memset(rend, 0, sizeof *rend); 8.25 + return true; 8.26 +} 8.27 + 8.28 +void Renderer::shutdown() 8.29 +{ 8.30 + if(rend) { 8.31 + delete rend; 8.32 + rend = 0; 8.33 + } 8.34 +} 8.35 + 8.36 void Renderer::draw() const 8.37 { 8.38 + memset(fb_pixels, 0, fb_width * fb_height * 4); 8.39 } 8.40 + 8.41 +void Renderer::handle_keyboard(int key, bool press) 8.42 +{ 8.43 + switch(key) { 8.44 + case KB_ESC: 8.45 + deactivate_screen(); 8.46 + break; 8.47 + 8.48 + } 8.49 +}
9.1 --- a/src/renderer.h Sat Apr 12 23:37:55 2014 +0300 9.2 +++ b/src/renderer.h Sun Apr 13 08:06:21 2014 +0300 9.3 @@ -3,11 +3,21 @@ 9.4 9.5 #include "screen.h" 9.6 9.7 +struct RendererImpl; 9.8 + 9.9 class Renderer : public Screen { 9.10 +private: 9.11 + RendererImpl *rend; 9.12 + 9.13 public: 9.14 Renderer(); 9.15 9.16 + bool init(); 9.17 + void shutdown(); 9.18 + 9.19 void draw() const; 9.20 + 9.21 + void handle_keyboard(int key, bool press); 9.22 }; 9.23 9.24 #endif // RENDERER_H_
10.1 --- a/src/scene.cc Sat Apr 12 23:37:55 2014 +0300 10.2 +++ b/src/scene.cc Sun Apr 13 08:06:21 2014 +0300 10.3 @@ -142,8 +142,7 @@ 10.4 } 10.5 } 10.6 10.7 - m3d_color(1, 1, selected ? 0.25 : 1); 10.8 - nodes[i]->draw(); 10.9 + nodes[i]->draw(selected); 10.10 } 10.11 } 10.12
11.1 --- a/src/snode.cc Sat Apr 12 23:37:55 2014 +0300 11.2 +++ b/src/snode.cc Sun Apr 13 08:06:21 2014 +0300 11.3 @@ -1,6 +1,7 @@ 11.4 #include <string.h> 11.5 #include <assert.h> 11.6 #include "snode.h" 11.7 +#include "min3d.h" 11.8 11.9 11.10 SceneNode::SceneNode() 11.11 @@ -165,6 +166,8 @@ 11.12 // TODO: hierarchy 11.13 void SceneNode::calc_matrix() const 11.14 { 11.15 + if(xform_valid) return; 11.16 + 11.17 xform.set_identity(); 11.18 xform.translate(pivot.x, pivot.y, pivot.z); 11.19 xform = xform * rot.get_matrix(); 11.20 @@ -177,14 +180,52 @@ 11.21 11.22 void SceneNode::calc_inv_matrix() const 11.23 { 11.24 + if(inv_xform_valid) return; 11.25 + 11.26 calc_matrix(); 11.27 11.28 inv_xform = xform.inverse(); 11.29 inv_xform_valid = true; 11.30 } 11.31 11.32 -void SceneNode::draw() const 11.33 +void SceneNode::pre_draw() const 11.34 { 11.35 + m3d_matrix_mode(M3D_MODELVIEW); 11.36 + m3d_push_matrix(); 11.37 + m3d_mult_matrix(get_matrix()[0]); 11.38 +} 11.39 + 11.40 +void SceneNode::post_draw() const 11.41 +{ 11.42 + m3d_matrix_mode(M3D_MODELVIEW); 11.43 + m3d_pop_matrix(); 11.44 +} 11.45 + 11.46 +void SceneNode::draw(bool emph) const 11.47 +{ 11.48 + if(emph) { 11.49 + float avg_scale = (scale.x + scale.y + scale.z) / 3.0; 11.50 + m3d_push_matrix(); 11.51 + m3d_scale(avg_scale / scale.x, avg_scale / scale.y, avg_scale / scale.z); 11.52 + 11.53 + m3d_begin(M3D_LINES); 11.54 + m3d_color(1, 0, 0); 11.55 + m3d_vertex(0, 0, 0); 11.56 + m3d_vertex(0.5, 0, 0); 11.57 + m3d_color(0, 1, 0); 11.58 + m3d_vertex(0, 0, 0); 11.59 + m3d_vertex(0, 0.5, 0); 11.60 + m3d_color(0, 0, 1); 11.61 + m3d_vertex(0, 0, 0); 11.62 + m3d_vertex(0, 0, 0.5); 11.63 + m3d_end(); 11.64 + 11.65 + m3d_pop_matrix(); 11.66 + 11.67 + m3d_color(1, 0.8, 0.1); 11.68 + } else { 11.69 + m3d_color(0.9, 0.9, 0.9); 11.70 + } 11.71 } 11.72 11.73 bool SceneNode::intersect(const Ray &ray, float *dist) const
12.1 --- a/src/snode.h Sat Apr 12 23:37:55 2014 +0300 12.2 +++ b/src/snode.h Sun Apr 13 08:06:21 2014 +0300 12.3 @@ -37,6 +37,9 @@ 12.4 virtual void calc_matrix() const; 12.5 virtual void calc_inv_matrix() const; 12.6 12.7 + virtual void pre_draw() const; 12.8 + virtual void post_draw() const; 12.9 + 12.10 public: 12.11 SceneNode(); 12.12 virtual ~SceneNode(); 12.13 @@ -77,7 +80,7 @@ 12.14 virtual const Matrix4x4 &get_matrix() const; 12.15 virtual const Matrix4x4 &get_inv_matrix() const; 12.16 12.17 - virtual void draw() const; 12.18 + virtual void draw(bool emph = false) const; 12.19 12.20 virtual bool intersect(const Ray &ray, float *dist = 0) const; 12.21 };
13.1 --- a/src/vmathray.h Sat Apr 12 23:37:55 2014 +0300 13.2 +++ b/src/vmathray.h Sun Apr 13 08:06:21 2014 +0300 13.3 @@ -6,10 +6,10 @@ 13.4 13.5 class Ray { 13.6 public: 13.7 - Vector3 pos, dir; 13.8 + Vector3 origin, dir; 13.9 13.10 Ray() {} 13.11 - Ray(const Vector3 &p, const Vector3 &d) : pos(p), dir(d) {} 13.12 + Ray(const Vector3 &p, const Vector3 &d) : origin(p), dir(d) {} 13.13 }; 13.14 13.15 inline Ray transform(const Matrix4x4 &m, const Ray &r) 13.16 @@ -18,7 +18,7 @@ 13.17 rmat[0][3] = rmat[1][3] = rmat[2][3] = rmat[3][0] = rmat[3][1] = rmat[3][2] = 0.0; 13.18 rmat[3][3] = 1.0; 13.19 13.20 - return Ray(transform(m, r.pos), transform(rmat, r.dir)); 13.21 + return Ray(transform(m, r.origin), transform(rmat, r.dir)); 13.22 } 13.23 13.24 #endif // VMATH_RAY_H_