XGL Device Pipeline Porting Guide
この本のみを検索
PDF 文書ファイルをダウンロードする

Getting Information from XGL Objects

6

This chapter describes how a device pipeline gets information from XGL objects and uses object interfaces. The chapter includes information on the following topics:
  • Getting information from the Context and from objects associated with the Context
  • Getting information from the Device and Color Map

Imported image(30x36)

As you read this chapter, you will find it helpful to have access to the following header files:
  • Context.h, Context2d.h, and Context3d.h
  • Cmap.h
  • Device.h,Raster.h, RasterWin.h, and RasterMem.h
  • DmapTexture.h
  • Light.h
  • LinePattern.h
  • Marker.h
  • MipMapTexture.h
  • Sfont.h
  • Tmap.h
  • Transform.h

What You Should Know About XGL Attribute Values

The values of XGL attributes are stored in the Context object and in API objects associated with the Context object, such as the Light object and the Transform object. At rendering time, the device pipeline often needs to get information on various attributes from within its XglDpCtx and XglDpDev objects.
The pipeline is linked to a specific Context and a specific Device through its XglDpCtx object; from the XglDpCtx, the pipeline can get to the Context attributes it needs and to the attributes of objects associated with the Context. Similarly, the pipeline is linked to the Device object through its XglDpDev object, and it can get information on the device-independent Device object and the Color Map object through the XglDpDev. Figure 6-1 shows the architecture of the device-independent objects and their relationship to pipeline objects. In this illustration, the filled arrows denote a permanent relationship; for example, the XglDpCtx object is always linked to a unique Context object and unique Device object. The unfilled arrows show possibly transitory API relationships.

グラフィック

Figure 6-1

Pipelines access API attribute data via public methods in the public interface of the API object classes; the data itself is not exposed in the public interface or accessible to the pipeline. To see the interface for an object, look at the class hierarchy for the object.
Part of the public interface implements the XGL API. Thus, in the API object classes, there are two categories of functions: functions that correspond closely to API attributes and other functions that are for internal uses, including the device pipeline (flagged with XGL_INTERNAL). A third category is reserved for the XGL core and is inaccessible to the device pipelines (flagged with XGL_CORE). In the public interface, you will notice a number of set...() functions; for the most part, these implement the API set functions and are not meant to be used by the pipeline. An exception to this is the pipeline use of device->setBufDisplay() and device->setBufDraw() from within its XglDpCtx li1NewFrame()primitive.

Naming Conventions for Internal Attributes

The mapping of an API attribute name to its corresponding C++ method is handled in a standard way. For example, in Light.h, you will see the function getColor(). This function gets the light color and corresponds to the API attribute XGL_LIGHT_COLOR. The naming conventions for internal attributes, such as a hypothetical API attribute XGL_CLASS_ATTRIBUTE_HAS_WORDS, are as follows:
  • The internal method to get the attribute is getAttributeHasWords().
  • The method is declared in the XglClass class in the Class.h header file.
Here are some examples:
  • For the Context attribute XGL_CTX_MARKER_COLOR, the function getMarkerColor() is declared in the XglContext class in Context.h.
  • For the Context attribute XGL_3D_CTX_SURF_FRONT_ILLUMINATION, the function getSurfFrontIllumination() is declared in the XglContext3d class in Context3d.h.
  • For the Device attribute XGL_DEV_COLOR_MAP, the function getCmap() is declared in the XglDevice class in Device.h.

Note - In some cases, although an attribute may be present in the parent class, it might actually be defined in a descendant class. Note also that the corresponding set/get functions might be in a descendant class when the action depends on the descendant class.

Context Attributes and LI Layers

The Context attributes that the pipeline needs to check at rendering time vary depending on the pipeline layer. A pipeline written at the LI-1 layer needs to implement the complete set of XGL attributes, or at least account for them. At the LI-2 layer, the device pipeline is using the software pipeline to handle some of the processing; therefore, the device pipeline has a smaller subset of attributes that it is accountable for. At the LI-3 layer, the number of attributes that a device pipeline must handle is even smaller. For example, an LI-1 port must handle back surface attributes and transforms, but at the LI-2 level these attributes have been processed by the software pipeline, and the device pipeline no longer needs to concern itself with them. This concept is illustrated in Figure 6-2.

グラフィック

Figure 6-2

See Chapter 9, "Writing Loadable Interfaces" for information on the attributes used by each LI function.
Note that you will probably want to make use of the objectSet() function to optimize Context state retrieval. The objectSet() function notifies the device pipeline about changes to Context attributes. If a change occurred, the pipeline must get the new value of the attribute and reload the state into the hardware. In addition, the pipeline uses the stroke tables to get the values of attributes for primitives multiplexed on the multipolyline primitive. See Chapter 5, "Handling Changes to Object State" for information on the objectSet() function and stroke groups.

