Chapter 3. After toogl: How to Finish Porting to OpenGL

After you run your IRIS GL program through toogl, you can use this chapter to find out how to replace IRIS GL calls that toogl didn't translate completely or correctly. To get the most out of this discussion, refer to the reference pages as necessary.

The chapter discusses these topics:

Header Files

toogl doesn't replace header files for you, so you have to replace them yourself. This section lists the files your IRIS GL program probably used and the OpenGL files to replace them with.

Table 3-1. Include Lines in IRIS GL and OpenGL Programs

IRIS GL Include Lines

OpenGL Include Lines

#include <gl/gl.h>

#include <gl/device.h>

#include <gl/get.h>

#include <GL/gl.h>

#include <GL/glu.h>

/* X header files start here*/

#include <Xm/Xm.h>

#include <Xm/Frame.h>

#include <Xm/Form.h>

#include <X11/StringDefs.h>

#include <X11/keysym.h>

If you use the GLUT library, you also have to include the GLUT header file:

#include <GL/glut.h>

If you use the Motif widget, replace the include lines as indicated in Table 3-2.

Table 3-2. Include Lines for IRIS GL and OpenGL Motif Widgets

IRIS GL Motif Widget Include Lines

OpenGL Motif Widget Include Lines

For the IRIS IM version of the widget:

#include <X11/Xirisw/GlxMDraw.h>

For the IRIS IM version of the widget:

#include <GL/GLwMDrawA.h>

For the generic version of the widget:

#include <X11/Xirisw/GLxDraw.h>

For the generic version of the widget:

#include <GL/GLwDrawA.h>

If you're using Xlib and OpenGL/X calls, add

#include <GL/glx.h>

Porting greset()

OpenGL replaces the functionality of greset() with the commands glPushAttrib() and glPopAttrib(). Use these commands to save and restore groups of state variables.

Call glPushAttrib() to indicate which groups of state variables to push onto an attribute stack by taking a bitwise OR of symbolic constants, as follows:

void glPushAttrib( GLbitfield mask );

The attribute stack has a finite depth of at least 16.

The glPushAttrib() and glPopAttrib() calls push and pop the server attribute stacks. In OpenGL 1.1, you can also use the functions glPushClientAttrib() and glPopClientAttrib() to push and pop the client attribute stack.

Each constant refers to a group of state variables. Table 3-3 shows the attribute groups with their corresponding symbolic constant names. For a complete list of the OpenGL state variables associated with each constant, see the glPushAttrib reference page.

Table 3-3. State Attribute Groups

Attribute

Constant

accumulation buffer clear value

GL_ACCUM_BUFFER_BIT

color buffer

GL_COLOR_BUFFER_BIT

current

GL_CURRENT_BIT

depth buffer

GL_DEPTH_BUFFER_BIT

enable

GL_ENABLE_BIT

evaluators

EGL_VAL_BIT

fog

GL_FOG_BIT

GL_LIST_BASE setting

GL_LIST_BIT

hint variables

GL_HINT_BIT

lighting variables

GL_LIGHTING_BIT

line drawing mode

GL_LINE_BIT

pixel mode variables

GL_PIXEL_MODE_BIT

point variables

GL_POINT_BIT

polygon

GL_POLYGON_BIT

polygon stipple

GL_POLYGON_STIPPLE_BIT

scissor

GL_SCISSOR_BIT

stencil buffer

GL_STENCIL_BUFFER_BIT

texture

GL_TEXTURE_BIT

transform

GL_TRANSFORM_BIT

viewport

GL_VIEWPORT_BIT

GL_ALL_ATTRIB_BITS

pixel storage modes

GL_CLIENT_PIXEL_STORE_BITS (1.1 only)

vertex arrays and enables

GL_CLIENT_VERTEX_ARRAY_BIT (1.1 only)

To restore the values of the state variables to those saved with the last glPushAttrib(), call glPopAttrib(). The variables you didn't save remain unchanged.

Porting IRIS GL get* Commands

IRIS GL get* calls are of this form:

int getthing();
int getthings( int *a, int *b);

Your IRIS GL program probably includes calls that look like the following:

thing = getthing();
if(getthing() == THING) { /* stuff */ }
getthings (&a, &b);

OpenGL uses glGet*() calls for equivalent functionality; they look like this:

void glGetIntegerfv(NAME_OF_THING, &thing);

Table A-1 lists the IRIS GL get functions with their OpenGL equivalents.

In general, this guide lists various parameters for glGet*() calls in the sections that discuss topics related to those parameters. To see the parameter values related to matrices, for example, see “Porting Matrix and Transformation Calls”.

There are other functions to query the OpenGL state, such as glGetClipPlane() and glGetLight(). These commands are discussed in the sections on related calls, and also in the reference pages.

About glGet*()

There are four types of glGet*() functions:

  • glGetBooleanv()

  • glGetIntegerv()

  • glGetFloatv()

  • glGetDoublev()

The functions have this syntax:

glGet<Datatype>v( value, *data )

value is of type GLenum and data of type GLdatatype. If you issue a glGet*() call that returns types different from the expected types, each type is converted appropriately. For a complete list of parameters, see the glGet reference page.

In addition to the basic glGet*() function, there are a number of special purpose information retrieval functions: glGetClipPlane, glGetError, glGetLight, glGetMap, glGetMaterial, glGetPixelMap, glGetPointerv, glGetPolygonStipple, glGetString, glGetTexEnv, glGetTexGen, glGetTexImage, glGetTexlevelParameter, glGetTexParameter.

glGet*() Conventions Used in This Book

For the sake of brevity, this guide usually shortens the reference to the form

glGet*(GL_GET_TYPE) 

For example,

glGetIntegerv(GL_VIEWPORT, *params);

is abbreviated as

glGet*(GL_VIEWPORT);

in tables and text (but not in code examples).

Porting Commands That Required Current Graphics Positions

OpenGL doesn't maintain a current graphics position. IRIS GL commands that depend on the current graphics position, such as move(), draw(), and rmv(), have no equivalents in OpenGL.

Older versions of IRIS GL included drawing commands that relied upon the current graphics position, though their use was discouraged in more recent versions. You have to reimplement parts of your program if you relied on the current graphics position in any way, or used any of the following routines:

  • draw() and move()

  • pmv(), pdr(), and pclos()

  • rdr(), rmv(), rpdr(), and rpmv()

  • getgpos()

OpenGL has a concept of raster position that corresponds to the IRIS GL current character position. See “Porting Pixel Operations” for more information.

Porting Screen and Buffer Clearing Commands

OpenGL replaces a variety of IRIS GL clear() calls (such as zclear(), aclear(), sclear(), and so on) with one: glClear(). Specify exactly what you want to clear by passing masks to glClear().

When porting screen and buffer clearing commands, consider the following issues:

  • OpenGL maintains clear colors separately from drawing colors, with calls like glClearColor() and glClearIndex(). Be sure to set the clear color for each buffer before making a clear call.

  • Since toogl has no concept of context, it cannot correctly translate color calls immediately preceding clear calls into glClearColor() calls. You have to translate these calls explicitly. For example, suppose your program clears the viewport as follows:

    color(BLACK);
    clear();
    

    toogl translates those two lines as follows:

    glIndex(BLACK);
    glClear(GL_COLOR_BUFFER_BIT);
    

    A better translation of this fragment the following:

    glClearIndex(0);
    glClear(GL_COLOR_BUFFER_BIT);
    

    Remember that IRIS GL color constants, such as BLACK, are not defined in OpenGL.

  • Instead of using one of several differently named clear calls, you now clear several buffers with one call, glClear(), by ORing together buffer masks. For example, czclear() is replaced by

    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT )
    

  • IRIS GL respects the polygon stipple and the color write mask. OpenGL ignores the polygon stipple but respects the write mask. czclear() ignored both the polygon stipple and the write mask.

Table 3-4 lists the various clear calls with their IRIS GL equivalents.

Table 3-4. Calls for Clearing the Screen

IRIS GL Call

OpenGL Call

Meaning

acbuf(AC_CLEAR)

glClear(GL_ACCUM_BUFFER_BIT)

Clear the accumulation buffer.

glClearColor()

Set the RGBA clear color.

glClearIndex()

Set the clear color index.

clear()

glClear(GL_COLOR_BUFFER_BIT)

Clear the color buffer.

glClearDepth()

Specify the clear value for the depth buffer.

zclear()

glClear(GL_DEPTH_BUFFER_BIT)

Clear the depth buffer.

czclear()

glClear(GL_COLOR_BUFFER_BIT |

GL_DEPTH_BUFFER_BIT)

Clear the color buffer and the depth buffer.

glClearAccum()

Specify clear values for the accumulation buffer.

glClearStencil()

Specify the clear value for the stencil buffer.

sclear()

glClear(GL_STENCIL_BUFFER_BIT)

Clear the stencil buffer.

If your IRIS GL code used both gclear() and sclear(), you can instead use a single glClear() call. As a result, your program's performance may improve.

Porting Matrix and Transformation Calls

