# HG changeset patch # User John Tsiombikas # Date 1397372076 -10800 # Node ID be616b58df99833026a225fda1545a8c3037e05d # Parent a9a948809c6ff99469bcbd495cacc39a516def8c continued the renderer slightly diff -r a9a948809c6f -r be616b58df99 GNUmakefile --- a/GNUmakefile Sun Apr 13 08:06:21 2014 +0300 +++ b/GNUmakefile Sun Apr 13 09:54:36 2014 +0300 @@ -1,4 +1,4 @@ -baseobj = src/main.o src/logger.o src/screen.o src/scrman.o +baseobj = src/main.o src/logger.o src/screen.o src/scrman.o src/rbtree.o modelobj = src/modeller.o src/min3d.o src/m3drast.o src/lines.o rendobj = src/renderer.o src/vmath.o scnobj = src/scene.o src/object.o src/light.o src/camera.o src/snode.o diff -r a9a948809c6f -r be616b58df99 Makefile --- a/Makefile Sun Apr 13 08:06:21 2014 +0300 +++ b/Makefile Sun Apr 13 09:54:36 2014 +0300 @@ -1,4 +1,4 @@ -baseobj = main.obj logger.obj screen.obj scrman.obj swapbuf.obj +baseobj = main.obj logger.obj screen.obj scrman.obj swapbuf.obj rbtree.obj modelobj = modeller.obj min3d.obj m3drast.obj lines.obj rendobj = renderer.obj vmath.obj scnobj = scene.obj object.obj light.obj camera.obj snode.obj diff -r a9a948809c6f -r be616b58df99 src/camera.cc --- a/src/camera.cc Sun Apr 13 08:06:21 2014 +0300 +++ b/src/camera.cc Sun Apr 13 09:54:36 2014 +0300 @@ -1,9 +1,10 @@ #include "camera.h" +#include "rayzor.h" Camera::Camera() { type = NODE_CAMERA; - fov = M_PI; + fov = M_PI / 4.0; set_position(Vector3(0, 0, 10)); } @@ -29,14 +30,11 @@ void Camera::calc_matrix() const { - xform.set_identity(); - xform.lookat(pos, target.get_position(), Vector3(0, 1, 0)); - xform_valid = true; -} - -void Camera::calc_inv_matrix() const -{ - // TODO + if(!xform_valid) { + xform.set_identity(); + xform.lookat(pos, target.get_position(), Vector3(0, 1, 0)); + xform_valid = true; + } } void Camera::draw() const @@ -47,3 +45,20 @@ { return false; } + +Ray Camera::get_primary_ray(int x, int y) const +{ + calc_inv_matrix(); + + float aspect = (float)fb_width / (float)fb_height; + float pwidth = 2.0 * aspect / (float)fb_width; + float pheight = 2.0 / (float)fb_height; + + Vector3 dir; + dir.x = (float)x * pwidth - aspect; + dir.y = 1.0 - (float)y * pheight; + dir.z = -1.0 / tan(fov / 2.0); + dir.normalize(); + + return transform(inv_xform, Ray(Vector3(0, 0, 0), dir)); +} diff -r a9a948809c6f -r be616b58df99 src/camera.h --- a/src/camera.h Sun Apr 13 08:06:21 2014 +0300 +++ b/src/camera.h Sun Apr 13 09:54:36 2014 +0300 @@ -10,7 +10,6 @@ float fov; void calc_matrix() const; - void calc_inv_matrix() const; public: Camera(); @@ -24,6 +23,8 @@ void draw() const; bool intersect(const Ray &ray, float *dist = 0) const; + + Ray get_primary_ray(int x, int y) const; }; #endif // CAMERA_H_ diff -r a9a948809c6f -r be616b58df99 src/inttypes.h --- a/src/inttypes.h Sun Apr 13 08:06:21 2014 +0300 +++ b/src/inttypes.h Sun Apr 13 09:54:36 2014 +0300 @@ -9,6 +9,8 @@ typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned long uint32_t; + +typedef unsigned long intptr_t; #else #include #endif diff -r a9a948809c6f -r be616b58df99 src/modeller.cc --- a/src/modeller.cc Sun Apr 13 08:06:21 2014 +0300 +++ b/src/modeller.cc Sun Apr 13 09:54:36 2014 +0300 @@ -12,6 +12,7 @@ struct ModellerImpl { int mx, my; float cam_theta, cam_phi, cam_dist; + Camera *viewport_cam; struct m3d_image rbuf; @@ -36,6 +37,8 @@ mod = new ModellerImpl; memset(mod, 0, sizeof *mod); + mod->viewport_cam = new Camera; + mod->cam_phi = 25; mod->cam_dist = 5; @@ -138,11 +141,28 @@ break; case 'r': - case 'R': + case 'p': if(kb_isdown(KB_ALT) || kb_isdown(KB_CTRL)) { + case KB_F5: + case KB_F6: Screen *rs = get_screen("renderer"); if(rs) { activate_screen(rs); + + if(key == 'r' || key == KB_F5) { + // start a rendering, and make sure there is a camera + if(!scene->get_active_camera()) { + scene->set_active_camera(mod->viewport_cam); + } + Vector3 dir; + dir.x = sin(DEG2RAD(mod->cam_theta)) * cos(DEG2RAD(mod->cam_phi)) * mod->cam_dist; + dir.y = sin(DEG2RAD(mod->cam_phi)); + dir.z = cos(DEG2RAD(mod->cam_theta)) * cos(DEG2RAD(mod->cam_phi)) * mod->cam_dist; + mod->viewport_cam->set_position(dir); + mod->viewport_cam->set_target(Vector3(0, 0, 0)); + + rs->message(message_atom("start")); + } } else { printlog("failed to find renderer screen!\n"); } diff -r a9a948809c6f -r be616b58df99 src/renderer.cc --- a/src/renderer.cc Sun Apr 13 08:06:21 2014 +0300 +++ b/src/renderer.cc Sun Apr 13 09:54:36 2014 +0300 @@ -1,15 +1,26 @@ #include #include "renderer.h" #include "rayzor.h" +#include "scene.h" #include "keyb.h" #include "scrman.h" +#include "timer.h" +#include "logger.h" struct RendererImpl { bool in_progress; int cur_x, cur_y; // current pixel being rendered - int cur_pix; // current pixel (linear) + + uint32_t *pixels; + + MsgAtom msg_start; }; + +static Vector3 ray_trace(const Ray &ray, int iter = 0); +static Vector3 shade(const Ray &ray, float t, int iter); + + Renderer::Renderer() { set_name("renderer"); @@ -19,12 +30,22 @@ { rend = new RendererImpl; memset(rend, 0, sizeof *rend); + + rend->pixels = new uint32_t[fb_width * fb_height]; + if(!rend->pixels) { + return false; + } + memset(rend->pixels, 0, fb_width * fb_height * 4); + + rend->msg_start = message_atom("start"); + return true; } void Renderer::shutdown() { if(rend) { + delete [] rend->pixels; delete rend; rend = 0; } @@ -32,7 +53,43 @@ void Renderer::draw() const { - memset(fb_pixels, 0, fb_width * fb_height * 4); + Camera *cam = scene->get_active_camera(); + + // if a rendering is not in progress, just show the last buffer + if(!rend->in_progress || !cam) { + memcpy(fb_pixels, rend->pixels, fb_width * fb_height * 4); + return; + } + + // render for approximately half a second, then show and return + unsigned long start = get_msec(); + uint32_t *dest = rend->pixels + rend->cur_y * fb_width + rend->cur_x; + + for(;;) { + Ray ray = cam->get_primary_ray(rend->cur_x, rend->cur_y); + Vector3 color = ray_trace(ray); + + int r = color.x > 1.0 ? 255 : (int)(color.x * 255.0); + int g = color.y > 1.0 ? 255 : (int)(color.y * 255.0); + int b = color.z > 1.0 ? 255 : (int)(color.z * 255.0); + + *dest++ = (r << 16) | (g << 8) | b; + + if(++rend->cur_x >= fb_width) { + rend->cur_x = 0; + if(++rend->cur_y >= fb_height) { + rend->in_progress = false; + printlog("done!\n"); + break; + } + } + + if(get_msec() - start >= 500) { + break; + } + } + + memcpy(fb_pixels, rend->pixels, fb_width * fb_height * 4); } void Renderer::handle_keyboard(int key, bool press) @@ -42,5 +99,29 @@ deactivate_screen(); break; + default: + break; } } + +void Renderer::message(MsgAtom msg) +{ + if(msg == rend->msg_start) { + rend->cur_x = rend->cur_y = 0; + rend->in_progress = true; + memset(rend->pixels, 0, fb_width * fb_height * 4); + + printlog("starting a new rendering!\n"); + } +} + + +static Vector3 ray_trace(const Ray &ray, int iter) +{ + return shade(ray, 0, iter); +} + +static Vector3 shade(const Ray &ray, float t, int iter) +{ + return Vector3(1.0, 0.0, 0.0); +} diff -r a9a948809c6f -r be616b58df99 src/renderer.h --- a/src/renderer.h Sun Apr 13 08:06:21 2014 +0300 +++ b/src/renderer.h Sun Apr 13 09:54:36 2014 +0300 @@ -18,6 +18,8 @@ void draw() const; void handle_keyboard(int key, bool press); + + void message(MsgAtom msg); }; #endif // RENDERER_H_ diff -r a9a948809c6f -r be616b58df99 src/scene.cc --- a/src/scene.cc Sun Apr 13 08:06:21 2014 +0300 +++ b/src/scene.cc Sun Apr 13 09:54:36 2014 +0300 @@ -125,6 +125,16 @@ return cameras[idx]; } +void Scene::set_active_camera(Camera *cam) +{ + active_cam = cam; +} + +Camera *Scene::get_active_camera() const +{ + return active_cam; +} + void Scene::draw() const { if(active_cam) { diff -r a9a948809c6f -r be616b58df99 src/scene.h --- a/src/scene.h Sun Apr 13 08:06:21 2014 +0300 +++ b/src/scene.h Sun Apr 13 09:54:36 2014 +0300 @@ -45,6 +45,9 @@ Camera *get_camera(int idx); const Camera *get_camera(int idx) const; + void set_active_camera(Camera *cam); + Camera *get_active_camera() const; + void draw() const; void select(int s); diff -r a9a948809c6f -r be616b58df99 src/screen.cc --- a/src/screen.cc Sun Apr 13 08:06:21 2014 +0300 +++ b/src/screen.cc Sun Apr 13 09:54:36 2014 +0300 @@ -1,5 +1,35 @@ +#include #include #include "screen.h" +#include "rbtree.h" +#include "logger.h" + +MsgAtom message_atom(const char *str) +{ + static struct rbtree *atoms; + static MsgAtom last_atom; + struct rbnode *node; + MsgAtom atom; + + if(!atoms) { + if(!(atoms = rb_create(RB_KEY_STRING))) { + printlog("fatal: message_atom failed to create symbol table\n"); + abort(); + } + } + + if((node = rb_find(atoms, (void*)str))) { + return *(MsgAtom*)&node->data; + } + + atom = ++last_atom; + if(rb_insert(atoms, (void*)str, (void*)atom) == -1) { + printlog("message_atom failed to insert new atom\n"); + --last_atom; + return -1; + } + return atom; +} Screen::Screen() { @@ -47,3 +77,7 @@ void Screen::handle_mmotion(int x, int y) { } + +void Screen::message(MsgAtom ma) +{ +} diff -r a9a948809c6f -r be616b58df99 src/screen.h --- a/src/screen.h Sun Apr 13 08:06:21 2014 +0300 +++ b/src/screen.h Sun Apr 13 09:54:36 2014 +0300 @@ -1,6 +1,10 @@ #ifndef SCREEN_H_ #define SCREEN_H_ +typedef int MsgAtom; + +MsgAtom message_atom(const char *str); + class Screen { private: char *name; @@ -21,6 +25,8 @@ virtual void handle_keyboard(int key, bool press); virtual void handle_mbutton(int bn, bool press, int x, int y); virtual void handle_mmotion(int x, int y); + + virtual void message(MsgAtom ma); }; #endif // SCREEN_H_ diff -r a9a948809c6f -r be616b58df99 src/vmath.h --- a/src/vmath.h Sun Apr 13 08:06:21 2014 +0300 +++ b/src/vmath.h Sun Apr 13 09:54:36 2014 +0300 @@ -4,6 +4,9 @@ #include #include "vmathmat.h" +#define DEG2RAD(x) (M_PI * (x) / 180.0) +#define RAD2DEG(x) (180.0 * (x) / M_PI) + class Vector3 { public: float x, y, z;