1. Introduction

VglTools Programmer Manual

The VglTools library from Visual Kinematics, Inc. is now part of the Tech Soft 3D portfolio. It is designed to be an object based development toolkit to aid in rendering 3D graphics objects in 2D and 3D graphics display environments. The basic design philosophy is to provide a class library which features an easy to use, flexible and high performance interface to industry standard 2D and 3D graphics application programming interfaces (APIs). For 3D environments, the interface modules optimize for each API environment. For 2D environments, the interface modules perform in software many of the functions which are found on 3D graphics systems and are performed in hardware. These functions include z-buffering, lighting calculations, modelling and viewing transformations, raster font display and color dithering. The basic features of VglTools are summarized below.

  • Software z-buffer which accepts and scan converts filled and stippled polygons, lines of varying width and style, raster text, bitmaps and points of varying size.
  • Modeling, viewing and projection transforms simulate the transformation stack model which is customarily implemented in hardware on 3D graphics machines.
  • Raster fonts provide high quality annotation text. Raster fonts are computationally efficient to generate and display, yielding consistent results across all graphics environments.
  • Texture mapping allows complexity to be added to an image without increasing the polygon count. Texture mapping in VglTools has been implemented with an emphasis on data visualization.
  • Software frame buffer capabilities for all display function primitives generated by scan conversion modules.
  • Display list capability caches graphics primitives and attributes in a hierarchical manner for later traversal
  • Graphics optimization modules provide for the sorting, grouping and software lighting of graphics primitives to increase rendering performance.
  • Interaction modules implement several useful object manipulation functions such as a virtual trackball, windowing, fitting, etc. Included is a special popup menu module which implements a device independent popup menu facility utilizing 3D graphics functions for high performance.
  • Software "data" rendering module provides a unique ability to render arbitrary integer and floating point data to a software frame buffer.
  • Supports reading and writing of 2D image formats such as GIF, Targa, Pict, BMP, Tiff, JPEG, PNG and SGI RGB.
  • Supports writing of 3D object formats such as STL and VRML.
  • Graphics interface modules provided for OpenGL, GDI and X11.
  • Object-based architecture, written in ANSI C with C++ language bindings.
  • Hardware and graphics device independence.

1.1 Module Summary

VglTools is designed to provide a set of modules which perform functions and support entities in software which are normally found implemented in hardware in 3D graphics environments. VglTools is meant to be integrated into existing graphics software systems such as finite element post processors and visual data analysis (VDA) systems with minimal impact upon established data structures and low level graphics subsystems. The modules currently available in VglTools may be divided into 5 categories: 1) raster, 2) transformation 3) user interaction 4) utilities and 5) drawing function.

  • Raster and Scan Conversion
        Bitmap      Define bitmaps, line styles and stipples
        FBuffer     Software frame buffer
        Texture     Texture maps
        Pixelmap    Device dependent frame buffer storage
        RasFont     Raster font operations
        ZBuffer     Z-buffer for hidden line and hidden surface removal
        
  • Transformation
        Xfm         Define transformation matrix
        XfmStack    Model and viewing transformations
        
  • User Interaction
        IActor      Object manipulation
        Popup       Popup menus
        
  • Utilities
        Quadric     Draw quadric surfaces
        
  • Drawing Function
        DataBuf      Data rendering
        DrawFun      Define functions pointers to graphics subsystem
        DFile        Display file
        DList        Display list
        DOpt         Graphics primitive optimization
        DTee         Display tee
        GDIDev       Interface to Microsoft Windows
        OpenGLDev    Interface to SGI OpenGL
        RendBuf      Software rendering
        X11Dev       Interface to X Windows
        
Each of the modules in VglTools either provides a complete 3D interface to a graphics API or a software implementation of a piece of the hardware geometry pipeline of a 3D graphics machine. The algorithms used in VglTools for lighting calculations, modeling and viewing transformations and hidden line hidden surface removal are common to most 3D graphics architectures.

The most straight-forward application of VglTools involves the use of the graphics interface modules. Each module provides a uniform interface to a common 2D or 3D graphics API environment such as GL, OpenGL, X11, etc. For 3D APIs such as OpenGL, the interface modules are optimized to allow the API to maximize graphics hardware utilization. For 2D APIs such as X windows, operations such as z-buffering, transformation, lighting and color dithering are done in software using other VglTools modules.

