rayzor
view src/renderer.cc @ 15:be616b58df99
continued the renderer slightly
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sun, 13 Apr 2014 09:54:36 +0300 |
parents | a9a948809c6f |
children | 79609d482762 |
line source
1 #include <string.h>
2 #include "renderer.h"
3 #include "rayzor.h"
4 #include "scene.h"
5 #include "keyb.h"
6 #include "scrman.h"
7 #include "timer.h"
8 #include "logger.h"
10 struct RendererImpl {
11 bool in_progress;
12 int cur_x, cur_y; // current pixel being rendered
14 uint32_t *pixels;
16 MsgAtom msg_start;
17 };
20 static Vector3 ray_trace(const Ray &ray, int iter = 0);
21 static Vector3 shade(const Ray &ray, float t, int iter);
24 Renderer::Renderer()
25 {
26 set_name("renderer");
27 }
29 bool Renderer::init()
30 {
31 rend = new RendererImpl;
32 memset(rend, 0, sizeof *rend);
34 rend->pixels = new uint32_t[fb_width * fb_height];
35 if(!rend->pixels) {
36 return false;
37 }
38 memset(rend->pixels, 0, fb_width * fb_height * 4);
40 rend->msg_start = message_atom("start");
42 return true;
43 }
45 void Renderer::shutdown()
46 {
47 if(rend) {
48 delete [] rend->pixels;
49 delete rend;
50 rend = 0;
51 }
52 }
54 void Renderer::draw() const
55 {
56 Camera *cam = scene->get_active_camera();
58 // if a rendering is not in progress, just show the last buffer
59 if(!rend->in_progress || !cam) {
60 memcpy(fb_pixels, rend->pixels, fb_width * fb_height * 4);
61 return;
62 }
64 // render for approximately half a second, then show and return
65 unsigned long start = get_msec();
66 uint32_t *dest = rend->pixels + rend->cur_y * fb_width + rend->cur_x;
68 for(;;) {
69 Ray ray = cam->get_primary_ray(rend->cur_x, rend->cur_y);
70 Vector3 color = ray_trace(ray);
72 int r = color.x > 1.0 ? 255 : (int)(color.x * 255.0);
73 int g = color.y > 1.0 ? 255 : (int)(color.y * 255.0);
74 int b = color.z > 1.0 ? 255 : (int)(color.z * 255.0);
76 *dest++ = (r << 16) | (g << 8) | b;
78 if(++rend->cur_x >= fb_width) {
79 rend->cur_x = 0;
80 if(++rend->cur_y >= fb_height) {
81 rend->in_progress = false;
82 printlog("done!\n");
83 break;
84 }
85 }
87 if(get_msec() - start >= 500) {
88 break;
89 }
90 }
92 memcpy(fb_pixels, rend->pixels, fb_width * fb_height * 4);
93 }
95 void Renderer::handle_keyboard(int key, bool press)
96 {
97 switch(key) {
98 case KB_ESC:
99 deactivate_screen();
100 break;
102 default:
103 break;
104 }
105 }
107 void Renderer::message(MsgAtom msg)
108 {
109 if(msg == rend->msg_start) {
110 rend->cur_x = rend->cur_y = 0;
111 rend->in_progress = true;
112 memset(rend->pixels, 0, fb_width * fb_height * 4);
114 printlog("starting a new rendering!\n");
115 }
116 }
119 static Vector3 ray_trace(const Ray &ray, int iter)
120 {
121 return shade(ray, 0, iter);
122 }
124 static Vector3 shade(const Ray &ray, float t, int iter)
125 {
126 return Vector3(1.0, 0.0, 0.0);
127 }