Making test cases as simple as possible is especially important with Performer applications due to the high number of OpenGL calls that Performer generates.
We are going to use ogldebug to produce firstly a gls trace file, which is a list of OpenGL function calls encoded in ogldebug's gls language. Then we will use ogldebug to play back the gls file, and then to produce compilable C programs based on either GLUT or X. I will be using a real example, the test case of which is called simpleBug - it must be run with a file called ground.iv. The source code is simpleBug.C.
Ogldebug allows you to specify a display for the ogldebug GUI with the -display option, and a separate display for the test case to display to, with the -appdisplay option. If your test case is a full screen application, which is often the case with Performer applications, this may prove more convenient.
Run the test case in ogldebug (I need to use ogldebug32 - ogldebug will inform you if you should do so with your test case) :-
IRIS# ogldebug32 ./simpleBug ground.iv
The ogldebug window appears, and proceeds to run the test case,
but blocks on the first OpenGL function call.
Hit the 'Continue' button, and wait for the test case to finish rendering. Push the test case's window to the back, so that the ogldebug window is visible. While the test case was rendering, ogldebug was recording all the OpenGL calls made by the application. We now need to save that recording to a file. |
Select 'Call History' from the 'Information' menu. A 'GL Context' window
appears, listing all the OpenGL contexts the test case created.
Ogldebug records the OpenGL functions calls made within each OpenGL context separately. This makes it much easier to isolate drawing to different buffers. My Performer test case has three separate contexts. I have found that the last context listed, in this case GL context 3, is the one which represents the main Performer window. Selecting the 'GL context 3' line will bring up a 'GL Context 3 History Panel', and a quick look over the list should confirm it is the correct context - it should be much longer than the other contexts. |
With Performer applications which are anything more than simple, the list of OpenGL functions it calls will be extremely lengthy. When this is the case, ogldebug avoids immediately listing them, and will, instead, bring up a dialogue asking if you want to view them, or just save them. |
If you're sure it is the correct context, then there is no need to view them - simply hit save. A file selection dialogue box will appear, allowing you to specify a file. By default it is the test case's filename with '.gls' appended, in this case simpleBug.gls After it has finished saving, quit ogldebug by hitting 'Cancel' on the two windows, and selecting 'Quit' from the file menu. |
You may now use ogldebug to play back the gls file. Ogldebug seems somewhat unreliable in this function, so don't expect it to work. Different (older) versions may do a better job. For our task, it isn't important that this work, so it isn't a problem.
The next step is to use ogldebug to convert the gls file into a compilable C program (it can produce a C code snippet also for including in your own programs). It can produce code based on GLUT, or on X. It doesn't matter too much which you choose, but if you are going to submit the program as a test case for a bug, then I would recommend using X.
The following command will convert the gls file into a compilable C program based on GLUT :-
IRIS# ogldebug32 -gls2glut simpleBug.gls > simpleBug.glut.c
to compile, use the standard GLUT compile line (from the glut(3GLUT) man page) :-
IRIS# cc -o simpleBug.glut simpleBug.glut.c -lglut -lGLU -lGL -lXmu -lXi -lXext -lX11 -lm
To convert to a compilable program based on X :-
IRIS# ogldebug32 -gls2x simpleBug.gls > simpleBug.x.c
which can be compiled with :-
IRIS# cc -o simpleBug.x simpleBug.x.c -lGL -lXext -lX11
Now you have an simple version of the test case, which doesn't involve
any of the complexities of a Performer application.
|
|
---|---|
Performer does tend to make _alot_ of OpenGL calls, even for simple
scenes. Before submitting a program such as the above, it would be worth
editing the program by hand - the OpenGL function calls are placed in a
function called DrawScene()for X, and Draw() for GLUT.
For example, in the simpleBug.x.c program produced
above, the DrawScene() function contains a lot of glGetString()
function calls, the return values of which is ignored. These can quite
likely be removed without affecting the main purpose of the program. Also,
Performer creates a lot of display lists for fonts, which it uses in it's
GUI and stats graph. These can safely be removed. Beyond that, you may
find things such as redundant state setting, such as two sequential calls
to color(), for example - obviously only the latter call has any lasting
effect. You should use your own judgement, and test frequently to see if
removing calls affects the display of the problem. The smaller the program
you can get, the less time engineers have to spend on narrowing it down,
and the more time they get to spend on developing spiffing new products
:-)
Of course, with this functionality, ogldebug can be a great help when converting IrisGL code to OpenGL.
switch (keySym) {
case XK_Escape:
exit(EXIT_SUCCESS);
default:
break;
}
Adding another case with, say XK_Down or XK_Up, is straight forward.
I used just this technique to quickly develop a gangdraw program to test the swapready functionality of an Onyx. I called the program gangrene.c.
First, run the GLUT program in ogldebug to produce a gls file and convert that gls file to X. If the GLUT example was also produced with ogldebug, this should prove sufficient. Otherwise, parts of the GLUT program will need to be copied into the relevant part of the X program. How easy this is, will depend on how similar the GLUT example was to an example output by ogldebug.
I found this method useful when an engineer, who was working on a bug I had submitted, requested a test case based on X rather than GLUT. Converting it took a matter of a minute or two, which impressed said engineer :-)