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