glutIdleFunc

Hi, I’m having a really frustrating problem with glutIdleFunc, and I hope you guys can help!

I’ve set a function as the Idle function (with glutIdleFunc) which just syncs data with another thread (which handles the physics of my application) then calls glutPostWindowRedisplay() on my 3 sub-windows. This all works fine, except that the idle func is called regularly about every 10-20ms, for about 2 secs then doesn’t get called for a whole half second! the result is nice smooth animation for 2 seconds followed by a half second pause at regular intervals.

I’ve spent a good few hours crawling though my code, searching for bugs or loops that might account for this, but I’m certain there aren’t any - I compiled my program on another machine and it ran seamlessly.

I’ve tried enabling and disabling syncing to v-blank in my system setting, but it has no effect - if somebody has a foolproof way of enabling and disabling it on a linux system please let me know!

my system is a 64-bit linux (fedora 13) with nvidia drivers installed.

If someone has any ideas or suggestions please let me know - I know there’s not much to go on, but I’m really stuck with this one!

Try doing something really basic in your idle func like waiting a few milliseconds to simulate it and see if the problem is related to inconsistent thread performance or if it’s possibly thread related.

Thanks. I commented out the whole idle func and replaced it with

static unsigned long int i = 0;
  std::cout << "update_lander_state " << i++ << "\r" << std::flush;
  usleep(5000);

It ran smoothly, so I uncommented each function until it didn’t, and found that the entire jerkyness is caused by the another function, so I treated it the same way, (commented out everything, then added stuff back in until I found which part was to blame) and I eventually discovered that it was being caused by my three calls to glutPostWindowRedisplay. (by that I mean that calling any one of them causes it to be jerky)
First I tried commenting out the entire of the display call-back to each window, which changed nothing. So then I removed the calls to glutDisplayFunc, and the counter was smooth.

So, a more specific description of the problem is - calling glutPostWindowRedisplay when there’s a display callback set (even if it’s an empty function which does nothing) sometimes causes up to a 500mS delay somewhere between the point where the idle function returns and the display callback gets called.

I’ll include my main function, in case I’ve done something weird during my initiation of glut/gl

int main (int argc, char* argv[])
  // Initializes GLUT windows and lander state, then enters GLUT main loop
{
  atexit(cleanup);
  
  int i;

  // Main GLUT window
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
  glutInitWindowPosition(0, 0);
  glutInitWindowSize(PREFERRED_WIDTH, PREFERRED_HEIGHT);
  view_width = (PREFERRED_WIDTH - 4*GAP)/2;
  view_height = (PREFERRED_HEIGHT - INSTRUMENT_HEIGHT - 4*GAP);
  main_window = glutCreateWindow("Mars Lander Simulation");
  glDrawBuffer(GL_BACK);
  glLineWidth(2.0);
  glDisable(GL_LIGHTING);
  glDisable(GL_DEPTH_TEST);
  glutDisplayFunc(draw_main_window);
  glutReshapeFunc(reshape_main_window);
  set_drawing(true);
  glutKeyboardFunc(glut_key);
  glutSpecialFunc(glut_special);

  // The close-up view subwindow
  closeup_window = glutCreateSubWindow(main_window, GAP, GAP, view_width, view_height);
  glDrawBuffer(GL_BACK);
  setup_lights();
  glEnable(GL_DEPTH_TEST);
  glEnable(GL_LIGHTING);
  glEnable(GL_CULL_FACE); // we only need back faces for the parachute
  glDisable(GL_BLEND);
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  glEnable(GL_NORMALIZE);
  glDepthFunc(GL_LEQUAL);
  glShadeModel(GL_SMOOTH);
  glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
  glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); // we need two-sided lighting for the parachute
  glEnable(GL_COLOR_MATERIAL);
  glFogi(GL_FOG_MODE, GL_EXP);
  glutDisplayFunc(draw_closeup_window);
  glutMouseFunc(closeup_mouse_button);
  glutMotionFunc(closeup_mouse_motion);
  glutKeyboardFunc(glut_key);
  glutSpecialFunc(glut_special);
  texture_available = generate_terrain_texture();
  if (!texture_available) do_texture = false;
  closeup_offset = 50.0;
  closeup_xr = 10.0;
  closeup_yr = 0.0;
  terrain_angle = 0.0;

  // The orbital view subwindow
  orbital_window = glutCreateSubWindow(main_window, view_width + 3*GAP, GAP, view_width, view_height);
  glDrawBuffer(GL_BACK);
  setup_lights();
  glEnable(GL_DEPTH_TEST);
  glEnable(GL_LIGHTING);
  glEnable(GL_CULL_FACE); // since the only polygons in this view define a solid sphere
  glDisable(GL_BLEND);
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  glEnable(GL_NORMALIZE);
  glDepthFunc(GL_LEQUAL);
  glShadeModel(GL_SMOOTH);
  glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
  glEnable(GL_COLOR_MATERIAL);
 // glutDisplayFunc(draw_orbital_window);
  glutMouseFunc(orbital_mouse_button);
  glutMotionFunc(orbital_mouse_motion);
  glutKeyboardFunc(glut_key);
  glutSpecialFunc(glut_special);
  quadObj = gluNewQuadric();
  orbital_quat.v.x = 0.53; orbital_quat.v.y = -0.21;
  orbital_quat.v.z = 0.047; orbital_quat.s = 0.82;
  normalize_quat(orbital_quat);
  save_orbital_zoom = 1.0;
  orbital_zoom = 1.0;

  // The instrument subwindow
  instrument_window = glutCreateSubWindow(main_window, GAP, view_height + 3*GAP, 2*(view_width+GAP), INSTRUMENT_HEIGHT);
  //glutDisplayFunc(draw_instrument_window);
  glutKeyboardFunc(glut_key);
  glutSpecialFunc(glut_special);

  // Generate the random number table
  srand(0);
  for (i=0; i<N_RAND; i++) randtab[i] = (float)rand()/RAND_MAX;

  // Initialize the simulation state
  reset_simulation();
  microsecond_time(time_program_started);

  glutMainLoop();
}

Thanks!