Software scan conversion of points, lines, polygons and raster text occurs using the ZBuffer module. Polygon fill patterns and raster text may be defined using the Bitmap and RasFont modules respectively. The objects instanced from these modules are given to a ZBuffer object as attribute objects to control polygon filling and raster text generation.

1.2 Compiling and Linking a VglTools Application

To use VglTools on a particular computer platform, the VglTools source must be compiled and linked to an application. Either the object files may be used directly or they may be installed in an object library archive so that the loader may selectively relocate only the objects which are required. VglTools is written in ANSI C. It is suggested to use the highest level of serial optimization options available on the C compiler.

In addition to the overall C preprocessor definitions described in section DevTools, Compiling and Linking a DevTools Application, there are four categories of C preprocessor definitions which are used to conditionally compile source code. The first category is the window system. Possible window system APIs are the following,

    VKI_WIND_WIN32      Microsoft Windows
    VKI_WIND_X11        X windows
    VKI_WIND_MESA       Mesa windowless
    
The Mesa 3D graphics library may accessed at the following URL
    http://www.mesa3d.org
    

The second category is the 3D graphics device interface API. The architectures for which the graphics device interfaces are allowed appear in parentheses.

    VKI_3DAPI_OPENGL    OpenGL (Any architecture)
    
The official support level of OpenGL on Windows is OpenGL 1.1. In order to use the vertex buffer objects, vertex array features and shader features of OpenGL in Windows it is recommended using GLEW, the OpenGL Extension Wrangler Library to enable more current versions of OpenGL. To compile support for this library define VKI_LIBAPI_GLEW

    VKI_LIBAPI_GLEW    OpenGL Extension Wrangler Library (Microsoft Windows)
    
This library may accessed at the following URL
    http://www.glew.sourceforge.net
    

The third category is publicly available external library support for image file format reading and writing and font rendering. In some cases there are two options. The user may conditionally compile source to reference a user supplied installation of the external library or conditionally compile source to reference a modified version of the publicly available source which is delivered in the vgl/ext directory.

    VKI_LIBAPI_JPEG      JPEG user installed external library
    VKI_LIBAPI_PNG       PNG user installed external library
    VKI_LIBAPI_TIFF      TIFF user installed external library
    VKI_LIBAPI_FFMPEG    FFMPEG user installed external library
    VKI_LIBAPI_FREETYPE  FreeType user installed external library
    
    VKI_EXTAPI_JPEG      JPEG vgl/ext/jpeg source
    VKI_EXTAPI_PNG       PNG vgl/ext/png source
    VKI_EXTAPI_TIFF      TIFF vgl/ext/tiff source
    
The FFmpeg library may accessed at the following URL
    http://www.ffmpeg.org
    

The FreeType library may accessed at the following URL

    http://www.freetype.org
    

The fourth category is used to configure the text drawing features of VglTools for single byte or double byte (wide) characters. The affected text drawing functions use a type of Vtchar for all string arguments which are configurable in this way.

    VKI_WIDECHAR        Vtchar double byte
    
If VKI_WIDECHAR is not defined, Vtchar is typedef'ed as char. If VKI_WIDECHAR is defined, Vtchar is typedef'ed as wchar_t. All Text and TextDC drawing functions contain Vtchar string arguments. In addition, all functions in the RasFont object which draw or manipulate text strings contain Vtchar string arguments. On Microsoft Windows platforms, it is required that the user define UNICODE if VKI_WIDECHAR is defined when compiling all application code.

To use VglTools on a particular computer platform, the VglTools source must be compiled and linked to an application. Either the object files may be used

As an example of compiling VglTools on a SGI system create a directory SGI under lib to hold the final devtools.a archive file. Assume that X11 window system and OpenGL 3D graphics interfaces are desired. Then from the devtools/src/vgl directory compile using

    cc -c -O2 -ansi -DVKI_ARCH_SGI -DVKI_WIND_X11 -DVKI_3DAPI_OPENGL \\
          -I.. *.c
    
