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:
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> |
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.
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.
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.
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.
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.
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.
A generic OpenGL translation is shown in the equation in Figure 3-2.
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} |
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.
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.
IRIS GL Matrix Mode | OpenGL Mode | Meaning | Min. Stack Depth |
---|---|---|---|
Operate on the texture matrix stack. | 2 | ||
Operate on the modelview matrix stack. | 32 | ||
Operate on the projection matrix stack. | 2 |
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 ); |
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 |
---|---|---|
Return the current matrix mode. | ||
Return a copy of the current modelview matrix. | ||
getmatrix() in MPROJECTION mode | Return a copy of the current projection matrix. | |
getmatrix() in MTEXTURE mode | 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. |
The following IRIS GL calls have no direct OpenGL equivalent:
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.
IRIS GL Call | OpenGL Call | Meaning |
---|---|---|
glViewport(x, y, width, height) | Set the viewport. | |
glPopAttrib() glPushAttrib(GL_VIEWPORT_BIT) | Push and pop the stack. | |
glGet*(GL_VIEWPORT) | Return viewport dimensions. |
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 |
---|---|---|
glEnable(GL_CLIP_PLANEi) | Enable clipping on plane i. | |
clipplane(i, CP_DEFINE, plane) | Define clipping plane. | |
— | Return clipping plane equation. | |
— | glIsEnabled( GL_CLIP_PLANEi) | Return true if clip plane i is enabled. |
Define the scissor box. | ||
glGet*(GL_SCISSOR_BOX) | Return the current scissor box. |
To turn on the scissor test, call glEnable() with GL_SCISSOR_BOX as the parameter.
The following sections discuss how to port IRIS GL drawing primitives, discussing the following topics:
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 |
---|---|
Create a new quadric object. | |
Delete a quadric object. | |
Associate a callback with a quadric object, for error handling. | |
Specify normals: no normals, one per face, or one per vertex. | |
Specify direction of normals: outward or inward. | |
Turn texture coordinate generation on or off. | |
Specify drawing style: polygons, lines, points, and so on. | |
Draw a sphere. | |
Draw a cylinder or cone. | |
Draw an arc. | |
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); |
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.
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
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.
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 |
---|---|---|
— | Draw a single point. | |
Interpret vertices as points. | ||
Turn on point antialiasing (see “Porting Antialiasing Calls”). |
See the glPointSize reference page for information about related glGet*() commands.
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 |
---|---|---|
Draw a closed line. | ||
glBegin(GL_LINE_STRIP) | Draw line segments. | |
Set line width. | ||
Return current line width. | ||
Specify a line stipple pattern. | ||
factor argument of glLineStipple() | Set a repeat factor for the line style. | |
glGet*(GL_LINE_STIPPLE_PATTERN) | Return line stipple pattern. | |
glGet*(GL_LINE_STIPPLE_REPEAT) | Return repeat factor. | |
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”.
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”.
These older polygon drawing calls have no direct equivalents in OpenGL:
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 |
---|---|---|
Vertices define boundary of a simple convex polygon. | ||
— | glBegin(GL_QUADS), glEnd() | Interpret quadruples of vertices as quadrilaterals. |
glBegin(GL_QUAD_STRIP), glEnd() | Interpret vertices as linked strips of quadrilaterals. | |
— |
| |
Set polygon drawing mode. | ||
Draw a rectangle. | ||
— | Draw a screen-aligned rectangle. |
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.
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. |
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 |
---|---|---|
Set the stipple pattern. | ||
— | OpenGL keeps only one polygon stipple pattern. | |
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 (); } |
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:
Table 3-18 lists the calls for drawing tessellated polygons.
Table 3-18. Tessellated Polygon Calls
GLU Call | Meaning |
---|---|
Create a new tessellation object. | |
Delete a tessellation object. | |
— | |
Begin the polygon specification. | |
Specify a polygon vertex. Successive gluTessVertex() calls describe a closed contour. | |
Indicate that the next series of vertices describe a new contour. | |
End the polygon specification. |
For details, see the reference pages for the commands in Table 3-18.
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. |
GL_TRIANGLE_STRIP | Linked strips of triangles. | |
— | GL_TRIANGLE_FAN | Linked fans of triangles. |
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 |
---|---|---|
Draw an arc. | ||
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.
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 |
---|---|---|
Create a new sphere object. | ||
Delete sphere object and free memory used. | ||
Draw a sphere. | ||
— | Set sphere attributes. | |
— | Control sphere orientation. | |
— | Return number of polygons in current sphere. |
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.
Table 3-22 lists IRIS GL color calls and their OpenGL equivalents.
IRIS GL Call | OpenGL Call | Meaning |
---|---|---|
glColor*() | Sets RGB color. | |
color(), colorf() | glIndex*() | Sets the color index. |
Returns the current color index. | ||
XQueryColor() | Gets a copy of a colormap entry's RGB values. | |
Gets the current RGB color values. | ||
See “Using X Color Maps”. | ||
glColor() | Sets RGB color. | |
Sets the color index mode color mask. | ||
Sets the RGB color mode mask. | ||
glGet*(GL_INDEX_WRITEMASK) | Gets the color mask. | |
glGet*(GL_COLOR_WRITEMASK) | Gets the color mask. | |
— |
![]() | 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.
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 |
---|---|---|
Do flat shading. | ||
shademodel(GOURAUD) | glShadeModel(GL_SMOOTH) | Do smooth shading. |
Return current shade model. | ||
dither(DT_OFF) | Turn dithering on/off. |
Smooth shading and dithering are on by default, as in IRIS GL.
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.
IRIS GL Call | OpenGL Call | Meaning |
---|---|---|
Read a block of pixels from the frame buffer. | ||
Write a block of pixels to the frame buffer. | ||
Copy pixels in the frame buffer. | ||
Specify pixel zoom factors for glDrawPixels() and glCopyPixels(). | ||
Specify raster position for pixel operations. | ||
Select a color buffer source for pixels. | ||
Set pixel storage modes. | ||
Set pixel transfer modes. | ||
Specify a logical operation for pixel writes. | ||
— | 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); |
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:
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 |
---|---|---|
Set various fog parameters. | ||
fogvertex(FG_ON) | Turn fog on. | |
fogvertex(FG_OFF) | 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().
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:
Table 3-27 lists the OpenGL equivalents for IRIS GL 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. */ } |
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:
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.
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 |
---|---|
Create a new NURBS object. | |
Delete a NURBS object. | |
Associate a callback for error handling with a NURBS object. |
When using NURBS objects, consider the following issues:
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 |
---|---|---|
Begin a curve definition. | ||
Specify curve attributes. | ||
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.
IRIS GL Type | OpenGL Type | Meaning |
---|---|---|
N_V3D | GL_MAP1_VERTEX_3 | |
N_V3DR | GL_MAP1_VERTEX_4 | |
— | 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.
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 |
---|---|---|
Begin trimming curve definition. | ||
Define a piecewise linear curve. | ||
Specify trimming curve attributes. | ||
End trimming curve definition. |
Table 3-32 summarizes the calls for drawing NURBS surfaces.
Table 3-32. Calls for Drawing NURBS Surfaces
IRIS GL Call | OpenGL Call | Meaning |
---|---|---|
Begin a surface definition. | ||
Specify surface attributes. | ||
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 | |
N_V3DR | GL_MAP2_VERTEX_4 | |
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; } |
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 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.
IRIS GL | OpenGL | Meaning |
---|---|---|
— | Turn on blending. | |
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.
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 |
|
Table 3-36 lists the available alpha test functions.
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 |
---|---|---|
Enable antialiasing of points. | ||
glEnable(GL_LINE_SMOOTH) | Enable antialiasing of lines. | |
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:
Use the highest quality smoothing. | |
Use the most efficient smoothing. | |
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.
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:
Use glReadPixels() to read from the depth buffer.
Massage the results as necessary.
Draw the resulting data to an auxiliary buffer.
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 |
---|---|---|
Operate on the accumulation buffer. | ||
— | Set clear values for accumulation buffer. | |
acbuf(AC_CLEAR) | Clear the accumulation buffer. | |
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.
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 |
---|---|---|
glXChooseVisual() | — | |
Enable stencil tests. | ||
stencil() | Set stencil test actions. | |
stencil(... func, ...) | Set function & reference value for stencil testing. | |
Specify which stencil bits can be written. | ||
— | Specify the clear value for the stencil buffer. | |
— |
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.
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:
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. |
Execute display list(s). | ||
Test for display list existence. | ||
Delete contiguous group of display lists. | ||
Generate the given number of contiguous empty display lists. | ||
— | Get the display list base for glCallLists(). |
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.
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 (); |
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 ); |
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:
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 ); |
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,...) | Define a light source. | |
lmdef(DEFLMODEL, ...) | Define a lighting model. | |
lmbind() | Enable light i. | |
lmbind() | glEnable(GL_LIGHTING) | Enable lighting. |
— | Get light source parameters. | |
lmdef(DEFMATERIAL, ...) | Define a material. | |
Change effect of color commands while lighting is active. | ||
— | 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] |
|
|
(0.2, 0.2, 0.2, 1.0) | Ambient color | ||
(0.8, 0.8, 0.8, 1.0) | Diffuse color | ||
GL_SPECULAR[b] | (0.0, 0.0, 0.0, 1.0) | Specular color | |
(0.0, 0.0, 0.0, 1.0) | Emissive color | ||
0.0 | Specular exponent | ||
— | (see above) | Equivalent to calling glMaterial() twice with same values | |
— | 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 | (0.2, 0.2, 0.2, 1.0) | Ambient color of scene. | |
ATTENUATION | — | — | See glLight(). |
LOCALVIEWER | GL_FALSE | Viewer local (TRUE) or infinite (FALSE). | |
TWOSIDE | 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.
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. |
|
|
| |
(0.0, 0.0, 1.0, 0.0) | Position of light. | ||
(0, 0, -1) | Spot direction. | ||
-- |
|
| |
| 0 | Intensity distribution. | |
| 180 | Maximum spread angle of light source. | |
DEFLMODEL, 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(); } |
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.
IRIS GL Call | OpenGL Call | Meaning |
---|---|---|
Specify a 2D texture image. | ||
Select a texture function. | ||
Define a texture mapping environment. | ||
Select a texture environment. | ||
— |
| |
Control generation of texture coordinates. | ||
— | — | |
— | — | |
— | — | |
— | 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.
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 |
---|---|
no direct OpenGL equivalent | |
no direct OpenGL equivalent |
For more detailed information on how to use these options, see the glTexEnv reference page.
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 |
---|---|
— |
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.
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 |
---|---|---|
GL_TEXTURE_GEN_S | ||
GL_TEXTURE_GEN_T | ||
GL_TEXTURE_GEN_R | ||
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 |
---|---|---|
— |
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); |
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.
IRIS GL Call | OpenGL Call | Notes |
---|---|---|
clearhitcode() | not supported | Clears global variable, hitcode. |
Switch to selection/picking mode. | ||
Switch back to rendering mode. | ||
| ||
— | Set the return array. | |
— | ||
— | ||
— |
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”.
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.
IRIS GL Call | OpenGL Call | Notes |
---|---|---|
Switch to feedback mode. | ||
glRenderMode(GL_RENDER) | Switch back to rendering mode. | |
— | — | |
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; } |
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).
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.