XGL Programmer's Guide
  Suchtext Nur in diesem Buch
Dieses Buch im PDF-Format herunterladen

Basic XGL Concepts

The XGL programming model and the relationship between XGL and the X window system were briefly introduced in Chapter 1. The sections that follow provide additional information on XGL and the X window system, and describe more fully the XGL object-based programming model. For an example of an XGL program, turn to "Example Program" on page 37.

XGL and the X Window System Environment

An XGL application is an X client program running in an X window system environment, such as Sun's OpenWindows environment. The X window system is composed of several components. The central component is the display server, which is responsible for managing output requests from client applications to draw onto the display and for distributing input events to the appropriate client applications. The server and the client applications communicate via the X and/or PEX protocol(s). During a work session, client applications generate protocol queries and requests using the Xlib or PEXlib programming interface or an X toolkit, and the server processes these requests.
An XGL application program uses Xlib or X toolkit functions to connect to the server, create a window on the display, and handle event interpreting. The server manages the relationship among the various windows on the screen and provides input and events to the application, and the toolkit provides the application's user interface. The application renders its geometric data to the window using XGL primitives. The Xlib or X toolkit calls coexist with the XGL calls, sharing the same process space and drawable area on the screen. Figure 3-1 on page 28 illustrates a high-level view of this relationship.

Grafik

Figure 3-1

Rendering Graphics Locally and Remotely

When a client XGL application is running locally under Sun's OpenWindows server and the hardware supports Direct Graphics Access (DGA) protocol, XGL renders using DGA technology rather than rendering through the server via the X protocol. DGA is a set of mechanisms that enables OpenWindows client processes to directly drive a graphics device that is under the control of the OpenWindows server. Although the server manages the resources of the device, the XGL client process coordinates with the server to send rendering commands directly to the device rather than sending X11 protocol messages to the server. This allows XGL to eliminate the communication overhead of the server-based window system, thereby improving performance.
Figure 3-2 on page 29 illustrates the XGL system's relationship to DGA and the server. When an application program creates a Raster Device object, the XGL library automatically determines whether DGA is available and whether XGL supports the frame buffer. If DGA is available and the frame buffer includes DGA support, XGL synchronizes with the server to share direct access to the frame buffer. In this case, XGL renders graphics geometry to the frame buffer, and the server performs other window operations. Note that XGL will render through Xlib or PEXlib when used with a non-OpenWindows server. This allows XGL to render to any X11 server; however, rendering will be accelerated on a machine running the OpenWindows server.

Grafik

Figure 3-2

Like all X applications, an XGL application can be run remotely and displayed on a user's local workstation if the two workstations are part of a network. Remote rendering through the X11 protocol or the PEX protocol is handled automatically by XGL. When the XGL client program is running remotely, XGL uses Xlib or PEXlib to do all rendering. If the server includes the PEX extension and XGL has access to its PEX loadable library, XGL uses PEXlib to render. If PEX is not available, XGL uses Xlib for 2D rendering. For primitives and rendering options that are not supported by Xlib, XGL does scan conversion to send the pixels through Xlib to the device. Figure 3-3 on page 30 illustrates remote rendering.

Grafik

Figure 3-3

How an XGL Application Works

As mentioned above, an XGL application follows the general format of Xlib, PEXlib, or X toolkit programming, using the event-driven model of X applications for interaction handling. With Xlib calls, PEXlib calls, or X toolkit calls, the application first creates the window system objects that it needs, such as a window for graphics display, and then opens the XGL system. When XGL is opened, it automatically creates the System State object as well as internal objects that handle interactions between the device-dependent and the device-independent parts of the XGL system. To set up a framework for rendering, the application must create a Device object, which is an abstraction representing the display device, and a Context object, which controls all rendering actions on a device. These objects are created using an XGL object creation operator that takes attributes describing the object as input arguments, creates an instance of the object, and returns a handle to the object. The application program must associate the Device object with the Context object before geometry can be rendered. When the Context object and Device object are associated, the application can use XGL primitives to render geometry and can pass control of the program to Xlib or an X toolkit to process events.
During the work session, the application can change Context attributes to change the display characteristics of geometry. It can also render geometric data using XGL drawing primitives and create other objects as needed. For example, the application might want to create several Stroke Font objects to enable the use of different character sets, or create Line Pattern objects to provide the user with application-specific line patterns. Multiple Device
objects, such as Window Raster and Memory Raster devices, can be associated with and disassociated from the Context object as needed for rendering. When the application exits XGL, the System State object destroys existing objects, frees resources, and then destroys itself, closing XGL.

