src/raytracer.cc
branchpyrit
changeset 19 4e0955fca797
parent 16 20bceb605f48
child 20 f22952603f29
equal deleted inserted replaced
18:25b7c445cf61 19:4e0955fca797
   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) {
   257 				free(d);
   255 				free(d);
   258 #else
   256 #else
   259 		renderrow((void *)d);
   257 		renderrow((void *)d);
   260 		free(d);
   258 		free(d);
   261 #endif
   259 #endif
   262 		vy += dy;
   260 		dfix += dy;
   263 		printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b%4d (%2d%% done)", y, y*100/(h-1));
   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));
   264 	}
   262 	}
   265 	printf("\n");
   263 	printf("\n");
   266 
   264 
   267 #ifdef PTHREADS
   265 #ifdef PTHREADS