void run_example( const char* screenshot_path, int argc, char ** argv ) { const GLuint width = 800, height = 600; SDLInitializer sdl_initializer("OGLplus example", width, height); GLAPIInitializer api_init; ExampleParams params(argc, argv); setupExample(params); params.Check(); std::unique_ptr<Example> example(makeExample(params)); example->Reshape(width, height); example->MouseMove(width/2, height/2, width, height); if(screenshot_path) { make_screenshot( example, width, height, screenshot_path ); } else run_loop(example, width, height); }
void run_example( const char* screenshot_path, int argc, char** argv ) { GLFWInitializer glfw_initializer; const GLuint width = 800, height = 600; GLFWwindow* window = glfwCreateWindow( width, height, "OGLplus example", NULL, NULL ); if(!window) { throw std::runtime_error("Error creating GLFW3 window"); } else { glfwMakeContextCurrent(window); GLAPIInitializer api_init; ExampleParams params(argc, argv); setupExample(params); params.Check(); std::unique_ptr<Example> example(makeExample(params)); example->Reshape(width, height); example->MouseMove(width/2, height/2, width, height); if(screenshot_path) { make_screenshot( example, window, width, height, screenshot_path ); } else run_loop(example, window, width, height); } }
void run_example( const char* screenshot_path, int argc, char** argv ) { GLFWInitializer glfw_initializer; const GLuint width = 800, height = 600; if(!glfwOpenWindow( width, height, 8, 8, 8, 8, 32, 8, GLFW_WINDOW )) throw std::runtime_error("Error creating GLFW window"); else { glfwSetWindowTitle("OGLplus example"); GLAPIInitializer api_init; ExampleParams params(argc, argv); setupExample(params); params.Check(); std::unique_ptr<Example> example(makeExample(params)); example->Reshape(width, height); example->MouseMove(width/2, height/2, width, height); if(screenshot_path) { make_screenshot( example, width, height, screenshot_path ); } else run_loop(example, width, height); } }
void run_example( const x11::Display& display, const char* screenshot_path, const char* framedump_prefix, int argc, char ** argv ) { static int visual_attribs[] = { GLX_X_RENDERABLE , True, GLX_DRAWABLE_TYPE , GLX_WINDOW_BIT, GLX_RENDER_TYPE , GLX_RGBA_BIT, GLX_X_VISUAL_TYPE , GLX_TRUE_COLOR, GLX_RED_SIZE , 8, GLX_GREEN_SIZE , 8, GLX_BLUE_SIZE , 8, GLX_ALPHA_SIZE , 8, GLX_DEPTH_SIZE , 24, GLX_STENCIL_SIZE , 8, GLX_DOUBLEBUFFER , True, None }; glx::Version version(display); version.AssertAtLeast(1, 3); glx::FBConfig fbc = glx::FBConfigs( display, visual_attribs ).FindBest(display); x11::VisualInfo vi(display, fbc); const GLuint width = framedump_prefix?852:800; const GLuint height = framedump_prefix?480:600; x11::Window win( display, vi, x11::Colormap(display, vi), "OGLplus example", width, height ); x11::ScreenNames screen_names; ExampleParams params(argc, argv); if(framedump_prefix) params.quality = 1.0; params.max_threads = 128; params.num_gpus = screen_names.size(); // TODO: something more reliable setupExample(params); params.Check(); glx::Context ctx(display, fbc, 3, 3); ctx.MakeCurrent(win); // The clock for animation timing ExampleClock clock; std::vector<std::thread> threads; ThreadSemaphore thread_ready, master_ready; ExampleThreadData::Common example_thread_common_data = { nullptr, params, clock, screen_names, display, vi, fbc, ctx, thread_ready, master_ready, false /*failure*/, false /*done*/ }; try { // Initialize the GL API library (GLEW/GL3W/...) oglplus::GLAPIInitializer api_init; // things required for multi-threaded examples std::vector<ExampleThreadData> thread_data; // prepare the example data for(unsigned t=0; t!=params.num_threads; ++t) { ExampleThreadData example_thread_data = { t, nullptr, std::string(), &example_thread_common_data }; thread_data.push_back(example_thread_data); } // start the examples and let them // create their own contexts shared with // the main context for(unsigned t=0; t!=params.num_threads; ++t) { threads.emplace_back( call_example_thread_main, std::ref(thread_data[t]) ); // wait for the thread to create // an off-screen context thread_ready.Wait(); // check for errors if(!thread_data[t].error_message.empty()) { example_thread_common_data.failure = true; example_thread_common_data.master_ready.Signal(t); throw std::runtime_error( thread_data[t].error_message ); } } // make the example std::unique_ptr<Example> example(makeExample(params)); // tell the threads about the example // and let them call makeExampleThread example_thread_common_data.example = example.get(); for(unsigned t=0; t!=params.num_threads; ++t) { // signal that the example is ready master_ready.Signal(); // wait for the threads to call makeExampleThread thread_ready.Wait(); } // check for potential errors and let // the example do additional thread-related preparations for(unsigned t=0; t!=params.num_threads; ++t) { if(!thread_data[t].error_message.empty()) { example_thread_common_data.failure = true; example_thread_common_data.master_ready.Signal( params.num_threads ); throw std::runtime_error( thread_data[t].error_message ); } assert(thread_data[t].example_thread); example->PrepareThread(t,*thread_data[t].example_thread); } // signal that the example threads may start // rendering master_ready.Signal(params.num_threads); example->Reshape(width, height); example->MouseMove(width/2, height/2, width, height); if(screenshot_path) { make_screenshot( display, win, ctx, example, clock, width, height, screenshot_path ); } else if(framedump_prefix) { run_framedump_loop( display, win, ctx, example, clock, width, height, framedump_prefix ); } else { run_example_loop( display, win, ctx, example, example_thread_common_data, clock, width, height ); } example_thread_common_data.done = true; // cancel the example threads for(unsigned t=0; t!=params.num_threads; ++t) { if(thread_data[t].example_thread) thread_data[t].example_thread->Cancel(); } // join the example threads for(unsigned t=0; t!=params.num_threads; ++t) { threads[t].join(); } for(unsigned t=0; t!=params.num_threads; ++t) { if(!thread_data[t].error_message.empty()) throw std::runtime_error( thread_data[t].error_message ); } } catch(...) { example_thread_common_data.failure = true; master_ready.Signal(params.num_threads); try {for(auto& thread : threads) thread.join(); } catch(...){ } throw; } ctx.Release(display); }
void run_example( const eglplus::Display& display, ExampleOptions& opts, int argc, char ** argv ) { eglplus::Configs configs( display, eglplus::ConfigAttribs() .Add(eglplus::ConfigAttrib::RedSize, 8) .Add(eglplus::ConfigAttrib::GreenSize, 8) .Add(eglplus::ConfigAttrib::BlueSize, 8) .Add(eglplus::ConfigAttrib::DepthSize, 24) .Add(eglplus::ConfigAttrib::StencilSize, 8) .Add(eglplus::ConfigAttrib::SampleBuffers, opts.samples>0?1:0) .Add(eglplus::ConfigAttrib::Samples, opts.samples>0?opts.samples:0) .Add(eglplus::ColorBufferType::RGBBuffer) .Add(eglplus::RenderableTypeBit::OpenGL) .Add(eglplus::SurfaceTypeBit::Pbuffer) .Get() ); eglplus::Config config = configs.First(); eglplus::SurfaceAttribs surface_attribs = eglplus::SurfaceAttribs() .Add(eglplus::SurfaceAttrib::Width, GLint(opts.width)) .Add(eglplus::SurfaceAttrib::Height, GLint(opts.height)); eglplus::Surface surface = eglplus::Surface::Pbuffer( display, config, surface_attribs.Get() ); eglplus::BindAPI(eglplus::RenderingAPI::OpenGL); eglplus::ContextAttribs context_attribs = eglplus::ContextAttribs() .Add(eglplus::ContextAttrib::MajorVersion, 3) .Add(eglplus::ContextAttrib::MinorVersion, 3) .Add(eglplus::OpenGLProfileBit::Core); eglplus::Context context( display, config, context_attribs.Get() ); context.MakeCurrent(surface); ExampleParams params(argc, argv); params.quality = 1.0; params.max_threads = 128; params.num_gpus = 1; setupExample(params); params.Check(); ExampleClock clock; std::vector<std::thread> threads; ThreadSemaphore thread_ready, master_ready; ExampleThreadData::Common example_thread_common_data = { nullptr, params, clock, display, config, surface_attribs, context_attribs, context, thread_ready, master_ready, false, //failure false //done }; try { // Initialize the GL API library (GLEW/GL3W/...) oglplus::GLAPIInitializer api_init; // things required for multi-threaded examples std::vector<ExampleThreadData> thread_data; // prepare the example data for(unsigned t=0; t!=params.num_threads; ++t) { ExampleThreadData example_thread_data = { t, nullptr, std::string(), &example_thread_common_data }; thread_data.push_back(example_thread_data); } // start the examples and let them // create their own contexts shared with // the main context for(unsigned t=0; t!=params.num_threads; ++t) { threads.emplace_back( call_example_thread_main, std::ref(thread_data[t]) ); // wait for the thread to create // an off-screen context thread_ready.Wait(); // check for errors if(!thread_data[t].error_message.empty()) { example_thread_common_data.failure = true; example_thread_common_data.master_ready.Signal(t); throw std::runtime_error( thread_data[t].error_message ); } } // make the example std::unique_ptr<Example> example(makeExample(params)); // tell the threads about the example // and let them call makeExampleThread example_thread_common_data.example = example.get(); for(unsigned t=0; t!=params.num_threads; ++t) { // signal that the example is ready master_ready.Signal(); // wait for the threads to call makeExampleThread thread_ready.Wait(); } // check for potential errors and let // the example do additional thread-related preparations for(unsigned t=0; t!=params.num_threads; ++t) { if(!thread_data[t].error_message.empty()) { example_thread_common_data.failure = true; example_thread_common_data.master_ready.Signal( params.num_threads ); throw std::runtime_error( thread_data[t].error_message ); } assert(thread_data[t].example_thread); example->PrepareThread(t,*thread_data[t].example_thread); } // signal that the example threads may start // rendering master_ready.Signal(params.num_threads); example->Reshape(opts.width, opts.height); example->MouseMove(opts.width/2, opts.height/2, opts.width, opts.height); if(opts.screenshot_path) { make_screenshot(surface, example, clock, opts); } else if(opts.framedump_prefix) { run_framedump_loop(surface, example, clock, opts); } else assert(!"Never should get here!"); example_thread_common_data.done = true; // cancel the example threads for(unsigned t=0; t!=params.num_threads; ++t) { if(thread_data[t].example_thread) { thread_data[t].example_thread->Cancel(); } } // join the example threads for(unsigned t=0; t!=params.num_threads; ++t) { threads[t].join(); } for(unsigned t=0; t!=params.num_threads; ++t) { if(!thread_data[t].error_message.empty()) { throw std::runtime_error( thread_data[t].error_message ); } } } catch(...) { example_thread_common_data.failure = true; master_ready.Signal(params.num_threads); try {for(auto& thread : threads) thread.join(); } catch(...){ } throw; } }