creating .o files in the vgl directory. To place the object files in an archive file issue

    ar rs ../../lib/SGI/devtools.a *.o
    
The object files may be deleted after the devtools.a archive is successfully created. Place the devtools.a archive immediately before the display subsystem libraries in the load line. A devtools.a archive must be built for each computer platform using the methodology outlined above.

On Microsoft Windows platforms, if the OpenGL device interface is used, the final executable should be linked with the library opengl32.lib. The library vfw32.lib must be included to satisfy references to the audio visual interface (AVI) system.

1.3 Using Drawing Function Modules

VglTools provides an object oriented graphics device interface capability. The modules which implement this graphics functionality are DrawFun, DList, DFile, DOpt, DTee, DataBuf, GDIDev, OpenGLDev, RendBuf, SVGDev and X11Dev. The key module is the drawing function module, DrawFun. This module contains nearly 100 function pointers which together define the graphics functionality of VglTools. The functions fall into the following categories.
  • Window operations
        
  • Frame buffer control
        
  • Query
        
  • Pixel level operations
        
  • Lighting
        
  • Projection and viewport transformations
        
  • Modelling and viewing transformations
        
  • Graphics attributes
        
  • Graphics primitives
        
  • Graphics input
        
The DrawFun module provides an abstract drawing function capability. Each of the other graphics modules implements a particular variety of drawing function. Each module contains a method expressly for the purpose of loading a drawing function object with its unique variety of function pointers. For example, the OpenGLDev module implements drawing functions which render to any system supporting OpenGL, X11Dev renders to any X window. The DList module caches graphics primitives, etc. in a display list for later traversal. The DFile module reads and writes graphics primitives to industry standard 3D object file formats such as OpenInventor. The DTee module accepts graphics primitives as input and calls two drawing function objects as output, acting as a "tee". The DataBuf module renders "data" to a software frame buffer for later query.

Some modules are drawing function filters and other are renderers. The filter modules such as DList and DOpt accept drawing functions as input, perform some operation on the drawing function data and invoke drawing functions as output. The render modules act as a terminal point for drawing function data, accepting drawing functions as input and rendering to a hardware or software frame buffer as output. In this way a user can form a pipeline of drawing function objects to implement "immediate" mode rendering directly to a graphics device interface object or "retained" mode rendering through a drawing function object containing display list functions.

1.3.1 Graphics Device Interface Modules

The device interface modules provide a drawing function interface to common 2D and 3D graphics API environments such as GL, OpenGl and X11. Each module is designed to provide a consistently high level of 3D graphics functionality including zbuffering, transformation, Gouraud shading and double buffering. The device interface modules can be divided into two categories, 1) 3D APIs which maximize graphics hardware utilization and 2) 2D APIs which use other VglTools modules to perform zbuffering, 3D transformation, Gouraud shading, etc. in software. The modules fall into these two classes as follows, While the 3D API modules yield high performance and functionality when the underlying graphics device provides zbuffering, double buffering and Gouraud shading in hardware, there is little or no software backup when a critical function is not available on a device. Fortunately most 3D graphics workstations are designed with a balanced functionality. That is, if Gouraud shading is provided, so also is zbuffering, double buffering and 3D transformation pipelines. In a X windows terminology, this means that if a "TrueColor" or "DirectColor" RGB visual is available on a display, then use the appropriate 3D device interface module, otherwise use a 2D device interface module such as X11Dev.

Currently, VglTools supports the graphics device interface modules in an X windows or Microsoft Windows environment. The user is responsible for opening the X window display and selecting a screen. Each graphics interface module which ultimately draws to an X window must be informed of the appropriate X window display and screen. When a user closes the X window display he should notify any graphics interface modules first so that they may release memory resources, etc. properly.

1.4 Graphics Device Testing and Performance

Two source files are provided to enable the user to perform finction testing and gather performance statistics for VglTools for various graphics devices. The ousrce files are located in the test subdiretory under the vgl source directory. The function testing source is in file vgltest.c and the performance gathering source is in file vglperf.c. The executables, vgltest.x and vglperf.x may be made from the vgl/test directory using:

    make vgltest
    make vglperf
    
Complete HTML based guides to running vgltest.x and vglperf.x are located in the vgl/test/html directory. Use the root HTML files vgltest.htm and vglperf.htm with a Web browser.


