void run_example_loop( const x11::Display& display, const x11::Window& win, const glx::Context& ctx, std::unique_ptr<Example>& example, ExampleThreadData::Common& common, ExampleClock& clock, GLuint width, GLuint height ) { std::cout << "-+-[Begin]" << std::endl; #if GL_ARB_debug_output && !OGLPLUS_NO_LAMBDAS ARB_debug_output dbg; ARB_debug_output::LogSink sink( [](const ARB_debug_output::CallbackData& data) -> void { std::cout << " |" << std::endl; std::cout << " +-+-[" << data.id << "] '" << data.message << "'" << std::endl; std::cout << " | +---[source] '" << EnumValueName(data.source).c_str() << "'" << std::endl; std::cout << " | +---[type] '" << EnumValueName(data.type).c_str() << "'" << std::endl; std::cout << " | `---[severity] '" << EnumValueName(data.severity).c_str() << "'" << std::endl; } ); dbg.Control( DebugOutputARBSource::DontCare, DebugOutputARBType::DontCare, DebugOutputARBSeverity::Low, true ); dbg.InsertMessage( DebugOutputARBSource::Application, DebugOutputARBType::Other, 0, DebugOutputARBSeverity::Low, "Starting main loop" ); #endif // GL_ARB_debug_output win.SelectInput( StructureNotifyMask| PointerMotionMask| KeyPressMask ); ::Atom wmDelete = ::XInternAtom(display, "WM_DELETE_WINDOW", True); ::XSetWMProtocols(display, win, &wmDelete, 1); XEvent event; os::steady_clock os_clock; bool done = false; while(!done && !common.failure) { while(display.NextEvent(event)) { switch(event.type) { case ClientMessage: case DestroyNotify: done = true; break; case ConfigureNotify: width = event.xconfigure.width; height = event.xconfigure.height; example->Reshape( width, height ); case MotionNotify: example->MouseMove( event.xmotion.x, height- event.xmotion.y, width, height ); break; case KeyPress: if(::XLookupKeysym( &event.xkey, 0 ) == XK_Escape) done = true; break; default:; } } clock.Update(os_clock.seconds()); if(!example->Continue(clock)) break; example->Render(clock); ctx.SwapBuffers(win); } std::cout << " `-[Done]" << std::endl; }
void window_loop( const x11::Window& window, AppData& app_data, CommonData& common, RaytracerTarget& rt_target, std::size_t n_threads ) { Context gl; Renderer renderer(app_data, rt_target.tex_unit); renderer.Use(app_data); Saver saver(app_data); window.SelectInput(StructureNotifyMask| PointerMotionMask| KeyPressMask); ::XEvent event; while(!common.Done()) { if(app_data.verbosity > 0) { app_data.logstr() << "Rendering cube face " << common.Face() << std::endl; } // clear the raytrace target rt_target.Clear(app_data); renderer.InitFrame(app_data, common.Face()); renderer.Render(app_data); common.context.SwapBuffers(window); // setup logging period std::chrono::system_clock::duration log_period; if(app_data.verbosity > 4) { log_period = std::chrono::seconds(1); } else if(app_data.verbosity > 3) { log_period = std::chrono::seconds(5); } else if(app_data.verbosity > 2) { log_period = std::chrono::seconds(15); } else if(app_data.verbosity > 1) { log_period = std::chrono::minutes(1); } auto log_time = std::chrono::system_clock::now(); // signal all threads that they can start raytracing tiles common.master_ready.Signal(n_threads); while(!common.FaceDone()) { unsigned slot = 0; while(common.display.NextEvent(event)) { switch(event.type) { case ClientMessage: case DestroyNotify: common.Stop(); break; case ConfigureNotify: app_data.render_width = event.xconfigure.width; app_data.render_height = event.xconfigure.height; break; case MotionNotify: break; case KeyPress: if(::XLookupKeysym(&event.xkey, 0) == XK_Escape) common.Stop(); break; default:; } } if(common.Done()) break; if((slot++ % 5) == 0) { auto lock = common.Lock(); renderer.Render(app_data); gl.Finish(); lock.unlock(); common.context.SwapBuffers(window); } if(app_data.verbosity > 1) { auto now = std::chrono::system_clock::now(); if(log_time + log_period < now) { common.LogProgress(app_data); log_time = now; } } std::chrono::milliseconds period(5); std::this_thread::sleep_for(period); } if(common.Done()) break; // wait for all raytracer threads to finish common.thread_ready.Wait(n_threads); renderer.Render(app_data); common.context.SwapBuffers(window); if(app_data.verbosity > 1) { app_data.logstr() << "Finished cube face " << common.Face() << std::endl; } // save the face image saver.SaveFrame(app_data, rt_target, common.Face()); // switch the face common.NextFace(app_data); // signal that the master is ready to render // the next face common.master_ready.Signal(n_threads); } }