9 #include <pthread.h> |
9 #include <pthread.h> |
10 #endif |
10 #endif |
11 |
11 |
12 #include <stdio.h> |
12 #include <stdio.h> |
13 #include <malloc.h> |
13 #include <malloc.h> |
14 #include "common.h" |
|
15 #include "raytracer.h" |
14 #include "raytracer.h" |
16 |
15 |
17 // Hammersley spherical point distribution |
16 // Hammersley spherical point distribution |
18 // http://www.cse.cuhk.edu.hk/~ttwong/papers/udpoint/udpoints.html |
17 // http://www.cse.cuhk.edu.hk/~ttwong/papers/udpoint/udpoints.html |
19 Vector3 Raytracer::SphereDistribute(int i, int n, float extent, Vector3 &normal) |
18 Vector3 Raytracer::SphereDistribute(int i, int n, float extent, Vector3 &normal) |
193 pthread_exit((void *)d); |
192 pthread_exit((void *)d); |
194 #endif |
193 #endif |
195 return (void *)d; |
194 return (void *)d; |
196 } |
195 } |
197 |
196 |
198 float *Raytracer::render(int w, int h) |
197 void Raytracer::render(int w, int h, float *buffer) |
199 { |
198 { |
200 if (!camera || !top) |
199 if (!camera || !top || !buffer) |
201 return NULL; |
200 return; |
202 |
|
203 float *data; |
|
204 |
|
205 data = (float *) malloc(w*h*3*sizeof(float)); |
|
206 if (!data) |
|
207 return NULL; |
|
208 |
201 |
209 RenderrowData *d; |
202 RenderrowData *d; |
210 |
|
211 printf("* building kd-tree\n"); |
|
212 top->optimize(); |
|
213 |
203 |
214 float S = 0.5/w; |
204 float S = 0.5/w; |
215 Vector3 dfix = camera->u*(-w/2.0*S/camera->f) |
205 Vector3 dfix = camera->u*(-w/2.0*S/camera->f) |
216 + camera->v*(h/2.0*S/camera->f) + camera->p; |
206 + camera->v*(h/2.0*S/camera->f) + camera->p; |
217 Vector3 dx = camera->u * (S/camera->f); |
207 Vector3 dx = camera->u * (S/camera->f); |
218 Vector3 dy = camera->v * (-S/camera->f); |
208 Vector3 dy = camera->v * (-S/camera->f); |
219 |
209 |
220 #ifdef PTHREADS |
210 #ifdef PTHREADS |
221 printf("* pthreads enabled, using %d threads\n", num_threads); |
211 infomsg("* pthreads enabled, using %d threads\n", num_threads); |
222 pthread_t threads[num_threads]; |
212 pthread_t threads[num_threads]; |
223 for (int t = 0; t < num_threads; t++) |
213 for (int t = 0; t < num_threads; t++) |
224 threads[t] = pthread_self(); |
214 threads[t] = pthread_self(); |
225 int t = 0; |
215 int t = 0; |
226 #endif |
216 #endif |
227 |
217 |
228 /* for each pixel... */ |
218 /* for each pixel... */ |
229 printf("* rendering row 0 ( 0%% done)"); |
219 infomsg("* rendering row 0 ( 0%% done)"); |
230 for (int y = 0; y < h; y++) { |
220 for (int y = 0; y < h; y++) |
|
221 { |
231 d = (RenderrowData*) malloc(sizeof(RenderrowData)); |
222 d = (RenderrowData*) malloc(sizeof(RenderrowData)); |
232 d->rt = this; |
223 d->rt = this; |
233 d->w = w; |
224 d->w = w; |
234 d->eye = camera->eye; |
225 d->eye = camera->eye; |
235 d->dfix = dfix; |
226 d->dfix = dfix; |
236 d->dx = dx; |
227 d->dx = dx; |
237 #if OVERSAMPLING |
228 #if OVERSAMPLING |
238 d->dy = dy; |
229 d->dy = dy; |
239 #endif |
230 #endif |
240 d->iter = data + y*3*w; |
231 d->iter = buffer + y*3*w; |
241 #ifdef PTHREADS |
232 #ifdef PTHREADS |
242 /* create new thread and increase 't' */ |
233 /* create new thread and increase 't' */ |
243 int rc = pthread_create(&threads[t++], NULL, renderrow, (void *)d); |
234 int rc = pthread_create(&threads[t++], NULL, renderrow, (void *)d); |
244 if (rc) { |
235 if (rc) { |
245 printf("\nERROR: return code from pthread_create() is %d\n", rc); |
236 infomsg("\nERROR: return code from pthread_create() is %d\n", rc); |
246 exit(1); |
237 exit(1); |
247 } |
238 } |
248 /* when 't' owerflows, reset it */ |
239 /* when 't' owerflows, reset it */ |
249 if (t >= num_threads) |
240 if (t >= num_threads) |
250 t = 0; |
241 t = 0; |
256 #else |
247 #else |
257 renderrow((void *)d); |
248 renderrow((void *)d); |
258 free(d); |
249 free(d); |
259 #endif |
250 #endif |
260 dfix += dy; |
251 dfix += dy; |
261 printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b%4d (%2d%% done)", y, y*100/(h-1)); |
252 infomsg("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b%4d (%2d%% done)", y, y*100/(h-1)); |
262 } |
253 } |
263 printf("\n"); |
254 infomsg("\n"); |
264 |
255 |
265 #ifdef PTHREADS |
256 #ifdef PTHREADS |
266 printf("* waiting for threads to finish\n"); |
257 infomsg("* waiting for threads to finish\n"); |
267 for (t = 0; t < num_threads; t++) |
258 for (t = 0; t < num_threads; t++) |
268 if (pthread_join(threads[t], (void**)&d) == 0) |
259 if (pthread_join(threads[t], (void**)&d) == 0) |
269 free(d); |
260 free(d); |
270 #endif |
261 #endif |
271 |
|
272 return data; |
|
273 } |
262 } |
274 |
263 |
275 void Raytracer::addlight(Light *light) |
264 void Raytracer::addlight(Light *light) |
276 { |
265 { |
277 lights.push_back(light); |
266 lights.push_back(light); |