Chapter 2. Using the toogl Tool
Prev |  | Next

## 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” explains how you can get a copy of `toogl` and then explores calling `toogl` for one file and in batch mode.

- “Using xdiff or gdiff to Compare Files” explains two tools that are helpful for comparing your original IRIS GL file with the OpenGL output produced by `toogl`.

- “Using toogl Effectively”

- “Editing toogl Output: Areas that Need Special Attention”

- “Editing toogl Output: An Example”

## 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”

- “Parentheses and Quotes”

- “Defined Color Constants”

- “clear() Calls”

- “Get Calls”

- “rotate() Calls”

- “swaptmesh() Calls”

- “Texturing Calls”

- “def/bind Calls”

- “Calls Without Direct Equivalents”

- “Finding OpenGL Replacements for IRIS GL Calls”

- “Performance”

### 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);

Prev | Table of Contents | Next
Chapter 1. Introduction to Porting From IRIS GL to OpenGL |  | Chapter 3. After toogl: How to Finish Porting to OpenGL