Glide 2.2 Programming Guide

Programming the 3Dfx Interactive Glide Rasterization Library 2.2



Document Release 014

08 March 1997

Copyright ã 1995-1997 3Dfx Interactive, Inc. All Rights Reserved



3Dfx Interactive, Inc.

4435 Fortran Avenue

San Jose, CA 94134



Trademarks

Glide, TexUS, Pixelfx and Texelfx are trademarks of 3Dfx Interactive, Inc.

OpenGL is a trademark of Silicon Graphics, Inc.

Autodesk CDK is a trademark of Autodesk, Inc.

MS-DOS and Win32 are trademarks of Microsoft, Inc.

Other product names are trademarks of the respective holders.




Copyright © 1995-1997 by 3Dfx Interactive, Inc.


All rights reserved. No part of this publication may be reproduced, stored in a retrieval system, or transmitted, in any form or by any means, without prior written consent.


Table of Contents

Table of Contents

List of Figures

List of Tables

List of Examples

Chapter One An Introduction to Glide

Why Glide?

Voodoo Graphics

The Rendering Engine

About This Manual

Other Documentation

Chapter Two Glide in Style

In this Chapter

Naming and Notational Conventions

The State Machine Model

Specifying Vertices

Numerical Data

Chapter Three Getting Started

In This Chapter

Starting Up

Driving Multiple Systems

Shutting Down

The Display Buffer

Masking Writes to the Frame Buffer

Swapping Buffers

Clearing Buffers

Error Handling

Chapter Four Rendering Primitives

In This Chapter

The GrVertex Structure

Clipping

Triangles

Points

Lines

Convex Polygons

Backface Culling

Anti-aliasing

Chapter Five Color and Lighting

In This Chapter

Specifying Colors

Dithering

The Color Combine Unit

Gamma Correction

Chapter Six Using the Alpha Component

In This Chapter

Specifying Alpha

The Alpha Combine Unit

Alpha Buffering

Alpha Blending

Chapter Seven Depth Buffering

In This Chapter

Enabling Depth Buffering

The Depth Test

Fixed Point z buffering

Floating Point w buffering

Establishing a Depth Bias

An Example: Hidden Surface Removal

Chapter Eight Special Effects

In This Chapter

Fog

Chroma-keying

Alpha Testing

Stenciling

Chapter Nine Texture Mapping

In This Chapter

A Look at Texture Mapping and Glide

Glide Textures and Texels

Texel Coordinate Systems

Texture Filtering

Texture Clamping

Mipmapping

Mipmap Blending

Trilinear Filtering

LOD Bias

Combining Textures

Examples of Configuring the Texture Pipeline

Chapter Ten Managing Texture Memory

In This Chapter

Texture Map Formats

Narrow Channel Compression

The Color Palette (not implemented in TMU Revision 0)

Texture Memory

Computing the Size of a Mipmap

Querying for Available Memory

Downloading Mipmaps

Identifying a Mipmap as the Texel Source

Loading a Mipmap into Fragmented Memory

Downloading a Decompression Table or Color Palette

Loading Mipmaps From Disk

Chapter Eleven Accessing the Linear Frame Buffer

In This Chapter

Acquiring an LFB Read or Write Pointer

Calculating a Pixel Address

Reading from the LFB

Writing to the LFB

Setting LFB Write Parameters

Special Effects and Linear Frame Buffer Writes

Writing a Rectangle of Pixels into the LFB

Chapter Twelve Housekeeping Routines

In This Chapter

Retrieving Configuration Information

Checking System Status

Utilizing Two Displays

Monitoring System Performance

Chapter Thirteen Glide Utilities

In This Chapter

A Higher Level Color Combine Function

A Higher Level Alpha Combine Function

A Higher Level Texture Combine Function

Allocating Texture Memory

Downloading Textures

Chapter Fourteen Programming Tips and Techniques

In This Chapter

Floating Point Vertex Snapping and Area Calculations

Avoiding Redundant State Setting

Avoiding Screen Clears by Rendering Background Polygons

Using LOD Bias To Control Texture Aliasing

Linear z Buffering and Coordinate System Ranges

State Coherency and Contention Between Processes

Appendix A A Sample Program

Appendix B Glide State Constants

Glossary

Index


List of Figures


Figure 1.2 The pixel pipeline.

Figure 3.1 Locating the origin.

Figure 3.2 Logical layout of the linear frame buffer.

Figure 4.1 Specifying a clipping window.

Figure 4.2 Pixel rendering.

Figure 4.3 Polygons.

Figure 4.4 Polygon orientation and the sign of the area.

Figure 4.5 Aliased and anti-aliased lines.

Figure 4.6 Pixel coverage and lines.

Figure 9.1 TMU connectivity.

Figure 9.2 Point sampled and bilinear filtering.

Figure 9.3 Texture clamping.

Figure 9.4 Mipmaps.

Figure 10.1 The color palette.

Figure 10.2 The size of a mipmap depends on the setting of the evenOdd flag.

Figure 10.3 Downloading a mipmap.

Figure 10.4 Replacing a single LOD.

Figure 10.5 Replacing a few rows of an LOD.

Figure 11.1 Reading from and writing to the LFB.

Figure 11.2 Frame buffer writes: encoding the location of the origin as the sign of the strideInBytes.

Figure 12.1 The Voodoo Graphics status register.



List of Tables


Table 3.1 Frame buffer color formats.

Table 3.2 Frame buffer resolution and configuration.

Table 4.1 The location of the origin affects triangle orientation and the sign of its area.

Table 5.1 Configuring the color combine unit.

Table 5.2 The color combine function scale factor.

Table 5.3 Choosing local and other colors for the color combine unit.

Table 5.4 Overriding the local color when the high order bit of atexture is set.

Table 6.1 Combining functions for alpha.

Table 6.2 Scale factors for the alpha combine function.

Table 6.3 Specifying local and other alpha values.

Table 6.4 Alpha blending factors.

Table 7.1 The depth test.

Table 8.1 Alpha test functions.

Table 9.1 The stw hints.

Table 9.2 Mapping pixels to texture coordinates in texture maps.

Table 9.3 Texture sizes and shapes.

Table 9.4 Texture combine functions.

Table 9.5 Scale factors for texture color generation.

Table 9.6 The number of TMUs affects texture mapping functionality.

Table 10.1 Texture formats.

Table 10.2 Glide constants that specify arguments to grTex functions.

Table 11.1 Interpreting data read from the LFB.

Table 11.2 16-bit LFB data formats.

Table 11.3 32-bit LFB data formats.

Table 11.4 Color, alpha, and depth sources.

Table 11.5 Source data formats for the grLfbWriteRegion() routine.

Table 13.1 Color combine functions.

Table 13.2 Alpha combine unit modes.

Table 13.3 Texture combine functions.



List of Examples


Example 3.2 Setting a state variable in all Voodoo Graphics subsystems.

Example 3.3 A minimal Glide program.

Example 4.1 A thousand points of light.

Example 4.2 Drawing an anti-aliased triangle.

Example 5.1 Drawing a constant color triangle.

Example 5.2 Drawing a flat shaded triangle.

Example 5.3 Drawing a smooth shaded triangle.

Example 5.4 Drawing a flat-shaded textured triangle.

Example 5.5 Drawing a smooth-shaded textured triangle.

Example 5.6 Drawing a smooth shaded triangle with specular lighting.

Example 5.7 Drawing a smooth shaded textured triangle with specular highlights.

Example 5.8 Drawing a smooth shaded triangle with monochrome diffuse and colored specular lighting.

Example 6.1 Blending two images.

Example 6.2 Blending two images, part II.

Example 6.3 A compositing example.

Example 7.1 Configuring a z buffer.

Example 7.2 Configuring a w buffer.

Example 7.3 Using a depth bias.

Example 7.4 Hidden surface removal using a z buffer.

Example 8.1 Fogging with iterated alpha.

Example 8.2 Creating a fog table.

Example 8.3 Fogging with 1/w and a fog table.

Example 8.4 Simulating a blue-screen with chroma-keying.

Example 9.1 Setting up simple (decal) texture mapping.

Example 9.2 Applying a modulated (projected) texture.

Example 9.3 Using trilinear filtering: mipmap blending with bilinear filtering.

Example 9.4 Creating a composite texture.

Example 10.1 Will the mipmap fit?

Example 10.2 Setting up to load several mipmaps.

Example 10.3 Downloading a texture for decal texture mapping.

Example 10.4 Downloading two textures for modulated or composite texture mapping.

Example 10.5 Splitting a texture across two TMUs for trilinear mipmapping.

Example 10.6 Using multiple texture base registers.

Example 10.7 Loading an NCC table.

Example 10.8 Loading a color palette.

Example 10.9 Reading a .3DF file.

Example 11.1 Reading a pixel value from the LFB.

Example 11.2 Enabling specific special effects.

Example 11.3 Writing One 565 RGB Pixel to the back buffer (RGB ordering).

Example 11.4 Writing Two 565 RGB Pixels to the back buffer (RGB color ordering).

Example 11.5 Writing One 888 RGB Pixel to the back buffer (ARGB color ordering).

Example 14.1 Snapping coordinates to .0625 resolution.

Example 14.2 Masking off precision control bits on Intel processors.

Example 14.3 A portable way to snap coordinates to .0625 resolution.


An Introduction to Glide

