"There's no problem in Computer Science that can't be solved by an added layer of indirection."
Bypass abstracts away the system-specific details of library call interception, allowing the user to write a single source file that will compile on many different architectures without lots of nasty #ifdefs and similar garbage.
Bypass was written by Doug Thain at the University of Wisconsin as a part of his Ph.D. work with the Condor project. Bypass can downloaded from the Bypass webpage.
Currently, there are two basic forms of command the controller can send. First, it can tell the shared object to override the settings of certain OpenGL parameters. It can also tell the shared object to stop overriding these settings. Second, it can enable and disable special rendering effects, like cartoon shading.
If the OpenGL application tries to change an overridden parameter, jefGL doesn't not pass the call down to OpenGL. However, it can't just throw the new value away. It needs to keep it for two reasons. First, if overriding of the parameter is turned off later, jefGL needs to restore the latest value set by the application. Second, if the application later queries the value of the parameter, jefGL needs to return the last value set by the application, not the overriding value. This keeps the application completely unaware of what's going on.
Currently, most lighting and material parameters can be overridden. This includes the ambient, diffuse and specular settings of the lights and the global ambient setting. Individual lights and lighting as a whole can also be turned on and off. The ambient, diffuse, specular, and shininess settings of objects can also be modified, as can the color parameter (when lighting is disabled). Changing material and color properties modifies all objects in the scene.
In jefGL, glNormal calls are caught and the normal saved (after having the modelview matrix applied). Then, on each glVertex call, the normal is dotted with a vector from the light to the vertex. If the result is negative, the normal is facing towards the light. Otherwise, it's facing away. In cartoon shading, lighting is disabled and glColor is set to the highlight color for light-facing vertices and the shadow color for non-light-facing vertices. The highlight and shadow colors are calculated from the material and light's ambient and diffuse settings in the same way OpenGL calculates lighting colors (the shadow color has no diffuse component while the highlight has a full diffuse component).
One such effect is the outlining of cartoon shaded objects. The effecient algorithms I found required knowing which sets of polygons form a single object or the drawing of all front-facing polygons of an object before the back-facing ones. Neither of these is easy to know at the level at whcih jefGL sits.
Another hard effect is the setting of a different viewing position. Setting a new viewing position thats relative to the one specified by the application is easy: just prepend your transformation matrix to the front of the modelview matrix. But setting an absolute new position is difficult. This is because it's impossible to reliably differentiate viewpoint-setting transformations from object-positioning transformations (unless the application is only using gluLookAt to set the viewing position).
Another difficult task is setting properties for a limited set of objects. As mentioned earlier, it's hard to reliably distinguish one object's polygons from the next's. So when jefGL changes object properties, they affect everything in the scene.
There is a performance penalty for using jefGL. Applications can be slowed down by up to 25% even when jefGL isn't modifying anything.. This is primarily due to the interception of all glVertex* and glNormal* calls, which is done for the cartoon shading and wire framing. Unfortunately, there isn't a way to disable the interception of selected calls at run time with Bypass. Otherwise, you could decide to not intercept glVertex* and glNormal* calls when cartoon shading and wire framing are turned off.