Next: Molecule objects
Up: Function and Class
Previous: Utility objects
The following objects are used mainly for the purpose of displaying images
to the screen. Items which have a specific section listed for them are
explained in detail in that section.
Table 6.2: VMD
display objects.

Contains a list of all the items which have an assigned color,
and the list of all the different color categories which exist. VMD
uses a colormap made of 16 base colors (plus black), and a colorscale made of 32 colors in user-definable gradient (e.g., red-green-blue, or red-white-blue). Color categories are used to contain the names of items which are related and which may have their colors changed; an example of a color category is `Axes', which contains the colors for the `X', `Y', and `Z' axes. The categories contain just a list of names and the associated colors assigned to these names (an integer, from 0 ... 16). Other objects in VMD
which are derived from ColorUser
can add new color categories (or can query if one of a specific name already exists), and can add new names to an existing color category. The colors assigned to the named items in each category can be changed via the Color menu, or through the color text command. Once a category is created by some ColorUser
object (or, if it already exists, has been obtained by the object from ColorList
), the ColorUser
can use the category to retrieve the proper color to use for whatever purpose it needs it (i.e., creating the object's display list if it is a Displayable
).
There are three different ways to set the colorscale:
- RGB: red -- green -- blue.
- RWB: red -- white -- blue.
- BLK_W: dark grey -- light grey.
There are sixteen colors in the colormap, along with black, for seventeen total colors. They are: blue, red, grey, orange, yellow, tan, silver, green, white pink, cyan, purple, lime, mauve, ochre, iceblue, and black.
- NameList<int> colorNames -- a list of all the different colors, and their corresponding colormap index.
- float colorData[MAXCOLORS][COLOR_ITEMS] -- the data which define each color, including all the colormap colors and the colorscale colors.
- NameList<NameListIntPtr> categories -- a list of all the color categories. Each category has a name, and an associated list of named items (so, first the right category is found by looking up a name in categories, and then the right color is found by looking up a name in the list associated with the given category name).
VMD
contains one global instance of this class, colors. It is used by all objects derived from ColorUser
, which includes all Displayable
objects as well as DisplayDevice
. An object which wishes to allow the user to be able to change its colors goes through these steps:
- call ColorList::_color_category(char *)
; this adds a new category with the given name and returns a unique index for that category, or else returns the index of the category if it already exists. This index should be saved for later use.
- once a category exists, names should be added to the category that correspond to all the components that can be configured, with default colors. This is done by doing the following:
(colors->color_category(catIndex))->add_name("item name", defaultColor)
- When the colors have been added, they may be retrieved later when creating a display list by doing the following:
(colors->color_category(catIndex))->data("item name")
This will return the index of the color assigned to the given item name.

Simple base class for objects which will be needing to use a ColorList
for colors. This class provides routines for being given a ColorList
object, and for being informed of when colors are changed. The user
can create new categories of colors in the ColorList, and add specific
color objects to the category with an identifying name. The user can
edit these colors via commands.
- ColorList *colorList -- a pointer to a ColorList object for this object to use. The ColorList
is the object which keeps the global lists of color categories.
- virtual void use_colors(ColorList *) -- this function is used to set up this object to use the specified ColorList
to store and retrieve data. By default, it will save the pointer and then call do_use_colors.
- virtual void color_changed(ColorList *collist, int c) -- after a color has been changed via the GUI or a text command, the ColorUser
must be notified of the change so that it can update any internal state. This routine is called when color c in the specified ColorList
is changed. By default, this just calls the virtual function do_color_changed.
- virtual void do_use_colors(void) -- this is called after a new ColorList
object is provided. It is a protected function, and by default does nothing. It should only be defined if the derived class needs to do something special when a new ColorList
is given, such as create a new color category.
- virtual void do_color_changed(ColorList *collist, int c) -- this is called after a color in the given category is changed. It is a protected function, and by default does nothing. It should only be defined if the derived class needs to do something special when a color is changed, such as rebuild a display list or recalculate some data.
ColorUser
is a base class designed to be specified as a parent for some class which desires to use a ColorList
to maintain categories of colors associated with names, and to make these names be customizeable to the user via the VMD
user interfaces. All Displayable
objects are derived from ColorUser
, as are all DisplayDevice
objects.
ColorList
describes how to create new categories and how to access them. If a new class wishes to use these features, it should derive from ColorUser
, and define versions of the protected virtual functions do_use_colors and do_color_changed. This first is designed to be only called once, right after the object is created -- it should create new categories, and add the necessary names to these categories. The second is designed to be called every time a particular color changes. The do_color_changed should check to see which color was modified, and then update itself if necessary.

DispCmd
is a base class for a large number of objects which are used to create the display lists in Displayable
objects. Each subclass represents a particular drawing primitive, such as plotting a line, changing the current color, or applying a rotation. These objects take the data required for the particular primitive they represent (for example, the endpoints of a line, or the index of a color) and append this data to the end of the display list for a given Displayable
. Routines are available to permit a DispCmd
to be used more than once, and also to have the DispCmd
remember the location where the data was most recently appended so that new data may be copied over existing data in a display list.
- DispCmd::(int code, int size)
code is a special index used to distinguish what type of DispCmd
this is; it is supplied by the derived class, and should be one of the enumeration values listed at the top of the file DispCmds.h.
size is the number of bytes that the data will occupy when placed into the display list; it is also supplied by the derived class. It can be zero.
At the beginning of DispCmds.h is an enumeration with entries for all the different DispCmd
-derived classes. These names are used by the render routine in each DisplayDevice
to determine what the commands are in a display list. When new drawing primitives are added, a new name should be put in this list, and that name should be specified in the DispCmd
base class constructor.
Following this are enumerations describing the different types of spheres that may be drawn, and the different types of lines.
- int cmdCode -- the unique integer ID of the command; this is one of the names in the main enumeration described above.
- int cmdSize -- the number of bytes which the data will occupy when copied into a given display list.
- void *Data -- a block of cmdSize bytes which stores the data to be copied into a given display list.
- void *dataLoc -- a pointer to the last place into which the bytes in Data were copied. If it is NULL, the data has not yet been copied. This is stored so that the reput command can copy new data over previously-stored data, instead of just appending the data to the end of a display list.
- void put(Displayable *dobj) -- This is the main function in each DispCmd
object. It copies the values stored in Data to the end of the specified Displayable
object's display list. As well, the integer code indicating which primitive this is is copied into the list, and also the size of the data (in bytes). The order of copying data is as follows:
- cmdCode (one integer)
- cmdSize (one integer)
- Data ( cmdSize bytes)
- reput(Displayable *dobj) -- Same as put, except that if the same DispCmd
has had the put routine called, this command will copy the data into the same location as was used previously. This can be used to copy data over previously-copied data. A particular example is in Displayable
, which uses reput to replace the matrix data in the multiply-transformation-matrix command used at the beginning of each Displayable
's display list. If put has NOT been called prior to calling reput, then reput does exactly the same thing as put.
Each class derived from DispCmd
should have two constructors:
- A default constructor, with no arguments - this will just initialize all the internal storage to default values.
- A data constructor, which takes arguments with the data necessary for the command. This will copy the arguments into the internal data storage of the object.
If a derived class does not require any arguments (for example, the PUSH command, which just signals to push the top transformation matrix, but does not require any data itself), only the default constructor is used. Otherwise, each derived class should also provide two new functions;
- void putdata( args, Displayable *dobj) -- This should copy the data specifed in args, and then call put(dobj). This is used when an instance of this class is created with a default constructor, and the instance is to be used more than once. Each time the instance it used, putdata is called to append new data to the end of dobj's display list.
- void reputdata( args, Displayable *dobj) -- Same as putdata, but it should call reput after copying the given data instead of put.
Within the put and reput functions, DispCmd
uses several routines in Displayable
to start the action of writing a new command to the end of the display list, to copy over the data itself, and to signal the data is copied.
At present, most Displayable
objects contain instances of these commands as private members, which are used to create their internal display lists. This is not really necessary, it would probably be better if there were one global instance of each different DispCmd
, available for use by the Displayable
objects. This would decrease the memory used, and the time for construction of the Displayable
using the global instances instead of a local copy.

DisplayDevice
is one of the main classes in VMD
. It is a base class for all the objects which are responsible for drawing the current scene, either to an on-screen graphics window, or to a file. It is also responsible for encapsulating the window-manager-specific routines which are different for each type of windowing environment (e.g., GL-based window management and rendering, or X-Windows-based window management and OpenGL rendering, etc.). Finally, it is used to determine which item a pointer is currently selecting when a pointer button is pressed, either by a 2D mouse or by a 3D pointer. There are a large number of virtual functions which each subclass may define (if relevant). The DisplayDevice
base class provides default versions for all the virtual functions, however, so that by default a bare DisplayDevice
acts as an ``empty'' device, which essentially does nothing but which still functions to the rest of the program as a working DisplayDevice
.
The main DisplayDevice
instance used by VMD
is also responsible for checking for and reporting window events, such as when the window is resized, or when a mouse button is pressed, etc. The main graphics window has one main popup menu (which could be implemented as a pulldown menu if required), which the DisplayDevice
must be able to create and acquire events from.
There are two types of subclasses of DisplayDevice
used in VMD
:
- On-screen rendering devices, which manage a graphics display window on the workstation monitor, and which define new versions for basically all virtual functions in DisplayDevice
.
- Image-file rendering devices, which are used to render the current scene to an image file, or to create an input script for some post-rendering processor (such as a ray-tracing program or the Raster3D application). These subclasses are designed to be used to create a new file each time the render routine is called. Since file-rendering DisplayDevice
's do not have to manage a window, deal with picking objects with a pointer, etc., they are much simpler and do not define new version of many of the virtual functions. For file rendering devices, many of the internal variables, enumerations, and functions are irrelevant and may be ignored when new file rendering subclasses are written.
- DisplayEye lists the different locations for the viewers eye: NOSTEREO if the display is not in stereo, LEFTEYE or RIGHTEYE if the view from either eye is being used.
- Buttons lists the different input buttons which are assumed to be available. B_LEFT, B_MIDDLE, and B_RIGHT are for the three buttons on a mouse, while B_F1 through B_F12 are for 12 function keys, and B_ESC is for the `esc' key of the keyboard.
- EventCodes lists the different types of window events which are assume to be possible. These are all prefixed with `WIN_', and include redraw, mouse and keyboard button events, as well as events for when mouse focus changes or the window is exposed.
- int colorCat -- the index of the color category which holds the `Background' color item. DisplayDevice
is derived from ColorUser
, and creates a new category `Display' which holds the names used for coloring items in DisplayDevice
. The background color is accessed through this category, when the display is cleared.
- long xOrig, yOrig, xSize, ySize -- the position of the lower-left corner of the graphics window, and the size of the window, in pixels.
- float backColor[3] -- the color of the background, as should be used the next time the display is cleared. When the background color is changed via user commands, the virtual function do_color_changed gets called and the value of backColor gets updated.
- int Dim -- the current dimension of the display, 2 or 3. Note that presently 2D drawing still needs work.
- Stack<Matrix4> transMat -- the transformation matrix stack for this display. The top matrix is the matrix used to transform `world' coordinates to pre-projection coordinates. It can be pushed and popped with the push() and pop() virtual routines in DisplayDevice
. Some devices may wish to use some other matrix stack, for example the GL matrix stack.
- int lineStyle, lineWidth, sphereRes, sphereMode -- the current settings for these drawing characteristics. They may be modified through DisplayDevice
calls, but are most often changed via drawing command in a display list created by a Displayable
.
- float eyePos[3], nearClip, farClip, vSize, zDist, Aspect, cpUp, cpDown, cpLeft, cpRight -- these describe the current viewing geometry, by specifying where the viewer's eye is located, how far from the eye to the near and far clipping planes, and how large the screen is vertically and how far it is from the origin. When these values have been given, the routine calc_frustrum() is used to calculate the current aspect ratio, and the location of the corners of the viewing frustrum (the pyramid-shaped view formed from the eye (located at the tip of the pyramid) to the screen (located at the base of the pyramid).
- int inStereo, stereoModes -- the current stereo mode; 0 always means the display is not in stereo, while values greater than 0 indicate one of the display's available mode. stereoModes indicates how many different modes are available. Each DisplayDevice
must set this to indicate if it has stereo capabilities.
- char **stereoNames -- a pointer to an array of names used to indicate the different stereo modes available. There should be stereoModes number of names in this list. Note that `stereo off' counts as one mode, and is the default. So, if a new DisplayDevice
cannot display stereo, it should not change this variable, or stereoModes.
- float eyeSep, eyeDist, eyeDir[3], upDir[3], eyeSepDir[3] -- these describe the current stereo viewing geometry. Along with the eye position, these define vectors describing where the eye is looking, where the `up' direction is, and a vector along the line formed between the two eyes. These also describe how far apart the eyes are, and how far from the current eye position to the viewing focal point.
- int lightDefined[], lightOn[] -- flags indicating whether data for the light sources has been provided (via a drawing command), and whether the light sources are currently on or off.
- float lightColor[][3], lightPos[][3] -- the RGB color, and XYZ position, of each light source.
- int matDefined[], materialsActive, materialOn -- flags indicating whether data for material characteristics has been provided (via a drawing command), whether material characteristics should be used or not when drawing polygons, and the current material index that should be used to draw the next polygon (if materialsActive is true).
- float matData[][] -- the color, emissitivity, specularity, transparency, etc. of each material that has been defined.
- pickRegion -- how large an area to use as the search region when a pointer is attempting to select an item. When picking items, the graphics window is assumed to be in `relative scaled coordinates', that is, it is assumed to have coordinates 0 ... 1 in both the X and Y directions, with the origin in the lower left corner. Having a pickRegion == 1.0 means the entire screen. A typical value for this is 0.01.
- virtual void queue_events(void) -- Indicate to the event manager that windowing and mouse movement events need to be reported. The actual commands executed through this function will be different based on the window manager used, and the GUI library being used (basically, it depends on who is handling events, which is different when just using straight GL, when using the FORMS library, when using Tk, when using just Xlib, when using ... ack).
- virtual int test_events(void) -- Check and see if there is an event pending, but do not get the event yet.
- virtual int read_event(long &, long &) -- Check for an event; return true if one was found, and return the code and value for the event in the arguments.
- virtual int x() -- The current X position of the mouse, measured in pixels from the lower-left corner of the screen.
- virtual int y() -- The current Y position of the mouse, measured in pixels from the lower-left corner of the screen.
- virtual int button_down(int) -- Check if the specified button is currently being pressed.
- virtual int menu_create(PopupMenu *) -- Given a pointer to a PopupMenu
instance, this creates the popup menu to be used when a request is made to make a selection from the menu. The popup menu contains selections, separators, and submenus.
- virtual int menu_activate(void) -- After the popup menu is created, this routine will activate that menu and return the special selection code for the item selected, or -1 if nothing is selected.
- virtual void set_stereo_mode(int = 0) -- Changes to a new stereo mode.
- virtual void abs_screen_loc_3D(float *, long *) -- Given a point in 3D `world' coordinates (the first arg), this routine converts the point to absolute 2D `screen' coordinates, i.e. the location measured in pixels from the lower-left corner of the screen.
- virtual void rel_screen_loc_3D(float *, float *) -- Given a point in 3D `world' coordinates (the first arg), this routine converts the point to `relative, scaled' 2D coordinates, which are 0 ... 1 inside the graphics display window in each X, Y dimension, and undefined outside this region.
- virtual void find_3D_from_2D(float *A, float *B, float *C) -- Given a point A, and a 2D relative screen position point B, this computes the 3D point corresponding to the position of the 2D point. Since the 2D point is not sufficient to determine the 3D position in space for that point, the point A is given to serve as a `reference' point. Currently, the algorithm only supports the simple case where the eye is looking directly along the Z axis.
- virtual void push() -- pushes the top matrix on the transformation matrix stack; the top matrix is unchanged, but is saved one level down on the stack.
- virtual void pop() -- pops the matrix stack, restoring a previously pushed matrix state.
- virtual void loadmatrix(Matrix4 &) -- copies the given 4 x 4 matrix into the top matrix on the stack, destroying the previous matrix value there.
- virtual void multmatrix(Matrix4 &) -- premultiplies the top matrix on the stack by the given 4 x 4 matrix.
- virtual void prepare2D(int = true) -- get the display ready to draw 2D objects, by setting the proper projection matrices and viewport. The argument indicates whether to clear the screen.
- virtual void prepare3D(int = true) -- get the display ready to draw 3D objects, by setting the proper projection matrices and viewport. The argument indicates whether to clear the screen.
- virtual void clear(void) -- erase the current display window, setting the background to the proper color.
- virtual void left(void) -- prepare to draw the left eye image when in stereo. Note that when drawing in stereo, the left eye should always be drawn first.
- virtual void right(voivd) -- prepare to draw the right eye image when in stereo. Note that when drawing in stereo, the right eye should always be drawn last.
- virtual void normal(void) -- prepare to draw a non-stereo image.
- virtual void update(int = true) -- after drawing is complete, this routine `cleans up', by doing any actions which only need to be done once at the end of drawing (for example, swapping buffers which drawing using double buffers). The argument indicates whether to actually perform a buffer swap.
- virtual void reshape(void) -- refresh the display after it has been reshaped or exposed.
- virtual void render(void *) -- the most important routine in DisplayDevice
: this routine takes the given display list (created by some Displayable
, and goes through the list executing the drawing commands as they are listed. Each DisplayDevice
subclass must provide a version of render, to do the actions required to draw a scene.
- virtual int pick(int, float *, void *, float &) -- pick objects based on given list of draw commands, and determine which (if any) item in the list of drawing command was under the given pointer position. The arguments are the dimension of picking (2 or 3), the position of the pointer, draw command list, and returned distance from object to eye position (this last argument is set to the distance from the object to the current eye position, which can be used to determine which item is closest when multiple objects are under the pointer). This function returns the ID code ('tag') for the item closest to the pointer, or (-1) if nothing was picked. If an object is picked, the eye distance argument is set to the distance from the display's eye position to the object (after its position has been found from the transformation matrix). If the value of the argument when pick is called is negative or zero, a pick will be generated if any item is near the pointer. If the value of the argument is positive, a pick will be generated only if an item is closer to the eye position than the value of the
argument. For 2D picking, the pointer coordinates are the relative position in the window from the lower-left corner (both in the range 0 ... 1). For 3D picking, the pointer coordinates are the world coordinates of the pointer. They are the coordinates of the pointer after its transformation matrix has been applied, and these coordinates are compared to the coordinates of the objects when their transformation matrices are applied.
Once a DisplayDevice
has been defined, and an instance created, a simple sequence of routines are used to have the device render a scene. This sequence is implemented by the Scene::(DisplayDevice *display)
routine. A Scene
object maintains a list of display lists and Displayable
objects which create those lists (see section 6.3.7). The draw routine uses the DisplayDevice
as follows:
- display->prepare3D()
- Set the stereo mode to the left eye, or just normal, using the command display->left() or display->normal()
- For each Displayable
in the Scene
, the prepare routine is called to make that object ready to be drawn.
- For each display list maintained by the Scene
, the command display->render(displist) is called.
- If the display is in stereo, display->right() is called and the previous step repeated.
- display->update()
Drawing to a file instead of the screen is almost identical, with the following exceptions:
- At present, only non-stereo file rendering is supported.
- The routine Scene::(char *method, char *filename, DisplayDevice *display)
is used instead of draw, since a specific filetype and filename must also be given.
Currently, VMD
uses the GL library (through a GLDisplayDevice
). To make VMD
portable to a much larger number of platforms, a DisplayDevice
using OpenGL and Xlib should be written, which will use the XFORMS library for the GUI.
Another suggestion is to change the current VMD
style of constantly redrawing the screen to a style where the screen is only redrawn under any of these conditions:
- The window is reshaped or exposed;
- Any Displayable
object indicates (during the call to prepare) that it requires a redraw (i.e. when animating a molecule, or rotating an object).
- A specific request is made for a redraw.

The Displayable
base class is the parent class for all items which need
to be drawn to a DisplayDevice
. For example, the set of axes which
appear in the corner of the VMD
display screen are maintained as a
Displayable
, and each Molecule
is one as well. The Scene
(section 6.3.7) object maintains a list of all the Displayable
's
that are to be drawn to the screen. Each Displayable
consists of the
following components:
The Displayable
class is the fundamental building block for all items
which want to draw something to the screen. Consequently, it is a rather
complicated beast.
- Displayable::(TransMethod, char *, int, Scene *, int)
TransMethod is an enumeration value indicating how the objects
transformation matrix should affect the matrix of the DisplayDevice
(either it should multiply the matrix (MULT), replace it (LOAD), or it should
be ignored altogether (NONE)). The following arguments are the name of the
object, the dimension (2 or 3), the Scene
with which this object should
register, and the initial size of the display list storage (in kilobytes).
- Displayable::(TransMethod, char *, int, Displayable *, int)
This is the same as the first constructor, but instead of specifying a
Scene
to register with, a parent Displayable
is given. The new
Displayable
will become a child of the given parent, instead of
registering with a Scene
.
TransMethod is a public enumeration which is used to indicate the
method of use of the objects transformation matrix. It is one of the
following:
- MULT: multiply the DisplayDevice
's transformation matrix
by this object's matrix when the object is drawn.
- LOAD: replace the DisplayDevice
's transformation matrix
by this object's matrix when the object is drawn.
- NONE: do not use the object's transformation matrix when
rendering.
- Displayable *parent -- each Displayable
has a parent, which
may be null. The parent is in charge of collecting children and
displaying them as a single entity with separate display lists. Operations
which are applied to the parent are also applied ot the children, such as
rotations, commands to turn the item on or off, etc. Note that the reverse
is NOT true: operations applied to children are not applied to their parent.
Thus, if you rotate a parent, all the children will rotate in the same way,
but it is possible to rotate each child separately.
- ResizeArray<Displayable *> children -- the list of children for
this object. This is quite often empty. But other Displayable
's have
many children, for example MoleculeList
has as its children all the
Molecule
objects.
- void *cmdListBeg -- the start of the display list for this object
- void *cmdListPos -- the location in the display list where the
next drawing command should be placed
- Scene *origScene -- each Displayable
must register itself
with a Scene
object, and this item stores a pointer to that Scene
- ResizeArray<Scene *> sceneList -- if the Displayable
is
registered with more than one Scene
, they are stored here
- Matrix4 tm -- the current transformation matrix. This is a
public variable so it may be accessed quickly. The transformation matrix is
actually just four different matrices multiplied together; these matrices are
centm, rotm, globm, and scalem. The order of multiplication is as follows:
tm = globm * rotm * scalem * centm
When a vector is multiplied by tm, the operations these matrices represent
are:
- centm -- a centering translation. When tm multiplies a vector,
this centering translation is applied first.
- scalem -- scales the vector. This is done after the centering
translation, so the 'units' for the centering are in the same units as
used for the `world' coordinates.
- rotm -- rotates the vector. This follows the scaling operation
(although the two may be done in either order).
- globm -- a 'global' translation, which is the last operation done
to the vector. Since this is done after the scaling, the units are
in post-scaled world coordinates.
Displayable
contains many routines which add to or set the values of
these matrices.
- char *name -- the name of the object
- TransMethod transMethod -- the method for use of the
transmforamtion matrix. At the beginning of each display list is placed
commands to either multiply the current DisplayDevice
's trans matrix,
or to replace it, or to not modify it at all. This variable indicates how
this should be done. In almost all cases it should be MULT
- doCent, doRot, doGlob, doScale -- flags indicating whether this
object should obey commands to modify the respective transformation
components. Routines exist to toggle them on or off
- int *displayObj, *isFixed, *Dim -- flags indicating whether to
draw the object, whether to keep it fixed (so that it does not respond
to any transformation commands), and of what dimension it is (2 or 3). These
values are actually stored at the beginning of the display list, and these
pointers reference those locations
- virtual void prepare(DisplayDevice *) -- this should be supplied
by each derived class that needs to do some preparation before drawing. It
is called by the Scene
right before the scene is to be rendered. By
default, it does nothing.
A Displayable
must either be registered with a parent (i.e. be a child of
some parent), or it must be registered with a Scene
(in which case it
cannot be the child of any other Displayable
). To create a new class
derived from Displayable
, you need to provide two
constructors, one taking a Scene
pointer, one a Displayable
pointer.
Once created, then in the derived-class-provided prepare routine, the display
list of for the Displayable
must be set up. If this display list will
never change during the program, it can be done just once in the constructor
and no prepare is necessary. The display list is created by using
DispCmd
objects.
The display list for each Displayble
must be given to a Scene
,
regardless of whether it is child or parent or both. It is these display
lists which are given to the DisplayDevice
to be rendered. The
Scene
keeps a list of registered Displayable
's as well so that it
can prepare them for drawing. When a parent is prepared for drawing, it also
prepares all its children, so only top-level parents need to be registered
with the Scene
.
Since this class is derived from Pickable
and ColorUser
, there are
several virtual functions which may need to be supplied in order for the
derived Displayable
to be picked by the pointers, or to have access to
the color database. See the descriptions of these objects for more info.
One note about the display lists: the reason they are done in the current
scheme is that the CAVE requires the use of shared memory to hold the
information for the rendering processes to draw, while a separate update
process keeps track of updating the information in shared memory. Since the
shared memory cannot have pointers to non-shared memory locations, the display
lists are designed to ONLY hold integer and floating-point data. When drawing
in the CAVE, a special CaveScene
supplies shared memory blocks for the
Displayable
's to use for their display lists.
Right now every item is redrawn each time through the VMD
event loop.
However, there are times when nothing changes, and no redraw is necessary. The
prepare routine might be modified to have it return TRUE if a redraw is
needed, so that if none of the current Displayable
's need a redraw, that
extra work is avoided.
Also, this class is kind of a mess, but most of it is necessary ...

A 4 by 4 matrix of floats, used primarily for the transformation matrix of
Displayable
and DisplayDevice
objects. Along with general
routines to rotate, translate, and scale the matrix, this also contains
overloaded operators for = (copy, either a matrix or a scalar), *=
(multiply, by either a matrix or a scalar), and += (add a matrix).
There are many functions in this class to simply add or multiply the
matrix, to take the inverse of the matrix, or to apply rotations,
translations, etc. Most importantly, functions exist to take a 3- or
4-vector, and multiply (transform) it by this matrix.
- Matrix4::(void)
-- creates a 4 by 4 identity matrix.
- Matrix4::(float)
-- creates a 4 by 4 matrix with
all elements set to the given constant.
- Matrix4::(float *)
-- creates a 4 by 4 matrix, copying
the given array of 16 floats into the matrix (in row-major format).
- Matrix4::(const Matrix&)
-- creates a 4 by 4 matrix identical to the matrix given.
- float mat[4][4] -- the matrix data itself.
The many functions in this class are not listed here. The most common use
of this is to maintain a transformation matrix for transforming 3D vectors
from one coordinate space to another, i.e. to rotate, translate, and
scale them. Once a 4 by 4 matrix `M' has been set up, then a vector `V'
is tranformed and placed in the view vector `VT' as:
M.multpoint3d(V, VT)

The Scene
maintains and organizes a database with all the
Displayable
objects which are to be drawn by a DisplayDevice
. It
contains routines to add new Displayable
's to its database, and to draw
them to the screen or to a file. It is derived from PickList
, and so
maintains the information about what diffent picking modes are available, as
well routines to pick an item with a pointer.
There are two different sets of lists stored by the Scene
, with each list
kept for both the 2D case and the 3D case. The lists are:
- Registered Displayable
's; this list is used to prepare items to
be drawn. Only top-level Displayable
objects are kept in this list.
When a Displayable
is created, it registers itself with a Scene
,
and so gets added to this list.
- Registered display lists, the lists of drawing tokens created by
Displayables
. This list is used to actually draw the graphics, each
item in this list represents one display list and is given to a
DisplayDevice
to be rendered.
This object also contains routines to apply a constant rotation to all
Displayable
's each time they are drawn, as well as to apply general
transformations to all the items in the scene. The most important function of
Scene
is, however, to draw the scene to a display or to a file.
- int numDisplayable2D, numDisplayable3D -- the number of 2D and 3D
Displayable
's which have registered. Derived classes maintain the
actual lists.
- int numCmdLists2D, numCmdLists3D -- the number of 2D and 3D
display lists have been registered. Derived classes maintain the
actual lists.
- virtual void prepare(DisplayDevice *) -- goes through all
the registered objects and prepares them for drawing. This should be called
before draw.
- virtual void draw(DisplayDevice *) -- actually draws the scene,
using the given DisplayDevice
. If this display is in stereo, this will
first draw the left eye view, then the right.
- virtual int filedraw(char *, char *, DisplayDevice *) -- very
similar to draw, except this draws the scene to a file-based
DisplayDevice
. The first two arguments are the format, and the
filename. The different formats and file-rendering objects are maintained by
a global instance of the object FileRenderList
.
A Scene
is created at the start of the program, and all Displayable
objects should be added to that scene (or to another Displayable
as a
child). It is used in the primary event loop to prepare and draw all the
Displayable
's. It is also used to pick items with a pointer. The global
routine VMDupdate contains an example of using a Scene
object.
There are two derived classes from Scene
:
- NormalScene
-- this is the basic version, which is used for every
case except when the CAVE display device is being used. It uses standard
memory allocation routines to create storage for display lists, and to store
the lists of Displayable
s and display lists.
- CaveScene
-- this uses shared memory to store the display lists,
so that the CAVE processes can all see the same data for rendering the scene.
As mentioned for Displayable
, the prepare routine could be modified
to return a flag indicating whether anything has changed in the
Displayable
objects which would require a redraw. If nothing changed,
then a redraw could be avoided.
Next: Molecule objects
Up: Function and Class
Previous: Utility objects
Andrew Dalke
Wed May 15 02:25:03 CDT 1996