University of illinois Urbana-Champaign

Syzygy Getting Started

Getting the software

Syzygy works on reasonably modern versions of Linux, Windows, Mac OS X, and Irix. Every user should read the testing document. You will also want to look at the chapter on  installing supporting libraries for Syzygy compilation. If you want to write Syzygy programs in Python, then you will also need to read about compiling the  Python bindings.

Software Packages

The following software (and data) packages are part of the Syzygy distribution:

  • szg-1.3.zip: Everything necessary to build and test the libraries. Includes some example programs. Also includes everything needed for writing Syzygy programs in Python.
  • szgdata-1.3.zip: Data necessary for the sample applications, as outlined in the example programs page, but excluding some particularly large files, which are available by request.
  • external-1.3.zip: External libraries and headers for all platforms

A Note about GLUT

We're gradually phasing the GLUT dependency out of Syzygy. GLUT is no longer used for window mangagement, but it is still used in a few places for rendering (e.g. using glutWireSphere() to draw a wireframe sphere). These are the only GLUT commands that you can use in your programs, and if you do use them you should include the header arGlut.h.

 

OS-Specific Build Instructions

Linux

  • X11 and ncurses development packages are required for compilation. Your distribution might not install these by default, e.g. on Ubuntu 8.04 we install build-essential, libncurses5-dev, libxi-dev, libxext-dev, libxmu-dev. For Python development install python-sip4-dev and sip4; note also that if you want to compile the Python bindings a bug in g++ 4.2 will make this a very slow process; 4.1 or 4.3 will work much better.
  • GLUT is required for compilation as well. Either install a GLUT development package via your distribution (freeglut3-dev) or install GLUT in Syzygy's external build libraries, as described here.
  • IMPORTANT NOTE: the Syzygy build environment produces code for the i686 architecture by default.If you have an older processor, you need to change the "-march=i686" flag in szg/build/make/Makefile.varslinux. Experiment with either removing it or downgrading, for instance to "-march=i586".

Windows

  • Syzygy's build system uses GNU make and either the command line Visual Studio compiler and linker (either Visual Studio 6 with the STLPort STL headers or Visual Studio 7 (.NET) without) or the MinGW implementation of the GNU g++ compiler and linker. Note that when compiling with g++ on Windows, the device driver for the SpacePad is unavailable (see Supported Input Devices. However, we can supply you with a precompiled binary of the device driver. Users have successfully built Syzygy with Visual Studio 2005. New in 1.2: Speech synthesis, .3ds model files, and joysticks are now supported when using the MinGW g++ compiler. It turns out that it was possible to build the Python bindings all along, presumably because the MinGW runtime is linked against the dynamic-linked Microsoft runtime library.
  • You will need a Unix-like environment for Windows that provides a GNU make utility. We have tested two, MinGW/MSYS and Cygwin. If you're not currently using either (and are not using Windows 98, see below), we recommend MinGW. Cygwin is a much larger package, comprising an entire Unix system, and is only available via a network installer. On the other hand, MinGW is relatively small and comes as two self-contained installers.
  • Syzygy programs expect to be able to scrape their name from the command-line args. The Windows NT, Windows 2000, and Windows XP (cmd.exe) shells all work. Unfortunately, the Win98 cmd.exe shell mangles argv[0], interfering with Syzygy's proper operation. The cygwin shell does, however, work with Syzygy on all Windows versions, including Windows 98. Consequently, we recommend using installing and using the cygwin shell on Windows 98.
  • To install MinGW, run the MinGW installer first (which gives you the underlying system) and then the MSYS installer (which gives you the Unix-like shell needed to run the commands). Please note, the MSYS shell, as of this writing, has a hard time printing text from Syzygy programs (it stalls frequently). Consequently, we recommend running Syzygy commands from a regular Windows shell (cmd.exe) and only compiling in MSYS. This workaround means that MinGW is unsuitable for Win98, where cygwin should be used instead.
  • You might prefer to install cygwin (www.cygwin.com) if you want more Unix functionality from the command line than MinGW provides. You can create a minimum-disk-space Cygwin which will still build Syzygy by selecting only these packages (uncheck all other checkboxes):

 

Category: Base
ash bash cygwin fileutils login sh-utils

 

Category: Devel
bin-utils make

 

Category: Shells
ash bash sh-utils

 

  • Install MS Visual Studio. If you are using Visual Studo 6, you'll also need STLport to replace VC-6's non-threadsafe STL. With Visual Studio .NET (i.e. 7), STLport is not necessary. Please see Supporting Libraries for instructions.
  • To compile from the command-line, Visual Studio needs several enviroment variables to be set appropriately. Please see Visual Studio Environment Variables for details.
  • You will need to install GLUT, as described in the Windows section of Supporting Libraries. Please note that we no longer encourage users to install the glut headers and library in the Visual Studio directory.

Mac OS X

The Syzygy shared library code uses dlopen, as is provided in szg/contrib/dlcompat. You must compile this first:

  1. cd szg/contrib/dlcompat
  2. make
  3. PLEASE NOTE that the Syzygy application frameworks now use their own windowing API (as built on X11) in place of GLUT. Consequently, to run Syzygy graphical applications you will need X11 installed on your system and running (by default it does not start at system start). If X11 is not running, the application will fail upon launch with an error message prompting you to start X11.

Irix

Either install GLUT on your machine in the normal Unix way or follow the SGI instructions here to install GLUT in a Syzygy-specific way, which does not require "root".

 

Environment Variables for Microsoft Visual Studio

Building Syzygy

The Windows build environment invokes the VC++ tools from the command line, via GNU make and the Cygwin shell. If you haven't set up VC++ to run from the command line, compiling will fail. Possible error messages include not being able to find cl.exe (the compiler) and the linker not finding required dll's. Here are the settings for the environment variables include, lib, MSDevDir, and path that work with a standard install of Visual Studio 6.0.

include
  C:\Program Files\Microsoft Visual Studio\VC98\atl\include;
  C:\Program Files\Microsoft Visual Studio\VC98\mfc\include;
  C:\Program Files\Microsoft Visual Studio\VC98\include
lib
  C:\Program Files\Microsoft Visual Studio\VC98\mfc\lib;
  C:\Program Files\Microsoft Visual Studio\VC98\lib
MSDevDir
  C:\Program Files\Microsoft Visual Studio\Common\MSDev98
path
  C:\Program Files\Microsoft Visual Studio\Common\Tools\WinNT;
  C:\Program Files\Microsoft Visual Studio\Common\MSDev98\Bin;
  C:\Program Files\Microsoft Visual Studio\Common\Tools;
  C:\Program Files\Microsoft Visual Studio\VC98\bin

 

The following work with a standard install of Microsoft Visual Studio .NET 2003. In Windows XP, it helps if these are "user variables" rather than "system variables", since the Cygwin shell inherits values from the former.

include
  C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\ATLMFC\INCLUDE;
  C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\INCLUDE;
  C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\include
lib
  C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\ATLMFC\Lib;
  C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\Lib;
  C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\Lib
path
  C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE;
  C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\BIN;
  C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools;
  C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools\bin

Syzygy Build Environment Variables

The Syzygy build process uses recursive make. A top-level Makefile in szg/build guesses the operating system and executes a machine-specific Makefile in a subdirectory. For example, on a Windows machine, the Syzygy shared library libarLanguage.dll would be built in szg/build/win32/language, but on a Linux system libarLanguage.so would be built in szg/build/linux/language. The Makefile guesses the operating system via uname, defaulting to the OSTYPE environment variable if this fails. If the top-level makefile fails to guess your machine type, you can fix the problem by setting $OSTYPE (to "linux" or "cygwin", for instance).

Supporting Libraries). By default, copies of libraries and executables will end up in the directory szg/bin/<OS>, e.g szg/bin/win32; if you want them to go somewhere else, you can set SZGBIN to the path to the desired directory.

 

 SZGHOME=D:/szg
 SZGEXTERNAL=g:/public

 

The following environment variables are meaningful on all systems:

  • SZGHOME: (required) The top-level syzygy directory (for example, /home/user1/szg).

     

  • SZGEXTERNAL: (optional) The location of external libraries, such as those providing sound. If this is not set, the code will compile but disable support for such features. The arrangement of the

     

  • SZGBIN: (optional) The directory where the built binaries and shared libraries should be placed. If this is not set it defaults to szg/bin/$(MACHINE_TYPE), where MACHINE_TYPE is one of linux, win32, darwin, mips3, or mips4. The last two possibilities refer to SGI processor families.

     

  • SZGDEBUG: (optional) If set to "TRUE", a debug build will be produced.

     

  • SZG_LINKING: (optional) By default, the Syzygy makefiles are set up to use dynamic linking, i.e. libraries are built as shared libraries (dll's on Windows, so's on Linux, etc.) If this variable is set to STATIC, the build process will create static libraries, and executables will link the resulting libraries statically. This can be useful sometimes for simplifying DLL management. To prevent a name conflict (on Win32 the DLL import/export libraries have the same .lib extension as static libraries), the static libraries have different names, such as libarLanguage_static.lib on Win32.

     

    IMPORTANT NOTE: Using Visual C++ on Win32, there is a problem with static linking. Because DLL's cannot link to a static libc, loadable DLLs cannot be built with this option. The Python bindings must be built as a DLL and cannot be built with SZG_LINKING set to STATIC. The supported Unix-like platforms do not suffer from this problem. New in Syzygy 1.2: You can now compile input device drivers and the DeviceServer program with static linking. The device drivers are linked directly into the DeviceServer executable instead of each comprising its own shared library. Building the Python bindings with static linking enabled appears to work with the MinGW g++ compiler. New in Syzygy 1.3: The device drivers are built as dll's using MinGW g++ on Win32.

The following environment variables only have meaning on Windows.

  • SZG_STLPORT: Visual Studio 6's STL implementation is insufficent to run Syzygy. In this case, STLport must be used instead. It must be installed in the SZGEXTERNAL directory (see  Supporting Libraries) and SZG_STLPORT must be set to TRUE.

     

  • SZG_USE_PCH: (optional) To get the Windows build reasonably fast, precompiled headers must be used (the default). However, these are extremely sensitive to minor differences in Visual Studio patch level. Sometimes it is convenient to be able to turn off precompiled headers by setting this variable to "FALSE".

Compiling the Syzygy Libraries

Make sure you have followed the following specific guidelines for your platform (if any):

  1. Unpack szg-1.3.[zip/tar.gz].

     

  2. You MUST set $SZGHOME appropriately and should optionally set other variables (Syzygy Build Environment Variables).

     

  3. In szg/build, type "make". Note that "make clean" deletes previously-built libraries. On Windows this must be done from a cygwin or MinGW shell since syzygy uses GNU make (actually, any shell will do provided the appropriate version of make.exe, compiler, linker, and so on are on your application search path as specified by the PATH environment variable. One of us routinely uses IPython as a build shell). On Irix, you MUST use "gmake" instead of "make", since Syzygy uses GNU make syntax.

     

  • If the supporting libraries are not properly installed (see Supporting Libraries), then Syzygy will build, but certain capabilities, such as sound, will be disabled.

Potential problems

  • If SZGBIN is set but doesn't indicate a directory, the cp command at the end of each step in the recursive make will fail.

     

  • On most systems, the build system will automatically guess the system type and proceed. But if the build fails with "Makefile failed to guess OS type", manually set the environment variable OSTYPE to one of linux, cygwin, darwin, or irix and try again.

     

  • If cygwin was not installed properly, you might not have gotten "make" or "ar". In this case, the build will fail, complaining that it can't find the relevant executable. Please try installing cygwin again, this time making sure the packages mentioned in the Windows section of OS-Specific Build Instructions are included.

     

  • If you are using cygwin on Win32 and see the following error message:
     link error: too many arguments
    
    You should check the which executable you are running as the linker by typing "which link". It is very likely that it will report you are running a cygwin executable, whereas you should be running an executable in a Visual Studio directory. There are various solutions to this problem. One is to simply delete the cygwin executable, another is to change your $PATH environment variable (say via the .bashrc in your home directory that cygwin reads on start up) so that the Visual Studio directory comes first (see Visual Studio Build Variables for details).

Generated Files

