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