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!