void RasterizerGLES3::set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale) { if (p_image.is_null() || p_image->empty()) return; begin_frame(0.0); int window_w = OS::get_singleton()->get_video_mode(0).width; int window_h = OS::get_singleton()->get_video_mode(0).height; glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES3::system_fbo); glViewport(0, 0, window_w, window_h); glDisable(GL_BLEND); glDepthMask(GL_FALSE); if (OS::get_singleton()->get_window_per_pixel_transparency_enabled()) { glClearColor(0.0, 0.0, 0.0, 0.0); } else { glClearColor(p_color.r, p_color.g, p_color.b, 1.0); } glClear(GL_COLOR_BUFFER_BIT); canvas->canvas_begin(); RID texture = storage->texture_create(); storage->texture_allocate(texture, p_image->get_width(), p_image->get_height(), 0, p_image->get_format(), VS::TEXTURE_TYPE_2D, VS::TEXTURE_FLAG_FILTER); storage->texture_set_data(texture, p_image); Rect2 imgrect(0, 0, p_image->get_width(), p_image->get_height()); Rect2 screenrect; if (p_scale) { if (window_w > window_h) { //scale horizontally screenrect.size.y = window_h; screenrect.size.x = imgrect.size.x * window_h / imgrect.size.y; screenrect.position.x = (window_w - screenrect.size.x) / 2; } else { //scale vertically screenrect.size.x = window_w; screenrect.size.y = imgrect.size.y * window_w / imgrect.size.x; screenrect.position.y = (window_h - screenrect.size.y) / 2; } } else { screenrect = imgrect; screenrect.position += ((Size2(window_w, window_h) - screenrect.size) / 2.0).floor(); } RasterizerStorageGLES3::Texture *t = storage->texture_owner.get(texture); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, t->tex_id); canvas->draw_generic_textured_rect(screenrect, Rect2(0, 0, 1, 1)); glBindTexture(GL_TEXTURE_2D, 0); canvas->canvas_end(); storage->free(texture); // free since it's only one frame that stays there end_frame(true); }
void sound_add_cycles(unsigned c) { #if !defined(PSP) && !defined(EMSCRIPTEN) cycles += c; if (cycles >= MAX_CYCLES) { cycles -= MAX_CYCLES; end_frame(); } #endif }
blargg_err_t SNES_SPC::play( int count, sample_t* out ) { require( (count & 1) == 0 ); // must be even if ( count ) { set_output( out, count ); end_frame( count * (clocks_per_sample / 2) ); } const char* err = m.cpu_error; m.cpu_error = 0; return err; }
void Renderer::render_frame() { begin_frame(); if (scene_to_render != nullptr) { pre_render(); gbuffer_render(); main_render(); post_render(); } gui.render_frame(); end_frame(); }
int main(int argc, char *argv[]) { const fixed dt = (1 << FIXPOINT_SHIFT) / 100; // 60 FPS fixed t = 0; fixed accumulator = 0; fixed delta_time = 0; SDL_Event event; init(); while (!app.quit) { start_frame(); delta_time = get_last_frame_time(); if (SDL_PollEvent(&event)) { handle_event(&event); } if (!app.paused) { accumulator += delta_time; // trace("accumulator %ld, dt: %ld, delta_time %ld", accumulator, dt, delta_time); while (accumulator >= dt) { move_objects(t, dt); t += dt; accumulator -= dt; } interpolate(fpdiv(accumulator, dt)); draw_scene(); } end_frame(); } return 0; }
/* switch client to new state */ void set_state( int newstate ) { if ( client_state == newstate ) return; if ( newstate == CS_PLAY ) grab_input( 1 ); if ( client_state == CS_PLAY ) grab_input( 0 ); if ( client_state == CS_CONFIRM_WARP || client_state == CS_CONFIRM_RESTART || client_state == CS_CONFIRM_QUIT || client_state == CS_CONFIRM_CONTINUE || client_state == CS_GET_READY || client_state == CS_PAUSE || client_state == CS_FINAL_PLAYER_INFO || client_state == CS_GET_READY_FOR_NEXT_LEVEL || client_state == CS_RECV_LEVEL || client_state == CS_ROUND_RESULT || client_state == CS_RECV_STATS || client_state == CS_FATAL_ERROR ) { /* show offscreen */ if ( offscreen ) { stk_surface_blit( offscreen, 0,0,-1,-1, stk_display, 0,0 ); end_frame(); } /* do not refresh when coming from RECV_LEVEL as a GET_READY * will follow */ if ( client_state != CS_RECV_LEVEL ) if ( client_state != CS_ROUND_RESULT ) if ( client_state != CS_RECV_STATS ); stk_display_update( STK_UPDATE_ALL ); } client_state = newstate; stk_timer_reset(); }
void Profiler::begin_frame() { // End the previous frame if any end_frame(); begin_block("RunFrame"); }
static void filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref) { end_frame(link); }
static int filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref) { end_frame(link); return 0; }
/* run the state driven loop until game is broken up or finished */ void client_game_run( void ) { int ms, frame_delay = config.fps?10:1; int button_clicked, key_pressed; SDL_Event event; int abort = 0, i, j, penalty; /* frame rate */ int frames = 0; int frame_time = SDL_GetTicks(); event_clear_sdl_queue(); stk_display_fade( STK_FADE_IN, STK_FADE_DEFAULT_TIME ); stats_received = 0; stk_timer_reset(); ms = 1; while ( !abort && !stk_quit_request ) { /* check wether an event occured */ button_clicked = key_pressed = 0; if ( SDL_PollEvent( &event ) ) { if ( client_state == CS_PAUSE && game->game_type == GT_NETWORK ) gui_dispatch_event( &event, ms ); else if ( event.type == SDL_MOUSEBUTTONDOWN ) button_clicked = event.button.button; else if ( event.type == SDL_KEYDOWN ) { key_pressed = event.key.keysym.sym; if ( handle_default_key( key_pressed, &abort ) ) key_pressed = 0; } else if (event.type == SDL_ACTIVEEVENT) { if (event.active.state == SDL_APPINPUTFOCUS || event.active.state == SDL_APPACTIVE ) if (event.active.gain == 0 ) client_set_pause(1); } } else if ( client_state == CS_PAUSE && game->game_type == GT_NETWORK ) gui_dispatch_event( 0, ms ); /* check whether Shift is pressed to switch between own and highest score */ if (game->game_type == GT_LOCAL) handle_display_switch(); /* let server know we're still alive except * in CS_PLAY as we send paddle updates there */ if ( game->game_type == GT_NETWORK ) comm_send_heartbeat(); /* handle client */ switch ( client_state ) { case CS_FINAL_STATS: if ( key_pressed==SDLK_SPACE ) abort = 1; break; case CS_FATAL_ERROR: /* after game was violently broken up the server * may still send the stats of the game so far */ if ( button_clicked || key_pressed ) { SDL_Delay(250); /* give time to release button */ set_state( CS_RECV_STATS ); display_text( font, "Receiving final stats..." ); } break; case CS_FINAL_TABLE: if ( button_clicked || key_pressed ) { check_highscores(); select_chart( game_set->name, 0 ); /* remove saved game */ slot_delete( 0 ); slot_update_hint( 0, item_resume_0->hint ); /* quit local game */ abort = 1; } break; case CS_SCORE_TABLE: /* show who's next player and scores in local game */ display_score_table( "Next Player: %s", cur_player->name ); set_state( CS_GET_READY ); break; case CS_BONUS_LEVEL_SCORE: /* display total score from this level for player */ display_bonus_level_score(); set_state( CS_GET_READY_FOR_NEXT_LEVEL ); break; case CS_FINAL_PLAYER_INFO: if ( button_clicked || key_pressed ) { SDL_Delay(250); /* give time to release button */ set_state( CS_NEXT_PLAYER ); } break; case CS_RECV_LEVEL: comm_recv(); if ( cur_player->next_level_received ) { cur_player->next_level_received = 0; cur_player->paddle_id = cur_player->next_paddle_id; init_next_round(); } break; case CS_RECV_STATS: comm_recv(); if ( stats_received ) { set_state( CS_FINAL_STATS ); display_final_stats(); } break; case CS_ROUND_RESULT: if ( button_clicked || key_pressed ) { SDL_Delay(250); /* give time to release button */ if ( game_over ) { set_state( CS_RECV_STATS ); display_text( font, "Receiving final stats..." ); } else { set_state( CS_RECV_LEVEL ); display_text( font, "Receiving level data..." ); } } break; case CS_GET_READY: if ( button_clicked || key_pressed ) { SDL_Delay(250); /* give time to release button */ comm_send_short( MSG_READY ); set_state( CS_PLAY ); } break; case CS_GET_READY_FOR_NEXT_LEVEL: if ( button_clicked || key_pressed ) { SDL_Delay(250); /* give time to release button */ set_state( CS_NEXT_LEVEL ); } break; case CS_PAUSE: if ( game->game_type == GT_LOCAL ) break; /* check wether pause chatroom has been closed * either by client or remote */ comm_recv(); break; case CS_PLAY: /* hide objects */ begin_frame(); /* apply events to local paddle */ paddle_handle_events( l_paddle, ms ); /* update local objects and communicate if * comm_delay ms have passed */ update_game( ms ); /* show objects */ end_frame(); /* handle local level over */ if ( game->level_over ) { if ( game->game_type == GT_LOCAL ) { if ( game_set == 0 ) { abort = 1; /* was a test level */ grab_input(0); break; } if ( game->winner == PADDLE_BOTTOM ) { if (local_game->isBonusLevel) set_state( CS_BONUS_LEVEL_SCORE ); else set_state( CS_NEXT_LEVEL ); } else set_state( CS_LOOSE_LIFE ); } else { finalize_round(); } } break; case CS_NEXT_LEVEL: /* apply paddle stats to player */ game_set_current( local_game ); game_update_stats( PADDLE_BOTTOM, &cur_player->stats ); game_set_current( game ); /* init next level for player in local game */ cur_player->level_id++; if ( cur_player->level_id >= game_set->count ) { /* deactivate player */ cur_player->lives = 0; display_text( font, "You've cleared all levels...#Congratulations!!!" ); set_state( CS_FINAL_PLAYER_INFO ); break; } /* get snapshot for next init */ cur_player->snapshot = *game_set->levels[cur_player->level_id]; /* cycle players */ set_state( CS_NEXT_PLAYER ); break; case CS_RESTART_LEVEL: /* apply paddle stats to player */ game_set_current( local_game ); game_update_stats( PADDLE_BOTTOM, &cur_player->stats ); game_set_current( game ); /* reset level for next turn */ cur_player->snapshot = *game_set->levels[cur_player->level_id]; /* decrease lives (is checked that this wasn't the last one) */ cur_player->lives--; /* cycle players */ set_state( CS_NEXT_PLAYER ); break; case CS_LOOSE_LIFE: /* apply paddle stats to player */ game_set_current( local_game ); game_update_stats( PADDLE_BOTTOM, &cur_player->stats ); game_set_current( game ); /* remember level for next turn */ game_get_level_snapshot( &cur_player->snapshot ); /* decrease lives */ cur_player->lives--; if ( cur_player->lives == 0 ) { display_text( font, "You've lost all lives...#Do you want to buy a continue#for 100%% of your score? y/n" ); set_state( CS_CONFIRM_CONTINUE ); //set_state( CS_FINAL_PLAYER_INFO ); break; } set_state( CS_NEXT_PLAYER ); break; case CS_NEXT_PLAYER: /* game over? */ if ( players_count() == 0 ) { display_score_table( "Game Over!" ); set_state( CS_FINAL_TABLE ); break; } /* speak and fade */ play_speech(); fade_anims(); /* finalize current game context */ finalize_level(); /* set next player */ cur_player = players_get_next(); init_level( cur_player, PADDLE_BOTTOM ); if ( player_count > 1 ) set_state( CS_SCORE_TABLE ); else { set_state( CS_PLAY ); /* one player starts immediately */ stk_display_update( STK_UPDATE_ALL ); } break; case CS_CONFIRM_CONTINUE: case CS_CONFIRM_QUIT: case CS_CONFIRM_WARP: case CS_CONFIRM_RESTART: if ( key_pressed == 0 ) break; if ( key_pressed==SDLK_n||key_pressed==SDLK_ESCAPE ) { /* if denying continue... DIE!!! */ if ( client_state == CS_CONFIRM_CONTINUE ) { SDL_Delay(250); /* give time to release button */ set_state( CS_NEXT_PLAYER ); //set_state( CS_FINAL_PLAYER_INFO ); } else set_state( CS_PLAY ); break; } if ( key_pressed != SDLK_y && key_pressed != SDLK_z ) break; /* handle confirmed action */ SDL_Delay(250); /* give time to release button */ switch( client_state ) { case CS_CONFIRM_CONTINUE: /* clear score and give full lives again */ cur_player->lives = game->diff->lives; cur_player->stats.total_score = 0; set_state( CS_NEXT_PLAYER ); break; case CS_CONFIRM_QUIT: comm_send_short( MSG_QUIT_GAME ); if ( game->game_type == GT_LOCAL ) { /* apply paddle stats to player */ game_set_current( local_game ); game_update_stats( PADDLE_BOTTOM, &cur_player->stats ); game_set_current( game ); /* no higscore check anymore as game is supposed to * be resumed until normal game over */ /* testing levels don't got for * high scores *** if ( game_set ) { check_highscores(); select_chart( game_set->name, 0 ); }*/ /* save local game */ if ( game_set != 0 /*not testing a level*/ ) save_local_game( 0 ); abort = 1; } else { /* await game stats */ set_state( CS_RECV_STATS ); display_text( font, "Receiving final stats..." ); } break; case CS_CONFIRM_WARP: game->winner = -1; /* no speech */ local_game->winner = -1; /* not counted as win */ /* substract doubled score of remaining bricks */ penalty = 0; for ( i = 0; i < MAP_WIDTH; i++ ) for ( j = 0; j < MAP_HEIGHT; j++ ) if ( local_game->bricks[i][j].dur != -1 ) penalty += local_game->bricks[i][j].score; printf( "warp penalty: -%d\n", penalty ); local_game->paddles[0]->score -= penalty; set_state( CS_NEXT_LEVEL ); break; case CS_CONFIRM_RESTART: game->winner = -1; /* no speech */ local_game->winner = -1; /* not counted as win */ local_game->level_over = 1; set_state( CS_RESTART_LEVEL ); break; } break; } /* update anything that was changed */ stk_display_update( STK_UPDATE_RECTS ); /* get time since last call and delay if below frame_delay */ ms = stk_timer_get_time(); if ( ms < frame_delay ) { SDL_Delay( frame_delay - ms ); ms += stk_timer_get_time(); } frames++; } finalize_level(); client_state = CLIENT_NONE; stk_display_fade( STK_FADE_OUT, STK_FADE_DEFAULT_TIME ); if ( stk_quit_request ) comm_send_short( MSG_DISCONNECT ); else comm_send_short( MSG_UNHIDE ); /* frame rate */ frame_time = SDL_GetTicks() - frame_time; printf( "Time: %.2f, Frames: %i -> FPS: %.2f\n", (double)frame_time / 1000, frames, 1000.0*frames/frame_time ); event_clear_sdl_queue(); /* update the selected user and the user list in network as * we received ADD/REMOVE_USER messages */ gui_list_update( list_users, client_users->count ); /* re-select current entry */ if ( client_user ) { i = list_check( client_users, client_user ); if ( i != -1 ) gui_list_select( list_users, 0, i, 1 ); } }
void VideoViewer(const std::string& input_uri, const std::string& output_uri) { pangolin::Var<int> record_timelapse_frame_skip("viewer.record_timelapse_frame_skip", 1 ); pangolin::Var<int> end_frame("viewer.end_frame", std::numeric_limits<int>::max() ); pangolin::Var<bool> video_wait("video.wait", true); pangolin::Var<bool> video_newest("video.newest", false); // Open Video by URI pangolin::VideoRecordRepeat video(input_uri, output_uri); const size_t num_streams = video.Streams().size(); if(num_streams == 0) { pango_print_error("No video streams from device.\n"); return; } // Output details of video stream for(size_t s = 0; s < num_streams; ++s) { const pangolin::StreamInfo& si = video.Streams()[s]; std::cout << "Stream " << s << ": " << si.Width() << " x " << si.Height() << " " << si.PixFormat().format << " (pitch: " << si.Pitch() << " bytes)" << std::endl; } // Check if video supports VideoPlaybackInterface pangolin::VideoPlaybackInterface* video_playback = pangolin::FindFirstMatchingVideoInterface<pangolin::VideoPlaybackInterface>(video); const int total_frames = video_playback ? video_playback->GetTotalFrames() : std::numeric_limits<int>::max(); const int slider_size = (total_frames < std::numeric_limits<int>::max() ? 20 : 0); if( video_playback ) { if(total_frames < std::numeric_limits<int>::max() ) { std::cout << "Video length: " << total_frames << " frames" << std::endl; } end_frame = 0; } std::vector<unsigned char> buffer; buffer.resize(video.SizeBytes()+1); // Create OpenGL window - guess sensible dimensions pangolin::CreateWindowAndBind( "VideoViewer", (int)(video.Width() * num_streams), (int)(video.Height() + slider_size) ); // Assume packed OpenGL data unless otherwise specified glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ALIGNMENT, 1); glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Setup resizable views for video streams std::vector<pangolin::GlPixFormat> glfmt; std::vector<std::pair<float,float> > gloffsetscale; std::vector<size_t> strides; std::vector<pangolin::ImageViewHandler> handlers; handlers.reserve(num_streams); size_t scratch_buffer_bytes = 0; pangolin::View& container = pangolin::Display("streams"); container.SetLayout(pangolin::LayoutEqual) .SetBounds(pangolin::Attach::Pix(slider_size), 1.0, 0.0, 1.0); for(unsigned int d=0; d < num_streams; ++d) { const pangolin::StreamInfo& si = video.Streams()[d]; pangolin::View& view = pangolin::CreateDisplay().SetAspect(si.Aspect()); container.AddDisplay(view); glfmt.push_back(pangolin::GlPixFormat(si.PixFormat())); gloffsetscale.push_back(std::pair<float,float>(0.0f, 1.0f) ); if( si.PixFormat().bpp % 8 ) { pango_print_warn("Stream %i: Unable to display formats that are not a multiple of 8 bits.", d); } if( (8*si.Pitch()) % si.PixFormat().bpp ) { pango_print_warn("Stream %i: Unable to display formats whose pitch is not a whole number of pixels.", d); } if(glfmt.back().gltype == GL_DOUBLE) { scratch_buffer_bytes = std::max(scratch_buffer_bytes, sizeof(float)*si.Width() * si.Height()); } strides.push_back( (8*si.Pitch()) / si.PixFormat().bpp ); handlers.push_back( pangolin::ImageViewHandler(si.Width(), si.Height()) ); view.SetHandler(&handlers.back()); } // current frame in memory buffer and displaying. pangolin::Var<int> frame("ui.frame", -1, 0, total_frames-1 ); pangolin::Slider frame_slider("frame", frame.Ref() ); if(video_playback && total_frames < std::numeric_limits<int>::max()) { frame_slider.SetBounds(0.0, pangolin::Attach::Pix(slider_size), 0.0, 1.0); pangolin::DisplayBase().AddDisplay(frame_slider); } std::vector<unsigned char> scratch_buffer; scratch_buffer.resize(scratch_buffer_bytes); std::vector<pangolin::Image<unsigned char> > images; #ifdef CALLEE_HAS_CPP11 const int FRAME_SKIP = 30; const char show_hide_keys[] = {'1','2','3','4','5','6','7','8','9'}; const char screenshot_keys[] = {'!','"','#','$','%','^','&','*','('}; // Show/hide streams for(size_t v=0; v < container.NumChildren() && v < 9; v++) { pangolin::RegisterKeyPressCallback(show_hide_keys[v], [v,&container](){ container[v].ToggleShow(); } ); pangolin::RegisterKeyPressCallback(screenshot_keys[v], [v,&images,&video](){ if(v < images.size() && images[v].ptr) { try{ pangolin::SaveImage( images[v], video.Streams()[v].PixFormat(), pangolin::MakeUniqueFilename("capture.png") ); }catch(std::exception e){ pango_print_error("Unable to save frame: %s\n", e.what()); } } } ); } pangolin::RegisterKeyPressCallback('r', [&](){ if(!video.IsRecording()) { video.SetTimelapse( static_cast<size_t>(record_timelapse_frame_skip) ); video.Record(); pango_print_info("Started Recording.\n"); }else{ video.Stop(); pango_print_info("Finished recording.\n"); } fflush(stdout); }); pangolin::RegisterKeyPressCallback('p', [&](){ video.Play(); end_frame = std::numeric_limits<int>::max(); pango_print_info("Playing from file log.\n"); fflush(stdout); }); pangolin::RegisterKeyPressCallback('s', [&](){ video.Source(); end_frame = std::numeric_limits<int>::max(); pango_print_info("Playing from source input.\n"); fflush(stdout); }); pangolin::RegisterKeyPressCallback(' ', [&](){ end_frame = (frame < end_frame) ? frame : std::numeric_limits<int>::max(); }); pangolin::RegisterKeyPressCallback('w', [&](){ video_wait = !video_wait; if(video_wait) { pango_print_info("Gui wait's for video frame.\n"); }else{ pango_print_info("Gui doesn't wait for video frame.\n"); } }); pangolin::RegisterKeyPressCallback('d', [&](){ video_newest = !video_newest; if(video_newest) { pango_print_info("Discarding old frames.\n"); }else{ pango_print_info("Not discarding old frames.\n"); } }); pangolin::RegisterKeyPressCallback('<', [&](){ if(video_playback) { frame = video_playback->Seek(frame - FRAME_SKIP) -1; end_frame = frame + 1; }else{ pango_print_warn("Unable to skip backward."); } }); pangolin::RegisterKeyPressCallback('>', [&](){ if(video_playback) { frame = video_playback->Seek(frame + FRAME_SKIP) -1; end_frame = frame + 1; }else{ end_frame = frame + FRAME_SKIP; } }); pangolin::RegisterKeyPressCallback(',', [&](){ if(video_playback) { frame = video_playback->Seek(frame - 1) -1; end_frame = frame+1; }else{ pango_print_warn("Unable to skip backward."); } }); pangolin::RegisterKeyPressCallback('.', [&](){ // Pause at next frame end_frame = frame+1; }); pangolin::RegisterKeyPressCallback('0', [&](){ video.RecordOneFrame(); }); pangolin::RegisterKeyPressCallback('a', [&](){ // Adapt scale for(unsigned int i=0; i<images.size(); ++i) { if(container[i].HasFocus()) { pangolin::Image<unsigned char>& img = images[i]; pangolin::ImageViewHandler& ivh = handlers[i]; const bool have_selection = std::isfinite(ivh.GetSelection().Area()) && std::abs(ivh.GetSelection().Area()) >= 4; pangolin::XYRangef froi = have_selection ? ivh.GetSelection() : ivh.GetViewToRender(); gloffsetscale[i] = pangolin::GetOffsetScale(img, froi.Cast<int>(), glfmt[i]); } } }); pangolin::RegisterKeyPressCallback('g', [&](){ std::pair<float,float> os_default(0.0f, 1.0f); // Get the scale and offset from the container that has focus. for(unsigned int i=0; i<images.size(); ++i) { if(container[i].HasFocus()) { pangolin::Image<unsigned char>& img = images[i]; pangolin::ImageViewHandler& ivh = handlers[i]; const bool have_selection = std::isfinite(ivh.GetSelection().Area()) && std::abs(ivh.GetSelection().Area()) >= 4; pangolin::XYRangef froi = have_selection ? ivh.GetSelection() : ivh.GetViewToRender(); os_default = pangolin::GetOffsetScale(img, froi.Cast<int>(), glfmt[i]); break; } } // Adapt scale for all images equally // TODO : we're assuming the type of all the containers images' are the same. for(unsigned int i=0; i<images.size(); ++i) { gloffsetscale[i] = os_default; } }); #endif // CALLEE_HAS_CPP11 #ifdef DEBUGVIDEOVIEWER unsigned int delayms = 0; pangolin::RegisterKeyPressCallback('z', [&](){ // Adapt delay delayms += 1; std::cout << " Fake delay " << delayms << "ms" << std::endl; }); pangolin::RegisterKeyPressCallback('x', [&](){ // Adapt delay delayms = (delayms > 1) ? delayms-1 : 0; }); pangolin::basetime start,now; #endif // DEBUGVIDEOVIEWER // Stream and display video while(!pangolin::ShouldQuit()) { glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); glColor3f(1.0f, 1.0f, 1.0f); if(frame.GuiChanged()) { if(video_playback) { frame = video_playback->Seek(frame) -1; } end_frame = frame + 1; } #ifdef DEBUGVIDEOVIEWER boostd::this_thread::sleep_for(boostd::chrono::milliseconds(delayms)); std::cout << "-------------------------------------------------------" << std::endl; now = pangolin::TimeNow(); std::cout << " FPS: " << 1.0/pangolin::TimeDiff_s(start, now) << " artificial delay: " << delayms <<"ms"<< std::endl; std::cout << "-------------------------------------------------------" << std::endl; start = now; #endif if ( frame < end_frame ) { if( video.Grab(&buffer[0], images, video_wait, video_newest) ) { frame = frame +1; } } #ifdef DEBUGVIDEOVIEWER const pangolin::basetime end = pangolin::TimeNow(); std::cout << "Total grab time: " << 1000*pangolin::TimeDiff_s(start, end) << "ms" << std::endl; #endif glLineWidth(1.5f); glDisable(GL_DEPTH_TEST); for(unsigned int i=0; i<images.size(); ++i) { if(container[i].IsShown()) { container[i].Activate(); pangolin::Image<unsigned char>& image = images[i]; // Get texture of correct dimension / format const pangolin::GlPixFormat& fmt = glfmt[i]; pangolin::GlTexture& tex = pangolin::TextureCache::I().GlTex((GLsizei)image.w, (GLsizei)image.h, fmt.scalable_internal_format, fmt.glformat, GL_FLOAT); // Upload image data to texture tex.Bind(); if(fmt.gltype == GL_DOUBLE) { // Convert to float first, using scrath_buffer for storage pangolin::Image<float> fimage(image.w, image.h, image.w*sizeof(float), (float*)scratch_buffer.data()); ConvertPixels<float,double>( fimage, image.Reinterpret<double>() ); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); tex.Upload(fimage.ptr,0,0, (GLsizei)fimage.w, (GLsizei)fimage.h, fmt.glformat, GL_FLOAT); }else{ glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint)strides[i]); tex.Upload(image.ptr,0,0, (GLsizei)image.w, (GLsizei)image.h, fmt.glformat, fmt.gltype); } // Render handlers[i].UpdateView(); handlers[i].glSetViewOrtho(); const std::pair<float,float> os = gloffsetscale[i]; pangolin::GlSlUtilities::OffsetAndScale(os.first, os.second); handlers[i].glRenderTexture(tex); pangolin::GlSlUtilities::UseNone(); handlers[i].glRenderOverlay(); } } glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); // leave in pixel orthographic for slider to render. pangolin::DisplayBase().ActivatePixelOrthographic(); if(video.IsRecording()) { pangolin::glRecordGraphic(pangolin::DisplayBase().v.w-14.0f, pangolin::DisplayBase().v.h-14.0f, 7.0f); } pangolin::FinishFrame(); } }