src/raytracer.cc
branchpyrit
changeset 20 f22952603f29
parent 19 4e0955fca797
child 21 79b516a3803d
equal deleted inserted replaced
19:4e0955fca797 20:f22952603f29
     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);