When porting matrix and transformation calls, consider the following issues:

  • There is no single-matrix mode. OpenGL is always in double-matrix mode.

  • Angles are now measured in degrees, instead of tenths of degrees.

  • Projection matrix calls, like glFrustum() and glOrtho(), now multiply with the current matrix, instead of being loaded onto the current matrix.

  • The OpenGL call glRotate() is different from rotate(). glRotate() lets you rotate around any arbitrary axis, instead of being confined to the x, y, and z axes. But you probably have to port rotate() calls explicitly, because toogl often doesn't translate them correctly. For example, toogl might translate

    rotate(200*(i+1), 'z');
    

    into

    glRotate(.1*(200*(i+1)), ( 'z')=='x', ( 'z')=='y', 
                             ( 'z')=='z');
    

    toogl correctly switched to degrees from tenths of degrees, but didn't correctly handle the replacement of z with a vector for the z-axis. A better translation is

    glRotate(.1*(200*(i+1), 0.0, 0.0, 1.0);
    

  • OpenGL documentation presents matrices in a manner more consistent with standard usage in linear algebra than did IRIS GL documentation. Specifically, in IRIS GL documentation, vectors are treated as rows, and a matrix is applied to a vector on the right of the vector. multmatrix() replaces the current matrix C with C' = MC. In OpenGL documentation, vectors are treated as columns, and a matrix applies to a vector on the left of the vector. glMultMatrix() computes C' = CM.

    A generic IRIS GL translation is shown in the equation in Figure 3-1.

    Figure 3-1. Generic IRIS GL Translation

    Figure 3-1 Generic IRIS GL Translation

    A generic OpenGL translation is shown in the equation in Figure 3-2.

    Figure 3-2. Generic OpenGL Translation

    Figure 3-2 Generic OpenGL Translation

    The important thing is that this is a change in documentation only—OpenGL matrices are completely compatible with the ones in IRIS GL except that they are stored in column-major order. So, if you want the matrix shown in the equation in Figure 3-3 in your OpenGL application, you would declare it as follows:

    float mat[16] = {a, e, i, m, b, f, j, n, c, g,
                     k, o, d, h, l, p}
    

    Figure 3-3. OpenGL Matrix Example

    Figure 3-3 OpenGL Matrix Example

  • OpenGL has no equivalent to the polarview() call. You can replace such a call with a translation and three rotations. For example, the IRIS GL call

    polarview(distance, azimuth, incidence, twist);
    

    translates to

    glTranslatef( 0.0, 0.0, -distance);
    glRotatef( -twist * 10.0, 0.0, 0.0, 1.0);
    glRotatef( -incidence * 10.0, 1.0, 0.0, 0.0);
    glRotatef( -azimuth * 10.0, 0.0, 0.0, 1.0);
    

  • The replacement for the lookat() call, gluLookAt(), takes an up vector instead of a twist angle. toogl doesn't translate this call correctly, so you have to port explicitly. See the gluLookAt reference page for more information.

Table 3-5 lists the OpenGL matrix calls and their IRIS GL equivalents.

Table 3-5. Matrix Operations

IRIS GL Call

OpenGL Call

Meaning

mmode()

glMatrixMode()

Set current matrix mode.

glLoadIdentity()

Replace current matrix with the identity matrix.

loadmatrix()

glLoadMatrixf(),
glLoadMatrixd()

Replace current matrix with the specified matrix.

multmatrix()

glMultMatrixf(),
glMultMatrixd()

Post-multiply current matrix with the specified matrix (note that multmatrix() pre-multiplied).

mapw(), mapw2()

gluUnProject()

Project world space coordinates to object space (see also gluProject()).

ortho()

glOrtho()

Multiply current matrix by an orthographic projection matrix.

ortho2()

gluOrtho2D()

Define a two-dimensional orthographic projection matrix.

perspective()

gluPerspective()

Define a perspective projection matrix.

picksize()

gluPickMatrix()

Define a picking region.

popmatrix()

glPopMatrix()

Pop current matrix stack, replacing the current matrix with the one below it.

pushmatrix()

glPushMatrix()

Push current matrix stack down by one, duplicating the current matrix.

rotate(), rot()

glRotated(), glRotatef()

Rotate current coordinate system by the given angle about the vector from the origin through the given point. Note that rotate() rotated only about the x, y, and z axes.

scale()

glScaled(),glScalef()

Multiply current matrix by a scaling matrix.

translate()

glTranslatef(),
glTranslated()

Move coordinate system origin to the specified point by multiplying the current matrix by a translation matrix.

window()

glFrustum()

Given coordinates for clipping planes, multiply the current matrix by a perspective matrix.

OpenGL has three matrix modes, which are set with glMatrixMode(). Table 3-6 lists the IRIS GL mmode() arguments in the first column and the corresponding arguments to glMatrixMode() in the second column.

Table 3-6. Matrix Modes

IRIS GL Matrix Mode

OpenGL Mode

Meaning

Min. Stack Depth

MTEXTURE

GL_TEXTURE

Operate on the texture matrix stack.

2

MVIEWING

GL_MODELVIEW

Operate on the modelview matrix stack.

32

MPROJECTION

GL_PROJECTION

Operate on the projection matrix stack.

2


Porting MSINGLE Mode Code

OpenGL has no equivalent for MSINGLE, single-matrix mode. Though use of this mode has been discouraged, it was the default for IRIS GL and your program may have used it. If it did, you have to reimplement part of it. OpenGL is always in double-matrix mode, and is initially in GL_MODELVIEW mode.

Most IRIS GL code in MSINGLE mode looks as follows:

...
projectionmatrix();
...

projectionmatrix() is one of the following: ortho(), ortho2(), perspective(), window(). To port to OpenGL, replace the MSINGLE mode projectionmatrix() call by the following pseudo-code:

...
glMatrixMode( GL_PROJECTION );
glLoadMatrix( identity matrix );
[one of these calls: 
        glFrustrum(), glOrtho(), glOrtho2(), gluPerspective()];
glMatrixMode( GL_MODELVIEW );
glLoadMatrix( identity matrix );

Porting get* Calls for Matrices and Transformations

Table 3-7 maps IRIS GL matrix queries to OpenGL matrix queries.

Table 3-7. Arguments for Transformation Matrix Queries

IRIS GL Matrix Query

OpenGL glGet*() Matrix Query

Meaning

getmmode()

GL_MATRIX_MODE

Return the current matrix mode.

getmatrix() in MVIEWING mode

GL_MODELVIEW_MATRIX

Return a copy of the current modelview matrix.

getmatrix() in MPROJECTION mode

GL_PROJECTION_MATRIX

Return a copy of the current projection matrix.

getmatrix() in MTEXTURE mode

GL_TEXTURE_MATRIX

Return a copy of the current texture matrix.

GL_MAX_MODELVIEW_STACK_DEPTH

Return maximum supported depth of modelview matrix stack.

GL_MAX_PROJECTION_STACK_DEPTH

Return maximum supported depth of projection matrix stack.

GL_MAX_TEXTURE_STACK_DEPTH

Return maximum supported depth of texture matrix stack.

GL_MODELVIEW_STACK_DEPTH

Return number of matrices on modelview stack.

GL_PROJECTION_STACK_DEPTH

Return number of matrices on projection stack.

GL_TEXTURE_STACK_DEPTH

Return number of matrices on texture stack.


Porting Viewports, Screenmasks, and Scrboxes

The following IRIS GL calls have no direct OpenGL equivalent:

  • reshapeviewport()

  • scrbox(), getscrbox()

The IRIS GL viewport() call had as parameters the x coordinates (in pixels) for the left and right of the viewport rectangle and the y coordinates for the top and bottom. The OpenGL glViewport() call has as parameters the x and y coordinates (in pixels) of the lower left corner of the viewport rectangle, as well as the rectangle's width and height.

Table 3-8 lists the OpenGL equivalents for viewport commands.

Table 3-8. Viewport Calls

IRIS GL Call

OpenGL Call

Meaning

viewport(left, right, bottom, top)

glViewport(x, y, width, height)

Set the viewport.

popviewport()

pushviewport()

glPopAttrib()

glPushAttrib(GL_VIEWPORT_BIT)

Push and pop the stack.

getviewport()

glGet*(GL_VIEWPORT)

Return viewport dimensions.


Porting Clipping Planes

OpenGL implements clipping planes the way IRIS GL did, though you can now also query clipping planes. Table 3-9 lists the OpenGL equivalents to IRIS GL calls.

Table 3-9. Clipping Plane Calls

IRIS GL Call

OpenGL Call

Meaning

clipplane(i, CP_ON, params)

glEnable(GL_CLIP_PLANEi)

Enable clipping on plane i.

clipplane(i, CP_DEFINE, plane)

glClipPlane( GL_CLIP_PLANEi, plane)

Define clipping plane.

glGetClipPlane()

Return clipping plane equation.

glIsEnabled( GL_CLIP_PLANEi)

Return true if clip plane i is enabled.

scrmask()

glScissor()

Define the scissor box.

getscrmask()

glGet*(GL_SCISSOR_BOX)

Return the current scissor box.

To turn on the scissor test, call glEnable() with GL_SCISSOR_BOX as the parameter.

Porting Drawing Commands

The following sections discuss how to port IRIS GL drawing primitives, discussing the following topics:

Porting the IRIS GL Sphere Library

The sphere library that worked with IRIS GL isn't available for OpenGL. You can replace sphere library calls with quadrics routines from the GLU library or with the GLUT functions for geometric object rendering. Refer to the OpenGL Programming Guide and the GLU reference pages in the OpenGL Reference Manual for details on using the GLU library. Table 3-10 summarizes OpenGL quadrics calls.

Table 3-10. Calls for Drawing Quadrics

OpenGL Call

Meaning

gluNewQuadric()

Create a new quadric object.

gluDeleteQuadric()

Delete a quadric object.

gluQuadricCallback()

Associate a callback with a quadric object, for error handling.

gluQuadricNormals()

Specify normals: no normals, one per face, or one per vertex.

gluQuadricOrientation()

Specify direction of normals: outward or inward.

gluQuadricTexture()

Turn texture coordinate generation on or off.

gluQuadricDrawstyle()

Specify drawing style: polygons, lines, points, and so on.

gluSphere()

Draw a sphere.

gluCylinder()

Draw a cylinder or cone.

gluPartialDisk()

Draw an arc.

gluDisk()

Draw a circle or disk.

You can use one quadric object for all quadrics you'd like to render in similar ways. The code fragment in Example 3-1 uses two quadrics objects to draw four quadrics, two of them textured.

Example 3-1. Drawing Quadrics Objects

GLUquadricObj    *texturedQuad, *plainQuad;

texturedQuad = gluNewQuadric(void);
gluQuadricTexture(texturedQuad, GL_TRUE);
gluQuadricOrientation(texturedQuad, GLU_OUTSIDE);
gluQuadricDrawStyle(texturedQuad, GLU_FILL);

plainQuad = gluNewQuadric(void);
gluQuadricDrawStyle(plainQuad, GLU_LINE);

glColor3f (1.0, 1.0, 1.0);

gluSphere(texturedQuad, 5.0, 20, 20);
glTranslatef(10.0, 10.0, 0.0);
gluCylinder(texturedQuad, 2.5, 5, 5, 10, 10);
glTranslatef(10.0, 10.0, 0.0);
gluDisk(plainQuad, 2.0, 5.0, 10, 10);
glTranslatef(10.0, 10.0, 0.0);
gluSphere(plainQuad, 5.0, 20, 20);


Porting v() Commands

In IRIS GL, you use variations on the v() call to specify vertices. The OpenGL glVertex() call is a direct successor of this call:

glVertex2[d|f|i|s][v]( x, y );

glVertex3[d|f|i|s][v]( x, y, z);
glVertex4[d|f|i|s][v]( x, y, z, w);

glVertex() takes suffixes the same way other OpenGL calls do. The vector versions of the call take arrays of the proper size as arguments. In the 2D version, z = 0 and w = 1. In the 3D version, w = 1.

Porting bgn/end Commands

IRIS GL uses the begin/end paradigm but has a different call for each graphics primitive. For example, bgnpolygon() and endpolygon() draw polygons, and bgnline() and endline() draw lines. In OpenGL, you use the glBegin()/glEnd() structure. OpenGL draws most geometric objects by enclosing a series of calls that specify vertices, normals, textures, and colors between pairs of glBegin() and glEnd() calls.

void glBegin( GLenum mode) ;
   /* vertex list, colors, normals, textures, materials */
void glEnd( void );

glBegin() takes a single argument that specifies the drawing mode, and thus the primitive. Here's an OpenGL code fragment that draws a polygon and then a line:

glBegin( GL_POLYGON) ;
   glVertex2f(20.0, 10.0);
   glVertex2f(10.0, 30.0);
   glVertex2f(20.0, 50.0);
   glVertex2f(40.0, 50.0);
   glVertex2f(50.0, 30.0);
   glVertex2f(40.0, 10.0);
glEnd();
glBegin( GL_LINES ) ;
   glVertex2i(100,100);
   glVertex2i(500,500);
glEnd();

In OpenGL, you draw different geometric objects by specifying different arguments to glBegin(). These arguments are listed in Table 3-11 below, along with the IRIS GL calls they replace (if any). There is no limit to the number of vertices you can specify between a glBegin()/glEnd() pair.

Table 3-11. Calls for Drawing Primitives

IRIS GL Call

Value of glBegin() Mode

Meaning

bgnpoint()

GL_POINTS

Individual points

bgnline()

GL_LINE_STRIP

Series of connected line segments

bgnclosedline()

GL_LINE_LOOP

Series of connected line segments, with a segment added between first and last vertices

GL_LINES

Pairs of vertices interpreted as individual line segments

bgnpolygon()

GL_POLYGON

Boundary of a simple convex polygon

GL_TRIANGLES

Triples of vertices interpreted as triangles

bgntmesh()

GL_TRIANGLE_STRIP

Linked strips of triangles

GL_TRIANGLE_FAN

Linked fans of triangles

GL_QUADS

Quadruples of vertices interpreted as quadrilaterals

bgnqstrip()

GL_QUAD_STRIP

Linked strips of quadrilaterals

For a detailed discussion of the differences between triangle meshes, strips, and fans, see “Porting Triangles”.

In addition to specifying vertices inside a glBegin()/glEnd() pair, you can also specify a current normal, current texture coordinates, and a current color. Table 3-12 lists the commands valid inside a glBegin()/glEnd() pair.

Table 3-12. Valid Commands Inside a Begin/End Structure

IRIS GL Call

OpenGL Equivalent

Meaning

v2*(), v3*(), v4*()

glVertex*()

Set vertex coordinates.

RGBcolor(), cpack()

glColor*()

Set current color.

color(), colorf()

glIndex*()

Set current color index.

n3f()

glNormal*()

Set normal vector coordinates.

glEvalCoord()

Evaluate enabled one- and two-dimensional maps.

callobj()

glCallList(),

glCallLists()

Execute display list(s).

t2()

glTexCoord()

Set texture coordinates.

glEdgeFlag()

Control drawing edges.

lmbind()

glMaterial()

Set material properties.

If you use any other OpenGL command inside a glBegin()/glEnd() pair, results are unpredictable and an error may result.

Porting Points

OpenGL has no command to draw a single point. Otherwise, porting point calls is straightforward. Table 3-13 lists commands for drawing points.

Table 3-13. Calls for Drawing Points

IRIS GL Call

OpenGL Equivalent

Meaning

pnt()

Draw a single point.

bgnpoint(),

endpoint()

glBegin(GL_POINTS),

glEnd()

Interpret vertices as points.

pntsize()

glPointSize()

Set point size in pixels.

pntsmooth()

glEnable(GL_POINT_SMOOTH)

Turn on point antialiasing (see “Porting Antialiasing Calls”).

See the glPointSize reference page for information about related glGet*() commands.

Porting Lines

Porting code that draws lines is fairly straightforward, though you should note the differences in the way OpenGL does stipples.

Table 3-14. Calls for Drawing Lines

IRIS GL Call

OpenGL Call

Meaning

bgnclosedline(),

endclosedline()

glBegin(GL_LINE_LOOP)

glEnd()

Draw a closed line.

bgnline()

glBegin(GL_LINE_STRIP)

Draw line segments.

linewidth()

glLineWidth()

Set line width.

getlwidth()

glGet*(GL_LINE_WIDTH)

Return current line width.

deflinestyle()

setlinestyle()

glLineStipple(factor, pattern)

Specify a line stipple pattern.

lsrepeat()

factor argument of glLineStipple()

Set a repeat factor for the line style.

getlstyle()

glGet*(GL_LINE_STIPPLE_PATTERN)

Return line stipple pattern.

getlsrepeat()

glGet*(GL_LINE_STIPPLE_REPEAT)

Return repeat factor.

linesmooth(),

smoothline()

glEnable(GL_LINE_SMOOTH)

Turn on line antialiasing (see “Porting Antialiasing Calls”).

There are no tables for line stipples. OpenGL maintains only one line stipple pattern. You can use glPushAttrib() and glPopAttrib() to switch between different stipple patterns.

Old-style line style routines are not supported by OpenGL. If you used the calls: draw(), lsbackup(), getlsbackup(), resetls(), getresetls(), reimplement that part of your program.

For information on drawing antialiased lines, see “Porting Antialiasing Calls”.

Porting Polygons and Quadrilaterals

When porting polygons and quadrilaterals, consider the following issues:

  • There is no direct equivalent for concave(TRUE). Consider using the GLU tessellation routines described in “Porting Tessellated Polygons”.

  • Polygon modes are now set differently.

  • These older polygon drawing calls have no direct equivalents in OpenGL:

    • the poly() family of routines

    • the polf() family of routines

    • pmv(), pdr(), and pclos()

    • rpmv() and rpdr()

    • splf()

    • spclos()

    If you used these calls, reimplement that part of the program using glBegin(GL_POLYGON).

Table 3-15 lists the OpenGL equivalents to IRIS GL polygon drawing calls.

Table 3-15. Calls for Drawing Polygons

IRIS GL Call

OpenGL Equivalent

Meaning

bgnpolygon(), endpolygon()

glBegin(GL_POLYGON), glEnd()

Vertices define boundary of a simple convex polygon.

glBegin(GL_QUADS), glEnd()

Interpret quadruples of vertices as quadrilaterals.

bgnqstrip(), endqstrip()

glBegin(GL_QUAD_STRIP), glEnd()

Interpret vertices as linked strips of quadrilaterals.

glEdgeFlag()

 

polymode()

glPolygonMode()

Set polygon drawing mode.

rect(),

rectf()

glRect()

Draw a rectangle.

sbox(),

sboxf()

Draw a screen-aligned rectangle.


Setting Polygon Modes

The call for setting the polygon mode has changed slightly. The OpenGL call glPolygonMode() allows you to specify which side of a polygon (front or back) the mode applies to. Its syntax is

void glPolygonMode( GLenum face, GLenum mode )

face is one of the following:

GL_FRONT

Mode applies to front-facing polygons.

GL_BACK

Mode applies to back-facing polygons.

GL_FRONT_AND_BACK

Mode applies to both front- and back-facing polygons.

The equivalents to IRIS GL polymode() calls would use GL_FRONT_AND_BACK. Table 3-16 lists IRIS GL polygon modes and the corresponding OpenGL modes.

Table 3-16. Polygon Modes

IRIS GL Mode

OpenGL Mode

Meaning

PYM_POINT

GL_POINT

Draw vertices as points.

PYM_LINE

GL_LINE

Draw boundary edges as line segments.

PYM_FILL

GL_FILL

Draw polygon interior filled.

PYM_HOLLOW

Fill only interior pixels at the boundaries.


Setting Polygon Stipples

When porting polygon stipples, consider the following issues:

  • There are no tables for polygon stipples. OpenGL keeps only one stipple pattern. You can use display lists to store different stipple patterns.

  • The polygon stipple bitmap size is always a 32 x 32 bit pattern.

  • Stipple encoding is affected by glPixelStore(). See “Porting Pixel Operations” for more information.

Table 3-17 lists polygon stipple calls.

Table 3-17. Polygon Stipple Calls

IRIS GL Call

OpenGL Call

Meaning

defpattern()

glPolygonStipple()

Set the stipple pattern.

setpattern()

OpenGL keeps only one polygon stipple pattern.

getpattern()

glGetPolygonStipple()

Return the stipple bitmap (used to return an index).

Enable and disable polygon stippling by passing GL_POLYGON_STIPPLE as an argument to glEnable() and glDisable().

Example 3-2 shows an OpenGL code fragment that demonstrates polygon stippling.

Example 3-2. OpenGL Polygon Stippling

/*  polys.c  */
#include <GL/gl.h>
#include <GL/glu.h>

void display(void)
{
    GLubyte fly[] = {
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x03, 0x80, 0x01, 0xC0, 0x06, 0xC0, 0x03, 0x60,
      0x04, 0x60, 0x06, 0x20, 0x04, 0x30, 0x0C, 0x20,
      0x04, 0x18, 0x18, 0x20, 0x04, 0x0C, 0x30, 0x20,
      0x04, 0x06, 0x60, 0x20, 0x44, 0x03, 0xC0, 0x22,
      0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22,
      0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22,
      0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22,
      0x66, 0x01, 0x80, 0x66, 0x33, 0x01, 0x80, 0xCC,
      0x19, 0x81, 0x81, 0x98, 0x0C, 0xC1, 0x83, 0x30,
      0x07, 0xe1, 0x87, 0xe0, 0x03, 0x3f, 0xfc, 0xc0,
      0x03, 0x31, 0x8c, 0xc0, 0x03, 0x33, 0xcc, 0xc0,
      0x06, 0x64, 0x26, 0x60, 0x0c, 0xcc, 0x33, 0x30,
      0x18, 0xcc, 0x33, 0x18, 0x10, 0xc4, 0x23, 0x08,
      0x10, 0x63, 0xC6, 0x08, 0x10, 0x30, 0x0c, 0x08,
      0x10, 0x18, 0x18, 0x08, 0x10, 0x00, 0x00, 0x08
    };
    GLubyte halftone[] = {
      0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
      0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
      0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
      0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
      0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
      0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
      0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
      0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
      0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
      0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
      0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
      0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
      0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
      0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
      0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
      0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55
    };

    glClear (GL_COLOR_BUFFER_BIT);
    glColor3f (1.0, 1.0, 1.0); /* draw all polys in white */

/*  draw 1 solid unstippled rectangle, then 2 stippled ones*/
    glRectf (25.0, 25.0, 125.0, 125.0);
    glEnable (GL_POLYGON_STIPPLE);
    glPolygonStipple (fly);
    glRectf (125.0, 25.0, 225.0, 125.0);
    glPolygonStipple (halftone);
    glRectf (225.0, 25.0, 325.0, 125.0);
    glDisable (GL_POLYGON_STIPPLE);
    glFlush ();
}


Porting Tessellated Polygons

The GLU has routines you can use to draw concave polygons. You no longer just use concave(TRUE) and then bgnpolygon().

To draw a concave polygon with OpenGL, follow these steps:

  1. Create a tesselation object.

  2. Define callbacks that will be used to process the triangles generated by the tessellator.

  3. Specify the concave polygon to be tessellated.

Table 3-18 lists the calls for drawing tessellated polygons.

Table 3-18. Tessellated Polygon Calls

GLU Call

Meaning

gluNewTess()

Create a new tessellation object.

gluDeleteTess()

Delete a tessellation object.

gluTessCallback()

gluBeginPolygon()

Begin the polygon specification.

gluTessVertex()

Specify a polygon vertex. Successive gluTessVertex() calls describe a closed contour.

gluNextContour()

Indicate that the next series of vertices describe a new contour.

gluEndPolygon()

End the polygon specification.

For details, see the reference pages for the commands in Table 3-18.

Porting Triangles

OpenGL provides three ways to draw triangles: separate triangles, triangle strips, and triangle fans.

When porting triangles, consider the following issues:

  • There's no OpenGL equivalent for swaptmesh(). Instead, use a combination of triangles, triangle strips, and triangle fans.

  • If your IRIS GL program draws individual triangles by surrounding each triangle with a bgntmesh() / endtmesh() pair, surround the entire group of individual triangles with just one glBegin(GL_TRIANGLES) / glEnd() pair in your OpenGL program, for a noticeable performance increase.

Table 3-19 lists the commands for drawing triangles.

Table 3-19. Calls for Drawing Triangles

IRIS GL Call

Equivalent glBegin() Argument

Meaning

GL_TRIANGLES

Triples of vertices interpreted as triangles.

bgntmesh(), endtmesh()

GL_TRIANGLE_STRIP

Linked strips of triangles.

GL_TRIANGLE_FAN

Linked fans of triangles.


Porting Arcs and Circles

In OpenGL, filled arcs and circles are drawn with the same calls as unfilled arcs and circles. See the reference pages for specifics. Table 3-20 lists the IRIS GL arc and circle commands and the corresponding OpenGL (GLU) commands.

Table 3-20. Calls for Drawing Arcs and Circles

IRIS GL Call

OpenGL Call

Meaning

arc(), arcf()

gluPartialDisk()

Draw an arc.

circ(), circf()

gluDisk()

Draw a circle or disk.

The gluPartialDisk() call is different from the arc() call. See the gluPartialDisk reference page for complete information.

IRIS GL arcs and circles are called disks and partial disks in OpenGL. You can do some things with OpenGL disks and partial disks that you could not do with IRIS GL. See the OpenGL Programming Guide and the reference pages in the OpenGL Reference Manual for detailed information.

When porting arcs and circles, consider these issues:

  • Angles are no longer measured in tenths of degrees, but simply in degrees.

  • The start angle is measured from the positive y axis, and not from the x axis.

  • The sweep angle is now clockwise instead of counterclockwise, as shown in Figure 3-4.

    Figure 3-4. Drawing Angles: Comparing IRIS GL and OpenGL

    Figure 3-4 Drawing Angles: Comparing IRIS GL and OpenGL

Porting Spheres

When porting spheres, consider these issues:

  • In OpenGL, you cannot control the type of primitives used to draw the sphere. Instead, you can control drawing precision by using the slices and stacks parameters. Slices are longitudinal; stacks are latitudinal.

  • Spheres are now drawn centered at the origin. Instead of specifying the location, as you used to in sphdraw() calls, precede a gluSphere() call with a translation.

  • The sphere library isn't yet available for OpenGL—see “Porting the IRIS GL Sphere Library” for more information about replacing sphere library calls.

Table 3-21 lists the IRIS GL calls for drawing spheres along with the corresponding GLU calls where available.

Table 3-21. Calls for Drawing Spheres

IRIS GL Call

GLU Call

Notes

sphobj()

gluNewQuadric()

Create a new sphere object.

sphfree()

gluDeleteQuadric()

Delete sphere object and free memory used.

sphdraw()

gluSphere()

Draw a sphere.

sphmode()

Set sphere attributes.

sphrotmatrix()

Control sphere orientation.

sphgnpolys()

Return number of polygons in current sphere.


Porting Color, Shading, and Writemask Commands

When porting color, shading, and writemask calls, note that color map implementation differs between OpenGL and IRIS GL and consider these issues:

  • Although you can set color map indices with the OpenGL glIndex() call, OpenGL doesn't provide a routine for loading color map indices. See “Using X Color Maps” for an example code fragment that sets up a color map.

  • Color values are normalized to their data type. See the glColor reference page for details.

  • There is no simple equivalent for cpack(). You can use glColor() instead, but you have to port explicitly.

  • Some calls to c() or color() may have to be translated to glClearColor() or glClearIndex() and not glColor() or glIndex(). See “Porting Screen and Buffer Clearing Commands” for details.

  • The RGBA writemask is not for each bit, just for each component.

  • IRIS GL provided defined color constants: BLACK, BLUE, RED, GREEN, MAGENTA, CYAN, YELLOW, and WHITE. OpenGL doesn't provide these constants and toogl doesn't translate them, so you have to port them explicitly.

Porting Color Calls

Table 3-22 lists IRIS GL color calls and their OpenGL equivalents.

Table 3-22. Color Calls

IRIS GL Call

OpenGL Call

Meaning

c3*(), c4*()

glColor*()

Sets RGB color.

color(), colorf()

glIndex*()

Sets the color index.

getcolor()

glGet*(GL_CURRENT_INDEX)

Returns the current color index.

getmcolor()

XQueryColor()

Gets a copy of a colormap entry's RGB values.

gRGBcolor()

glGet*(GL_CURRENT_COLOR)

Gets the current RGB color values.

mapcolor()

XStoreColor()

See “Using X Color Maps”.

RGBcolor()

glColor()

Sets RGB color.

writemask()

glIndexMask()

Sets the color index mode color mask.

wmpack()

RGBwritemask()

glColorMask()

Sets the RGB color mode mask.

getwritemask()

glGet*(GL_COLOR_WRITEMASK)

glGet*(GL_INDEX_WRITEMASK)

Gets the color mask.

gRGBmask()

glGet*(GL_COLOR_WRITEMASK)

Gets the color mask.

zwritemask()

glDepthMask()



Note: Be careful when replacing zwritemask() with glDepthMask(): glDepthMask() takes a boolean argument; zwritemask() takes a bitfield.

If you want to use multiple color maps, use the X colormap facilities. The functions multimap(), onemap(), getcmmode(), setmap(), and getmap() have no OpenGL equivalents.

Porting Shading Models

Just like IRIS GL, OpenGL lets you switch between smooth (Gouraud) shading and flat shading. Table 3-23 lists the calls.

Table 3-23. Shading and Dithering

IRIS GL Call

OpenGL Call

Meaning

shademodel(FLAT)

glShadeModel(GL_FLAT)

Do flat shading.

shademodel(GOURAUD)

glShadeModel(GL_SMOOTH)

Do smooth shading.

getsm()

glGet*(GL_SHADE_MODEL)

Return current shade model.

dither(DT_ON)

dither(DT_OFF)

glEnable(GL_DITHER)

glDisable(GL_DITHER)

Turn dithering on/off.

Smooth shading and dithering are on by default, as in IRIS GL.

Porting Pixel Operations

When porting pixel operations, consider the following issues:

  • Logical pixel operations are not applied to RGBA color buffers. See the glLogicOp reference page for more information.

  • In general, IRIS GL used the ABGR format for pixels (that is, with color components in the order Alpha, Blue, Green, Red), while OpenGL uses the RGBA format. Although glPixelStore() can reverse the order of bytes within a color component, it can't reverse the order of the components within a pixel; thus, it can't be used to convert IRIS GL pixels to OpenGL pixels. Instead, you must reverse the order of the components yourself.

  • When porting lrectwrite() calls, be careful to note where lrectwrite() is writing (for instance, it could be writing to the depth buffer).

  • If you wanted to read from the z-buffer in IRIS GL, you specified that buffer with readsource() and then used lrectread() or rectread() to do the reading. If you want to read from the z-buffer in OpenGL, you simply specify that buffer as a parameter to glReadPixels().

OpenGL provides some additional flexibility in pixel operations. Table 3-24 lists calls for pixel operations.

Table 3-24. Pixel Operations

IRIS GL Call

OpenGL Call

Meaning

lrectread(), rectread(),

readRGB()

glReadPixels()

Read a block of pixels from the frame buffer.

lrectwrite(), rectwrite()

glDrawPixels()

Write a block of pixels to the frame buffer.

rectcopy()

glCopyPixels()

Copy pixels in the frame buffer.

rectzoom()

glPixelZoom()

Specify pixel zoom factors for glDrawPixels() and glCopyPixels().

cmov()

glRasterPos()

Specify raster position for pixel operations.

readsource()

glReadBuffer()

Select a color buffer source for pixels.

pixmode()

glPixelStore()

Set pixel storage modes.

pixmode()

glPixelTransfer()

Set pixel transfer modes.

logicop()

glLogicOp()

Specify a logical operation for pixel writes.

glEnable(GL_LOGIC_OP)

Turn on pixel logic operations.

See the reference page for glLogicOp for a list of possible logical operations.

Here's a code fragment that shows a typical pixel write operation:

unsigned long *packedRaster;
...
packedRaster[k] = 0x00000000;
...
lrectwrite(0, 0, xSize, ySize, packedRaster);

Here is how toogl translates the call to lrectwrite():

/* OGLXXX lrectwrite: see man page for glDrawPixels */
glRasterPos2i(0,  0);
glDrawPixels(( xSize)-(0)+1, ( ySize)-( 0)+1, GL_RGBA,
             GL_UNSIGNED_BYTE, packedRaster);

After some tweaking, the finished code might look like this:

glRasterPos2i(0, 0);
glDrawPixels(xSize + 1, ySize + 1, GL_RGBA,
             GL_UNSIGNED_BYTE, packedRaster);

Porting Depth Cueing and Fog Commands

When porting depth cueing and fog commands, consider these issues:

  • The fog calls have been restructured, so you have to rewrite them explicitly in most cases. The IRIS GL call fogvertex() set a mode and parameters affecting that mode. In OpenGL, you call glFog() once to set the mode, then again twice or more to set various parameters.

  • Depth cueing is no longer a separate feature. Use linear fog instead of depth cueing. (This section provides an example of how to do this.) The following calls therefore have no direct OpenGL equivalent:

    • depthcue()

    • lRGBrange()

    • lshaderange()

    • getdcm()

  • To adjust fog quality, call glHint(GL_FOG_HINT).

Table 3-25 lists the IRIS GL calls for managing fog along with the corresponding OpenGL calls.

Table 3-25. Calls for Managing Fog

IRIS GL Call

OpenGL Call

Meaning

fogvertex()

glFog()

Set various fog parameters.

fogvertex(FG_ON)

glEnable(GL_FOG)

Turn fog on.

fogvertex(FG_OFF)

glDisable(GL_FOG)

Turn fog off.

depthcue()

glFog(GL_FOG_MODE, GL_LINEAR)

Use linear fog for depth cueing.

Table 3-26 lists the arguments you can pass to glFog().

Table 3-26. Fog Parameters

Fog Parameter

Meaning

Default

GL_FOG_DENSITY

Fog density.

1.0

GL_FOG_START

Near distance for linear fog.

0.0

GL_FOG_END

Far distance for linear fog.

1.0

GL_FOG_INDEX

Fog color index.

0.0

GL_FOG_COLOR

Fog RGBA color.

(0, 0, 0, 0)

GL_FOG_MODE

Fog mode.

see Table 3-27

The OpenGL fog density argument differs from the IRIS GL fog density argument. They are related as follows:

  • If fogMode is EXP2:

    openGLfogDensity = (IRISGLfogDensity) (sqrt( - log( 1 / 255 ) ))

  • If fogMode is EXP:

    openGLfogDensity = (IRISGLfogDensity) (- log( 1 / 255 ) )

where

sqrt

Is the square root operation.

log

Is the natural logarithm.

IRISGLfogDensity

Is the IRIS GL fog density.

openGLfogDensity

Is the OpenGL fog density.

To switch between calculating fog in per-pixel mode and per-vertex mode, use glHint(GL_FOG_HINT, hintMode). Two hint modes are available:

GL_NICEST 

per-pixel fog calculation

GL_FASTEST 

per-vertex fog calculation

Table 3-27 lists the OpenGL equivalents for IRIS GL fog modes.

Table 3-27. Fog Modes

IRIS GL Fog Mode

OpenGL Fog Mode

Hint Mode

Meaning

FG_VTX_EXP,

FG_PIX_EXP

GL_EXP

GL_FASTEST,

GL_NICEST

Heavy fog mode (default)

FG_VTX_EXP2,

FG_PIX_EXP2

GL_EXP2

GL_FASTEST,

GL_NICEST

Haze mode

FG_VTX_LIN,

FG_PIX_LIN

GL_LINEAR

GL_FASTEST,

GL_NICEST

Linear fog mode (use for depthcueing)

Example 3-3 shows a code fragment that demonstrates depth cueing in OpenGL.

Example 3-3. Depth Cueing in OpenGL

/*
 *  depthcue.c
 *  This program draws a wireframe model, which uses
 *  intensity (brightness) to give clues to distance.
 *  Fog is used to achieve this effect.
 */
#include <stdlib.h>
#include <GL/glut.h>

/*  Initialize linear fog for depth cueing.
 */
void myinit(void)
{
    GLfloat fogColor[4] = {0.0, 0.0, 0.0, 1.0};

    glEnable(GL_FOG);
    glFogi(GL_FOG_MODE, GL_LINEAR);
    glHint(GL_FOG_HINT, GL_NICEST);  /*  per pixel   */
    glFogf(GL_FOG_START, 3.0);
    glFogf(GL_FOG_END, 5.0);
    glFogfv(GL_FOG_COLOR, fogColor);
    glClearColor(0.0, 0.0, 0.0, 1.0);

    glDepthFunc(GL_LESS);
    glEnable(GL_DEPTH_TEST);
    glShadeModel(GL_FLAT);
}

/*  display() draws an icosahedron.
 */
void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glColor3f(1.0, 1.0, 1.0);
    glutWireIcosahedron();
    glFlush();
}