Voodoo Graphics is the first video subsystem that enables personal computers and low cost video game platforms to host true 3D entertainment applications. Optimized for real-time texture-mapped 3D images, the Voodoo Graphics subsystem provides acceleration for advanced 3D features including true-perspective texture mapping with trilinear mipmapping and lighting, detail and projected texture mapping, texture anti-aliasing, and high precision subpixel correction. In addition, it supports general purpose 3D pixel processing functions, including triangle-based Gouraud shading, depth buffering, alpha blending, and dithering.

real-time, true-perspective, texture-mapped rendering with lighting support at low cost

simplified software porting: only the inner rasterization loop is affected

lowest cost solution designed expressly for use in the entertainment markets

patent pending techniques to reduce texture memory requirements

The Glide Rasterization Library is a set of low level rendering functions that serve as a software “micro-layer” to the Voodoo Graphics family of graphics hardware, including the 3Dfx Interactive Texelfx ™ and the Pixelfx™ special purpose chips. Glide perm its easy and efficient implementation of 3D rendering libraries, games, and drivers.

Why Glide?

Glide serves three primary purposes:

It defines an abstraction of the Voodoo Graphics hardware to facilitate ease of software porting.

It acts as a delivery vehicle for sample source code providing in-depth hardware-specific optimizations for the Voodoo Graphics hardware.

By abstracting the low level details of interfacing with the Voodoo Graphics hardware into a set of C-callable functions, Glide allows developers to avoid working with hardware registers and memory directly, enabling faster development and lower probabili ty of bugs. Glide also handles mundane and error prone chores such as initialization and shutdown.

Glide is but one part of the 3Dfx Interactive Software Developer’s Kit (SDK), which is designed to assist developers in creating tools and titles that are optimized for the Voodoo Graphics hardware. Other components of the SDK include the Game Controller I nterface (GCI) Library and the Texture Utility Software (TexUS™).

Glide is not a full featured graphics API such as OpenGL™, PHIGS, or the Autodesk CDK™: it does not provide high level 3D graphics operations such as transformations, display list management, or light source shading. Glide specifically implements only thos e operations that are natively supported by the Voodoo Graphics hardware. In general, Glide does not implement any functions that do not directly access a Voodoo Graphics subsystem’s memory or registers.

The Glide Utility Library contains utility routines create fog tables, extensions that do significant pre-processing before calling Glide routines to access the graphics system, and obsolete routines that are provided for interim compatibility as Glide dev elopment continues.

The Glide library can be linked with an application with or without debugging aids. The debug version has error checking and parameter validation, which may cause performance degradation. When an application is initially developed and debugged it should us e the debugging version of Glide. After development is complete the release build of Glide is employed for optimum performance.

Voodoo Graphics

The Voodoo Graphics subsystem sits on the PCI system bus of the host computer. The entry-level system configuration consists of two 3Dfx Interactive proprietary ASICs, Texelfx and Pixelfx and memory. shows the entry level configuration as well as sever al ways to expand the system and enhance graphics performance. Increasing the number of Texelfx ASICs decreases the number of passes required to perform various texture mapping techniques. Systems with more than one Voodoo Graphics subsystem can utilize s can-line interleaving to achieve the highest possible rendering performance.

Glide and the Voodoo Graphics hardware supports a rich set of rendering techniques, including

Gouraud shading. The programmer provides initial red, green, blue, and alpha values for each vertex; Glide calculates the associated gradients and the hardware automatically iterates the color across the defined triangle.

Texture mapping. The programmer provides initial texture values s/w, t/w, and 1/w for each vertex and Glide computes the gradients. The hardware performs the proper iteration and perspective correction for true-perspective texture mapping. During each ite ration of row/column walking, a division is performed by 1/w to correct for perspective distortion.

Texture mapping with lighting. Texture-mapped rendering can be combined with Gouraud shading to introduce lighting effects during the texture mapping process. The programmer supplies initial color and texture values, Glide calculates the appropriate gra dients, and the hardware performs the proper calculations to implement the lighting models and texture lookups. A texel is either modulated (multiplied by), added, or blended to the Gouraud shaded color. The selection of color modulation or addition is p rogrammable.

Texture space decompression. Texture map compression uses a patent-pending “narrow channel” Yab compression scheme that maps 24-bit RGB values to a 8-bit Yab format with little loss in precision.

Depth buffering. Voodoo Graphics supports hardware accelerated depth buffered rendering with no performance penalty. The depth buffer is implemented in frame buffer memory: 2 Mbyte systems can utilize a 640×480 double buffered display buffer and a 16-bit z buffer. To eliminate many of the z aliasing problems typically encountered with 16-bit z buffer systems, the Voodoo Graphics subsystem allows a floating point representation of the 1/w parameter to be used as the depth component.

Figure 1.1 Voodoo Graphics system configurations.

The Pixelfx chip interfaces with the host computer, the linear frame buffer, and the display monitor, and implements basic 3D primitives including Gouraud shading, alpha blending, depth buffering, dithering, and fog. The TMU (located on the Texelfx chip) implements texture mapping, including true-perspective, detail, and projected texture mapping, bilinear and trilinear filtering, and level-of-detail mipmapping.

(a) The basic configuration has one Pixelfx chip and one TMU. The advanced texture mapping techniques of detail texture mapping, projected texture mapping, and trilinear texture filtering are two-pass operations, but there is no performance penalty fo r point sampled or bilinear filtered texture mapping with mipmapping.

(b) A two TMU configuration allows single pass, full-speed, detail texture mapping, projected texture mapping, or trilinear filtering.

(c) Three TMUs can be chained together to provide single-pass, full-speed rendering of all supported advanced texture mapping features including projected texture mapping.

(d) For the highest possible rendering performance, multiple Voodoo Graphics subsystems can be chained together utilizing scan-line interleaving to effectively double the rendering rate of a single subsystem.




Pixel blending. The hardware supports alpha blending functions that blend incoming source pixels with current destination pixels with no performance penalty. Alpha buffering is supported, but is mutually exclusive with depth buffering and triple buffer ing. Note that alpha buffering is required only if destination alpha is used in alpha blending; alpha blending modes that do not use destination alpha can be used with depth buffering and triple buffering.

Fog. The Voodoo Graphics subsystem supports a 64-entry lookup table to support atmospheric effects such as fog and haze. When enabled, a 14-bit floating point representation of 1/w is used to index into the 64-entry lookup table and interpolate between e ntries. The output of the lookup table is a value that represents the level of blending to be performed between a reference fog color and the incoming pixel.

Chroma-keying. Voodoo Graphics supports a chroma-key operation used for transparent object effects. When enabled, an outgoing pixel is compared with the chroma-key register. If a match is detected, the outgoing pixel is invalidated in the pixel pipeline , and the frame buffer is not updated.

Color dithering: Numeric operations are performed on 24-bit colors within the Voodoo Graphics subsystem. However, the final stage of the pixel pipeline dithers the color from 24 bits to 16 bits before storing it in the display buffer. The 16-bit color d ithering allows for the generation of photo-realistic images without the additional cost of a true color frame buffer storage area.

The Rendering Engine

The Voodoo Graphics hardware has a very flexible lighting and texture mapping pipeline to support all of the features described above. Glide abstracts it into three distinct units: the texture combine unit, the color and alpha combine unit, and the speci al effects unit. The basic architecture is illustrated in .

Figure 1.2 The pixel pipeline.

The rendering engine is structured as a pipeline through which each pixel drawn to the screen must pass. The individual stages of the pixel pipeline modify or invalidate individual pixels based on mode settings. The pixel source is one of four things: a t exture value, an iterated RGBA value, a constant RGBA value, or data for a frame buffer write. Pixels that pass the chroma-key test go to the color combine unit where a user-specified lighting function is applied. The special effects unit further modifies the pixel with alpha and depth testing, fog, and alpha blending operations. The final 24-bit color value is then dithered to 16 bits and written to the frame buffer.


About This Manual

The Glide 2.2 Programming Guide attempts to introduce a knowledgeable graphics programmer to the capabilities of the Voodoo Graphics subsystem through the Glide interface. The subroutines are introduced in a logical progression: initialization and terminat ion requirements are first, then simple rendering capabilities, followed by more and more complex function. The audience for this manual is the application programmer who just took delivery on a Voodoo Graphics subsystem and wants to port existing applicat ions or develop new applications in Glide. The experienced Glide programmer will use the Glide Reference Manual to research specific Glide functions, but will reach for this manual when trying out new features.

Chapter , , describes data types, data formats, and programming model used in Glide and the Voodoo Graphics subsystem.

Chapter , , describes the display buffers and the initialization and termination requirements for Glide and the graphics hardware and includes a very simple but complete program that clears the screen.

Chapter , , describes the functions that draw points, lines, triangles, and convex polygons in both aliased and anti-aliased forms. In addition, clipping and backface culling are discussed.

Chapter , , describes the functions that control the Voodoo Graphics color and alpha combine unit, which can produce effects that run the gamut from simple Gouraud shading to diffuse ambient lighting with specular highlights and other complex lighting mod els.

Chapter , , describes the various ways to utilize the alpha channel: alpha blending, alpha buffering, and alpha testing.

Chapter , , presents the two flavors of depth buffers.

Chapter , , describes other special rendering effects that can be produced in the pixel pipeline: atmospheric effects like fog, haze, and smoke; transparent objects implemented with chroma-keying; stippling; color dithering; alpha masking.

Chapter , , describes the texture pipeline and texture mapping while Chapter 10, Managing Texture Memory, describes the process of downloading textures into texture memory.

Chapter , , describes the Glide functions that provide a path for reading and writing the frame buffer directly.

