Tying together OpenGL objects and GLSL shaders using traditional code can be tedious and error-prone. Gander makes the process much easier.

Most importantly, Gander features an intuitive XML scene graph that takes care of the low-level details in creating OpenGL scenes, allowing the user to focus on writing the shaders themselves.

In addition, Gander supports several advanced features that can help facilitate more specialized scenes, such as those that need multiple rendering passes for example.

Please take a look at all of the features below. Click on the more link below the feature to see specific details about it.

Basic Tags


Gander includes Cube, Box, Square, Disk, Cone, and Line shapes, all of which use vertex buffers and generic vertex attributes for optimal performance and flexibility.

During preparation of the scene, the shapes automatically query locations of their generic vertex attributes and disable any that won't be used.

Furthermore, static shapes share one vertex buffer between all instances of a class to save memory.



2D and 3D textures can be loaded from files, or a 2D one of a certain size can be created for storage.

Gander uses DevIL to load JPG, PNG, and other image formats, and the paths to the files are considered relative to the XML file no matter where Gander itself is launched from, so working with images is easy.

3D volumetric datasets are also well supported. Gander can read datasets stored in unsigned byte, unsigned short, and float formats, most of which can be normalized or compressed on the fly. There is even a utility to convert datasets and view a histogram of their values.


Shaders and Programs

Multiple shaders can be loaded into a program, all of which are themselves loaded from files. Like with textures, Gander will look for the files relative to the scene file no matter where it is launched from.

To ease splitting files into multiple modules and to encourage code reuse, Gander includes a simple preprocessor that supports the traditional #include, #define, and #ifdef directives.

When an error occurs, Gander reports the file and line number of the problem, even if the shader uses multiple files via the #include directive.


Uniform Variables

Set variables in a shader program that remain the same across an entire shape. Gander will automatically find the location of the variable in the program when the scene is prepared.

Float and Integer types are straightforward, with the user simply specifying a value, while the Vector type will take a value with multiple numbers separated by spaces.

Matrix types are generally used to send the current OpenGL matrices to the shader program and thus take an attribute to specify which one of those you would like to send. In fact, if the shader writer uses a set of default names, the corresponding matrix will be chosen automatically.

Lastly, the Sampler type will automatically find the texture it is linked to in order to determine its value.



Gander includes the traditional Translate, Rotate, and Scale transformations. They can be applied in a hierarchical manner to one or multiple shapes.

Other nodes that perform calculations based on the transformations can be added as observers so that updates are only performed when necessary.


Advanced Tags


To reduce repetition and resources, a group of tags can be defined and then instanced multiple times throughout the file.

Instances are more than simple copies. They save and restore the locations of uniforms and vertex attributes for the shader program the instance is in. That way multiple different shader programs can all contain an instance of the same group without problems, and if the value of a uniform changes it will still be visible in all the instances.


Offscreen Rendering

Gander includes a Framebuffer tag that can be used to render to textures or offscreen renderbuffers.

It supports multiple simultaneous attachments, and fragment shader output variables can easily be bound to the attachments by name. When the scene is ready to


Boolean Operations

Boolean AND and XOR nodes calculate the intersecting or non-intersecting pieces of shapes in a group.

To let the user move the shapes around, and thus change the results of the Boolean operations, an Instance of the group is usually provided. Updates in the operation are only calculated when the user moves one of the shapes, not every time the scene is drawn.

Boolean nodes are particularly useful for volume rendering. Currently we're using BooleanAnd nodes to clip volumes so the user can see into them better. Also we're experimenting with efficiently rendering intersecting volumes by using BooleanXor to render the non-overlapping sections of the volumes independently.



Gander provides a wrapper for the OpenGL blending function to simulate transparency.

Of course, shapes must be drawn from back to front for blending to work correctly, so the Sort node is provided for that reason.



Octree is a 1D integer texture for accelerating access to datasets.


Mouse Controls

Objects can be selected by clicking them, and they can be moved and scaled along each axis using onscreen manipulators.

Information and Editing

Gander shows the contents of the scene in a tree format on the side of the display. Nodes in the tree can be expanded and collapsed as desired, and some nodes, including some Uniforms, can be edited without reloading Gander.