void myReshape(int w, int h)
{
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0, (GLfloat)w/(GLfloat)h, 3.0, 5.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(0.0, 0.0, -4.0);  /*  move object into view   */
}

/*  Main Loop
 */
int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode (GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH);
    glutCreateWindow(argv[0]);
    myinit();
    glutReshapeFunc(myReshape);
    glutDisplayFunc(display);
    glutMainLoop();
    return 0;             /* ANSI C requires main to return int. */
}


Porting Curve and Surface Commands

OpenGL doesn't support equivalents to the old-style curves and surface patches. You have to reimplement your code if it uses any of these calls:

  • defbasis()

  • curvebasis(), curveprecision(), crv(), crvn(), rcrv(), rcrvn(), and curveit()

  • patchbasis(), patchcurves(), patchprecision(), patch(), and rpatch()

Silicon Graphics recommends that you reimplement these calls using evaluators, rather than trying to replace them with NURBS. Refer to the OpenGL Reference Manual and to the section “Evaluators” on page 440 of the OpenGL Programming Guide, Second Edition, for more information on using evaluators.

NURBS Objects

OpenGL treats NURBS as objects, similar to the way it treats quadrics: you create a NURBS object and then specify how it should be rendered. Table 3-28 lists the NURBS object commands.

Table 3-28. Calls for Managing NURBS Objects

