[SDL] SDL alternative to glutIdleFunc()?

William Brodie-Tyrrell william at brodie-tyrrell.org
Sat Oct 21 00:29:06 PDT 2006


Stoned koala bears drooled eucalyptus spit in awe as Eric Lilja said:

> Ok, but if I used the idle func to increment a variable and then 
> redisplaying the screen, how would I do that in sdl? A timer?

What you need to do is write the main loop yourself since you don't
have glut providing it.  In your loop, you call event methods (I make
them virtual methods of my SDLDisplay class and let subclasses override
them), some of which are caused by the user and one is for drawing.

See the on_draw() method; it renders single frame.  In there, you
increment your variable and draw stuff to the screen.  Or (better yet)
follow David O's advice on making your state update aware of elapsed
wallclock time instead of mere frame numbers.

When I was using glut, the contents of my glutIdleFunc was just
"glutPostRedisplay();" and that of course causes the draw function to
be called, making it equivalent to the code below.  If you've got
separate & interesting stuff in your idle and draw functions, then
that's a little different maybe.

/// call this after initialising SDL and the scene graph
void SDLDisplay::run()
{
	done=false;
	// done is set by the stop() method, called 
	// inside some event handler
	while(!done){

		// deal with events
		SDL_Event event;
		while(SDL_PollEvent(&event)){
			switch(event.type){
			case SDL_ACTIVEEVENT:
				on_active(event.active);
				break;
			case SDL_KEYDOWN:
			case SDL_KEYUP:
				on_key(event.key);
				break;
			case SDL_MOUSEMOTION:
				on_mousemotion(event.motion);
				break;
			case SDL_MOUSEBUTTONDOWN:
			case SDL_MOUSEBUTTONUP:
				on_mousebutton(event.button);
				break;
			case SDL_JOYAXISMOTION:
				on_joyaxis(event.jaxis);
				break;
			case SDL_JOYBALLMOTION:
				on_joyball(event.jball);
				break;
			case SDL_JOYHATMOTION:
				on_joyhat(event.jhat);
				break;
			case SDL_JOYBUTTONDOWN:
			case SDL_JOYBUTTONUP:
				on_joybutton(event.jbutton);
				break;
			case SDL_QUIT:
				done=true;
				break;
			case SDL_SYSWMEVENT:
				on_syswm(event.syswm);
				break;
			case SDL_VIDEORESIZE:
				res.first=event.resize.w;
				res.second=event.resize.h;
				main_view->setViewport(0, res.first-1,
0, res.second-1); on_reshape(event.resize);
				break;
			case SDL_VIDEOEXPOSE:
				on_expose(event.expose);
				break;
			case SDL_USEREVENT:
				on_user(event.user);
				break;
			default:
				cerr << "Bad SDL event type " <<
event.type << endl; done=true;
				break;
			}
		}

		on_draw();

		glFinish();
		SDL_GL_SwapBuffers();
	}

	on_shutdown();
}


You probably want to have a function that advances time in your
program; in on_draw() you measure the elapsed time of the last frame
(perhaps SDL_GetTicks) and then call your simulation function with the
amount of time that has elapsed.  Things that move, move a distance
proportional to time, etc.  If you've got non-linear simulations, you
need to be more careful with the size and uniformity of time steps, but
simple proportional movement may be enough for you.

I use a clock class that tells me current time and time since the last
tick.  I update it like this in the on_draw() method:

rep.clock.tick();
t=rep.clock.getTime();
framedt=rep.clock.getDelta();
rep.tick(framedt);

note the last line... that sends a notification of elapsed time to all
objects that have requested such notification.


-- 
William Brodie-Tyrrell

Carpe Diem - fish of the day.

<william at brodie-tyrrell.org>
http://www.brodie-tyrrell.org/




More information about the SDL mailing list