# HG changeset patch # User John Tsiombikas # Date 1397365581 -10800 # Node ID a9a948809c6ff99469bcbd495cacc39a516def8c # Parent 964f8ea5f095dbd26efdcc38cc92b53b5850efb4 starting the renderer screen, plus misc stuff diff -r 964f8ea5f095 -r a9a948809c6f src/dosemu/direct.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/dosemu/direct.h Sun Apr 13 08:06:21 2014 +0300 @@ -0,0 +1,2 @@ +/* watcom has opendir/readdir in direct.h instead of dirent.h for some reason */ +#include diff -r 964f8ea5f095 -r a9a948809c6f src/dosemu/dosemu.c --- a/src/dosemu/dosemu.c Sat Apr 12 23:37:55 2014 +0300 +++ b/src/dosemu/dosemu.c Sun Apr 13 08:06:21 2014 +0300 @@ -508,10 +508,7 @@ static int translate_sdlkey(int sym) { - if(sym >= 0 && sym < 256) { - return sdlkey_tbl[sym]; - } - return sym; + return sdlkey_tbl[sym]; } static void update_modkeys(void) diff -r 964f8ea5f095 -r a9a948809c6f src/main.cc --- a/src/main.cc Sat Apr 12 23:37:55 2014 +0300 +++ b/src/main.cc Sun Apr 13 08:06:21 2014 +0300 @@ -2,6 +2,8 @@ #include #include #include +#include +#include #include "inttypes.h" #include "gfx.h" #include "keyb.h" @@ -29,6 +31,7 @@ static void display(); static void swap_buffers(); static void draw_cursor(uint32_t *buf, int mx, int my); +static void screenshot(); static void handle_keyboard(); static void handle_mouse(); static bool parse_args(int argc, char **argv); @@ -50,6 +53,7 @@ static bool use_mouse; static int mouse_x, mouse_y; static bool quit; +static bool cap_shot; int main(int argc, char **argv) { @@ -188,6 +192,11 @@ draw_cursor(fb_pixels, mouse_x, mouse_y); } + if(cap_shot) { + screenshot(); + cap_shot = false; + } + if(!novideo) { wait_vsync(); #ifdef USE_ASM_SWAPBUF @@ -279,6 +288,51 @@ } } +#define PPM_COMMENT "screenshot saved by the rayzor modeller/renderer" +static void screenshot() +{ + static int shotidx = -1; + FILE *fp; + char fname[PATH_MAX]; + + if(shotidx == -1) { + DIR *dir; + struct dirent *dent; + + shotidx = 0; + if((dir = opendir("."))) { + while((dent = readdir(dir))) { + int i, num; + for(i=0; dent->d_name[i]; i++) { + fname[i] = tolower(dent->d_name[i]); + } + fname[i] = 0; + + if(sscanf(fname, "shot%d.ppm", &num) == 1 && num > shotidx) { + shotidx = num; + } + } + closedir(dir); + } + } + + sprintf(fname, "shot%04d.ppm", ++shotidx); + if(!(fp = fopen(fname, "wb"))) { + printlog("failed to save screenshot %s: %s\n", fname, strerror(errno)); + return; + } + + fprintf(fp, "P6\n" PPM_COMMENT "\n%d %d\n255\n", fb_width, fb_height); + for(int i=0; i #include "object.h" #include "vmath.h" #include "min3d.h" @@ -12,18 +13,6 @@ { } -void Object::pre_draw() const -{ - m3d_matrix_mode(M3D_MODELVIEW); - m3d_push_matrix(); - m3d_mult_matrix(get_matrix()[0]); -} - -void Object::post_draw() const -{ - m3d_pop_matrix(); -} - // ---- sphere ---- Sphere::Sphere() { @@ -36,7 +25,7 @@ #define USUB 12 #define VSUB 6 -void Sphere::draw() const +void Sphere::draw(bool emph) const { static Vector3 *varr; static unsigned int *iarr; @@ -85,6 +74,7 @@ } pre_draw(); + SceneNode::draw(emph); m3d_vertex_array(&varr->x); m3d_draw_indexed(M3D_QUADS, iarr, num_indices); @@ -93,9 +83,36 @@ post_draw(); } -bool Sphere::intersect(const Ray &ray, float *dist) const +bool Sphere::intersect(const Ray &wray, float *dist) const { - return false; // TODO + Ray ray = transform(get_inv_matrix(), wray); + + // assumes center is 0,0,0, and radius is 1 + float a = dot(ray.dir, ray.dir); + float b = 2.0 * ray.dir.x * ray.origin.x + + 2.0 * ray.dir.y * ray.origin.y + + 2.0 * ray.dir.z * ray.origin.z; + float c = dot(ray.origin, ray.origin) - 1.0; + + float discr = b * b - 4.0 * a * c; + if(discr < 1e-4) + return false; + + float sqrt_discr = sqrt(discr); + float t0 = (-b + sqrt_discr) / (2.0 * a); + float t1 = (-b - sqrt_discr) / (2.0 * a); + + if(t0 < 1e-4) + t0 = t1; + if(t1 < 1e-4) + t1 = t0; + + float t = t0 < t1 ? t0 : t1; + if(t < 1e-4) + return false; + + if(dist) *dist = t; + return true; } // ---- box ---- @@ -117,7 +134,7 @@ 4------------5 */ -void Box::draw() const +void Box::draw(bool emph) const { static const float verts[] = { -1, 1, 1, @@ -139,6 +156,7 @@ }; pre_draw(); + SceneNode::draw(emph); m3d_vertex_array(verts); m3d_draw_indexed(M3D_QUADS, indices, sizeof indices / sizeof *indices); diff -r 964f8ea5f095 -r a9a948809c6f src/object.h --- a/src/object.h Sat Apr 12 23:37:55 2014 +0300 +++ b/src/object.h Sun Apr 13 08:06:21 2014 +0300 @@ -5,10 +5,6 @@ #include "snode.h" class Object : public SceneNode { -protected: - void pre_draw() const; - void post_draw() const; - public: Object(); virtual ~Object(); @@ -19,7 +15,7 @@ Sphere(); ~Sphere(); - void draw() const; + void draw(bool emph = false) const; bool intersect(const Ray &ray, float *dist = 0) const; }; @@ -29,7 +25,7 @@ Box(); ~Box(); - void draw() const; + void draw(bool emph = false) const; bool intersect(const Ray &ray, float *dist = 0) const; }; diff -r 964f8ea5f095 -r a9a948809c6f src/rayzor.h --- a/src/rayzor.h Sat Apr 12 23:37:55 2014 +0300 +++ b/src/rayzor.h Sun Apr 13 08:06:21 2014 +0300 @@ -1,6 +1,8 @@ #ifndef RAYZOR_H_ #define RAYZOR_H_ +#include "inttypes.h" + // global framebuffer (back buffer) extern uint32_t *fb_pixels; extern int fb_width, fb_height; diff -r 964f8ea5f095 -r a9a948809c6f src/renderer.cc --- a/src/renderer.cc Sat Apr 12 23:37:55 2014 +0300 +++ b/src/renderer.cc Sun Apr 13 08:06:21 2014 +0300 @@ -1,10 +1,46 @@ +#include #include "renderer.h" +#include "rayzor.h" +#include "keyb.h" +#include "scrman.h" + +struct RendererImpl { + bool in_progress; + int cur_x, cur_y; // current pixel being rendered + int cur_pix; // current pixel (linear) +}; Renderer::Renderer() { set_name("renderer"); } +bool Renderer::init() +{ + rend = new RendererImpl; + memset(rend, 0, sizeof *rend); + return true; +} + +void Renderer::shutdown() +{ + if(rend) { + delete rend; + rend = 0; + } +} + void Renderer::draw() const { + memset(fb_pixels, 0, fb_width * fb_height * 4); } + +void Renderer::handle_keyboard(int key, bool press) +{ + switch(key) { + case KB_ESC: + deactivate_screen(); + break; + + } +} diff -r 964f8ea5f095 -r a9a948809c6f src/renderer.h --- a/src/renderer.h Sat Apr 12 23:37:55 2014 +0300 +++ b/src/renderer.h Sun Apr 13 08:06:21 2014 +0300 @@ -3,11 +3,21 @@ #include "screen.h" +struct RendererImpl; + class Renderer : public Screen { +private: + RendererImpl *rend; + public: Renderer(); + bool init(); + void shutdown(); + void draw() const; + + void handle_keyboard(int key, bool press); }; #endif // RENDERER_H_ diff -r 964f8ea5f095 -r a9a948809c6f src/scene.cc --- a/src/scene.cc Sat Apr 12 23:37:55 2014 +0300 +++ b/src/scene.cc Sun Apr 13 08:06:21 2014 +0300 @@ -142,8 +142,7 @@ } } - m3d_color(1, 1, selected ? 0.25 : 1); - nodes[i]->draw(); + nodes[i]->draw(selected); } } diff -r 964f8ea5f095 -r a9a948809c6f src/snode.cc --- a/src/snode.cc Sat Apr 12 23:37:55 2014 +0300 +++ b/src/snode.cc Sun Apr 13 08:06:21 2014 +0300 @@ -1,6 +1,7 @@ #include #include #include "snode.h" +#include "min3d.h" SceneNode::SceneNode() @@ -165,6 +166,8 @@ // TODO: hierarchy void SceneNode::calc_matrix() const { + if(xform_valid) return; + xform.set_identity(); xform.translate(pivot.x, pivot.y, pivot.z); xform = xform * rot.get_matrix(); @@ -177,14 +180,52 @@ void SceneNode::calc_inv_matrix() const { + if(inv_xform_valid) return; + calc_matrix(); inv_xform = xform.inverse(); inv_xform_valid = true; } -void SceneNode::draw() const +void SceneNode::pre_draw() const { + m3d_matrix_mode(M3D_MODELVIEW); + m3d_push_matrix(); + m3d_mult_matrix(get_matrix()[0]); +} + +void SceneNode::post_draw() const +{ + m3d_matrix_mode(M3D_MODELVIEW); + m3d_pop_matrix(); +} + +void SceneNode::draw(bool emph) const +{ + if(emph) { + float avg_scale = (scale.x + scale.y + scale.z) / 3.0; + m3d_push_matrix(); + m3d_scale(avg_scale / scale.x, avg_scale / scale.y, avg_scale / scale.z); + + m3d_begin(M3D_LINES); + m3d_color(1, 0, 0); + m3d_vertex(0, 0, 0); + m3d_vertex(0.5, 0, 0); + m3d_color(0, 1, 0); + m3d_vertex(0, 0, 0); + m3d_vertex(0, 0.5, 0); + m3d_color(0, 0, 1); + m3d_vertex(0, 0, 0); + m3d_vertex(0, 0, 0.5); + m3d_end(); + + m3d_pop_matrix(); + + m3d_color(1, 0.8, 0.1); + } else { + m3d_color(0.9, 0.9, 0.9); + } } bool SceneNode::intersect(const Ray &ray, float *dist) const diff -r 964f8ea5f095 -r a9a948809c6f src/snode.h --- a/src/snode.h Sat Apr 12 23:37:55 2014 +0300 +++ b/src/snode.h Sun Apr 13 08:06:21 2014 +0300 @@ -37,6 +37,9 @@ virtual void calc_matrix() const; virtual void calc_inv_matrix() const; + virtual void pre_draw() const; + virtual void post_draw() const; + public: SceneNode(); virtual ~SceneNode(); @@ -77,7 +80,7 @@ virtual const Matrix4x4 &get_matrix() const; virtual const Matrix4x4 &get_inv_matrix() const; - virtual void draw() const; + virtual void draw(bool emph = false) const; virtual bool intersect(const Ray &ray, float *dist = 0) const; }; diff -r 964f8ea5f095 -r a9a948809c6f src/vmathray.h --- a/src/vmathray.h Sat Apr 12 23:37:55 2014 +0300 +++ b/src/vmathray.h Sun Apr 13 08:06:21 2014 +0300 @@ -6,10 +6,10 @@ class Ray { public: - Vector3 pos, dir; + Vector3 origin, dir; Ray() {} - Ray(const Vector3 &p, const Vector3 &d) : pos(p), dir(d) {} + Ray(const Vector3 &p, const Vector3 &d) : origin(p), dir(d) {} }; inline Ray transform(const Matrix4x4 &m, const Ray &r) @@ -18,7 +18,7 @@ rmat[0][3] = rmat[1][3] = rmat[2][3] = rmat[3][0] = rmat[3][1] = rmat[3][2] = 0.0; rmat[3][3] = 1.0; - return Ray(transform(m, r.pos), transform(rmat, r.dir)); + return Ray(transform(m, r.origin), transform(rmat, r.dir)); } #endif // VMATH_RAY_H_