Chapter , , and Chapter , Glide Utilities, describes the routines in Glide and the Glide Utilities Library that haven’t been discussed already.

Chapter 14, Programming Tips and Techniques, give some hints about how to head off trouble and get the best performance from your Voodoo Graphics hardware.

The Glide Programming Guide concludes with two appendices, one containing a non-trivial example, and the other summarizing the Glide constants used to set state variables. There is also a Glossary of frequently used terms and comprehensive Index.

Other Documentation

Available from 3Dfx Interactive, Inc. :

Glide 2.2 Reference Manual

SST1 Application Notes

TexUS Manual

Additional published references:

FOLE90 Foley, J., A. van Dam, S. Feiner, and J. Hughes, Computer Graphics, Addison-Wesley, Reading, MA, 1990

OPEN92 OpenGL Architecture Review Board, OpenGL Reference Manual, Addison-Wesley, Reading, MA, 1992

OPEN93 OpenGL Architecture Review Board with J. Neider, T. Davis, and M. Woo, OpenGL Programming Guide, Addison-Wesley, Reading, MA, 1992

PHIG88 PHIGS+ Committee, A. van Dam, Chair, “PHIGS+ Functional Description - Revision 3.0”. Computer Graphics, 22(3), p. 125-218

SUTH74 Sutherland, I. E. and G. W. Hodgman, “Reentrant Polygon Clipping”, CACM 17(1), p. 32-42

WATT92 Watt, A. and M. Watt, Advanced Animation and Rendering Techniques: Theory and Practice, Addison-Wesley, Reading, MA, 1992

WILL83 Williams, L., “Pyramidal Parametrics”, SIGGRAPH 83, p. 1-11


Online references:

http://www.3dfx.com

http://www.sgi.com/grafica/texmap/index.html

http://reality.sgi.com/Fun/Free_graphics.html


Glide in Style

In this Chapter

You will learn about:

the naming conventions for functions, types, and constants

the notational conventions that designate functions, types, variables, parameters, and constants in this manual

the state machine model that Glide uses to minimize bandwidth to the hardware and increase graphics performance

the functions that save and restore Glide state

the GrVertex structure that holds the coordinates and parameters that define a vertex

the constraints and properties of numerical data representing geometric, color, and texture coordinates

Naming and Notational Conventions

Functions are divided into families consisting of routines related in their duties. All Glide functions are prefixed with gr; all Glide Utility functions use gu as the prefix. The Glide prefix is immediately followed by the family name, for example grDrawT riangle() and grDrawPolygon() are both parts of the grDraw family. Glide uses the mixed caps convention for function names. When function names appear in the text of this manual, they will be shown in bold face type. Actual function names end with ‘()’; function family names do not.

The internal name for the Voodoo Graphics subsystem is “SST-1”or “SST”. Some function names, type definitions, and constants within Glide reflect this internal name, which is easier to type than Voodoo Graphics. For example, grSstOpen() initializes the ha rdware.

Constants are named values that are defined in glide.h. The names of constants use all uppercase letters, as in MAX_NUM_SST and GR_TEXTUREFILTER_BILINEAR and will be shown in Courier font when they appear in the text of this manual.

C specifications for functions and data types will be displayed in shaded rectangles throughout this manual. Glide type definitions are shown in Helvetica type to distinguish them from the C keywords and primitive types. Glide makes use of enumerated types for function arguments in order to restrict them to the defined set of values. Enumerated types end with _t, as in GrColorFormat_t.

Glide variable names and function arguments will be italicized in both the C specifications and the text.

Code segments use Courier font.

The State Machine Model

Glide is state based: rendering “modes” can be set once and then remain in effect until reset. Parameter values like a reference value for depth comparisons and a specific depth test are set once and will be used whenever depth testing is enabled (until t hey are given new values). The state machine model allows users to set modes and reference values only when they change, minimizing the host-to-hardware transfers.

For example, one of the state variables Glide maintains is the “current mipmap”, used during texture mapping. A mipmap is a collection of hierarchically defined texture maps that are loaded into the texture memory that supports the TMUs. A stateless model would not retain information about the contents of the texture memory, so each rendering operation would have to include a texture memory address.

Sending redundant state information can lead to noticeable performance degradation. For example, if a system is attempting to render 200,000 triangles per second and the “current mipmap” is sent as a 4-byte address, bandwidth associated with updating this single state variable can amount to 800KB/sec. Compound this with all of the other state information necessary and the amount of unnecessary data sent across the system bus can become overwhelming.

Two library functions are used to save and restore state.

void grGlideGetState( GrState *state )


void grGlideSetState( const GrState *state )

grGlideGetState() makes a copy of the current state of the current Voodoo Graphics subsystem in a GrState structure state provided by the user. The saved state can be restored at some later time with grGlideSetState(). These routines save and restore all Glide state, and therefore are expensive to use. If only a small subset of Glide state needs to be saved and restored, these routines should not be used.

Specifying Vertices

Voodoo Graphics is a rendering engine. The user configures the texture and pixel pipelines (see Figure 1.2) and then sends streams of vertices representing points, lines, triangles, and convex polygons. (In fact, the hardware renders only triangles; Glid e converts points and lines to triangles and triangulates polygons as needed.)

Vertices are specified in the GrVertex data structure, shown below and defined in glide.h. Up to ten parameters can be used to specify a point:

the geometric coordinates (x, y, z, w) where x and y indicate a screen location, z indicates depth, and w is the homogeneous coordinate

the color components (r, g, b, a)

the texture coordinates (s, t)

Note that the GrVertex structure has a spot for z, but actually uses its reciprocal (ooz, for “one over z”). Similarly, 1/w is stored in the variable oow. And, s/w and t/w are stored in the structure (as sow and tow) rather than s and t, because the scale d values are the ones actually used by the Voodoo Graphics system. These values need to be computed only once for each vertex, regardless of how many triangles include the vertex.

The GrVertex structure also includes a small array of GrTmuVertex data structures, one for each TMU present in the system, and each of the array elements contains private oow, sow, and tow variables. Each TMU and the Pixelfx chip each have their own copy of 1/w, s/w, and t/w. Normally, they will all be the same. However, projected textures have a different w value than non-projected textures. Projected textures iterate q/w where w is the homogeneous distance from the eye and q is the homogeneous distanc e from the projected source.

typedef struct {

float oow; /* 1/w */

float sow; /* s/w texture coordinate */

float tow; /* t/w texture coordinate */

} GrTmuVertex;

typedef struct {

float x, y, z; /* x, y, z of screen space. z is ignored */

float ooz; /* a linear function of 1/z (used for z buffering) */

float oow; /* 1/w (used for w buffering) */

float r, g, b, a; /* red, green, blue, and alpha ([0..255.0]) */

GrTmuVertex tmuvtx[GLIDE_NUM_TMU];

} GrVertex;

Every vertex must specify values for x and y, but the other parameters are optional and need only be set if the rendering configuration requires them. lists some typical rendering operations and the vertex parameters they use.

Table 2.1 Vertex parameter requirements depend on the rendering function being performed.

The x and y coordinates must be specified for every vertex, regardless of the rendering function being performed. The other parameters stored in the GrVertex structure are optional and need to be supplied only if required for the desired computation. The table below details the values required by the rendering functions implemented by Glide and the Voodoo Graphics hardware.


rendering function

required variables

expected values

see Chapter

all vertices, all rendering functions

x, y

–2048 to +2047

4

Gouraud shading

r, g, b

0 to 255.0

5

alpha blending/testing

a

0 to 255.0

6

non-projected texture mapping

tmuvtx[0].oow, tmuvtx[0].sow, tmuvtx[0].tow

1/w where w is in the range [1..65535]

s/w where s is in the range [0..255.0]

t/w where t is in the range [0..255.0]

9

projected texture mapping

tmuvtx[0].oow, tmuvtx[0].sow, tmuvtx[0].tow


tmuvtx[1].oow, tmuvtx[1].sow, tmuvtx[1].tow

1/w where 1/w is in the range [–4096..61439]

s/w where s/w is in the range [–32768..32767]

t/w where t/w is in the range [–32768..32767]


q/w where q/w is in the range [–4096..61439]

s/w where s/w is in the range [–32768..32767]

t/w where t/w is in the range [–32768..32767]

9

linear z buffering

ooz

1/z where 1/z is in the range [0, 65535]


w buffering

oow

1/w where w is in the range [1..65535]


fog with iterated alpha

a

[0..255.0]

8

fog with iterated z

ooz

1/z where 1/z is in the range [0, 65535]

8

fog with table

oow

1/w where w is in the range [1..65535]

8

Numerical Data

The Voodoo Graphics hardware can accept vertex data in either fixed point or floating point formats. However, Glide provides only a floating point interface, since RISC and Pentium processors are optimized for floating point calculations. If you are portin g a fixed point application to the Voodoo Graphics system, plan to convert all your data to floating point representation as part of the porting process.

The GrVertex structure contains single-precision, IEEE 754 32-bit floating point values.

Geometric Coordinates

The x and y coordinates are specified in pixel units in the range [–2048..2047]. The pixel coordinate (0.5, 0.5) represents the exact center of the first visible pixel on the screen.

The ooz coordinate should be assigned a value that is linear in screen space. That is, it should be a linear function of 1/w that can be scaled and translated such that it increases or decreases with distance from the viewer. The valid range for ooz value s is [0..65535]. To minimize z aliasing this range should be mapped to the smallest possible range of eye coordinates. For example, if w eye coordinates are within the range [2..15] and 1/w is in the range [1/2..1/15] then the mapping would be approximate ly