make process will build a collection of shared libraries that collectively comprise the Syzygy toolkit (shown here with Linux/Irix extensions, replace '.so' with '.dll' for Windows):

  • libarLanguage.so
  • libarPhleet.so
  • libarBarrier.so
  • libarMath.so
  • libarDrivers.so
  • libarGraphics.so
  • libarSound.so
  • libarObject.so
  • libarInteraction.so
  • libarFramework.so

     

    Alternatively, if you chose the static linking option, the built libraries will look like (shown here with Linux/Irix extensions, replace '.a' with '.lib' for Windows):

     

  • libarLanguage_static.a
  • libarPhleet_static.a
  • libarBarrier_static.a
  • libarMath_static.a
  • libarDrivers_static.a
  • libarGraphics_static.a
  • libarSound_static.a
  • libarObject_static.a
  • libarInteraction_static.a
  • libarFramework_static.a

     

    It will also compile a collection of plugins for the input framework (e.g., input device drivers), infrastructure programs like szgserver, and utility programs like dkillall. Remember, in the special case of statically-linked Syzygy on Win32, your input driver plugins will not work with DeviceServer. However, static builds have no such drawback on supported Unix-like platforms.

     

Compiling the Sample Applications in szg

example applications are included with the Syzygy code (located in szg/src/demo).

  • atlantis
  • coaster
  • hspace
  • ribbons
  • schprel
  1. Set SZGHOME, SZGBIN, SZGEXTERNAL, etc. as before.

     

  2. To build all the samples, in szg/build type "make demo", which will result in the executables being placed either in szg/win/<MACHINE_TYPE> or in the directory pointed to by the SZGBIN environment variable. The "demo" target also rebuilds the libraries (i.e. does the equivalent of "make") if needed. If one sample application fails to build, it continues to the next. You can clean the demo directories with "make demo-clean".

    cd szg/build/linux/demo/atlantis; make. As above, for this to work properly, the build environment variables must be set appropriately.

Advanced Makefile Targets

  • drivers: build only up to the drivers. Don't build anything involving graphics, sound, or the application frameworks. This is useful when OpenGL is missing. The drivers requires dynamic linking.

     

  • install-shared: This is in every top level Makefile and in Makefile.rules. It copies shared libraries into the binary directory (i.e. $SZGBIN).

     

  • bin-install: This target exists in every top level Makefile and in Makefile.rules. It copies a project's compiled binaries and libraries into the binary directory ($SZGBIN).

NOTE: Syzygy no longer supports precompiled SDK's.

  • create-sdk: This is in every top level Makefile and also in Makefile.rules (and consequently every low-level Makefile as well). When invoked from a developer's install of the szg source, it creates an SDK installation in $SZGHOME/szg-install. All executables and shared libraries, including the external libraries, are copied into the bin subdirectory and symbolic links are created there to deal with library sonames, as required. In addition, documentation, header files, and some of the make infratsructure are copied over. Elsewhere (like in py-szg or szgdemo), create-sdk just causes locally produced binaries and libraries to be added to an existing $SZGHOME/szg-install.

     

  • clean-sdk: This is in the top-level Makefile of the developer's version of szg only. Removes the working SDK installation, if such exists (i.e. deletes $SZGHOME/szg-install).

     

  • install-pch: This has meaning only when using the Windows version of the SDK. By default, compiling with the SDK has precompiled headers turned off, resulting in slower compilation on Windows. To use precompiled headers to speed up compilation, invoke this from the build directory of the SDK. Afterwards, turn on precompiled headers by setting environment variable SZG_USE_PCH to TRUE.

     

  • clean-pch: This deletes the precompiled header file created by the install-pch target.

Supporting Libraries

Syzygy's build system is designed to let you compile your software using the optional supporting libraries but without installing them in a standard system location. This allows non-root users to compile Syzygy with supporting libraries. The build system expects the "external" libraries to be installed in a directory given by the SZGEXTERNAL environment variable.

The Syzygy makefiles (via szg/build/make/Makefile.libscan) will automatically detect the presence of the libraries, given that they are copied to the places outlined below. See Makefile.libscan for details. This is the file you should change if you need to use different library versions or otherwise tweak this process for your local installation.

General Comments on External Libraries

With the possible exception of the GLUT libraries, if you do not properly install an optional library in SZGEXTERNAL, Syzygy programs will still build and run, but with certain features (such as sound) disabled. When an external library requires a shared library, the runtime linker must be able to find it. A Makefile target exists to install shared libries in $SZGBIN.

  cd $SZGHOME/build
  make install-shared

 

If you have compiled your executables from scratch on a Unix system, they have a runtime linker path including $SZGBIN. Consequently, installing the shared libraries with the Syzygy executables will let the runtime linker find them. If you are on a Windows system, the runtime linker automatically searches the directory in which the executable it runs resides.

