![]() |
![]() |
![]() |
![]() |
This chapter provides on overview of the architecture of the Graphics Display (GD) Kit. You should read this chapter before beginning the Tutorials
- Introduction, Section 1.1
- Base types, Section 1.2
- Editors, Section 1.3
- Components, Section 1.4
- Graphics Display Kit module execution, Section 1.5
- Rendering subsystem, Section 1.6
The Graphics Display Kit, as illustrated in the diagram below, is built on top of windowing systems and graphics libraries.
![]()
The first level up from the system level is the Graphics Display Kit rendering subsystem. This subsystem provides all of the window system-dependent and graphics-library-dependent routines that make up a renderer in the Graphics Display Kit. It also provides the data-independent routines that convert the raw data into a renderable form that can be passed to the renderer-specific routines.
The second level up from the system level contains the base types that make up the Graphics Display Kit. Base types include a view, camera, and properties. This layer and the rendering subsystem layer contain all of the functions that make up the high level language API of the Graphics Display Kit.
The levels above this depend on other components in AVS/Express. At a minimum, this includes the Object Manager and can include the field data schema and user interface components.
The Graphics Display Kit has a number of base types that form its basic building blocks. You can combine these base types using the visual programming enviroment into more complex pieces (e.g., Components).
The base types can be separated into two groups: those that can have children and those that cannot. Of the base types described below view, camera, light information, light, and object can all have children and the rest cannot.
The view base type can be considered the "root" since all other base types either connect to the view or to a child of the view. Subobjects of the view include the type of renderer (e.g., software, OpenGL), the double buffer flag, and background color. Children of the view include a handle to the parent user interface widget, a virtual palette, light information, an array of cameras, and pick control information.
The camera base type controls how the objects in it are viewed. An important subobject of the camera is type: either 3D or 2D. The type of camera controls if the objects in it are rendered using 3D or 2D primitives. Other subobjects of the camera include a viewport specification, orientation and projection parameters, and depth cueing information. Children of the camera include an array of objects and a transformation.
The light information base type controls the color and state of the ambient light source. The light information base type has an array of lights as children.
The light base type controls the type and state (i.e., on/off) of the light. Other subobjects include color, attentuation, and concentration. The light base type can have a transformation as a child.
The virtual palette controls the type and amount of color resources used by the view. Subobjects include visual class, gamma correction value, and cube_size.
The pick control base type has subobjects that provide the XY position for picking and various pick-related attributes.
The object base type has subobjects that control visibility, pickability, caching, surface conversion, and image display. Children of the object base type include a datamap, a transformation, properties, modes, a texture, and an alternate object.
The properties base type include subobjects that control primary color, highlight colors, material, transparency, drawing mode, line width, and line style. In addition, it includes a subobject that determines if the properties are inherited from its parent.
The modes base type includes subobjects that control point, line, surface, volume, and bounds rendering modes.
The transformation base type includes a scale and rotation matrix, a position vector, and a center vector.
The texture base type contains subobjects that control if and how a texture map is applied to the object.
The datamap base type contains subobjects that control how the data values in the input data are converted into color information for the rendering subsystem.
The pick information base type contains subobjects that convey information such as an indication if the object is picked, how many primitives in the object were picked, the vertex picked, the point picked, various indices back into the input data, and a variety of transformation matrices that map the data from world space to object space.
Each of the base types has a standard set of routines associated with them:
- The create routine is used to make an instance of the base type.
- The delete routine is used to remove an instance of the base type.
- The update routine is called automatically by the Object Manager whenever one of the subobjects of the base type has changed so the instance of the base type can update itself. For example, if another object is added to a camera, the camera update function is called, which causes the view update function to be called, which in turn causes the view to be rerendered because it has changed.
- The get and set routines allow you to access the subobjects of a base type. Any subobject that can be written can also be read.
- Only building blocks that can have children have attach and detach routines. These routines are used to connect children to their parent. For example, there are routines that attach and detach a camera from a view.
There is a 1:1 correspondence between Graphics Display Kit base types and Graphics Display Kit editors. The editors take a base type (e.g., view, camera) and an additional number of subobjects as input and produce an updated version of the base type. The editor subobjects are typically attached to user interface widgets.
The editor's update function executes for two reasons: either the base type it is attached to has changed or one of the other subobjects has changed. In the first case, the editor uses:
- The get routines of the base type to retrieve the existing values of the base type.
- A set of Object Manager routines to take the new values and set them in the user interface widgets. This happens as long as the shell_vis subobject in the editor is set to 1. This subobject is normally attached to the visible subobject of the editor's UIshell. This is an optimization that eliminates updates to widgets that are not visible.
In the latter case, the editor uses:
- A set of Object Manager interface utilities to test the individual subobjects in the editor to determine if the value has changed since the last execution of the update routine.
- The set routines of the base type to take the new user interface values and update the values in the base type.
The editors are the preferred interface to the Graphics Display Kit base types. The reason for this is that the editors can provide additional functionality on top of the base type. For example, the properties editor automatically clears its inherit subobject when any other subobject changes. This causes the default behavior of inheriting a parent's properties to be overidden when a subobject changes.
The editors are built in a manner that allows them to be shared between multiple instances of base types. This is important since the editors are user interface intensive. Instead of having a separate instance of an editor for each instance of a base type, there is a single instance for each kind of base type. The base type input to the editor is then switched based on the current or picked object.
The editors are also reconfigurable or replaceable components. It is easy to reconfigure the user interfaces for the editors since they are all expresed in V. It is also easy to replace an editor, since there are a set of Object Manager utilities and the get/set routines of the base type.
Once you start to connect the Graphics Display Kit base types and editors together, you can classify them as components. The Graphics Display Kit comes with a set of prebuilt components that are commonly used.
Custom components can easily be built using AVS/Express' visual programming environment. The diagram below shows a custom view component.
![]()
The diagram below shows a custom object component.
![]()
The following is a look at the general flow of module execution in the Graphics Display Kit from the time that you change a user interface widget to the time the view is actually rerendered.
The action that starts this process is a change to a user interface widget. For the purpose of this discussion, say you change the slider that is attached to the red value in the Graphics Display Kit properties editor. The diagram shown below illustrates the modules that execute in this sequence.
![]()
A change in the value of the slider triggers the window system callback for that widget. The callback writes the new value of the widget to the attached subobject in the Object Manager. In this case, the red slider's value is attached to the Graphics Display Kit properties editor red subobject.
This change causes AVS/Express to activate the properties editor. The properties editor determines which of its subobjectes has changed and updates the properties base type that is attached. In this case, since the value of red has changed, the color subobject of the properties base type is updated.
The change to the properties base type causes AVS/Express to activate the properties update function. The update function keeps the local structure associated with the base type in synch with the contents in the Object Manager. This is done so when the view is rerendered, access to subobjects via the Object Manager are kept to a minimum.
The change to the properties base type also triggers activations of the update routine for all Graphics Display Kit objects that reference this instance of the properties. One of the actions that the object update function performs is to notify all the views it is attached to that a child object has changed. Since the camera has only expressed an interest in knowing if the number of objects attached to it has changed, the camera update routine is not activated. The camera has not asked to be told when an object itself has changed. This can be done because the objects directly notify the views they are attached to. Therefore, a layer of activations that would otherwise occur during a render process are eliminated. Note that if any duplicate notifications are generated during this process, the Object Manager compresses the events so that each view update function receives only one activation. This causes the view update function to run for each view. The last action the view update function takes is to invoke the rendering subsystem to rerender the view.
As we have discussed in the previous section, the Graphics Display Kit rendering subsystem is invoked as the last action of the view's update function. These sections describe the execution that takes place whenever a view is rendered.
This section briefly describes the components that make up a renderer in the Graphics Display Kit.
Each view has a state and a stack associated with it. The view's state contains the current set of attributes a renderer needs in order to render data. This includes color, transformation, and line style. The view's stack contains attributes from the state that have been "pushed" or "popped" onto the stack while the object hierarchy in the view is being traversed. This is the mechanism that is used to keep the state current while we render the cameras and objects that are in the view.
A renderer in the Graphic Display Kit is composed of three distinct sets of routines:
The view level renderer routines depend on the windowing system at a minimum and may also depend on the graphics library. For example, there are separate view level routines for the software renderer on X-based systems and Win32-based systems. The V code below shows the definition of these routines for the software renderer.
group sw_view_funcs {
int renderer = 0;
func+virtual view_available = "GDsw_view_available";
func+virtual view_create = "GDsw_view_create";
func+virtual view_clear = "GDsw_view_clear";
func+virtual view_transp_pass =
"GDsw_view_transp_pass";
func+virtual view_accel = "GDsw_view_accel";
func+virtual view_swap1 = "GDsw_view_swap1";
func+virtual view_image_pass =
"GDsw_view_image_pass";
func+virtual view_swap2 = "GDsw_view_swap2";
func+virtual view_refresh = "GDsw_view_refresh";
func+virtual view_delete = "GDsw_view_delete";
func+virtual view_resize = "GDsw_view_resize";
};
The state level renderer routines depend on the graphics library. For example, there are separate state level routines for the OpenGL, XGL, and PEXlib renderers. They include set color, set material, and set line width routines. The V code below shows some of these routines for the OpenGL renderer.
group gl_state_funcs {
int renderer = 1;
func+virtual state_init = "GDgl_state_init";
func+virtual state_set_color = "GDgl_set_color";
func+virtual state_set_material = "GDgl_set_material";
func+virtual state_set_mode = "GDgl_set_mode";
};
The primitive level routines are broken up into two groups: drawing and picking. The primitive draw routines depend on the graphics library just as the state level routines do. As with the state level routines, there are separate primitive level routines for each renderer. They include draw 3D line, draw 3D polyline, draw 3D triangle strip, draw 2D lines, and draw image routines. The V code below shows some of these routines for the XGL renderer.
group xgl_prim_funcs {
int renderer = 2;
func+virtual prim_3d_points = "GDxgl_points";
func+virtual prim_3d_lines = "GDxgl_lines";
func+virtual prim_3d_polyline = "GDxgl_polyline";
func+virtual prim_3d_polytri = "GDxgl_polytri";
func+virtual prim_3d_spheres = "GDxgl_spheres";
};
The primitive pick routines are independent from either the window system or graphics library. In fact, they are independent of the renderer and are shared among all the renderers. They include routines like pick 3D points, pick 3D lines, and pick 2D lines.
The Graphics Display Kit's rendering subsystem is invoked when the view update functions calls the view render routine. This starts the process of rendering a view in which the following actions take place. Note that the description of the flow of execution is for the case where accelerate mode is not enabled.
- The renderer-specific view clear routine is called.
- A start view render indicator is pushed onto the stack.
- The renderer-specific state set lights routine is called.
- If there are 3D cameras in the view, they are rendered by the 3D camera render routine.
The renderer-specific swap first pass routine is called. In the case of the software renderer, this routine takes the contents of the 3D frame buffer, dithers if necessary, and "puts" the contents to a 2D drawable. The 2D drawable is either a window or a pixmap if the windowing system is X Windows. This procedure may be different for the hardware renderers depending on, for example, the ability to intermix graphics library calls and window system calls to render data.
The renderer-specific view swap second pass routine is called. In the case of the software renderer, this means copying the 2D drawable to the window. This is only necessary if we are in double buffer mode.
Whenever a 3D camera is rendered, the 3D camera render routine is called. This starts the process of rendering a camera in which the following actions take place. Note that the description of the flow of execution is for the case where accelerate mode is not enabled.
- A start camera render indicator is pushed onto the stack.
- The renderer-specific state routines to set camera attributes routine are called.
- If there are opaque objects in the camera, they are rendered by the object render routine.
- If there are transparent objects in the camera, the renderer-specific view transparent pass routine is called. This gives the renderer an opportunity to setup to render the transparent objects in the view.
All transparent objects in the camera are rendered by the object render routine.
Whenever a 2D camera is rendered, the 2D camera render routine is called. This starts the process of rendering a camera in which the following actions take place. Note that the description of the flow of execution is for the case where accelerate mode is not enabled.
- A start camera render indicator is pushed onto the stack.
- The renderer-specific state routines to set camera attributes routine are called.
- If an image pass has been requested and if there are images in the camera, they are rendered by the object render routine. The renderer-specific view image pass routine is called. All other objects in the camera are rendered by the object render routine.
Otherwise, all objects in the camera are rendered by the object render routine.
- If there are transparent objects in the camera, they are rendered by the object render routine.
- The stack is popped to restore it to its state before the camera was rendered.
Whenever an object is rendered, the object render routine is called. This starts the process of rendering an object in which the following actions take place.
- A start object render indicator is pushed onto the stack.
- The renderer-specific state routines associated with the object are called.
- The renderer-specific state set data map routine is called.
- The renderer-specific state routines associated with the modes are called.
- The renderer-specific state routines associated with the properties are called.
- The renderer-specific state routine associated with the texture is called.
- The renderer-specific state routines associated with the transformation are called.
- The object render routine determine if the object should be rendered in this pass. If the alternate object is enabled, the object render routine is called for the alternate object.
Otherwise, if there is data to render, the object draw routine is called.
- If the object has any children, the object render routine is called for each child.
- The stack is popped to restore it to its state before the object was rendered.
Whenever the object draw routine is called, the following actions take place:
- For a cached object that has a valid cache, the object is rendered using the data in the cache. One of the attributes associated with each object is whether or not a renderable representation of the data should be cached. The cache is invalidated for a number of reasons. For example, the cache is invalidated when the data changes or when the rendering mode changes. The cache attribute can be set on a per object basis.
- For non-cached objects or for objects without a valid cache, the object draw routine gets the render method associated with the data and calls it. In order for data to be rendered by the Graphics Display Kit, it must have a render method. This render method is specific to the data and converts the data from its current format, usually an AVS/Express field, into calls to the renderer's primitive level routines.
All data that is to be rendered by the Graphics Display Kit must have a render method associated with it. The presence of a render method is what allows any data to be connected to one of the Graphics Display Kit viewers in the Network Editor. This method converts the data from its current form, usually an AVS/Express field, into a renderable representation that can be passed to the renderer-specific primitive level routines. Currently, the Graphics Display Kit supports render methods for four separate groups: structured fields, unstructured fields, "tiled" fields, and text. The details on the Graphics Display Kit render methods are found in the Render Methods chapter.
![]() |
![]() |
![]() |
![]() |
![]() |
Copyright © 2001 Advanced Visual Systems
Inc.
All rights reserved.