XGL Drawing Primitives

The XGL library provides a set of drawing primitives that the application can use to render geometric data. The available primitives include basic line, polygon, and text primitives as well as more complex primitives, such as NURBS curve, curved surface, and quadrilateral mesh primitives. In the XGL system, geometry is rendered via the Context object, which also maintains graphic and environment state information that is used in rendering. Because XGL is an immediate mode system, it needs access to current state information at the time of rendering. Since the application can create more than one Context object and can render the same geometric data using different Context objects, the application must define which Context object is to be used to render. Thus, the drawing primitives require the Context object as an input parameter and are considered to belong to the Context object.
The drawing primitives are listed in Table 3-1 and are described in more detail in Chapter 8, "Primitives and Graphics Context Attributes".
Table 3-1
Primitive TypeDescriptionXGL Primitive
LinesA set of unconnected linesxgl_multipolyline()
B-spline curvesA spline (NURBS) curvexgl_nurbs_curve()
MarkersA set of markersxgl_multimarker()
CirclesA set of circlesxgl_multicircle()
Circular arcsA set of arcsxgl_multiarc()
Elliptical arcsA set of 3D elliptical arcsxgl_multi_elliptical_arc()
RectanglesA set of rectanglesxgl_multirectangle()
PolygonA single planar polygonxgl_polygon()
Multiple polygonsA set of 3- or 4-sided polygonsxgl_multi_simple_polygon()
Stroke textA text stringxgl_stroke_text()
Table 3-1
Primitive TypeDescriptionXGL Primitive
Annotation textA text string displayed in a plane parallel to the display surfacexgl_annotation_text()
Quadrilateral meshA set of connected quadrilateral polygonsxgl_quadrilateral_mesh()
Triangle stripA set of connected triangular polygonsxgl_triangle_strip()
Triangle listA set of connected triangles
arranged as a triangle strip or as
a triangle star, or a set of
unconnected triangles
xgl_triangle_list()
Curved surfaceB-spline surfacexgl_nurbs_surface()

Handling 2D and 3D Data

XGL handles the dimensionality of application data via the dimension of the Context object, the type of point data input to the drawing primitives, and the set of attributes available to a Context. Context objects can be either 2D or 3D. An application that needs to render both 2D and 3D model data will typically create two Context objects, one for 2D rendering and one for 3D rendering. When the Context object is created, a default rendering pipeline, which includes transformations and clipping,, is also created. Creation of a 2D Context object results in the creation of a pipeline tailored to the processing of 2D geometry; creation of a 3D Context results in the creation of a more complex 3D pipeline, which handles lighting, shading, and texturing.
Application model data must be input to the drawing primitives using a point type appropriate to the Context object. Thus, for example, a 2D application might define a 2D Context object and set up the application data in XGL 2D point structures, choosing from integer or floating point structures. The XGL library provides a wide variety of point data types, including point types with and without color and/or normal data.
The dimension of the Context object also controls the set of attributes available to the application for rendering. For example, a 2D Context object includes a set of attributes that controls how the front of a surface is displayed; a 3D Context object has access to the front surface attributes but has an additional set of attributes for back surface rendering as well.
Once the appropriate Context object has been created, the application model data has been set up in XGL point data structures, and the applicable attributes have been set, the application can render using the drawing primitives. Many of the XGL drawing primitives can be used for both 2D and 3D rendering, but some are specific to 3D geometry, as shown in Table 3-2.
Table 3-2
Primitive2D Rendering3D Rendering
xgl_multipolyline()vv
xgl_multimarker()vv
xgl_multicircle()vv
xgl_multiarc()vv
xgl_multi_elliptical_arc()
v
xgl_multirectangle()vv
xgl_polygon()vv
xgl_multi_simple_polygon()vv
xgl_stroke_text()vv
xgl_annotation_text()vv
xgl_quadrilateral_mesh()
v
xgl_triangle_strip()
v
xgl_triangle_list()
v
xgl_nurbs_curve()vv
xgl_nurbs_surface()
v

