void Raytracer::trace_packet(PacketRegion region, float refractive, unsigned char *buffer) { Int2 ll = region.ll; Int2 lr = region.lr; Int2 ul = region.ul; Int2 ur = region.ur; IsectInfo infos[rays_per_packet]; bool intersected[rays_per_packet]; Packet packet; get_viewing_frustum(ll, lr, ul, ur, packet.frustum); Vector3 eye = scene->camera.get_position(); Int2 pixels[rays_per_packet]; int r = 0; // counter for rays in packet for (int y = ll.y; y <= ul.y; y++) { for (int x = ll.x; x <= lr.x; x++) { Int2 pixel(x, y); packet.rays[r].eye = eye; packet.rays[r].dir = get_viewing_ray(pixel); pixels[r] = pixel; intersected[r] = false; r++; } } for (size_t i = 0; i < scene->num_geometries(); i++) { scene->get_geometries()[i]->intersect_packet(packet, infos, intersected); } for (int i = 0; i < rays_per_packet; i++) { if (intersected[i]) { Color3 color = trace_pixel_end(0, packet.rays[i], refractive, infos[i]); color.to_array(&buffer[4 * (pixels[i].y * width + pixels[i].x)]); } else { Color3 color = scene->background_color; color.to_array(&buffer[4 * (pixels[i].y * width + pixels[i].x)]); } } }
/** * Raytraces some portion of the scene. Should raytrace for about * max_time duration and then return, even if the raytrace is not copmlete. * The results should be placed in the given buffer. * @param buffer The buffer into which to place the color data. It is * 32-bit RGBA (4 bytes per pixel), in row-major order. * @param max_time, If non-null, the maximum suggested time this * function raytrace before returning, in seconds. If null, the raytrace * should run to completion. * @return true if the raytrace is complete, false if there is more * work to be done. */ bool Raytracer::raytrace( unsigned char *buffer, real_t* max_time ) { // TODO Add any modifications to this algorithm, if needed. static long start_time; // used to show how long time ray tracing cost if (0 == current_row) start_time = clock(); static const size_t PRINT_INTERVAL = 64; // the time in milliseconds that we should stop unsigned int end_time = 0; bool is_done = false; if ( max_time ) { // convert duration to milliseconds unsigned int duration = (unsigned int) ( *max_time * 1000 ); end_time = SDL_GetTicks() + duration; } // until time is up, run the raytrace. we render an entire row at once // for simplicity and efficiency. for ( ; !max_time || end_time > SDL_GetTicks(); ++current_row ) { if ( current_row % PRINT_INTERVAL == 0 ) { printf( "Raytracing (row %u)...\n", current_row ); } // we're done if we finish the last row is_done = current_row == height; // break if we finish if ( is_done ) break; for ( size_t x = 0; x < width; ++x ) { // trace a pixel Color3 color = trace_pixel( scene, x, current_row, width, height ); // write the result to the buffer, always use 1.0 as the alpha color.to_array( &buffer[4 * ( current_row * width + x )] ); } } if ( is_done ) { printf( "Done raytracing!\n" ); printf( "Used %d milliseconds.\n", clock()-start_time ); } return is_done; }
// Raytraces some portion of the scene bool Raytracer::raytrace( unsigned char *buffer, real_t* max_time ) { static const size_t PRINT_INTERVAL = 64; unsigned int end_time = 0; bool is_done; if ( max_time ) { // convert duration to milliseconds unsigned int duration = (unsigned int) ( *max_time * 1000 ); end_time = SDL_GetTicks() + duration; } // until time is up, run the raytrace. we render an entire row at once for ( ; !max_time || end_time > SDL_GetTicks(); ++current_row ) { if ( current_row % PRINT_INTERVAL == 0 ) { printf( "Raytracing (row %u)...\n", current_row ); } // we're done if we finish the last row is_done = current_row == height; if ( is_done ) break; for ( size_t x = 0; x < width; ++x ) { // trace a pixel Color3 color = trace_pixel( scene, x, current_row, width, height ); color.to_array( &buffer[4 * ( current_row * width + x )] ); } } if ( is_done ) { printf( "Done raytracing!\n" ); } return is_done; }