# Ygl Version 4.2 Description

#### ©opyright 1993-2007 by Fred Hucht (fred(AT)thp.Uni-Duisburg.DE)

Ygl is distributed in terms of the GNU LIBRARY GENERAL PUBLIC LICENSE. Please see the file LICENSE for further details. You may not distribute this project without this file (ReadMe.html) and the LICENSE file included.

Here you can read the Changes history and the Ygl FAQ.

## Description

Ygl emulates SGI's GL routines under X11. It compiles fine under AIX >3.2, HP-UX >7.0, Linux with XFree/Xorg, SunOS, ConvexOS, Mac A/UX, Mac OS/X and many others, but needs an ANSI-C compiler (gcc is ok). It was written for two reasons:

- On our RS/6000 GT4 hardware, 2D Ygl is up to twenty times faster (`circf()`) than GL (strange, isn't it?...)
- 2D (and 3D using OpenGL) graphics runs on non GL hardware and even on remote X-Servers.

Included are most of the two-dimensional graphics routines, the queue device routines, the query routines, doublebuffering, RGB mode with dithering, window attribute routines, FORTRAN bindings and more (see below).

3D stuff was added with version 4.0 using OpenGL calls.

Since Version 2.8, all Ygl functions do have a FORTRAN interface. The FORTRAN versions of all functions have an underscore appended, so the FORTRAN compiler must append a '_' to all function names. f2c does this, xlf (under AIX 3.2) requires the option `-qextname`. See smile_f77.f for an example program. Set `FortranBindings` to `0` in Imakefile or change Makefile.std if you don't want these bindings. FORTRAN bindings are not tested because I have no programs.f to test. If you find bugs, feel free to report them to me.

You can always find the latest version of Ygl in the directory ftp.thp.Uni-Duisburg.de/pub/source/X11/.

Note that perl, python and tcl bindings for Ygl are available here thanks to Prabhu Ramachandran.

## Details

### Environment variables:

Several environment variables are referenced in the library to control the behavior of Ygl:

- The environment variable YGL_PRIVATECOLORMAP or YGL_PCM can be set to 1 to force Ygl to use a private colormap. While GL always uses a private colormap, Ygl uses the global map by default to avoid technicolor effects on X-Servers not capable of more than one colormap at a time. Note that you can only redefine the color of already drawn objects when you use a private colormap.
- The environment variable YGL_FLUSHTIME or YGL_FT (default value: 0.1) can be used to adjust the time in seconds between flushes of the graphics pipeline. It can be set to 0 to disable the automatic update via interval timer. Setting YGL_FLUSHTIME to -1 will put the X-Server into synchronous mode (see XSynchronize). This mode seems to be veeeryyy slooow, but is good for debugging...
- The environment variable YGL_BACKINGSTORE or YGL_BS can be set to 1 to enable BackingStore support for all Ygl windows. With BackingStore, the X-Server remembers the contents of a window when it gets obscured or iconified. You must start your X-Server with the option "-bs" ("+bs" on some systems) to use this feature.
- The environment variables YGL_CMAPVISUAL or YGL_CV and YGL_RGBVISUAL or YGL_RV control the selection of visuals for cmapmode and RGBmode. Set these variables to the visual id of the desired visual as returned by xdpyinfo (both hex and decimal is ok). Setting one of these variables to -1 forces Ygl to use the default visual of the screen instead of the best visual.
- The environment variable YGL_SINGLEGC or YGL_GC can be set to 1 to force Ygl to use a single graphics context for colormap windows. Per default Ygl uses one GC for each color, i.e. 256 GCs for a 8 bit colormap window, because this speeds up drawing with many color changes by a factor of 2 or so on many systems. Using a single GC may be faster if you use many mapcolor calls as in colormap animation. Note that if the used colormap visual has more than 256 colors YGL_GC defaults to 1.
- The environment variable YGL_PARENTWID or YGL_PWID controls the parent window of Ygl. Per default the root window of the default screen of the given display is the parent window of windows opened with winopen(). Set this variable to the window id of the desired window as returned by xwininfo (both hex and decimal is ok).
- The environment variable YGL_DITHERSIZE or YGL_DSZ controls dithering in RGB mode.With this variable you can specify the size of the dither matrix. The default value is 4, leading to a 4x4 dither matrix. Valid values range from 0 to 6. On a normal 8 bit TrueColor visual ({3,3,2} bits {red,green,blue}) you obtain 113x113x49 = 625681 different "colors" with YGL_DSZ=4, leading to an effective screen depth of approx. 19 bits. The other values and the effective screendepth are:

               |  8 bit (3-3-2)  | 12 bit (4-4-4)  |  16 bit (6-5-5)
        YGL_DSZ| # colors (bits) | # colors (bits) |  # colors (bits)
        -------------------------------------------------------------
          0,1  |      256 ( 8  ) |     4096 (12  ) |     65536 (16  )
           2   |    10933 (13.4) |   226981 (17.8) |   3953125 (21.9)
           3   |   114688 (16.8) |  2515456 (21.3) |  44531200 (25.4)
           4   |   625681 (19.3) | 13997521 (23.7) | 249232081 (27.9)
           5   |  2354176 (21.2) | 53157376 (25.7) | 949029376 (29.8)
           6   |  6976981 (22.7) |158340421 (27.2) |2831006341 (31.4)

  Note that dithering costs speed. You may set YGL_DSZ=0 to disable dithering. If you are lucky and have a 24 bit TrueColor visual, YGL_DSZ is automatically set to zero.

### Doublebuffering:

Ygl supports doublebuffering via the XServer extensions "DOUBLE-BUFFER" (new in X11R6.1) and "Multi-Buffering". The related routines are `doublebuffer()`, `swapbuffer()` and `singlebuffer()`.

Notes:

OpenGL:
  You can use the routine `gsync()` to wait for the next vertical retrace. If you use doublebuffering, it might help to set the environment variable `__GL_SYNC_TO_VBLANK` to 1 to swap buffers at a vertical retrace.
X11R6.1:
  If you have X11R6.1 or later, set `DoubleBuffer` to 1 in Imakefile.
AIX < 3.2.5:
  The extension "Multi-Buffering" is new in X11R5 and is included in the lpp X11dev.src under AIX. To use doublebuffering you have to link the "Multi-Buffering" extension into your X-Server (under AIX, see /usr/lpp/X11/Xamples/README, "Linking the Sample Extensions into the Server").
AIX >= 3.2.5:
  You don't need to recompile the X-Server anymore to use doublebuffering under AIX 3.2.5 (AIXWindows 1.2.3). You simply have to add the option "-x mbx" to the X-Servers command line on startup.
AIX >= 4.1:
  You need the LPP X11.adt.ext to compile Ygl with doublebuffering enabled.

### RGB mode:

Ygl can run in a per window RGB mode, if the X-Server has a TrueColor or DirectColor visual. Ygl will always select the appropiate visual for the desired mode, independent of the default visual, i.e.:

     Colormap mode <-> PseudoColor, StaticColor,
                       GrayScale, StaticGray,
                       TrueColor or DirectColor visual

     RGB mode      <-> TrueColor or DirectColor visual

A RGB mode window is a child of the initially created colormap mode window. Ygl uses the property `WM_COLORMAP_WINDOWS` to tell the window manager, which colormaps are to be installed. To toggle the colormaps when a RGB window is subwindow of a colormap window, use the window manager function `f.colormap` in twm or `f.next_cmap` in mwm. Ygl will automatically dither all output if the X-Server doesn't support 24 bits. See the section environment variables for details.

### Multiple Expose events (REDRAW) in qread:

Ygl ignores all Expose events that have e.xexpose.count != 0 (see XExposeEvent(3X11)) AND all Expose events when another Expose event for the same window is in the Event queue. This procedure minimizes unnessesary redraws. Nevertheless, a REDRAW event is generated when a window is moved even when the contents of the window does not have to be redrawn. This is to be compatible with SGI's GL, where no extra event for window moves exist :-(

### Automatic flushing of the graphics pipeline:

The process virtual interval timer (see setitimer(3)) is used to flush the graphics pipeline every 0.1 seconds. This interval is adjustable (see above). The system functions sleep() and usleep() are covered by the library to flush the pipeline, too. This had to be done because the GL hardware flushes the pipeline automatically on every vertical retrace and has no command to flush.

Note that sleep() and usleep() always return 0.

You can use "sleep(0)" to flush the graphics pipeline explicitly. If you have problems with sleep() and usleep(), undefine COVERSLEEP in header.h.

## Supported routines

Finally a list of supported GL routines is included. For a detailed description of the routines see the GL manuals in the Info-Explorer (under AIX) or click at the command below.

### Window related routines:

minsize, maxsize, prefsize, prefposition, stepunit, keepaspect, winopen, winclose, gconfig, gexit, wintitle, winset, winget, getsize, getorigin, getXdpy, getXwid, getbutton, getvaluator, winmove, winposition, ginit, winpop, winpush, windepth, swinopen, winconstraints, noport, noborder, winX.
Note: The routine `winX(Display *dpy, Window win)` will ignore the first argument `dpy`. Ygl always uses the XServer specified in the environment variable DISPLAY.

### Color related routines:

RGBmode, RGBcolor, cmode, color, mapcolor, getplanes, getmcolor, getmcolors, getcolor, gRGBcolor, c3s, c3i, c3f, cpack.

### Device related routines:

tie, noise, isqueued, qdevice, unqdevice, qreset, qtest, qread, qenter,
Notes:

- Currently supported devices are: REDRAW, KEYBD, INPUTCHANGE, LEFTMOUSE, MIDDLEMOUSE, RIGHTMOUSE (MENUBUTTON), MOUSEX, MOUSEY, WINQUIT, and all individual keys as F1KEY, ESCKEY, UPARROWKEY, and so on.
- qenter does only support the REDRAW device.

### Menu routines:

defpup, newpup, addtopup, dopup, freepup, setpup.
Note: The routines `addpup()` and `defpup()` accept an additional modifier '%M'. If you define a submenu anchor with '%M' instead of '%m', Ygl calls the function defined with '%F' with the two arguments `menu-return` and `submenu-return`, i.e.:

    int callback(Int32 m, Int32 s) {
      sleep(s);
      switch(m) {
      case 1: explode(); break;
      case 2: implode(); break;
      }
      return(m << 8 + s);
    }

    main() {
      ...
      sub  = defpup("Seconds%t|1|2|3|4|5");
      menu = defpup("Menu%t%F|Explode%M|Implode%M",	callback, sub, sub);
      ...
    }

See `examples/popup.c` for details.

### Font routines:

loadXfont, font, getfont, getfontencoding, getheight, getdescender, strwidth, charstr.

### Doublebuffer routines:

singlebuffer, doublebuffer, swapbuffers, frontbuffer, backbuffer.

### Misc routines:

gflush, gsync, gversion, rectzoom, lrectread, lrectwrite, rectcopy, readsource, rectread, rectwrite, readpixels, writepixels, readRGB, writeRGB, blendfunction, linewidth, getlwidth, deflinestyle, setlinestyle, getlstyle, lsrepeat, getlsrepeat, logicop, getdisplaymode, getgdesc, setbell, ringbell.

### Coordinate transformation routines:

ortho2, viewport, getviewport, reshapeviewport, pushviewport, popviewport, getmatrix.

### Drawing routines:

clear, pnt2s, pnt2i, pnt2, move2s, move2i, move2, rmv2s, rmv2i, rmv2, draw2s, draw2i, draw2, rdr2s, rdr2i, rdr2, arcs, arci, arc, arcfs, arcfi, arcf, circs, circi, circ, circfs, circfi, circf, rects, recti, rect, rectfs, rectfi, rectf, sboxs, sboxi, sbox, sboxfs, sboxfi, sboxf, concave, pmv2s, pmv2i, pmv2, rpmv2s, rpmv2i, rpmv2, pdr2s, pdr2i, pdr2, rpdr2s, rpdr2i, rpdr2, pclos, poly2s, poly2i, poly2, polf2s, polf2i, polf2, bgnpoint, endpoint, bgnline, endline, bgnclosedline, endclosedline, bgnpolygon, endpolygon, v2s, v2i, v2f, v2d, cmov2s, cmov2i, cmov2, getcpos.
Note: It's not possible to change drawing attributes (color, ...) in the middle of a vertex pipeline in Ygl. This affects the routines `{bgn|end}{point|line|closedline|polygon}()` and `pdr(), rpdr()`.

### 3D routines

#### Drawing:

c4s, c4i, c4f, cmovs, cmovi, cmov, pnts, pnti, pnt, moves, movei, move, draws, drawi, draw, rmvs, rmvi, rmv, rdrs, rdri, rdr, pmvs, pmvi, pmv, rpmvs, rpmvi, rpmv, pdrs, pdri, pdr, rpdrs, rpdri, rpdr, polfs, polfi, polf, v3s, v3i, v3f, v3d, v4s, v4i, v4f, v4d, swaptmesh.

#### Coordinate Systems:

ortho, lookat, window, perspective, polarview, rot, rotate, scale, translate, loadmatrix, multmatrix, pushmatrix, popmatrix, getmmode, mmode.

#### Polygon specs:

shademodel, n3f, normal, backface, frontface.

#### z-Buffer:

zbuffer, zclear, zdraw, zfunction, czclear, depthcue, lRGBrange, lsetdepth, lshaderange.

#### Display lists:

genobj, isobj, makeobj, getopenobj, closeobj, callobj, delobj.

#### Misc:

lmbind, lmcolor, lmdef, RGBwritemask, pushattributes, popattributes, scrmask.

#### Picking/Names:

pick, endpick, picksize, initnames, loadname, pushname, popname.

#### NOPs:

foreground, drawmode, iconsize, overlay, fullscrn, endfullscrn.

### Routines not in SGI's GL:

The following routines are added to standard GL:

- `GC getXgc(void)`
  return current graphics context. You can for example use it to draw lines xor'ed with the background:

      #include <X11/X.h>
      ...
      XSetFunction(getXdpy(), getXgc(), GXxor);

  Note: Since version 3.1, getXgc() is not supported anymore, as you can use the routine logicop() to set the drawing function.

- `Window getXdid()`
  return window id of the current drawable. This id differs from the window id returned by `getXwid()` when in RGB mode or when using doublebuffering.

- `Int32 crectread(Screencoord x1, Screencoord y1, Screencoord x2, Screencoord y2, Uint8 *data)`
  read screen data to unsigned char array `data`

- `void crectwrite(Screencoord x1, Screencoord y1, Screencoord x2, Screencoord y2, Uint8 *data)`
  write unsigned char array `data` to screen

- `void arcxs(Scoord x,Scoord y,Scoord rx,Scoord ry,Angle s,Angle e)
  void arcxi(Icoord x,Icoord y,Icoord rx,Icoord ry,Angle s,Angle e)
  void arcx(Coord x,Coord y,Coord rx,Coord ry,Angle s,Angle e)`
  draw ellipses

- `void arcxfs(Scoord x,Scoord y,Scoord rx,Scoord ry,Angle s,Angle e)
  void arcxfi(Icoord x,Icoord y,Icoord rx,Icoord ry,Angle s,Angle e)
  void arcxf(Coord x,Coord y,Coord rx,Coord ry,Angle s,Angle e)`
  draw filled ellipses

- `int gl2ppm(char *filename)`
  write out active Ygl window to portable pixmap file `'filename'`. When `filename[0] == '|'`, uses `popen()` instead of `fopen()`. Note that `gl2ppm()` can also be used in a GL application. Just add `gl2ppm.o` to the list of object files.

## Acknowledgements

The author would like to thank Michael Staats (michael(AT)thp.Uni-Duisburg.DE) and Ralf Meyer (ralf(AT)thp.Uni-Duisburg.DE) for some hints and tips.

GL is a registered trademark of Silicon Graphics, Inc.