template<class T> void RENDER_WORLD<T>:: Render(const RANGE<VECTOR<int,2> >& pixels, PROGRESS_INDICATOR &progress) { RENDERING_RAY<T> dummy_root; VECTOR<int,2> box_size=camera.film.Samples_Extent(); VECTOR<int,2> lengths=pixels.Edge_Lengths(); ARRAY<typename FILM<T>::SAMPLE> samples; progress.Initialize((lengths.x/box_size.x+1)*(lengths.y/box_size.y+1)); // +1 to account for rounding; occasionally will be incorrect, but will get close enough to 100% to judge // progress if(threads>1){ #ifdef USE_PTHREADS pthread_mutex_t mutex; pthread_mutex_init(&mutex,0); THREAD_QUEUE task_queue(4); for(int box_x=0;box_x*box_size.x<lengths.x;box_x++) for(int box_y=0;box_y*box_size.y<lengths.y;box_y++){ VECTOR<int,2> lower_corner=VECTOR<int,2>(box_x*box_size.x,box_y*box_size.y)+pixels.min_corner; task_queue.Queue(new RENDER_TASK<T>(*this,progress,&mutex,RANGE<VECTOR<int,2> >(lower_corner,lower_corner+box_size)));} task_queue.Wait(); pthread_mutex_destroy(&mutex); #else PHYSBAM_FATAL_ERROR("Threads non 1, but USE_PTHREADS disabled"); #endif } else for(int box_x=0;box_x*box_size.x<lengths.x;box_x++) for(int box_y=0;box_y*box_size.y<lengths.y;box_y++){ samples.Remove_All(); VECTOR<int,2> lower_corner=VECTOR<int,2>(box_x*box_size.x,box_y*box_size.y)+pixels.min_corner; camera.film.Generate_Samples(RANGE<VECTOR<int,2> >(lower_corner,lower_corner+box_size),camera,samples); progress.Progress(); for(int i=1;i<=samples.m;i++){ typename FILM<T>::SAMPLE& sample=samples(i); RENDERING_RAY<T> ray(RAY<VECTOR<T,3> >(camera.position,sample.world_position-camera.position),1,Point_Inside_Object(camera.position)); dummy_root.recursion_depth=0;dummy_root.current_object=ether; sample.radiance=Cast_Ray(ray,dummy_root); sample.alpha=ray.ray.semi_infinite?(T)0:(T)1; camera.film.Add_Sample(sample);}} }