SingleExample( GLuint width, GLuint height, const ExampleParams& params, const char* screenshot_path ): _fps_time(0.0) , _prim_count(0.0) , _frame_no(0) , _width(width) , _height(height) , _example(makeExample(params)) , _primitive_query(new Query()) , _screenshot_path(screenshot_path) { assert(!SingleInstance()); SingleInstance() = this; assert(_example); _example->Reshape(width, height); _example->MouseMove(width/2, height/2, width, height); _os_clock.reset(); if(_screenshot_path) _clock.Update(_example->HeatUpTime()); }
void make_screenshot( const x11::Display& display, const x11::Window& win, const glx::Context& ctx, std::unique_ptr<Example>& example, ExampleClock& clock, GLuint width, GLuint height, const char* screenshot_path ) { XEvent event; double s = example->HeatUpTime(); double t = example->ScreenshotTime(); double dt = example->FrameTime(); clock.Update(s); // heat-up while(true) { while(display.NextEvent(event)); s += dt; clock.Update(s); example->Render(clock); if(s < t) ctx.SwapBuffers(win); else break; } while(display.NextEvent(event)); glFinish(); //save it to a file std::vector<char> pixels(width * height * 3); glReadPixels( 0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels.data() ); std::ofstream output(screenshot_path); output.write(pixels.data(), pixels.size()); ctx.SwapBuffers(win); }
void make_screenshot( eglplus::Surface& surface, std::unique_ptr<Example>& example, ExampleClock& clock, const ExampleOptions& opts ) { double s = example->HeatUpTime(); double t = example->ScreenshotTime(); double dt = example->FrameTime(); clock.Update(s); glEnable(GL_MULTISAMPLE); // heat-up while(s < t) { s += dt; clock.Update(s); unsigned part_no = 0; double comp = 0.0; do { comp = example->RenderPart(part_no++, clock); } while(comp < 1.0); if(s < t) surface.SwapBuffers(); } glFinish(); //save it to a file std::vector<char> pixels(opts.width * opts.height * 3); glReadPixels( 0, 0, opts.width, opts.height, GL_RGB, GL_UNSIGNED_BYTE, pixels.data() ); std::ofstream output(opts.screenshot_path); output.write(pixels.data(), pixels.size()); surface.SwapBuffers(); }
void run_loop( std::unique_ptr<Example>& example, GLuint width, GLuint height ) { GLuint mouse_x = width / 2; GLuint mouse_y = height / 2; os::steady_clock os_clock; ExampleClock clock; while(true) { clock.Update(os_clock.seconds()); if(!example->Continue(clock)) break; example->Render(clock); glfwSwapBuffers(); int new_x, new_y; glfwGetWindowSize(&new_x, &new_y); if((int(width) != new_x) || (int(height) != new_y)) { if(new_x <= 0) new_x = 1; if(new_y <= 0) new_y = 1; width = GLuint(new_x); height = GLuint(new_y); example->Reshape(width, height); } glfwGetMousePos(&new_x, &new_y); if((int(mouse_x) != new_x) || (int(mouse_y) != new_y)) { if(new_x <= 0) new_x = 1; if(new_y <= 0) new_y = 1; mouse_x = GLuint(new_x); mouse_y = GLuint(new_y); example->MouseMove( mouse_x, height- mouse_y, width, height ); } if(glfwGetKey(GLFW_KEY_ESC)) { glfwCloseWindow(); break; } if(!glfwGetWindowParam(GLFW_OPENED)) break; } }
void Display(void) { _clock.Update(_os_clock.seconds()); double frame_time = _clock.Now().Seconds(); _frame_no++; GLuint primitives_per_frame = 0; if(_primitive_query) { try { auto query_exec = _primitive_query->Execute( Query::Target::PrimitivesGenerated, primitives_per_frame ); _example->Render(_clock); glutSwapBuffers(); } catch(Error&) { _primitive_query.reset(); } } else { _example->Render(_clock); glutSwapBuffers(); } _prim_count += double(primitives_per_frame); const double fps_interval = 10.0; const double this_interval = frame_time - _fps_time; if(this_interval >= fps_interval) { _fps_time = frame_time; std::cout.width(5); std::cout.precision(3); std::cout << _frame_no << " frames in " << std::fixed << this_interval << " seconds = " << std::fixed << _frame_no/this_interval << " FPS; " << std::scientific << _prim_count/this_interval << " PPS; " << std::scientific << _prim_count/_frame_no << " PPF; " << std::endl; _frame_no = 0; _prim_count = 0.0; } if(!_example->Continue(_clock)) { Quit(); } }
void make_screenshot( eglplus::Surface& surface, std::unique_ptr<Example>& example, ExampleClock& clock, GLuint width, GLuint height, const char* screenshot_path ) { double s = example->HeatUpTime(); double t = example->ScreenshotTime(); double dt = example->FrameTime(); clock.Update(s); // heat-up while(true) { s += dt; clock.Update(s); example->Render(clock); if(s < t) surface.SwapBuffers(); else break; } glFinish(); //save it to a file std::vector<char> pixels(width * height * 3); glReadPixels( 0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels.data() ); std::ofstream output(screenshot_path); output.write(pixels.data(), pixels.size()); surface.SwapBuffers(); }
void run_loop( std::unique_ptr<Example>& example, GLuint width, GLuint height ) { os::steady_clock os_clock; ExampleClock clock; bool done = false; while(!done) { clock.Update(os_clock.seconds()); if(!example->Continue(clock)) break; example->Render(clock); SDL_GL_SwapBuffers(); SDL_Event event; while(SDL_PollEvent(&event)) { if(event.type == SDL_MOUSEMOTION) { example->MouseMove( event.motion.x, height- event.motion.y, width, height ); } else if(event.type == SDL_KEYUP) { if(event.key.keysym.sym == SDLK_ESCAPE) done = true; } else if(event.type == SDL_VIDEORESIZE) { width = event.resize.w; height = event.resize.h; example->Reshape(width, height); } else if(event.type == SDL_QUIT) { done = true; } } } }
void run_framedump_loop( const x11::Display& display, const x11::Window& win, const glx::Context& ctx, std::unique_ptr<Example>& example, ExampleClock& clock, GLuint width, GLuint height, const char* framedump_prefix ) { std::vector<char> txtbuf(1024); std::cin.getline(txtbuf.data(), txtbuf.size()); if(std::strcmp(framedump_prefix, txtbuf.data()) != 0) return; const std::size_t mouse_path_pts = 7; std::vector<Vec2f> mouse_path_pos(mouse_path_pts); std::vector<Vec2f> mouse_path_dir(mouse_path_pts); for(std::size_t p=0; p!= mouse_path_pts; ++p) { mouse_path_pos[p] = Vec2f( std::rand() % width, std::rand() % height ); mouse_path_dir[p] = Vec2f( (std::rand()%2?1.0:-1.0)*10.0f* (0.2+float(std::rand())/float(RAND_MAX)*0.8), (std::rand()%2?1.0:-1.0)*10.0f* (0.2+float(std::rand())/float(RAND_MAX)*0.8) ); } typedef CubicBezierLoop<Vec2f, double> Loop; double t = 0.0; double period = 1.0 / 25.0; GLuint frame_no = 0; std::vector<char> pixels(width * height * 4); GLuint border = 32; XEvent event; while(true) { while(display.NextEvent(event)); Vec2f mouse_pos = Loop(mouse_path_pos).Position(t*0.2); for(std::size_t p=0; p!= mouse_path_pts; ++p) { Vec2f dir = mouse_path_dir[p]; Vec2f pos = mouse_path_pos[p]; if((pos.x() < border) && (dir.x() < 0.0)) dir = Vec2f(-dir.x(), dir.y()); if((pos.y() < border) && (dir.y() < 0.0)) dir = Vec2f( dir.x(),-dir.y()); if((pos.x() > width-border) && (dir.x() > 0.0)) dir = Vec2f(-dir.x(), dir.y()); if((pos.y() >height-border) && (dir.y() > 0.0)) dir = Vec2f( dir.x(),-dir.y()); mouse_path_dir[p] = dir; mouse_path_pos[p] = pos + dir; } float mouse_x = mouse_pos.x(); float mouse_y = mouse_pos.y(); if(mouse_x < 0.0f) mouse_x = 0.0f; if(mouse_y < 0.0f) mouse_y = 0.0f; if(mouse_x > width) mouse_x = width; if(mouse_y > height) mouse_y = height; example->MouseMove( GLuint(mouse_x), GLuint(mouse_y), width, height ); t += period; clock.Update(t); if(!example->Continue(clock)) break; example->Render(clock); glFinish(); glReadPixels( 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data() ); glFinish(); ctx.SwapBuffers(win); std::stringstream filename; filename << framedump_prefix << std::setfill('0') << std::setw(6) << frame_no << ".rgba"; { std::ofstream file(filename.str()); file.write(pixels.data(), pixels.size()); file.flush(); } std::cout << filename.str() << std::endl; ++frame_no; txtbuf.resize(filename.str().size()+1); std::cin.getline(txtbuf.data(), txtbuf.size()); if(std::strncmp( filename.str().c_str(), txtbuf.data(), txtbuf.size() ) != 0) break; } while(display.NextEvent(event)); }
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 run_framedump_loop( eglplus::Surface& surface, std::unique_ptr<Example>& example, ExampleClock& clock, const ExampleOptions& opts ) { std::vector<char> txtbuf(1024); std::cin.getline(txtbuf.data(), txtbuf.size()); if(std::strcmp(opts.framedump_prefix, txtbuf.data()) != 0) return; const std::size_t mouse_path_pts = 7; std::vector<Vec2f> mouse_path_pos(mouse_path_pts); std::vector<Vec2f> mouse_path_dir(mouse_path_pts); for(std::size_t p=0; p!= mouse_path_pts; ++p) { mouse_path_pos[p] = Vec2f( std::rand() % opts.width, std::rand() % opts.height ); mouse_path_dir[p] = Vec2f( (std::rand()%2?1.0:-1.0)*10.0f* (0.2+float(std::rand())/float(RAND_MAX)*0.8), (std::rand()%2?1.0:-1.0)*10.0f* (0.2+float(std::rand())/float(RAND_MAX)*0.8) ); } typedef CubicBezierLoop<Vec2f, double> Loop; double t = 0.0; double period = 1.0 / 25.0; GLuint frame_no = 0; std::vector<char> pixels(opts.width * opts.height * 4); GLuint border = 32; glEnable(GL_MULTISAMPLE); while(true) { Vec2f mouse_pos = Loop(mouse_path_pos).Position(t*0.2); for(std::size_t p=0; p!= mouse_path_pts; ++p) { Vec2f dir = mouse_path_dir[p]; Vec2f pos = mouse_path_pos[p]; if((pos.x() < border) && (dir.x() < 0.0)) { dir = Vec2f(-dir.x(), dir.y()); } if((pos.y() < border) && (dir.y() < 0.0)) { dir = Vec2f( dir.x(),-dir.y()); } if((pos.x() > opts.width-border) && (dir.x() > 0.0)) { dir = Vec2f(-dir.x(), dir.y()); } if((pos.y() >opts.height-border) && (dir.y() > 0.0)) { dir = Vec2f( dir.x(),-dir.y()); } mouse_path_dir[p] = dir; mouse_path_pos[p] = pos + dir; } float mouse_x = mouse_pos.x(); float mouse_y = mouse_pos.y(); if(mouse_x < 0.0f) mouse_x = 0.0f; if(mouse_y < 0.0f) mouse_y = 0.0f; if(mouse_x > opts.width) mouse_x = opts.width; if(mouse_y > opts.height) mouse_y = opts.height; example->MouseMove( GLuint(mouse_x), GLuint(mouse_y), opts.width, opts.height ); t += period; clock.Update(t); if(!example->Continue(clock)) break; unsigned part_no = 0; double comp = 0.0; do { comp = example->RenderPart(part_no++, clock); } while(comp < 1.0); glFinish(); glReadPixels( 0, 0, opts.width, opts.height, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data() ); glFinish(); surface.SwapBuffers(); std::stringstream filename; filename << opts.framedump_prefix << std::setfill('0') << std::setw(6) << frame_no << ".rgba"; { std::ofstream file(filename.str()); file.write(pixels.data(), pixels.size()); file.flush(); } std::cout << filename.str() << std::endl; ++frame_no; txtbuf.resize(filename.str().size()+1); std::cin.getline(txtbuf.data(), txtbuf.size()); if(std::strncmp( filename.str().c_str(), txtbuf.data(), txtbuf.size() ) != 0) break; } }
void run_loop( std::unique_ptr<Example>& example, GLFWwindow* window, GLuint width, GLuint height ) { GLuint mouse_x = width / 2; GLuint mouse_y = height / 2; os::steady_clock os_clock; ExampleClock clock; while(true) { clock.Update(os_clock.seconds()); if(!example->Continue(clock)) break; example->Render(clock); glfwSwapBuffers(window); glfwPollEvents(); int new_x, new_y; double tmp_x, tmp_y; glfwGetWindowSize(window, &new_x, &new_y); if((int(width) != new_x) || (int(height) != new_y)) { if(new_x <= 0) new_x = 1; if(new_y <= 0) new_y = 1; width = GLuint(new_x); height = GLuint(new_y); example->Reshape(width, height); } glfwGetCursorPos(window, &tmp_x, &tmp_y); new_x = std::floor(tmp_x); new_y = std::floor(tmp_y); if((int(mouse_x) != new_x) || (int(mouse_y) != new_y)) { if(new_x <= 0) new_x = 1; if(new_y <= 0) new_y = 1; mouse_x = GLuint(new_x); mouse_y = GLuint(new_y); example->MouseMove( mouse_x, height- mouse_y, width, height ); } if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) { glfwSetWindowShouldClose(window, 1); break; } if(glfwWindowShouldClose(window)) { break; } } }