More on XGL Object-Based Programming

XGL represents graphics information with abstract data structures called objects. An XGL object represents a graphics resource, such as a line pattern or a font. Each object describes a virtual component of the graphics rendering system and contains information necessary to perform graphics operations. A display device, for example, is known to the XGL programmer as a Window Raster Device object. This abstraction of the display device hides the specifics of the device-dependent code for the graphics hardware device and lets the XGL programmer interact with the device in a device-independent manner.
Internally, XGL objects are instances of classes. A class is an abstract data type that combines state information with functions that perform actions on the object. The class's attributes and functions define the characteristics of the object. A class is only a data type definition; it does not exist in memory. A class must be instantiated to be used, and it can be instantiated many times to create distinct objects that all belong to the same class. Objects exist in system memory and provide the functionality that the application program needs to render geometry.
Figure 3-4 on page 35 shows a diagram of the XGL class hierarchy with objects that have been instantiated by calls to xgl_object_create(). The illustration shows a possible XGL runtime system consisting of two Context objects, a Window Raster object, a Memory Raster object, two Stroke Font objects, and a Transform object.

Grafik

Figure 3-4

Operators

Operators are functions that control the behavior of an object. Most XGL objects have a set of operators that handle operations required by the object. For example, the Transform object includes operators that perform transformation operations, such as matrix concatenation. The XGL system also provides operators that perform functions common to objects, such as object creation or destruction. These operators, listed in Table 3-3, provide a consistent method of working with all XGL objects.
Table 3-3
OperatorDescription
xgl_object_create()Creates an XGL object.
xgl_object_set()Sets the value of an attribute.
xgl_object_get()Gets the value of an attribute.
xgl_object_destroy()Destroys an object.
Operators provide a way for the application to access an object and manipulate the object's data structures, since direct access to the object data structures is not provided. If, for example, the application program needs to change the
color of a line, it must use the xgl_object_set() operator to change the value of the line color attribute, since it cannot directly access the line color attribute field in the object data structure.

Attributes

Attributes control much of the functionality of XGL, such as the appearance of rendered geometry, the way picking is handled, and the orientation of virtual device coordinate space. Although some attributes are read-only, an application can change the value of most attributes at any time. Attributes are input as arguments to XGL operators, some of which take an attribute-value list as one of the input parameters. Each attribute-value pair in the list consists of an attribute name followed by its value. The attribute-value list may have as few as zero attribute-value pairs or as many as the total number of the object's attributes, but in all cases it is terminated with the NULL character, where NULL is defined as in stdio.h.

Object Relationships

Some objects use other objects as resources. When an association has been established between two objects, the objects communicate via messages that inform the using object of changes that have occurred in the data structures of the used object. For example, if an application has created a new Line Pattern object and has associated the Line Pattern object with the Context object, the Context object will automatically be kept up to date on the characteristics of the Line Pattern object so that the line pattern will be rendered correctly.
Object relationships are set up by the application and are managed internally by XGL object management functions. When an application has created a new object, it establishes the association between the new object and an existing
object using the xgl_object_set() operator, a connecting attribute, and the handles of the two objects. Table 3-4 lists objects that are associated as graphics resources with the Context and Device objects.
Table 3-4
Using objectObject being used
Raster DeviceSystem State
Color Map
ContextSystem State
Device
Data Map Texture
Texture Map
Transform
Line Pattern
Marker
MipMap Texture
Pcache
Stroke Font
Light (3D Context only)
Information on the specific attributes that associate resource objects with the Context or Device objects is available in the chapters that follow.