OpenGL Call

Meaning

gluNewNurbsRenderer()

Create a new NURBS object.

gluDeleteNurbsRenderer()

Delete a NURBS object.

gluNurbsCallback()

Associate a callback for error handling with a NURBS object.

When using NURBS objects, consider the following issues:

  • NURBS control points are now floats, not doubles.

  • The stride parameter is now counted in floats, not bytes.

  • If you're using lighting and you're not specifying normals, call glEnable() with GL_AUTO_NORMAL as the parameter to generate normals automatically.

NURBS Curves

The OpenGL calls for drawing NURBS are similar to the IRIS GL calls. You specify knot sequences and control points using a gluNurbsCurve() call, which must be contained within a glBeginCurve()/glEndCurve() pair.

Table 3-29 summarizes the calls for drawing NURBS curves.

Table 3-29. Calls for Drawing NURBS Curves

IRIS GL Call

OpenGL Call

Meaning

bgncurve()

gluBeginCurve()

Begin a curve definition.

nurbscurve()

gluNurbsCurve()

Specify curve attributes.

endcurve()

gluEndCurve()

End a curve definition.

Position, texture, and color coordinates are associated by presenting each as a separate gluNurbsCurve() inside the begin/end pair. You can make no more than one call to gluNurbsCurve() for each piece of color, position, and texture data within a single gluBeginCurve()/gluEndCurve() pair. You must make exactly one call to describe the position of the curve (a GL_MAP1_VERTEX_3 or GL_MAP1_VERTEX_4 description). When you call gluEndCurve(), the curve will be tessellated into line segments and then rendered.