Getting Attribute Values from the Context

From the XglDpCtx object, you can get Context attribute values and values for objects associated with the Context. The XglDpCtx object is provided with a pointer to the Context object. This pointer is named ctx and is an XglDpCtx protected member data. Note that ctx already points to a Context of the right dimension. In other words, in XglDpCtx2d, ctx is already of type XglContext2d*, and in XglDpCtx3d, ctx is already of type XglContext3d*, so you don't have to cast the pointer to the correct type. Using the Context pointer, you can get an attribute using ctx->getAttribute().
Example code for a pipeline getting depth cue attributes from a 3D Context might be:

  Xgl_depth_cue_mode        dc_mode = ctx->getDepthCueMode();  
  
  if (dc_mode != XGL_DEPTH_CUE_OFF) {  
       float   scale_front;      // Scale factors to use  
       float   scale_back;  
  
       if (dc_mode == XGL_DEPTH_CUE_SCALED) {  
           float        scale_factors[2]; // XGL DC scale factors  
           ctx->getDepthCueScaleFactors(scale_factors);  
           scale_front = scale_factors[0];  
           scale_back = scale_factors[1];  
       }  
  else {  // continue  

Getting Attribute Values from Other Objects

To render line patterns, markers, and other application-definable data, the device pipeline needs to get information from the objects that the application has associated with the Context. In most cases, handles for these objects are retrieved from the Context object using ctx->getObject(). In the following cases, however, the pipeline does not retrieve the object handle for an object from the Context, even though these objects are associated with the Context at the API-level:
Table 6-1 shows the objects that the application can associate with the Context and the get...() functions used to retrieve data from them.
Table 6-1
ObjectFunction
Data Map Texture object (3D only)getDmapTexture()
Device objectSee page 145.
Light object (3D only)getLight()
Line Pattern objectgetLinePattern()
Marker objectgetMarker()
Stipple pattern Memory Raster objectgetRasterFpat()
Stroke Font objectgetSfont()
Texture Map object (3D only)getTmap()
Transform objectSee page 125.
Using the object handle, the pipeline can retrieve attribute data through the public interfaces of the DI object classes.
The following example shows a pipeline accessing a Marker via the Context, using a Marker interface, and getting a Marker attribute from the Context.

  const XglMarker*          marker;  
  const XglPrimData*        mdata;  
  float                     scale;  
  
  marker = ctx->getMarker();  
  mdata = marker->getActualDescription();  
  scale = ctx->getMarkerScaleFactor()  

Getting Information from a Transform Object

To access member functions of the Transform object, the pipeline gets a handle to the Transform object through the view group interface object. The pipeline is provided with a view group interface object and a pointer to the object named viewGrpItf in the XglPipeCtx{2,3}d parent class. The pointer to the view group interface object is of type XglViewGrp2dItf* or XglViewGrp3dItf*, depending on the Context.
To access the Transform, use the pointer to the view group interface object and then access the Transform's interfaces using the handle to the Transform. The following example shows a pipeline using the Transform interface getMatrixFloat() from a Transform associated with a 2D Context.

       XglTransform*               xform;  
       const Xgli_matrix_f3x3*     matrix;  
  
       // Load the MC-to-DC transform matrix  
       xform = (XglTransform*) viewGrpItf->getMcToDc();  
       matrix = (const Xgli_matrix_f3x3*) xform->getMatrixFloat();  

See "Transform Interfaces and Flags" on page 137 in this chapter for information on Transform interfaces, and see Chapter 7, "View Model Derived Data" for information on the view group interface object. Note that if the pipeline is not using the derived data facility, it can get Transforms from the Context; see page 150 for more information.

Getting Attribute Values From the Stroke Group Object

For primitives that are multiplexed on the multipolyline primitive, the XGL core provides a generic group, the stroke group, that holds the necessary attribute information. The stroke group is the source from which the pipeline obtains the values for the line attributes, such as line color, during an li1/2MultiPolyline() call. The stroke group attributes that map to API attributes are:
  • Antialiasing blend equation
  • Antialiasing filter width
  • Antialiasing filter shape
  • Alternate color
  • Cap
  • Color
  • Color selector
  • Join
  • Miter limit
  • Pattern
  • Style
  • Width scale factor
The Context object provides a current stroke pointer to indicate which stroke group will be used for rendering. The current stroke pointer points to one of the stroke group objects. When the device pipeline receives a request to render a multipolyline, it gets the pointer to the current stroke group using the Context interface getCurrentStroke():
cur_stroke = ctx->getCurrentStroke()

The pipeline can then get the attribute values for the attributes from the current stroke group. For example, to get the current value for color, the pipeline calls the stroke group's getColor() interface:
cur_stroke->getColor()

From within curves (for example, li1MultiArc()), the pipeline can use
ctx->getLinePattern() or
ctx->getCurrentStroke()->getPattern(). See Chapter 5, "Handling

Changes to Object State" for more information on getting attribute information through the stroke group.

Non-API Interfaces Provided in API Objects

The API attributes are documented in the XGL Reference Manual; therefore, the interfaces the pipeline can use to retrieve API attribute values are not documented here. However, the device-independent classes provide internal methods to support the pipeline, and these methods are briefly described in this chapter.

Context Interfaces

Imported image(30x36)

See Context.h for the get...() interfaces you can use to retrieve state values from the Context. The XglContext class provides the following internal interfaces.
const Xgli_surf_face_attr*
        const getSurfFrontFaceAttr() const
const Xgli_surf_attr_2d* const getSurfAttr() const
  Functions that enable the pipeline to get general surface attributes within a
  single structure. These functions can facilitate device pipeline manipulation
  of surface attributes. See Context.h for the structure definitions.

Xgl_render_mode getRealRenderBuffer() const
  This function takes into account the number of buffers allocated (in the case
  of the Window Raster) and if the Z-buffer is enabled, determines which
  buffers the pipeline should render into.

Xgl_usgn32 getRealPlaneMask() const
  The real plane mask is the XGL_CTX_PLANE_MASK diminished by the bits,
  which should not be touched in relation to the X color map.

Xgl_usgn32 getNewFramePlaneMask()
  Since the real plane mask prevents regular rendering from changing the bits
  that XGL does not own in the X pixels, new frame must prepare those bits
  (in other words, write them once per frame).

void
addPickToBuffer(Xgl_usgn32 pick_id1, Xgl_usgn32 pick_id2)

Adds a pick event to the device-independent pick buffer.
Xgl_boolean checkLastPick() const

  Compares the last recorded pick IDs with the current pick IDs. Returns
  TRUE if identical.

Xgl_attribute* getAttrTypeListAll() const

Returns a list of all 2D and 3D Context attributes.
virtual void receive(XglObject* obj, const XglMsg& msg)

Used by XGL core only.

Context 2D Interfaces

Imported image(30x36)

See Context2d.h for the get...() interfaces you can use to retrieve state values from the Context2d class.The XglContext2D class includes the following internal interfaces:
const XglStrokeGroup*  getCurrentStroke() const
  Returns a pointer to the current stroke group.

XglDpCtx2d* getDp() {return dp;}

Used by XGL core only.
XglSwpCtx2d* getSwp() const

Used by XGL core only.
void assignCurStrokeAsLine()
void assignCurStrokeAsText()
void assignCurStrokeAsEdge()
void assignCurStrokeAsMarker()
void assignCurStrokeAsSurfFront()

Sets the Context current stroke pointer to the requested stroke group. For example, assignCurStrokeAsLine() causes the Context current stroke pointer to point to the line stroke group.
XglViewGrp2dItf* getViewGrp() const

Used by XGL core only. The pipeline should not use this function but should use instead the pointer to its own view group interface object in its XglDpCtx object.

Context 3D Interfaces

Imported image(30x36)

See Context3d.h for the get...() interfaces you can use to retrieve state values from the 3D Context.The XglContext3d class includes the following internal interfaces:
const Xgli_surf_face_attr_3d* const
        getSurfFrontFaceAttr3d() const
const Xgli_surf_face_attr* const
        getSurfBackFaceAttr() const
const Xgli_surf_face_attr_3d* const
        getSurfBackFaceAttr3d() const
const Xgli_surf_attr_3d* const getSurfFrontAttr3d() const
const Xgli_surf_attr_3d* const getSurfBackAttr3d() const

Functions that allow the pipeline to get a number of 3D surface attributes within a single structure. These functions can facilitate device pipeline manipulation of 3D surface attributes. At LI-2, face determination has already taken place. A pipeline can set up the surface attribute pointer based on the facing in the renderer and do all the attribute processing without referring to the actual facing. See Context3d.h for the structure definitions.
const XglStrokeGroup3d*  getCurrentStroke() const
  Returns a pointer to the current stroke group.

void assignCurStrokeAsLine()
void assignCurStrokeAsText()
void assignCurStrokeAsEdge()
void assignCurStrokeAsMarker()
void assignCurStrokeAsSurfFront()
void assignCurStrokeAsSurfBack()

Points the Context current stroke pointer to the requested stroke group. For example, assignCurStrokeAsLine() causes the Context current stroke pointer to point to the line stroke group.
Xgl_boolean getFrontTexturing() const

Returns an Xgl_boolean value, which is TRUE if the color type is RGB, if front fill style is other than hollow or empty, and there is at least one active front Data Map Texture object in the Context.
Xgl_boolean getBackTexturing() const

Returns an Xgl_boolean value, which is TRUE if the color type is RGB, if back fill style is other than hollow or empty, and there is at least one active back Data Map Texture object in the Context.
Xgl_boolean getTlistEdgeFlag() const

If NURBS edge flags are on and the device pipeline calls the software pipeline to render a NURBS surface, the software pipeline calls the device pipeline li1QuadrilateralMesh() or li1TriangleStrip(). The software pipeline uses ctx->setTlistEdgeFlag() to inform the pipeline primitives whether they should show the edges of tesselated triangle lists. The functions li1QuadrilateralMesh() or li1TriangleStrip() can access tlistEdgeFlag by calling ctx->getTlistEdgeFlag(). The default value is FALSE.
virtual void receive(XglObject* obj, const XglMsg& msg)

Used by XGL core only.

Data Map Texture Interfaces

Imported image(30x36)

See DmapTexture.h for the get...() interfaces you can use to retrieve state values from the Data Map Texture object.The XglDmapTexture class includes the following internal functions:
Xgl_texture_desc* const* getDescriptors() const

  Returns a pointer to the texture descriptors (that are read-only) in a Data
  Map Texture object. This is similar to the function
  getDescriptors(Xgl_texture_desc[]), except that in this case the
  device pipeline has to allocate space for the texture descriptors and a copy
  of the texture descriptors is returned as opposed to a pointer.

virtual void receive(XglObject* obj, const XglMsg& msg)

Used by XGL core only.

Device Interfaces

Imported image(30x36)

See Device.h for the get...() interfaces you can use to retrieve state values from the Device object. The XglDevice class includes the following internal functions.
Xgl_vdc_orientation getDcOrientation() const

  Used by XGL core only.

XglDpDev* getDpDev() const

Returns a pointer to the XglDpDev object.
XglDrawable* getDrawable() const

Returns the drawable associated with the Device.
float getGammaValue() const
  Returns the gamma value of the device needed by the software pipeline to
  implement gamma correction for antialiased stroke primitives.

float* getGammaPowerTable() const

Returns a pointer to the gammaPowerTable. The ith entry of the table is the value i/255.0 raised to the power of the gamma value. The size of the table is 256 entries.
float* getGammaInversePowerTable() const

Returns a pointer to the gammaInversePower Table. The ith entry of the table is the value i/255.0 raised to the power of the reciprocal of the gamma value. The size of the table is 256 entries.

Light Interfaces

Imported image(30x36)

See Light.h for the get...() interfaces you can use to retrieve state values from the Light object. The XglLight class includes the following internal functions:
const Xgl_pt_f3d& getNegDirection() const

For lights of type directional (XGL_LIGHT_DIRECTIONAL) and spot (XGL_LIGHT_SPOT), this function returns the vector opposite to the direction of propagation for directional lights, or opposite to the light ray on the central axis for spot lights, in other words, the negative of XGL_LIGHT_DIRECTIONAL, or pointing toward the light source.
float getCosAngle2() const

For lights of type XGL_LIGHT_SPOT, this function returns the cosine of half the spot angle, in other words, the angle between the central axis of the spot light and any ray at the boundary of the cone of illumination.

Line Pattern Interfaces

Imported image(30x36)

See LinePattern.h for the get...() interfaces you can use to retrieve state values from the Line Pattern object. The XglLinePattern class includes the following internal functions.

Note - In most cases, you will get to Line Pattern data via the stroke group. For example, use ctx->getCurrentStroke()->getPattern().

void getActualData (float*) const

  Copies the actual line pattern data. The actual data differs from the API data
  in that it is always float, and it includes the odd-length processing.

const float* getActualData() const

Returns a pointer to the actual line pattern data, including the odd-length processing.
Xgl_usgn32 getActualDataSize() const

Returns the size of the actual line pattern data.
float getActualOffset() const

  Returns the offset in the actual line pattern data.

float getLength() const

Returns the total length of the line pattern in actual data.
Xgl_usgn32 getStartSeg() const

Returns the segment in actual data where the offset is.
float getStartSegRemain() const

Returns the remaining length in the segment in actual data at the offset location.

Marker Interfaces

Imported image(30x36)

See Marker.h for the get...() interfaces you can use to retrieve state values from the Marker object. The XglMarker class includes the following internal function:
const XglPrimData* getActualDescription() const

Returns a pointer to the XglPrimData description of the marker.

MipMap Texture Interfaces

Imported image(30x36)

See MipMapTexture.h for the get...() interfaces you can use to retrieve state values from the MipMap Texture object. The XglMipMapTexture class includes the following internal function:
Xgl_usgn8 getElement(Xgl_usgn32 level,Xgl_usgn32
                    channel_num,Xgl_usgn32 x,Xgl_usgn32 y)

Returns the contents of the channel channel_num at position (x,y) from the level level in the MipMap.

Raster Interfaces

Imported image(30x36)

See Raster.h for the get...() interfaces you can use to retrieve state values from the Raster object. The XglRaster class includes the following internal interfaces:
void setDoPixelMapping (Xgl_boolean b)

  Used by the Memory Raster device pipeline only. Differentiates between a
  "real" Memory Raster device (b is FALSE) and a backing store Memory
  Raster (b is TRUE).

Xgl_boolean getDoPixelMapping() const

Used by RefDpCtx, a Memory Raster, and the software pipeline to determine if DoPixelMapping has been set.

Texture Map Interfaces

Imported image(30x36)

See Tmap.h for the get...() interfaces you can use to retrieve state values from the Texture Map object.The XglTmap class includes the following internal functions:
Xgl_texture_general_desc* const* getDescriptors() const

  Returns a pointer to the texture descriptors (that are read-only) in a Texture
  Map object. This is similar to the function
  getDescriptors(Xgl_texture_general_desc[]), except that in this
  case the device pipeline has to allocate space for the texture descriptors and
  a copy of the texture descriptors is returned as opposed to a pointer.

virtual void receive(XglObject* obj, const XglMsg& msg)

Used by XGL core only.

Window Raster Interfaces

Imported image(30x36)

See RasterWin.h for the get...() interfaces you can use to retrieve state values from the Window Raster object. The XglRasterWin class includes the following internal functions:
void setDgaCmapPutFunc(void(*PutFunc)(Dga_cmap dga_cmap,
                    int inden, int count, u_char* red,
                    u_char* green, u_char* blue)

Provided by the XGL core so that a device pipeline can register a callback function to update the hardware color map. For more information on PutFunc, see the documentation for dga_cm_write() in the OpenWindows Server Device Developer's Guide.
XglPixRectMem* getSwZBuffer() const

Returns a pointer to the XglPixRectMem object that represents the software Z-buffer.
XglPixRectMem* getSwAccumBuffer() const

  Returns a pointer to the XglPixRectMem object that represents the software
  accumulation buffer.

virtual void receive(XglObject* obj, const XglMsg& msg)

Used by XGL core only.

Memory Raster Interfaces

Imported image(30x36)

See RasterMem.h for the get...() interfaces you can use to retrieve state values from the Memory Raster object. The XglRasterMem class provides the following internal functions:
XglPixRectMem* getImageBufferPixRect() const

  Returns a pointer to the XglPixRectMem object that represents the image
  buffer for the memory raster.

XglPixRectMem* getZBufferPixRect() const

Returns a pointer to the XglPixRectMem object that represents the Z-buffer for the memory raster.
XglPixRectMem* getAccumBufferPixRect() const

  Returns a pointer to the XglPixRectMem object that represents the
  accumulation buffer for the memory raster.

Xgl_usgn32 getImgBufLineBytes() const
  Gets the value for linebytes for the image buffer when the memory raster
  is set up to access memory for retained windows. linebytes is the number
  of bytes that separates one line in a raster, in other words, the number of
  bytes from (x,y) to (x,y+1).

void syncRtnDevice(XglRasterWin*)

Used by the XGL core only.
virtual void receive(XglObject* obj, const XglMsg& msg)

Used by XGL core only.

Stroke Font Interfaces

Imported image(30x36)

See Sfont.h for the get...() interfaces you can use to retrieve state values from the Stroke Font object. The XglSfont class includes the following internal functions:
Xgl_boolean getIsFontLoaded() const

Returns a Boolean value that indicates whether the font file is actually loaded.
Xgl_sfont_data* getSfontData()

  Loads the font file and returns a pointer to the data.

Sfont_inst* getSfontInst()

Returns a pointer to the actual strokes that define an entire font.

Transform Interfaces and Flags

Transform Flag

The Transform object maintains a member datum called flag that contains internal information for the XglTransform class. The pipeline can get the flag information by calling the getFlag() function. The flag consists of the values in the enumerated type Xgli_trans_flag. Most of the flag bits are used to keep track of the state of the Transform, but two of the bits, XGLI_TRANS_SINGULAR and XGLI_TRANS_INVERSE_VALID, may be of use to the device pipeline.
If the XGLI_TRANS_SINGULAR bit is set, this indicates that the matrix is singular and that the application, the XGL core, or the device pipeline has attempted to invert it. However, if the bit is not set, this does not necessarily mean that the matrix is nonsingular but may simply mean there has not been an attempt to take the inverse of the matrix. The XGLI_TRANS_INVERSE_VALID bit works similarly. Table 6-2 shows the relationship between these two bits and what the bit settings mean.
Table 6-2
SINGULARINVERSE VALIDMeaning
0
0The inverse of the matrix has not been taken, so information on its singularity is not available.
1
0Singular matrix.
0
1Nonsingular matrix.
1
1Not possible.

Transform Member Records

The Transform member datum memberRecord defines the matrix groups to which a matrix is a member. If the application has specified the membership of a matrix to a matrix group with xgl_transform_write_specific() or the application constructs its Transforms with XGL's transform utilities, such as xgl_transform_scale(), the device pipeline can use the
getMemberRecord() function to determine which groups the matrix belongs to and take advantage of that information to speed up the processing of transformations.
The member datum memberRecord holds combinations of the macros XGL_TRANS_GROUP_xx defined in xgl.h. The groups are:
/* Transform groups */
typedef         Xgl_usgn32                      Xgl_trans_group;
#define XGL_TRANS_GROUP_IDENTITY                0x001
#define XGL_TRANS_GROUP_TRANSLATION             0x002
#define XGL_TRANS_GROUP_SCALE                   0x004
#define XGL_TRANS_GROUP_ROTATION                0x008
#define XGL_TRANS_GROUP_WINDOW                  0x010
#define XGL_TRANS_GROUP_SHEAR_SCALE             0x020
#define XGL_TRANS_GROUP_LENGTH_PRESERV          0x040
#define XGL_TRANS_GROUP_ANGLE_PRESERV           0x080
#define XGL_TRANS_GROUP_AFFINE                  0x100
#define XGL_TRANS_GROUP_LIM_PERSPECTIVE 0x200

Each group has special properties. XGL takes advantage of these for more efficient operations, including inversion and multiplication of two matrices, multiplication of a matrix by points, and multiplication of a matrix by normal vectors. The device pipeline can use the groups to classify a matrix in order to apply optimized operations during rendering.
Applications can specify the member record using the Transform operator xgl_transform_write_specific() to write a matrix into a Transform. This operator takes a parameter of type Xgl_trans_member, which is defined in xgl.h and which specifies the groups the matrix belongs to. In addition, XGL maintains the member record when applications use XGL's utilities for constructing Transforms. If applications use their own utilities for constructing matrices, and they do not specify the member record when they write a matrix into a Transform, the member record is not maintained because analyzing the matrix is time-consuming. For information on the member groups, see the XGL Reference Manual page on xgl_transform_write_specific().
The device pipeline can test the member flags by calling the getMemberRecord() function of the Transform object, as in the following pseudocode example. Note that in this example, the application has not supplied the w value.

  Xgl_trans_group           group = transform->getMemberRecord();  
  const Xgl_matrix_f3d*mat = (const Xgl_matrix_f3d*)  
                         transform->getMatrixFloat();  
  
  if (group & XGL_TRANS_GROUP_IDENTITY) {  
  // identity  
         x1 = x ; y1 = y ; z1 = z ; w1 = 1 ;  
       }  
  else if (group & XGL_TRANS_GROUP_TRANSLATION) {  
  // translation  
         x1 = x + (*mat)[3][0] ;  
         y1 = y + (*mat)[3][2] ;  
         z1 = z + (*mat)[3][2]; w1 = 1 ;  
  }  

It is the device pipeline's responsibility to check the membership record from the Transform object. Derived data calculates the correct matrix, but a device pipeline may or may not be able to use that matrix in certain circumstances. The device pipeline can take advantage of knowing that certain flag bits are set.
Example: Checking a Member Record for Identity One example of using a member record is to determine whether a transform is identity, as shown in this code sample:
const XglTransform* mc_to_cc = viewGrpItf->getMcToCc();

if (mc_to_cc->getMemberRecord() & XGL_TRANS_GROUP_IDENTITY) {
        // transform is identity
}
else {
        // transform is not identity
}

Example: Checking a Member Record to Do Lighting A device may implement lighting in Model Coordinates (MC) for improved performance over World Coordinates (WC) and Lighting Coordinates (LC) because the normal vectors do not need to be transformed to do lighting in MC (see Chapter 7, "View Model Derived Data" for a description of coordinate systems). Lighting can be performed correctly in MC only if the Model Transform preserves angles. The reason is that lighting is specified in WC in the conceptual view model so lighting must be performed in a coordinate system related to WC by an angle-preserving matrix; otherwise, the dot products in lighting calculations do not equal those in WC. You must check the member record of the Model Transform as discussed below before you attempt to perform lighting calculations in Model Coordinates.
The membership record of the Model Transform can give additional information relevant to lighting calculations. The Model Transform may have the following properties:
  1. Length-preserving

  2. Angle-preserving

  3. Affine with anisotropic scaling

  4. Perspective

  5. Singular

The order of these properties for lighting is from easiest to hardest, which is the sequence that you should apply to testing the Model Transform. The testing needs to be performed at least once whenever the Model Transform changes. The view group interface can assist detection of these changes; see Chapter 7, "View Model Derived Data" for information on the view group interface.
When the Model Transform preserves lengths (and angles), you can perform lighting in MC. However, if the device always performs lighting in WC or LC, then the device would transform normal vectors as column vectors by the 3.3 upper-left submatrix of the WC-to-MC or LC-to-MC Transform respectively. Lighting calculations generally require unit length vectors, so XGL requires applications to supply unit length normal vectors in MC. If the Model Transform preserves lengths, then the normal vectors in WC and LC have unit length, so you do not have to readjust their lengths after transformation. To
determine whether the Model Transform preserves lengths, you can check the membership record to see if the XGL_TRANS_GROUP_LENGTH_PRESERV bit is set.
When the Model Transform preserves angles, you can perform lighting in MC. However, if the device always performs lighting in WC or LC, you can transform normal vectors the same way as for the length-preserving case. Unit normal vectors in MC transformed in this manner by an angle-preserving matrix always have the same length after transformation. This length is the isotropic scale factor, which can be obtained with getIsotropicScale(). If you need a unit vector after transformation by an angle-preserving matrix, just divide the transformed vector by the isotropic scale factor. If you have several vectors that you want to transform by an angle-preserving matrix and you need unit length vectors after the transformation, then you can divide all the elements of the matrix by the isotropic scale factor, and the unit length vectors transformed by this matrix will yield unit length vectors. This saves you from dividing all the vectors by the isotropic scale factor. To determine whether the Model Transform preserves angles, you can check the membership record to see if the XGL_TRANS_GROUP_ANGLE_PRESERV bit is set.
When the Model Transform is affine and does not preserve angles, you must perform lighting in WC or LC. In this case, the Model Transform scales geometry anisotropically, and the amount of scaling depends on the direction. After transforming a unit vector by an affine matrix with anisotropic scaling, you need to calculate the length of the transformed vector and divide the vector by its length. Calculation of the length usually requires a square root, but a lookup table may be faster and accurate enough. To determine whether the Model Transform is affine and does not preserve angles, you can check the membership record to see if the XGL_TRANS_GROUP_AFFINE bit is set after checking that the XGL_TRANS_GROUP_ANGLE_PRESERV bit is not set.
When a Model Transform has perspective, lighting calculations are correct only in WC or LC. The calculation of transformed normal vectors is difficult, and most applications do not use Model Transforms with perspective. You can assume that this situation never occurs. If it does occur, treat it as if the Model Transform is affine with anisotropic scaling. XGL has the limitation that the Model Transform cannot have perspective.
When a Model Transform is singular, lighting calculations cannot be performed except for ambient lighting. In MC, the light positions and eye position or vector cannot be calculated. In WC or LC, the normal vectors cannot be
calculated uniquely. Therefore, you should only do ambient lighting. To determine whether the Model Transform is singular, get its flag as described on page 137.

Transform Internal Interfaces

Imported image(30x36)

See Transform.h for the get...() interfaces you can use to retrieve state values from the Transform object. The XglTransform class includes the following internal functions.

Note - The pipeline can access transforms and view group attributes via the Context object if the pipeline never falls back on the software pipeline. If the device pipeline never uses the software pipeline, it can access the Local Model Transform using XglTransform* mt = ctx->getModelTrans(). Even in this case, however, it is a good idea for pipelines to use derived data so that they work consistently with other pipelines. So the preferred way to access the Local Model Transform is to use derived data, as in mt = (XglTransform*) viewGrpItf->getMcToWc(). Then, to get to the interfaces for the Transform, use mt->getxx.

Xgli_trans_flags getFlag()

  Returns the transform flag described on page 137.

Xgl_trans_group getMemberRecord()

Returns a word containing the matrix groups. See page 137 for information on the internal flag memberRecord and see the xgl_transform_write_specific() man page for information on the member groups.
const float* getMatrixFloat()

Returns a floating-point representation of a single-precision matrix. Note that when an application uses xgl_transform_write_specific() to write a matrix, it passes a pointer to a matrix type defined in xgl.h. However, the internal matrix types defined in Transform.h are the actual representations of the matrix data that the application will get. Although the API documentation states that 2D matrices are 3.2 and in xgl.h the matrix
type Xgl_matrix_f2d is defined as a float 3.2 matrix, internally the 2D matrices are 3.3 matrices of type Xgli_matrix_i3x3, Xgli_matrix_f3x3, or Xgli_matrix_d3x3.
Note that XGL does calculations in double-precision format and only converts to single-precision format when the application or pipeline requests it by calling getMatrixFloat().
const float* getMatrix()

  Equivalent to getMatrixFloat(); however, getMatrixFloat() is the
  recommended version.

const double* getMatrixDouble()

Returns a double-precision matrix.
const Xgl_sgn32* getMatrixInt()

Returns a 32-bit integer version of the matrix.
double getIsotropicScale()
  Returns a value that indicates how much scaling the matrix does when it
  scales isotropically. This is valid only when the
  XGL_TRANS_GROUP_ANGLE_PRESERV bit is set in the member record.

double getNorm()

Returns the mathematical norm of a matrix.
double getNormInverse()

Returns the reciprocal of the norm of a matrix.
copyConvert()

Used internally by getMatrixInt().
void transPt(const Xgli_pt*, Xgli_pt*)

Transforms a single point of type Xgli_pt (defined in Transform.h) and stores it in a different block of memory. This is different than the API xgl_transform_point() function, which transforms a point and overwrites the original block of memory.
void transPtList(const Xgli_pt_list*, Xgli_pt_list*)
  Transforms a point list of type Xgli_pt_list (defined in Transform.h) and
  stores it in a different block of memory. This is different than the API
  xgl_transform_point_list() function.

void transNormal(const Xgl_pt_f3d* src, xgl_pt_f3d* dest)

Transforms a normal of type Xgl_pt_f3d and returns a normal of the same type.
void
transUnitNormal(const Xgl_pt_f3d* src, Xgl_pt_f3d* dest)
  Transforms a unit normal of type Xgl_pt_f3d and returns a unit normal of
  the same type.

void
transUnitNormalDouble(const Xgl_pt_d3d* src,
                                Xgl_pt_d3d* dest)

Transforms a unit normal of type Xgl_pt_d3d and returns a unit normal of the same type.

Getting Information From the Device Object

The device pipeline may need to get information from the device-independent Device object, from the Drawable associated with the Device, or from a Color Map object that the application has associated with the Device. Pointers to the Device object are available as follows:
  • The XglDpDev object has a member data device that holds a pointer to the device-independent Device object. Note that device already points to a Device of the right type. In other words, in an XglDpDevWinRas object, device is already XglRasterWin*, in an XglDpDevMemRas object, device is already XglRasterMem*, and in an XglDpDevStream object, device is already XglStream*.
  • The XglDpCtx object has a member data device that holds a pointer to the device-independent Device object.
A pointer to the Drawable object is available in the XglDpCtx object. Your pipeline XglDpCtx can use the drawable pointer rather than using getDevice()->getDrawable(). Note that the device and drawable pointers are fixed at XglDpDev creation and do not change for the life of the XglDpDev object.
To get a handle to the Color Map object, use the inline function getCmap(), as in device->getCmap(). The getCmap() function is defined in Device.h.
If you frequently use some object pointers (or even data itself), you can cache the object pointers, provided that you use the objectSet() function correctly to stay synchronized with Context state changes. A good example of this is caching a pointer to the color map object. If you think frequent use of device->getCmap() is too time consuming, save the return value in a member data of your own XglDpCtx.

Color Map Interfaces

Because the Color Map object is set on the Device, its interfaces are available through the Device object. With a handle to the Color Map object, the pipeline can access the Color Map's interfaces as follows:
device->getCmap()->getColorMapper()

Note that the application can change the color map by setting a new Color Map object on the Device or by changing an existing color map. The pipeline is notified of color map changes by the message passing mechanism (see page 99) and by a direct dpDev->setCmap(cmap) call from the Context to the pipeline XglDpDev object (see page 54). Although the color map can change during program execution, applications are not allowed to change the device's color type after the device has been created.

Imported image(30x36)

See Cmap.h for the get...() interfaces you can use to retrieve state values from the Color Map object. The XglCmap class includes the following internal functions.
Xgl_usgn32 getPlaneMaskMask() const

  Returns an Xgl_usgn32 value in which the bits set indicate the knowledge
  XGL has of the bits where rendering is allowed, with regard to the XGL and
  X colormaps.

Xgl_color* getColorTable() const

This function returns a pointer to the first color of the color table.
XglCmapDrawable* getCmapDrawable() const

Used by XGL core only.
Xgl_usgn32 lookUpDitherValue(Xgl_usgn32, Xgl_usgn32)

Returns the dither matrix value at the given position.
Xgl_sgn32 lookUpInternalDitherValue(Xgl_usgn32, Xgl_usgn32)

Returns the value of the internal dither matrix at the given position. The internal dither matrix is the transpose of the regular dither matrix in "fract24" (s7.24) format, and it is divided by 255 (so the renderer need not divide). The internal dither matrix is valid only when the dither matrix is 8.8. It is the transpose of the regular matrix to allow scanline access.
Xgl_sgn32*
lookUpInternalDitherAddress(Xgl_usgn32, Xgl_usgn32)

Returns the address of the value of the internal dither matrix at the given position.
Xgl_boolean getMapperHasBeenSet() const

  Indicates whether color mapper has been set. Used by the XGL core only.

Xgl_boolean getInverseMapperHasBeenSet() const

Indicates whether the inverse color mapper has been set. Used by the XGL core only.