Chapter 2. Using the toogl Tool

toogl (which stands for To OpenGL and is pronounced TOO-guhl) is a script that takes IRIS GL code as input and produces commented, nearly equivalent OpenGL code as output.

This chapter explores how to use and get the most from toogl. It explains where to find a copy of toogl and how to use toogl most effectively. It also mentions some areas of your IRIS GL code that might give you problems.

The chapter discusses the following topics:

Getting Started with toogl

You can use toogl to do much of the work of translating your IRIS GL code to OpenGL code. While toogl can't do everything, it can do all the tedious work of changing command names, and it can call your attention to code you have to port explicitly.

This section first explains “Finding and Building toogl,” then provides the syntax in “Calling toogl,” and explores “Using toogl in Batch Mode.” The last section briefly discusses “What toogl Will and Won't Do for You.”

Finding and Building toogl

A copy of toogl is in the /usr/share directory. The exact location depends on the operating system version you are using. If you want to look at the source (it's in C++), you can get a copy from the OpenGL directory.

You can also get a copy of the tool from the “Contributed Tools” area of the Silicon Graphics OpenGL home page (http://www.sgi.com/Technology/openGL/)

To build the tool, enter:

# setenv OBJECT_STYLE 32
# make


Warning: If you build toogl with OBJECT_STYLE set to n32 (the default on current systems), the tool does not work!


Calling toogl

toogl syntax:

toogl [-cwq] < infile > outfile

You can use any of these options with toogl:

-c 

Don't clutter up the output with comments

-w 

Don't remove window manager calls like winopen(), mapcolor()

-q 

Don't remove event queue calls like qread(), setvaluator()


Note: toogl doesn't attempt to translate event queue and windowing calls. It simply removes them, and replaces them with warning comments. The -w and -q flags merely suppress the comments.

Keep your original source! Accidents happen.

Using toogl in Batch Mode

To process a directory full of source files automatically, you could use a shell script like the following:

#!/bin/sh
mkdir OpenGL
for i in *.c
   do
      echo "Converting " $i " ..."
      toogl < $i > OpenGL/$i
   done

What toogl Will and Won't Do for You

toogl is a filter that scans each line of an input file, looking for IRIS GL calls. When toogl finds an IRIS GL function, it replaces the function with the corresponding OpenGL function(s).

Because toogl can't translate everything, you have to edit its output. Any time toogl translates code that you may have to look at, check, or change, it marks the potential problem with a comment starting with “OGLXXX”. (You can use the -c option to suppress the comments.)

Using xdiff or gdiff to Compare Files

After you've converted your program using toogl, you have to edit the toogl output. You'll probably want to examine the differences between the toogl output and your original program—or any other version of the program. To do so, use either gdiff or xdiff.

To use gdiff, enter:

gdiff -b file1 file2

where file1 and file2 are the names of the files you want to compare. The -b option tells gdiff to ignore trailing blanks on lines when comparing files. You might also want to use the -w option, which tells gdiff to ignore white space.

To use xdiff, enter:

xdiff file1 file2

See the xdiff reference page for more information.

Using toogl Effectively

Here are a few suggestions for getting the most out of toogl:

  • For best results, use a C beautifier (such as cb) on your code before running toogl.

  • Use gdiff (or xdiff) to browse through the source and the translation simultaneously.

  • toogl expects to find the matching parentheses or quotes on the same line as the IRIS GL function.

  • toogl expects to find only spaces and tabs between a function name and the opening parenthesis. For example, the code

    v3f
    (foo);
    

    will be left unchanged, as will

    v3f /* comment */ (foo);
    

    Running a C beautifier on your program before using toogl can prevent problems like this.

  • toogl expects that C comments inside the argument list of a function don't contain parentheses or quote characters. Faced with the following code, toogl will generate a warning and will not do a translation:

    v3f ( foo /* I really mean bar “-) */ );
    

Editing toogl Output: Areas that Need Special Attention

After you've run toogl on your code, you have to edit the output. Some areas are more problematic than others—for example, v() calls usually translate quite neatly into glVertex() calls, but texture calls often don't translate well. This section lists some of the general areas that are likely to need special attention. Chapter 3, “After toogl: How to Finish Porting to OpenGL,” provides more detailed information on problem areas.

This section briefly addresses the following issues:

Windowing, Device, and Event Calls

toogl can't translate sections of code that make window manager, window configuration, device, or event calls, or that load a color map. You have to rewrite these code sections yourself. You can use the -w and -q options to make toogl leave this code untouched, so you can still read it to translate it manually. If your windowing and event handling calls are simple and straightforward, you can replace them with calls from the GLUT library. For more information on GLUT, see the OpenGL home page http://www.OpenGL.org or the Silicon Graphics OpenGL page http://www.sgi.com/Technology/openGL/. See also “GLX and GLUT Documentation”.

If your windowing and event handling calls are fairly sophisticated, you have to incorporate the OpenGL code into X Windows directly, either using the OpenGL widget or using Xlib. This is explained in Chapter 4, “OpenGL in the X Window System.”

Parentheses and Quotes

toogl understands a little about matching parentheses and quotes. It translates

v3f( v[strlen(strcat(foo, "foo("))] );

into

glVertex3fv( v[strlen(strcat(foo, "foo("))] );

Defined Color Constants

IRIS GL provides defined color constants: BLACK, BLUE, RED, GREEN, MAGENTA, CYAN, YELLOW, and WHITE. OpenGL does not provide these constants and toogl does not translate them, so you have to port them explicitly.

clear() Calls

Make sure clear() calls are correctly translated. For example, assume your program clears the window as follows:

color(BLACK);
clear();

toogl translates those two lines as follows:

glIndex(BLACK);
glClear(GL_COLOR_BUFFER_BIT);

The above code fragment is incorrect for these reasons:

  • OpenGL does not provide the color constant BLACK

  • OpenGL maintains a clear color that's distinct from the drawing color.

A better translation is the following:

glIndex(0);
glClearIndex(0);
glClear(GL_COLOR_BUFFER_BIT);

Get Calls

toogl does not always translate IRIS GL “get” calls (such as getdepth(), getcolor(), and so on) correctly. toogl translates

i = getcolor();
getdepth(&near, &far);

into

/* OGLXXX replace value with your variable */
i = glGetIntegerv(GL_CURRENT_INDEX, &value);

/* OGLXXX You can probably do better than this. */
{
  int get_depth_tmp[2];
  glGetIntegerv(GL_DEPTH_RANGE, get_depth_tmp);
  *(&near)=get_depth_tmp[0];
  *( &far)=get_depth_tmp[1];
};

This guide lists the glGet*() calls related to a particular topic in the section on that topic. For general information on replacing get calls, see “Porting IRIS GL get* Commands”.

rotate() Calls

The OpenGL rotation call glRotate() is different from rotate(). You will probably have to modify the code after translating the program with toogl. See “Porting Matrix and Transformation Calls” for details.

swaptmesh() Calls

OpenGL has no equivalent for swaptmesh(); toogl flags occurrences of the function and leaves it up to you to restructure your triangles.

Texturing Calls

toogl correctly translates texture coordinate calls. You have to do additional work, as explained in “Porting Texture Calls”.


Note: If you're using OpenGL 1.1, you can take advantage of subtextures. Because toogl was developed for OpenGL 1.0, you have to implement the use of OpenGL subtextures yourself.


def/bind Calls

OpenGL does not keep tables of predefined lights and materials, so it has no equivalent for “binds.” You can use display lists to mimic the behavior. See “Porting defs, binds, and sets: Replacing `Tables' of Stored Definitions” for more information. See also “Porting Lighting and Materials Calls” and “Porting Texture Calls” for more discussion and some examples.

Calls Without Direct Equivalents

There are some IRIS GL calls that toogl cannot directly translate into OpenGL calls. arcf() is one example. You have to port such calls explicitly. “Editing toogl Output: An Example” gives an example for porting a call like arcf().

Finding OpenGL Replacements for IRIS GL Calls

Appendix A, “OpenGL Commands and Their IRIS GL Equivalents,” contains a table listing IRIS GL commands and the corresponding OpenGL commands, and tells you where to go for more information. This table also indicates which IRIS GL calls are not supported in OpenGL.

Performance

toogl doesn't necessarily produce fast OpenGL code; in fact, such an automatic port usually results in loss of performance. Details of improving OpenGL performance are beyond the scope of the current edition of this guide; however, you can find some specific tips in “Porting Screen and Buffer Clearing Commands” and “Porting Lighting and Materials Calls”.


Note: The performance chapters of OpenGL on Silicon Graphics Systems provide additional information.

Two features of OpenGL that can drastically improve performance are display lists and direct rendering. Use these features whenever possible in OpenGL programs. For information on display lists, see “Porting Display Lists” in Chapter 3. For information on direct rendering, see the glXCreateContext reference page. If you aren't careful, you may set up indirect rendering without noticing that it's indirect; specify direct rendering explicitly where possible.

Here are few more tips:

  • If you're drawing independent triangles, there's no need to put glBegin() and glEnd() around each set of three vertices. Instead, call glBegin(GL_TRIANGLES) and then list as many individual triangles as you need before the glEnd(). This optimization alone can noticeably improve performance.

  • If you aren't using the depth buffer, disable it. This is particularly important when you call glDrawPixels() or other non-3D drawing functions.

  • Disable texturing when you call glDrawPixels() or any other function that shouldn't use textures. Otherwise, the texture overhead slows down drawing even if you're only drawing a bitmap.

Editing toogl Output: An Example

This section provides an example for working with toogl output.

toogl translates the call

arcf(1.0, 1.0, 0.9, 1200, 2200);

as

/* OGLXXX see gluPartialDisk man page */
gluPartialDisk( *gobj, innerRad, outerRad, slices, loops, startAng, endAng);

The IRIS GL call arcf() can't be directly translated into an OpenGL call. The GL Utility Library call gluPartialDisk() is the nearest equivalent, but you have to fill in its arguments explicitly. Compare the reference pages for the two commands, or refer to the section in this guide that discusses porting that command (in this case, “Porting Arcs and Circles”).

Those materials explain that you have to account for the following changes:

  • Arcs are now quadrics and are drawn using quadric objects.

  • Angles are now measured in degrees instead of tenths of degrees.

  • Instead of specifying a center for your arc in the call, you now do a translation first.

  • Angles are now measured on different coordinate axes. The second angle is now a sweep angle instead of an end angle.

Your completed arcf() translation might look like this:

gluQuadricObj *arcObj;
arcObj = gluNewQuadric(void);
glTranslatef( 1.0, 1.0, 0.0 );
gluPartialDisk( *arcObj, 0.0, 0.9, 100, 2, -30, -100);