Table 3-30 lists NURBS curve types.

Table 3-30. NURBS Curve Types

IRIS GL Type

OpenGL Type

Meaning

N_V3D

GL_MAP1_VERTEX_3

Polynomial curve.

N_V3DR

GL_MAP1_VERTEX_4

Rational curve.

GL_MAP1_TEXTURE_COORD_*

Control points are texture coordinates.

GL_MAP1_NORMAL

Control points are normals.

For more information on available evaluator types, see the glMap1 reference page.

Trimming Curves

OpenGL trimming curves are similar to IRIS GL trimming curves. Table 3-31 lists the calls for defining trimming curves.

Table 3-31. Calls for Drawing NURBS Trimming Curves

IRIS GL Call

OpenGL Call

Meaning

bgntrim()

gluBeginTrim()

Begin trimming curve definition.

pwlcurve()

gluPwlCurve()

Define a piecewise linear curve.

nurbscurve()

gluNurbsCurve()

Specify trimming curve attributes.

endtrim()

gluEndTrim()

End trimming curve definition.


NURBS Surfaces

Table 3-32 summarizes the calls for drawing NURBS surfaces.

Table 3-32. Calls for Drawing NURBS Surfaces

IRIS GL Call

OpenGL Call

Meaning

bgnsurface()

gluBeginSurface()

Begin a surface definition.

nurbssurface()

gluNurbsSurface()

Specify surface attributes.

endsurface()

gluEndSurface()

End a surface definition.

Table 3-33 lists parameters for surface types.

Table 3-33. NURBS Surface Types

IRIS GL Type

OpenGL Type

Meaning

N_V3D

GL_MAP2_VERTEX_3

Polynomial curve

N_V3DR

GL_MAP2_VERTEX_4

Rational curve

N_C4D

GL_MAP2_COLOR_4

Control points define color surface in (R,G,B,A) form

N_C4DR

N_T2D

GL_MAP2_TEXTURE_COORD_2

Control points are texture coordinates.

N_T2DR

GL_MAP2_TEXTURE_COORD_3

Control points are texture coordinates.

GL_MAP2_NORMAL

Control points are normals.

For more information on available evaluator types, see the glMap2 reference page.

Example 3-4 draws a trimmed NURBS surface.

Example 3-4. Drawing an OpenGL NURBS surface

/*
 *  trim.c
 *  This program draws a NURBS surface in the shape of a 
 *  symmetrical hill, using both a NURBS curve and pwl
 *  (piecewise linear) curve to trim part of the surface.
 */
#include <stdlib.h>
#include <GL/glut.h>
#include <stdio.h>

GLfloat ctlpoints[4][4][3];

GLUnurbsObj *theNurb;

/*
 *  Initializes the control points of the surface to a small hill.
 *  The control points range from -3 to +3 in x, y, and z
 */
void init_surface(void)
{
   int u, v;

   for (u = 0; u < 4; u++) {
      for (v = 0; v < 4; v++) {
         ctlpoints[u][v][0] = 2.0 * ((GLfloat)u - 1.5);
         ctlpoints[u][v][1] = 2.0 * ((GLfloat)v - 1.5);

         if ((u == 1 || u == 2) && (v == 1 || v == 2))
            ctlpoints[u][v][2] = 3.0;
         else
            ctlpoints[u][v][2] = -3.0;
      }
   }
}

void nurbsError(GLenum errorCode)
{
   const GLubyte *estring;

   estring = gluErrorString(errorCode);
   fprintf (stderr, "Nurbs Error: %s\n", estring);
   exit (0);
}
			
/*  Initialize material property and depth buffer.
 */
void init(void)
{
   GLfloat mat_diffuse[] = { 0.7, 0.7, 0.7, 1.0 };
   GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
   GLfloat mat_shininess[] = { 100.0 };

   glClearColor(0.0, 0.0, 0.0, 0.0);
   glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
   glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
   glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);

   glEnable(GL_LIGHTING);
   glEnable(GL_LIGHT0);
   glEnable(GL_DEPTH_TEST);
   glEnable(GL_AUTO_NORMAL);
   glEnable(GL_NORMALIZE);

   init_surface();

   theNurb = gluNewNurbsRenderer();
   gluNurbsProperty(theNurb, GLU_SAMPLING_TOLERANCE, 25.0);
   gluNurbsProperty(theNurb, GLU_DISPLAY_MODE, GLU_FILL);
   gluNurbsCallback(theNurb, GLU_ERROR, (GLvoid (CALLBACK*)())nurbsError);
}

void display(void)
{
   GLfloat knots[8] = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0};
   GLfloat edgePt[5][2] = /* counter clockwise */
      {{0.0, 0.0}, {1.0, 0.0}, {1.0, 1.0}, {0.0, 1.0}, {0.0, 0.0}};
   GLfloat curvePt[4][2] = /* clockwise */ 
      {{0.25, 0.5}, {0.25, 0.75}, {0.75, 0.75}, {0.75, 0.5}};
   GLfloat curveKnots[8] = 
      {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0};
   GLfloat pwlPt[4][2] = /* clockwise */ 
      {{0.75, 0.5}, {0.5, 0.25}, {0.25, 0.5}};

   glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
   glPushMatrix();
   glRotatef(330.0, 1.,0.,0.);
   glScalef(0.5, 0.5, 0.5);

   gluBeginSurface(theNurb);
   gluNurbsSurface(theNurb, 8, knots, 8, knots,
                   4*3, 3, &ctlpoints[0][0][0], 
                   4, 4, GL_MAP2_VERTEX_3);
   gluBeginTrim(theNurb);
      gluPwlCurve(theNurb, 5, &edgePt[0][0], 2, GLU_MAP1_TRIM_2);
   gluEndTrim(theNurb);
   gluBeginTrim(theNurb);
      gluNurbsCurve(theNurb, 8, curveKnots, 2, 
                    &curvePt[0][0], 4, GLU_MAP1_TRIM_2);
      gluPwlCurve(theNurb, 3, &pwlPt[0][0], 2, GLU_MAP1_TRIM_2);
   gluEndTrim(theNurb);
   gluEndSurface(theNurb);
        
   glPopMatrix();
   glFlush();
}

void reshape(int w, int h)
{
   glViewport(0, 0, (GLsizei)w, (GLsizei)h);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   gluPerspective(45.0, (GLdouble)w/(GLdouble)h, 3.0, 8.0);

   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
   glTranslatef(0.0, 0.0, -5.0);
}

/* ARGSUSED1 */
void keyboard(unsigned char key, int x, int y)
{
   switch (key) {
      case 27:
         exit(0);
         break;
   }
}

/*  Main Loop 
 */
int main(int argc, char **argv)
{
   glutInit(&argc, argv);
   glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH);
   glutInitWindowSize(500, 500);
   glutInitWindowPosition(100, 100);
   glutCreateWindow(argv[0]);
   init();
   glutReshapeFunc(reshape);
   glutDisplayFunc(display);
   glutKeyboardFunc(keyboard);
   glutMainLoop();
   return 0; 
}


Porting Antialiasing Calls

This section discusses topics related to antialiasing:

In OpenGL, subpixel mode is always on, so the IRIS GL call subpixel(TRUE) is not necessary and has no OpenGL equivalent.

Blending

Blending is off by default. If you use _DA or _MDA blend functions, you have to allocate destination alpha bits when you choose a visual. You have to use X to choose the visual, so refer to Chapter 4.


Tip: In IRIS GL, when drawing to both front and back buffers, blending is done by reading one of the buffers, blending with that color, and then writing the result to both buffers. In OpenGL, however, each buffer is read in turn, blended, and then written.

Table 3-34 lists IRIS GL and OpenGL blending calls.

Table 3-34. Blending Calls

IRIS GL

OpenGL

Meaning

glEnable(GL_BLEND)

Turn on blending.

blendfunction()

glBlendFunc()

Specify a blend function.

The calls glBlendFunc() and blendfunction() are almost identical. Table 3-35 lists the OpenGL equivalents to the IRIS GL blend factors.

Table 3-35. Blending Factors

IRIS GL

OpenGL

Notes

BF_ZERO

GL_ZERO

 

BF_ONE

GL_ONE

 

BF_SA

GL_SRC_ALPHA

 

BF_MSA

GL_ONE_MINUS_SRC_ALPHA

 

BF_DA

GL_DST_ALPHA

 

BF_MDA

GL_ONE_MINUS_DST_ALPHA

 

BF_SC

GL_SRC_COLOR

 

BF_MSC

GL_ONE_MINUS_SRC_COLOR

Destination only

BF_DC

GL_DST_COLOR

Source only

BF_MDC

GL_ONE_MINUS_DST_COLOR

Source only

BF_MIN_SA_MDA

GL_SRC_ALPHA_SATURATE

 


afunction() Test Functions

Table 3-36 lists the available alpha test functions.

Table 3-36. Alpha Test Functions

afunction()

glAlphaFunc()

AF_NOTEQUAL

GL_NOTEQUAL

AF_ALWAYS

GL_ALWAYS

AF_NEVER

GL_NEVER

AF_LESS

GL_LESS

AF_EQUAL

GL_EQUAL

AF_LEQUAL

GL_LEQUAL

AF_GREATER

GL_GREATER

AF_GEQUAL

GL_GEQUAL


Antialiasing Calls

OpenGL has direct equivalents to the IRIS GL antialiasing calls. Table 3-37 lists them.

Table 3-37. Calls to Draw Antialiased Primitives

IRIS GL Call

OpenGL Call

Meaning

pntsmooth()

glEnable(GL_POINT_SMOOTH)

Enable antialiasing of points.

linesmooth()

glEnable(GL_LINE_SMOOTH)

Enable antialiasing of lines.

polysmooth()

glEnable(GL_POLYGON_SMOOTH)

Enable antialiasing of polygons.

Use the corresponding glDisable() calls to turn off antialiasing.

In IRIS GL, you can control the quality of the antialiasing by calling

linesmooth(SML_ON + SML_SMOOTHER);

OpenGL provides similar control—use glHint():

glHint(GL_POINT_SMOOTH_HINT, hintMode);
glHint(GL_LINE_SMOOTH_HINT, hintMode);
glHint(GL_POLYGON_SMOOTH_HINT, hintMode);

hintMode is one of the following:

GL_NICEST

Use the highest quality smoothing.

GL_FASTEST

Use the most efficient smoothing.

GL_DONT_CARE

You don't care which smoothing method is used.

You could perform end correction in IRIS GL by calling

linesmooth(SML_ON + SML_END_CORRECT);

OpenGL doesn't provide an equivalent for this call.

Accumulation Buffer Calls

You must allocate your accumulation buffer by requesting the appropriate visual with glXChooseVisual(). For information on glXChooseVisual(), see the glXIntro and glXChooseVisual reference pages and refer to Chapter 4.

IRIS GL allows you to draw colors in the depth buffer, so acbuf() can use that buffer as a color source for accumulation. Some developers have used this depth-buffer reading capability to put depth data into accumulation buffers as well. OpenGL, on the other hand, doesn't put color information in the depth buffer; glAccum() thus can't read any information from the depth buffer.

To emulate accumulation from the depth buffer (using a configuration that supports auxiliary buffers) use the following procedure:

  1. Use glReadPixels() to read from the depth buffer.

  2. Massage the results as necessary.

  3. Draw the resulting data to an auxiliary buffer.

  4. Select this auxiliary buffer with glReadBuffer(), and use glAccum() to accumulate from that buffer.

This procedure requires caution in converting among data types.

Except as noted above, porting accumulation buffer calls is straightforward. Table 3-38 lists calls that affect the accumulation buffer.

Table 3-38. Accumulation Buffer Calls

IRIS GL Call

OpenGL Call

Meaning

acbuf()

