159 } |
159 } |
160 |
160 |
161 static void *renderrow(void *data) |
161 static void *renderrow(void *data) |
162 { |
162 { |
163 RenderrowData *d = (RenderrowData*) data; |
163 RenderrowData *d = (RenderrowData*) data; |
|
164 Vector3 dir = d->dfix; |
164 for (int x = 0; x < d->w; x++) { |
165 for (int x = 0; x < d->w; x++) { |
165 // generate a ray from eye passing through this pixel |
166 // generate a ray from eye passing through this pixel |
166 #if 1 |
167 #if OVERSAMPLING |
167 // no oversampling |
|
168 Vector3 dir = Vector3(d->vx, d->vy, 0) - d->eye; |
|
169 dir.normalize(); |
|
170 Ray ray(d->eye, dir); |
|
171 Colour c = d->rt->raytrace(ray, 0, NULL); |
|
172 #else |
|
173 // 5x oversampling |
168 // 5x oversampling |
174 Vector3 dir = Vector3(); |
|
175 Colour c = Colour(); |
169 Colour c = Colour(); |
176 |
170 |
177 for (int i = 0; i < 5; i++) |
171 for (int i = 0; i < 5; i++) |
178 { |
172 { |
179 float osax[] = {0.0, -0.4, +0.4, +0.4, -0.4}; |
173 float osax[] = {0.0, -0.4, +0.4, +0.4, -0.4}; |
180 float osay[] = {0.0, -0.4, -0.4, +0.4, +0.4}; |
174 float osay[] = {0.0, -0.4, -0.4, +0.4, +0.4}; |
181 dir = Vector3(d->vx + osax[i] * d->dx, |
175 Vector3 tmpdir = dir + osax[i]*d->dx + osay[i]*d->dy; |
182 d->vy + osay[i]*d->dy , 0) - d->eye; |
176 tmpdir.normalize(); |
183 dir.normalize(); |
177 Ray ray(d->eye, tmpdir); |
184 Ray ray(d->eye, dir); |
|
185 c += d->rt->raytrace(ray, 0, NULL); |
178 c += d->rt->raytrace(ray, 0, NULL); |
186 } |
179 } |
187 c = c * (1./5); |
180 c = c * (1./5); |
|
181 #else |
|
182 // no oversampling |
|
183 dir.normalize(); |
|
184 Ray ray(d->eye, dir); |
|
185 Colour c = d->rt->raytrace(ray, 0, NULL); |
188 #endif |
186 #endif |
189 *(d->iter++) = c.r; |
187 *(d->iter++) = c.r; |
190 *d->iter++ = c.g; |
188 *d->iter++ = c.g; |
191 *d->iter++ = c.b; |
189 *d->iter++ = c.b; |
192 d->vx += d->dx; |
190 dir += d->dx; |
193 } |
191 } |
194 #ifdef PTHREADS |
192 #ifdef PTHREADS |
195 pthread_exit((void *)d); |
193 pthread_exit((void *)d); |
196 #endif |
194 #endif |
197 return (void *)d; |
195 return (void *)d; |
198 } |
196 } |
199 |
197 |
200 float *Raytracer::render(int w, int h) |
198 float *Raytracer::render(int w, int h) |
201 { |
199 { |
|
200 if (!camera || !top) |
|
201 return NULL; |
|
202 |
202 float *data; |
203 float *data; |
203 |
204 |
204 data = (float *) malloc(w*h*3*sizeof(float)); |
205 data = (float *) malloc(w*h*3*sizeof(float)); |
205 if (!data) |
206 if (!data) |
206 return NULL; |
207 return NULL; |
207 |
208 |
208 float startx = -1.0 * 4, starty = (float)h/w * 4; |
|
209 float dx = -2*startx/w, dy = -2*starty/h; |
|
210 float vy; |
|
211 RenderrowData *d; |
209 RenderrowData *d; |
212 |
210 |
213 printf("* building kd-tree\n"); |
211 printf("* building kd-tree\n"); |
214 top->optimize(); |
212 top->optimize(); |
215 |
213 |
216 //srand(time(NULL)); |
214 float S = 0.5/w; |
217 |
215 Vector3 dfix = camera->u*(-w/2.0*S/camera->f) |
218 /* eye - viewing point */ |
216 + camera->v*(h/2.0*S/camera->f) + camera->p; |
219 Vector3 eye(0, 0, -5); |
217 Vector3 dx = camera->u * (S/camera->f); |
220 |
218 Vector3 dy = camera->v * (-S/camera->f); |
221 vy = starty; |
|
222 |
219 |
223 #ifdef PTHREADS |
220 #ifdef PTHREADS |
224 printf("* pthreads enabled, using %d threads\n", num_threads); |
221 printf("* pthreads enabled, using %d threads\n", num_threads); |
225 pthread_t threads[num_threads]; |
222 pthread_t threads[num_threads]; |
226 for (int t = 0; t < num_threads; t++) |
223 for (int t = 0; t < num_threads; t++) |
232 printf("* rendering row 0 ( 0%% done)"); |
229 printf("* rendering row 0 ( 0%% done)"); |
233 for (int y = 0; y < h; y++) { |
230 for (int y = 0; y < h; y++) { |
234 d = (RenderrowData*) malloc(sizeof(RenderrowData)); |
231 d = (RenderrowData*) malloc(sizeof(RenderrowData)); |
235 d->rt = this; |
232 d->rt = this; |
236 d->w = w; |
233 d->w = w; |
237 d->vx = startx; |
234 d->eye = camera->eye; |
238 d->vy = vy; |
235 d->dfix = dfix; |
239 d->dx = dx; |
236 d->dx = dx; |
|
237 #if OVERSAMPLING |
240 d->dy = dy; |
238 d->dy = dy; |
241 d->eye = eye; |
239 #endif |
242 d->iter = data + y*3*w; |
240 d->iter = data + y*3*w; |
243 #ifdef PTHREADS |
241 #ifdef PTHREADS |
244 /* create new thread and increase 't' */ |
242 /* create new thread and increase 't' */ |
245 int rc = pthread_create(&threads[t++], NULL, renderrow, (void *)d); |
243 int rc = pthread_create(&threads[t++], NULL, renderrow, (void *)d); |
246 if (rc) { |
244 if (rc) { |