1.5 A First Program

As an example of a simple VglTools application the following program illustrates drawing the now classic "Hello World" to either an X window or a Microsoft window using OpenGL. All VglTools programs require the header files appearing in the program. They contain C preprocessor macros and object definitions. It may be instructive to look at the contents of these files. For X Windows The user must open the X window display and select a screen. The class function vgl_OpenGLDevConnectX is used to inform the OpenGLDev module of the display and screen information. For Microsoft Windows the class function vgl_OpenGLDevConnectWIN is used to connect to the window system. A drawing function object, df, and OpenGL device object, ogldev, are instanced. The drawing function object, df is loaded with function pointers by vgl_OpenGLDevDrawFun. At this point all further drawing and control of the window are handled through the drawing function object, df. A window position attribute is specified and the window is opened. By default the window is double buffered and uses a true color visual if available on the underlying hardware. The frame buffer is cleared, the string "Hello World" is drawn in white and the buffers are swapped to display the image. The system waits 10 seconds and then terminates. Proper termination involves reversing the initialization process. The window is closed, instanced objects are freed, the OpenGLDev module is disconnected from the window system and, for X Windows, the X display is closed. The source to this example resides in file intro1.c in the exam directory. A C++ version is in file intro1cc.cxx.

    #include "base/base.h"
    #include "vgl/vgl.h"
    
    /*----------------------------------------------------------------------
                          Hello World
    ----------------------------------------------------------------------*/
    int
    main()
    {
    #ifdef VKI_WIND_X11
       Display *display;
       int screen;
    #endif
    
       Vfloat x[3], c[3];
    
       vgl_OpenGLDev *ogldev;
       vgl_DrawFun *df;
    
                       /* connect to window system */
    #ifdef VKI_WIND_X11
       display = XOpenDisplay (0);
       screen = DefaultScreen (display);
       vgl_OpenGLDevConnectX (display,screen);
    #endif
    #ifdef VKI_WIND_WIN32
       vgl_OpenGLDevConnectWIN ();
    #endif
    
                       /* create drawing functions */
       df = vgl_DrawFunBegin();
    
                       /* create device objects and load drawing functions */
       ogldev = vgl_OpenGLDevBegin();
       vgl_OpenGLDevDrawFun (ogldev,df);
    
                       /* open windows */
       vgl_DrawFunPositionWindow (df,400,400,400,300);
       vgl_DrawFunOpenWindow (df,"OpenGL window");
    
                       /* draw hello world in raster font */ 
       vgl_DrawFunClear (df);
       c[0] = 1.; c[1] = 1.; c[2] = 1.;
       vgl_DrawFunColor (df,c);
       x[0] = 0.; x[1] = 0.; x[2] = 0.;
       vgl_DrawFunText (df,x,"Hello World");
       vgl_DrawFunSwap (df);
    
                       /* wait */
       vgl_DrawFunDelay (df,5.);
    
                       /* close windows */ 
       vgl_DrawFunCloseWindow (df);
    
                       /* free objects */ 
       vgl_OpenGLDevEnd (ogldev);
       vgl_DrawFunEnd (df);
    
                       /* disconnect from window system */
       vgl_OpenGLDevDisconnect ();
    
                       /* close X display */
    #ifdef VKI_WIND_X11
       XCloseDisplay (display);
    #endif
       return 0;
    }
    

Figure 1-1, Output from First Program

1.6 Drawing to an X11 Device

This example illustrates how one uses a graphics interface device module, in this case X11Dev, to draw to an X window. In an X windows environment, the display must be opened and managed by the user. Use vgl_X11DevConnectXServer to inform the X11Dev module of the display information. Note that this function is a "class" method. All X11Dev windows will use this display and screen. A drawing function object, DrawFun and device object, X11Dev are created. In general a drawing function object is created for each device object. The drawing functions for the X11Dev object are loaded using vgl_X11DevDrawFun. At this point all further drawing or control functions to the window are handled by the drawing function object.

