Next: Displayable Up: Display objects Previous: DispCmd   Contents

Subsections

## DisplayDevice

 Files: DisplayDevice.h, DisplayDevice.C Derived from: \bf ColorUser Global instance (if any): display Used in optional component: Part of main VMD code

### Description

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., 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.

### Enumerations, lists or character name arrays

• 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.

### Internal data structures

• 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 OpenGL 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 member functions

• 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 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 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.

### Method of use

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 void Scene::draw(DisplayDevice *display) routine. A Scene object maintains a list of display lists and Displayable objects which create those lists (see section 24.7). The draw routine uses the DisplayDevice as follows:
1. display->prepare3D()
2. Set the stereo mode to the left eye, or just normal, using the command display->left() or display->normal()
3. For each Displayable in the Scene, the prepare routine is called to make that object ready to be drawn.
4. For each display list maintained by the Scene, the command display->render(displist) is called.
5. If the display is in stereo, display->right() is called and the previous step repeated.
6. 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 int Scene::filedraw(char *method, char *filename, DisplayDevice *display) is used instead of draw, since a specific filetype and filename must also be given.