1/z = 151214.6/w – 10080.9

where w is eye w and ooz is the value iterated in the Voodoo Graphics subsystem.

The w coordinate is a scaled positive depth value used during perspective projection, perspective texture mapping, and depth buffering. Some graphics systems do not use homogeneous coordinates; in these instances the z depth value can be used in lieu of the w coordinate, assuming that the z value is positively increasing into the screen. The range of w is [1..65535].

Glide and Voodoo Graphics actually use the reciprocal of the homogeneous coordinate, 1/w. The valid range for 1/w is [–4096..61439]. Normally, the homogeneous coordinate is clipped to a positive range of [1, far] and so its reciprocal is in the range [1.. 1/far]. Negative values should be avoided.

Each TMU and the Pixelfx chip each have their own 1/w. Normally, the values in all the chips will be the same. However, projected textures have a different w value than non-projected textures. Projected textures iterate q/w where w is the homogeneous di stance from the eye and q is the homogeneous distance from the projected source. In this case, q/w has a valid range of [–-4096..61439].

The 1/w value in Pixelfx is used only for fog calculations and w buffering, and is not used for texture mapping. It can be scaled differently than the 1/w values sent to the TMUs. The fog table spans a range in 1/w from [1/65535..1]. If w buffering i s enabled, the w buffer spans a range in 1/w from [1/65528..1]. Therefore, scale the 1/w value in Pixelfx such that the range [1/65535..1] encompasses all that is interesting in the scene.

Colors

The color components are in the range [0..255] where 0 is black and 255 is maximum intensity. Colors should be clamped to this range.

Glide supports four different color byte orderings: RGBA, ARGB, BGRA, and ABGR. Color byte ordering determines how linear frame buffer writes and color arguments passed to the constant color functions (see Chapter 5) are interpreted. Color ordering is est ablished when Glide and the Voodoo Graphics system are initialized (see Chapter ).

When the terms “RGB” and “RGBA” appear in this manual, they typically refer to any color system that represents red, green, blue, and optionally, alpha, as separate components, regardless of the byte order or component width. The exceptions will be clearly recognizable as discussions about specific color resolution and format.

Texture Coordinates

Glide uses texture coordinates in the range [–32768..32767] and refers to them as (s,t) pairs, similar to the naming convention of OpenGL. A texture contains texels with (s,t) coordinates in the range [0..255.0]; the texture may be replicated many times t o cover a surface by mapping the texture coordinates modulo 256 to a texel in the texture. The Voodoo Graphics subsystem iterates s/w and t/w, so s and t must be divided by w (or multiplied by oow) before storing them in the GrVertex structure.

The w term iterated by the SST-1 is actually 1/w or the reciprocal of the homogeneous coordinate. The valid range for 1/w is [–4096..61439]. Normally, the homogeneous coordinate is clipped to a positive range of [1..far] and so its reciprocal is in the ra nge [1..1/far]. Negative values should be avoided. Each TMU has its own s, t, and w values. Normally, they will be the same as the w in the Pixelfx. However, in certain cases they will be different. For example, projected textures have a different w valu e than non-projected textures. Projected textures iterate q/w where w is the homogeneous distance from the eye and q is the homogeneous distance from the projected source. In this case, q/w has a valid range of [–4096..61439].

Mipmapping [WILL83] is a method of organizing several pre-filtered texture maps into a single logical entity used for anti-aliased texture mapping. The term mipmap is sometimes used to describe a pyramidal organization of gradually smaller, filtered sub-t extures or an individual texture map within such an organization. Glide adopts the original convention that defines the term mipmap to mean the entire group of textures that comprise a single pyramidal data structure. Individual textures within a mipmap ar e referred to as mipmap levels.


Getting Started

In This Chapter

You will learn how to:

initialize Glide

configure and initialize the hardware

manage multiple Voodoo Graphics subsystems

terminate cleanly

manage the display buffers

detect and respond to errors

Starting Up

Glide provides several functions to initialize Glide and to detect and configure a Voodoo Graphics subsystem. Two routines, grSstQueryHardware() and grSstQueryBoards() detect the presence of Voodoo Graphics subsystems. Three functions, grGlideInit(), grS stSelect(), and grSstOpen(), initialize Glide and the hardware and must be called, in the order listed, before calling any other Glide routines (except grSstQueryHardware() and grSstQueryBoards()). Failing to do this will cause the system to operate in an undefined (and, most likely, undesirable) state.

typedef struct {

int num_sst;

GrSstConfig_t SSTs[MAX_NUM_SST];

} GrHwConfiguration;


FxBool grSstQueryBoards( GrHwConfiguration *hwConfig )


FxBool grSstQueryHardware( GrHwConfiguration *hwConfig )

grSstQueryBoards() determines the number of installed Voodoo Graphics subsystems and stores this number in hwConfig->num_sst. No other information is stored in the structure at this time; grSstQueryHardware() can be called after grGlideInit() to fill in t he rest of the structure. grSstQueryBoards() is the only Glide routine that can be called before grGlideInit(); it does not change the state of any hardware, nor does it render any graphics.

grSstQueryHardware() detects the presence of one or more Voodoo Graphics subsystems and determines how they are configured. It should be called immediately after grGlideInit() but before any other Glide functions.

grSstQueryHardware() returns a Boolean value: FXTRUE indicates that at least one Voodoo Graphics subsystem was found. The argument, hwConfig, is a pointer to a structure that will be filled in with information about the number and configuration of the Voo doo Graphics subsystems it found.

Note that when two Voodoo Graphics subsystems are configured as a single scan-line interleaved system they are viewed by Glide and an application as a single subsystem.

The first initialization function, grGlideInit(), sets up the Glide library and thus must be called before any other Glide functions are executed. It allocates memory, sets up pointers, and initializes library variables and counters. There are no argument s, and no value is returned.

void grGlideInit( void )


The next function called to initialize the system is grSstSelect(), which makes a specific Voodoo Graphics subsystem “current”. It must be called after grSstQueryHardware() and grGlideInit() but before grSstOpen().

void grSstSelect( int whichSST )


The argument is the ordinal number of the subsystem that will be made active and must be in the range [0..hwconfig.num_sst] where hwConfig is the structure that holds the system configuration information returned by the preceding call to grSstQueryHardware (). If whichSST is outside the proper range of values and the debugging version of Glide is used, a run-time error will be generated. If the release version of Glide is loaded, use of an inappropriate value for whichSST will result in undefined behavior.

The final initialization function, grSstOpen(), initializes the currently active Voodoo Graphics subsystem, specified by the most recent call to grSstSelect(), to the default state. All hardware special effects (depth buffering, fog, chroma-key, alpha blending, alpha testing, etc.) are disabled. All global state constants (the chroma-key reference value, the alpha test reference, the constant depth value, the constant alpha value, the constant color value, etc.) and pixel rendering statistic counters are initialized to 0.

grSstOpen() should be called once per installed Voodoo Graphics subsystem (note that scan-line interleaved subsystems are treated as a single Voodoo Graphics subsystem) and must be executed after grGlideInit(), grSstQueryHardware() and grSstSelect(). I t returns FXTRUE if the initialization was successful and FXFALSE otherwise.

FxBool grSstOpen( GrScreenResolution_t res,

GrScreenRefresh_t refresh,

GrColorFormat_t cFormat,

GrOriginLocation_t locateOrigin,

GrSmoothingMode_t smoothMode,

int numBuffers

)

The arguments to grSstOpen() configure the frame buffer. The screen resolution and refresh rate are specified in the first two arguments, res and refresh. Both variables are given values chosen from enumerated types defined in the sst1vid.h header file. A typical application might set res to GR_RESOLUTION_640x480 and refresh to GR_REFRESH_60HZ.

The third argument, cFormat , specifies the packed color RGBA ordering in the frame buffer. Different software systems assume different byte ordering formats for pixel color data. For the widest possible compatibility across a wide range of software, Gli de provides “byte swizzling”, meaning that incoming pixels can have their color values interpreted in one of four different formats that are defined in the enumerated type GrColorFormat_t and are shown in Table 3.1. The color format affects data written t o the linear frame buffer (the subject of Chapter 11) and parameters for the following Glide functions: grBufferClear() (described later in this chapter), grChromakeyValue() (described in Chapter 8), grConstantColorValue() (see Chapter 5), and grFogColo rValue() (see Chapter 8).

Table 3.1 Frame buffer color formats.

Glide supports four different color byte orderings: RGBA, ARGB, BGRA, and ABGR. Color byte ordering determines how linear frame buffer writes and color arguments passed to the constant color functions are interpreted. The first column in the table shows t he name of the format, as defined in the enumerated type GrColorFormat_t. The second column in the table shows the byte ordering of the color components within a 32-bit word.

color format

byte ordering


GR_COLORFORMAT_RGBA



GR_COLORFORMAT_ARGB



GR_COLORFORMAT_BGRA



GR_COLORFORMAT_ABGR



The fourth parameter to grSstOpen() specifies the location of the screen space origin. If locateOrigin is GR_ORIGIN_UPPER_LEFT, the screen space origin is in the upper left corner with positive y going down (a la IBM VGA). GR_ORIGIN_LOWER_LEFT places the screen space origin at the lower left corner with positive y going up (a la SGI GL). Figure 3.1 shows the two possibilities for locating the origin.

Figure 3.1 Locating the origin.

