Monday, May 16, 2005

Hacking GLUT

Here's a great website and a lifesaver -

http://sjbaker.org/steve/software/glut_hack.html

I repost the article here in case his server ever goes offline -

Hacking GLUT to Eliminate the glutMainLoop() Problem

Mark Kilgard's GLUT library is one of the most truly useful aids to portable programming. It carefully hides all the ugly issues of window manipulation, producing simple menu's, keboard, mouse and joystick I/O. If your application can tolerate the restrictions of GLUT, it's a breeze to write code that will port across dozens of dissimilar platforms.

There has to be a 'BUT'...

Yep - there certainly is. GLUT is a strictly event driven library. Essentially, all GLUT applications must set up callbacks for all the events they are interested in (Keystrokes, redisplay, resize, mouse clicks, etc) - and then hand over control to a GLUT function called 'glutMainLoop()' - which never returns. That's fine for simple programs that don't use certain other libraries - but now and again, you'll want to link a GLUT program to another library that ALSO assumes control of the main loop. Another time this can be a pain is if you want to retro-fit a simple user interface into an existing, complex application which might not be able to use the glutIdleFunc callback.

This turns off a lot of users and IMHO is an unnecessary restriction.
So What Can I do About It?
There are several ways to get around the problem of needing another library that also wants to 'own' the main loop.
  • You could attack the OTHER library and try to remove its main-loop restriction. That isn't always possible - and if you don't have the sources to the other library then you've had it.
  • You could try to create multiple execution threads - one for GLUT's main loop, another for the other library. That won't work in all operating systems - and some libraries are not at all thread-safe. This sometimes works well though.
  • You can hack GLUT.
The last option is really the reason for this Web page. I have found that a dozen lines of code is all that's required and the resulting hacked GLUT remains 100% compatible with the original library.

What Do I Do?

Locate the GLUT source code. In every release I have examined, there will be a file named lib/glut/glut_event.c

Inside that file you'll find the source for glutMainLoop(). In outline it looks like this:

/* CENTRY */
void APIENTRY
glutMainLoop(void)
{


for (;;) {

}
}
/* ENDCENTRY */

This may be changed to look like this:

/* CENTRY */
void APIENTRY
glutMainLoop(void)
{
for(;;)
glutMainLoopUpdate () ;
}
/* ENDCENTRY */

/* CENTRY */
void APIENTRY
glutMainLoopUpdate(void)
{


}
/* ENDCENTRY */

You'll have to add a declaration for glutMainLoopUpdate() into glut.h:

extern void APIENTRY glutMainLoop(void);
extern void APIENTRY glutMainLoopUpdate(void);

Recompile...and that's it.

How Do I Use It?

Now, your code can change from:

glutMainLoop () ;

...to...

while ( 1 )
glutMainLoopUpdate () ;

But more usefully, you can now use one of the callbacks of some other library to call the new glutMainLoopUpdate() function:

some_other_library_IdleFunc ( glutMainLoopUpdate ) ;
some_other_library_MainLoop () ;

Is this Reliable?

It certainly seems to be - I know of dozens of people who have used this hack (or something very close to it) without any problems. All current GLUT implementations can be fixed in the exact same way.

It does have a microscopic effect on performance because the error checking that glutMainLoop() used to do only once is now done in every iteration of glutMainLoopUpdate(). However, in all current GLUT releases, the amount of checking is truly negligable - so this should not be a concern. If it worries you then dump the error checking code - it's not checking for anything too subtle - just making sure you called glutInit and opened a window.

Will This Become a Part of the Normal GLUT Release?

Well, I begin to doubt it. It seems a simple enough change - and there is no doubt that people find it useful. However, I have now asked Mark Kilgard to include it in the release on several occasions. He refuses on grounds of unnecessary complexity - I don't understand that view - but GLUT is his baby and he has the right to release whatever he wants.

IMPORTANT NOTE:


The information in this document has been obsoleted by the arrival on the scene of the freeglut library. freeglut has the 'hack' described below included as a standard part of the library, and additionally is released under a clear OpenSource license (the Xfree license) so it can be modified and redistributed without strings attached. freeglut is a superset of the GLUT functionality and can be linked with existing GLUT applications without modifications or recompiling.

0 Comments:

Post a Comment

<< Home