A note about GLUT. Syzygy compilation requires it (although hopefully it won't in version 1.2). Some systems will have in installed by default (Mac OS X). Some systems might or might not have it installed (Linux, SGI), and some will probably not have it installed (Windows). If it is installed so that the compiler will automatically find the header and library and the runtime linker will find the shared library, then you need do nothing else. Otherwise, you can either install GLUT like that yourself, or install it for Syzygy only in SZGEXTERNAL, as described below.

Directory Structure of SZGEXTERNAL

The top level of the SZGEXTERNAL directory has subdirectories for each system (Linux, Windows, Mac OS X, SGI) that it supports. When creating your own SZGEXTERNAL, you do not need all of these subdirectories, since you might support only one or two system types.

  SZGEXTERNAL
    darwin
    linux
    sgi
    win32

 

 

  darwin
    fmod-4
    jpeg

  linux
    fmod-4
    glut-3.7
    jpeg
    lib3ds
    vrpn
    zlib

  sgi
    glut-3.7

  win32
    STLport
    ascension
    fmod-4
    glut-3.7
    isense
    jpeg
    lib3ds
    sapi-5.1
    zlib
    evart

 

Use of Specific Libraries

  • STLport: Visual Studio 6 (Windows) needs a replacement STL, which this provides.

     

  • ascension: Contains a Windows-only driver for the Flock-of-Birds.

     

  • evart: Contains a driver for the Motion Analysis optical motion capture system.

     

  • fmod-4: A cross-platform sound library.

     

  • glut-3.7: A cross-platform OpenGL windowing library.

     

  • isense: Drivers for the Intersense motion trackers.

     

  • jpeg: A library for encoding/decoding jpeg image files. Needed by the q33 and cubecake demos.

     

  • lib3ds: A library for reading 3ds (3D Studio Max) files.

     

  • sapi-5.1: A Microsoft text-to-speech library.

     

  • vrpn: A library for interfacing with VR input devices.

     

  • zlib: A library for compressing/decompressing files. Needed by the q33 and cubecake demos.

Installing Libraries for Windows

Of special note is the STLport library. If you are using Visual Studio 6 to compile Syzygy, you CANNOT use the native STL. In this case, you MUST use STLport (the software will crash otherwise). If you are using Visual STudio .NET, you should use the native STL.

  • STLport
    1. You should only compile against STLport if you have Visual Studio 6.
    2. Down and compile STLport (you will want the iostream library, not just the header files).
    3. Make a directory $(SZGEXTERNAL)/win32/STLport. This is the Syzygy STLport directory (in contrast with the native STLport directory where you compiled the software).
    4. From the native STLport directory, copy the lib and stlport subdirectories to the Syzygy STLport directory.

       

  • ascension
    1. Download BirdWindowsDriver.zip from the Ascension website.
    2. Copy Bird.lib and Bird.dll to $(SZGEXTERNAL)/win32/ascension/lib.
    3. Copy Bird.h to $(SZGEXTERNAL)/win32/ascension/include.

       

  • evart
    1. You should have received files EvaRT.h, macrtcom.lib, and macrtcom.dll with your optical motion capture system.
    2. Copy EvaRT.h into $(SZGEXTERNAL)/win32/evart/include.
    3. Copy macrtcom.lib and macrtcom.dll into $(SZGEXTERNAL)/win32/evart/lib.

       

  • fmod-4
    1. For sound support, install fmod version 4.
    2. Copy fmod.dll and fmodvc.lib into $(SZGEXTERNAL)/win32/fmod-4/lib.
    3. Copy these include files into $(SZGEXTERNAL)/win32/fmod-4/include: fmoddyn.h, fmod.h, fmod_errors.h, wincompat.h.
    4. If you don't copy these files, Syzygy will still build and run but sound support will be disabled.

       

  • glut-3.7
    1. You will need to obtain GLUT since it is not built in on Windows systems.
    2. Download GLUT-3.7.
    3. Make a directory $(SZGEXTERNAL)/win32/glut-3.7/include/GL and put glut.h there.
    4. Make a directory $(SZGEXTERNAL)/win32/glut-3.7/lib and put glut32.dll and glut32.lib there.

       

  • isense

     

  • jpeg
    1. You will need to download, configure, and compile libjpeg for your system. This is trickier than on Unix-like systems.
      1. Before compiling, copy jconfig.vc to jconfig.h.
      2. Before compiling, copy makefile.vc to Makefile.
      3. Before compiling, edit jmorecfg.h so that:
            #ifndef XMD_H                   /* X11/xmd.h correctly defines INT32 */
            typedef long INT32;
            #endif
        
        becomes
            #ifndef _BASETSD_H_
            #ifndef XMD_H                   /* X11/xmd.h correctly defines INT32 */
            typedef long INT32;
            #endif
            #endif
        
      4. Before compiling, edit Makefile so that
            $(cc) $(CFLAGS) $*.c
        
        becomes
            $(cc) $(CFLAGS) /MD $*.c
        
      5. You will need to use nmake from a DOS prompt to build the software.
    2. Make a directory $(SZGEXTERNAL)/win32/jpeg/lib and copy libjpeg.lib there.
    3. Make a directory $(SZGEXTERNAL)/win32/jpeg/include and copy jconfig.h, jmorecfg.h, and jpeglib.h there.

       

  • lib3ds
    1. In order to import .3ds files (Autodesk 3D Studio format), you will need to build and install lib3ds. Included in $SZGHOME/contrib/ is a folder named "lib3ds", which is simply the latest release of lib3ds, downloaded from the SourceForge lib3ds page. Follow the instructions provided in $SZGHOME/contrib/lib3ds/INSTALL to build the library.
    2. Make a directory $(SZGEXTERNAL)/win32/lib3ds/include/lib3ds and copy all header files there.
    3. Make a directory $(SZGEXTERNAL)/win32/lib3ds/lib and copy lib3ds.lib there.

       

  • sapi-5.1

     

  • zlib
    1. Download, configure, and compile zlib. This will be done using nmake from the DOS prompt. You will want to add the compile flag "/MD" as in the libjpeg example above.
    2. Make a directory $(SZGEXTERNAL)/linux/zlib/lib and copy libz.lib there.
    3. Make a directory $(SZGEXTERNAL)/linux/zlib/include and copy zconf.h and zlib.h there.

       

  • GL
    1. This is only used to provide glext.h to certain demos (q33 and cubecake).
    2. Make a directory $(SZGEXTERNAL)/win32/GL/include. Copy glext.h there.
    3. Make a directory $(SZGEXTERNAL)/win32/GL/include/GL. Copy glext.h there.

Installing Libraries for Mac OS X (darwin)

  • fmod-4
    1. For sound support, install fmod version 4.
    2. Copy libfmod.a into $(SZGEXTERNAL)/darwin/fmod-4/lib.
    3. Copy these include files into $(SZGEXTERNAL)/darwin/fmod-4/include: fmoddyn.h, fmod.h, fmod_errors.h, wincompat.h.
    4. If you don't copy these files, Syzygy will still build and run but sound support will be disabled.

       

  • jpeg
    1. Either download, configure, and compile libjpeg or simply copy the files that are already installed on your system (try 'locate libjpeg').
    2. Make a directory $(SZGEXTERNAL)/darwin/jpeg/lib and copy libjpeg.a there.
    3. Make a directory $(SZGEXTERNAL)/darwin/jpeg/include and copy jconfig.h, jmorecfg.h, and jpeglib.h there.

Installing Libraries for Linux

  • fmod-4
    1. For sound support, install fmod version 4.
    2. Copy libfmod-4.so into $(SZGEXTERNAL)/linux/fmod-4/lib.
    3. Copy these include files into $(SZGEXTERNAL)/linux/fmod-4/include: fmoddyn.h, fmod.h, fmod_errors.h, wincompat.h.
    4. If you don't copy these files, Syzygy will still build and run but sound support will be disabled.

       

  • glut-3.7
    1. Download and compile GLUT-3.7.
    2. Make a directory $(SZGEXTERNAL)/linux/glut-3.7/include/GL and put glut.h there.
    3. Make a directory $(SZGEXTERNAL)/linux/glut-3.7/lib and put libglut.so.3.7 there. You will also need to make symbolic links like so:
            ln -s libglut.so.3.7 libglut.so.3
            ln -s libglut.so.3 libglut.so
      

       

  • jpeg
    1. Either download, configure, and compile libjpeg or simply copy the files that are already installed on your system (try 'locate libjpeg.a').
    2. Make a directory $(SZGEXTERNAL)/linux/jpeg/lib and copy libjpeg.a there.
    3. Make a directory $(SZGEXTERNAL)/linux/jpeg/include and copy jconfig.h, jmorecfg.h, and jpeglib.h there.

       

  • lib3ds
    1. In order to import .3ds files (Autodesk 3D Studio format), you will need to build and install lib3ds. Included in $SZGHOME/contrib/ is a folder named "lib3ds", which is simply the latest release of lib3ds, downloaded from the SourceForge lib3ds page. Follow the instructions provided in $SZGHOME/contrib/lib3ds/INSTALL to build the library.
    2. Make a directory $(SZGEXTERNAL)/linux/lib3ds/include/lib3ds and copy all header files there.
    3. Make a directory $(SZGEXTERNAL)/linux/lib3ds/lib and copy lib3ds.a there.

       

  • vrpn
    1. Download and compile vrpn.
    2. Copy libvrpn.a to $(SZGEXTERNAL)/linux/vrpn/lib.
    3. Make a directory $(SZGEXTERNAL)/linux/vrpn/include and copy the vrpn header files there. Note that only vrpn_Shared.h, vrpn_Tracker.h, vrpn_Analog.h, and vrpn_Button.h are needed.

       

  • zlib
    1. Either download, configure, and compile zlib or simply copy the files that are already installed on your system (try "locate libz.a").
    2. Make a directory $(SZGEXTERNAL)/linux/zlib/lib and copy libz.a there.
    3. Make a directory $(SZGEXTERNAL)/linux/zlib/include and copy zconf.h and zlib.h there.

Installing Libraries for SGI

  • glut-3.7
    1. Download and compile GLUT-3.7. You will want to compile "n32" format objects since this is what Syzygy uses.
    2. Make a directory $(SZGEXTERNAL)/sgi/glut-3.7/include/GL and put glut.h there.
    3. Make a directory $(SZGEXTERNAL)/sgi/glut-3.7/lib and put libglut.a there.

Running Programs in Standalone Mode

When a Syzygy program is run, it goes through the following decision process to determine whether or not it is running in Standalone mode:

  1. It determines the current user's system name (as reported by the native operating system).

     

  2. It looks for a corresponding Syzygy login file (described in Creating a Cluster: The Syzygy Login Files.

     

  3. If this file exists and specifies that the user is logged into a Syzygy server, then the program attempts to connect to the server.

     

  4. If it connects successfully, the program is running in Cluster Mode.

     

  5. Otherwise, the program is running in standalone mode.

     

    If it is running in standalone mode, your program will print (among many other lines of start-up information) the following line:
    szg:CRITICAL: my_program_name running standalone.
    

    Introduction to Syzygy programming.

When running "hspace" in standalone mode, something looking like a green spiderweb should fill the window. There will also be a small overlay window in the lower right corner showing the tracker simulator interface, whose operation is described in this  Example Programs.

Configuration Information in Standalone Mode

When a Syzygy program starts, it needs to be configured with information regarding where it should find data files, where it should place its graphics screen on the desktop, and where sound and texture files exist, among other things. In Standalone Mode this information is read from an XML file. By default, the program looks for a file in the current working directory named either szg_parameters.xml or szg_parameters.txt, in that order. However, the file name can be overriden by passing a special command line argument to the program, for example:

my_program_name arg1 arg2 -szg parameter_file=szg_anaglyph.xml
my_program_name arg1 arg2 -szg parameter_file-szg_virtualcave.xml

-szg are interepreted as special Syzygy arguments and are removed from the argument array and processed by the Syzygy libraries before the array is handed to the application code.

If the program cannot open the specified config file it will check to see if the environment variable SZG_PARAM is set; if so, it will use SZG_PARAM's value as a file name and try to load that file.

System Configuration chapter. The only aspect of this format that is specific to Standalone Mode regards the specification of the computer name. In Cluster Mode, each computer-specific or local parameter must be defined using the name of the computer, e.g.

my_computer SZG_DATA path C:\Data

In Standalone Mode, on the other hand, the value NULL can be substituted for the computer name (since there's only one computer under consideration):

NULL SZG_DATA path C:\Data

 

If a program requests the value of a configuration parameter and it is not present in the file, the program will try to get it from an environment variable whose name consists of the parameter's group and name. For example, if the program wants the value of the parameter SZG_DATA/path, it will look for an environment variable named SZG_DATA_path containing the value.

 

Device Drivers in Standalone Mode

Input Simulator, which allows the user to simulate a tracked head and wand using the mouse and keyboard.

Now, however, standalone applications can load input device drivers. New in version 1.3: Previously, the syzygy libraries had to be dynamically linked (i.e. SZG_LINKING=DYNAMIC) in order to use this capability. Now this is only true with Visual C++. The choice between the Input Simulator and a device driver is made using the database parameter SZG_STANDALONE/input_config, which defaults to "simulator". If given any other value, this is assumed to be the name of a global input device configuration parameter in the parameter file. Any defined input sources (drivers), filters, and PForth filter code are loaded.

Alternate Input Simulators

Input Simulator as a shared library and load it at runtime based on the value of the Syzygy database parameter SZG_INPUTSIM/sim_type. A stupid example called arDefaultInputSimulator is contained in szg/skeleton; it behaves just like the built-in one, but it does show you which methods are available for overriding. Copy the skeleton directory tree somewhere, rename the source file, and modify skeleton/build/makefiles/Makefile.my_app appropriately. To use it, add e.g. the following in an <assign> block in your szg_parameters.xml:

  NULL SZG_INPUTSIM sim_type arDefaultInputSimulator

...and provided your app can find it, it should load an use it.

Example Programs

The below is a list of a few example Syzygy programs, along with a few important bits of information about each:

  1. The source code location; programs in szg/src/demo are part of the base distribution, whereas those in szgdemo are part of a separate package.
  2. A brief description.
  • atlantis (src/demo/atlantis): A port of the GLUT demo to our system. A school of dolphins, sharks, and whales swims around in a clustered formation.
  • coaster (src/demo/coaster): A port of the GLUT demo. Ride a roller coaster.
  • hspace (src/demo/hspace): A visualization of hyperbolic geometry, non-Euclidean three-space tiled with dodecahedra. The projection into Euclidean space is controlled by the joystick (backwards/fowards plus what looks like a rotate).
  • schprel (src/demo/schprel): A visualization of the warping effects caused by travelling near the speed of light.

Running Example Programs

6DOF-tracked input device with buttons and joysticks, or in  Input Simulator.

Tracking and Input Device Simulator

Syzygy applications work best with traditional VR head- and wand-tracking, that is, a six-degree-of-freedom (6DOF) position sensor on the head and another on a handheld gamepad that has several buttons and at least one joystick. But when these are not available, you can still simulate them from mouse and keyboard.

In standalone mode, this simulator overlays the lower-right corner of the window. In cluster mode, the simulator is a separate program, inputsimulator, defined as the primary input (INPUT0) of the virtual computer.

 

The input simulator sends data to the application specifying the position and orientation of the head and the wand, the placement of the wand's joysticks and sliders, and the up/down state of the wand's buttons (matrices, axes, and buttons, in Syzygy jargon).

The Default Input Simulator

The input simulator's display looks forwards into a 10-foot cubical space, like a wireframe cave. A wireframe sphere in the center represents your head (initially facing forwards, although the view has been rotated in this figure, see mode 7 below).

The blue rectangle at lower right contains numbered red circles, which represent virtual buttons on the wand. To change how many buttons the wand has, set the parameter SZG_INPUTSIM/number_button_events to the desired number in the  Syzygy database. The two (or three) columns of red circles correspond to the buttons on your two- or three-button mouse. To map mouseclicks to a particular row of buttons, e.g. 3 4 5, hit the spacebar; a white dot at left cycles through the rows, showing which row will be used. If you commonly use a 3-button mouse, set the Syzygy database parameter SZG_INPUTSIM/mouse_buttons to the string 0/1/2, to start with 3 rather than 2 columns. If your mouse has even more buttons, extended it to something like 0/1/2/3/4.

 

Below the red circles, the green dot represents the wand's joystick. The white square indicates how far the green dot can move. For example, when the dot is at the top of the square, that means the joystick is pushed all the way forwards.

The input simulator has several modes. To activate a mode, hit its corresponding number key, 0 through 9.

  • 1: Mouse moves the head in the horizontal plane.
  • 2: Mouse moves the head in the vertical plane.
  • 3: Mouse aims the head.
  • 4: Mouse moves the wand in the horizontal plane.
  • 5: Mouse moves the wand in the vertical plane.
  • 6: Mouse aims the wand.
  • 7: Mouse moves the joystick, only while a mouse button is held (``click and drag''). The joystick recenters when you release the mouse button.
  • 8: Mouse horizontal motion rolls the head about its gaze vector.
  • 9: Mouse horizontal motion rolls the wand about its ``forwards'' vector.
  • 0: Mouse twirls the entire wireframe box, to better show its contents' spatial relationships.

     

    If you hit a number key twice, the corresponding mode resets to its initial value. For example, hitting 6 twice aims the wand directly forward; hitting 1 twice moves the head back to its central starting point.

     

    Note 1: In most of these modes, simply moving the mouse will modify the input. This can be painful if you're using e.g. a pen tablet instead of a mouse. In this case, typing 'B' will change the behavior such that dragging the input device with the left button held down is required.

     

    Note 2: Whether or not head rotation noticeably affects the application's display depends on the viewing camera. With the default head-mounted camera, rotating the head 90 degrees will rotate the field of view 90 degrees. But with fixed-screen cameras (as used in a CAVE), the displays change almost imperceptibly.

     

    Note 3: If you move the mouse outside the window containing the inputsimulator, a variety of things can happen. If you don't have any buttons held down, whatever you're manipulating will just freeze. If you do have a button held down, however, different things happen on different platforms. On Linux, the object being manipulated will continue to move smoothly as though you were still inside the window. On Win32, on the other hand, the X-coordinate will jump and the Y-coordinate reverses in sign, so whetever you're dragging will probably disappear (if it's the head, something funky will happen to the viewpoint). We plan on changing the Win32 behavior.

Alternate Input Simulators

As of 2/08, you can create your own Input Simulator interface as a shared library and load it at runtime based on the value of the Syzygy database parameter SZG_INPUTSIM/sim_type. A stupid example called arDefaultInputSimulator is contained in szg/skeleton; it behaves just like the built-in one, but it does show you which methods are available for overriding. Copy the skeleton directory tree somewhere, rename the source file, and modify skeleton/build/makefiles/Makefile.my_app appropriately. To use it, add e.g. the following in an <assign> block in your dbatch file:

  <computer> SZG_INPUTSIM sim_type arDefaultInputSimulator

...where <computer> is the computer on which the inputsimulator program will run, as specified in the SZG_INPUT#/map section of your virtual computer definition.

Syzygy System Configuration

The Syzygy Database

Syzygy maintains a database for storing useful bits of information in a way that your program can easily get at. Some of this information is used by the Syzygy libraries to configure your application; you can also use it for storing your own application parameters.

In Standalone Mode, the information is read in from a parameter file (by default, named either szg_parameters.xml or szg_parameters.txt) in the current directory. You make changes to the configuration by editing this text file before launching the application.

In Cluster Mode, this database is maintained by the Syzygy Server and accessed from within the application by means of the arSZGClient object. The database parameters can be examined and changed one at a time using the dget and  dbatch command with the name of a parameter file. Happily, the parameter file for the dbatch command has the same format as the Standalone Mode parameter file. A separate set of parameters is maintained for each user, so any database commands will access the database for the last user logged in to the Syzygy server using the dlogin command.

Loading a Parameter File with dbatch

This is the simplest way to load a large number of parameters in to the Syzygy database. To load a file-full of parameter information:

dbatch <file path>

<file path> can be either an absolute or relative path from the current directory or a file name. If the latter,  dbatch will look for the file in the current working directory. If it isn't there, it will query the Syzygy database for the value of the local parameter SZG_SCRIPT/path. If this parameter is defined it will interpret it as a directory path and look for the named file there.

Printing or Saving Lots of Parameters with dget

To print all of the current user's database parameters:

dget -a

If you redirect this to a file (``dget -a >myparams.xml"), that file can be used for subsequent dbatch commands.

To list all parameters containing a particular string (either in the computer name, group name, parameter name, or value):

dget -a <string>

For example, dget -a my_computer lists all parameters defined for the computer 'my_computer`, and any others that happen to contain that string (such as single lines from virtual computer definitions).

Global and Local Parameters

Parameters in the Syzygy database are either global (not tied to any particular computer) or local (computer-specific).

Global Parameters

There are two main types of global parameters: graphics configurations and input device descriptions. These parameters allow the user to define complex attributes of the system --for example, a graphics window corresponding to one eye of a head-mounted display, or the configuration of a tracking device--without having to consider which computer will perform those functions. This facility makes it easier to re-arrange and replace computers in your cluster.

Global parameters are keyed only by name, and their values are specified in XML. Their structure can be quite complex, so they are discussed in two separate chapters:

Global Graphics Parameters

Read the Syzygy Graphics Configuration chapter.

Global Input Device Parameters

Read the Syzygy Input Device Configuration chapter.

Getting and Setting Global Parameter Values

When running a Syzygy cluster, it is possible (although not very practical) to get and set values of individual global parameters at the command line.

To set a single global parameter using the dset command:

  dset parameter_name parameter_value

However, the value is typically a longish XML string; global parameters are generally specified in a parameter file.

Similarly, you could set a single parameter value using:

  dget parameter_name

 

Local Parameters

Local parameters give information that is particular to a given computer. They are specified or keyed within the database by the computer name, a parameter group, and the parameter name. In documentation, these are typically written as a slash-delimited string, i.e.

  <computer name>/<parameter group>/<parameter name>

For example, the parameter to tell a computer named 'my_computer' the standard location for data files, is represented by:

  my_computer/SZG_DATA/path

 

However, to set these parameters, use the format below.

Getting and Setting Local Parameters

When interacting with the database, either via dget and dset in Cluster Mode or in a parameter file, the key elements are separated by spaces. A parameter file entry line for the parameter above might look like:

  my_computer SZG_DATA path G:\Data

or to set it in Cluster Mode using dset:

  dset my_computer SZG_DATA path G:\Data

If you then typed

  dget my_computer SZG_DATA path

the command would return the value

  G:\Data

 

Categories of Local Parameters

Head Parameters

See the relevant section in the Syzygy Graphics Configuration chapter.

Display Selection

See the relevant section in the Syzygy Graphics Configuration chapter.

Resource Path Specification

Read the chapter on Resource Path Specification.

Alternate Input Simulator

If you're using the inputsimulator as your input device instead of a real device, you can create your own simulator interface as a shared library. See the Alternate Input Simulators section.

Virtual Computers

virtual computer is a means of specifying how a set of computers are wired together and what functions each will perform. You run a program on a virtual computer by issuing a single command; the separate instances of the program and any supporting services are then launched automatically.

See Virtual Computer Configuration and Using a Virtual Computer for more information.

Parameter File Format

Syzygy parameter files are written in XML. A parameter file can contain 3 types of XML records, <comment><assign>, and <param>. These records cannot be nested. For instance, a  <comment> block cannot appear within an <assign>. They can appear in the file in any order, however, and there can be any number of them.

<comment> record contains a comment. These are discarded by the parser. An <assign> record contains either a list of local parameter definitions or a virtual computer definition. Finally, a  <param> record contains a global parameter definition.

Here is an example. Note the required <szg_config>/</szg_config> tags that enclose the entire file:

  <szg_config>
    <comment>
      This is what comments look like in a complex parameter file.
      The following 'assign' record contains a number of local
      parameter definitions.
    </comment>
    <assign>
      smoke SZG_DATA path /home/public/Data
      smoke SZG_RENDER texture_path /home/public/Texture
      smoke SZG_RENDER text_path /home/public/Texture/Text
      smoke SZG_SOUND path /home/public/Sounds
      smoke SZG_DISPLAY0 name head_mounted
    </assign>
    <comment>
      The following 'param' record contains a global device definition.
    </comment>
    <param>
      <name> windows_joystick_filter </name>
      <value>
        define filter_axis_0
          getCurrentEventAxis 0.000031 * setCurrentEventAxis
        enddef
        define filter_axis_1
          getCurrentEventAxis -0.000031 * setCurrentEventAxis
        enddef
      </value>
    </param>
  </szg_config>

 

Example Parameter Files

We've included several templates for the main parameter files in use at the Illinois Simulator Lab. For each template, a valid configuration file for a particular user is generated by substituting his Syzygy user name for "THE_USER_NAME".

The file cube.txt gives a template parameter file for a 6-sided fixed screen VR environment (virtual computer=cube). It also demonstrates how different virtual computers (cube and wincube) can share the same virtual computer location (cube).

The file lab.txt gives a template parameter file for a lab containing a group of workstations, a dual-headed passive stereo display (virtual computer=passive), an Immersadesk-style active stereo display (virtual computer=idesk), and a 3x2 video wall (virtual computer=wall). This template also demonstrates the use of include directives in dbatch files. The include locations are given by SZG_SCRIPT local parameters and the included files contain  screen configurationsdevice configurations, and virtual computer definitions respectively.

The file cave.txt gives a template parameter file for a 4-sided fixed screen VR environment (virtual computer=cave).

Graphic Configuration

As discussed in Syzygy System Configuration, a Syzygy parameter or 'dbatch' file contains two types of parameters, local (computer-specific) and global. Specification of graphical display devices falls into the global category; after defining one or more display devices, you define local parameters for each computer specifying which display or displays it will use.

Global Graphics Parameters

The Syzygy graphics system contains a number of different levels of objects linking the 2-D space of your computer screen or screens to the 3-D space of the virtual world. Starting from the 3-D end, which is also the bottom of the object hierarchy, these are:

  1. Screens: rectangular windows in the virtual world.
  2. Cameras: devices for computing the viewing frustum. Some types use screens.
  3. Viewports: regions of a window, each with an attached camera.
  4. Viewport Lists: Sets of viewports within a single window, either enumerated 'by hand' or auto-generated by pre-defined viewing modes.
  5. Windows: windows of your computer's graphical interface.
  6. Displays: the top-level object; each running render program has one and only one. May contain multiple windows (but usually only one).

Screens

A screen is a virtual window into the virtual world. It is defined by three unit vectors (centernormal, and up) that specify its position and orientation and by its width and height in feet. Note that the normal vector points away from the viewer, and the three vectors don't have to specified as unit vectors, they will be normalized. Note also that all of these quantities represent virtual-world coordinates. Generally speaking, you will probably want them to be congruent with the real-world layout of your physical screens, but you certainly don't have to set them up that way.

A screen has a number of other parameters:

  • headmounted (yes or no) specifies whether the screen's placement (position and orientation) are fixed in the virtual world or relative to the midpoint of the viewer's eyes.
  • tile: If you have a number of screens arranged as a video wall, you can specify them as a single Syzygy screen (having the overall dimensions of the wall), in which case this parameter specifies which tile the current screen is. (tilex/tiley/numtilesx/numtilesy). tilex and tiley are zero-based. For example, if this screen is in the middle row, 3rd position from the left of 4x3 wall, then tilex=2,numtilesx=4,tiley=1,numtilesy=3.
  • usefixedhead (allow, always, or ignore). For multi-person demos in a CAVE, it is preferable to specify a fixed rendering position rather than to render for the position specified by the single operator's head-tracking sensor. This parameter specifies whether or not this screen should honor this fixed-head mode.
  • fixedheadpos is a 3-element vector specifying the rendering position for the current screen for the aforementioned fixed-head mode. The orientation is automatically chosen to face the center of each screen, with the final degree of freedom specified by...
  • fixedheadupangle: For vertical screens you generally want the head to be assumed to be upright in fixed-head mode (fixedheadupangle=0). For horizontal screens (i.e. a ceiling or floor) it can be trickier. This parameter allows you to adjust the direction the top of the head is assumed to point in fixed-head mode for the current screen. Note that, for non-headmounted screens, the head orientation only affects the relative displacement between the left- and right-eye images, so if your setup is not stereoscopic this parameter is irrelevant to you.

     

    Here's how to specify a screen in a parameter file. The structure is XML. For each named global parameter, you create a <param> record with  <name> and <value> sub-records.

     

    <param>
      <name>screen_default</name>
      <value>
        <szg_screen>
          <center x="0." y="0." z="-3." />
          <up x="0." y="1." z="0." />
          <normal x="0." y="0." z="-1." />
          <dim width="8." height="6." />
          <headmounted value="yes" />
          <usefixedhead value="ignore" />
          <fixedheadpos x="0.0" y="5.0" z="0.0" />
          <fixedheadupangle value="0.0" />
          <tile tilex="0" numtilesx="1" tiley="0" numtilesy="1" />
        </szg_screen>
      </value>
    </param>
    
    This defines a head-mounted screen 8x6 feet in size and 3 feet in front of the viewer. Generally speaking, you want a head-mounted screen to ignore fixed-head mode (it's intended for world-fixed screens as in a CAVE), so we set the usefixedhead parameter accordingly. The two following parameters are of course irrelevant in this case, I've just included them for completeness, and the tile parameter is set to the default value.

Cameras

A camera is an object for computing the viewing frustum. There are three types of cameras:

  • The default is the Syzygy VR camera. This uses a screen object (see above) and a head object to compute the frustum according to the laws of perspective projection. The head parameters are local parameters, so they are specified separately. The VR camera has no additional parameters.

The other two types of cameras don't use a screen or head object (or head tracking, for that matter). They also specify near and far clipping planes. Ordinarily, Syzygy programs specify their own near and far clipping distances, and the VR camera honors these. The other two camera types don't. For these reasons, they are only useful in special circumstances:

  • Perspective camera generates a similar frustum to a VR camera. In both cases, objects appear smaller the farther they are from the viewer. BugFix: prior to Syzygy 1.0.1, requesting a perspective camera would actually get you an ortho one.
  • An Ortho camera creates an orthographic projection, in which an object appears the same size regardless of distance.

Both are specified with the following two parameters:

  • frustum (left/right/top/bottom/near/far) specifies the boundaries of the viewing frustum. In the case of a perspective camera, left/right/top/bottom specifies the dimensions of the near edge of the frustum; an ortho camera's frustum is rectangular, so front and back edges are the same size.
  • lookat (viewx/viewy/viewz/lookatx/lookaty/lookatz/upx/upy/upz). The first three specify the viewing position, the second three a point looked at, the final three the 'up' direction.

     

    Here are examples. The first one's pretty boring, it's a VR camera using the screen object from the preceding example.
    <param>
      <name>camera_default</name>
      <value>
        <szg_camera type="vr">
          <szg_screen usenamed = "screen_default" />
        </szg_camera>
      </value>
    </param>
    
    Here's a perspective camera with the same field of view:
    <param>
      <name>camera_perspective</name>
      <value>
        <szg_camera type="perspective">
          <frustum left="-4."  right="4."  bottom="-3."
                    top="3."    near="3."     far="1000000." />
          <lookat viewx="0."   viewy="5."   viewz="0."
                lookatx="0." lookaty="5." lookatz="-1."
                    upx="0."     upy="1."     upz="0." />
        </szg_camera>
      </value>
    </param>
    

Viewports

A viewport binds a camera object to a specific sub-region within a window on your computer screen. Besides a camera, a viewport has the following parameters:

  • coords (left/bottom/width/height): numbers between 0. and 1., specifying the location of the viewport within a window.
  • depthclear (value=yes/no): whether or not the Z-buffer is cleared before rendering into this viewport. Default is no; the Z-buffer for the entire window is cleared at the beginning of each frame. Setting this is necessary for e.g. anaglyph mode. It incurs a performance hit, as each viewport that sets this invokes a glClear().
  • colormask (R/G/B/A, all yes/no): which color channels to draw into.
  • eyesign (value=a float): Whether this viewport is a right(1.)- or left(-1.)-eye view, or for monocular viewing (0.). This information is used by a Syzygy VR camera (see Cameras above) to modify its frustum appropriately for stereoscopic viewing. The Perspective and Ortho cameras ignore the eye sign.
  • ogldrawbuf: many possible values (GL_BACK_LEFT is safe). See the OpenGL Programming Guide ("red book"), chapter 10, "Selecting Color Buffers for Writing."
  • colorclear (value=yes/no): whether or not the color buffer is cleared before rendering into this viewport. Default is no; the color buffer for the entire window is cleared at the beginning of each frame. Setting this is necessary for overlapping viewports, e.g. if you want a rear-view mirror viewport a bit below the top of a windshield viewport you would set colorclear=yes in the mirror viewport definition. Otherwise, the content from the windshield viewport would be visible underneath the mirror content. It incurs a performance hit, as each viewport that sets this invokes a glClear(). The colorclear feature is new as of 5/17/2011 and is _not_ backwards compatible, i.e. programs linked against older versions of Syzygy will refuse to run if presented with a viewport that has a colorclear parameter. If you need to run older programs, they'll have to provided with separate viewports, windows, displays, and virtual computers.

Note that you can specify more than one viewport in the same part of the window, in fact it's sometimes necessary. For example, to manually specify a red/cyan anaglyph stereo window (this is unnecessary, as we'll see below), you would create two viewports with coords=(0/0/1/1): the first with e.g. colormask=(R=yes/G=no/B=no/A=yes) and eyesign value=-1., the second with colormask=(R=no/G=yes/B=yes/A=yes), eyesign=1., and depthclear=yes.

Here's a very ordinary viewport, with the point of view at the midpoint of the eyes.

<param>
  <name>viewport_default</name>
  <value>
    <szg_viewport>
      <szg_camera usenamed="camera_default" />
      <coords left="0." bottom="0." width="1." height="1." />
      <depthclear value="no" />
      <colormask R="yes" G="yes" B="yes" A="true" />
      <eyesign value="0." />
      <ogldrawbuf value="GL_BACK_LEFT" />
    </szg_viewport>
  </value>
</param>

Note that for boolean values, yes/no and true/false are interchangeable.

Viewport Lists

A viewport list may contain one or more viewports. They can be specified in a couple of different ways:

  1. By setting the viewmode parameter to 'custom' and defining a viewport list in which you enumerate a set of viewports using the parameters described above.
  2. By setting the viewmode parameter to one of the pre-defined viewing modes. In these viewing modes, you only specify a camera that is shared by the viewports; the software automatically generates one or more viewports. The number of viewports generated depends on whether or not the window's "stereo" parameter is set to "true" (for active stereo). In each case, two sets of viewports are created if active stereo is in use; one set has eyesign set to -1 and ogldrawbuf set to GL_BACK_LEFT, while the other has eyesign set to +1 and ogldrawbuf set to GL_BACK_RIGHT. Each set is as described below. If active stereo is not in use, all viewports have ogldrawbuf set to GL_BACK_LEFT. In most of the viewing modes, pairs of viewports are generated with eyesign equal to 1 and -1.

     

    The predefined viewing modes are:
    • normal: A single viewport that fills the window, i.e.:
        <szg_viewport_list viewmode="normal">
          <szg_camera usenamed="camera_default" />
        </szg_viewport_list>
      
      ...is equivalent to:
        <szg_viewport_list viewmode="custom">
          <szg_viewport>
            <szg_camera usenamed="camera_default" />
            <coords left="0." bottom="0." width="1." height="1." />
            <depthclear value="no" />
            <colormask R="yes" G="yes" B="yes" A="true" />
            <eyesign value="0." />
            <ogldrawbuf value="GL_BACK_LEFT" />
          </szg_viewport>
        </szg_viewport_list>
      
      ...or if active stereo is in use, to:
        <szg_viewport_list viewmode="custom">
          <szg_viewport>
            <szg_camera usenamed="camera_default" />
            <coords left="0." bottom="0." width="1." height="1." />
            <depthclear value="no" />
            <colormask R="yes" G="yes" B="yes" A="true" />
            <eyesign value="-1." />
            <ogldrawbuf value="GL_BACK_LEFT" />
          </szg_viewport>
          <szg_viewport>
            <szg_camera usenamed="camera_default" />
            <coords left="0." bottom="0." width="1." height="1." />
            <depthclear value="no" />
            <colormask R="yes" G="yes" B="yes" A="true" />
            <eyesign value="1." />
            <ogldrawbuf value="GL_BACK_RIGHT" />
          </szg_viewport>
        </szg_viewport_list>
      

       

    • anaglyph: As described above, for stereo viewing with red/cyan anaglyph glasses, available from [http://www.berezin.com/3D/3dglasses.htm] or [ http://www.3dglassesonline.com/]. This:
        <szg_viewport_list viewmode="anaglyph">
          <szg_camera usenamed="camera_default" />
        </szg_viewport_list>
      
      ...is equivalent to (without active stereo; note colormask and depthclear values):
        <szg_viewport_list viewmode="custom">
          <szg_viewport>
            <szg_camera usenamed="camera_default" />
            <coords left="0." bottom="0." width="1." height="1." />
            <depthclear value="no" />
            <colormask R="yes" G="no" B="no" A="yes" />
            <eyesign value="-1." />
            <ogldrawbuf value="GL_BACK_LEFT" />
          </szg_viewport>
          <szg_viewport>
            <szg_camera usenamed="camera_default" />
            <coords left="0." bottom="0." width="1." height="1." />
            <depthclear value="yes" />
            <colormask R="no" G="yes" B="yes" A="yes" />
            <eyesign value="1." />
            <ogldrawbuf value="GL_BACK_LEFT" />
          </szg_viewport>
        </szg_viewport_list>
      
      Note that this will only work properly if your scene is rendered in gray-scale.
    • walleyed: Divides the window in half horizontally, with the left-eye image in the left half and the right-eye image on the right. For e.g. the Screenscope viewer. This:
        <szg_viewport_list viewmode="walleyed">
          <szg_camera usenamed="camera_default" />
        </szg_viewport_list>
      
      ...is equivalent to:
        <szg_viewport_list viewmode="custom">
          <szg_viewport>
            <szg_camera usenamed="camera_default" />
            <coords left="0." bottom="0." width=".5" height="1." />
            <depthclear value="no" />
            <colormask R="yes" G="yes" B="yes" A="yes" />
            <eyesign value="-1." />
            <ogldrawbuf value="GL_BACK_LEFT" />
          </szg_viewport>
          <szg_viewport>
            <szg_camera usenamed="camera_default" />
            <coords left=".5" bottom="0." width=".5" height="1." />
            <depthclear value="no" />
            <colormask R="yes" G="yes" B="yes" A="yes" />
            <eyesign value="1." />
            <ogldrawbuf value="GL_BACK_LEFT" />
          </szg_viewport>
        </szg_viewport_list>
      
    • crosseyed: The converse of the above, with the right-eye image on the left and vice versa.
    • overunder: Divides the window in half vertically, for viewers like the View Magic.

As stated above, all of the viewing modes described here can be combined with active stereo. This is not something you'd want to do for normal VR, but it's there if you need it.

Windows

A Syzygy window corresponds to a window of your computer's graphical interface. A window contains a viewport list and the following additional parameters:

  • size (width/height in pixels).
  • position (x/y in pixels from upper-left screen corner).
  • fullscreen (yes/no). If yes, the window is zoomed or maximized after being created.
  • decorate (yes/no). Whether or not the window has a frame, close widget, etc.
  • stereo (yes/no). This refers to active stereo, in which your scene is rendered in alternation for the left and right eyes and you view it through LCD shutter glasses that are synchronized with the vertical refresh of the graphics card (see e.g. the Barco Active Stereo page). If you set this to 'yes' and your graphics card does not support active stereo, applications will crash. Note that this setting is independent of the stereo viewing modes described above. For normal active stereo, you would set stereo to 'yes' and viewmode to 'normal'.
  • zorder (normal/top/topmost). Whether or not your window tries to stay on top of other windows. 'topmost' is stronger than 'top', in that 'top' only tries to stay above other 'normal' windows, but 'special' windows (particularly on Win32) might cover it. 'topmost' tries to stay on top of everything.
  • bpp. Color depth (bits/pixel). MS Windows only, I think.
  • title. Appears in window title bar, task bar, etc.
  • xdisplay. Only meaningful on Unix sytems (Linux, Mac, Irix). Gives the name of the X display where the window should appear. Default is ":0.0".
  • cursor (arrow/none/help/wait). The appearance of the mouse cursor when it's inside the window.

     

    Here's a definition for a fullscreen window:
    <param>
    <name>win_default</name>
    <value>
      <szg_window>
        <size width="400" height="300" />
        <position x="50" y="50" />
        <decorate value="false" />
        <fullscreen value="true" />
        <cursor value="none" />
        <title value="A Syzygy Window" />
        <stereo value="false" />
        <zorder value="topmost" />
        <szg_viewport_list usenamed="vplist_default" />
      </szg_window>
    </value>
    </param>
    

Displays

Each Syzygy rendering program will attach itself to a display. As of Syzygy 0.8, a display contains one or more windows; previously each process could only open one window.

Other parameters of displays are:

  • framelock (wgl/wildcat/none): specifies whether the display supports hardware gen-locking Note that "wgl" and "wildcat" are equivalent, "wildcat" is deprecated.
  • threaded (yes/no): In a multi-window display, are the windows rendered by separate program threads.

     

    Not much to it:
    <param>
    <name>display_default</name>
    <value>
      <szg_display framelock="none" threaded="no">
        <szg_window usenamed="win_default" />
      </szg_display>
    </value>
    </param>
    

Nesting Parameter Definitions

Putting it all together: Up til now I've been putting each object in it's own <param> block and then referring to it later by name. Which is elegant and flexible, but verbose. You can also glom it all together into one XML record, as shown here:

<param>
  <name>display_glommed</name>
  <value>
    <szg_display framelock="none" threaded="no">
      <szg_window>
        <size width="400" height="300" />
        <position x="50" y="50" />
        <decorate value="false" />
        <fullscreen value="true" />
        <cursor value="none" />
        <title value="A Syzygy Window" />
        <stereo value="false" />
        <zorder value="topmost" />
        <szg_viewport_list viewmode="walleyed">
          <szg_camera type="vr">
            <szg_screen>
              <center x="0." y="0." z="-3." />
              <up x="0." y="1." z="0." />
              <normal x="0." y="0." z="-1." />
              <dim width="8." height="6." />
              <headmounted value="yes" />
              <usefixedhead value="ignore" />
              <fixedheadpos x="0.0" y="5.0" z="0.0" />
              <fixedheadupangle value="0.0" />
              <tile tilex="0" numtilesx="1" tiley="0" numtilesy="1" />
            </szg_screen>
          </szg_camera>
        </szg_viewport_list>
      </szg_window>
    </szg_display>
  </value>
</param>

or, omitting default and unimportant values:

<param>
  <name>display_compact</name>
  <value>
    <szg_display>
      <szg_window>
        <size width="400" height="300" />
        <position x="50" y="50" />
        <decorate value="false" />
        <fullscreen value="true" />
        <cursor value="none" />
        <zorder value="topmost" />
        <szg_viewport_list viewmode="walleyed">
          <szg_camera type="vr">
            <szg_screen>
              <center x="0." y="0." z="-3." />
              <up x="0." y="1." z="0." />
              <normal x="0." y="0." z="-1." />
              <dim width="8." height="6." />
              <headmounted value="yes" />
              <usefixedhead value="ignore" />
            </szg_screen>
          </szg_camera>
        </szg_viewport_list>
      </szg_window>
    </szg_display>
  </value>
</param>

(Actually, headmounted="yes" is the default, but I figure that's important enough to always specify explicitly).

Basically, any tag beginning with 'szg_' represents a record that can either be embedded within another record or split off into its own named parameter.

Local Graphics Parameters

As mentioned in the Syzygy System Configuration chapter Syzygy configuration parameters are global or  local. There are three sets of local parameters that are relevant to the display of your virtual world: head parameters, selection of displays, and resource paths. If one of these parameters is not defined in the parameter database, then Syzygy will query an appropriate environment variable for the value (see Standalone Mode for an explanation).

Heads

As mentioned above in the Cameras section, a Syzygy VR camera requires a head object to compute the viewing frustum. This object contains information about the spatial relationships between the eyes and a tracking sensor on the user's head. These do not need to be defined on every computer, just on each computer that is either a master or trigger (NOTE: need a link here). A master computer is one on which the master instance of a master/slave application runs; the controller program of a distributed scene graph application runs on the trigger computer. These programs will share the head information with relevant other programs running on the cluster. When running in Standalone Mode, the current computer is both master and trigger for the purposes of this section. Please see the chapter on the Cluster Mode for a definition of these terms.

A head has the following parameters:

  • eye_spacing: The inter-ocular separation in feet. Defaults to 0.2 (about 6.1 cm.), which is just a bit below the average for the adult population.
  • eye_direction: A unit vector specifying the direction from the midpoint of the eyes to the right eye as measured in the coordinate system defined by the head-tracking sensor. Three-element vectors are represented in the parameter database as '/'-delimited strings of numbers. eye_direction defaults to 1/0/0, i.e. the positive X direction.
  • mid_eye_offset: A three-element vector specifying the position of the midpoint of the eyes in the head-tracking sensor coordinate system.
  • fixed_head_mode: As discussed in the section on screens, Syzygy supports a fixed-head rendering mode that is preferable for multi-person demos in a CAVE or other fixed-screen environment. This variable (a boolean, i.e. one of yes/no/true/false) is the switch that puts a program in that mode. It can be overridden for an individual screen object by the appropriate choice of the usefixedhead parameter.

An example. The following block of parameters specifies that, for computer 'Machine':

  • The distance between the eyes is 0.2 feet.
  • The unit vector from the midpoint of the eyes towards the right eye in the head tracker coordinate system is (x=1,y=0,z=0).
  • The offset in feet to the midpoint of the eyes in the tracker coordinate system (i.e. with respect to the head-tracking sensor) is (x=0.29,y=0,z=0).
  • Fixed-head mode is turned off. Fixed-head mode is a special viewing mode intended for group demos. Instead of rendering the virtual world for the head position specified by the tracker, each computer renders it for a specified head position and orientation. See the Screens section.

     

      Machine SZG_HEAD eye_spacing 0.2
      Machine SZG_HEAD eye_direction 1/0/0
      Machine SZG_HEAD mid_eye_offset 0.29/0/0
      Machine SZG_HEAD fixed_head_mode false
    

Display Selection

As discussed in the section on displays, each computer can be assigned one or more display objects. These are differentiated on the basis of a 0-based index, i.e. the default display is #0, the next #1, etc.

A simple example should suffice to demonstrate the selection of two displays (we'll use named displays defined above) for the computer named 'Machine':

  Machine SZG_DISPLAY0 name display_default
  Machine SZG_DISPLAY1 name display_compact

 

TroubleShooting

The global graphics parameter portions of a Syzygy parameter ('dbatch') file are not parsed when the file is loaded, but when an application is launched and about to open a window. Error messages will typically begin with:

  szg:ERROR: arGUIXML ...

usually give a fairly accurate indication of where the error occurred.

Besides XML syntax errors, the parser will catch mis-spelled attribute names. It will also catch illegal attribute values if the set of legal values is small (e.g. if the value must be one of yes/no/true/false). It makes no attempt to check that numerical values are reasonable, so to catch that sort of error you'll have to inspect the virtual scene display itself.

Graphics Configuration Examples

This chapter contains some special graphics configuration examples.

It assumes that you've built Syzygy with dynamic linking (i.e., not with g++ in Windows).

Defining a Virtual Cube in a Single Window (Using Viewports)

Sometimes, for debugging purposes, it might be convenient to be able to see, in a single window, most of the screens (in this case 5 out of 6) in an immersive virtual environment. This lets us make sure that are camera projection code is doing the right thing with minimal hassle and also gives an interesting visual effect. We now explore how to create such a custom graphics configuration. In this case, we show the XML config for a "virtual cube", where the viewports are the front, top, bottom, left, and right walls of a CAVE-style environment. Note how the XML "pointers" are used to refer from inside "virtual_cube_window" to appropriate screen configs.

  <param>
  <name> front_wall </name>
  <value>
  <szg_screen>
    <center x="0" y="4.93" z="-4.93" />
    <up x="0" y="1" z="0" />
    <dim width="9.86" height="9.86" />
    <normal x="0" y="0" z="-1" />
    <headmounted value="false" />
    <tile tilex="0" numtilesx="1" tiley="0" numtilesy="1" />
    <usefixedhead value="allow" />
    <fixedheadpos x="0.0" y="5.5" z="0.0" />
    <fixedheadupangle value="0.0" />
  </szg_screen>
  </value>
  </param>
  <param>
  <name> right_wall </name>
  <value>
  <szg_screen>
    <center x="4.93" y="4.93" z="0" />
    <up x="0" y="1" z="0" />
    <dim width="9.86" height="9.86" />
    <normal x="1" y="0" z="0" />
    <headmounted value="false" />
    <tile tilex="0" numtilesx="1" tiley="0" numtilesy="1" />
    <usefixedhead value="allow" />
    <fixedheadpos x="0.0" y="5.5" z="0.0" />
    <fixedheadupangle value="0.0" />
  </szg_screen>
  </value>
  </param>
  <param>
  <name> left_wall </name>
  <value>
  <szg_screen>
    <center x="-4.93" y="4.93" z="0" />
    <up x="0" y="1" z="0" />
    <dim width="9.86" height="9.86" />
    <normal x="-1" y="0" z="0" />
    <headmounted value="false" />
    <tile tilex="0" numtilesx="1" tiley="0" numtilesy="1" />
    <usefixedhead value="allow" />
    <fixedheadpos x="0.0" y="5.5" z="0.0" />
    <fixedheadupangle value="0.0" />
  </szg_screen>
  </value>
  </param>
  <param>
  <name> top_wall_unrotated </name>
  <value>
  <szg_screen>
    <center x="0" y="9.86" z="0" />
    <up x="0" y="0" z="1" />
    <dim width="9.86" height="9.86" />
    <normal x="0" y="1" z="0" />
    <headmounted value="false" />
    <tile tilex="0" numtilesx="1" tiley="0" numtilesy="1" />
    <usefixedhead value="allow" />
    <fixedheadpos x="0.0" y="5.5" z="0.0" />
    <fixedheadupangle value="0" />
  </szg_screen>
  </value>
  </param>
  <param>
  <name> bottom_wall </name>
  <value>
  <szg_screen>
    <center x="0" y="0" z="0" />
    <up x="0" y="0" z="-1" />
    <dim width="9.86" height="9.86" />
    <normal x="0" y="-1" z="0" />
    <headmounted value="false" />
    <tile tilex="0" numtilesx="1" tiley="0" numtilesy="1" />
    <usefixedhead value="allow" />
    <fixedheadpos x="0.0" y="5.5" z="0.0" />
    <fixedheadupangle value="0.0" />
  </szg_screen>
  </value>
  </param>
  <param>
  <name>virtual_cube_window</name>
  <value>
  <szg_display>
   <szg_window>
     <size width="600" height="600" />
     <position x="50" y="50" />
     <decorate value="true" />
     <fullscreen value="false" />
     <title value="szg" />
     <stereo value="false" />
     <topmost value="false" />
     <xdisplay value="" />
     <szg_viewport_list viewmode="custom">
       <szg_viewport>
         <depthclear value="false" />
         <colormask R="true" G="true" B="true" A="true" />
         <ogldrawbuf value="GL_BACK_LEFT" />
         <eyesign value="0" />
         <coords left="0.3333" bottom="0.3333" width="0.3333" height="0.3333" />
         <szg_camera>
           <szg_screen usenamed="front_wall" />
         </szg_camera>
       </szg_viewport>
       <szg_viewport>
         <eyesign value="0" />
         <coords left="0.6666" bottom="0.3333" width="0.3333" height="0.3333" />
         <szg_camera>
           <szg_screen usenamed="right_wall" />
         </szg_camera>
       </szg_viewport>
       <szg_viewport>
         <eyesign value="0" />
         <coords left="0" bottom="0.3333" width="0.3333" height="0.3333" />
         <szg_camera>
           <szg_screen usenamed="left_wall" />
         </szg_camera>
       </szg_viewport>
       <szg_viewport>
         <eyesign value="0" />
         <coords left="0.3333" bottom="0.6666" width="0.3333" height="0.3333" />
         <szg_camera>
           <szg_screen usenamed="top_wall_unrotated" />
         </szg_camera>
       </szg_viewport>
       <szg_viewport>
         <eyesign value="0" />
         <coords left="0.3333" bottom="0" width="0.3333" height="0.3333" />
         <szg_camera>
           <szg_screen usenamed="bottom_wall" />
         </szg_camera>
       </szg_viewport>
     </szg_viewport_list>
   </szg_window>
  </szg_display>
  </value>
  </param>

 

Of course, to use the virtual cube window (by default) on a computer, you will want the following local parameter in the Syzygy database:

  the_computer_name SZG_DISPLAY0 name virtual_cube_window

 

Inside the "virtual_cube_window" XML, note how the szg_viewport_list element has a viewmode attribute with value "custom". This tells Syzygy to look for szg_viewport children of the szg_viewport_list element. Each describes a viewport of the window into which a view of the scene will be drawn. The viewports are drawn in order of their appearance and can overlap. For instance, anaglyph stereo can be implemented with overlapping viewports, color masking, and depth buffer manipulation.

  <coords left="0.3333" bottom="0.3333" width="0.3333" height="0.3333" />

The viewport's coordinates are relative to the window. The window's lower left corner has coordinates (0,0), the upper right (1,1). So the width and height of the full window are both 1. This parameter defaults to 0/0/1/1.

  <colormask R="true" G="true" B="true" A="true" />

The OpenGL color mask to be applied to the window, e.g. for doing anaglyphic stereo. The color mask values are given in RGBA order, and must be either "true" or "false". In the example here, only the red value of the scene's pixels will be drawn. The default is "true/true/true/true", which draws the scene normally.

  <depthclear value="false" />

When multiple passes of the same scene are drawn on the same part of the screen (as in anaglyphic stereo), the second pass must clear the depth buffer before drawing. Iff this parameter is "true," the depth buffer will be cleared before drawing. The default is "false".

  <ogldrawbuf value="GL_BACK_LEFT" />

The OpenGL buffer into which the viewport draws, by default GL_BACK_LEFT.

  <eyesign value="0" />

The eyesign (i.e. right eye, left eye, or eye midpoint). The default is 0, the midpoint; 1 means the right eye; and -1 means the left eye.

Passive Stereo

Syzygy supports a variety of passive stereo configurations. One of them, "walleyed", is suited to working with dual-headed graphics cards under Windows. Many of these cards can be set up so that the Windows desktop extends across both monitors and a single hardware accelerated OpenGL window can cover the whole thing. Under this scenario, a full screen window, with a left eye view on one half and the right eye view on the other half, can provide passive stereo. Simply hook up projectors to each of the card's outputs, put polarizing filters on each, and project onto the same screen. You can then use cheap stereo glasses (based on polarized light) to see the visualization in 3D. The following configuration shows how to do this.

  <param>
  <name>passive_stereo</name>
  <value>
  <szg_display threaded="false">
   <szg_window>
     <size width="600" height="600" />
     <position x="0" y="0" />
     <decorate value="false" />
     <fullscreen value="true" />
     <cursor value="none" />
     <stereo value="false" />
     <zorder value="topmost" />
     <szg_viewport_list viewmode="walleyed">
       <szg_camera>
         <szg_screen>
           <center x="0" y="5" z="-5" />
           <up x="0" y="1" z="0" />
           <dim width="13.33" height="10" />
           <normal x="0" y="0" z="-1" />
           <headmounted value="false" />
         </szg_screen>
       </szg_camera>
     </szg_viewport_list>
   </szg_window>
  </szg_display>
  </value>
  </param>

 

Easy Demo Passive Stereo Display in Standalone Mode

Since passive stereo displays are so easy to set up and so cheap, given how common dual headed video game graphics cards are, they are ideal for travelling demos, like one might bring to a conference or trade show. One consideration with demo system design is tracking, since, in the interests of simplicity, one would like to avoid it all together. Tracking can be of marginal benefit in such situations.

Consequently, a simple demo system might skip tracking altogether in favor of gamepad control. Syzygy VR framework applications often assume their input device provides them with a matrix giving head position and orientation (matrix 0) and a matrix giving wand (manipulation device) position and orientation (matrix 1). Navigation in the world is accomplished by a combination of wand matrix plus button pushes and axis manipulation. In many cases, leaving the wand matrix in a default (identity matrix) position still allows for sufficient navigation for a successdul demo. However, the head matrix often needs to go into a non-default position (not (0,0,0)) to have things appear sensibly on screen.

To fix this problem, we construct a PForth filter that, when processing an event from the gamepad, creates an additional (and spurious) head matrix event, putting the head in the desired default position.

The following dbatch file ("complex" format) gives a Standalone Mode configuration for a demo system as described above. Note that the lone global parameter gives a PForth program instead of a full input node configuration. In Standalone Mode, Syzygy VR framework applications either use an embedded inputsimulator to generate input events or rely on joystick input. The value of SZG_DEMO/control_mode (either "joystick" or "normal", which is the default) determines the control scheme used. Also, SZG_PFORTH/program_names gives the name of the global parameter holding the PForth program to be applied, if any.

The "joystick" PForth program listed, of course, pertains to a particular gamepad. However, it does illustrate how to switch axes around. For instance, it addition to rescaling, axis 2 is mapped to axis 3 and axis 5 is mapped to axis 2.

In examining the config file given below, remember that "NULL", when used as a computer name, is a wildcard refering to whatever computer one is currently executing upon.

<szg_config>
  <param>
    <name> joystick </name>
    <value>

      /* Declare a 4x4 matrix variable named 'temp' */
      matrix fixHeadMatrix
      /* Store a y += 5 translation in temp */
      0 5 0 fixHeadMatrix translationMatrix

      /* Define a number of 'filter' words. For each incoming input
         event, it checks to see whether a filter word with the
         appropriate event type and index in its name exists
         and calls it (e.g. filter_axis_0) is called whenever
         an axis event #0 comes in) */
      define filter_axis_0
        /* Rescale the axis event (presumably to map it to [-1,1]) */
        getCurrentEventAxis 0.000031 * setCurrentEventAxis
      enddef

      define filter_axis_1
        /* Create a new matrix #0 (i.e. head) event placing the
           head at y = 5. */
        fixHeadMatrix 0 insertMatrixEvent
        getCurrentEventAxis -0.000031 * setCurrentEventAxis
      enddef

      define filter_axis_2
        getCurrentEventAxis -32768 + -0.000031 * setCurrentEventAxis
        /* Change the current event's index from 2 to 3 */
        3 setCurrentEventIndex
      enddef

      define filter_axis_5
        getCurrentEventAxis -32768 + 0.000031 * setCurrentEventAxis
        2 setCurrentEventIndex
      enddef

    </value>
  </param>

  <param>
    <name>passive_stereo</name>
    <value>
      <szg_display threaded="false">
       <szg_window>
         <size width="600" height="600" />
         <position x="0" y="0" />
         <decorate value="false" />
         <fullscreen value="true" />
         <cursor value="none" />
         <stereo value="false" />
         <zorder value="topmost" />
         <szg_viewport_list viewmode="walleyed">
           <szg_camera>
             <szg_screen>
               <center x="0" y="5" z="-5" />
               <up x="0" y="1" z="0" />
               <dim width="13.33" height="10" />
               <normal x="0" y="0" z="-1" />
               <headmounted value="false" />
             </szg_screen>
           </szg_camera>
         </szg_viewport_list>
       </szg_window>
      </szg_display>
    </value>
  </param>

  <assign>
    NULL SZG_DATA path ./
    NULL SZG_STANDALONE input_config joystick
    NULL SZG_DISPLAY0 name passive_stereo
  </assign>
</szg_config>

 

Fixed-Display Virtual Environments

An early supported Syzygy configuration was one stereo window per PC, with each window supporting one wall of an immersive virtual environment. The following text shows screen definitions (plus a virtual computer employing them) for a six-walled virtual environment. See Cluster Mode for a discussion of virtual computers.

  <szg_config>
  <assign>
  cube SZG_CONF    location       cube
  cube SZG_CONF    virtual        true
  cube SZG_TRIGGER map            air
  cube SZG_MASTER  map            SZG_DISPLAY2
  cube SZG_DISPLAY  number_screens 6
  cube SZG_DISPLAY0 map            top/SZG_DISPLAY0
  cube SZG_DISPLAY0 networks       internet
  cube SZG_DISPLAY1 map            bottom/SZG_DISPLAY0
  cube SZG_DISPLAY1 networks       internet
  cube SZG_DISPLAY2 map            north/SZG_DISPLAY0
  cube SZG_DISPLAY2 networks       internet
  cube SZG_DISPLAY3 map            south/SZG_DISPLAY0
  cube SZG_DISPLAY3 networks       internet
  cube SZG_DISPLAY4 map            east/SZG_DISPLAY0
  cube SZG_DISPLAY4 networks       internet
  cube SZG_DISPLAY5 map            west/SZG_DISPLAY0
  cube SZG_DISPLAY5 networks       internet
  cube SZG_INPUT0  map            air/cube_tracker/joystick/cube_joystick
  cube SZG_INPUT0  networks       internet
  top SZG_DISPLAY0 name top_window_stereo
  bottom SZG_DISPLAY0 name bottom_window_stereo
  north SZG_DISPLAY0 name north_window_stereo
  south SZG_DISPLAY0 name south_window_stereo
  east SZG_DISPLAY0 name east_window_stereo
  west SZG_DISPLAY0 name west_window_stereo
  </assign>
  <param>
  <name> front_wall </name>
  <value>
  <szg_screen>
    <center x="0" y="4.93" z="-4.93" />
    <up x="0" y="1" z="0" />
    <dim width="9.86" height="9.86" />
    <normal x="0" y="0" z="-1" />
    <headmounted value="false" />
    <tile tilex="0" numtilesx="1" tiley="0" numtilesy="1" />
    <usefixedhead value="allow" />
    <fixedheadpos x="0.0" y="5.5" z="0.0" />
    <fixedheadupangle value="0.0" />
  </szg_screen>
  </value>
  </param>
  <param>
  <name> right_wall </name>
  <value>
  <szg_screen>
    <center x="4.93" y="4.93" z="0" />
    <up x="0" y="1" z="0" />
    <dim width="9.86" height="9.86" />
    <normal x="1" y="0" z="0" />
    <headmounted value="false" />
    <tile tilex="0" numtilesx="1" tiley="0" numtilesy="1" />
    <usefixedhead value="allow" />
    <fixedheadpos x="0.0" y="5.5" z="0.0" />
    <fixedheadupangle value="0.0" />
  </szg_screen>
  </value>
  </param>
  <param>
  <name> left_wall </name>
  <value>
  <szg_screen>
    <center x="-4.93" y="4.93" z="0" />
    <up x="0" y="1" z="0" />
    <dim width="9.86" height="9.86" />
    <normal x="-1" y="0" z="0" />
    <headmounted value="false" />
    <tile tilex="0" numtilesx="1" tiley="0" numtilesy="1" />
    <usefixedhead value="allow" />
    <fixedheadpos x="0.0" y="5.5" z="0.0" />
    <fixedheadupangle value="0.0" />
  </szg_screen>
  </value>
  </param>
  <param>
  <name> rear_wall </name>
  <value>
  <szg_screen>
    <center x="0" y="4.93" z="4.93" />
    <up x="0" y="1" z="0" />
    <dim width="9.86" height="9.86" />
    <normal x="0" y="0" z="1" />
    <headmounted value="false" />
    <tile tilex="0" numtilesx="1" tiley="0" numtilesy="1" />
    <usefixedhead value="allow" />
    <fixedheadpos x="0.0" y="5.5" z="0.0" />
    <fixedheadupangle value="0.0" />
  </szg_screen>
  </value>
  </param>
  <param>
  <name> top_wall </name>
  <value>
  <szg_screen>
    <center x="0" y="9.86" z="0" />
    <up x="-1" y="0" z="0" />
    <dim width="9.86" height="9.86" />
    <normal x="0" y="1" z="0" />
    <headmounted value="false" />
    <tile tilex="0" numtilesx="1" tiley="0" numtilesy="1" />
    <usefixedhead value="allow" />
    <fixedheadpos x="0.0" y="5.5" z="0.0" />
    <fixedheadupangle value="-90" />
  </szg_screen>
  </value>
  </param>
  <param>
  <name> bottom_wall </name>
  <value>
  <szg_screen>
    <center x="0" y="0" z="0" />
    <up x="0" y="0" z="-1" />
    <dim width="9.86" height="9.86" />
    <normal x="0" y="-1" z="0" />
    <headmounted value="false" />
    <tile tilex="0" numtilesx="1" tiley="0" numtilesy="1" />
    <usefixedhead value="allow" />
    <fixedheadpos x="0.0" y="5.5" z="0.0" />
    <fixedheadupangle value="0.0" />
  </szg_screen>
  </value>
  </param>
  <param>
  <name>front_window_stereo</name>
  <value>
  <szg_display framelock="wgl">
   <szg_window>
     <decorate value="false" />
     <fullscreen value="true" />
     <stereo value="true" />
     <zorder value="topmost" />
     <cursor value="none" />
     <szg_viewport_list viewmode="normal">
       <szg_camera>
         <szg_screen usenamed="front_wall" />
       </szg_camera>
     </szg_viewport_list>
   </szg_window>
  </szg_display>
  </value>
  </param>
  <param>
  <name>right_window_stereo</name>
  <value>
  <szg_display framelock="wgl">
   <szg_window>
     <decorate value="false" />
     <fullscreen value="true" />
     <stereo value="true" />
     <zorder value="topmost" />
     <cursor value="none" />
     <szg_viewport_list viewmode="normal">
       <szg_camera>
         <szg_screen usenamed="right_wall" />
       </szg_camera>
     </szg_viewport_list>
   </szg_window>
  </szg_display>
  </value>
  </param>
  <param>
  <name>left_window_stereo</name>
  <value>
  <szg_display framelock="wgl">
   <szg_window>
     <decorate value="false" />
     <fullscreen value="true" />
     <stereo value="true" />
     <zorder value="topmost" />
     <cursor value="none" />
     <szg_viewport_list viewmode="normal">
       <szg_camera>
         <szg_screen usenamed="left_wall" />
       </szg_camera>
     </szg_viewport_list>
   </szg_window>
  </szg_display>
  </value>
  </param>
  <param>
  <name>rear_window_stereo</name>
  <value>
  <szg_display framelock="wgl">
   <szg_window>
     <decorate value="false" />
     <fullscreen value="true" />
     <stereo value="true" />
     <zorder value="topmost" />
     <cursor value="none" />
     <szg_viewport_list viewmode="normal">
       <szg_camera>
         <szg_screen usenamed="rear_wall" />
       </szg_camera>
     </szg_viewport_list>
   </szg_window>
  </szg_display>
  </value>
  </param>
  <param>
  <name>top_window_stereo</name>
  <value>
  <szg_display framelock="wgl">
   <szg_window>
     <decorate value="false" />
     <fullscreen value="true" />
     <stereo value="true" />
     <zorder value="topmost" />
     <cursor value="none" />
     <szg_viewport_list viewmode="normal">
       <szg_camera>
         <szg_screen usenamed="top_wall" />
       </szg_camera>
     </szg_viewport_list>
   </szg_window>
  </szg_display>
  </value>
  </param>
  <param>
  <name>bottom_window_stereo</name>
  <value>
  <szg_display framelock="wgl">
   <szg_window>
     <decorate value="false" />
     <fullscreen value="true" />
     <stereo value="true" />
     <zorder value="topmost" />
     <cursor value="none" />
     <szg_viewport_list viewmode="normal">
       <szg_camera>
         <szg_screen usenamed="bottom_wall" />
       </szg_camera>
     </szg_viewport_list>
   </szg_window>
  </szg_display>
  </value>
  </param>
  </szg_config>

 

Head-Mounted Displays

Syzygy's first application in Spring 2000 was a cluster-driven HMD, with a seperate consumer PC driving each eye. This configuration is still supported, along with a single PC set up, where two viewports in a single window give left eye and right eye views, respectively. For a head-mounted display, simply change the "headmounted" element value to "true" in the config file in the Easy Demo Passive Stereo Display in Standalone Mode section.

Multiple Displays on a Single Computer

Sometimes having multiple seperate graphics screens on a single computer is desirable. For instance, in this way, you can run Syzygy applications on an SMP computer (like the SGI Onyx series) with mutliple graphics cards. It also helps when testing whether a Syzygy master/slave application will work properly on a cluster, but without having to have a cluster available.

Note that consumer level graphics cards, as a rule, do not do very well having multiple OpenGL windows active simultaneously. Performance degrades significantly over the equivalent Standalone Mode case where there are multiple viewports in a single window. Indeed, on many common systems, just having a inputsimulator window open (which is a small window with very simple OpenGL graphics) in addition to an application window severely degrades application performance. This is actually why Standalone Mode was originally invented: to deal with the limitations of Syzygy application development on very low end hardware.

Of course, these performance conisderations DO NOT apply to the high end computers with multiple graphics cards and processors that are designed to run these types of applications (again like an SGI Onyx or, say, a 4-way Linux box with multiple graphics cards).

The following dbatch file defines a virtual computer "smoke_test" which has four screens and uses a inputsimulator for an input device. These screens give a 2x2 tiled display and are automatically placed in the proper arrangement upon launch, through the SZG_DISPLAY(n)/position parameter. Similarly, the inputsimulator is placed to the right of everything, as given by the SZG_INPUTSIM/position parameter. Please note that the desktop in question is 1600x1200. A smaller desktop would need positions and window sizes reduced.

  <szg_config>
  <assign>
  smoke_test SZG_CONF virtual true
  smoke_test SZG_TRIGGER map smoke
  smoke_test SZG_MASTER map SZG_DISPLAY0
  smoke_test SZG_DISPLAY number_screens 4
  smoke_test SZG_DISPLAY0 map smoke/SZG_DISPLAY1
  smoke_test SZG_DISPLAY1 map smoke/SZG_DISPLAY2
  smoke_test SZG_DISPLAY2 map smoke/SZG_DISPLAY3
  smoke_test SZG_DISPLAY3 map smoke/SZG_DISPLAY4
  smoke_test SZG_INPUT0 map smoke/inputsimulator
  smoke SZG_INPUTSIM position 1305/0
  smoke SZG_DISPLAY1 name single_window_3x2_00
  smoke SZG_DISPLAY2 name single_window_3x2_01
  smoke SZG_DISPLAY3 name single_window_3x2_11
  smoke SZG_DISPLAY4 name single_window_3x2_10
  </assign>
  <param>
  <name>single_window_3x2_00</name>
  <value>
  <szg_display>
   <szg_window>
     <size width="400" height="400" />
     <position x="0" y="400" />
     <decorate value="false" />
     <fullscreen value="false" />
     <cursor value="none" />
     <szg_viewport_list viewmode="normal">
       <szg_camera>
         <szg_screen usenamed="front_tile_3x2_00" />
       </szg_camera>
     </szg_viewport_list>
   </szg_window>
  </szg_display>
  </value>
  </param>
  <param>
  <name> front_tile_3x2_00 </name>
  <value>
  <szg_screen>
    <center x="0" y="5" z="-5" />
    <up x="0" y="1" z="0" />
    <dim width="20" height="10" />
    <normal x="0" y="0" z="-1" />
    <headmounted value="false" />
    <tile tilex="0" numtilesx="3" tiley="0" numtilesy="2" />
    <usefixedhead value="allow" />
    <fixedheadpos x="0.0" y="5.0" z="0.0" />
    <fixedheadupangle value="0.0" />
  </szg_screen>
  </value>
  </param>
  <param>
  <name> front_tile_3x2_10 </name>
  <value>
  <szg_screen>
    <center x="0" y="5" z="-5" />
    <up x="0" y="1" z="0" />
    <dim width="20" height="10" />
    <normal x="0" y="0" z="-1" />
    <headmounted value="false" />
    <tile tilex="1" numtilesx="3" tiley="0" numtilesy="2" />
    <usefixedhead value="allow" />
    <fixedheadpos x="0.0" y="5.0" z="0.0" />
    <fixedheadupangle value="0.0" />
  </szg_screen>
  </value>
  </param>
  <param>
  <name> front_tile_3x2_11 </name>
  <value>
  <szg_screen>
    <center x="0" y="5" z="-5" />
    <up x="0" y="1" z="0" />
    <dim width="20" height="10" />
    <normal x="0" y="0" z="-1" />
    <headmounted value="false" />
    <tile tilex="1" numtilesx="3" tiley="1" numtilesy="2" />
    <usefixedhead value="allow" />
    <fixedheadpos x="0.0" y="5.0" z="0.0" />
    <fixedheadupangle value="0.0" />
  </szg_screen>
  </value>
  </param>
  <param>
  <name> front_tile_3x2_01 </name>
  <value>
  <szg_screen>
    <center x="0" y="5" z="-5" />
    <up x="0" y="1" z="0" />
    <dim width="20" height="10" />
    <normal x="0" y="0" z="-1" />
    <headmounted value="false" />
    <tile tilex="0" numtilesx="3" tiley="1" numtilesy="2" />
    <usefixedhead value="allow" />
    <fixedheadpos x="0.0" y="5.0" z="0.0" />
    <fixedheadupangle value="0.0" />
  </szg_screen>
  </value>
  </param>
  <param>
  <name>single_window_3x2_10</name>
  <value>
  <szg_display>
   <szg_window>
     <size width="400" height="400" />
     <position x="400" y="400" />
     <decorate value="false" />
     <fullscreen value="false" />
     <cursor value="none" />
     <szg_viewport_list viewmode="normal">
       <szg_camera>
         <szg_screen usenamed="front_tile_3x2_10" />
       </szg_camera>
     </szg_viewport_list>
   </szg_window>
  </szg_display>
  </value>
  </param>
  <param>
  <name>single_window_3x2_11</name>
  <value>
  <szg_display>
   <szg_window>
     <size width="400" height="400" />
     <position x="400" y="0" />
     <decorate value="false" />
     <fullscreen value="false" />
     <cursor value="none" />
     <szg_viewport_list viewmode="normal">
       <szg_camera>
         <szg_screen usenamed="front_tile_3x2_11" />
       </szg_camera>
     </szg_viewport_list>
   </szg_window>
  </szg_display>
  </value>
  </param>
  <param>
  <name>single_window_3x2_01</name>
  <value>
  <szg_display>
   <szg_window>
     <size width="400" height="400" />
     <position x="0" y="0" />
     <decorate value="false" />
     <fullscreen value="false" />
     <cursor value="none" />
     <szg_viewport_list viewmode="normal">
       <szg_camera>
         <szg_screen usenamed="front_tile_3x2_01" />
       </szg_camera>
     </szg_viewport_list>
   </szg_window>
  </szg_display>
  </value>
  </param>
  </szg_config>

Resource Path Specification

As part of your System Configuration, you can specify a number of search paths for various kinds of application data. Each path contains semicolon-delimited directory absolute paths. Paths are specified in the normal OS-dependent manner, e.g. 'C:\Data' on Windows and '/home/public/Data' on Linux. (Sadly, Windows build-related paths need forward slashes while resource paths for running programs need backward ones. Not our fault. Sorry.)

IMPORTANT: Syzygy 1.1 changes how applications are searched for and where they may look for their data. Also, szgd now has a 'base paths' argument that limits where programs can be launched from. This argument is a semicolon-delimited list of absolute directory paths; and directory paths listed in SZG_EXEC/path, SZG_PYTHON/executable, SZG_PYTHON/path, and SZG_PYTHON/lib_path must fall inside/below one of the directories listed in the 'base paths' argument. See Creating a Cluster: The Remote Execution Daemon.

  1. Executables:
    SZG_EXEC path directory_path_1;directory_path_2;...
    
    In cluster mode, this tells the remote execution daemon szgd where to look for programs. Before Syzygy 1.1, szgd would only look in directories on the search path, and applications had to look for their data files in directories on the SZG_DATA path, below. Now szgd also looks in the immediate subdirectories of directories on the path. When szgd finds the program, it sets the current directory to the directory containing the program. This lets a program and its data share the same directory, enabling conventional file-reading relative to the program's path.

     

    All directories listed in this path are also added to the Python module import path before a Python program is launched. They are added after any directories specified in the PYTHONPATH environment variable, SZG_PYTHON/path, and SZG_PYTHON/lib_path.

     

    All directory paths listed must be contained within a directory path in szgd's 'base paths' argument, mentioned above.

     

  2. Python executable:
    SZG_PYTHON executable executable_path_1
    
    In cluster mode, this tells the remote execution daemon szgd where to look for the Python executable. It should be the complete path to the executable, but should not include the '.exe' suffix on Windows. If special command line arguments (to the Python executable itself, not the Python program you are running) are required, delimit them with vertical bars: For example, if you were using Movable Python and wanted to pass the '-o' argument, you might set it to the following:
    SZG_PYTHON executable C:\movpy-2.0.0-py2.4.4\movpy\movpy|-o
    
    All directory paths listed must be contained within a directory path in szgd's 'base paths' argument, mentioned above.

     

  3. Python programs:
    SZG_PYTHON path directory_path_1;directory_path_2;...
    
    In cluster mode, this tells the remote execution daemon szgd where to look for Python programs. szgd looks in the immediate subdirectories of directories on the path. When szgd finds the program, it sets the current directory to the directory containing the program. This lets a program and its data share the same directory, enabling conventional file-reading relative to the program's path.

     

    All directories listed in this path are also added to the Python module import path before a Python program is launched. They are added after any directories specified in the PYTHONPATH environment variable, but before directories in SZG_PYTHON/lib_path and SZG_EXEC/path.

     

    All directory paths listed must be contained within a directory path in szgd's 'base paths' argument, mentioned above.

     

  4. Python modules:
    SZG_PYTHON lib_path directory_path_1;directory_path_2;...
    
    In cluster mode, all directories listed in this path are added to the Python module import path before a Python program is launched. They are added after any directories specified in the PYTHONPATH environment variable and in SZG_PYTHON/lib_path, but before directories in SZG_EXEC/path.

     

    All directory paths listed must be contained within a directory path in szgd's 'base paths' argument, mentioned above.

     

  5. Data:
    SZG_DATA path directory_path_1;directory_path_2;...
    
    Data files to be found by programs using the ar_fileFind() function should be placed in a directory on this path. This is no longer necessary, however: See Accessing data in Cluster Mode.

     

  6. Sound files:
      SZG_SOUND path directory_path_1;directory_path_2;...
    
    Location of sound files to be loaded by SoundRender. Note that these can also be placed with the application, but if so it must inform SoundRender using either of the application frameworks' setDataBundlePath() method (see the Programming chapter).

     

  7. Texture maps used in a distributed scene graph program (again, see Programming and to be displayed by szgrender:
      SZG_RENDER texture_path directory_path_1;directory_path_2;...
    

     

  8. Texture-mapped fonts:
      SZG_RENDER text_path directory_1
    
    BUG: This one is not yet semicolon-delimited like the others. It can only be a single directory.