The Voodoo Graphics hardware allows the origin to be in the upper left or lower left corner of the screen. The choice of coordinate system must be made when first initializing Glide and a Voodoo Graphics subsystem by passing the appropriate parameter to g rSstOpen().


The Voodoo Graphics hardware operates on 32-bit ARGB color values internally. However, these values are eventually dithered to 16-bit RGB (5:6:5) by the hardware. Hardware dithering provides good display quality while at the same time reducing memory con sumption by a third, allowing for less expensive hardware implementations. The fifth argument to grSstOpen(), smoothMode, enables or disables an optional 24-bit smoothing filter that can be applied during video refresh. Enabling smoothing reduces dither ing artifacts but may result in a slightly blurrier image.

The final argument to grSstOpen(), numBuffers, specifies double or triple buffering and is an integer value, either 2 or 3. If there is not enough memory to support the desired resolution (e.g. 800´600 triple buffered on a 2MB system) then an error wil l occur.

Example . The Glide initialization sequence.

This code fragment demonstrates the four Glide functions that must be called, in order, to properly initialize both the software and the hardware subsystems. The parameters to grSstOpen() establish a double buffered frame buffer with 640´480 screen resolu tion and a 60Hz refresh rate. Colors are stored as RGBA, smoothing techniques will be applied to reduce dithering artifacts, and the origin is in the lower left corner.

GrHwConfiguration hwconfig;


grGlideInit(void);

if (grSstQueryHardware(hwconfig)) {

grSstSelect(0);

grSstOpen( GR_RESOLUTION_640x480, GR_REFRESH_60HZ, GR_COLORFORMAT_RGBA, GR_ORIGIN_LOWER_LEFT, GR_SMOOTHING_ENABLE, 2);

};

else printf(“ERROR: no Voodoo Graphics!\n”);




Driving Multiple Systems

Glide supports two forms of multiple Voodoo Graphics subsystem support: multiple Voodoo Graphics subsystems driving multiple displays and two Voodoo Graphics subsystems driving a single display.

Selecting Voodoo Graphics Units

At any given moment, only a single Voodoo Graphics subsystem is active. The grSstSelect(), presented above, activates a specific unit. All Glide functions, with the exception of the grGlide family and grSstSelect(), operate on only the currently active Vo odoo Graphics subsystem. Note that the global Glide state is bound to each Voodoo Graphics independently. So, to set the constant color in each Voodoo Graphics unit to the same value, for example, you must write a loop that selects each one in turn and set s the color, as shown in .

Example . Setting a state variable in all Voodoo Graphics subsystems.

Each Voodoo Graphics subsystem has its own version of the Glide state variables, including a constant color value that will be used to clear the screen. The constant color is zero by default. The code fragment below cycles through all the Voodoo Graphics u nits found by a previous call to grSstQueryHardware(), setting the constant color to black.

GrHwConfiguration hwconfig;


for ( i = 0; i < hwconfig.num_sst; i++ )

{

grSstSelect( i );

grConstantColorValue( ~0 ); /* only affects SST “i” */

}


Opening Multiple Voodoo Graphics Units

grSstOpen() must be called once for each Voodoo Graphics subsystem that will be used. Note that two Voodoo Graphics subsystems linked together in a scan-line interleaving configuration are treated in software as a single Voodoo Graphics subsystem.

Scan-line Interleaved Voodoo Graphics Units

Two Voodoo Graphics subsystems can be wired together in a configuration known as scan-line interleaving, which effectively doubles rasterization performance. From an application’s perspective, two Voodoo Graphics subsystems in a scan-line interleaved confi guration are treated as if a single Voodoo Graphics subsystem is installed in the system, including during Voodoo Graphics selection, initialization, state management, texture download, etc.

Shutting Down

After an application has completed using Glide and the Voodoo Graphics subsystem, proper shutdown must be performed. This allows Glide to de-allocate system resources like memory, timers, address space, and file handles that were used during program execut ion.

The function grGlideShutdown() shuts down Glide and all Voodoo Graphics subsystems previously opened with grSstOpen(). It should be called only when an application is finished using Glide, and should not be executed unless grGlideInit() and grSstOpen() have already been called.

void grGlideShutdown( void )


shows a minimal Glide program: it executes the four function calls that initialize the Voodoo Graphics subsystem and then terminates.

Example . A minimal Glide program.

The complete program below includes the Glide initialization and termination procedure and nothing else.

#include <glide.h>


GrHwConfiguration hw;


void main(void)

{

grGlideInit(void);

if (! grSstQueryHardware(hw)) printf(“ERROR: no Voodoo Graphics!\n”);

grSstSelect(0);

grSstOpen( GR_RESOLUTION_640x480, GR_REFRESH_60HZ, GR_COLORFORMAT_RGBA

GR_ORIGIN_LOWER_LEFT, GR_SMOOTHING_ENABLE, 2);

grGlideShutdown();

}


The Display Buffer

Glide manages several logical hardware graphics buffers, all of which are based out of the same area of memory known as the “frame buffer”. Depending on the amount of memory installed on the hardware, the frame buffer is typically arranged as three logical units: the front buffer, the back buffer, and, optionally, the auxiliary buffer.

void grRenderBuffer( GrBuffer_t buffer )


grRenderBuffer() selects the buffer for primitive drawing and buffer clears. Valid values are GR_BUFFER_FRONTBUFFER and GR_BUFFER_BACKBUFFER; the default is GR_BUFFER_BACKBUFFER.

The auxiliary buffer in a Voodoo Graphics subsystem can be used either as a depth buffer, an alpha buffer, or as a third rendering buffer for triple buffering. The auxiliary buffer is not available on systems with 2MB of frame buffer DRAM running at 80 0´600. However, it is always available on systems with 4MB of frame buffer DRAM installed or with the screen resolution set to 640´480.

Triple buffering allows an application to continue rendering even when a swap buffer command is pending. When triple buffering is enabled an application can act as if the hardware is operating in double buffer mode; intricacies of dealing with the third b uffer are hidden from the application by the hardware. Since the auxiliary buffer can serve only a single use, depth buffering, alpha buffering, and triple buffering are mutually exclusive.

An application selects the purpose of the auxiliary buffer implicitly whenever depth buffering, alpha buffering, or triple buffering are enabled. For example, if grDepthBufferMode() is called with a parameter other than GR_DEPTHBUFFER_DISABLE (see Cha pter ), it is assumed that the auxiliary buffer will be used for depth buffering. Similarly, grSstOpen() enables triple buffering; alpha buffering is enabled if grAlphaBlendFunction() selects a destination alpha blending factor (see Chapter 6) or grC olorMask() enables writes to the alpha buffer. The release build of Glide does not check for contention of the auxiliary buffer. Unexpected results may occur if the auxiliary buffer is used for more that one function (e.g. both depth buffering and tripl e buffering are enabled). The debugging version of the library will report the contention.

Note that source alpha blending can coexist with depth or triple buffering, but destination alpha blending cannot.

Table 3.2 Frame buffer resolution and configuration.

The frame buffer can be configured with two or three rendering buffers. In double buffer modes, an alpha or depth buffer can also be used. The available resolution depends on the amount of installed memory.


frame buffer memory

double buffer mode

double buffer mode with 16-bit alpha/depth buffer

triple buffer mode

2 Mbytes

800 by 600 by 16

640 by 480 by 16

640 by 480 by 16

4 Mbytes

800 by 600 by 16

800 by 600 by 16

800 by 600 by 16


Logical Layout of the Linear Frame Buffer

The frame buffer is logically organized as a 1024´1024 array of 16 or 32-bit values, regardless of the amount of memory installed on the board, and is shown in . Scan-line size is independent of screen resolution and is always 1024 pixels wide. The data fo rmat within the frame buffer is programmable and is described in detail in Chapter .

Figure 3.2 Logical layout of the linear frame buffer.

The frame buffer is logically organized as a 1024´1024 array of 16 or 32-bit values, regardless of the amount of memory installed on the board and the screen resolution. The drawable area is a rectangular subset of the frame buffer; its location depends on the location of the y origin. The remainder of the board’s memory (shaded area) is used as an auxiliary buffer that can be utilized as an alpha/depth buffer or as a third display buffer (triple buffering). This logical layout is independent of the user-specified origin location.


Masking Writes to the Frame Buffer

Writes to the frame buffer and depth buffer can be selectively disabled and enabled. The Glide functions grColorMask() and grDepthMask() control buffer masking: FXTRUE values allow writes to the associated buffer, FXFALSE values disable writes to the as sociated buffer. Writes to the color and alpha buffers are controlled by grColorMask() whereas writes to the depth buffer are controlled by grDepthMask() (described in Chapter ). Note that disabling writes to the alpha planes is the same as disabling wri tes to the depth planes since they both share the same memory.

void grColorMask( FxBool rgb, FxBool alpha )


void grDepthMask( FxBool enable )

grColorMask() specifies whether the color and/or alpha buffers can or cannot be written to during rendering operations. If rgb is FXFALSE, for example, no change is made to the color buffer regardless of the drawing operation attempted. The alpha paramet er is ignored if depth buffering is enabled since the alpha and depth buffers share memory.

grDepthMask() enables writes to the depth buffer.

The value of grColorMask() and grDepthMask() are ignored during linear frame buffer writes if grLfbBypassMode() is enabled (see Chapter ). The default values are FXTRUE, indicating that the associated buffers are writable.

Swapping Buffers