glAccum()

Operate on the accumulation buffer.

glClearAccum()

Set clear values for accumulation buffer.

acbuf(AC_CLEAR)

glClear(GL_ACCUM_BUFFER_BIT)

Clear the accumulation buffer.

acsize()

glXChooseVisual()

Specify number of bitplanes per color component in accumulation buffer.

Table 3-39 lists the IRIS GL acbuf() arguments along with the corresponding arguments to the OpenGL glAccum() call.

Table 3-39. Accumulation Buffer Operations

IRIS GL Argument

OpenGL Argument

AC_ACCUMULATE

GL_ACCUM

AC_CLEAR_ACCUMULATE

GL_LOAD

AC_RETURN

GL_RETURN

AC_MULT

GL_MULT

AC_ADD

GL_ADD


Stencil Plane Calls

In OpenGL, you allocate stencil planes by requesting the appropriate visual with glXChooseVisual(). (For information on glXChooseVisual(), see the glXIntro and glXChooseVisual reference pages and refer to Chapter 4.) Otherwise, porting should be straightforward. Table 3-40 lists calls that affect the stencil planes.

Table 3-40. Stencil Operations

IRIS GL Call

OpenGL Call

Meaning

stensize()

glXChooseVisual()

stencil(TRUE, ...)

glEnable(GL_STENCIL_TEST)

Enable stencil tests.

stencil()

glStencilOp()

Set stencil test actions.

stencil(... func, ...)

glStencilFunc()

Set function & reference value for stencil testing.

swritemask()

glStencilMask()

Specify which stencil bits can be written.

glClearStencil()

Specify the clear value for the stencil buffer.

sclear()

glClear(GL_STENCIL_BUFFER_BIT)

Stencil comparison functions and stencil pass/fail operations are almost equivalent in OpenGL and IRIS GL. The IRIS GL stencil function flags are prefaced with SF, the OpenGL flags with GL. IRIS GL pass/fail operation flags are prefaced with ST, the OpenGL flags with GL. Compare the IRIS GL and OpenGL reference pages for further details.

Porting Display Lists

The OpenGL implementation of display lists is similar to the IRIS GL implementation, with two exceptions: you can't edit display lists once you've created them and you can't call functions from within display lists.

Because you can't edit or call functions from within display lists, these IRIS GL commands have no equivalents in OpenGL:

  • editobj()

  • objdelete(), objinsert(), and objreplace()

  • maketag(), gentag(), istag(), and deltag()

  • callfunc()

In IRIS GL, you used the commands makeobj() and closeobj() to create display lists. In OpenGL, you use glNewList() and glEndList(). For details on using glNewList() (including a description of the two list modes and a list of commands that are not compiled into the display list but are executed immediately), see the glNewList reference page and the OpenGL Programming Guide.

Table 3-41 lists the IRIS GL display list commands with the corresponding OpenGL commands.

Table 3-41. Display List Commands

IRIS GL Call

OpenGL Call

Meaning

makeobj()

glNewList()

Create a new display list.

closeobj()

glEndList()

Signal end of display list.

callobj()

glCallList(), glCallLists()

Execute display list(s).

isobj()

glIsList()

Test for display list existence.

delobj()

glDeleteLists()

Delete contiguous group of display lists.

genobj()

glGenLists()

Generate the given number of contiguous empty display lists.

glListBase()

Get the display list base for glCallLists().


Porting bbox2() Calls

The command bbox2() has no OpenGL equivalent. To port bbox2() calls, first create a new (OpenGL) display list that has everything that was in the corresponding IRIS GL display list except the bbox2() call. Then, in feedback mode, draw a rectangle the same size as the IRIS GL bounding box: if nothing comes back, the box was completely clipped and you shouldn't draw the display list.

Achieving Edited Display List Behavior

Although you can't actually edit OpenGL display lists, you can get a similar result by nesting display lists, then destroying and creating new versions of the sublists. The following OpenGL code fragment illustrates how to do this:

glNewList (1, GL_COMPILE);
    glIndexi (MY_RED);
glEndList ();
    glNewList (2, GL_COMPILE);
    glScalef (1.2, 1.2, 1.0);
glEndList ();

glNewList (3, GL_COMPILE);
    glCallList (1);
    glCallList (2);
glEndList ();
     .
     .
glDeleteLists (1, 2);
glNewList (1, GL_COMPILE);
    glIndexi (MY_CYAN);
glEndList ();
glNewList (2, GL_COMPILE);
    glScalef (0.5, 0.5, 1.0);
glEndList ();

Sample Implementation of a Display List

Example 3-5 defines three IRIS GL display lists. One display list refers to the others in its definition.

Example 3-5. IRIS GL Display Lists

makeobj (10);                             /* 10 object   */
   cpack (0x0000FF);
   recti (164, 33, 364, 600);             /* hollow rectangle */
closeobj ();

makeobj (20);                             /*20 object--various things*/
   cpack (0xFFFF00);
   circi(0,0,25);                         /* draw an unfilled circle */
   rectfi (100, 100, 200, 200);           /* draw filled rect */
closeobj ();
   
makeobj (30);                             /* 30 -- THE MAIN OBJECT */
   callobj (10);
   cpack (0xFFFFFF);      
   rectfi (400, 100, 500, 300);            /* draw filled rect */
   callobj (20);
closeobj ();
                                    /* now draw by calling the lists */
callobj(30);

Translated to OpenGL, the code from Example 3-5 might look Example 3-6.

Example 3-6. OpenGL Display Lists

glNewList( 10, GL_COMPILE );
   glColor3f( 1, 0, 0 );
   glRecti( 164, 33, 364, 600 );
glEndList();

glNewList( 20, GL_COMPILE );
   glColor3f( 1, 1, 0 );              /* set color to YELLOW  */
   glPolygonMode(GL_BOTH, GL_LINE);   /* unfilled mode */
   glBegin(GL_POLYGON);           /*use polygon to approximate circle*/
      for(i=0;i<100;i++) {
         cosine = 25 * cos(i*2*PI/100.0);
         sine =   25 * sin(i*2*PI/100.0);
        glVertex2f(cosine,sine);
      }
   glEnd();

   glBegin(GL_QUADS);
      glColorf( 0, 1, 1 );                    /* set color to CYAN  */
      glVertex2i(100,100);
      glVertex2i(100,200);
      glVertex2i(200,200);
      glVertex2i(100,200);
   glEnd();
glEndList();

glNewList(30, GL_COMPILE);                     /* List #30 */
   glCallList( 10 );
      glColorf( 1, 1, 1 );                     /* set color to WHITE */   
      glRecti(400, 100, 500, 300);
   glCallList( 20 );
glEndList();

                                        /* execute the display lists */
glCallList( 30 );


Porting defs, binds, and sets: Replacing `Tables' of Stored Definitions

OpenGL doesn't have tables of stored definitions—you cannot define lighting models, materials, textures, line styles, or patterns as separate objects as you could in IRIS GL. Thus, there are no direct equivalents to these IRIS GL calls:

  • lmdef() and lmbind()

  • tevdef() and tevbind()

  • texdef() and texbind()

  • deflinestyle() and setlinestyle()

  • defpattern() and setpattern()

However, you can use display lists to mimic the def/bind behavior. (It's often best to optimize by writing display lists that contain just a single material definition.)

For example, here is a material definition in IRIS GL:

float mat[] = {
    AMBIENT, .1, .1, .1,
    DIFFUSE, 0, .369, .165,
    SPECULAR, .5, .5, .5,
    SHININESS, 10,
    LMNULL
};
lmdef(DEFMATERIAL, 1, 0, mat);
lmbind(MATERIAL, 1);

In the following code fragment, the same material is defined in a display list, referred to by the list number in MYMATERIAL:

#define MYMATERIAL 10
/* you would probably use glGenLists() to get list numbers */
GLfloat   mat_amb[] = {.1, .1, .1, 1.0}; 
GLfloat   mat_dif[] = {0, .369, .165, 1.0};
GLfloat   mat_spec[] = { .5, .5, .5, 1.0};

glNewList( MYMATERIAL, GL_COMPILE );
    glMaterialfv( GL_FRONT, GL_AMBIENT, mat_amb);
    glMaterialfv( GL_FRONT, GL_DIFFUSE, mat_dif);
    glMaterialfv( GL_FRONT, GL_SPECULAR, mat_spec);
    glMateriali(  GL_FRONT, GL_SHININESS, 10);
glEndList();

glCallList( MYMATERIAL );

Porting Lighting and Materials Calls

You probably have to port lighting and materials code explicitly, because the OpenGL calls differ substantially from the IRIS GL calls. The OpenGL API has separate calls for setting lights, light models, and materials.

When porting lighting and materials calls, consider the following issues:

  • OpenGL has no table of stored definitions. It has no separate lmdef() and lmbind() calls. You can use display lists to mimic the def/bind behavior. See “Porting defs, binds, and sets: Replacing `Tables' of Stored Definitions” for an example. Using display lists can have the added benefit of improving your program's performance.

  • Attenuation is now associated with each light source, rather than with the overall lighting model.

  • Diffuse and specular components are separated out in OpenGL light sources.

  • OpenGL light sources have an alpha component. When porting your code, it's best to set the alpha component to 1.0, indicating 100% fully opaque. That way, alpha values will be determined solely by the alpha component of your materials and the objects in your scene will look just as they did in IRIS GL.

  • In IRIS GL, you could call lmcolor() between a call to bgnprimitive() and the corresponding endprimitive() call. In OpenGL, you can't call glColorMaterial() between a glBegin() and its corresponding glEnd().

Table 3-42 lists IRIS GL lighting and materials commands and the corresponding OpenGL commands.

Table 3-42. Lighting and Materials Commands

IRIS GL Call

OpenGL Call

Meaning

lmdef(DEFLIGHT,...)

glLight()

Define a light source.

lmdef(DEFLMODEL, ...)

glLightModel()

Define a lighting model.

lmbind()

glEnable(GL_LIGHTi)

Enable light i.

lmbind()

glEnable(GL_LIGHTING)

Enable lighting.

glGetLight()

Get light source parameters.

lmdef(DEFMATERIAL, ...)

glMaterial()

Define a material.

lmcolor()

glColorMaterial()

Change effect of color commands while lighting is active.

glGetMaterial()

Get material parameters.

When the first argument for lmbind() is DEFMATERIAL, the equivalent command is glMaterial(). Table 3-43 lists the various materials parameters you can set.

Table 3-43. Material Definition Parameters

lmdef() index

glMaterial() parameter

Default

Meaning

ALPHA

GL_DIFFUSE[a]

 

 

AMBIENT

GL_AMBIENT

(0.2, 0.2, 0.2, 1.0)

Ambient color

DIFFUSE

GL_DIFFUSE

(0.8, 0.8, 0.8, 1.0)

Diffuse color

SPECULAR

GL_SPECULAR[b]

(0.0, 0.0, 0.0, 1.0)

Specular color

EMISSION

GL_EMISSION

(0.0, 0.0, 0.0, 1.0)

Emissive color

SHININESS

GL_SHININESS

0.0

Specular exponent

GL_AMBIENT_AND_ DIFFUSE

(see above)

Equivalent to calling glMaterial() twice with same values

COLORINDEXES

GL_COLOR_INDEXES

Color indices for ambient, diffuse, and specular lighting

[a] The fourth value in the GL_DIFFUSE parameter specifies the alpha value.

[b] In IRIS GL, if the specular exponent (i.e. SHININESS) is zero, then the specular component of the light is not added in. In OpenGL, the specular component is added in anyway.

When the first argument of lmdef() is DEFLMODEL, the equivalent OpenGL call is glLightModel(). The exception is the case when the first argument of lmdef() is DEFLMODEL, ATTENUATION—in this case, you have to replace lmdef() with several glLight() calls. Table 3-44 lists equivalent lighting model parameters.

Table 3-44. Lighting Model Parameters

lmdef() index

glLightModel() Parameter

Default

Meaning

AMBIENT

GL_LIGHT_MODEL_AMBIENT

(0.2, 0.2, 0.2, 1.0)

Ambient color of scene.

ATTENUATION

See glLight().

LOCALVIEWER

GL_LIGHT_MODEL_
LOCAL_VIEWER

