void Tracer::trace() { if( !scene_ || is_tracing_ ) { return; } startTracing(); const int width = film_->getWidth(); const int height = film_->getHeight(); const double aspect = static_cast< double >( width ) / static_cast< double >( height ); Logging::log( LogLevel::Info, "[Tracer] Tracing image with " + std::to_string( width ) + " x " + std::to_string( height ) + " pixels (w x h) and " + std::to_string( rays_per_pixel_ ) + " samples per pixel." ); std::thread t( [=]{ #pragma omp parallel for schedule( dynamic, 1 ) for( int samp = 0; samp < rays_per_pixel_; ++samp ) { for( int y = 0; y < height && is_tracing_; ++y ) { for( int x = 0; x < width && is_tracing_; ++x ) { const double x_d = static_cast< double >( x ); const double y_d = static_cast< double >( y ); const double width_d = static_cast< double >( width ); const double height_d = static_cast< double >( height ); const double dx = aspect * ( x_d / width_d - .5 ); const double dy = ( y_d / height_d - .5 ); Color sample = traceLocation( dx, dy ); film_->addSample( x, y, sample ); curr_num_samples_.fetch_add( 1 ); } } } stopTracing(); auto perf_string = std::to_string( getSpeedAsMsamplesPerSec() ); // @TODO cutting away unwanted digits entails wrong rounding perf_string = perf_string.substr( 0, perf_string.length() - 4 ); Logging::log( LogLevel::Info, "[Tracer] Generated samples at a rate of " + perf_string + " Msamples/sec." ); } ); t.detach(); }
////////////////////////////////////////////////////////////////////////////// //WINMAIN ////////////////////////////////////////////////////////////////////////////// int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd) { #ifdef DEBUGGING startTracing(TRACEFILENAME); #endif TRACE ("Start of Session___"); //assign instance to global variable hInstMain=hInstance; //create window class WNDCLASSEX wcx; //set the size of the structure wcx.cbSize=sizeof(WNDCLASSEX); //class style wcx.style=CS_OWNDC | CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; //window procedure wcx.lpfnWndProc=TheWindowProc; //class extra wcx.cbClsExtra=0; //window extra wcx.cbWndExtra=0; //application handle wcx.hInstance=hInstMain; //icon wcx.hIcon=LoadIcon(NULL,IDI_APPLICATION); //cursor wcx.hCursor=LoadCursor(NULL,IDC_ARROW); //background color wcx.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH); //menu wcx.lpszMenuName=NULL; //class name wcx.lpszClassName=WINDOWCLASS; //small icon wcx.hIconSm=NULL; //register the window class, return 0 if not successful if(!RegisterClassEx(&wcx)) return(0); //create main window hWndMain=CreateWindowEx(0, WINDOWCLASS, WINDOWTITLE, WS_BORDER | WS_SYSMENU | WS_VISIBLE, 0, 0, windowHorizontalSize, windowVerticalSize, NULL, NULL, hInstMain, NULL); //error check if(!hWndMain) { return(0); } //if program initialization failed, then return with 0 if(!Prog_Init()) { return(0); } //message structure MSG msg; TRACE("start message pump.."); //message pump for(;;) { //look for a message if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { //there is a message //check that we arent quitting if(msg.message==WM_QUIT) { break; } //translate message TranslateMessage(&msg); //dispatch message DispatchMessage(&msg); } //run main game loop Prog_Loop(); } //clean up program data Prog_Done(); #ifdef DEBUGGING stopTracing(); #endif //return the wparam from the WM_QUIT message return(msg.wParam); }