In a double or triple buffered frame buffer, the next scene will be rendered in a back buffer while the front buffer is being displayed. After an image has been rendered, it is displayed with a call to grBufferSwap(), which exchanges the front and back b uffers in the Voodoo Graphics subsystem after swapInterval vertical retraces. If the swapInterval is 0, then the buffer swap does not wait for vertical retrace. If the monitor frequency is 60 Hz, for example, a swapInterval of 3 results in a maximum frame rate of 20 Hz.

void grBufferSwap( int swapInterval )


A swapInterval of 0 may result in visual artifacts, such as ‘tearing’, since a buffer swap can occur during the middle of a screen refresh cycle. This setting is very useful in performance monitoring situations, as true rendering performance can be measure d without including the time buffer swaps spend waiting for vertical retrace.

grBufferSwap() does not wait for the specified vertical blanking period; instead, it queues the buffer swap command and returns immediately. If the application is double buffering, the Voodoo Graphics subsystem will stop rendering and wait until the swap occurs before executing more commands. If the application is triple buffering and the third rendering buffer is available, then rendering commands will take place immediately in the third buffer.

A Glide application can poll the Voodoo Graphics subsystem using the grBufferNumPending() function to determine the number of buffers waiting to be viewed, although this is generally not necessary.

int grBufferNumPending( void )


grBufferNumPending() returns the number of queued buffer swap requests. The maximum value returned is 7, even though there may be more buffer swap requests in the queue. To minimize rendering latency in response to interactive input, grBufferNumPending() should be called in a loop once per frame until the returned value is less than some small number such as 1, 2, or 3.

Synchronizing with Vertical Retrace

Synchronization to vertical retrace is supported with the grSstVRetraceOn() and grSstVideoLine() functions. grSstVRetraceOn() returns FXTRUE if the monitor is in vertical retrace and FXFALSE otherwise.

FxBool grSstVRetraceOn( void )


grSstVideoLine() returns the current line number of the display beam. This number is 0 during vertical retrace and increases as the display beam progresses down the screen. There are a small number of video lines that are not displayed at the top of the s creen: the vertical backporch. Thus, grSstVideoLine() returns a small positive number when the display beam is at the top of the screen; as the beam goes off the bottom of the screen, the line number may exceed the number returned by grSstScreenHeight().

FxU32 grSstVideoLine( void )


The Glide 2.1 release was the first release to include grSstVideoLine(). Earlier versions used grSstVRetraceTicks(), now obsolete.

Note that an application does not need to explicitly synchronize to vertical retrace if it only wishes to remove tearing artifacts. grBufferSwap() will automatically synchronize to vertical retrace if desired.

Clearing Buffers

The ability to clear a display buffer is fundamental to animation, since the remnants of a previously rendered scene must be reset before a new scene can be rendered. The Voodoo Graphics hardware allows the back buffer and alpha or depth buffer to be clea red simultaneously.

A buffer clear fills pixels at twice the rate of triangle rendering, therefore the performance cost of clearing the buffer is half the cost of rendering a rectangle. Clearing the buffer is not necessary when the scene paints a background that covers the en tire area.

Buffers are cleared by calling grBufferClear(). The area within the buffer to be cleared is defined by grClipWindow(), described in the next chapter. The three parameters specify the values that will be used to clear the display buffer (color), the alpha buffer (alpha), and the depth buffer (depth). Although the color, alpha, and depth parameters are always specified, the parameters actually used will depend on the current configuration of the hardware; the irrelevant parameters are ignored.

The depth parameter can be one of the constants GR_ZDEPTHVALUE_NEAREST, GR_ZDEPTHVALUE_FARTHEST, GR_WDEPTHVALUE_NEAREST, GR_WDEPTHVALUE_FARTHEST, or a direct representation of a value in the depth buffer. See Chapter for more details.

void grBufferClear( GrColor_t color, GrAlpha_t alpha, FxU16 depth )


Any buffers that are enabled are automatically and simultaneously cleared by grBufferClear(). For example, if depth buffering is enabled (with grDepthBufferMode(), described in Chapter ), the depth buffer will be cleared to depth. If alpha buffering i s enabled (with grAlphaBlendFunction(), described in Chapter 6), the alpha buffer will be cleared to alpha. And if writes to the display buffer are enabled (with grColorMask(), described in Chapter 5), then it will be cleared to color. If an application does not want a buffer to be cleared, it should mask off writes to the buffer using grDepthMask() and grColorMask() as appropriate.

Error Handling

Glide provides a family of error management functions to assist a developer with application debugging. This family of routines consists of Glide related error management (errors generated by Glide) and application level error management (errors generated by an application).

The debug build of Glide performs extensive parameter validation and resource checking. When an error condition is detected, a user-supplied callback function may be executed. This callback function is installed by calling grErrorSetCallback(). If no call back function is specified, a default error function that prints an error message to stderr is used.

void grErrorSetCallback( void (*function)(const char *string, FxBool fatal) )


The callback function accepts a string describing the error and a flag indicating if the error is fatal or recoverable. grErrorSetCallback() is relevant only when using the debugging version of Glide; the release build of Glide removes all internal paramet er validation and error checking so the callback function will never be called.


Rendering Primitives

In This Chapter

You will learn how to:

establish a clipping window

draw a point, a line, a triangle, or a convex polygon on the screen

cull back-facing polygons from the scene

draw an anti-aliased point, line, triangle, or convex polygon

The GrVertex Structure

The GrVertex structure, first presented in Chapter 2, collects together all the parameters that define a vertex. In this chapter, only the x and y coordinates will be discussed; the other parameters are called into play in later chapters.

typedef struct {

float x, y, z; /* x, y, z of screen space. z is ignored */

float ooz; /* 65535/z (used for z buffering) */

float oow; /* 1/w (used for w buffering) */

float r, g, b, a; /* red, green, blue, and alpha ([0..255.0]) */

GrTmuVertex tmuvtx[GLIDE_NUM_TMU];

} GrVertex;

The x and y coordinates are 32-bit floating point values that represent the position of the vertex in screen space. While the Voodoo Graphics hardware renders only triangles, Glide provides functions to draw points, lines, and polygons as well as triangles .

When a point, line, triangle, or polygon is rendered, its appearance will reflect the current state of the rendering pipeline. That is, if texture mapping is enabled, then the point, line, triangle, or polygon will be texture mapped. Similarly, alpha blend ing, fogging, color, and lighting effects, chroma-keying, and other special effects will contribute to the appearance of any and all geometric shapes drawn while they are enabled.

Clipping

The Voodoo Graphics hardware supports per-pixel clipping to an arbitrary rectangle defined with the Glide function grClipWindow(). Any pixels outside the clipping window are rejected. Values are inclusive for minimum x and y values and exclusive for maxi mum x and y values, as shown in Figure 4.1. The clipping window also specifies the area grBufferClear(), described in the last chapter, will clear.

Figure 4.1 Specifying a clipping window.

The clipping window is defined by two pairs of integers in the range [0..1024) specifying the left and right edges and the top and bottom edges of the rectangle.



The grClipWindow() routine has four parameters that define the clipping rectangle. The values must be less than or equal to the current screen resolution and greater than or equal to 0; otherwise, they will be ignored. Glide does not perform any geometric clipping outside of supporting a hardware clipping window. For optimal performance, an application should perform proper geometric clipping before passing any primitives to Glide. The clipping window should not be used in place of true geometric clipping .

void grClipWindow( int minX, int minY, int maxX, int maxY )


The default values for the clip window are the full size of the screen: (0,0,640,480) for 640´480 mode and (0,0,800,600) for 800´600 mode. To disable clipping, simply set the size of the clip window to the screen size. The Voodoo Graphics subsystem’s clipp ing window should not be used for general purpose primitive clipping; since clipped pixels are processed but discarded, proper geometric clipping should be done by the application for best performance. The Voodoo Graphics subsystem’s clip window should be used to prevent stray pixels that appear from imprecise geometric clipping. Note that if grLfbBypassMode() is enabled, clipping is not performed on linear frame buffer writes (see Chapter 11 for more information).

Triangles

The triangle is the basic Glide rendering primitive. The Glide function grDrawTriangle() renders an arbitrarily oriented triangle with vertices a, b, and c to the screen.

void grDrawTriangle( const GrVertex *a, const GrVertex *b, const GrVertex *c )


Triangles are rendered with the following filling rules:

zero area triangles render zero pixels

pixels are rendered if and only if their center lies within the triangle

A pixel center is within a triangle if it is inside all three of the edges. When a pixel center lies exactly on an edge, it is inside the triangle if the edge is considered inside, and outside otherwise. Left edges are in, right edges are out. Horizontal e dges with the smaller y value are in; those with a larger y value are out.

Figure 4.2 gives an example. Eight triangles are shown, all sharing a common vertex. Only one of the triangles renders the pixel whose center is the shared vertex. Can you guess which one?

The shared vertex is part of the “right edge” of triangles A, H, G, and F, and hence outside. It is part of the “top edge” (since the origin is in the lower left) of triangles G, F, E and D, and thus outside them as well. In triangle B, the vertex is on o ne inside edge and one outside edge and hence is considered outside the triangle. Only in triangle C does the vertex lie on two “inside” edges and thus lies inside the triangle.

Clipping a Triangle

Recall from the clipping window discussion above that the hardware clipping implemented by Voodoo Graphics is at the end of the rendering pipeline: a pixel will incur all the rendering cost only to be discarded just before being written to the frame buffe r. An alternative solution is to use host bandwidth to clip the triangle and process only the pixels that will be displayed. The Glide Utility Library provides just such a function. guDrawTriangleWithClip() uses Sutherland-Hodgman clipping [SUTH74] to cli p the triangle to the rectangle specified by grClipWindow() and then draws the resulting polygon.