A window is sized and opened and zbuffering is enabled. All colors are specified using red, green and blue color components. The window is cleared, and a white raster text title, a transparent white triangle, a double width magenta line and yellow raster text are drawn. The white triangle appears somewhat gray because of the 50 percent transparency against a black background. The function vgl_DrawFunSwap is used to ensure that all graphics primitives have been rendered to the window.

To terminate the graphics application, reverse the initialization procedure. The window is closed, objects deleted, the X11Dev module is disconnected from the X windows display and the X windows display is closed. The output from this example is shown in Figure 1-2 rendered on a grayscale PostScript device. The source to this example resides in file intro2.c in the exam directory. A C++ version is in file intro2cc.cxx.

    #include "base/base.h"
    #include "vgl/vgl.h"
    
    static Vfloat xtri[3][3] = {
       {0.,.5,0.}, {.5,-.5,0.}, {-.5,-.5,0.} };
    static Vfloat xlin[2][3] = {
       {-.7,0.,.1}, {.7,0.,.1 }};
    static Vfloat xtex[3] = {
       -.9,-.6,.1 };
    
    /*----------------------------------------------------------------------
                          Draw to an X11 Device
    ----------------------------------------------------------------------*/
    int
    main()
    {
       Display *display;
       int screen;
    
       vgl_X11Dev  *x11dev;
       vgl_DrawFun *df;
       Vfloat x[3], c[3];
    
                       /* open X display */ 
       display = XOpenDisplay (0);
       screen = DefaultScreen (display);
    
                       /* inform X device of display information */ 
       vgl_X11DevConnectX (display,screen);
    
                       /* create drawing function */
       df = vgl_DrawFunBegin();
    
                       /* create X window device object */ 
       x11dev = vgl_X11DevBegin();
    
                       /* load drawing functions for X device */ 
       vgl_X11DevDrawFun (x11dev,df);
    
                       /* request size and open window */ 
       vgl_DrawFunPositionWindow (df,100,100,500,400);
       vgl_DrawFunOpenWindow (df,"X11 Device");
    
                       /* turn on zbuffering */ 
       vgl_DrawFunSetMode (df,VGL_ZBUFFERMODE,VGL_OFF);
    
                       /* clear window and draw text */ 
       vgl_DrawFunClear (df);
       c[0] = 1.; c[1] = 1.; c[2] = 1.;
       vgl_DrawFunColor (df,c);
       x[0] = -.9; x[1] = .9; x[2] = 0.;
       vgl_DrawFunText (df,x,"Transparent triangle, wide line and raster text");
    
                       /* transparent triangle */
       vgl_DrawFunTrans (df,.5);
       c[0] = 1.; c[1] = 1.; c[2] = 1.;
       vgl_DrawFunColor (df,c);
       vgl_DrawFunPolygon (df,VGL_POLYGON,3,xtri,VGL_NOSHADE,NULL);
    
                       /* wide line */ 
       c[0] = 0.; c[1] = 1.; c[2] = 1.;
       vgl_DrawFunLineWidth (df,2);
       vgl_DrawFunColor (df,c);
       vgl_DrawFunPolyLine (df,VGL_LINESTRIP,2,xlin);
    
                       /* text strings */ 
       c[0] = 1.; c[1] = 1.; c[2] = 0.;
       vgl_DrawFunColor (df,c);
       vgl_DrawFunText (df,xtex,"!#$%&''()*+,-./0123456789:;<=>?@");
       xtex[1] -= .15;
       vgl_DrawFunText (df,xtex,"ABCDEFGHIJKLMNOPQRSTUVWXYZ[[]^_`");
       xtex[1] -= .15;
       vgl_DrawFunText (df,xtex,"abcdefghijklmnopqrstuvwxyz{|}~");
    
                       /* make sure window is current */ 
       vgl_DrawFunSwap (df);
    
                       /* wait a bit */ 
       vgl_DrawFunDelay (df,10.);
    
                       /* close window */
       vgl_DrawFunCloseWindow (df);
    
                       /* delete objects */ 
       vgl_X11DevEnd (x11dev);
       vgl_DrawFunEnd (df);
    
                       /* disconnect from X */ 
       vgl_X11DevDisconnect ();
    
                       /* close X display */ 
       XCloseDisplay (display);
       return 0;
    }
    

Figure 1-2, Output from Drawing to an X11 Device