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);  |