void guDrawTriangleWithClip( const GrVertex *a, const GrVertex *b, const GrVertex *c )



Figure 4.2 Pixel rendering.

Which of the eight triangles shown in diagram (a) will render the pixel at the common vertex? In diagram (b), solid edges are considered inside the triangle while dotted edges are outside. The top row of diagrams are drawn with the origin in the lower left corner. The bottom row represent the other possibility: the origin is in the upper left corner. The two pairs of diagrams are mirror images of each other.



Points

The Glide function grDrawPoint() renders a single point to the screen. The point will be treated as a triangle with nearly coincident vertices (that is, a very small triangle) for rendering purposes. If many points will be rendered, noticeable performance improvement can be achieved by writing pixels directly to the frame buffer. (grDrawPoint() send three vertices per point to the hardware and iterates along three edges; only one linear frame buffer write per point is required.)

void grDrawPoint( const GrVertex *a )


Example . A thousand points of light.

This code fragment clears the screen to black and then draws a thousand random points. By default, the rendering buffer is set to GR_BUFFER_BACKBUFFER and the color buffer is writable. The color white is made by specifying maximal values for red, green, an d blue, and a quick way to do that is ~0. Some of the points will be clipped out: the random number generator selects point with coordinates in the range [0..1024); the screen resolution is less than that. By default, the clipping window is set to the scr een size.

int n;

GrVertex p;


/* clear the back buffer to black */

grBufferClear(0, 0, 0);


/* set color to white */

grColorCombine( GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE,

GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_NONE,FXFALSE );

grConstantColorValue(~0)


/* generate and draw 1000 random points */

for (n=0; n<1000; n++) {

p.x = (float) (rand() % 1024);

p.y = (float) (rand() % 1024);

grDrawPoint(p);

}


Lines

The Glide function grDrawLine() renders an arbitrarily oriented line segment. Enabled special effects (e.g. fog, blending, chroma-key, dithering, etc.) will affect a line’s appearance.

void grDrawLine( const GrVertex *a, const GrVertex *b )


Convex Polygons

A polygon is a planar area enclosed by a closed loop of line segments, specified by their endpoints. While the Voodoo Graphics hardware does not render polygons directly, Glide provides a set of polygon rendering functions that are optimized for the hardwa re. The polygons rendered by the Glide functions are subject to some strong restrictions:

The edges of the polygon cannot intersect.

The polygon must be convex, that is, have no indentations. (The glossary at the end of this manual gives a precise definition of convexity.)

shows some examples of both valid and invalid polygons.

Figure 4.3 Polygons.


The convex polygons rendered by Glide are assumed to be planar in coordinate space. Two polygon rendering routines (grDrawPlanarPolygon() and grDrawPlanarPolygonVertexList()) requires that the rendering parameters (r, g, b, a, ooz, oow, sow, tow) be pla nar as well. None of the polygon rendering functions do any geometric clipping.

void grDrawPlanarPolygon( int nVerts, int ilist[], const GrVertex vlist[] )


void grDrawPolygon( int nVerts, int ilist[], const GrVertex vlist[] )

grDrawPlanarPolygon() and grDrawPolygon() both render a convex polygon with nVerts vertices. The second argument, ilist, is an array of indices into the list of vertices provided in the third argument. This level of indirection in specifying vertices is useful if you need to pre-process the list to do geometric clipping or hidden surface removal. The preprocessor can create the ilist for you rather than copying selected vertices to a new list.

grDrawPlanarPolygon() assumes that the vertex parameters for the polygon are planar. Parameter gradients will be calculated only once for the entire polygon, thus reduce the number of calculations significantly.

Another pair polygon rendering functions defined in Glide, grDrawPlanarPolygonVertexList() and grDrawPolygonVertexList(), are functionally equivalent to grDrawPlanarPolygon () and grDrawPolygon() respectively. The difference between the two pairs of ro utines is the way the vertices are specified.

void grDrawPlanarPolygonVertexList( int nVerts, const GrVertex vlist[] )

void grDrawPolygonVertexList( int nVerts, const GrVertex vlist[] )


There is no level of indirection in grDrawPlanarPolygonVertexList() and grDrawPolygonVertexList(). The ith vertex of the polygon passed to these routines is vlist[i], assuming that 0£i<nVerts, whereas the ith vertex of a polygon passed to grDrawPlanarPol ygon () or grDrawPolygon() is vlist[ilist[i]].

Backface Culling

Glide supports backface culling based on the signed area of a polygon. When Glide renders a polygon, the first step is to divide the polygon into triangles, the rendering primitive of the Voodoo Graphics hardware. shows a pair of triangles whose vertices have been labeled according to the rule given above.

Figure 4.4 Polygon orientation and the sign of the area.

The polygons on the left are defined relative to an origin in the upper left corner; the ones on the right have the origin in the lower left corner. Clockwise and counter-clockwise refer to the direction that the vertices are traversed in alphabetical ord er.



The sign of the area of the triangle can be used for backface culling (quickly discarding triangles that won’t be visible on the screen before they are rendered). Because the area must be computed anyway, this is a cheap way to cull. However, removing ba ck-facing triangles earlier may be advantageous. For example, if back face removal is performed before lighting, then the computationally expensive lighting calculations for invisible triangles can be skipped.

The Glide function grCullMode() has one parameter, a mode that can be set to GR_CULL_NONE, GR_CULL_NEGATIVE, or GR_CULL_POSITIVE. When the culling mode is GR_CULL_NONE, the default value, all polygons are rendered to the screen regardless of their signed area. Otherwise, if the sign of the area matches the mode, then the triangle is rejected. grCullMode() assumes that GR_CULL_POSITIVE corresponds to a counter-clockwise oriented triangle when the origin is in the lower left corner of the screen, and a clock wise oriented triangle when the origin is in the upper left corner, as shown in .

void grCullMode( GrCullMode_t mode )


Note that grCullMode() has no effect on points and lines, but does effect the rendering of triangles and polygons.

Table 4.1 The location of the origin affects triangle orientation and the sign of its area.

If the origin location is

and the triangle orientation is

then the sign of the area will be

GR_ORIGIN_LOWERLEFT

clockwise

negative

GR_ORIGIN_LOWERLEFT

counter-clockwise

positive

GR_ORIGIN_UPPERLEFT

clockwise

positive

GR_ORIGIN_UPPERLEFT

counter-clockwise

negative


Anti-aliasing

If you look closely and critically at lines drawn on the screen, particularly lines that are nearly horizontal or nearly vertical, they may appear to be jagged. The screen is a grid of pixels and the line is approximated by lighting spans of pixels on that grid. The jaggedness is called aliasing; examples of aliased lines are shown in Figure 4.5(a). Anti-aliasing techniques reduce the jaggedness, as shown in Figure 4.5(b), by partially coloring neighboring pixels to simulate partial pixel coverage.

Figure 4.5 Aliased and anti-aliased lines.

These lines are drawn at a resolution of 50 pixels/inch in order to exaggerate the jagged edges of the aliased lines and highlight the widening and blending in the anti-aliased lines. These lines are examples of the general concepts; if you replicate this drawing on a Voodoo Graphics screen, the results may be different in detail.


Figure 4.6 shows an angled line segment one pixel wide, superimposed on a pixel grid. Some pixels are almost completely covered by the line, while others have only a small corner involved. Glide’s anti-aliasing routines compute a coverage value for each p ixel and uses that in combination with the source and destination alpha values to blend the pixel color.

Figure 4.6 Pixel coverage and lines.


Glide draws anti-aliased points, lines, triangles, and polygons by setting up the alpha iterator so that it represents pixel coverage. You must correctly configure the alpha combine unit (discussed in detail in Chapter 6) and enable alpha blending befor e using any of the anti-aliased drawing commands. The code segment in details the proper sequence of Glide commands that must precede the actual anti-aliased drawing commands. Briefly, you must

Set the alpha combine unit to produce iterated alpha.

Set the alpha blending function. Blending functions are specified for source and destination color components and for source and destination alpha values, and the choice of function depends on whether the scene will be rendered front to back or back to fr ont.

Set the alpha value for each vertex. The chosen alpha value should represent the transparency of the object being rendered, with opaque objects setting alpha to 255. This alpha value will be multiplied by the pixel coverage to obtain the final alpha value used for alpha blending.

Call a grAADraw or guAADraw function. The six functions are as shown below.

void grAADrawPoint( GrVertex *p )

void grAADrawLine( GrVertex *va, GrVertex *vb )

void grAADrawTriangle( GrVertex *va, GrVertex *vb, GrVertex *vc, FxBool aaAB, FxBool aaBC, FxBool aaCA )

void grAADrawPolygon( int nVerts, const int ilist[], const GrVertex vlist[] )

void grAADrawPolygonVertexList( int nVerts, const GrVertex vlist[] )

void guAADrawTriangleWithClip( const GrVertex *va, const GrVertex *vb, const GrVertex *vc )


grAADrawPoint() renders the point as four pixels, each blended according to the computed pixel coverage.

Lines drawn with grAADrawLine() will be somewhat “fatter” than expected.

grAADrawTriangle() has three more arguments than its aliased counterpart grDrawTriangle(). The arguments, aaAB, aaBC, and aaBC are Boolean values that allow to selectively anti-alias the edges of the triangle.