GL_FALSE

Viewer local (TRUE) or infinite (FALSE).

TWOSIDE

GL_LIGHT_MODEL_TWO_SIDE

GL_FALSE

Use two-sided lighting when TRUE.

When the first argument of lmdef() is DEFLIGHT, the equivalent OpenGL call is glLight(). Table 3-45 lists equivalent lighting parameters.

Table 3-45. Light Parameters

lmdef() index

glLight() Parameter

Default

Meaning

AMBIENT

GL_AMBIENT

(0.0, 0.0, 0.0, 1.0)

Ambient intensity.

 

GL_DIFFUSE

(1.0, 1.0, 1.0, 1.0)

Diffuse intensity.

 

GL_SPECULAR

(1.0, 1.0, 1.0, 1.0)

Specular intensity.

LCOLOR

 

 

 

POSITION

GL_POSITION

(0.0, 0.0, 1.0, 0.0)

Position of light.

SPOTDIRECTION

GL_SPOT_DIRECTION

(0, 0, -1)

Spot direction.

SPOTLIGHT

--

 

 

 

GL_SPOT_EXPONENT

0

Intensity distribution.

 

GL_SPOT_CUTOFF

180

Maximum spread angle of light source.

DEFLMODEL, ATTENUATION, ...

GL_CONSTANT_ATTENUATION

GL_LINEAR_ATTENUATION

GL_QUADRATIC_ATTENUATION

(1,0,0)

Attenuation factors.

Example 3-7 is an OpenGL code fragment that demonstrates some OpenGL lighting and material calls, including two-sided lighting.

Example 3-7. OpenGL Lighting and Material Calls

/* Initialize lighting */
void myinit(void)
{
    GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 };
    GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
    GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
/*      light_position is NOT default value     */
    GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };

    glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
    glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
    glLightfv(GL_LIGHT0, GL_POSITION, light_position);

    glFrontFace (GL_CW);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable(GL_AUTO_NORMAL);
    glEnable(GL_NORMALIZE);
    glDepthFunc(GL_LEQUAL);
    glEnable(GL_DEPTH_TEST);
}

void display(void)
{
    GLdouble eqn[4] = {1.0, 0.0, -1.0, 1.0};
    GLfloat mat_diffuse[] = { 0.8, 0.8, 0.8, 1.0 };
    GLfloat back_diffuse[] = { 0.8, 0.2, 0.8, 1.0 };

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glPushMatrix ();
    glClipPlane (GL_CLIP_PLANE0, eqn);  /*  slice objects   */
    glEnable (GL_CLIP_PLANE0);

    glPushMatrix ();
    glTranslatef (0.0, 2.0, 0.0);
    auxSolidTeapot(1.0);        /*  one-sided lighting  */
    glPopMatrix ();

        /*  two-sided lighting, but same material       */
    glLightModelf (GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
    glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE,
                  mat_diffuse);
    glPushMatrix ();
    glTranslatef (0.0, 0.0, 0.0);
    auxSolidTeapot(1.0);
    glPopMatrix ();

        /*  two-sided lighting, two different materials */
    glMaterialfv (GL_FRONT, GL_DIFFUSE, mat_diffuse);
    glMaterialfv (GL_BACK, GL_DIFFUSE, back_diffuse);
    glPushMatrix ();
    glTranslatef (0.0, -2.0, 0.0);
    auxSolidTeapot(1.0);
    glPopMatrix ();

    glLightModelf (GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
    glDisable (GL_CLIP_PLANE0);
    glPopMatrix ();
    glFlush();
}


Porting Texture Calls

When porting texture calls, consider these issues:

  • At times, a single IRIS GL texturing call has to be replaced with two or more OpenGL calls. For those cases, edit the toogl output to use more variables than it did before or restructure the program.

  • Use glEnable() and glDisable() to turn texturing capabilities on and off. See the reference page for details.

  • OpenGL doesn't automatically generate mipmaps for you—if you're using mipmaps, call gluBuild2DMipmaps() first.

  • Texture size in OpenGL is more strictly regulated than in IRIS GL. An OpenGL texture must be

    2n + 2b

    where n is an integer and b is

    • 0, if there's no border

    • 1, if there's a border pixel (textures in OpenGL can have 1 pixel borders)

  • OpenGL 1.0 keeps no tables of textures, just a single 1D texture and a single 2D texture. If you want to reuse your textures, put them in a display list, as described in “Porting defs, binds, and sets: Replacing `Tables' of Stored Definitions”.

  • In OpenGL 1.1, you can use named textures. Use the functions glBindTexture(), glGenTexture(), and glDeleteTextures() to work with named texture object. You can also call glPrioritizeTextures() to have certain textures preferentially be assigned to texture memory, and glAreTexturesResident() to determine whether a named texture is currently in texture memory.

  • In OpenGL 1.1, you can use the subtexture mechanism for more efficient texture loading.

  • OpenGL 1.1 offers the proxy texture mechanism to let you test whether a texture will fit into texture memory on a certain system.

Table 3-46 lists the general OpenGL equivalents to IRIS GL texture calls.

Table 3-46. Texture Commands

IRIS GL Call

OpenGL Call

Meaning

texdef2d()

glTexImage2D()

glTexParameter()

gluBuild2DMipmaps()

Specify a 2D texture image.

texbind()

glTexParameter()

glTexImage2D()

gluBuild2DMipmaps()

Select a texture function.

tevdef()

glTexEnv()

Define a texture mapping environment.

tevbind()

glTexEnv()

Select a texture environment.

glTexImage1D()

 

t2*(), t3*(), t4*()

glTexCoord*()

Set the current texture coordinates.

texgen()

glTexGen()

Control generation of texture coordinates.

glGetTexParameter()

gluBuild1DMipmaps()

gluBuild2DMipmaps()

gluScaleImage()

Scale an image to arbitrary size.

The OpenGL Programming Guide describes in detail how textures work in OpenGL. Here are a few general tips:

  • Remember to call gluBuild2DMipmaps() or gluBuild1DMipmaps() before trying to use mipmaps.

  • Use glTexParameter() to specify wrapping and filters.

  • Use glTexEnv() to set up texturing environment.

  • Use glTexImage2D() or glTexImage1D() to load each image.

  • Use glEnable() and glDisable() to turn texturing capabilities on and off.

See the reference page for each call for detailed information.

Translating tevdef()

Here's an example of an IRIS GL texture environment definition that specifies the TV_DECAL texture environment option:

float tevprops[] = {TV_DECAL, TV_NULL};

tevdef(1, 0, tevprops);

Here's how you could translate that code to OpenGL:

glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);

Table 3-47 lists the IRIS GL texture environment options and their OpenGL equivalents.

Table 3-47. Texture Environment Options

IRIS GL Option

OpenGL Option

TV_MODULATE

GL_MODULATE

TV_DECAL

GL_DECAL

TV_BLEND

GL_BLEND

TV_COLOR

GL_TEXTURE_ENV_COLOR

TV_ALPHA

no direct OpenGL equivalent

TV_COMPONENT_SELECT

no direct OpenGL equivalent

For more detailed information on how to use these options, see the glTexEnv reference page.

Translating texdef()

Here's an example of an IRIS GL texture definition:

float texprops[] = { TX_MINFILTER, TX_POINT,
                     TX_MAGFILTER, TX_POINT,
                     TX_WRAP_S, TX_REPEAT,
                     TX_WRAP_T, TX_REPEAT,
                     TX_NULL };
texdef2d(1, 1, 6, 6, granite_texture, 7, texprops)

In the above code example, texdef() specifies the TX_POINT filter as both the magnification and the minification filter, and TX_REPEAT as the wrapping behavior. It also specifies the texture image, in this case an image called granite_texture.

In OpenGL, the image specification is handled by the glTexImage*() functions and property-setting is handled by glTexParameter(). To translate to OpenGL, you'd replace a texdef() call with a call to a glTexImage*() routine and one or more calls to glTexParameter().

Here's an example of one way you could translate the IRIS GL code fragment above:

GLfloat nearest [] = {GL_NEAREST};
GLfloat repeat [] = {GL_REPEAT};
glTexParameterfv( GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER,
                  nearest);
glTexParameterfv( GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER,
                  nearest);
glTexParameterfv( GL_TEXTURE_1D, GL_TEXTURE_WRAP_S,
                  repeat);
glTexParameterfv( GL_TEXTURE_1D, GL_TEXTURE_WRAP_T,
                  repeat);
glTexImage1D(GL_TEXTURE_1D, 0, 1, 6, 0, GL_RGB,
                  GL_UNSIGNED_SHORT,granite_tex); 

Table 3-48 lists the IRIS GL texture parameters with their OpenGL equivalents. For more detailed information on OpenGL texture parameters, see the glTexParameter reference page.

Table 3-48. IRIS GL and OpenGL Texture Parameters

texdef(... np, ...) Option

glTexParameter() Parameter Name

TX_MINFILTER

GL_TEXTURE_MIN_FILTER

TX_MAGFILTER

GL_TEXTURE_MAG_FILTER

TX_WRAP, TX_WRAP_S

GL_TEXTURE_WRAP_S

TX_WRAP, TX_WRAP_T

GL_TEXTURE_WRAP_T

GL_TEXTURE_BORDER_COLOR

Table 3-49 lists the possible values of the IRIS GL texture parameters along with their OpenGL equivalents. If you used special values available only on systems with RealityEngine™ graphics, you may have to wait for RealityEngine extensions to OpenGL before you can translate these values exactly (see “Porting RealityEngine Graphics Features” for further discussion). For more information on possible values of OpenGL texture parameters, see the glTexParameter reference page.

Table 3-49. Values for IRIS GL and OpenGL Texture Parameters

IRIS GL

OpenGL

TX_POINT

GL_NEAREST

TX_BILINEAR

GL_LINEAR

TX_MIPMAP_POINT

GL_NEAREST_MIPMAP_NEAREST

TX_MIPMAP_BILINEAR

GL_LINEAR_MIPMAP_NEAREST

TX_MIPMAP_LINEAR

GL_NEAREST_MIPMAP_LINEAR

TX_TRILINEAR

GL_LINEAR_MIPMAP_LINEAR


Translating texgen()

The functionality of texgen() is replaced by glTexGen() almost entirely, though you have to call glEnable() and glDisable() to turn coordinate generation on and off. Table 3-50 lists the equivalents for texture coordinate names.

Table 3-50. Texture Coordinate Names

IRIS GL Texture Coordinate

OpenGL Texture Coordinate

glEnable() Argument

TX_S

GL_S

GL_TEXTURE_GEN_S

TX_T

GL_T

GL_TEXTURE_GEN_T

TX_R

GL_R

GL_TEXTURE_GEN_R

TX_Q

GL_Q

GL_TEXTURE_GEN_Q

Table 3-51 lists texture generation mode and plane names.

Table 3-51. Texture Generation Modes and Planes

IRIS GL Texture Mode

OpenGL Texture Mode

Corresponding Plane Name

TG_LINEAR

GL_OBJECT_LINEAR

GL_OBJECT_PLANE

TG_CONTOUR

GL_EYE_LINEAR

GL_EYE_PLANE

TG_SPHEREMAP

GL_SPHERE_MAP

With IRIS GL, you call texgen() twice: once to simultaneously set the mode and a plane equation, and once more to enable texture coordinate generation. In OpenGL, you make three calls: two to glTexGen() (once to set the mode, and again to set the plane equation), and one to glEnable(). For example, if you called texgen() like this:

texgen(TX_S, TG_LINEAR, planeParams);
texgen(TX_S, TG_ON, NULL);

the equivalent OpenGL code is:

glTexGen(GL_S, GL_TEXTURE_GEN_MODE, modeName);
glTexGen(GL_S, GL_OBJECT_PLANE, planeParams);
glEnable(GL_TEXTURE_GEN_S);

Porting Picking Calls

All the IRIS GL picking calls have OpenGL equivalents, with the exception of clearhitcode(). Table 3-52 lists the IRIS GL picking calls and their OpenGL counterparts.

Table 3-52. Calls for Picking

IRIS GL Call

OpenGL Call

Notes

clearhitcode()

not supported

Clears global variable, hitcode.

pick(),

select()

glRenderMode(GL_SELECT)

Switch to selection/picking mode.

endpick(),

endselect()

glRenderMode(GL_RENDER)

Switch back to rendering mode.

picksize()

gluPickMatrix()

 

glSelectBuffer()

Set the return array.

initnames()

glInitNames()

pushname(), popname()

glPushName(), glPopName()

loadname()

glLoadName()

For more information on picking, refer to the gluPickMatrix reference page and the OpenGL Programming Guide. You can find a complete example and additional explanation in “OpenGL Programming for the X Window System,” page 438-441. See “GLX and GLUT Documentation”.

Porting Feedback Calls

Feedback under IRIS GL differed from machine to machine. OpenGL standardizes feedback, so you can now rely on consistent feedback from machine to machine, and from implementation to implementation. Table 3-53 lists IRIS GL and OpenGL feedback calls.

Table 3-53. Feedback Calls

IRIS GL Call

OpenGL Call

Notes

feedback()

glRenderMode(GL_FEEDBACK)

Switch to feedback mode.

endfeedback()

glRenderMode(GL_RENDER)

Switch back to rendering mode.

glFeedbackBuffer()

passthrough()

glPassThrough()

Place a token marker in the feedback buffer.

For more information, see the reference pages or the OpenGL Programming Guide.

Example 3-8 demonstrates OpenGL feedback.

Example 3-8. Feedback in OpenGL

/*
 * feedback.c
 * This program demonstrates use of OpenGL feedback.  First,
 * a lighting environment is set up and a few lines are drawn.
 * Then feedback mode is entered, and the same lines are 
 * drawn.  The results in the feedback buffer are printed.
 */
#include <GL/glut.h>
#include <stdlib.h>
#include <stdio.h>

/*  Initialize lighting.
 */
void init(void)
{
   glEnable(GL_LIGHTING);
   glEnable(GL_LIGHT0);
}

/* Draw a few lines and two points, one of which will 
 * be clipped.  If in feedback mode, a passthrough token 
 * is issued between the each primitive.
 */
void drawGeometry(GLenum mode)
{
   glBegin(GL_LINE_STRIP);
   glNormal3f(0.0, 0.0, 1.0);
   glVertex3f(30.0, 30.0, 0.0);
   glVertex3f(50.0, 60.0, 0.0);
   glVertex3f(70.0, 40.0, 0.0);
   glEnd();
   if (mode == GL_FEEDBACK)
      glPassThrough(1.0);
   glBegin(GL_POINTS);
   glVertex3f(-100.0, -100.0, -100.0);  /*  will be clipped  */
   glEnd();
   if (mode == GL_FEEDBACK)
      glPassThrough(2.0);
   glBegin(GL_POINTS);
   glNormal3f(0.0, 0.0, 1.0);
   glVertex3f(50.0, 50.0, 0.0);
   glEnd();
}

/* Write contents of one vertex to stdout.
*/
void print3DcolorVertex(GLint size, GLint *count, GLfloat *buffer)
{
   int i;

   printf("  ");
   for (i = 0; i < 7; i++) {
      printf("%4.2f ", buffer[size-(*count)]);
      *count = *count - 1;
   }
   printf ("\n");
}

/*  Write contents of entire buffer. (Parse tokens!)
*/
void printBuffer(GLint size, GLfloat *buffer)
{
   GLint count;
   GLfloat token;

   count = size;
   while (count) {
      token = buffer[size-count];
      count--;
      if (token == GL_PASS_THROUGH_TOKEN) {
         printf("GL_PASS_THROUGH_TOKEN\n");
         printf("  %4.2f\n", buffer[size-count]);
         count--;
      } else if (token == GL_POINT_TOKEN) {
         printf("GL_POINT_TOKEN\n");
         print3DcolorVertex (size, &count, buffer);
      } else if (token == GL_LINE_TOKEN) {
         printf("GL_LINE_TOKEN\n");
         print3DcolorVertex(size, &count, buffer);
         print3DcolorVertex(size, &count, buffer);
      } else if (token == GL_LINE_RESET_TOKEN) {
         printf("GL_LINE_RESET_TOKEN\n");
         print3DcolorVertex(size, &count, buffer);
         print3DcolorVertex(size, &count, buffer);
      }
   }
}

void display(void)
{
   GLfloat feedBuffer[1024];
   GLint size;

   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   glOrtho(0.0, 100.0, 0.0, 100.0, 0.0, 1.0);

   glClearColor(0.0, 0.0, 0.0, 0.0);
   glClear(GL_COLOR_BUFFER_BIT);
   drawGeometry(GL_RENDER);

   glFeedbackBuffer(1024, GL_3D_COLOR, feedBuffer);
   glRenderMode(GL_FEEDBACK);
   drawGeometry(GL_FEEDBACK);

   size = glRenderMode(GL_RENDER);
   printBuffer(size, feedBuffer);
}

/* ARGSUSED1 */
void keyboard(unsigned char key, int x, int y)
{
   switch (key) {
      case 27:
         exit(0);
         break;
   }
}

int main(int argc, char **argv)
{
   glutInit(&argc, argv);
   glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
   glutInitWindowSize(100, 100);
   glutInitWindowPosition(100, 100);
   glutCreateWindow(argv[0]);
   init();
   glutDisplayFunc(display);
   glutKeyboardFunc(keyboard);
   glutMainLoop();
   return 0; 
}


Porting RealityEngine Graphics Features

Some IRIS GL features that were available only on systems with RealityEngine graphics are unavailable in OpenGL; though several of them are supported either by OpenGL 1.1 or by an extension.

Table 3-54 lists the IRIS GL RealityEngine calls and their OpenGL counterparts.

Table 3-54. RealityEngine Calls

IRIS GL Call

OpenGL Call

Notes

blendcolor()

glBlendColorEXT()

Specify a color to blend.

convolve()

glConvolutionFilter2DEXT(), glSeparableFilter2DEXT(), glConvolutionParameterEXT(), glPixelTransfer()

Convolve an input image with a kernel image.

displacepolygon()

glPolygonOffsetEXT() (OpenGL 1.0)

glPolygonOffset() (OpenGL 1.1)

Specify z displacement for rendered polygons.

fbsubtexload()

Not supported

Load part or all of a texture.

gethgram()

glGetHistogramEXT()

Get histogram data.

getminmax()

glGetMinmaxEXT()

Get minimum and maximum graphics values.

hgram()

glHistogramEXT(), glResetHistogramEXT()

Compute histogram of pixel-transfer information.

ilbuffer()

Not supported

Allocate space for temporary image-processing results.

ildraw()

Not supported

Select an ilbuffer to draw into.

istexloaded()

glAreTexturesResidentEXT (OpenGL 1.0)

glAreTexturesResident (OpenGL 1.1)

Find out whether a given texture is resident in texture memory.

leftbuffer()

glDrawBuffer(GL_LEFT)

Enable left-buffer drawing.

minmax()

glMinmaxEXT()

Compute minimum and maximum pixel values.

monobuffer()

Superseded by selection of an appropriate GLX visual

Select monoscopic viewing.

msalpha()

glEnable( GL_SAMPLE_ALPHA_TO_MASK_SGIS), glEnable( GL_SAMPLE_ALPHA_TO_ONE_SGIS)

Specify treatment of alpha values during multisampling.

msmask()

glSampleMaskSGIS()

Specify a multisample mask.

mspattern()

glSamplePatternSGIS()

Specify a sample pattern for multisampling.

mssize()

glXChooseVisual() with attribute GLX_SAMPLE_BUFFERS_SGIS

Configure multisample buffer.

multisample()

glEnable(GL_MULTISAMPLE_SGIS)

Enable or disable multisampling.

pixelmap()

glPixelMap()

Define pixel transfer lookup tables.

pixeltransfer()

glPixelTransfer()

Set transfer modes.

readcomponent()

glReadPixels() gives partial support; some readcomponent() features aren't yet supported

Choose a component source.

rightbuffer()

glDrawBuffer(GL_RIGHT)

Enable drawing in right buffer.

stereobuffer()

Superseded by selection of an appropriate GLX visual.

Select stereoscopic viewing.

subtexload()

OpenGL 1.1 function glTexSubImage2D() gives partial support (the flags parameter to subtexload() isn't supported)

Load part or all of a texture.

texdef3d()

glTexImage3DEXT()

Convert 3D image into a texture.

tlutbind()

Not supported

Select a texture lookup table.

tlutdef()

Not supported

Define a texture lookup table.

zbsize()

Superseded by selection of an appropriate GLX visual

Specify number of bitplanes to use for the depth buffer.

Some RealityEngine features (mostly involving texturing) don't correspond to specific IRIS GL functions, and thus don't fit nicely into Table 3-54. Some such features are supported by extensions to OpenGL; you should check at runtime to see if the relevant extension is supported by calling glGetString(GL_EXTENSIONS) (see the glGetString reference page for more information). Some other non-function-specific IRIS GL RealityEngine features aren't supported at all.

Each of the following features is supported on a given machine if the corresponding OpenGL extension is supported. (“OpenGL Extensions” points you to additional information):

  • The internal texture storage format (TX_INTERNAL_FORMAT in IRIS GL) is supported by the texture extension (GL_EXT_texture). OpenGL without extensions supports a superset of the formats previously specified by TX_EXTERNAL_FORMAT; see the glTexImage2D reference page for more information.

  • Sharpen texture is supported by the GL_SGIS_sharpen_texture extension. This was done in IRIS GL by passing TX_SHARPEN to texdef().

  • Detail texture is supported by the GL_SGIS_detail_texture extension. This was done in IRIS GL by using the tokens TX_DETAIL, TX_ADD_DETAIL, and TX_MODULATE_DETAIL in texdef() calls.

  • The detail texture and sharpen texture extension both support control points (pairs of level-of-detail and scale values) to control the rate at which the relevant filters are applied (see TX_CONTROL_CLAMP and TX_CONTROL_POINT in the texdef() reference page). However, unlike IRIS GL, OpenGL uses a separate set of control points for each of the two filters.

  • The IRIS GL ABGR pixel format is supported by the GL_EXT_abgr extension.

  • Texture and texture environment definition and binding (formerly done by using texdef(), texbind(), tevdef(), and tevbind()) are currently handled in OpenGL by creating a display list containing a glTexImage2D() call. (No OpenGL extension is required.)

  • The texture object extension supports named textures and allows you to prioritize textures using glPrioritizeTexturesEXT(). This functionality is also part of OpenGL 1.1.

These features are not supported in OpenGL or its extensions:

  • Automatic mipmap generation is supported in the GLU library by gluBuild2DMipmaps(), but you can't change the default filtering used to generate mipmap levels (see TX_MIPMAP_FILTER_KERNEL in the texdef reference page).

  • Bicubic texture filtering (see the descriptions of TX_BICUBIC and TX_BICUBIC_FILTER in the texdef reference page).

  • shadows (see the descriptions of TX_BILINEAR_LEQUAL and TX_BILINEAR_GEQUAL in the texdef() reference page, and of TV_ALPHA in the tevdef() reference page).

  • Component selection (see TV_COMPONENT_SELECT in the tevdef() reference page).

  • Texture definition from a live video stream (available in IRIS GL using the flags argument to subtexload()).

    On some platforms, the video source extension, SGIX_video_source, lets you source pixel data from a video stream to the OpenGL renderer. The video source extension is available only for system configurations that have direct hardware paths from the video hardware to the graphics accelerator. On other systems, you need to transfer video data to host memory and then call glDrawPixels() or glTex{Sub}Image() to transfer data to the framebuffer or to texture memory.

  • Fast texture definition, as performed in IRIS GL with TX_FAST_DEFINE.

  • Quadlinear mipmap filtering (see TX_MIPMAP_QUADLINEAR in the texdef reference page).

  • Specifying separate alpha and non-alpha functions for texture magnification filtering (see TX_MAGFILTER_COLOR and TX_MAGFILTER_ALPHA in the texdef reference page).

OpenGL Extensions

For information on extensions to OpenGL, see the glintro and glxintro reference pages, as well as the reference pages for individual functions. (For a partial list of extension-related functions, see “Porting RealityEngine Graphics Features.”)

The manual OpenGL on Silicon Graphics Systems discusses each extension and explains how to use it.