grAADrawPolygon() and grAADrawPolygonVertexList() draw convex polygons with anti-aliased edges.

guAADrawTriangleWithClip() performs 2D clipping on the specified triangle, and draws the resultant polygon with grAADrawPolygonVertexList(). All edges of the clipped triangle will be anti-aliased.

Example . Drawing an anti-aliased triangle.

The alpha combine unit must be configured to produce an iterated alpha value in order to use the Glide anti-aliasing drawing functions. Consider the following code segment a recipe for success in this chapter; the alpha combine unit, alpha buffering, a nd alpha blending are the subject of Chapter 6.

The objects in the picture must be pre-sorted on depth. The alpha blending factors depend on whether the scene is drawn front to back or back to front. The first code shows the alpha blending factors is the scene is drawn front to back.

/* set alpha combine unit to produce an iterated alpha */

grAlphaCombine(GR_COMBINE_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_LOCAL_NONE, GR_LOCAL_INTERATED, FXFALSE);


/* blend colors based on alpha */

grAlphaBlendFunction(GR_BLEND_ ALPHA_SATURATE, GR_BLEND_ONE, GR_BLEND_ SATURATE, GR_BLEND_ONE);


/* draw the scene using the grAADraw routines */



Substitute the alpha blending factors shown below if the scene is drawn from back to front.

grAlphaBlendFunction(GR_BLEND_SRC_ALPHA, GR_BLEND_ONE_MINUS_SRC_ALPHA, GR_BLEND_ZERO, GR_BLEND_ZERO);



Color and Lighting

In This Chapter

You will learn about:

specifying colors

configuring the color combine unit that produces shading and lighting effects

drawing a flat-shaded object

drawing a smooth-shaded object

simulating various lighting effect

Specifying Colors

A color consists of three or four color components: red, green, blue, and optionally, alpha. The color component values should be clamped to the range [0..255] where 0 is black and 255 is maximum intensity.

The color components are packed together into a word to form a color. Glide supports four different color byte orderings, defined in the enumerated type GrColorFormat_t (see for a pictorial representation). Color byte ordering determines how linear fram e buffer writes and color arguments are interpreted and is established in the call to grSstOpen() when the Glide and Voodoo Graphics systems are initialized (see Chapter ).

The GrColor_t type definition represents a packed color value and is used in routines that set a constant color: grBufferClear() (see Chapter ), grConstantColorValue() (described below), grFogColorValue() and grChromakeyValue() (both described in Chapt er 8).

void grConstantColorValue( GrColor_t color )


Glide refers to a global constant color when performing flat shaded primitive rendering, set with grConstantColorValue(). The default value is 0xFFFFFFFF.

Vertex colors are specified in the GrVertex structure as individual color components, since the Voodoo Graphics system will iterate and compute slopes for each color individually.

Dithering

The Voodoo Graphics hardware represents color internally as 32-bit quadruplets in a format specified by the color format argument passed to grSstOpen() (see Chapter ). This color is eventually dithered to 16-bit RGB for storage in the frame buffer, then expanded and (optionally) filtered up to 24-bits for final display. From an application’s perspective, the 32-to-16-bit RGB dithering operation is transparent.

Dithering is a technique for increasing the perceived range of colors in an image by applying a pattern to surrounding pixels to modify their color values. When viewed from a distance, these colors appear to blend into an intermediate color that can’t be represented directly. Dithering is similar to the half-toning used in black and white publications to produce shades of gray.

void grDitherMode( GrDitherMode_t mode )


grDitherMode() selects the form of dithering the Voodoo Graphics subsystem uses when converting 24-bit RGB values to the 16-bit RGB color buffer format. Valid values are GR_DITHER_DISABLE, GR_DITHER_2x2, and GR_DITHER_4x4. GR_DITHER_DISABLE forces a simp le truncation that may result in noticeable banding. GR_DITHER_2x2 uses a 2x2 ordered dither matrix, and GR_DITHER_4x4 uses a 4x4 ordered dither matrix.

The default dithering mode is GR_DITHER_4x4.

The Color Combine Unit

Note: Control of high level rendering functions is managed by three functions, grColorCombine(), grAlphaCombine() (see Chapter ), and grTexCombine() (described in Chapter ). While the three routines will be presented individually, settings for one funct ion can potentially affect the inputs to the other routines.

The color combine unit computes an RGB color for each pixel as it is rendered. User-selected inputs are added, blended, and/or scaled to produce flat or smooth (Gouraud) shading with optional lighting effects. The color combine unit computes each RGB colo r component separately, but all three are computed using the same formula. The alpha combine unit computes the alpha component and is discussed in the next chapter.

The color combine unit computes a color component as

c = f * a + b

where c is the red, green, or blue color component, f is a scale factor, and a and b are sums and differences of the various input choices.

The Glide routine that configures the color combine unit is grColorCombine(). It specifies the function that will be used to compute the color and selects among the input options.

void grColorCombine( GrCombineFunction_t func,

GrCombineFactor_t factor,

GrCombineLocal_t local,

GrCombineOther_t other,

FxBool invert

)

Fourteen combining functions are defined in the GrCombineFunction_t enumerated type; one is selected with func, the first argument to grColorCombine(). gives the symbolic names and formulas for each color combine function.

The f variable in the combining formulas is defined by factor, the second argument to grColorCombine(). The choices for this scale factor are given in . Note that alpha values from the texture combine unit (atexture) or specified by grAlphaCombine() arg uments (alocal and aother) appear in some of the scale factors.

Table 5.1 Configuring the color combine unit.

The first argument to grColorCombine(), func, specifies the color combine function; its value is chosen from among the symbols list in the left hand column of the table below. The right hand column gives the combining function that corresponds to each sym bolic name. f is a scale factor and is defined by the factor argument to grColorCombine(). clocal and cother are specified by the third and fourth arguments. Some of the formulas specify an alpha value, alocal, that is defined in the grAlphaCombine() func tion described in the next chapter.


color combine function

computed color

GR_COMBINE_FUNCTION_ZERO

0

GR_COMBINE_FUNCTION_LOCAL

clocal

GR_COMBINE_FUNCTION_LOCAL_ALPHA

alocal

GR_COMBINE_FUNCTION_SCALE_OTHER

GR_COMBINE_FUNCTION_BLEND_OTHER

f * cother

GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL

f * cother + clocal

GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA

f * cother + alocal

GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL

f * (cotherclocal)

GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL

GR_COMBINE_FUNCTION_BLEND

f * (cotherclocal) + clocal

º f * cother + (1 – f) * clocal

GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA

f * (cotherclocal) + alocal

GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL

GR_COMBINE_FUNCTION_BLEND_LOCAL

f * (– clocal) + clocal

º (1 – f) * clocal

GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA

f * (– clocal) + alocal

Table 5.2 The color combine function scale factor.

The second argument to grColorCombine(), factor, specifies a scale factor, called f in the formulas delineated in ; its value is chosen from among the symbols list in the left hand column of the table below. The right hand column gives the scale factor th at corresponds to each symbolic name. clocal is specified by the third argument to grColorCombine(), alocal and aother are defined in the grAlphaCombine() function described in the next chapter, and atexture comes from the texture combine unit, described in Chapter .

combine factor

scale factor (f)

GR_COMBINE_FACTOR_NONE

unspecified

GR_COMBINE_FACTOR_ZERO

0

GR_COMBINE_FACTOR_LOCAL

clocal / 255

GR_COMBINE_FACTOR_OTHER_ALPHA

aother / 255

GR_COMBINE_FACTOR_LOCAL_ALPHA

alocal / 255

GR_COMBINE_FACTOR_TEXTURE_ALPHA

atexture / 255

GR_COMBINE_FACTOR_ONE

1

GR_COMBINE_FACTOR_ONE_MINUS_LOCAL

1 – clocal / 255

GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA

1 – aother / 255

GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA

1 – alocal / 255

GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA

1 – atexture / 255





The third and fourth arguments to grColorCombine() set values for the clocal and cother variables that appear in the combining functions; the choices are shown in . Iterated colors are computed by iterating the colors specified in GrVertex structures pas sed to drawing functions. The texture color comes from the texture combine unit (see Chapter ), and the constant color is set by grConstantColorValue() (described earlier in this chapter).

The func formula computes the red, green, and blue color components. The result of the computation is clamped to [0..255] and may be bit-wise inverted, based on the final argument to grColorCombine(), invert. Inverting the bits in a color component c is t he same as computing (1.0 – c) for floating point values in the range [0..1] or (255 – c) for 8-bit values in the range [0..255].

Table 5.3 Choosing local and other colors for the color combine unit.

The third and fourth arguments to grColorCombine(), local and other, specify the sources for the clocal and cother values that appear in the color combine formulas delineated in ; their values are chosen from among the symbols in the tables below. Iterate d colors are computed by iterating the colors specified in GrVertex structures passed to drawing functions. The texture color comes from the texture combine unit, and the constant color is set by grConstantColorValue().

local combine source

local color (clocal)

GR_COMBINE_LOCAL_NONE

unspecified color

GR_COMBINE_LOCAL_ITERATED

iterated vertex color (Gouraud shading)

GR_COMBINE_LOCAL_CONSTANT

constant color


other combine source

other color (cother)

GR_COMBINE_OTHER_NONE

unspecified color

GR_COMBINE_OTHER_ITERATED

iterated vertex color (Gouraud shading)

GR_COMBINE_OTHER_TEXTURE

color from texture map