summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rw-r--r--doc/gl-docs/GLU/Imakefile150
-rw-r--r--doc/gl-docs/GLU/begincurve.3gl65
-rw-r--r--doc/gl-docs/GLU/beginpolygon.3gl76
-rw-r--r--doc/gl-docs/GLU/beginsurface.3gl70
-rw-r--r--doc/gl-docs/GLU/begintrim.3gl106
-rw-r--r--doc/gl-docs/GLU/build1dmipmaplevels.3gl228
-rw-r--r--doc/gl-docs/GLU/build1dmipmaps.3gl228
-rw-r--r--doc/gl-docs/GLU/build2dmipmaplevels.3gl234
-rw-r--r--doc/gl-docs/GLU/build2dmipmaps.3gl236
-rw-r--r--doc/gl-docs/GLU/build3dmipmaplevels.3gl237
-rw-r--r--doc/gl-docs/GLU/build3dmipmaps.3gl238
-rw-r--r--doc/gl-docs/GLU/checkextension.3gl53
-rw-r--r--doc/gl-docs/GLU/cylinder.3gl70
-rw-r--r--doc/gl-docs/GLU/deletenurbsrenderer.3gl34
-rw-r--r--doc/gl-docs/GLU/deletequadric.3gl34
-rw-r--r--doc/gl-docs/GLU/deletetess.3gl33
-rw-r--r--doc/gl-docs/GLU/disk.3gl70
-rw-r--r--doc/gl-docs/GLU/errorstring.3gl47
-rw-r--r--doc/gl-docs/GLU/getnurbsproperty.3gl55
-rw-r--r--doc/gl-docs/GLU/getstring.3gl65
-rw-r--r--doc/gl-docs/GLU/gettessproperty.3gl50
-rw-r--r--doc/gl-docs/GLU/loadsamplingmatrices.3gl60
-rw-r--r--doc/gl-docs/GLU/lookat.3gl101
-rw-r--r--doc/gl-docs/GLU/newnurbsrenderer.3gl31
-rw-r--r--doc/gl-docs/GLU/newquadric.3gl33
-rw-r--r--doc/gl-docs/GLU/newtess.3gl30
-rw-r--r--doc/gl-docs/GLU/nextcontour.3gl102
-rw-r--r--doc/gl-docs/GLU/nurbscallback.3gl228
-rw-r--r--doc/gl-docs/GLU/nurbscallbackdata.3gl41
-rw-r--r--doc/gl-docs/GLU/nurbscallbackdataext.3gl38
-rw-r--r--doc/gl-docs/GLU/nurbscurve.3gl99
-rw-r--r--doc/gl-docs/GLU/nurbsproperty.3gl202
-rw-r--r--doc/gl-docs/GLU/nurbssurface.3gl124
-rw-r--r--doc/gl-docs/GLU/ortho2d.3gl41
-rw-r--r--doc/gl-docs/GLU/partialdisk.3gl87
-rw-r--r--doc/gl-docs/GLU/perspective.3gl96
-rw-r--r--doc/gl-docs/GLU/pickmatrix.3gl94
-rw-r--r--doc/gl-docs/GLU/project.3gl88
-rw-r--r--doc/gl-docs/GLU/pwlcurve.3gl69
-rw-r--r--doc/gl-docs/GLU/quadriccallback.3gl51
-rw-r--r--doc/gl-docs/GLU/quadricdrawstyle.3gl57
-rw-r--r--doc/gl-docs/GLU/quadricnormals.3gl51
-rw-r--r--doc/gl-docs/GLU/quadricorientation.3gl49
-rw-r--r--doc/gl-docs/GLU/quadrictexture.3gl45
-rw-r--r--doc/gl-docs/GLU/scaleimage.3gl172
-rw-r--r--doc/gl-docs/GLU/sphere.3gl66
-rw-r--r--doc/gl-docs/GLU/tessbegincontour.3gl44
-rw-r--r--doc/gl-docs/GLU/tessbeginpolygon.3gl73
-rw-r--r--doc/gl-docs/GLU/tesscallback.3gl294
-rw-r--r--doc/gl-docs/GLU/tessendpolygon.3gl68
-rw-r--r--doc/gl-docs/GLU/tessnormal.3gl67
-rw-r--r--doc/gl-docs/GLU/tessproperty.3gl99
-rw-r--r--doc/gl-docs/GLU/tessvertex.3gl99
-rw-r--r--doc/gl-docs/GLU/unproject.3gl78
-rw-r--r--doc/gl-docs/GLU/unproject4.3gl103
55 files changed, 5359 insertions, 0 deletions
diff --git a/doc/gl-docs/GLU/Imakefile b/doc/gl-docs/GLU/Imakefile
new file mode 100644
index 000000000..567dcafef
--- /dev/null
+++ b/doc/gl-docs/GLU/Imakefile
@@ -0,0 +1,150 @@
+XCOMM $XFree86: xc/doc/man/GLU/Imakefile,v 1.2 2001/01/16 02:23:46 dawes Exp $
+
+XCOMM License Applicability. Except to the extent portions of this file are
+XCOMM made subject to an alternative license as permitted in the SGI Free
+XCOMM Software License B, Version 1.1 (the "License"), the contents of this
+XCOMM file are subject only to the provisions of the License. You may not use
+XCOMM this file except in compliance with the License. You may obtain a copy
+XCOMM of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+XCOMM Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+XCOMM
+XCOMM http://oss.sgi.com/projects/FreeB
+XCOMM
+XCOMM Note that, as provided in the License, the Software is distributed on an
+XCOMM "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+XCOMM DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+XCOMM CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+XCOMM PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+XCOMM
+XCOMM Original Code. The Original Code is: OpenGL Sample Implementation,
+XCOMM Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+XCOMM Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+XCOMM Copyright in any portions created by third parties is as indicated
+XCOMM elsewhere herein. All Rights Reserved.
+XCOMM
+XCOMM Additional Notice Provisions: The application programming interfaces
+XCOMM established by SGI in conjunction with the Original Code are The
+XCOMM OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+XCOMM April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+XCOMM 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+XCOMM Window System(R) (Version 1.3), released October 19, 1998. This software
+XCOMM was created using the OpenGL(R) version 1.2.1 Sample Implementation
+XCOMM published by SGI, but has not been independently verified as being
+XCOMM compliant with the OpenGL(R) version 1.2.1 Specification.
+XCOMM
+
+MANDIR = $(LIBMANDIR)
+MANSUFFIX = $(LIBMANSUFFIX)
+MSUFF = man
+
+InstallManPage(gluBeginCurve,$(MANDIR))
+InstallManPageAliases(gluBeginCurve,$(MANDIR),gluEndCurve)
+InstallManPage(gluBeginPolygon,$(MANDIR))
+InstallManPageAliases(gluBeginPolygon,$(MANDIR),gluEndPolygon)
+InstallManPage(gluBeginSurface,$(MANDIR))
+InstallManPageAliases(gluBeginSurface,$(MANDIR),gluEndSurface)
+InstallManPage(gluBeginTrim,$(MANDIR))
+InstallManPageAliases(gluBeginTrim,$(MANDIR),gluEndTrim)
+InstallManPage(gluBuild1DMipmaps,$(MANDIR))
+InstallManPage(gluBuild2DMipmaps,$(MANDIR))
+InstallManPage(gluCylinder,$(MANDIR))
+InstallManPage(gluDeleteNurbsRenderer,$(MANDIR))
+InstallManPage(gluDeleteQuadric,$(MANDIR))
+InstallManPage(gluDeleteTess,$(MANDIR))
+InstallManPage(gluDisk,$(MANDIR))
+InstallManPage(gluErrorString,$(MANDIR))
+InstallManPage(gluGetNurbsProperty,$(MANDIR))
+InstallManPage(gluGetString,$(MANDIR))
+InstallManPage(gluGetTessProperty,$(MANDIR))
+InstallManPage(gluLoadSamplingMatrices,$(MANDIR))
+InstallManPage(gluLookAt,$(MANDIR))
+InstallManPage(gluNewNurbsRenderer,$(MANDIR))
+InstallManPage(gluNewQuadric,$(MANDIR))
+InstallManPage(gluNewTess,$(MANDIR))
+InstallManPage(gluNextContour,$(MANDIR))
+InstallManPage(gluNurbsCallback,$(MANDIR))
+InstallManPage(gluNurbsCallbackDataEXT,$(MANDIR))
+InstallManPage(gluNurbsCurve,$(MANDIR))
+InstallManPage(gluNurbsProperty,$(MANDIR))
+InstallManPage(gluNurbsSurface,$(MANDIR))
+InstallManPage(gluOrtho2D,$(MANDIR))
+InstallManPage(gluPartialDisk,$(MANDIR))
+InstallManPage(gluPerspective,$(MANDIR))
+InstallManPage(gluPickMatrix,$(MANDIR))
+InstallManPage(gluProject,$(MANDIR))
+InstallManPage(gluPwlCurve,$(MANDIR))
+InstallManPage(gluQuadricCallback,$(MANDIR))
+InstallManPage(gluQuadricDrawStyle,$(MANDIR))
+InstallManPage(gluQuadricNormals,$(MANDIR))
+InstallManPage(gluQuadricOrientation,$(MANDIR))
+InstallManPage(gluQuadricTexture,$(MANDIR))
+InstallManPage(gluScaleImage,$(MANDIR))
+InstallManPage(gluSphere,$(MANDIR))
+InstallManPage(gluTessBeginContour,$(MANDIR))
+InstallManPageAliases(gluTessBeginContour,$(MANDIR),gluTessEndContour)
+InstallManPage(gluTessBeginPolygon,$(MANDIR))
+InstallManPage(gluTessCallback,$(MANDIR))
+InstallManPage(gluTessEndPolygon,$(MANDIR))
+InstallManPage(gluTessNormal,$(MANDIR))
+InstallManPage(gluTessProperty,$(MANDIR))
+InstallManPage(gluTessVertex,$(MANDIR))
+InstallManPage(gluUnProject,$(MANDIR))
+
+
+#if 0
+GLUMANDIR = $(OGLSAMPLESRCDIR)/main/doc/man/manglu/standard
+GLUSUFFIX = gl
+#else
+GLUMANDIR = .
+GLUSUFFIX = 3gl
+#endif
+
+
+LinkFile(gluBeginCurve.$(MSUFF), $(GLUMANDIR)/begincurve.$(GLUSUFFIX))
+LinkFile(gluBeginPolygon.$(MSUFF), $(GLUMANDIR)/beginpolygon.$(GLUSUFFIX))
+LinkFile(gluBeginSurface.$(MSUFF), $(GLUMANDIR)/beginsurface.$(GLUSUFFIX))
+LinkFile(gluBeginTrim.$(MSUFF), $(GLUMANDIR)/begintrim.$(GLUSUFFIX))
+LinkFile(gluBuild1DMipmaps.$(MSUFF), $(GLUMANDIR)/build1dmipmaps.$(GLUSUFFIX))
+LinkFile(gluBuild2DMipmaps.$(MSUFF), $(GLUMANDIR)/build2dmipmaps.$(GLUSUFFIX))
+LinkFile(gluCylinder.$(MSUFF), $(GLUMANDIR)/cylinder.$(GLUSUFFIX))
+LinkFile(gluDeleteNurbsRenderer.$(MSUFF), $(GLUMANDIR)/deletenurbsrenderer.$(GLUSUFFIX))
+LinkFile(gluDeleteQuadric.$(MSUFF), $(GLUMANDIR)/deletequadric.$(GLUSUFFIX))
+LinkFile(gluDeleteTess.$(MSUFF), $(GLUMANDIR)/deletetess.$(GLUSUFFIX))
+LinkFile(gluDisk.$(MSUFF), $(GLUMANDIR)/disk.$(GLUSUFFIX))
+LinkFile(gluErrorString.$(MSUFF), $(GLUMANDIR)/errorstring.$(GLUSUFFIX))
+LinkFile(gluGetNurbsProperty.$(MSUFF), $(GLUMANDIR)/getnurbsproperty.$(GLUSUFFIX))
+LinkFile(gluGetString.$(MSUFF), $(GLUMANDIR)/getstring.$(GLUSUFFIX))
+LinkFile(gluGetTessProperty.$(MSUFF), $(GLUMANDIR)/gettessproperty.$(GLUSUFFIX))
+LinkFile(gluLoadSamplingMatrices.$(MSUFF), $(GLUMANDIR)/loadsamplingmatrices.$(GLUSUFFIX))
+LinkFile(gluLookAt.$(MSUFF), $(GLUMANDIR)/lookat.$(GLUSUFFIX))
+LinkFile(gluNewNurbsRenderer.$(MSUFF), $(GLUMANDIR)/newnurbsrenderer.$(GLUSUFFIX))
+LinkFile(gluNewQuadric.$(MSUFF), $(GLUMANDIR)/newquadric.$(GLUSUFFIX))
+LinkFile(gluNewTess.$(MSUFF), $(GLUMANDIR)/newtess.$(GLUSUFFIX))
+LinkFile(gluNextContour.$(MSUFF), $(GLUMANDIR)/nextcontour.$(GLUSUFFIX))
+LinkFile(gluNurbsCallback.$(MSUFF), $(GLUMANDIR)/nurbscallback.$(GLUSUFFIX))
+LinkFile(gluNurbsCallbackDataEXT.$(MSUFF), $(GLUMANDIR)/nurbscallbackdataext.$(GLUSUFFIX))
+LinkFile(gluNurbsCurve.$(MSUFF), $(GLUMANDIR)/nurbscurve.$(GLUSUFFIX))
+LinkFile(gluNurbsProperty.$(MSUFF), $(GLUMANDIR)/nurbsproperty.$(GLUSUFFIX))
+LinkFile(gluNurbsSurface.$(MSUFF), $(GLUMANDIR)/nurbssurface.$(GLUSUFFIX))
+LinkFile(gluOrtho2D.$(MSUFF), $(GLUMANDIR)/ortho2d.$(GLUSUFFIX))
+LinkFile(gluPartialDisk.$(MSUFF), $(GLUMANDIR)/partialdisk.$(GLUSUFFIX))
+LinkFile(gluPerspective.$(MSUFF), $(GLUMANDIR)/perspective.$(GLUSUFFIX))
+LinkFile(gluPickMatrix.$(MSUFF), $(GLUMANDIR)/pickmatrix.$(GLUSUFFIX))
+LinkFile(gluProject.$(MSUFF), $(GLUMANDIR)/project.$(GLUSUFFIX))
+LinkFile(gluPwlCurve.$(MSUFF), $(GLUMANDIR)/pwlcurve.$(GLUSUFFIX))
+LinkFile(gluQuadricCallback.$(MSUFF), $(GLUMANDIR)/quadriccallback.$(GLUSUFFIX))
+LinkFile(gluQuadricDrawStyle.$(MSUFF), $(GLUMANDIR)/quadricdrawstyle.$(GLUSUFFIX))
+LinkFile(gluQuadricNormals.$(MSUFF), $(GLUMANDIR)/quadricnormals.$(GLUSUFFIX))
+LinkFile(gluQuadricOrientation.$(MSUFF), $(GLUMANDIR)/quadricorientation.$(GLUSUFFIX))
+LinkFile(gluQuadricTexture.$(MSUFF), $(GLUMANDIR)/quadrictexture.$(GLUSUFFIX))
+LinkFile(gluScaleImage.$(MSUFF), $(GLUMANDIR)/scaleimage.$(GLUSUFFIX))
+LinkFile(gluSphere.$(MSUFF), $(GLUMANDIR)/sphere.$(GLUSUFFIX))
+LinkFile(gluTessBeginContour.$(MSUFF), $(GLUMANDIR)/tessbegincontour.$(GLUSUFFIX))
+LinkFile(gluTessBeginPolygon.$(MSUFF), $(GLUMANDIR)/tessbeginpolygon.$(GLUSUFFIX))
+LinkFile(gluTessCallback.$(MSUFF), $(GLUMANDIR)/tesscallback.$(GLUSUFFIX))
+LinkFile(gluTessEndPolygon.$(MSUFF), $(GLUMANDIR)/tessendpolygon.$(GLUSUFFIX))
+LinkFile(gluTessNormal.$(MSUFF), $(GLUMANDIR)/tessnormal.$(GLUSUFFIX))
+LinkFile(gluTessProperty.$(MSUFF), $(GLUMANDIR)/tessproperty.$(GLUSUFFIX))
+LinkFile(gluTessVertex.$(MSUFF), $(GLUMANDIR)/tessvertex.$(GLUSUFFIX))
+LinkFile(gluUnProject.$(MSUFF), $(GLUMANDIR)/unproject.$(GLUSUFFIX))
+
diff --git a/doc/gl-docs/GLU/begincurve.3gl b/doc/gl-docs/GLU/begincurve.3gl
new file mode 100644
index 000000000..6956baf68
--- /dev/null
+++ b/doc/gl-docs/GLU/begincurve.3gl
@@ -0,0 +1,65 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 begincurv
+.ds Xs 19309 4 begincurve.gl
+.TH GLUBEGINCURVE 3G
+.SH NAME
+.B "gluBeginCurve, gluEndCurve
+\- delimit a NURBS curve definition
+
+.SH C SPECIFICATION
+void \f3gluBeginCurve\fP(
+GLUnurbs* \fInurb\fP )
+.nf
+.fi
+
+void \f3gluEndCurve\fP(
+GLUnurbs* \fInurb\fP )
+.nf
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\f2nurb\fP\ \ 'u
+\f2nurb\fP
+Specifies the NURBS object (created with \%\f3gluNewNurbsRenderer\fP).
+.SH DESCRIPTION
+Use \%\f3gluBeginCurve\fP to mark the beginning of a NURBS
+curve definition.
+After
+calling \%\f3gluBeginCurve\fP, make one or more calls to
+\%\f3gluNurbsCurve\fP to define the attributes of the curve.
+Exactly one of the calls to \%\f3gluNurbsCurve\fP must have
+a curve type of \%\f3GL_MAP1_VERTEX_3\fP or \%\f3GL_MAP1_VERTEX_4\fP.
+To mark the end of the NURBS curve definition, call \%\f3gluEndCurve\fP.
+.P
+GL evaluators are used to render the NURBS curve as a series of line
+segments.
+Evaluator state is preserved during rendering
+with \f3glPushAttrib\fP(\%\f3GL_EVAL_BIT\fP) and
+\f3glPopAttrib\fP().
+See the \f3glPushAttrib\fP reference page for details on exactly what state
+these calls preserve.
+.SH EXAMPLE
+The following commands render a textured NURBS curve with normals;
+texture coordinates and normals are also specified as NURBS curves:
+.sp
+.Ex
+gluBeginCurve(nobj);
+ gluNurbsCurve(nobj, ..., GL_MAP1_TEXTURE_COORD_2);
+ gluNurbsCurve(nobj, ..., GL_MAP1_NORMAL);
+ gluNurbsCurve(nobj, ..., GL_MAP1_VERTEX_4);
+gluEndCurve(nobj);
+.Ee
+.SH SEE ALSO
+\%\f3gluBeginSurface(3G)\fP, \%\f3gluBeginTrim(3G)\fP, \%\f3gluNewNurbsRenderer(3G)\fP,
+\%\f3gluNurbsCurve(3G)\fP,
+\f3glPopAttrib(3G)\fP, \f3glPushAttrib(3G)\fP
+
diff --git a/doc/gl-docs/GLU/beginpolygon.3gl b/doc/gl-docs/GLU/beginpolygon.3gl
new file mode 100644
index 000000000..6e8e50d91
--- /dev/null
+++ b/doc/gl-docs/GLU/beginpolygon.3gl
@@ -0,0 +1,76 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 beginpoly
+.ds Xs 33625 4 beginpolygon.gl
+.TH GLUBEGINPOLYGON 3G
+.SH NAME
+.B "gluBeginPolygon, gluEndPolygon
+\- delimit a polygon description
+
+.SH C SPECIFICATION
+void \f3gluBeginPolygon\fP(
+GLUtesselator* \fItess\fP )
+.nf
+.fi
+
+void \f3gluEndPolygon\fP(
+GLUtesselator* \fItess\fP )
+.nf
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\f2tess\fP\ \ 'u
+\f2tess\fP
+Specifies the tessellation object (created with \%\f3gluNewTess\fP).
+.SH DESCRIPTION
+\%\f3gluBeginPolygon\fP and \%\f3gluEndPolygon\fP delimit the definition of a
+nonconvex polygon.
+To define such a polygon, first call \%\f3gluBeginPolygon\fP.
+Then define the contours of the polygon
+by calling
+\%\f3gluTessVertex\fP for each vertex
+and \%\f3gluNextContour\fP to start each new contour.
+Finally, call \%\f3gluEndPolygon\fP
+to signal the end of the definition.
+See the \%\f3gluTessVertex\fP and
+\%\f3gluNextContour\fP reference pages for more details.
+.P
+Once \%\f3gluEndPolygon\fP is called, the polygon is tessellated, and the
+resulting triangles are described through callbacks.
+See \%\f3gluTessCallback\fP for descriptions of the callback functions.
+.SH NOTES
+This command is obsolete and is provided for backward compatibility
+only. Calls to \%\f3gluBeginPolygon\fP are mapped to
+\%\f3gluTessBeginPolygon\fP
+followed by
+\%\f3gluTessBeginContour\fP. Calls to \%\f3gluEndPolygon\fP are mapped
+to \%\f3gluTessEndContour\fP followed by \%\f3gluTessEndPolygon\fP.
+.SH EXAMPLE
+A quadrilateral with a triangular hole in it can be described like this:
+.sp
+.Ex
+gluBeginPolygon(tobj);
+ gluTessVertex(tobj, v1, v1);
+ gluTessVertex(tobj, v2, v2);
+ gluTessVertex(tobj, v3, v3);
+ gluTessVertex(tobj, v4, v4);
+gluNextContour(tobj, GLU_INTERIOR);
+ gluTessVertex(tobj, v5, v5);
+ gluTessVertex(tobj, v6, v6);
+ gluTessVertex(tobj, v7, v7);
+gluEndPolygon(tobj);
+.Ee
+.SH SEE ALSO
+\%\f3gluNewTess(3G)\fP, \%\f3gluNextContour(3G)\fP, \%\f3gluTessCallback(3G)\fP, \%\f3gluTessVertex(3G)\fP,
+\%\f3gluTessBeginPolygon(3G)\fP, \%\f3gluTessBeginContour(3G)\fP
+
+
+
diff --git a/doc/gl-docs/GLU/beginsurface.3gl b/doc/gl-docs/GLU/beginsurface.3gl
new file mode 100644
index 000000000..4a7ff6b1e
--- /dev/null
+++ b/doc/gl-docs/GLU/beginsurface.3gl
@@ -0,0 +1,70 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 beginsurf
+.ds Xs 47264 4 beginsurface.gl
+.TH GLUBEGINSURFACE 3G
+.SH NAME
+.B "gluBeginSurface, gluEndSurface
+\- delimit a NURBS surface definition
+
+.SH C SPECIFICATION
+void \f3gluBeginSurface\fP(
+GLUnurbs* \fInurb\fP )
+.nf
+.fi
+
+void \f3gluEndSurface\fP(
+GLUnurbs* \fInurb\fP )
+.nf
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\f2nurb\fP\ \ 'u
+\f2nurb\fP
+Specifies the NURBS object (created with \%\f3gluNewNurbsRenderer\fP).
+.SH DESCRIPTION
+Use \%\f3gluBeginSurface\fP to mark the beginning of a NURBS
+surface definition. After
+calling \%\f3gluBeginSurface\fP, make one or more calls to
+\%\f3gluNurbsSurface\fP to define the attributes of the surface.
+Exactly one of these calls to \%\f3gluNurbsSurface\fP must have a
+surface type of \%\f3GL_MAP2_VERTEX_3\fP or \%\f3GL_MAP2_VERTEX_4\fP.
+To mark the end of the NURBS surface definition, call
+\%\f3gluEndSurface\fP.
+.P
+Trimming of NURBS surfaces is supported with \%\f3gluBeginTrim\fP,
+\%\f3gluPwlCurve\fP, \%\f3gluNurbsCurve\fP, and \%\f3gluEndTrim\fP. See the
+\%\f3gluBeginTrim\fP reference page for details.
+.P
+GL evaluators are used to render the NURBS surface as a set of polygons.
+Evaluator state is preserved during rendering
+with \f3glPushAttrib\fP(\%\f3GL_EVAL_BIT\fP) and
+\f3glPopAttrib\fP().
+See the \f3glPushAttrib\fP reference page for details on exactly what state
+these calls preserve.
+.SH EXAMPLE
+The following commands render a textured NURBS surface with normals;
+the texture coordinates and normals are also described as NURBS surfaces:
+.sp
+.Ex
+gluBeginSurface(nobj);
+ gluNurbsSurface(nobj, ..., GL_MAP2_TEXTURE_COORD_2);
+ gluNurbsSurface(nobj, ..., GL_MAP2_NORMAL);
+ gluNurbsSurface(nobj, ..., GL_MAP2_VERTEX_4);
+gluEndSurface(nobj);
+.Ee
+.sp
+.SH SEE ALSO
+\%\f3gluBeginCurve(3G)\fP, \%\f3gluBeginTrim(3G)\fP, \%\f3gluNewNurbsRenderer(3G)\fP,
+\%\f3gluNurbsCurve(3G)\fP, \%\f3gluNurbsSurface(3G)\fP, \%\f3gluPwlCurve(3G)\fP
+
+
+
diff --git a/doc/gl-docs/GLU/begintrim.3gl b/doc/gl-docs/GLU/begintrim.3gl
new file mode 100644
index 000000000..028fcd1a4
--- /dev/null
+++ b/doc/gl-docs/GLU/begintrim.3gl
@@ -0,0 +1,106 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 begintrim
+.ds Xs 15822 6 begintrim.gl
+.TH GLUBEGINTRIM 3G
+.SH NAME
+.B "gluBeginTrim, gluEndTrim
+\- delimit a NURBS trimming loop definition
+
+.SH C SPECIFICATION
+void \f3gluBeginTrim\fP(
+GLUnurbs* \fInurb\fP )
+.nf
+.fi
+
+void \f3gluEndTrim\fP(
+GLUnurbs* \fInurb\fP )
+.nf
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\f2nurb\fP\ \ 'u
+\f2nurb\fP
+Specifies the NURBS object (created with \%\f3gluNewNurbsRenderer\fP).
+.SH DESCRIPTION
+Use \%\f3gluBeginTrim\fP to mark the beginning of a
+trimming loop, and \%\f3gluEndTrim\fP to mark the end
+of a trimming loop. A trimming loop is
+a set of oriented curve segments (forming a closed curve) that
+define boundaries of a NURBS surface. You include these
+trimming loops in the definition of a NURBS
+surface, between calls to \%\f3gluBeginSurface\fP and \%\f3gluEndSurface\fP.
+.P
+The definition for a NURBS surface can contain many
+trimming loops. For example, if you wrote a definition
+for a NURBS surface that resembled a rectangle with
+a hole punched out, the definition would contain two
+trimming loops. One loop would define the outer edge
+of the rectangle; the other would define
+the hole punched out of the rectangle. The definitions
+of each of these trimming loops would be bracketed by a
+\%\f3gluBeginTrim\fP/\%\f3gluEndTrim\fP pair.
+.P
+The definition of a single closed trimming loop can consist
+of multiple curve segments, each described as a piecewise
+linear curve (see \%\f3gluPwlCurve\fP) or as a single NURBS
+curve (see \%\f3gluNurbsCurve\fP), or as a combination of
+both in any order. The only library calls that can
+appear in a trimming loop definition (between the calls
+to \%\f3gluBeginTrim\fP and \%\f3gluEndTrim\fP) are
+\%\f3gluPwlCurve\fP and \%\f3gluNurbsCurve\fP.
+.P
+The area of the NURBS surface that is displayed is the
+region in the domain to the left of the trimming curve
+as the curve parameter increases. Thus, the retained
+region of the NURBS surface is inside a
+counterclockwise trimming loop and outside a clockwise
+trimming loop. For the rectangle mentioned earlier,
+the trimming loop for the outer edge of the rectangle runs
+counterclockwise, while the trimming loop for the punched-out hole
+runs clockwise.
+.P
+If you use more than one curve to define a single trimming
+loop, the curve segments must form a closed loop (that is,
+the endpoint of each curve must be the starting point of the
+next curve, and the endpoint of the final curve must
+be the starting point of the first curve). If the
+endpoints of the curve are sufficiently close together
+but not exactly coincident, they will be coerced to match.
+If the endpoints are not sufficiently close, an error results
+(see \%\f3gluNurbsCallback\fP).
+.P
+If a trimming loop definition contains multiple curves,
+the direction of the curves must be consistent (that is, the
+inside must be to the left of all of the curves). Nested
+trimming loops are legal as long as the curve orientations
+alternate correctly.
+If trimming curves are self-intersecting,
+or intersect one another, an error results.
+.P
+If no trimming information is given
+for a NURBS surface, the entire surface is drawn.
+.SH EXAMPLE
+This code fragment defines a trimming loop that consists of one
+piecewise linear curve, and two NURBS curves:
+.sp
+.Ex
+gluBeginTrim(nobj);
+ gluPwlCurve(..., GLU_MAP1_TRIM_2);
+ gluNurbsCurve(..., GLU_MAP1_TRIM_2);
+ gluNurbsCurve(..., GLU_MAP1_TRIM_3);
+gluEndTrim(nobj);
+.Ee
+.SH SEE ALSO
+\%\f3gluBeginSurface(3G)\fP, \%\f3gluNewNurbsRenderer(3G)\fP, \%\f3gluNurbsCallback(3G)\fP,
+\%\f3gluNurbsCurve(3G)\fP, \%\f3gluPwlCurve(3G)\fP
+
+
diff --git a/doc/gl-docs/GLU/build1dmipmaplevels.3gl b/doc/gl-docs/GLU/build1dmipmaplevels.3gl
new file mode 100644
index 000000000..06a32827c
--- /dev/null
+++ b/doc/gl-docs/GLU/build1dmipmaplevels.3gl
@@ -0,0 +1,228 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 build1dmi
+.ds Xs 15416 9 build1dmipmaplevels.gl
+.TH GLUBUILD1DMIPMAPLEVELS 3G
+.SH NAME
+.B "gluBuild1DMipmapLevels
+\- builds a subset of one-dimensional mipmap levels
+
+.SH C SPECIFICATION
+GLint \f3gluBuild1DMipmapLevels\fP(
+GLenum \fItarget\fP,
+.nf
+.ta \w'\f3GLint \fPgluBuild1DMipmapLevels( 'u
+ GLint \fIinternalFormat\fP,
+ GLsizei \fIwidth\fP,
+ GLenum \fIformat\fP,
+ GLenum \fItype\fP,
+ GLint \fIlevel\fP,
+ GLint \fIbase\fP,
+ GLint \fImax\fP,
+ const void \fI*data\fP )
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\fIinternalFormat\fP\ \ 'u
+\f2target\fP
+Specifies the target texture. Must be \%\f3GL_TEXTURE_1D\fP.
+.TP
+\f2internalFormat\fP
+Requests the internal storage of the texture image. The most
+current version of the SGI implementation of GLU does not check this
+value for validity before passing it on to the underlying OpenGL
+implementation. A value that is not accepted by the OpenGL
+implementation will lead to an OpenGL error. The benefit of not
+checking this value at the GLU level is that OpenGL extensions can add
+new internal texture formats without requiring a revision of the GLU
+implementation. Older implementations of GLU check this value and
+raise a GLU error if it is not 1, 2, 3, or 4 or one of the following
+symbolic constants:
+\%\f3GL_ALPHA\fP,
+\%\f3GL_ALPHA4\fP,
+\%\f3GL_ALPHA8\fP,
+\%\f3GL_ALPHA12\fP,
+\%\f3GL_ALPHA16\fP,
+\%\f3GL_LUMINANCE\fP,
+\%\f3GL_LUMINANCE4\fP,
+\%\f3GL_LUMINANCE8\fP,
+\%\f3GL_LUMINANCE12\fP,
+\%\f3GL_LUMINANCE16\fP,
+\%\f3GL_LUMINANCE_ALPHA\fP,
+\%\f3GL_LUMINANCE4_ALPHA4\fP,
+\%\f3GL_LUMINANCE6_ALPHA2\fP,
+\%\f3GL_LUMINANCE8_ALPHA8\fP,
+\%\f3GL_LUMINANCE12_ALPHA4\fP,
+\%\f3GL_LUMINANCE12_ALPHA12\fP,
+\%\f3GL_LUMINANCE16_ALPHA16\fP,
+\%\f3GL_INTENSITY\fP,
+\%\f3GL_INTENSITY4\fP,
+\%\f3GL_INTENSITY8\fP,
+\%\f3GL_INTENSITY12\fP,
+\%\f3GL_INTENSITY16\fP,
+\%\f3GL_RGB\fP,
+\%\f3GL_R3_G3_B2\fP,
+\%\f3GL_RGB4\fP,
+\%\f3GL_RGB5\fP,
+\%\f3GL_RGB8\fP,
+\%\f3GL_RGB10\fP,
+\%\f3GL_RGB12\fP,
+\%\f3GL_RGB16\fP,
+\%\f3GL_RGBA\fP,
+\%\f3GL_RGBA2\fP,
+\%\f3GL_RGBA4\fP,
+\%\f3GL_RGB5_A1\fP,
+\%\f3GL_RGBA8\fP,
+\%\f3GL_RGB10_A2\fP,
+\%\f3GL_RGBA12\fP or
+\%\f3GL_RGBA16\fP.
+.TP
+\f2width\fP
+Specifies the width in pixels of the texture image.
+This should be a power of 2.
+.TP
+\f2format\fP
+Specifies the of the pixel data.
+Must be one of:
+\%\f3GL_COLOR_INDEX\fP,
+\%\f3GL_DEPTH_COMPONENT\fP,
+\%\f3GL_RED\fP,
+\%\f3GL_GREEN\fP,
+\%\f3GL_BLUE\fP,
+\%\f3GL_ALPHA\fP,
+\%\f3GL_RGB\fP,
+\%\f3GL_RGBA\fP,
+\%\f3GL_BGR\fP,
+\%\f3GL_BGRA\fP,
+\%\f3GL_LUMINANCE\fP, or
+\%\f3GL_LUMINANCE_ALPHA\fP.
+.TP
+\f2type\fP
+Specifies the data type for \f2data\fP.
+Must be one of: \%\f3GL_UNSIGNED_BYTE\fP,
+\%\f3GL_BYTE\fP,
+\%\f3GL_BITMAP\fP,
+\%\f3GL_UNSIGNED_SHORT\fP,
+\%\f3GL_SHORT\fP,
+\%\f3GL_UNSIGNED_INT\fP,
+\%\f3GL_INT\fP,
+\%\f3GL_FLOAT\fP,
+\%\f3GL_UNSIGNED_BYTE_3_3_2\fP,
+\%\f3GL_UNSIGNED_BYTE_2_3_3_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_5_6_5\fP,
+\%\f3GL_UNSIGNED_SHORT_5_6_5_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_4_4_4_4\fP,
+\%\f3GL_UNSIGNED_SHORT_4_4_4_4_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_5_5_5_1\fP,
+\%\f3GL_UNSIGNED_SHORT_1_5_5_5_REV\fP,
+\%\f3GL_UNSIGNED_INT_8_8_8_8\fP,
+\%\f3GL_UNSIGNED_INT_8_8_8_8_REV\fP,
+\%\f3GL_UNSIGNED_INT_10_10_10_2\fP, or
+\%\f3GL_UNSIGNED_INT_2_10_10_10_REV\fP.
+.TP
+\f2level\fP
+Specifies the mipmap level of the image data.
+.TP
+\f2base\fP
+Specifies the minimum mipmap level to pass to \f3glTexImage1D\fP.
+.TP
+\f2max\fP
+Specifies the maximum mipmap level to pass to \f3glTexImage1D\fP.
+.TP
+\f2data\fP
+Specifies a pointer to the image data in memory.
+.SH DESCRIPTION
+\%\f3gluBuild1DMipmapLevels\fP builds a subset of prefiltered one-dimensional texture maps of decreasing
+resolutions called a mipmap. This is used for the antialiasing of
+texture mapped primitives.
+.P
+A return value of zero indicates success, otherwise a GLU error code is
+returned (see \%\f3gluErrorString\fP).
+.P
+A series of mipmap levels from \f2base\fP to \f2max\fP is built by decimating
+\f2data\fP in half
+until size $1 ~times~ 1$ is reached. At each level, each texel in the
+halved mipmap level is an average of the corresponding two texels in the larger
+mipmap level.
+\f3glTexImage1D\fP is called to load these mipmap levels from \f2base\fP
+to \f2max\fP. If \f2max\fP is larger than the highest mipmap level for the
+texture of the specified size, then a GLU error code is returned (see
+\%\f3gluErrorString\fP) and nothing is loaded.
+.P
+For example, if \f2level\fP is 2 and \f2width\fP is 16, the
+following levels are possible: $16 ~times~ 1$, $8 ~times~ 1$, $4 ~times~ 1$,
+$2 ~times~ 1$, $1 ~times~ 1$. These correspond
+to levels 2 through 6 respectively.
+If \f2base\fP is 3 and \f2max\fP is 5, then only mipmap levels $8 ~times~ 1$,
+$4 ~times~ 1$ and $2 ~times~ 1$ are
+loaded. However, if \f2max\fP is 7 then an error is returned and nothing is
+loaded since \f2max\fP is larger than the highest mipmap level which is, in
+this case, 6.
+.P
+The highest mipmap level can be derived from the formula
+${log sub 2} (\f2width\fP^{2 sup \f2level\fP})$.
+.P
+See the \f3glTexImage1D\fP reference page for a description of the
+acceptable values for \f2type\fP parameter. See the \f3glDrawPixels\fP
+reference page for a description of the acceptable values
+for \f2level\fP parameter.
+.bp
+.SH NOTES
+\%\f3gluBuild1DMipmapLevels\fP is only available if the GLU version is 1.3 or greater.
+.P
+Formats \%\f3GL_BGR\fP, and \%\f3GL_BGRA\fP, and types
+\%\f3GL_UNSIGNED_BYTE_3_3_2\fP,
+\%\f3GL_UNSIGNED_BYTE_2_3_3_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_5_6_5\fP,
+\%\f3GL_UNSIGNED_SHORT_5_6_5_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_4_4_4_4\fP,
+\%\f3GL_UNSIGNED_SHORT_4_4_4_4_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_5_5_5_1\fP,
+\%\f3GL_UNSIGNED_SHORT_1_5_5_5_REV\fP,
+\%\f3GL_UNSIGNED_INT_8_8_8_8\fP,
+\%\f3GL_UNSIGNED_INT_8_8_8_8_REV\fP,
+\%\f3GL_UNSIGNED_INT_10_10_10_2\fP, and
+\%\f3GL_UNSIGNED_INT_2_10_10_10_REV\fP are only available if the GL version
+is 1.2 or greater.
+.SH ERRORS
+\%\f3GLU_INVALID_VALUE\fP is returned if \f2level\fP > \f2base\fP, \f2base\fP < 0,
+\f2max\fP < \f2base\fP or \f2max\fP is > the highest mipmap level for \f2data\fP.
+.P
+\%\f3GLU_INVALID_VALUE\fP is returned if \f2width\fP is < 1.
+.P
+\%\f3GLU_INVALID_ENUM\fP is returned if \f2internalFormat\fP, \f2format\fP, or \f2type\fP are not
+legal.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2type\fP is \%\f3GL_UNSIGNED_BYTE_3_3_2\fP or \%\f3GL_UNSIGNED_BYTE_2_3_3_REV\fP
+and \f2format\fP is not \%\f3GL_RGB\fP.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2type\fP is \%\f3GL_UNSIGNED_SHORT_5_6_5\fP or \%\f3GL_UNSIGNED_SHORT_5_6_5_REV\fP
+and \f2format\fP is not \%\f3GL_RGB\fP.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2type\fP is \%\f3GL_UNSIGNED_SHORT_4_4_4_4\fP or \%\f3GL_UNSIGNED_SHORT_4_4_4_4_REV\fP
+and \f2format\fP is neither \%\f3GL_RGBA\fP nor \%\f3GL_BGRA\fP.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2type\fP is \%\f3GL_UNSIGNED_SHORT_5_5_5_1\fP or \%\f3GL_UNSIGNED_SHORT_1_5_5_5_REV\fP
+and \f2format\fP is neither \%\f3GL_RGBA\fP nor \%\f3GL_BGRA\fP.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2type\fP is \%\f3GL_UNSIGNED_INT_8_8_8_8\fP or \%\f3GL_UNSIGNED_INT_8_8_8_8_REV\fP
+and \f2format\fP is neither \%\f3GL_RGBA\fP nor \%\f3GL_BGRA\fP.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2type\fP is \%\f3GL_UNSIGNED_INT_10_10_10_2\fP or \%\f3GL_UNSIGNED_INT_2_10_10_10_REV\fP
+and \f2format\fP is neither \%\f3GL_RGBA\fP nor \%\f3GL_BGRA\fP.
+.SH SEE ALSO
+\f3glDrawPixels(3G)\fP, \f3glTexImage1D(3G)\fP, \f3glTexImage2D(3G)\fP,
+\f3glTexImage3D(3G)\fP,
+\%\f3gluBuild1DMipmaps(3G)\fP, \%\f3gluBuild2DMipmaps(3G)\fP, \%\f3gluBuild3DMipmaps(3G)\fP,
+\%\f3gluErrorString(3G)\fP,
+\f3glGetTexImage(3G)\fP,
+\f3glGetTexLevelParameter(3G)\fP,
+\%\f3gluBuild2DMipmapLevels(3G)\fP, \%\f3gluBuild3DMipmapLevels(3G)\fP
diff --git a/doc/gl-docs/GLU/build1dmipmaps.3gl b/doc/gl-docs/GLU/build1dmipmaps.3gl
new file mode 100644
index 000000000..22577b198
--- /dev/null
+++ b/doc/gl-docs/GLU/build1dmipmaps.3gl
@@ -0,0 +1,228 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 build1dmi
+.ds Xs 40806 9 build1dmipmaps.gl
+.TH GLUBUILD1DMIPMAPS 3G
+.SH NAME
+.B "gluBuild1DMipmaps
+\- builds a one-dimensional mipmap
+
+.SH C SPECIFICATION
+GLint \f3gluBuild1DMipmaps\fP(
+GLenum \fItarget\fP,
+.nf
+.ta \w'\f3GLint \fPgluBuild1DMipmaps( 'u
+ GLint \fIinternalFormat\fP,
+ GLsizei \fIwidth\fP,
+ GLenum \fIformat\fP,
+ GLenum \fItype\fP,
+ const void \fI*data\fP )
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\fIinternalFormat\fP\ \ 'u
+\f2target\fP
+Specifies the target texture. Must be \%\f3GL_TEXTURE_1D\fP.
+.TP
+\f2internalFormat\fP
+Requests the internal storage of the texture image. The most
+current version of the SGI implementation of GLU does not check this
+value for validity before passing it on to the underlying OpenGL
+implementation. A value that is not accepted by the OpenGL
+implementation will lead to an OpenGL error. The benefit of not
+checking this value at the GLU level is that OpenGL extensions can add
+new internal texture formats without requiring a revision of the GLU
+implementation. Older implementations of GLU check this value and
+raise a GLU error if it is not 1, 2, 3, or 4 or one of the following
+symbolic constants:
+\%\f3GL_ALPHA\fP,
+\%\f3GL_ALPHA4\fP,
+\%\f3GL_ALPHA8\fP,
+\%\f3GL_ALPHA12\fP,
+\%\f3GL_ALPHA16\fP,
+\%\f3GL_LUMINANCE\fP,
+\%\f3GL_LUMINANCE4\fP,
+\%\f3GL_LUMINANCE8\fP,
+\%\f3GL_LUMINANCE12\fP,
+\%\f3GL_LUMINANCE16\fP,
+\%\f3GL_LUMINANCE_ALPHA\fP,
+\%\f3GL_LUMINANCE4_ALPHA4\fP,
+\%\f3GL_LUMINANCE6_ALPHA2\fP,
+\%\f3GL_LUMINANCE8_ALPHA8\fP,
+\%\f3GL_LUMINANCE12_ALPHA4\fP,
+\%\f3GL_LUMINANCE12_ALPHA12\fP,
+\%\f3GL_LUMINANCE16_ALPHA16\fP,
+\%\f3GL_INTENSITY\fP,
+\%\f3GL_INTENSITY4\fP,
+\%\f3GL_INTENSITY8\fP,
+\%\f3GL_INTENSITY12\fP,
+\%\f3GL_INTENSITY16\fP,
+\%\f3GL_RGB\fP,
+\%\f3GL_R3_G3_B2\fP,
+\%\f3GL_RGB4\fP,
+\%\f3GL_RGB5\fP,
+\%\f3GL_RGB8\fP,
+\%\f3GL_RGB10\fP,
+\%\f3GL_RGB12\fP,
+\%\f3GL_RGB16\fP,
+\%\f3GL_RGBA\fP,
+\%\f3GL_RGBA2\fP,
+\%\f3GL_RGBA4\fP,
+\%\f3GL_RGB5_A1\fP,
+\%\f3GL_RGBA8\fP,
+\%\f3GL_RGB10_A2\fP,
+\%\f3GL_RGBA12\fP, or
+\%\f3GL_RGBA16\fP.
+.TP
+\f2width\fP
+Specifies the width, in pixels, of the texture image.
+.TP
+\f2format\fP
+Specifies the of the pixel data.
+Must be one of
+\%\f3GL_COLOR_INDEX\fP,
+\%\f3GL_DEPTH_COMPONENT\fP,
+\%\f3GL_RED\fP,
+\%\f3GL_GREEN\fP,
+\%\f3GL_BLUE\fP,
+\%\f3GL_ALPHA\fP,
+\%\f3GL_RGB\fP,
+\%\f3GL_RGBA\fP,
+\%\f3GL_BGR\fP,
+\%\f3GL_BGRA\fP,
+\%\f3GL_LUMINANCE\fP,
+\%\f3GL_LUMINANCE_ALPHA\fP.
+.TP
+\f2type\fP
+Specifies the data type for \f2data\fP.
+Must be one of
+\%\f3GL_UNSIGNED_BYTE\fP,
+\%\f3GL_BYTE\fP,
+\%\f3GL_BITMAP\fP,
+\%\f3GL_UNSIGNED_SHORT\fP,
+\%\f3GL_SHORT\fP,
+\%\f3GL_UNSIGNED_INT\fP,
+\%\f3GL_INT\fP,
+\%\f3GL_FLOAT\fP,
+\%\f3GL_UNSIGNED_BYTE_3_3_2\fP,
+\%\f3GL_UNSIGNED_BYTE_2_3_3_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_5_6_5\fP,
+\%\f3GL_UNSIGNED_SHORT_5_6_5_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_4_4_4_4\fP,
+\%\f3GL_UNSIGNED_SHORT_4_4_4_4_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_5_5_5_1\fP,
+\%\f3GL_UNSIGNED_SHORT_1_5_5_5_REV\fP,
+\%\f3GL_UNSIGNED_INT_8_8_8_8\fP,
+\%\f3GL_UNSIGNED_INT_8_8_8_8_REV\fP,
+\%\f3GL_UNSIGNED_INT_10_10_10_2\fP, or
+\%\f3GL_UNSIGNED_INT_2_10_10_10_REV\fP.
+.TP
+\f2data\fP
+Specifies a pointer to the image data in memory.
+.SH DESCRIPTION
+\%\f3gluBuild1DMipmaps\fP builds a series of prefiltered one-dimensional texture maps of decreasing
+resolutions called a mipmap. This is used for the antialiasing of
+texture mapped primitives.
+.P
+A return value of zero indicates success, otherwise a GLU error code is
+returned (see \%\f3gluErrorString\fP).
+.P
+Initially, the \f2width\fP of \f2data\fP is checked to see if it is
+a power of 2. If not, a copy of \f2data\fP is scaled up or down to the
+nearest power of 2. (If \f2width\fP is exactly between powers of 2, then
+the copy of \f2data\fP will scale upwards.) This copy will be used for
+subsequent mipmapping operations described below.
+For example, if \f2width\fP is 57 then a copy of \f2data\fP
+will scale up to 64 before mipmapping
+takes place.
+.P
+Then, proxy textures (see \f3glTexImage1D\fP) are used to determine if
+the implementation can fit the requested texture. If not, \f2width\fP is
+continually halved until it fits.
+.P
+Next, a series of mipmap levels is built by decimating a copy of
+\f2data\fP in half
+until size $1 ~times~ 1$ is reached. At each level, each texel in the
+halved mipmap level is an average of the corresponding two texels in the larger
+mipmap level.
+.P
+\f3glTexImage1D\fP is called to load each of these mipmap levels.
+Level 0 is a copy of \f2data\fP.
+The highest level is ${log sub 2}(\f2width\fP)$.
+For example, if \f2width\fP is 64 and the implementation can store a texture of
+this size, the following mipmap levels are
+built: $64 ~times~ 1$, $32 ~times~ 1$, $16 ~times~ 1$, $8 ~times~ 1$,
+$4 ~times~ 1$, $2 ~times~ 1$ and $1 ~times~ 1$. These correspond to
+levels 0 through 6, respectively.
+.P
+See the \f3glTexImage1D\fP reference page for a description of the
+acceptable values for the \f2type\fP parameter. See the \f3glDrawPixels\fP
+reference page for a description of the acceptable values
+for the \f2data\fP parameter.
+.SH NOTES
+Note that there is no direct way of querying the maximum level. This can
+be derived indirectly via \f3glGetTexLevelParameter\fP. First, query
+for the
+width actually used at level 0.
+(The width may not be equal to \f2width\fP since
+proxy textures might have scaled it to fit the implementation.)
+Then the maximum
+level can be derived from the formula ${log sub 2}(\f2width\fP)$.
+.P
+Formats \%\f3GL_BGR\fP, and \%\f3GL_BGRA\fP, and types
+\%\f3GL_UNSIGNED_BYTE_3_3_2\fP,
+\%\f3GL_UNSIGNED_BYTE_2_3_3_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_5_6_5\fP,
+\%\f3GL_UNSIGNED_SHORT_5_6_5_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_4_4_4_4\fP,
+\%\f3GL_UNSIGNED_SHORT_4_4_4_4_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_5_5_5_1\fP,
+\%\f3GL_UNSIGNED_SHORT_1_5_5_5_REV\fP,
+\%\f3GL_UNSIGNED_INT_8_8_8_8\fP,
+\%\f3GL_UNSIGNED_INT_8_8_8_8_REV\fP,
+\%\f3GL_UNSIGNED_INT_10_10_10_2\fP, and
+\%\f3GL_UNSIGNED_INT_2_10_10_10_REV\fP are only available if the GL version
+is 1.2 or greater, and if the GLU version is 1.3 or greater.
+.SH ERRORS
+\%\f3GLU_INVALID_VALUE\fP is returned if \f2width\fP is < 1.
+.P
+\%\f3GLU_INVALID_ENUM\fP is returned if \f2format\fP or \f2type\fP are not legal.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2type\fP is \%\f3GL_UNSIGNED_BYTE_3_3_2\fP or \%\f3GL_UNSIGNED_BYTE_2_3_3_REV\fP
+and \f2format\fP is not \%\f3GL_RGB\fP.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2type\fP is \%\f3GL_UNSIGNED_SHORT_5_6_5\fP or \%\f3GL_UNSIGNED_SHORT_5_6_5_REV\fP
+and \f2format\fP is not \%\f3GL_RGB\fP.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2type\fP is \%\f3GL_UNSIGNED_SHORT_4_4_4_4\fP or \%\f3GL_UNSIGNED_SHORT_4_4_4_4_REV\fP
+and \f2format\fP is neither \%\f3GL_RGBA\fP nor \%\f3GL_BGRA\fP.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2type\fP is \%\f3GL_UNSIGNED_SHORT_5_5_5_1\fP or \%\f3GL_UNSIGNED_SHORT_1_5_5_5_REV\fP
+and \f2format\fP is neither \%\f3GL_RGBA\fP nor \%\f3GL_BGRA\fP.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2type\fP is \%\f3GL_UNSIGNED_INT_8_8_8_8\fP or \%\f3GL_UNSIGNED_INT_8_8_8_8_REV\fP
+and \f2format\fP is neither \%\f3GL_RGBA\fP nor \%\f3GL_BGRA\fP.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2type\fP is \%\f3GL_UNSIGNED_INT_10_10_10_2\fP or \%\f3GL_UNSIGNED_INT_2_10_10_10_REV\fP
+and \f2format\fP is neither \%\f3GL_RGBA\fP nor \%\f3GL_BGRA\fP.
+.SH SEE ALSO
+\f3glDrawPixels(3G)\fP,
+\f3glTexImage1D(3G)\fP,
+\f3glTexImage2D(3G)\fP,
+\f3glTexImage3D(3G)\fP,
+\%\f3gluBuild2DMipmaps(3G)\fP,
+\%\f3gluBuild3DMipmaps(3G)\fP,
+\%\f3gluErrorString(3G)\fP,
+\f3glGetTexImage(3G)\fP,
+\f3glGetTexLevelParameter(3G)\fP,
+\%\f3gluBuild1DMipmapLevels(3G)\fP,
+\%\f3gluBuild2DMipmapLevels(3G)\fP,
+\%\f3gluBuild3DMipmapLevels(3G)\fP
diff --git a/doc/gl-docs/GLU/build2dmipmaplevels.3gl b/doc/gl-docs/GLU/build2dmipmaplevels.3gl
new file mode 100644
index 000000000..37cdf02b4
--- /dev/null
+++ b/doc/gl-docs/GLU/build2dmipmaplevels.3gl
@@ -0,0 +1,234 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 build2dmi
+.ds Xs 35570 9 build2dmipmaplevels.gl
+.TH GLUBUILD2DMIPMAPLEVELS 3G
+.SH NAME
+.B "gluBuild2DMipmapLevels
+\- builds a subset of two-dimensional mipmap levels
+
+.SH C SPECIFICATION
+GLint \f3gluBuild2DMipmapLevels\fP(
+GLenum \fItarget\fP,
+.nf
+.ta \w'\f3GLint \fPgluBuild2DMipmapLevels( 'u
+ GLint \fIinternalFormat\fP,
+ GLsizei \fIwidth\fP,
+ GLsizei \fIheight\fP,
+ GLenum \fIformat\fP,
+ GLenum \fItype\fP,
+ GLint \fIlevel\fP,
+ GLint \fIbase\fP,
+ GLint \fImax\fP,
+ const void \fI*data\fP )
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\fIinternalFormat\fP\ \ 'u
+\f2target\fP
+Specifies the target texture. Must be \%\f3GL_TEXTURE_2D\fP.
+.TP
+\f2internalFormat\fP
+Requests the internal storage of the texture image. The most
+current version of the SGI implementation of GLU does not check this
+value for validity before passing it on to the underlying OpenGL
+implementation. A value that is not accepted by the OpenGL
+implementation will lead to an OpenGL error. The benefit of not
+checking this value at the GLU level is that OpenGL extensions can add
+new internal texture formats without requiring a revision of the GLU
+implementation. Older implementations of GLU check this value and
+raise a GLU error if it is not 1, 2, 3, or 4 or one of the following
+symbolic constants:
+\%\f3GL_ALPHA\fP,
+\%\f3GL_ALPHA4\fP,
+\%\f3GL_ALPHA8\fP,
+\%\f3GL_ALPHA12\fP,
+\%\f3GL_ALPHA16\fP,
+\%\f3GL_LUMINANCE\fP,
+\%\f3GL_LUMINANCE4\fP,
+\%\f3GL_LUMINANCE8\fP,
+\%\f3GL_LUMINANCE12\fP,
+\%\f3GL_LUMINANCE16\fP,
+\%\f3GL_LUMINANCE_ALPHA\fP,
+\%\f3GL_LUMINANCE4_ALPHA4\fP,
+\%\f3GL_LUMINANCE6_ALPHA2\fP,
+\%\f3GL_LUMINANCE8_ALPHA8\fP,
+\%\f3GL_LUMINANCE12_ALPHA4\fP,
+\%\f3GL_LUMINANCE12_ALPHA12\fP,
+\%\f3GL_LUMINANCE16_ALPHA16\fP,
+\%\f3GL_INTENSITY\fP,
+\%\f3GL_INTENSITY4\fP,
+\%\f3GL_INTENSITY8\fP,
+\%\f3GL_INTENSITY12\fP,
+\%\f3GL_INTENSITY16\fP,
+\%\f3GL_RGB\fP,
+\%\f3GL_R3_G3_B2\fP,
+\%\f3GL_RGB4\fP,
+\%\f3GL_RGB5\fP,
+\%\f3GL_RGB8\fP,
+\%\f3GL_RGB10\fP,
+\%\f3GL_RGB12\fP,
+\%\f3GL_RGB16\fP,
+\%\f3GL_RGBA\fP,
+\%\f3GL_RGBA2\fP,
+\%\f3GL_RGBA4\fP,
+\%\f3GL_RGB5_A1\fP,
+\%\f3GL_RGBA8\fP,
+\%\f3GL_RGB10_A2\fP,
+\%\f3GL_RGBA12\fP or
+\%\f3GL_RGBA16\fP.
+.TP
+\f2width\fP, \f2height\fP
+Specifies the width and height, respectively, in pixels of the texture image.
+These should be a power of 2.
+.TP
+\f2format\fP
+Specifies the of the pixel data.
+Must be one of
+\%\f3GL_COLOR_INDEX\fP,
+\%\f3GL_DEPTH_COMPONENT\fP,
+\%\f3GL_RED\fP,
+\%\f3GL_GREEN\fP,
+\%\f3GL_BLUE\fP,
+\%\f3GL_ALPHA\fP,
+\%\f3GL_RGB\fP,
+\%\f3GL_RGBA\fP,
+\%\f3GL_BGR\fP,
+\%\f3GL_BGRA\fP,
+\%\f3GL_LUMINANCE\fP, or
+\%\f3GL_LUMINANCE_ALPHA\fP.
+.TP
+\f2type\fP
+Specifies the data type for \f2data\fP.
+Must be one of
+\%\f3GL_UNSIGNED_BYTE\fP,
+\%\f3GL_BYTE\fP,
+\%\f3GL_BITMAP\fP,
+\%\f3GL_UNSIGNED_SHORT\fP,
+\%\f3GL_SHORT\fP,
+\%\f3GL_UNSIGNED_INT\fP,
+\%\f3GL_INT\fP,
+\%\f3GL_FLOAT\fP,
+\%\f3GL_UNSIGNED_BYTE_3_3_2\fP,
+\%\f3GL_UNSIGNED_BYTE_2_3_3_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_5_6_5\fP,
+\%\f3GL_UNSIGNED_SHORT_5_6_5_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_4_4_4_4\fP,
+\%\f3GL_UNSIGNED_SHORT_4_4_4_4_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_5_5_5_1\fP,
+\%\f3GL_UNSIGNED_SHORT_1_5_5_5_REV\fP,
+\%\f3GL_UNSIGNED_INT_8_8_8_8\fP,
+\%\f3GL_UNSIGNED_INT_8_8_8_8_REV\fP,
+\%\f3GL_UNSIGNED_INT_10_10_10_2\fP or
+\%\f3GL_UNSIGNED_INT_2_10_10_10_REV\fP.
+.TP
+\f2level\fP
+Specifies the mipmap level of the image data.
+.TP
+\f2base\fP
+Specifies the minimum mipmap level to pass to \f3glTexImage2D\fP.
+.TP
+\f2max\fP
+Specifies the maximum mipmap level to pass to \f3glTexImage2D\fP.
+.TP
+\f2data\fP
+Specifies a pointer to the image data in memory.
+.SH DESCRIPTION
+\%\f3gluBuild2DMipmapLevels\fP builds a subset of prefiltered two-dimensional texture maps of decreasing
+resolutions called a mipmap. This is used for the antialiasing of
+texture mapped primitives.
+.P
+A return value of zero indicates success, otherwise a GLU error code is
+returned (see \%\f3gluErrorString\fP).
+.P
+A series of mipmap levels from \f2base\fP to \f2max\fP is built by decimating
+\f2data\fP in half along
+both dimensions until size $1 ~times~ 1$ is reached. At each level, each texel in the
+halved mipmap level is an average of the corresponding four texels in the larger
+mipmap level. (In the case of rectangular images, the decimation will ultimately
+reach an $N ~times~ 1$ or $1 ~times~ N$ configuration. Here, two texels are
+averaged instead.)
+\f3glTexImage2D\fP is called to load these mipmap levels from \f2base\fP
+to \f2max\fP. If \f2max\fP is larger than the highest mipmap level for the
+texture of the specified size, then a GLU error code is returned (see
+\%\f3gluErrorString\fP) and nothing is loaded.
+.P
+For example, if \f2level\fP is 2 and \f2width\fP is 16 and \f2height\fP is 8, the
+following levels are possible: $16 ~times~ 8$, $8 ~times~ 4$, $4 ~times~ 2$,
+$2 ~times~ 1$, $1 ~times~ 1$. These correspond to levels 2 through 6
+respectively. If \f2base\fP is 3 and \f2max\fP is 5, then only mipmap levels
+$8 ~times~ 4$, $4 ~times~ 2$ and $2 ~times~ 1$ are loaded. However, if \f2max\fP
+is 7 then an error is returned and nothing is loaded since \f2max\fP is
+larger than the highest mipmap level which is, in this case, 6.
+.P
+The highest mipmap level can be derived from the formula
+log2(max(\f2width\fP,\f2height\fP)*(2^\f2level\fP)).
+.P
+See the \f3glTexImage1D\fP reference page for a description of the
+acceptable values for \f2format\fP parameter. See the \f3glDrawPixels\fP
+reference page for a description of the acceptable values
+for \f2type\fP parameter.
+.SH NOTES
+\%\f3gluBuild2DMipmapLevels\fP is only available if the GLU version is 1.3 or greater.
+.P
+Formats \%\f3GL_BGR\fP, and \%\f3GL_BGRA\fP, and types
+\%\f3GL_UNSIGNED_BYTE_3_3_2\fP,
+\%\f3GL_UNSIGNED_BYTE_2_3_3_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_5_6_5\fP,
+\%\f3GL_UNSIGNED_SHORT_5_6_5_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_4_4_4_4\fP,
+\%\f3GL_UNSIGNED_SHORT_4_4_4_4_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_5_5_5_1\fP,
+\%\f3GL_UNSIGNED_SHORT_1_5_5_5_REV\fP,
+\%\f3GL_UNSIGNED_INT_8_8_8_8\fP,
+\%\f3GL_UNSIGNED_INT_8_8_8_8_REV\fP,
+\%\f3GL_UNSIGNED_INT_10_10_10_2\fP, and
+\%\f3GL_UNSIGNED_INT_2_10_10_10_REV\fP are only available if the GL version
+is 1.2 or greater.
+.SH ERRORS
+\%\f3GLU_INVALID_VALUE\fP is returned if \f2level\fP > \f2base\fP, \f2base\fP < 0,
+\f2max\fP < \f2base\fP or \f2max\fP is > the highest mipmap level for \f2data\fP.
+.P
+\%\f3GLU_INVALID_VALUE\fP is returned if \f2width\fP or \f2height\fP is < 1.
+.P
+\%\f3GLU_INVALID_ENUM\fP is returned if \f2internalFormat\fP, \f2format\fP, or \f2type\fP is not
+legal.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2type\fP is \%\f3GL_UNSIGNED_BYTE_3_3_2\fP or \%\f3GL_UNSIGNED_BYTE_2_3_3_REV\fP
+and \f2format\fP is not \%\f3GL_RGB\fP.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2type\fP is \%\f3GL_UNSIGNED_SHORT_5_6_5\fP or \%\f3GL_UNSIGNED_SHORT_5_6_5_REV\fP
+and \f2format\fP is not \%\f3GL_RGB\fP.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2type\fP is \%\f3GL_UNSIGNED_SHORT_4_4_4_4\fP or \%\f3GL_UNSIGNED_SHORT_4_4_4_4_REV\fP
+and \f2format\fP is neither \%\f3GL_RGBA\fP nor \%\f3GL_BGRA\fP.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2type\fP is \%\f3GL_UNSIGNED_SHORT_5_5_5_1\fP or \%\f3GL_UNSIGNED_SHORT_1_5_5_5_REV\fP
+and \f2format\fP is neither \%\f3GL_RGBA\fP nor \%\f3GL_BGRA\fP.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2type\fP is \%\f3GL_UNSIGNED_INT_8_8_8_8\fP or \%\f3GL_UNSIGNED_INT_8_8_8_8_REV\fP
+and \f2format\fP is neither \%\f3GL_RGBA\fP nor \%\f3GL_BGRA\fP.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2type\fP is \%\f3GL_UNSIGNED_INT_10_10_10_2\fP or \%\f3GL_UNSIGNED_INT_2_10_10_10_REV\fP
+and \f2format\fP is neither \%\f3GL_RGBA\fP nor \%\f3GL_BGRA\fP.
+.SH SEE ALSO
+\f3glDrawPixels(3G)\fP,
+\f3glTexImage1D(3G)\fP,
+\f3glTexImage2D(3G)\fP,
+\f3glTexImage3D(3G)\fP,
+\%\f3gluBuild1DMipmaps(3G)\fP,
+\%\f3gluBuild2DMipmaps(3G)\fP,
+\%\f3gluBuild3DMipmaps(3G)\fP,
+\%\f3gluErrorString(3G)\fP,
+\f3glGetTexImage(3G)\fP,
+\f3glGetTexLevelParameter(3G)\fP,
+\%\f3gluBuild1DMipmapLevels(3G)\fP,
+\%\f3gluBuild3DMipmapLevels(3G)\fP
diff --git a/doc/gl-docs/GLU/build2dmipmaps.3gl b/doc/gl-docs/GLU/build2dmipmaps.3gl
new file mode 100644
index 000000000..e7d970c64
--- /dev/null
+++ b/doc/gl-docs/GLU/build2dmipmaps.3gl
@@ -0,0 +1,236 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 build2dmi
+.ds Xs 21901 10 build2dmipmaps.gl
+.TH GLUBUILD2DMIPMAPS 3G
+.SH NAME
+.B "gluBuild2DMipmaps
+\- builds a two-dimensional mipmap
+
+.SH C SPECIFICATION
+GLint \f3gluBuild2DMipmaps\fP(
+GLenum \fItarget\fP,
+.nf
+.ta \w'\f3GLint \fPgluBuild2DMipmaps( 'u
+ GLint \fIinternalFormat\fP,
+ GLsizei \fIwidth\fP,
+ GLsizei \fIheight\fP,
+ GLenum \fIformat\fP,
+ GLenum \fItype\fP,
+ const void \fI*data\fP )
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\fIinternalFormat\fP\ \ 'u
+\f2target\fP
+Specifies the target texture. Must be \%\f3GL_TEXTURE_2D\fP.
+.TP
+\f2internalFormat\fP
+Requests the internal storage of the texture image. The most
+current version of the SGI implementation of GLU does not check this
+value for validity before passing it on to the underlying OpenGL
+implementation. A value that is not accepted by the OpenGL
+implementation will lead to an OpenGL error. The benefit of not
+checking this value at the GLU level is that OpenGL extensions can add
+new internal texture formats without requiring a revision of the GLU
+implementation. Older implementations of GLU check this value and
+raise a GLU error if it is not 1, 2, 3, or 4 or one of the following
+symbolic constants:
+\%\f3GL_ALPHA\fP,
+\%\f3GL_ALPHA4\fP,
+\%\f3GL_ALPHA8\fP,
+\%\f3GL_ALPHA12\fP,
+\%\f3GL_ALPHA16\fP,
+\%\f3GL_LUMINANCE\fP,
+\%\f3GL_LUMINANCE4\fP,
+\%\f3GL_LUMINANCE8\fP,
+\%\f3GL_LUMINANCE12\fP,
+\%\f3GL_LUMINANCE16\fP,
+\%\f3GL_LUMINANCE_ALPHA\fP,
+\%\f3GL_LUMINANCE4_ALPHA4\fP,
+\%\f3GL_LUMINANCE6_ALPHA2\fP,
+\%\f3GL_LUMINANCE8_ALPHA8\fP,
+\%\f3GL_LUMINANCE12_ALPHA4\fP,
+\%\f3GL_LUMINANCE12_ALPHA12\fP,
+\%\f3GL_LUMINANCE16_ALPHA16\fP,
+\%\f3GL_INTENSITY\fP,
+\%\f3GL_INTENSITY4\fP,
+\%\f3GL_INTENSITY8\fP,
+\%\f3GL_INTENSITY12\fP,
+\%\f3GL_INTENSITY16\fP,
+\%\f3GL_RGB\fP,
+\%\f3GL_R3_G3_B2\fP,
+\%\f3GL_RGB4\fP,
+\%\f3GL_RGB5\fP,
+\%\f3GL_RGB8\fP,
+\%\f3GL_RGB10\fP,
+\%\f3GL_RGB12\fP,
+\%\f3GL_RGB16\fP,
+\%\f3GL_RGBA\fP,
+\%\f3GL_RGBA2\fP,
+\%\f3GL_RGBA4\fP,
+\%\f3GL_RGB5_A1\fP,
+\%\f3GL_RGBA8\fP,
+\%\f3GL_RGB10_A2\fP,
+\%\f3GL_RGBA12\fP or
+\%\f3GL_RGBA16\fP.
+.TP
+\f2width\fP, \f2height\fP
+Specifies in pixels the width and height, respectively, of the texture image.
+.TP
+\f2format\fP
+Specifies the of the pixel data.
+Must be one of
+\%\f3GL_COLOR_INDEX\fP,
+\%\f3GL_DEPTH_COMPONENT\fP,
+\%\f3GL_RED\fP,
+\%\f3GL_GREEN\fP,
+\%\f3GL_BLUE\fP,
+\%\f3GL_ALPHA\fP,
+\%\f3GL_RGB\fP,
+\%\f3GL_RGBA\fP,
+\%\f3GL_BGR\fP,
+\%\f3GL_BGRA\fP,
+\%\f3GL_LUMINANCE\fP, or
+\%\f3GL_LUMINANCE_ALPHA\fP.
+.TP
+\f2type\fP
+Specifies the data type for \f2data\fP.
+Must be one of
+\%\f3GL_UNSIGNED_BYTE\fP,
+\%\f3GL_BYTE\fP,
+\%\f3GL_BITMAP\fP,
+\%\f3GL_UNSIGNED_SHORT\fP,
+\%\f3GL_SHORT\fP,
+\%\f3GL_UNSIGNED_INT\fP,
+\%\f3GL_INT\fP,
+\%\f3GL_FLOAT\fP,
+\%\f3GL_UNSIGNED_BYTE_3_3_2\fP,
+\%\f3GL_UNSIGNED_BYTE_2_3_3_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_5_6_5\fP,
+\%\f3GL_UNSIGNED_SHORT_5_6_5_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_4_4_4_4\fP,
+\%\f3GL_UNSIGNED_SHORT_4_4_4_4_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_5_5_5_1\fP,
+\%\f3GL_UNSIGNED_SHORT_1_5_5_5_REV\fP,
+\%\f3GL_UNSIGNED_INT_8_8_8_8\fP,
+\%\f3GL_UNSIGNED_INT_8_8_8_8_REV\fP,
+\%\f3GL_UNSIGNED_INT_10_10_10_2\fP, or
+\%\f3GL_UNSIGNED_INT_2_10_10_10_REV\fP.
+.TP
+\f2data\fP
+Specifies a pointer to the image data in memory.
+
+
+.SH DESCRIPTION
+\%\f3gluBuild2DMipmaps\fP builds a series of prefiltered two-dimensional texture maps of decreasing
+resolutions called a mipmap. This is used for the antialiasing of
+texture-mapped primitives.
+.P
+A return value of zero indicates success, otherwise a GLU error code is
+returned (see \%\f3gluErrorString\fP).
+.P
+Initially, the \f2width\fP and \f2height\fP of \f2data\fP are checked to see if they
+are a power of 2. If not, a copy of \f2data\fP (not \f2data\fP), is scaled up
+or down to the nearest power of 2. This copy will be used for subsequent
+mipmapping operations described below. (If \f2width\fP or \f2height\fP is exactly
+between powers of 2, then the copy of \f2data\fP will scale upwards.) For
+example, if \f2width\fP is 57 and \f2height\fP is 23 then a copy of \f2data\fP will
+scale up to 64 in \f2width\fP and down to 16 in depth, before mipmapping takes
+place.
+.P
+Then, proxy textures (see \f3glTexImage2D\fP) are used to determine if
+the implementation can fit the requested texture. If not, both dimensions
+are continually halved until it fits. (If the OpenGL version is \(<= 1.0,
+both maximum texture dimensions are clamped to the value returned
+by \f3glGetIntegerv\fP with the argument \%\f3GL_MAX_TEXTURE_SIZE\fP.)
+.P
+Next, a series of mipmap levels is built by decimating a copy of \f2data\fP
+in half along both dimensions until size $1 ~times~ 1$ is reached. At
+each level,
+each texel in the halved mipmap level is an average of the corresponding
+four texels in the larger mipmap level. (In the case of rectangular
+images, the decimation will ultimately reach an $N ~times~ 1$ or
+$1 ~times~ N$ configuration. Here, two texels are averaged instead.)
+.P
+\f3glTexImage2D\fP is called to load each of these mipmap levels.
+Level 0 is a copy of \f2data\fP. The highest level is
+${log sub 2} ( max ("width","height"))$. For example,
+if \f2width\fP is 64 and \f2height\fP is 16
+and the implementation can store a texture of this size, the following
+mipmap levels are built: $64 ~times~ 16$, $32 ~times~ 8$, $16 ~times~ 4$,
+$8 ~times~ 2$, $4 ~times~ 1$, $2 ~times~ 1$ and $1 ~times~ 1$. These correspond to
+levels 0 through 6, respectively.
+.P
+See the \f3glTexImage1D\fP reference page for a description of the
+acceptable values for \f2format\fP parameter. See the \f3glDrawPixels\fP
+reference page for a description of the acceptable values
+for \f2type\fP parameter.
+.SH NOTES
+
+Note that there is no direct way of querying the maximum level. This can
+be derived indirectly via \f3glGetTexLevelParameter\fP. First, query
+for the width and height actually used at level 0. (The width and
+height may not be equal to \f2width\fP and \f2height\fP respectively since proxy
+textures might have scaled them to fit the implementation.) Then the
+maximum level can be derived from the formula
+${log sub 2}( max (\f2width\fP,\f2height\fP))$.
+.SH NOTES
+Formats \%\f3GL_BGR\fP, and \%\f3GL_BGRA\fP, and types
+\%\f3GL_UNSIGNED_BYTE_3_3_2\fP,
+\%\f3GL_UNSIGNED_BYTE_2_3_3_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_5_6_5\fP,
+\%\f3GL_UNSIGNED_SHORT_5_6_5_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_4_4_4_4\fP,
+\%\f3GL_UNSIGNED_SHORT_4_4_4_4_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_5_5_5_1\fP,
+\%\f3GL_UNSIGNED_SHORT_1_5_5_5_REV\fP,
+\%\f3GL_UNSIGNED_INT_8_8_8_8\fP,
+\%\f3GL_UNSIGNED_INT_8_8_8_8_REV\fP,
+\%\f3GL_UNSIGNED_INT_10_10_10_2\fP, and
+\%\f3GL_UNSIGNED_INT_2_10_10_10_REV\fP are only available if the GL version
+is 1.2 or greater and if the GLU version is 1.3 or greater.
+.SH ERRORS
+\%\f3GLU_INVALID_VALUE\fP is returned if \f2width\fP, or \f2height\fP is < 1.
+.P
+\%\f3GLU_INVALID_ENUM\fP is returned if \f2internalFormat\fP, \f2format\fP, or \f2type\fP is not
+legal.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2type\fP is \%\f3GL_UNSIGNED_BYTE_3_3_2\fP or \%\f3GL_UNSIGNED_BYTE_2_3_3_REV\fP
+and \f2format\fP is not \%\f3GL_RGB\fP.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2type\fP is \%\f3GL_UNSIGNED_SHORT_5_6_5\fP or \%\f3GL_UNSIGNED_SHORT_5_6_5_REV\fP
+and \f2format\fP is not \%\f3GL_RGB\fP.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2type\fP is \%\f3GL_UNSIGNED_SHORT_4_4_4_4\fP or \%\f3GL_UNSIGNED_SHORT_4_4_4_4_REV\fP
+and \f2format\fP is neither \%\f3GL_RGBA\fP nor \%\f3GL_BGRA\fP.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2type\fP is \%\f3GL_UNSIGNED_SHORT_5_5_5_1\fP or \%\f3GL_UNSIGNED_SHORT_1_5_5_5_REV\fP
+and \f2format\fP is neither \%\f3GL_RGBA\fP nor \%\f3GL_BGRA\fP.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2type\fP is \%\f3GL_UNSIGNED_INT_8_8_8_8\fP or \%\f3GL_UNSIGNED_INT_8_8_8_8_REV\fP
+and \f2format\fP is neither \%\f3GL_RGBA\fP nor \%\f3GL_BGRA\fP.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2type\fP is \%\f3GL_UNSIGNED_INT_10_10_10_2\fP or \%\f3GL_UNSIGNED_INT_2_10_10_10_REV\fP
+and \f2format\fP is neither \%\f3GL_RGBA\fP nor \%\f3GL_BGRA\fP.
+.SH SEE ALSO
+\f3glDrawPixels(3G)\fP,
+\f3glTexImage1D(3G)\fP,
+\f3glTexImage2D(3G)\fP,
+\f3glTexImage3D(3G)\fP,
+\%\f3gluBuild1DMipmaps(3G)\fP,
+\%\f3gluBuild3DMipmaps(3G)\fP,
+\%\f3gluErrorString(3G)\fP,
+\f3glGetTexImage(3G)\fP,
+\f3glGetTexLevelParameter(3G)\fP,
+\%\f3gluBuild1DMipmapLevels(3G)\fP,
+\%\f3gluBuild2DMipmapLevels(3G)\fP,
+\%\f3gluBuild3DMipmapLevels(3G)\fP
diff --git a/doc/gl-docs/GLU/build3dmipmaplevels.3gl b/doc/gl-docs/GLU/build3dmipmaplevels.3gl
new file mode 100644
index 000000000..768398349
--- /dev/null
+++ b/doc/gl-docs/GLU/build3dmipmaplevels.3gl
@@ -0,0 +1,237 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 build3dmi
+.ds Xs 53966 9 build3dmipmaplevels.gl
+.TH GLUBUILD3DMIPMAPLEVELS 3G
+.SH NAME
+.B "gluBuild3DMipmapLevels
+\- builds a subset of three-dimensional mipmap levels
+
+.SH C SPECIFICATION
+GLint \f3gluBuild3DMipmapLevels\fP(
+GLenum \fItarget\fP,
+.nf
+.ta \w'\f3GLint \fPgluBuild3DMipmapLevels( 'u
+ GLint \fIinternalFormat\fP,
+ GLsizei \fIwidth\fP,
+ GLsizei \fIheight\fP,
+ GLsizei \fIdepth\fP,
+ GLenum \fIformat\fP,
+ GLenum \fItype\fP,
+ GLint \fIlevel\fP,
+ GLint \fIbase\fP,
+ GLint \fImax\fP,
+ const void \fI*data\fP )
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\fIinternalFormat\fP\ \ 'u
+\f2target\fP
+Specifies the target texture. Must be \%\f3GL_TEXTURE_3D\fP.
+.TP
+\f2internalFormat\fP
+Requests the internal storage of the texture image. The most
+current version of the SGI implementation of GLU does not check this
+value for validity before passing it on to the underlying OpenGL
+implementation. A value that is not accepted by the OpenGL
+implementation will lead to an OpenGL error. The benefit of not
+checking this value at the GLU level is that OpenGL extensions can add
+new internal texture formats without requiring a revision of the GLU
+implementation. Older implementations of GLU check this value and
+raise a GLU error if it is not 1, 2, 3, or 4 or one of the following
+symbolic constants:
+\%\f3GL_ALPHA\fP,
+\%\f3GL_ALPHA4\fP,
+\%\f3GL_ALPHA8\fP,
+\%\f3GL_ALPHA12\fP,
+\%\f3GL_ALPHA16\fP,
+\%\f3GL_LUMINANCE\fP,
+\%\f3GL_LUMINANCE4\fP,
+\%\f3GL_LUMINANCE8\fP,
+\%\f3GL_LUMINANCE12\fP,
+\%\f3GL_LUMINANCE16\fP,
+\%\f3GL_LUMINANCE_ALPHA\fP,
+\%\f3GL_LUMINANCE4_ALPHA4\fP,
+\%\f3GL_LUMINANCE6_ALPHA2\fP,
+\%\f3GL_LUMINANCE8_ALPHA8\fP,
+\%\f3GL_LUMINANCE12_ALPHA4\fP,
+\%\f3GL_LUMINANCE12_ALPHA12\fP,
+\%\f3GL_LUMINANCE16_ALPHA16\fP,
+\%\f3GL_INTENSITY\fP,
+\%\f3GL_INTENSITY4\fP,
+\%\f3GL_INTENSITY8\fP,
+\%\f3GL_INTENSITY12\fP,
+\%\f3GL_INTENSITY16\fP,
+\%\f3GL_RGB\fP,
+\%\f3GL_R3_G3_B2\fP,
+\%\f3GL_RGB4\fP,
+\%\f3GL_RGB5\fP,
+\%\f3GL_RGB8\fP,
+\%\f3GL_RGB10\fP,
+\%\f3GL_RGB12\fP,
+\%\f3GL_RGB16\fP,
+\%\f3GL_RGBA\fP,
+\%\f3GL_RGBA2\fP,
+\%\f3GL_RGBA4\fP,
+\%\f3GL_RGB5_A1\fP,
+\%\f3GL_RGBA8\fP,
+\%\f3GL_RGB10_A2\fP,
+\%\f3GL_RGBA12\fP, or
+\%\f3GL_RGBA16\fP.
+.TP
+\f2width\fP, \f2height\fP, \f2depth\fP
+Specifies in pixels the width, height and depth respectively, of the texture
+image. These should be a power of 2.
+.TP
+\f2format\fP
+Specifies the of the pixel data.
+Must be one of
+\%\f3GL_COLOR_INDEX\fP,
+\%\f3GL_DEPTH_COMPONENT\fP,
+\%\f3GL_RED\fP,
+\%\f3GL_GREEN\fP,
+\%\f3GL_BLUE\fP,
+\%\f3GL_ALPHA\fP,
+\%\f3GL_RGB\fP,
+\%\f3GL_RGBA\fP,
+\%\f3GL_BGR\fP,
+\%\f3GL_BGRA\fP,
+\%\f3GL_LUMINANCE\fP, or
+\%\f3GL_LUMINANCE_ALPHA\fP.
+.TP
+\f2type\fP
+Specifies the data type for \f2data\fP.
+Must be one of
+\%\f3GL_UNSIGNED_BYTE\fP,
+\%\f3GL_BYTE\fP,
+\%\f3GL_BITMAP\fP,
+\%\f3GL_UNSIGNED_SHORT\fP,
+\%\f3GL_SHORT\fP,
+\%\f3GL_UNSIGNED_INT\fP,
+\%\f3GL_INT\fP,
+\%\f3GL_FLOAT\fP,
+\%\f3GL_UNSIGNED_BYTE_3_3_2\fP,
+\%\f3GL_UNSIGNED_BYTE_2_3_3_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_5_6_5\fP,
+\%\f3GL_UNSIGNED_SHORT_5_6_5_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_4_4_4_4\fP,
+\%\f3GL_UNSIGNED_SHORT_4_4_4_4_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_5_5_5_1\fP,
+\%\f3GL_UNSIGNED_SHORT_1_5_5_5_REV\fP,
+\%\f3GL_UNSIGNED_INT_8_8_8_8\fP,
+\%\f3GL_UNSIGNED_INT_8_8_8_8_REV\fP,
+\%\f3GL_UNSIGNED_INT_10_10_10_2\fP, or
+\%\f3GL_UNSIGNED_INT_2_10_10_10_REV\fP.
+.TP
+\f2level\fP
+Specifies the mipmap level of the image data.
+.TP
+\f2base\fP
+Specifies the minimum mipmap level to pass to \f3glTexImage3D\fP.
+.TP
+\f2max\fP
+Specifies the maximum mipmap level to pass to \f3glTexImage3D\fP.
+.TP
+\f2data\fP
+Specifies a pointer to the image data in memory.
+.SH DESCRIPTION
+\%\f3gluBuild3DMipmapLevels\fP builds a subset of prefiltered three-dimensional texture maps of
+decreasing resolutions called a mipmap. This is used for the antialiasing of
+texture mapped primitives.
+.P
+A return value of zero indicates success, otherwise a GLU error code is
+returned (see \%\f3gluErrorString\fP).
+.P
+A series of mipmap levels from \f2base\fP to \f2max\fP is built by
+decimating \f2data\fP in half along both dimensions until size $1 ~times~ 1
+~times~ 1$ is reached. At each level, each texel in the halved mipmap
+level is an average of the corresponding eight texels in the larger
+mipmap level. (If exactly one of the dimensions is 1, four texels are
+averaged. If exactly two of the dimensions are 1, two texels are
+averaged.) \f3glTexImage3D\fP is called to load these mipmap levels
+from \f2base\fP to \f2max\fP. If \f2max\fP is larger than the highest mipmap
+level for the texture of the specified size, then a GLU error code is
+returned (see \%\f3gluErrorString\fP) and nothing is loaded.
+.P
+For example, if \f2level\fP is 2 and \f2width\fP is 16, \f2height\fP is 8 and \f2depth\fP
+is 4, the following levels are possible: $16 ~times~ 8 ~times~ 4$, $8 ~times~
+4 ~times~ 2$, $4 ~times~ 2 ~times~ 1$, $2 ~times~ 1 ~times~ 1$,
+$1 ~times~ 1 ~times~ 1$.
+These correspond to levels 2 through 6 respectively. If \f2base\fP is
+3 and \f2max\fP is 5, then only mipmap levels $8 ~times~ 4 ~times~ 2$, $4
+~times~ 2 ~times~ 1$ and $2 ~times~ 1 ~times~ 1$ are loaded. However, if
+\f2max\fP is 7 then an error is returned and nothing is loaded, since
+\f2max\fP is larger than the highest mipmap level which is, in this case,
+6.
+.P
+The highest mipmap level can be derived from the formula
+${log sub 2} ( max ("width","height","depth")^{2 sup "level"})$.
+.P
+See the \f3glTexImage1D\fP reference page for a description of the
+acceptable values for \f2format\fP parameter. See the \f3glDrawPixels\fP
+reference page for a description of the acceptable values
+for \f2type\fP parameter.
+.SH NOTES
+\%\f3gluBuild3DMipmapLevels\fP is only available if the GLU version is 1.3 or greater.
+.P
+Formats \%\f3GL_BGR\fP, and \%\f3GL_BGRA\fP, and types
+\%\f3GL_UNSIGNED_BYTE_3_3_2\fP,
+\%\f3GL_UNSIGNED_BYTE_2_3_3_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_5_6_5\fP,
+\%\f3GL_UNSIGNED_SHORT_5_6_5_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_4_4_4_4\fP,
+\%\f3GL_UNSIGNED_SHORT_4_4_4_4_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_5_5_5_1\fP,
+\%\f3GL_UNSIGNED_SHORT_1_5_5_5_REV\fP,
+\%\f3GL_UNSIGNED_INT_8_8_8_8\fP,
+\%\f3GL_UNSIGNED_INT_8_8_8_8_REV\fP,
+\%\f3GL_UNSIGNED_INT_10_10_10_2\fP, and
+\%\f3GL_UNSIGNED_INT_2_10_10_10_REV\fP are only available if the GL version
+is 1.2 or greater.
+.SH ERRORS
+\%\f3GLU_INVALID_VALUE\fP is returned if \f2level\fP > \f2base\fP, \f2base\fP < 0,
+\f2max\fP < \f2base\fP or \f2max\fP is > the highest mipmap level for \f2data\fP.
+.P
+\%\f3GLU_INVALID_VALUE\fP is returned if \f2width\fP, \f2height\fP, or \f2depth\fP is < 1.
+.P
+\%\f3GLU_INVALID_ENUM\fP is returned if \f2internalFormat\fP, \f2format\fP, or \f2type\fP is not
+legal.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2type\fP is \%\f3GL_UNSIGNED_BYTE_3_3_2\fP or \%\f3GL_UNSIGNED_BYTE_2_3_3_REV\fP
+and \f2format\fP is not \%\f3GL_RGB\fP.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2type\fP is \%\f3GL_UNSIGNED_SHORT_5_6_5\fP or \%\f3GL_UNSIGNED_SHORT_5_6_5_REV\fP
+and \f2format\fP is not \%\f3GL_RGB\fP.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2type\fP is \%\f3GL_UNSIGNED_SHORT_4_4_4_4\fP or \%\f3GL_UNSIGNED_SHORT_4_4_4_4_REV\fP
+and \f2format\fP is neither \%\f3GL_RGBA\fP nor \%\f3GL_BGRA\fP.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2type\fP is \%\f3GL_UNSIGNED_SHORT_5_5_5_1\fP or \%\f3GL_UNSIGNED_SHORT_1_5_5_5_REV\fP
+and \f2format\fP is neither \%\f3GL_RGBA\fP nor \%\f3GL_BGRA\fP.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2type\fP is \%\f3GL_UNSIGNED_INT_8_8_8_8\fP or \%\f3GL_UNSIGNED_INT_8_8_8_8_REV\fP
+and \f2format\fP is neither \%\f3GL_RGBA\fP nor \%\f3GL_BGRA\fP.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2type\fP is \%\f3GL_UNSIGNED_INT_10_10_10_2\fP or \%\f3GL_UNSIGNED_INT_2_10_10_10_REV\fP
+and \f2format\fP is neither \%\f3GL_RGBA\fP nor \%\f3GL_BGRA\fP.
+.SH SEE ALSO
+\f3glDrawPixels(3G)\fP,
+\f3glTexImage1D(3G)\fP,
+\f3glTexImage2D(3G)\fP,
+\f3glTexImage3D(3G)\fP,
+\%\f3gluBuild1DMipmaps(3G)\fP,
+\%\f3gluBuild2DMipmaps(3G)\fP,
+\%\f3gluBuild3DMipmaps(3G)\fP,
+\%\f3gluErrorString(3G)\fP,
+\f3glGetTexImage(3G)\fP,
+\f3glGetTexLevelParameter(3G)\fP,
+\%\f3gluBuild1DMipmapLevels(3G)\fP,
+\%\f3gluBuild2DMipmapLevels(3G)\fP
diff --git a/doc/gl-docs/GLU/build3dmipmaps.3gl b/doc/gl-docs/GLU/build3dmipmaps.3gl
new file mode 100644
index 000000000..7df39c2c3
--- /dev/null
+++ b/doc/gl-docs/GLU/build3dmipmaps.3gl
@@ -0,0 +1,238 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 build3dmi
+.ds Xs 62292 10 build3dmipmaps.gl
+.TH GLUBUILD3DMIPMAPS 3G
+.SH NAME
+.B "gluBuild3DMipmaps
+\- builds a three-dimensional mipmap
+
+.SH C SPECIFICATION
+GLint \f3gluBuild3DMipmaps\fP(
+GLenum \fItarget\fP,
+.nf
+.ta \w'\f3GLint \fPgluBuild3DMipmaps( 'u
+ GLint \fIinternalFormat\fP,
+ GLsizei \fIwidth\fP,
+ GLsizei \fIheight\fP,
+ GLsizei \fIdepth\fP,
+ GLenum \fIformat\fP,
+ GLenum \fItype\fP,
+ const void \fI*data\fP )
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\fIinternalFormat\fP\ \ 'u
+\f2target\fP
+Specifies the target texture. Must be \%\f3GL_TEXTURE_3D\fP.
+.TP
+\f2internalFormat\fP
+Requests the internal storage of the texture image. The most
+current version of the SGI implementation of GLU does not check this
+value for validity before passing it on to the underlying OpenGL
+implementation. A value that is not accepted by the OpenGL
+implementation will lead to an OpenGL error. The benefit of not
+checking this value at the GLU level is that OpenGL extensions can add
+new internal texture formats without requiring a revision of the GLU
+implementation. Older implementations of GLU check this value and
+raise a GLU error if it is not 1, 2, 3, or 4 or one of the following
+symbolic constants:
+\%\f3GL_ALPHA\fP,
+\%\f3GL_ALPHA4\fP,
+\%\f3GL_ALPHA8\fP,
+\%\f3GL_ALPHA12\fP,
+\%\f3GL_ALPHA16\fP,
+\%\f3GL_LUMINANCE\fP,
+\%\f3GL_LUMINANCE4\fP,
+\%\f3GL_LUMINANCE8\fP,
+\%\f3GL_LUMINANCE12\fP,
+\%\f3GL_LUMINANCE16\fP,
+\%\f3GL_LUMINANCE_ALPHA\fP,
+\%\f3GL_LUMINANCE4_ALPHA4\fP,
+\%\f3GL_LUMINANCE6_ALPHA2\fP,
+\%\f3GL_LUMINANCE8_ALPHA8\fP,
+\%\f3GL_LUMINANCE12_ALPHA4\fP,
+\%\f3GL_LUMINANCE12_ALPHA12\fP,
+\%\f3GL_LUMINANCE16_ALPHA16\fP,
+\%\f3GL_INTENSITY\fP,
+\%\f3GL_INTENSITY4\fP,
+\%\f3GL_INTENSITY8\fP,
+\%\f3GL_INTENSITY12\fP,
+\%\f3GL_INTENSITY16\fP,
+\%\f3GL_RGB\fP,
+\%\f3GL_R3_G3_B2\fP,
+\%\f3GL_RGB4\fP,
+\%\f3GL_RGB5\fP,
+\%\f3GL_RGB8\fP,
+\%\f3GL_RGB10\fP,
+\%\f3GL_RGB12\fP,
+\%\f3GL_RGB16\fP,
+\%\f3GL_RGBA\fP,
+\%\f3GL_RGBA2\fP,
+\%\f3GL_RGBA4\fP,
+\%\f3GL_RGB5_A1\fP,
+\%\f3GL_RGBA8\fP,
+\%\f3GL_RGB10_A2\fP,
+\%\f3GL_RGBA12\fP, or
+\%\f3GL_RGBA16\fP.
+.TP
+\f2width\fP, \f2height\fP, \f2depth\fP
+Specifies in pixels the width, height and depth respectively, in pixels
+of the texture image.
+.TP
+\f2format\fP
+Specifies the of the pixel data.
+Must be one of
+\%\f3GL_COLOR_INDEX\fP,
+\%\f3GL_DEPTH_COMPONENT\fP,
+\%\f3GL_RED\fP,
+\%\f3GL_GREEN\fP,
+\%\f3GL_BLUE\fP,
+\%\f3GL_ALPHA\fP,
+\%\f3GL_RGB\fP,
+\%\f3GL_RGBA\fP,
+\%\f3GL_BGR\fP,
+\%\f3GL_BGRA\fP,
+\%\f3GL_LUMINANCE\fP, or
+\%\f3GL_LUMINANCE_ALPHA\fP.
+.TP
+\f2type\fP
+Specifies the data type for \f2data\fP.
+Must be one of:
+\%\f3GL_UNSIGNED_BYTE\fP,
+\%\f3GL_BYTE\fP,
+\%\f3GL_BITMAP\fP,
+\%\f3GL_UNSIGNED_SHORT\fP,
+\%\f3GL_SHORT\fP,
+\%\f3GL_UNSIGNED_INT\fP,
+\%\f3GL_INT\fP,
+\%\f3GL_FLOAT\fP,
+\%\f3GL_UNSIGNED_BYTE_3_3_2\fP,
+\%\f3GL_UNSIGNED_BYTE_2_3_3_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_5_6_5\fP,
+\%\f3GL_UNSIGNED_SHORT_5_6_5_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_4_4_4_4\fP,
+\%\f3GL_UNSIGNED_SHORT_4_4_4_4_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_5_5_5_1\fP,
+\%\f3GL_UNSIGNED_SHORT_1_5_5_5_REV\fP,
+\%\f3GL_UNSIGNED_INT_8_8_8_8\fP,
+\%\f3GL_UNSIGNED_INT_8_8_8_8_REV\fP,
+\%\f3GL_UNSIGNED_INT_10_10_10_2\fP, or
+\%\f3GL_UNSIGNED_INT_2_10_10_10_REV\fP.
+.TP
+\f2data\fP
+Specifies a pointer to the image data in memory.
+.SH DESCRIPTION
+\%\f3gluBuild3DMipmaps\fP builds a series of prefiltered three-dimensional texture maps of
+decreasing resolutions called a mipmap. This is used for the antialiasing of
+texture-mapped primitives.
+.P
+A return value of zero indicates success, otherwise a GLU error code is
+returned (see \%\f3gluErrorString\fP).
+.P
+Initially, the \f2width\fP, \f2height\fP and \f2depth\fP of \f2data\fP are checked to
+see if they are a power of 2. If not, a copy of \f2data\fP (not \f2data\fP),
+is scaled up or down to the nearest power of 2. (If \f2width\fP, \f2height\fP or
+\f2depth\fP is exactly between powers of 2, then the copy of \f2data\fP will
+scale upwards.) This copy will be used for subsequent mipmapping
+operations described below. For example, if \f2width\fP is 57, \f2height\fP is
+23 and \f2depth\fP is 24 then a copy of \f2data\fP will scale up to 64 in
+width, down to 16 in height and up to 32 in depth, before mipmapping
+takes place.
+.P
+Then, proxy textures (see \f3glTexImage3D\fP) are used to determine if
+the implementation can fit the requested texture. If not, all three dimensions
+are continually halved until it fits.
+.P
+Next, a series of mipmap levels is built by decimating a copy of \f2data\fP
+in half along all three dimensions until size $1 ~times~ 1 ~times~ 1$ is
+reached. At each level, each texel in the halved mipmap level is an
+average of the corresponding eight texels in the larger mipmap
+level. (If exactly one of the dimensions is 1, four texels are averaged.
+If exactly two of the dimensions are 1, two texels are averaged.)
+.P
+\f3glTexImage3D\fP is called to load each of these mipmap levels.
+Level 0 is a copy of \f2data\fP. The highest level is
+${log sub 2} ( max ("width","height","depth"))$.
+For example, if \f2width\fP is 64, \f2height\fP is
+16 and \f2depth\fP is 32, and the implementation can store a texture of this
+size, the following mipmap levels are built: $64 ~times~ 16 ~times~ 32$,
+$32 ~times~ 8 ~times~ 16$, $16 ~times~ 4 ~times~ 8$,
+$8 ~times~ 2 ~times~ 4$, $4 ~times~ 1 ~times~ 2$,
+$2 ~times~ 1 ~times~ 1$
+and $1 ~times~ 1 ~times~ 1$. These correspond
+to levels 0 through 6, respectively.
+.P
+See the \f3glTexImage1D\fP reference page for a description of the
+acceptable values for \f2format\fP parameter. See the \f3glDrawPixels\fP
+reference page for a description of the acceptable values
+for \f2type\fP parameter.
+.SH NOTES
+Note that there is no direct way of querying the maximum level. This can
+be derived indirectly via \f3glGetTexLevelParameter\fP. First, query
+for the width, height and depth actually used at level 0. (The width,
+height and depth may not be equal to \f2width\fP, \f2height\fP and \f2depth\fP
+respectively since proxy textures might have scaled them to fit the
+implementation.) Then the maximum level can be derived from the formula
+${log sub 2} ( max ("width","height","depth"))$.
+.P
+\%\f3gluBuild3DMipmaps\fP is only available if the GLU version is 1.3 or greater.
+.P
+Formats \%\f3GL_BGR\fP, and \%\f3GL_BGRA\fP, and types
+\%\f3GL_UNSIGNED_BYTE_3_3_2\fP,
+\%\f3GL_UNSIGNED_BYTE_2_3_3_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_5_6_5\fP,
+\%\f3GL_UNSIGNED_SHORT_5_6_5_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_4_4_4_4\fP,
+\%\f3GL_UNSIGNED_SHORT_4_4_4_4_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_5_5_5_1\fP,
+\%\f3GL_UNSIGNED_SHORT_1_5_5_5_REV\fP,
+\%\f3GL_UNSIGNED_INT_8_8_8_8\fP,
+\%\f3GL_UNSIGNED_INT_8_8_8_8_REV\fP,
+\%\f3GL_UNSIGNED_INT_10_10_10_2\fP, and
+\%\f3GL_UNSIGNED_INT_2_10_10_10_REV\fP are only available if the GL version
+is 1.2 or greater.
+.SH ERRORS
+\%\f3GLU_INVALID_VALUE\fP is returned if \f2width\fP, \f2height\fP, or \f2depth\fP is < 1.
+.P
+\%\f3GLU_INVALID_ENUM\fP is returned if \f2internalFormat\fP, \f2format\fP, or \f2type\fP is not
+legal.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2type\fP is \%\f3GL_UNSIGNED_BYTE_3_3_2\fP or \%\f3GL_UNSIGNED_BYTE_2_3_3_REV\fP
+and \f2format\fP is not \%\f3GL_RGB\fP.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2type\fP is \%\f3GL_UNSIGNED_SHORT_5_6_5\fP or \%\f3GL_UNSIGNED_SHORT_5_6_5_REV\fP
+and \f2format\fP is not \%\f3GL_RGB\fP.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2type\fP is \%\f3GL_UNSIGNED_SHORT_4_4_4_4\fP or \%\f3GL_UNSIGNED_SHORT_4_4_4_4_REV\fP
+and \f2format\fP is neither \%\f3GL_RGBA\fP nor \%\f3GL_BGRA\fP.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2type\fP is \%\f3GL_UNSIGNED_SHORT_5_5_5_1\fP or \%\f3GL_UNSIGNED_SHORT_1_5_5_5_REV\fP
+and \f2format\fP is neither \%\f3GL_RGBA\fP nor \%\f3GL_BGRA\fP.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2type\fP is \%\f3GL_UNSIGNED_INT_8_8_8_8\fP or \%\f3GL_UNSIGNED_INT_8_8_8_8_REV\fP
+and \f2format\fP is neither \%\f3GL_RGBA\fP nor \%\f3GL_BGRA\fP.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2type\fP is \%\f3GL_UNSIGNED_INT_10_10_10_2\fP or \%\f3GL_UNSIGNED_INT_2_10_10_10_REV\fP
+and \f2format\fP is neither \%\f3GL_RGBA\fP nor \%\f3GL_BGRA\fP.
+.SH SEE ALSO
+\f3glDrawPixels(3G)\fP,
+\f3glTexImage1D(3G)\fP,
+\f3glTexImage2D(3G)\fP,
+\f3glTexImage3D(3G)\fP,
+\%\f3gluBuild1DMipmaps(3G)\fP,
+\%\f3gluBuild3DMipmaps(3G)\fP,
+\%\f3gluErrorString(3G)\fP,
+\f3glGetTexImage(3G)\fP,
+\f3glGetTexLevelParameter(3G)\fP,
+\%\f3gluBuild1DMipmapLevels(3G)\fP,
+\%\f3gluBuild2DMipmapLevels(3G)\fP,
+\%\f3gluBuild3DMipmapLevels(3G)\fP
diff --git a/doc/gl-docs/GLU/checkextension.3gl b/doc/gl-docs/GLU/checkextension.3gl
new file mode 100644
index 000000000..da57be3e7
--- /dev/null
+++ b/doc/gl-docs/GLU/checkextension.3gl
@@ -0,0 +1,53 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 checkexte
+.ds Xs 16492 4 checkextension.gl
+.TH GLUCHECKEXTENSION 3G
+.SH NAME
+.B "gluCheckExtension
+\- determines if an extension name is supported
+
+.SH C SPECIFICATION
+GLboolean \f3gluCheckExtension\fP(
+const GLubyte \fI*extName\fP,
+.nf
+.ta \w'\f3GLboolean \fPgluCheckExtension( 'u
+ const GLubyte \fI*extString\fP )
+.fi
+
+.SH PARAMETERS
+.TP \w'\fIextString\fP\ \ 'u
+\f2extName\fP
+Specifies an extension name.
+.TP
+\f2extString\fP
+Specifies a space-separated list of extension names supported.
+.SH DESCRIPTION
+\%\f3gluCheckExtension\fP returns \%\f3GL_TRUE\fP if \f2extName\fP is supported otherwise
+\%\f3GL_FALSE\fP is returned.
+.P
+This is used to check for the presence for OpenGL, GLU or GLX extension names
+by passing the extension strings returned by \f3glGetString\fP,
+\%\f3gluGetString\fP, \f3glXGetClientString\fP,
+\f3glXQueryExtensionsString\fP, or \f3glXQueryServerString\fP,
+respectively, as \f2extString\fP.
+.SH NOTES
+Cases where one extension name is a substring of another are
+correctly handled.
+.P
+There may or may not be leading or trailing blanks in \f2extString\fP.
+.P
+Extension names should not contain embedded spaces.
+.P
+All strings are null-terminated.
+.SH SEE ALSO
+\f3glGetString(3G)\fP,
+\%\f3gluGetString(3G)\fP,
+\f3glXGetClientString(3G)\fP,
+\f3glXQueryExtensionsString(3G)\fP,
+\f3glXQueryServerString(3G)\fP
diff --git a/doc/gl-docs/GLU/cylinder.3gl b/doc/gl-docs/GLU/cylinder.3gl
new file mode 100644
index 000000000..af9ed0ac2
--- /dev/null
+++ b/doc/gl-docs/GLU/cylinder.3gl
@@ -0,0 +1,70 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 cylinder.
+.ds Xs 15544 4 cylinder.gl
+.TH GLUCYLINDER 3G
+.SH NAME
+.B "gluCylinder
+\- draw a cylinder
+
+.SH C SPECIFICATION
+void \f3gluCylinder\fP(
+GLUquadric* \fIquad\fP,
+.nf
+.ta \w'\f3void \fPgluCylinder( 'u
+ GLdouble \fIbase\fP,
+ GLdouble \fItop\fP,
+ GLdouble \fIheight\fP,
+ GLint \fIslices\fP,
+ GLint \fIstacks\fP )
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\fIheight\fP\ \ 'u
+\f2quad\fP
+Specifies the quadrics object (created with \%\f3gluNewQuadric\fP).
+.TP
+\f2base\fP
+Specifies the radius of the cylinder at \f2z\fP = 0.
+.TP
+\f2top\fP
+Specifies the radius of the cylinder at \f2z\fP = \f2height\fP.
+.TP
+\f2height\fP
+Specifies the height of the cylinder.
+.TP
+\f2slices\fP
+Specifies the number of subdivisions around the \f2z\fP axis.
+.TP
+\f2stacks\fP
+Specifies the number of subdivisions along the \f2z\fP axis.
+.SH DESCRIPTION
+\%\f3gluCylinder\fP draws a cylinder oriented along the \f2z\fP axis. The base of the cylinder
+is placed at \f2z\fP = 0, and the top at $ z ~=~ "height" $. Like a sphere,
+a cylinder is subdivided around the \f2z\fP axis into slices, and along the
+\f2z\fP axis into stacks.
+.P
+Note that if \f2top\fP is set to 0.0, this routine generates a cone.
+.P
+If the orientation is set to \%\f3GLU_OUTSIDE\fP
+(with \%\f3gluQuadricOrientation\fP), then any generated normals
+point away from the \f2z\fP axis. Otherwise, they point toward the
+\f2z\fP axis.
+.P
+If texturing is turned on (with \%\f3gluQuadricTexture\fP), then texture
+coordinates are generated so that \f2t\fP ranges linearly from 0.0
+at \f2z\fP = 0 to 1.0 at \f2z\fP = \f2height\fP, and \f2s\fP
+ranges from 0.0 at the +\f2y\fP axis, to 0.25 at the +\f2x\fP axis,
+to 0.5 at the -\f2y\fP axis, to 0.75 at the \-\f2x\fP axis,
+and back to 1.0 at the +\f2y\fP axis.
+.SH SEE ALSO
+\%\f3gluDisk(3G)\fP, \%\f3gluNewQuadric(3G)\fP, \%\f3gluPartialDisk(3G)\fP, \%\f3gluQuadricTexture(3G)\fP,
+\%\f3gluSphere(3G)\fP
diff --git a/doc/gl-docs/GLU/deletenurbsrenderer.3gl b/doc/gl-docs/GLU/deletenurbsrenderer.3gl
new file mode 100644
index 000000000..13823fb15
--- /dev/null
+++ b/doc/gl-docs/GLU/deletenurbsrenderer.3gl
@@ -0,0 +1,34 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 deletenur
+.ds Xs 47695 3 deletenurbsrenderer.gl
+.TH GLUDELETENURBSRENDERER 3G
+.SH NAME
+.B "gluDeleteNurbsRenderer
+\- destroy a NURBS object
+
+.SH C SPECIFICATION
+void \f3gluDeleteNurbsRenderer\fP(
+GLUnurbs* \fInurb\fP )
+.nf
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\f2nurb\fP\ \ 'u
+\f2nurb\fP
+Specifies the NURBS object to be destroyed.
+.SH DESCRIPTION
+\%\f3gluDeleteNurbsRenderer\fP destroys the NURBS object (which was created with
+\%\f3gluNewNurbsRenderer\fP) and frees any memory it uses.
+Once
+\%\f3gluDeleteNurbsRenderer\fP has been called, \f2nurb\fP cannot be used again.
+.SH SEE ALSO
+\%\f3gluNewNurbsRenderer(3G)\fP
diff --git a/doc/gl-docs/GLU/deletequadric.3gl b/doc/gl-docs/GLU/deletequadric.3gl
new file mode 100644
index 000000000..610d6d809
--- /dev/null
+++ b/doc/gl-docs/GLU/deletequadric.3gl
@@ -0,0 +1,34 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 deletequa
+.ds Xs 13251 3 deletequadric.gl
+.TH GLUDELETEQUADRIC 3G
+.SH NAME
+.B "gluDeleteQuadric
+\- destroy a quadrics object
+
+.SH C SPECIFICATION
+void \f3gluDeleteQuadric\fP(
+GLUquadric* \fIquad\fP )
+.nf
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\f2quad\fP\ \ 'u
+\f2quad\fP
+Specifies the quadrics object to be destroyed.
+.SH DESCRIPTION
+\%\f3gluDeleteQuadric\fP destroys the quadrics object (created with \%\f3gluNewQuadric\fP)
+and frees any memory it uses.
+Once \%\f3gluDeleteQuadric\fP has been called, \f2quad\fP cannot be used again.
+.SH SEE ALSO
+\%\f3gluNewQuadric(3G)\fP
+
diff --git a/doc/gl-docs/GLU/deletetess.3gl b/doc/gl-docs/GLU/deletetess.3gl
new file mode 100644
index 000000000..5d4325b2c
--- /dev/null
+++ b/doc/gl-docs/GLU/deletetess.3gl
@@ -0,0 +1,33 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 deletetes
+.ds Xs 7423 3 deletetess.gl
+.TH GLUDELETETESS 3G
+.SH NAME
+.B "gluDeleteTess
+\- destroy a tessellation object
+
+.SH C SPECIFICATION
+void \f3gluDeleteTess\fP(
+GLUtesselator* \fItess\fP )
+.nf
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\f2tess\fP\ \ 'u
+\f2tess\fP
+Specifies the tessellation object to destroy.
+.SH DESCRIPTION
+\%\f3gluDeleteTess\fP destroys the indicated tessellation object (which was created
+with \%\f3gluNewTess\fP) and frees any memory that it used.
+.SH SEE ALSO
+\%\f3gluBeginPolygon(3G)\fP, \%\f3gluNewTess(3G)\fP, \%\f3gluTessCallback(3G)\fP
+
diff --git a/doc/gl-docs/GLU/disk.3gl b/doc/gl-docs/GLU/disk.3gl
new file mode 100644
index 000000000..843d5a83f
--- /dev/null
+++ b/doc/gl-docs/GLU/disk.3gl
@@ -0,0 +1,70 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 disk.gl -
+.ds Xs 8360 4 disk.gl
+.TH GLUDISK 3G
+.SH NAME
+.B "gluDisk
+\- draw a disk
+
+.SH C SPECIFICATION
+void \f3gluDisk\fP(
+GLUquadric* \fIquad\fP,
+.nf
+.ta \w'\f3void \fPgluDisk( 'u
+ GLdouble \fIinner\fP,
+ GLdouble \fIouter\fP,
+ GLint \fIslices\fP,
+ GLint \fIloops\fP )
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\fIslices\fP\ \ 'u
+\f2quad\fP
+Specifies the quadrics object (created with \%\f3gluNewQuadric\fP).
+.TP
+\f2inner\fP
+Specifies the inner radius of the disk (may be 0).
+.TP
+\f2outer\fP
+Specifies the outer radius of the disk.
+.TP
+\f2slices\fP
+Specifies the number of subdivisions around the \f2z\fP axis.
+.TP
+\f2loops\fP
+Specifies the number of concentric rings about the origin into which
+the disk is subdivided.
+.SH DESCRIPTION
+\%\f3gluDisk\fP renders a disk on the \f2z\fP = 0 plane. The disk has a radius of
+\f2outer\fP, and contains a concentric circular hole with a radius
+of \f2inner\fP. If \f2inner\fP is 0, then no hole is generated. The disk is
+subdivided around the \f2z\fP axis into slices (like pizza slices), and also
+about the \f2z\fP axis into rings
+(as specified by \f2slices\fP and \f2loops\fP, respectively).
+.P
+With respect to orientation, the +\f2z\fP side of the disk is considered to be
+"outside" (see \%\f3gluQuadricOrientation\fP).
+This means that if the
+orientation is set to \%\f3GLU_OUTSIDE\fP, then any normals generated
+point along the +\f2z\fP axis. Otherwise, they point along the \-\f2z\fP
+axis.
+.P
+If texturing has been turned on (with \%\f3gluQuadricTexture\fP),
+texture coordinates are generated
+linearly such that where $ r ~=~ "outer" $, the value at (\f2r\fP, 0, 0) is
+(1, 0.5), at (0, \f2r\fP, 0) it is (0.5, 1), at (\-\f2r\fP, 0, 0)
+it is (0, 0.5), and
+at (0, \-\f2r\fP, 0) it is (0.5, 0).
+.SH SEE ALSO
+\%\f3gluCylinder(3G)\fP, \%\f3gluNewQuadric(3G)\fP, \%\f3gluPartialDisk(3G)\fP,
+\%\f3gluQuadricOrientation(3G)\fP,
+\%\f3gluQuadricTexture(3G)\fP, \%\f3gluSphere(3G)\fP
diff --git a/doc/gl-docs/GLU/errorstring.3gl b/doc/gl-docs/GLU/errorstring.3gl
new file mode 100644
index 000000000..31207ae7a
--- /dev/null
+++ b/doc/gl-docs/GLU/errorstring.3gl
@@ -0,0 +1,47 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 errorstri
+.ds Xs 24940 3 errorstring.gl
+.TH GLUERRORSTRING 3G
+.SH NAME
+.B "gluErrorString
+\- produce an error string from a GL or GLU error code
+
+.SH C SPECIFICATION
+const GLubyte * \f3gluErrorString\fP(
+GLenum \fIerror\fP )
+.nf
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\f2error\fP\ \ 'u
+\f2error\fP
+Specifies a GL or GLU error code.
+.SH DESCRIPTION
+\%\f3gluErrorString\fP produces an error string from a GL or GLU error code. The string
+is in ISO Latin 1 . For example,
+\%\f3gluErrorString\fP(\%\f3GL_OUT_OF_MEMORY\fP) returns the string
+\f2out of memory\fP.
+.P
+The standard GLU error codes are \%\f3GLU_INVALID_ENUM\fP,
+\%\f3GLU_INVALID_VALUE\fP,
+and \%\f3GLU_OUT_OF_MEMORY\fP.
+Certain other GLU functions can return specialized error codes
+through callbacks.
+See the \f3glGetError\fP reference page for the list of
+GL error codes.
+.SH ERRORS
+\%\f3NULL\fP is returned if \f2error\fP is not a valid GL or GLU error code.
+.SH SEE ALSO
+\f3glGetError(3G)\fP,
+\%\f3gluNurbsCallback(3G)\fP,
+\%\f3gluQuadricCallback(3G)\fP,
+\%\f3gluTessCallback(3G)\fP
diff --git a/doc/gl-docs/GLU/getnurbsproperty.3gl b/doc/gl-docs/GLU/getnurbsproperty.3gl
new file mode 100644
index 000000000..44f4bfd06
--- /dev/null
+++ b/doc/gl-docs/GLU/getnurbsproperty.3gl
@@ -0,0 +1,55 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 getnurbsp
+.ds Xs 29302 3 getnurbsproperty.gl
+.TH GLUGETNURBSPROPERTY 3G
+.SH NAME
+.B "gluGetNurbsProperty
+\- get a NURBS property
+
+.SH C SPECIFICATION
+void \f3gluGetNurbsProperty\fP(
+GLUnurbs* \fInurb\fP,
+.nf
+.ta \w'\f3void \fPgluGetNurbsProperty( 'u
+ GLenum \fIproperty\fP,
+ GLfloat* \fIdata\fP )
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\fIproperty\fP\ \ 'u
+\f2nurb\fP
+Specifies the NURBS object (created with \%\f3gluNewNurbsRenderer\fP).
+.TP
+\f2property\fP
+Specifies the property whose value is to be fetched. Valid values are
+\%\f3GLU_CULLING\fP,
+\%\f3GLU_SAMPLING_TOLERANCE\fP,
+\%\f3GLU_DISPLAY_MODE\fP,
+\%\f3GLU_AUTO_LOAD_MATRIX\fP,
+\%\f3GLU_PARAMETRIC_TOLERANCE\fP,
+\%\f3GLU_SAMPLING_METHOD\fP,
+\%\f3GLU_U_STEP\fP,
+\%\f3GLU_V_STEP\fP and
+\%\f3GLU_NURBS_MODE\fP.
+.TP
+\f2data\fP
+Specifies a pointer to the location into which the value of the
+named property is written.
+.SH DESCRIPTION
+\%\f3gluGetNurbsProperty\fP retrieves properties stored in a NURBS object. These
+properties affect the way that NURBS curves and surfaces
+are rendered. See the
+\%\f3gluNurbsProperty\fP reference page for information about what the
+properties are and what they do.
+.SH SEE ALSO
+\%\f3gluNewNurbsRenderer(3G)\fP,
+\%\f3gluNurbsProperty(3G)\fP
diff --git a/doc/gl-docs/GLU/getstring.3gl b/doc/gl-docs/GLU/getstring.3gl
new file mode 100644
index 000000000..3eb4b1c4d
--- /dev/null
+++ b/doc/gl-docs/GLU/getstring.3gl
@@ -0,0 +1,65 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 getstring
+.ds Xs 20129 4 getstring.gl
+.TH GLUGETSTRING 3G
+.SH NAME
+.B "gluGetString
+\- return a string describing the GLU version or GLU extensions
+
+.SH C SPECIFICATION
+const GLubyte * \f3gluGetString\fP(
+GLenum \fIname\fP )
+.nf
+.fi
+
+.SH PARAMETERS
+.TP \w'\f2name\fP\ \ 'u
+\f2name\fP
+Specifies a symbolic constant, one of
+\%\f3GLU_VERSION\fP, or \%\f3GLU_EXTENSIONS\fP.
+.SH DESCRIPTION
+\%\f3gluGetString\fP returns a pointer to a static string describing the
+GLU version or the GLU extensions that are supported.
+.P
+The version number is one of the following
+forms:
+.P
+\f2major_number.minor_number\fP
+.br
+\f2major_number.minor_number.release_number\fP.
+.P
+The version string is of the following form:
+.P
+\f2version number<space>vendor-specific information\fP
+.P
+Vendor-specific information is optional.
+Its and contents depend on the implementation.
+.P
+The standard GLU contains a basic set of features and capabilities.
+If a company or group of companies wish to support other features,
+these may be included as extensions to the GLU.
+If \f2name\fP is
+\%\f3GLU_EXTENSIONS\fP, then \%\f3gluGetString\fP
+returns a space-separated list of names of supported GLU extensions.
+(Extension names never contain spaces.)
+.P
+All strings are null-terminated.
+.SH NOTES
+\%\f3gluGetString\fP only returns information about GLU extensions. Call
+\f3glGetString\fP to get a list of GL extensions.
+.P
+\%\f3gluGetString\fP is an initialization routine. Calling it after
+a \f3glNewList\fP results in undefined behavior.
+.SH ERRORS
+NULL is returned if \f2name\fP is not
+\%\f3GLU_VERSION\fP or \%\f3GLU_EXTENSIONS\fP.
+.P
+.SH SEE ALSO
+\f3glGetString(3G)\fP
+
diff --git a/doc/gl-docs/GLU/gettessproperty.3gl b/doc/gl-docs/GLU/gettessproperty.3gl
new file mode 100644
index 000000000..eb69f5c03
--- /dev/null
+++ b/doc/gl-docs/GLU/gettessproperty.3gl
@@ -0,0 +1,50 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 gettesspr
+.ds Xs 26656 3 gettessproperty.gl
+.TH GLUGETTESSPROPERTY 3G
+.SH NAME
+.B "gluGetTessProperty
+\- get a tessellation object property
+
+.SH C SPECIFICATION
+void \f3gluGetTessProperty\fP(
+GLUtesselator* \fItess\fP,
+.nf
+.ta \w'\f3void \fPgluGetTessProperty( 'u
+ GLenum \fIwhich\fP,
+ GLdouble* \fIdata\fP )
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\fIwhich\fP\ \ 'u
+\f2tess\fP
+Specifies the tessellation object (created with \%\f3gluNewTess\fP).
+.TP
+\f2which\fP
+Specifies the property whose value is to be fetched. Valid values are
+\%\f3GLU_TESS_WINDING_RULE\fP,
+\%\f3GLU_TESS_BOUNDARY_ONLY\fP, and
+\%\f3GLU_TESS_TOLERANCE\fP.
+.TP
+\f2data\fP
+Specifies a pointer to the location into which the value of the
+named property is written.
+.SH DESCRIPTION
+\%\f3gluGetTessProperty\fP retrieves properties stored in a tessellation object. These
+properties affect the way that tessellation objects
+are interpreted and rendered. See the
+\%\f3gluTessProperty\fP reference page for information about the
+properties and what they do.
+.SH SEE ALSO
+\%\f3gluNewTess(3G)\fP,
+\%\f3gluTessProperty(3G)\fP
+
diff --git a/doc/gl-docs/GLU/loadsamplingmatrices.3gl b/doc/gl-docs/GLU/loadsamplingmatrices.3gl
new file mode 100644
index 000000000..54b3f2840
--- /dev/null
+++ b/doc/gl-docs/GLU/loadsamplingmatrices.3gl
@@ -0,0 +1,60 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm :37 loadsamp
+.ds Xs 25465 4 loadsamplingmatrices.gl
+.TH GLULOADSAMPLINGMATRICES 3G
+.SH NAME
+.B "gluLoadSamplingMatrices
+\- load NURBS sampling and culling matrices
+
+.SH C SPECIFICATION
+void \f3gluLoadSamplingMatrices\fP(
+GLUnurbs* \fInurb\fP,
+.nf
+.ta \w'\f3void \fPgluLoadSamplingMatrices( 'u
+ const GLfloat \fI*model\fP,
+ const GLfloat \fI*perspective\fP,
+ const GLint \fI*view\fP )
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\fIperspective\fP\ \ 'u
+\f2nurb\fP
+Specifies the NURBS object (created with \%\f3gluNewNurbsRenderer\fP).
+.TP
+\f2model\fP
+Specifies a modelview matrix (as from a \f3glGetFloatv\fP call).
+.TP
+\f2perspective\fP
+Specifies a projection matrix (as from a \f3glGetFloatv\fP call).
+.TP
+\f2view\fP
+Specifies a viewport (as from a \f3glGetIntegerv\fP call).
+.SH DESCRIPTION
+\%\f3gluLoadSamplingMatrices\fP uses \f2model\fP, \f2perspective\fP, and \f2view\fP to recompute the sampling and culling
+matrices stored in \f2nurb\fP.
+The sampling matrix determines how finely a NURBS curve or surface
+must be tessellated to satisfy the sampling tolerance (as determined by the
+\%\f3GLU_SAMPLING_TOLERANCE\fP property).
+The culling matrix is used in deciding if a NURBS curve or surface
+should be culled before
+rendering (when the \%\f3GLU_CULLING\fP property is turned on).
+.P
+\%\f3gluLoadSamplingMatrices\fP is necessary only if the \%\f3GLU_AUTO_LOAD_MATRIX\fP property is turned
+off (see \%\f3gluNurbsProperty\fP).
+Although it can be convenient to leave the \%\f3GLU_AUTO_LOAD_MATRIX\fP
+property turned on, there can be a performance penalty for doing so.
+(A round trip to the GL server is needed to fetch the current values
+of the modelview matrix, projection matrix, and viewport.)
+.SH SEE ALSO
+\%\f3gluGetNurbsProperty(3G)\fP,
+\%\f3gluNewNurbsRenderer(3G)\fP,
+\%\f3gluNurbsProperty(3G)\fP
diff --git a/doc/gl-docs/GLU/lookat.3gl b/doc/gl-docs/GLU/lookat.3gl
new file mode 100644
index 000000000..e4a10d486
--- /dev/null
+++ b/doc/gl-docs/GLU/lookat.3gl
@@ -0,0 +1,101 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 lookat.gl
+.ds Xs 1014 4 lookat.gl
+.TH GLULOOKAT 3G
+.SH NAME
+.B "gluLookAt
+\- define a viewing transformation
+
+.SH C SPECIFICATION
+void \f3gluLookAt\fP(
+GLdouble \fIeyeX\fP,
+.nf
+.ta \w'\f3void \fPgluLookAt( 'u
+ GLdouble \fIeyeY\fP,
+ GLdouble \fIeyeZ\fP,
+ GLdouble \fIcenterX\fP,
+ GLdouble \fIcenterY\fP,
+ GLdouble \fIcenterZ\fP,
+ GLdouble \fIupX\fP,
+ GLdouble \fIupY\fP,
+ GLdouble \fIupZ\fP )
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\f2eyeX\fP\ \f2eyeY\fP\ \f2eyeZ\fP\ \ 'u
+\f2eyeX\fP, \f2eyeY\fP, \f2eyeZ\fP
+Specifies the position of the eye point.
+.TP
+\f2centerX\fP, \f2centerY\fP, \f2centerZ\fP
+Specifies the position of the reference point.
+.TP
+\f2upX\fP, \f2upY\fP, \f2upZ\fP
+Specifies the direction of the \f2up\fP vector.
+.SH DESCRIPTION
+\%\f3gluLookAt\fP creates a viewing matrix derived from an eye point, a reference
+point indicating the center of the scene, and an \f2UP\fP vector.
+.P
+The matrix
+maps the reference point to the negative \f2z\fP axis and the
+eye point to the origin.
+When a typical projection matrix is used,
+the center of the scene therefore maps to the center of the viewport.
+Similarly, the direction described by the \f2UP\fP
+vector projected onto the viewing plane is mapped to the positive \f2y\fP
+axis so that it points upward in the viewport.
+The \f2UP\fP vector must not be parallel to the line of sight from the
+eye point to the reference point.
+.P
+Let
+.sp
+.EQ
+F ~=~ left ( down 20 { ~ matrix {
+ ccol {"centerX" above "centerY" above "centerZ"}
+ ccol { ~-~ above ~-~ above ~-~}
+ ccol {"eyeX" above "eyeY" above "eyeZ"}
+} } ~~ right )
+
+.EN
+
+.sp
+Let \f2UP\fP be the vector $("upX", "upY", "upZ")$.
+.P
+Then normalize as follows:
+.EQ
+f ~=~ F over {|| F ||}
+.EN
+.P
+.EQ
+UP sup prime ~=~ UP over {|| UP ||}
+.EN
+.sp
+.P
+Finally, let $s ~=~ f ~times~ UP sup prime$, and $u ~=~ s ~times~ f$.
+.P
+.sp
+M is then constructed as follows:
+.EQ
+M ~=~ left ( matrix {
+ ccol { ~s[0] above ~u[0] above -f[0] above 0 }
+ ccol { ~s[1] above ~u[1] above -f[1] above 0 }
+ ccol { ~s[2] above ~u[2] above -f[2] above 0 }
+ ccol { 0 above 0 above 0 above 1 }
+} ~~right )
+.EN
+.P
+and \%\f3gluLookAt\fP is equivalent to
+.Ex
+glMultMatrixf(M);
+glTranslated (-eyex, -eyey, -eyez);
+.Ee
+.SH SEE ALSO
+\f3glFrustum(3G)\fP, \%\f3gluPerspective(3G)\fP
diff --git a/doc/gl-docs/GLU/newnurbsrenderer.3gl b/doc/gl-docs/GLU/newnurbsrenderer.3gl
new file mode 100644
index 000000000..f9a8a5198
--- /dev/null
+++ b/doc/gl-docs/GLU/newnurbsrenderer.3gl
@@ -0,0 +1,31 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 newnurbsr
+.ds Xs 53296 3 newnurbsrenderer.gl
+.TH GLUNEWNURBSRENDERER 3G
+.SH NAME
+.B "gluNewNurbsRenderer
+\- create a NURBS object
+
+.SH C SPECIFICATION
+GLUnurbs* \f3gluNewNurbsRenderer\fP( void )
+.nf
+.fi
+
+.EQ
+delim $$
+.EN
+.SH DESCRIPTION
+\%\f3gluNewNurbsRenderer\fP creates and returns a pointer to
+a new NURBS object.
+This object must be referred to when calling
+NURBS rendering and control functions. A return value of
+0 means that there is not enough memory to allocate the object.
+.SH SEE ALSO
+\%\f3gluBeginCurve(3G)\fP, \%\f3gluBeginSurface(3G)\fP, \%\f3gluBeginTrim(3G)\fP, \%\f3gluDeleteNurbsRenderer(3G)\fP, \%\f3gluNurbsCallback(3G)\fP, \%\f3gluNurbsProperty(3G)\fP
+
diff --git a/doc/gl-docs/GLU/newquadric.3gl b/doc/gl-docs/GLU/newquadric.3gl
new file mode 100644
index 000000000..68cd7a515
--- /dev/null
+++ b/doc/gl-docs/GLU/newquadric.3gl
@@ -0,0 +1,33 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 newquadri
+.ds Xs 35023 3 newquadric.gl
+.TH GLUNEWQUADRIC 3G
+.SH NAME
+.B "gluNewQuadric
+\- create a quadrics object
+
+.SH C SPECIFICATION
+GLUquadric* \f3gluNewQuadric\fP( void )
+.nf
+.fi
+
+.EQ
+delim $$
+.EN
+.SH DESCRIPTION
+\%\f3gluNewQuadric\fP creates and returns a pointer to
+a new quadrics object. This object must be referred to when
+calling quadrics rendering and control functions. A return value of
+0 means that there is not enough memory to allocate the object.
+.SH SEE ALSO
+\%\f3gluCylinder(3G)\fP, \%\f3gluDeleteQuadric(3G)\fP, \%\f3gluDisk(3G)\fP,
+\%\f3gluPartialDisk(3G)\fP, \%\f3gluQuadricCallback(3G)\fP, \%\f3gluQuadricDrawStyle(3G)\fP,
+\%\f3gluQuadricNormals(3G)\fP, \%\f3gluQuadricOrientation(3G)\fP,
+\%\f3gluQuadricTexture(3G)\fP,
+\%\f3gluSphere(3G)\fP
diff --git a/doc/gl-docs/GLU/newtess.3gl b/doc/gl-docs/GLU/newtess.3gl
new file mode 100644
index 000000000..8f57025a3
--- /dev/null
+++ b/doc/gl-docs/GLU/newtess.3gl
@@ -0,0 +1,30 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 newtess.g
+.ds Xs 16871 3 newtess.gl
+.TH GLUNEWTESS 3G
+.SH NAME
+.B "gluNewTess
+\- create a tessellation object
+
+.SH C SPECIFICATION
+GLUtesselator* \f3gluNewTess\fP( void )
+.nf
+.fi
+
+.EQ
+delim $$
+.EN
+.SH DESCRIPTION
+\%\f3gluNewTess\fP creates and returns a pointer to a new tessellation object.
+This object must be referred to when calling
+tessellation functions. A return value of
+0 means that there is not enough memory to allocate the object.
+.SH SEE ALSO
+\%\f3gluTessBeginPolygon(3G)\fP, \%\f3gluDeleteTess(3G)\fP, \%\f3gluTessCallback(3G)\fP
+
diff --git a/doc/gl-docs/GLU/nextcontour.3gl b/doc/gl-docs/GLU/nextcontour.3gl
new file mode 100644
index 000000000..6640a6a72
--- /dev/null
+++ b/doc/gl-docs/GLU/nextcontour.3gl
@@ -0,0 +1,102 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 nextconto
+.ds Xs 37451 5 nextcontour.gl
+.TH GLUNEXTCONTOUR 3G
+.SH NAME
+.B "gluNextContour
+\- mark the beginning of another contour
+
+.SH C SPECIFICATION
+void \f3gluNextContour\fP(
+GLUtesselator* \fItess\fP,
+.nf
+.ta \w'\f3void \fPgluNextContour( 'u
+ GLenum \fItype\fP )
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\f2tess\fP\ \ 'u
+\f2tess\fP
+Specifies the tessellation object (created with \%\f3gluNewTess\fP).
+.TP
+\f2type\fP
+Specifies the type of the contour being defined. Valid values are
+\%\f3GLU_EXTERIOR\fP,
+\%\f3GLU_INTERIOR\fP,
+\%\f3GLU_UNKNOWN\fP,
+\%\f3GLU_CCW\fP, and
+\%\f3GLU_CW\fP.
+.SH DESCRIPTION
+\%\f3gluNextContour\fP is used in describing polygons with multiple contours. After the first
+contour has been described through a series of \%\f3gluTessVertex\fP calls,
+a \%\f3gluNextContour\fP call indicates that the previous contour is complete and that the
+next contour is about to begin.
+Another series of \%\f3gluTessVertex\fP calls is then used to describe the new
+contour. This process can be repeated until all contours have been described.
+.P
+\f2type\fP defines what type of contour follows.
+The legal contour types are as follows:
+.TP 18
+\%\f3GLU_EXTERIOR\fP
+An exterior contour defines an exterior boundary of the polygon.
+.TP
+\%\f3GLU_INTERIOR\fP
+An interior contour defines an interior boundary of the polygon (such as
+a hole).
+.TP
+\%\f3GLU_UNKNOWN\fP
+An unknown contour is analyzed by the library to determine if it is interior
+or exterior.
+.TP
+\%\f3GLU_CCW\fP,
+.TP
+\%\f3GLU_CW\fP
+The first \%\f3GLU_CCW\fP or \%\f3GLU_CW\fP contour defined is considered to
+be exterior. All other contours are considered to be exterior if they
+are oriented in the same direction (clockwise or counterclockwise) as
+the first contour, and interior if they are not.
+.P
+If one contour is of type \%\f3GLU_CCW\fP or \%\f3GLU_CW\fP, then all
+contours must be of the same type (if they are not, then all \%\f3GLU_CCW\fP
+and \%\f3GLU_CW\fP contours will be changed to \%\f3GLU_UNKNOWN\fP).
+.P
+Note that there is no real difference between the \%\f3GLU_CCW\fP and
+\%\f3GLU_CW\fP contour types.
+.P
+Before the first contour is described, \%\f3gluNextContour\fP can be called to
+define the type of the first contour.
+If \%\f3gluNextContour\fP is not called before the first contour, then the first contour is
+marked \%\f3GLU_EXTERIOR\fP.
+.P
+This command is obsolete and is provided for backward compatibility
+only. Calls to \%\f3gluNextContour\fP are mapped to \%\f3gluTessEndContour\fP
+followed by
+\%\f3gluTessBeginContour\fP.
+.SH EXAMPLE
+A quadrilateral with a triangular hole in it can be described as follows:
+.sp
+.Ex
+gluBeginPolygon(tobj);
+ gluTessVertex(tobj, v1, v1);
+ gluTessVertex(tobj, v2, v2);
+ gluTessVertex(tobj, v3, v3);
+ gluTessVertex(tobj, v4, v4);
+gluNextContour(tobj, GLU_INTERIOR);
+ gluTessVertex(tobj, v5, v5);
+ gluTessVertex(tobj, v6, v6);
+ gluTessVertex(tobj, v7, v7);
+gluEndPolygon(tobj);
+.Ee
+.SH SEE ALSO
+\%\f3gluBeginPolygon(3G)\fP, \%\f3gluNewTess(3G)\fP, \%\f3gluTessCallback(3G)\fP, \%\f3gluTessVertex(3G)\fP,
+\%\f3gluTessBeginContour(3G)\fP
+
diff --git a/doc/gl-docs/GLU/nurbscallback.3gl b/doc/gl-docs/GLU/nurbscallback.3gl
new file mode 100644
index 000000000..d418fa553
--- /dev/null
+++ b/doc/gl-docs/GLU/nurbscallback.3gl
@@ -0,0 +1,228 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 nurbscall
+.ds Xs 14092 10 nurbscallback.gl
+.TH GLUNURBSCALLBACK 3G
+.SH NAME
+.B "gluNurbsCallback
+\- define a callback for a NURBS object
+
+.SH C SPECIFICATION
+void \f3gluNurbsCallback\fP(
+GLUnurbs* \fInurb\fP,
+.nf
+.ta \w'\f3void \fPgluNurbsCallback( 'u
+ GLenum \fIwhich\fP,
+ _GLUfuncptr \fICallBackFunc\fP )
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\fICallBackFunc\fP\ \ 'u
+\f2nurb\fP
+Specifies the NURBS object (created with \%\f3gluNewNurbsRenderer\fP).
+.TP
+\f2which\fP
+Specifies the callback being defined.
+Valid values are \%\f3GLU_NURBS_BEGIN\fP, \%\f3GLU_NURBS_VERTEX\fP, \%\f3GLU_NURBS_NORMAL\fP, \%\f3GLU_NURBS_COLOR\fP, \%\f3GLU_NURBS_TEXTURE_COORD\fP, \%\f3GLU_NURBS_END\fP, \%\f3GLU_NURBS_BEGIN_DATA\fP, \%\f3GLU_NURBS_VERTEX_DATA\fP, \%\f3GLU_NURBS_NORMAL_DATA\fP, \%\f3GLU_NURBS_COLOR_DATA\fP, \%\f3GLU_NURBS_TEXTURE_COORD_DATA\fP, \%\f3GLU_NURBS_END_DATA\fP, and \%\f3GLU_NURBS_ERROR\fP.
+.TP
+\f2CallBackFunc\fP
+Specifies the function that the callback calls.
+.SH DESCRIPTION
+\%\f3gluNurbsCallback\fP is used to define a callback to be used by a NURBS
+object.
+If the specified callback is already defined, then it is replaced. If
+\f2CallBackFunc\fP is NULL, then this callback will not get
+invoked and the related data, if any, will be lost.
+.P
+Except the error callback, these callbacks are used by NURBS tessellator (when \%\f3GLU_NURBS_MODE\fP is set to be \%\f3GLU_NURBS_TESSELLATOR\fP) to return back the OpenGL
+polygon primitives resulting from the tessellation. Note that there are two
+versions of each callback: one with a user data pointer and one without. If both versions for a particular callback are specified then the callback with
+the user data pointer will be used. Note that ``userData'' is a copy of the pointer that was specified at the last call to \%\f3gluNurbsCallbackData\fP.
+.P
+The error callback function is effective no matter which value that
+\%\f3GLU_NURBS_MODE\fP is set to.
+All other callback functions are effective only when \%\f3GLU_NURBS_MODE\fP
+is set to \%\f3GLU_NURBS_TESSELLATOR\fP.
+.P
+The legal callbacks are as follows:
+.TP 10
+\%\f3GLU_NURBS_BEGIN\fP
+The begin callback indicates the start of a primitive. The function
+takes a single argument of type GLenum, which can be one of
+\%\f3GL_LINES\fP, \%\f3GL_LINE_STRIP\fP, \%\f3GL_TRIANGLE_FAN\fP, \%\f3GL_TRIANGLE_STRIP\fP, \%\f3GL_TRIANGLES\fP, or \%\f3GL_QUAD_STRIP\fP. The
+default begin callback function is NULL. The function prototype
+for this callback looks like:
+.RS
+.Ex
+void begin ( GLenum type );
+.Ee
+.RE
+.TP
+\%\f3GLU_NURBS_BEGIN_DATA\fP
+The same as the \%\f3GLU_NURBS_BEGIN\fP callback except that it takes an
+additional pointer argument. This pointer is a copy of the pointer that
+was specified at the last call to \%\f3gluNurbsCallbackData\fP. The
+default callback function is NULL. The function prototype for this
+callback function looks like:
+.RS
+.Ex
+void beginData (GLenum type, void *userData);
+.Ee
+.RE
+.TP
+\%\f3GLU_NURBS_VERTEX\fP
+The vertex callback indicates a vertex of the primitive. The
+coordinates of the vertex are stored in the parameter ``vertex''. All
+the generated vertices have dimension 3, that is, homogeneous
+coordinates have been transformed into affine coordinates. The default
+vertex callback function is NULL. The function prototype for this
+callback function looks like:
+.RS
+.Ex
+void vertex ( GLfloat *vertex );
+.Ee
+.RE
+.TP
+\%\f3GLU_NURBS_VERTEX_DATA\fP
+This is the same as the \%\f3GLU_NURBS_VERTEX\fP callback, except that
+it takes an additional pointer argument. This pointer is a copy of the
+pointer that was specified at the last call to
+\%\f3gluNurbsCallbackData\fP. The default callback function is NULL. The
+function prototype for this callback function looks like:
+.RS
+.Ex
+void vertexData ( GLfloat *vertex, void *userData );
+.Ee
+.RE
+.TP
+\%\f3GLU_NURBS_NORMAL\fP
+The normal callback is invoked as the vertex normal is generated.
+The components of the normal are stored in the parameter ``normal''.
+In the case of a NURBS curve, the callback function is effective only when
+the user provides a normal map (\%\f3GL_MAP1_NORMAL\fP).
+In the case of a NURBS surface, if a normal map (\%\f3GL_MAP2_NORMAL\fP) is provided, then the generated normal is computed from the normal map.
+If a normal map is not provided then a surface normal is computed in
+a manner similar to that described for evaluators when \%\f3GL_AUTO_NORMAL\fP
+is enabled.
+.bp
+The default normal callback function is NULL. The function
+prototype for this callback function looks like:
+.RS
+.Ex
+void normal ( GLfloat *normal );
+.Ee
+.RE
+.TP
+\%\f3GLU_NURBS_NORMAL_DATA\fP
+The same as the \%\f3GLU_NURBS_NORMAL\fP callback except that it
+takes an additional pointer argument. This pointer is a copy of the pointer
+that was specified at the last call to \%\f3gluNurbsCallbackData\fP. The default callback function is NULL. The function prototype for this callback function looks like:
+.RS
+.Ex
+void normalData ( GLfloat *normal, void *userData );
+.Ee
+.RE
+.TP
+\%\f3GLU_NURBS_COLOR\fP
+The color callback is invoked as the color of a vertex is generated.
+The components of the color are stored in the parameter ``color''.
+This callback is effective only when the user provides a color map
+(\%\f3GL_MAP1_COLOR_4\fP or \%\f3GL_MAP2_COLOR_4\fP). ``color'' contains four components: R,G,B,A. The default color callback function is NULL. The prototype for
+this callback function looks like:
+.RS
+.Ex
+void color ( GLfloat *color );
+.Ee
+.RE
+.TP
+\%\f3GLU_NURBS_COLOR_DATA\fP
+The same as the \%\f3GLU_NURBS_COLOR\fP callback except that it
+takes an additional pointer argument. This pointer is a copy of the pointer
+that was specified at the last call to \%\f3gluNurbsCallbackData\fP. The default callback function is NULL. The function prototype for this callback function looks like:
+.RS
+.Ex
+void colorData ( GLfloat *color, void *userData );
+.Ee
+.RE
+.TP
+\%\f3GLU_NURBS_TEXTURE_COORD\fP
+The texture callback is invoked as the texture coordinates
+of a vertex are generated. These coordinates are stored in the parameter
+``texCoord''. The number of texture coordinates can be 1, 2, 3, or 4 depending
+on which type of texture map is specified
+(\%\f3GL_MAP1_TEXTURE_COORD_1\fP,
+\%\f3GL_MAP1_TEXTURE_COORD_2\fP,
+\%\f3GL_MAP1_TEXTURE_COORD_3\fP,
+\%\f3GL_MAP1_TEXTURE_COORD_4\fP,
+\%\f3GL_MAP2_TEXTURE_COORD_1\fP,
+\%\f3GL_MAP2_TEXTURE_COORD_2\fP,
+\%\f3GL_MAP2_TEXTURE_COORD_3\fP,
+\%\f3GL_MAP2_TEXTURE_COORD_4\fP).
+If no texture map is specified, this callback function will not be called.
+.bp
+The default texture callback function is NULL. The function prototype
+for this callback function looks like:
+.RS
+.Ex
+void texCoord ( GLfloat *texCoord );
+.Ee
+.RE
+.TP
+ \%\f3GLU_NURBS_TEXTURE_COORD_DATA\fP
+This is the same as the \%\f3GLU_NURBS_TEXTURE_COORD\fP callback, except that it
+takes an additional pointer argument. This pointer is a copy of the pointer
+that was specified at the last call to \%\f3gluNurbsCallbackData\fP. The default callback function is NULL. The function prototype for this callback function looks like:
+.RS
+.Ex
+void texCoordData (GLfloat *texCoord, void *userData);
+.Ee
+.RE
+.TP
+\%\f3GLU_NURBS_END\fP
+The end callback is invoked at the end of a primitive. The default end callback function is NULL. The function prototype for this callback function looks like:
+.RS
+.Ex
+void end ( void );
+.Ee
+.RE
+.TP
+\%\f3GLU_NURBS_END_DATA\fP
+This is the same as the \%\f3GLU_NURBS_END\fP callback, except that it
+takes an additional pointer argument. This pointer is a copy of the pointer
+that was specified at the last call to \%\f3gluNurbsCallbackData\fP. The default callback function is NULL. The function prototype for this callback function looks like:
+.RS
+.Ex
+void endData ( void *userData );
+.Ee
+.RE
+.TP
+\%\f3GLU_NURBS_ERROR\fP
+The error function is called when an error is encountered.
+Its single argument
+is of type GLenum, and it indicates the specific error that occurred.
+There are 37 errors unique to NURBS named
+\%\f3GLU_NURBS_ERROR1\fP through \%\f3GLU_NURBS_ERROR37\fP.
+Character strings describing these errors can be retrieved with
+\%\f3gluErrorString\fP.
+.bp
+.SH NOTES
+\%\f3gluNurbsCallback\fP is available only if the GLU version is 1.2 or greater.
+.P
+GLU version 1.2 supports only the \%\f3GLU_ERROR\fP parameter for
+\f2which\fP. The \%\f3GLU_ERROR\fP value is deprecated in GLU version 1.3 in
+favor of \%\f3GLU_NURBS_ERROR\fP. All other accepted values for \f2CallBackFunc\fP
+are available only if the GLU version is 1.3 or greater.
+.SH SEE ALSO
+\%\f3gluErrorString(3G)\fP,
+\%\f3gluNewNurbsRenderer(3G)\fP,
+\%\f3gluNurbsCallbackData(3G)\fP,
+\%\f3gluNurbsProperty(3G)\fP
+
diff --git a/doc/gl-docs/GLU/nurbscallbackdata.3gl b/doc/gl-docs/GLU/nurbscallbackdata.3gl
new file mode 100644
index 000000000..a0a45f2d6
--- /dev/null
+++ b/doc/gl-docs/GLU/nurbscallbackdata.3gl
@@ -0,0 +1,41 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 nurbscall
+.ds Xs 16331 3 nurbscallbackdata.gl
+.TH GLUNURBSCALLBACKDATA 3G
+.SH NAME
+.B "gluNurbsCallbackData
+\- set a user data pointer
+
+.SH C SPECIFICATION
+void \f3gluNurbsCallbackData\fP(
+GLUnurbs* \fInurb\fP,
+.nf
+.ta \w'\f3void \fPgluNurbsCallbackData( 'u
+ GLvoid* \fIuserData\fP )
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\fIuserData\fP\ \ 'u
+\f2nurb\fP
+Specifies the NURBS object (created with \%\f3gluNewNurbsRenderer\fP).
+.TP
+\f2userData\fP
+Specifies a pointer to the user's data.
+.SH DESCRIPTION
+\%\f3gluNurbsCallbackData\fP is used to pass a pointer to the application's data to NURBS
+tessellator. A copy of this pointer will be passed by the tessellator
+in the NURBS callback functions (set by \%\f3gluNurbsCallback\fP).
+.SH NOTES
+\%\f3gluNurbsCallbackData\fP is available only if the GLU version is 1.3 or greater.
+.SH SEE ALSO
+\%\f3gluNewNurbsRenderer(3G)\fP,
+\%\f3gluNurbsCallback(3G)\fP
diff --git a/doc/gl-docs/GLU/nurbscallbackdataext.3gl b/doc/gl-docs/GLU/nurbscallbackdataext.3gl
new file mode 100644
index 000000000..8ff424ea6
--- /dev/null
+++ b/doc/gl-docs/GLU/nurbscallbackdataext.3gl
@@ -0,0 +1,38 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm :37 nurbscal
+.ds Xs 36770 3 nurbscallbackdataext.gl
+.TH GLUNURBSCALLBACKDATAEXT 3G
+.SH NAME
+.B "gluNurbsCallbackDataEXT
+\- set a user data pointer
+
+.SH C SPECIFICATION
+void \f3gluNurbsCallbackDataEXT\fP(
+GLUnurbs* \fInurb\fP,
+.nf
+.ta \w'\f3void \fPgluNurbsCallbackDataEXT( 'u
+ GLvoid* \fIuserData\fP )
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\fIuserData\fP\ \ 'u
+\f2nurb\fP
+Specifies the NURBS object (created with \%\f3gluNewNurbsRenderer\fP).
+.TP
+\f2userData\fP
+Specifies a pointer to the user's data.
+.SH DESCRIPTION
+\%\f3gluNurbsCallbackDataEXT\fP is used to pass a pointer to the application's data to NURBS
+tessellator. A copy of this pointer will be passed by the tessellator
+in the NURBS callback functions (set by \%\f3gluNurbsCallback\fP).
+.SH SEE ALSO
+\%\f3gluNurbsCallback(3G)\fP
diff --git a/doc/gl-docs/GLU/nurbscurve.3gl b/doc/gl-docs/GLU/nurbscurve.3gl
new file mode 100644
index 000000000..b528cbbbc
--- /dev/null
+++ b/doc/gl-docs/GLU/nurbscurve.3gl
@@ -0,0 +1,99 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 nurbscurv
+.ds Xs 25594 5 nurbscurve.gl
+.TH GLUNURBSCURVE 3G
+.SH NAME
+.B "gluNurbsCurve
+\- define the shape of a NURBS curve
+
+.SH C SPECIFICATION
+void \f3gluNurbsCurve\fP(
+GLUnurbs* \fInurb\fP,
+.nf
+.ta \w'\f3void \fPgluNurbsCurve( 'u
+ GLint \fIknotCount\fP,
+ GLfloat \fI*knots\fP,
+ GLint \fIstride\fP,
+ GLfloat \fI*control\fP,
+ GLint \fIorder\fP,
+ GLenum \fItype\fP )
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\fIknotCount\fP\ \ 'u
+\f2nurb\fP
+Specifies the NURBS object (created with \%\f3gluNewNurbsRenderer\fP).
+.TP
+\f2knotCount\fP
+Specifies the number of knots in \f2knots\fP.
+\f2knotCount\fP equals the number of control points plus the order.
+.TP
+\f2knots\fP
+Specifies an array of \f2knotCount\fP nondecreasing knot values.
+.TP
+\f2stride\fP
+Specifies the offset (as a number of single-precision floating-point values)
+between successive curve control points.
+.TP
+\f2control\fP
+Specifies a pointer to an array of control points. The coordinates must
+agree with \f2type\fP, specified below.
+.TP
+\f2order\fP
+Specifies the order of the NURBS curve. \f2order\fP equals degree + 1, hence
+a cubic curve has an order of 4.
+.TP
+\f2type\fP
+Specifies the type of the curve. If this curve is defined within a
+\%\f3gluBeginCurve\fP/\%\f3gluEndCurve\fP pair, then
+the type can be any of the valid
+one-dimensional evaluator types (such as \%\f3GL_MAP1_VERTEX_3\fP or
+\%\f3GL_MAP1_COLOR_4\fP). Between a \%\f3gluBeginTrim\fP/\%\f3gluEndTrim\fP pair,
+the only valid types are \%\f3GLU_MAP1_TRIM_2\fP and \%\f3GLU_MAP1_TRIM_3\fP.
+.SH DESCRIPTION
+Use \%\f3gluNurbsCurve\fP to describe a NURBS curve.
+.P
+When \%\f3gluNurbsCurve\fP appears between a \%\f3gluBeginCurve\fP/\%\f3gluEndCurve\fP pair, it is
+used to describe a curve to be rendered.
+Positional, texture, and color coordinates are associated
+by presenting each as a separate \%\f3gluNurbsCurve\fP between a
+\%\f3gluBeginCurve\fP/\%\f3gluEndCurve\fP pair. No more than
+one call to \%\f3gluNurbsCurve\fP for each of color, position, and texture
+data can be made within a single \%\f3gluBeginCurve\fP/\%\f3gluEndCurve\fP
+pair. Exactly one call must be made to describe the position of the
+curve (a \f2type\fP of \%\f3GL_MAP1_VERTEX_3\fP or \%\f3GL_MAP1_VERTEX_4\fP).
+.P
+When \%\f3gluNurbsCurve\fP appears between a \%\f3gluBeginTrim\fP/\%\f3gluEndTrim\fP pair, it is
+used to describe a trimming curve on a NURBS surface. If \f2type\fP is
+\%\f3GLU_MAP1_TRIM_2\fP, then it describes a curve in two-dimensional (\f2u\fP
+and \f2v\fP)
+parameter space. If it is \%\f3GLU_MAP1_TRIM_3\fP, then it describes a
+curve in two-dimensional homogeneous (\f2u\fP, \f2v\fP, and \f2w\fP)
+parameter space.
+See the \%\f3gluBeginTrim\fP reference page for more discussion about trimming
+curves.
+.SH EXAMPLE
+The following commands render a textured NURBS curve with normals:
+.sp
+.Ex
+gluBeginCurve(nobj);
+ gluNurbsCurve(nobj, ..., GL_MAP1_TEXTURE_COORD_2);
+ gluNurbsCurve(nobj, ..., GL_MAP1_NORMAL);
+ gluNurbsCurve(nobj, ..., GL_MAP1_VERTEX_4);
+gluEndCurve(nobj);
+.Ee
+.sp
+.SH NOTES
+To define trim curves which stitch well, use \%\f3gluPwlCurve\fP.
+.SH SEE ALSO
+\%\f3gluBeginCurve(3G)\fP, \%\f3gluBeginTrim(3G)\fP, \%\f3gluNewNurbsRenderer(3G)\fP, \%\f3gluPwlCurve(3G)\fP
+
diff --git a/doc/gl-docs/GLU/nurbsproperty.3gl b/doc/gl-docs/GLU/nurbsproperty.3gl
new file mode 100644
index 000000000..eec82105f
--- /dev/null
+++ b/doc/gl-docs/GLU/nurbsproperty.3gl
@@ -0,0 +1,202 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 nurbsprop
+.ds Xs 47701 10 nurbsproperty.gl
+.TH GLUNURBSPROPERTY 3G
+.SH NAME
+.B "gluNurbsProperty
+\- set a NURBS property
+
+.SH C SPECIFICATION
+void \f3gluNurbsProperty\fP(
+GLUnurbs* \fInurb\fP,
+.nf
+.ta \w'\f3void \fPgluNurbsProperty( 'u
+ GLenum \fIproperty\fP,
+ GLfloat \fIvalue\fP )
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\fIproperty\fP\ \ 'u
+\f2nurb\fP
+Specifies the NURBS object (created with \%\f3gluNewNurbsRenderer\fP).
+.TP
+\f2property\fP
+Specifies the property to be set. Valid values are
+\%\f3GLU_SAMPLING_TOLERANCE\fP,
+\%\f3GLU_DISPLAY_MODE\fP,
+\%\f3GLU_CULLING\fP,
+\%\f3GLU_AUTO_LOAD_MATRIX\fP,
+\%\f3GLU_PARAMETRIC_TOLERANCE\fP,
+\%\f3GLU_SAMPLING_METHOD\fP,
+\%\f3GLU_U_STEP\fP,
+\%\f3GLU_V_STEP\fP, or
+\%\f3GLU_NURBS_MODE\fP.
+.TP
+\f2value\fP
+Specifies the value of the indicated property.
+It may be a numeric value, or one of
+\%\f3GLU_OUTLINE_POLYGON\fP,
+\%\f3GLU_FILL\fP,
+\%\f3GLU_OUTLINE_PATCH\fP,
+\%\f3GL_TRUE\fP,
+\%\f3GL_FALSE\fP,
+\%\f3GLU_PATH_LENGTH\fP,
+\%\f3GLU_PARAMETRIC_ERROR\fP,
+\%\f3GLU_DOMAIN_DISTANCE\fP,
+\%\f3GLU_NURBS_RENDERER\fP, or
+\%\f3GLU_NURBS_TESSELLATOR\fP.
+.SH DESCRIPTION
+\%\f3gluNurbsProperty\fP is used to control properties stored in a NURBS object. These
+properties affect the way that a NURBS curve is rendered. The accepted
+values for \f2property\fP are as follows:
+.TP 15
+\%\f3GLU_NURBS_MODE\fP
+\f2value\fP should be set to be either \%\f3GLU_NURBS_RENDERER\fP or
+\%\f3GLU_NURBS_TESSELLATOR\fP. When set to \%\f3GLU_NURBS_RENDERER\fP, NURBS objects
+are tessellated into OpenGL primitives and sent to the pipeline for
+rendering. When set to \%\f3GLU_NURBS_TESSELLATOR\fP, NURBS objects are
+tessellated into OpenGL primitives but the vertices, normals, colors, and/or textures are
+retrieved back through a callback interface (see \%\f3gluNurbsCallback\fP). This allows the user to cache the
+tessellated results for further processing.
+The initial value is \%\f3GLU_NURBS_RENDERER\fP.
+.TP
+\%\f3GLU_SAMPLING_METHOD\fP
+Specifies how a NURBS surface should be
+tessellated.
+\f2value\fP may be one of \%\f3GLU_PATH_LENGTH\fP,
+\%\f3GLU_PARAMETRIC_ERROR\fP, \%\f3GLU_DOMAIN_DISTANCE\fP,
+\%\f3GLU_OBJECT_PATH_LENGTH\fP, or
+\%\f3GLU_OBJECT_PARAMETRIC_ERROR\fP.
+When set to \%\f3GLU_PATH_LENGTH\fP, the surface is rendered so that
+the maximum length, in
+pixels, of the edges of the tessellation polygons is no greater than
+what is specified by \%\f3GLU_SAMPLING_TOLERANCE\fP.
+.IP
+\%\f3GLU_PARAMETRIC_ERROR\fP specifies that the surface is rendered in such a
+way that the value specified by \%\f3GLU_PARAMETRIC_TOLERANCE\fP describes the
+maximum distance, in pixels, between the tessellation polygons and the
+surfaces they approximate.
+.IP
+\%\f3GLU_DOMAIN_DISTANCE\fP allows users to specify, in parametric coordinates,
+how many sample points per unit length are taken in \f2u\fP, \f2v\fP
+direction.
+.IP
+\%\f3GLU_OBJECT_PATH_LENGTH\fP is similar to \%\f3GLU_PATH_LENGTH\fP
+except that it is view independent, that is, the surface is rendered so that the maximum length, in object space, of edges of the tessellation polygons is no greater than what is specified by \%\f3GLU_SAMPLING_TOLERANCE\fP.
+.IP
+\%\f3GLU_OBJECT_PARAMETRIC_ERROR\fP is similar to \%\f3GLU_PARAMETRIC_ERROR\fP except that it is view independent, that is, the surface is rendered in such a way that the value specified by \%\f3GLU_PARAMETRIC_TOLERANCE\fP describes the maximum distance, in object space, between the tessellation polygons and the surfaces they approximate.
+.IP
+The initial value of \%\f3GLU_SAMPLING_METHOD\fP is \%\f3GLU_PATH_LENGTH\fP.
+.TP
+\%\f3GLU_SAMPLING_TOLERANCE\fP
+Specifies the maximum length, in pixels or in object space length unit,
+to use when the sampling method is set to \%\f3GLU_PATH_LENGTH\fP or
+\%\f3GLU_OBJECT_PATH_LENGTH\fP.
+The NURBS code is conservative when rendering a curve
+or surface, so the actual length can be somewhat shorter. The initial
+value is 50.0 pixels.
+.TP
+\%\f3GLU_PARAMETRIC_TOLERANCE\fP
+Specifies the maximum distance, in pixels or in object space length unit,
+to use when the sampling method is \%\f3GLU_PARAMETRIC_ERROR\fP or
+\%\f3GLU_OBJECT_PARAMETRIC_ERROR\fP.
+The initial value is 0.5.
+.TP
+\%\f3GLU_U_STEP\fP
+Specifies the number of sample points per unit length taken
+along the \f2u\fP axis in parametric coordinates. It is needed when
+\%\f3GLU_SAMPLING_METHOD\fP is set to \%\f3GLU_DOMAIN_DISTANCE\fP.
+The initial value is 100.
+.TP
+\%\f3GLU_V_STEP\fP
+Specifies the number of sample points per unit length taken
+along the \f2v\fP axis in parametric coordinate. It is needed when
+\%\f3GLU_SAMPLING_METHOD\fP is set to \%\f3GLU_DOMAIN_DISTANCE\fP. The initial
+value is 100.
+.TP
+\%\f3GLU_DISPLAY_MODE\fP
+\f2value\fP can be set to
+\%\f3GLU_OUTLINE_POLYGON\fP, \%\f3GLU_FILL\fP, or
+\%\f3GLU_OUTLINE_PATCH\fP.
+When \%\f3GLU_NURBS_MODE\fP is set to be \%\f3GLU_NURBS_RENDERER\fP,
+\f2value\fP defines how a NURBS surface should be rendered.
+When \f2value\fP is set to \%\f3GLU_FILL\fP, the surface is rendered as a
+set of polygons. When \f2value\fP is set to
+\%\f3GLU_OUTLINE_POLYGON\fP, the NURBS library draws only the outlines
+of the polygons created by tessellation. When \f2value\fP is set to
+\%\f3GLU_OUTLINE_PATCH\fP just the outlines of patches and trim
+curves defined by the user are drawn.
+.IP
+When \%\f3GLU_NURBS_MODE\fP is set to be \%\f3GLU_NURBS_TESSELLATOR\fP,
+\f2value\fP defines how a NURBS surface should be tessellated.
+When \%\f3GLU_DISPLAY_MODE\fP is set to \%\f3GLU_FILL\fP or
+\%\f3GLU_OUTLINE_POLYGON\fP,
+the NURBS surface is tessellated into OpenGL triangle primitives which can be
+retrieved back through callback functions. If \%\f3GLU_DISPLAY_MODE\fP is set to
+\%\f3GLU_OUTLINE_PATCH\fP, only the outlines of the patches and trim curves are generated as a sequence of line strips which can be retrieved back through callback functions.
+.IP
+The initial value is \%\f3GLU_FILL\fP.
+.TP
+\%\f3GLU_CULLING\fP
+\f2value\fP is a boolean value that, when set to \%\f3GL_TRUE\fP, indicates that
+a NURBS curve should be discarded prior to tessellation if its control points
+lie outside the current viewport. The initial value is \%\f3GL_FALSE\fP.
+.TP
+\%\f3GLU_AUTO_LOAD_MATRIX\fP
+\f2value\fP is a boolean value. When set to \%\f3GL_TRUE\fP, the NURBS code
+downloads the projection matrix, the modelview matrix, and the
+viewport from the GL server to compute sampling and
+culling
+matrices for each NURBS curve that is rendered. Sampling and culling matrices
+are required to determine the tessellation of a NURBS surface into line segments
+or polygons and to cull a NURBS surface if it lies outside the viewport.
+.IP
+If this mode is set to \%\f3GL_FALSE\fP, then the program needs
+to provide a projection matrix, a modelview matrix, and a viewport
+for the NURBS renderer to use to construct sampling and culling matrices.
+This can be done with the \%\f3gluLoadSamplingMatrices\fP function.
+This mode is initially set to \%\f3GL_TRUE\fP.
+Changing it from \%\f3GL_TRUE\fP to \%\f3GL_FALSE\fP does not affect
+the sampling and culling matrices until
+\%\f3gluLoadSamplingMatrices\fP
+is called.
+.SH NOTES
+If \%\f3GLU_AUTO_LOAD_MATRIX\fP is true, sampling and culling may be
+executed incorrectly if NURBS routines are compiled into a display list.
+.P
+A \f2property\fP of
+\%\f3GLU_PARAMETRIC_TOLERANCE\fP,
+\%\f3GLU_SAMPLING_METHOD\fP,
+\%\f3GLU_U_STEP\fP, or
+\%\f3GLU_V_STEP\fP,
+or a \f2value\fP of
+\%\f3GLU_PATH_LENGTH\fP,
+\%\f3GLU_PARAMETRIC_ERROR\fP,
+\%\f3GLU_DOMAIN_DISTANCE\fP
+are only available if the GLU version is 1.1 or greater. They are not
+valid parameters in GLU 1.0.
+.P
+\%\f3gluGetString\fP can
+be used to determine the GLU version.
+.P
+\%\f3GLU_NURBS_MODE\fP is only availble if the GLU version is 1.3 or
+greater.
+.P
+The \%\f3GLU_OBJECT_PATH_LENGTH\fP and \%\f3GLU_OBJECT_PARAMETRIC_ERROR\fP
+values for the \%\f3GLU_SAMPLING_METHOD\fP property are only available if
+the GLU version is 1.3 or greater.
+.SH SEE ALSO
+\%\f3gluGetNurbsProperty(3G)\fP,
+\%\f3gluLoadSamplingMatrices(3G)\fP,
+\%\f3gluNewNurbsRenderer(3G)\fP,
+\%\f3gluGetString(3G)\fP,
+\%\f3gluNurbsCallback(3G)\fP
diff --git a/doc/gl-docs/GLU/nurbssurface.3gl b/doc/gl-docs/GLU/nurbssurface.3gl
new file mode 100644
index 000000000..6199f88fb
--- /dev/null
+++ b/doc/gl-docs/GLU/nurbssurface.3gl
@@ -0,0 +1,124 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 nurbssurf
+.ds Xs 28728 6 nurbssurface.gl
+.TH GLUNURBSSURFACE 3G
+.SH NAME
+.B "gluNurbsSurface
+\- define the shape of a NURBS surface
+
+.SH C SPECIFICATION
+void \f3gluNurbsSurface\fP(
+GLUnurbs* \fInurb\fP,
+.nf
+.ta \w'\f3void \fPgluNurbsSurface( 'u
+ GLint \fIsKnotCount\fP,
+ GLfloat* \fIsKnots\fP,
+ GLint \fItKnotCount\fP,
+ GLfloat* \fItKnots\fP,
+ GLint \fIsStride\fP,
+ GLint \fItStride\fP,
+ GLfloat* \fIcontrol\fP,
+ GLint \fIsOrder\fP,
+ GLint \fItOrder\fP,
+ GLenum \fItype\fP )
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\fIsKnotCount\fP\ \ 'u
+\f2nurb\fP
+Specifies the NURBS object (created with \%\f3gluNewNurbsRenderer\fP).
+.TP
+\f2sKnotCount\fP
+Specifies the number of knots in the parametric \f2u\fP direction.
+.TP
+\f2sKnots\fP
+Specifies an array of \f2sKnotCount\fP nondecreasing knot values in the parametric
+\f2u\fP direction.
+.TP
+\f2tKnotCount\fP
+Specifies the number of knots in the parametric \f2v\fP direction.
+.TP
+\f2tKnots\fP
+Specifies an array of \f2tKnotCount\fP nondecreasing knot values in the parametric
+\f2v\fP direction.
+.TP
+\f2sStride\fP
+Specifies the offset (as a number of single-precision floating point values)
+between successive control points in the parametric \f2u\fP direction
+in \f2control\fP.
+.TP
+\f2tStride\fP
+Specifies the offset (in single-precision floating-point values)
+between successive control points in the parametric \f2v\fP direction
+in \f2control\fP.
+.TP
+\f2control\fP
+Specifies an array containing control points for the NURBS surface.
+The offsets between successive control points in the parametric \f2u\fP
+and \f2v\fP directions are given by \f2sStride\fP and \f2tStride\fP.
+.TP
+\f2sOrder\fP
+Specifies the order of the NURBS surface in the parametric \f2u\fP
+direction. The order is one more than the degree, hence
+a surface that is cubic in \f2u\fP has a \f2u\fP order of 4.
+.TP
+\f2tOrder\fP
+Specifies the order of the NURBS surface in the parametric \f2v\fP
+direction. The order is one more than the degree, hence
+a surface that is cubic in \f2v\fP has a \f2v\fP order of 4.
+.TP
+\f2type\fP
+Specifies type of the surface. \f2type\fP can be any of the valid
+two-dimensional evaluator types (such as \%\f3GL_MAP2_VERTEX_3\fP or
+\%\f3GL_MAP2_COLOR_4\fP).
+.SH DESCRIPTION
+Use \%\f3gluNurbsSurface\fP within a NURBS (Non-Uniform Rational B-Spline) surface
+definition to describe the shape of a NURBS surface (before
+any trimming). To mark the beginning of
+a NURBS surface definition, use the \%\f3gluBeginSurface\fP command.
+To mark the end of a NURBS surface definition, use the
+\%\f3gluEndSurface\fP command. Call \%\f3gluNurbsSurface\fP within a NURBS
+surface definition only.
+.P
+Positional, texture, and color coordinates are associated
+with a surface by presenting each as a separate \%\f3gluNurbsSurface\fP between a
+\%\f3gluBeginSurface\fP/\%\f3gluEndSurface\fP pair. No more than
+one call to \%\f3gluNurbsSurface\fP for each of color, position, and texture
+data can be made within a single \%\f3gluBeginSurface\fP/\%\f3gluEndSurface\fP
+pair. Exactly one call must be made to describe the position of the
+surface (a \f2type\fP of \%\f3GL_MAP2_VERTEX_3\fP or \%\f3GL_MAP2_VERTEX_4\fP).
+.P
+A NURBS surface can be trimmed by using the commands
+\%\f3gluNurbsCurve\fP and \%\f3gluPwlCurve\fP between calls to
+\%\f3gluBeginTrim\fP and \%\f3gluEndTrim\fP.
+.P
+Note that a \%\f3gluNurbsSurface\fP with \f2sKnotCount\fP knots in the \f2u\fP direction
+and \f2tKnotCount\fP knots in the \f2v\fP direction with orders
+\f2sOrder\fP and \f2tOrder\fP must have
+(\f2sKnotCount\fP - \f2sOrder\fP) $times$ (\f2tKnotCount\fP - \f2tOrder\fP) control points.
+.SH EXAMPLE
+The following commands render a textured NURBS surface with normals;
+the texture coordinates and normals are also NURBS surfaces:
+.sp
+.Ex
+gluBeginSurface(nobj);
+ gluNurbsSurface(nobj, ..., GL_MAP2_TEXTURE_COORD_2);
+ gluNurbsSurface(nobj, ..., GL_MAP2_NORMAL);
+ gluNurbsSurface(nobj, ..., GL_MAP2_VERTEX_4);
+gluEndSurface(nobj);
+.Ee
+.sp
+.SH SEE ALSO
+\%\f3gluBeginSurface(3G)\fP, \%\f3gluBeginTrim(3G)\fP, \%\f3gluNewNurbsRenderer(3G)\fP,
+\%\f3gluNurbsCurve(3G)\fP,
+\%\f3gluPwlCurve(3G)\fP
+
diff --git a/doc/gl-docs/GLU/ortho2d.3gl b/doc/gl-docs/GLU/ortho2d.3gl
new file mode 100644
index 000000000..02c38a9ee
--- /dev/null
+++ b/doc/gl-docs/GLU/ortho2d.3gl
@@ -0,0 +1,41 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 ortho2d.g
+.ds Xs 62574 3 ortho2d.gl
+.TH GLUORTHO2D 3G
+.SH NAME
+.B "gluOrtho2D
+\- define a 2D orthographic projection matrix
+
+.SH C SPECIFICATION
+void \f3gluOrtho2D\fP(
+GLdouble \fIleft\fP,
+.nf
+.ta \w'\f3void \fPgluOrtho2D( 'u
+ GLdouble \fIright\fP,
+ GLdouble \fIbottom\fP,
+ GLdouble \fItop\fP )
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\f2left\fP\ \f2right\fP\ \ 'u
+\f2left\fP, \f2right\fP
+Specify the coordinates for the left and right vertical clipping planes.
+.TP
+\f2bottom\fP, \f2top\fP
+Specify the coordinates for the bottom and top horizontal clipping planes.
+.SH DESCRIPTION
+\%\f3gluOrtho2D\fP sets up a two-dimensional orthographic viewing region.
+This is equivalent to calling \f3glOrtho\fP with $ near ~=~ -1 $ and
+$ far ~=~ 1 $.
+.SH SEE ALSO
+\f3glOrtho(3G)\fP, \%\f3gluPerspective(3G)\fP
+
diff --git a/doc/gl-docs/GLU/partialdisk.3gl b/doc/gl-docs/GLU/partialdisk.3gl
new file mode 100644
index 000000000..3794081e3
--- /dev/null
+++ b/doc/gl-docs/GLU/partialdisk.3gl
@@ -0,0 +1,87 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 partialdi
+.ds Xs 56621 5 partialdisk.gl
+.TH GLUPARTIALDISK 3G
+.SH NAME
+.B "gluPartialDisk
+\- draw an arc of a disk
+
+.SH C SPECIFICATION
+void \f3gluPartialDisk\fP(
+GLUquadric* \fIquad\fP,
+.nf
+.ta \w'\f3void \fPgluPartialDisk( 'u
+ GLdouble \fIinner\fP,
+ GLdouble \fIouter\fP,
+ GLint \fIslices\fP,
+ GLint \fIloops\fP,
+ GLdouble \fIstart\fP,
+ GLdouble \fIsweep\fP )
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\fIslices\fP\ \ 'u
+\f2quad\fP
+Specifies a quadrics object (created with \%\f3gluNewQuadric\fP).
+.TP
+\f2inner\fP
+Specifies the inner radius of the partial disk (can be 0).
+.TP
+\f2outer\fP
+Specifies the outer radius of the partial disk.
+.TP
+\f2slices\fP
+Specifies the number of subdivisions around the \f2z\fP axis.
+.TP
+\f2loops\fP
+Specifies the number of concentric rings about the origin into which
+the partial disk is subdivided.
+.TP
+\f2start\fP
+Specifies the starting angle, in degrees, of the disk portion.
+.TP
+\f2sweep\fP
+Specifies the sweep angle, in degrees, of the disk portion.
+.SH DESCRIPTION
+\%\f3gluPartialDisk\fP renders a partial disk on the $ z ~=~ 0 $ plane. A partial disk is
+similar to a full disk, except that only the subset of the disk from
+\f2start\fP through \f2start\fP + \f2sweep\fP is included (where 0 degrees is along the
++\f2y\f axis,
+90 degrees along the +\f2x\fP axis, 180 degrees along the \-\f2y\fP axis, and
+270 degrees along the \-\f2x\fP axis).
+.P
+The partial disk has a radius of
+\f2outer\fP, and contains a concentric circular hole with a radius
+of \f2inner\fP. If \f2inner\fP is 0, then no hole is generated. The partial disk is
+subdivided around the \f2z\fP axis into slices (like pizza slices), and also
+about the \f2z\fP axis into rings
+(as specified by \f2slices\fP and \f2loops\fP, respectively).
+.P
+With respect to orientation, the +\f2z\fP
+side of the partial disk is considered to
+be outside (see \%\f3gluQuadricOrientation\fP).
+This means that if the
+orientation is set to \%\f3GLU_OUTSIDE\fP, then any normals generated
+point along the +\f2z\fP axis. Otherwise, they point along the \-\f2z\fP
+axis.
+.P
+If texturing is turned on (with \%\f3gluQuadricTexture\fP), texture
+coordinates are generated
+linearly such that where $ r ~=~ "outer" $, the value at (\f2r\fP, 0, 0) is
+(1.0, 0.5), at (0, \f2r\fP, 0) it is (0.5, 1.0), at (\-\f2r\fP, 0, 0)
+it is (0.0, 0.5), and
+at (0, \-\f2r\fP, 0) it is (0.5, 0.0).
+.SH SEE ALSO
+\%\f3gluCylinder(3G)\fP, \%\f3gluDisk(3G)\fP, \%\f3gluNewQuadric(3G)\fP, \%\f3gluQuadricOrientation(3G)\fP,
+\%\f3gluQuadricTexture(3G)\fP,
+\%\f3gluSphere(3G)\fP
+
diff --git a/doc/gl-docs/GLU/perspective.3gl b/doc/gl-docs/GLU/perspective.3gl
new file mode 100644
index 000000000..e3df546ec
--- /dev/null
+++ b/doc/gl-docs/GLU/perspective.3gl
@@ -0,0 +1,96 @@
+.\" $XFree86$
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 perspecti
+.ds Xs 14699 5 perspective.gl
+.TH GLUPERSPECTIVE 3G
+.SH NAME
+.B "gluPerspective
+\- set up a perspective projection matrix
+
+.SH C SPECIFICATION
+void \f3gluPerspective\fP(
+GLdouble \fIfovy\fP,
+.nf
+.ta \w'\f3void \fPgluPerspective( 'u
+ GLdouble \fIaspect\fP,
+ GLdouble \fIzNear\fP,
+ GLdouble \fIzFar\fP )
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\fIaspect\fP\ \ 'u
+\f2fovy\fP
+Specifies the field of view angle, in degrees, in the \f2y\fP direction.
+.TP
+\f2aspect\fP
+Specifies the aspect ratio that determines
+the field of view in the \f2x\fP direction.
+The aspect ratio is the ratio of \f2x\fP (width) to \f2y\fP (height).
+.TP
+\f2zNear\fP
+Specifies the distance from the viewer to the near clipping plane
+(always positive).
+.TP
+\f2zFar\fP
+Specifies the distance from the viewer to the far clipping plane
+(always positive).
+.SH DESCRIPTION
+\%\f3gluPerspective\fP specifies a viewing frustum into the world coordinate system.
+In general, the aspect ratio in \%\f3gluPerspective\fP should match the aspect ratio
+of the associated viewport. For example, $ "aspect" ~=~ 2.0 $ means
+the viewer's
+angle of view is twice as wide in \f2x\fP as it is in \f2y\fP.
+If the viewport is
+twice as wide as it is tall, it displays the image without distortion.
+.P
+The matrix generated by \%\f3gluPerspective\fP is multiplied by the current matrix,
+just as if \f3glMultMatrix\fP were called with the generated matrix.
+To load the perspective matrix onto the current matrix stack instead,
+precede the call to \%\f3gluPerspective\fP with a call to \f3glLoadIdentity\fP.
+.P
+Given \f2f\fP defined as follows:
+.sp
+.ce
+.EQ
+f ~=~ cotangent"("{"fovy" over 2}")"
+.EN
+.bp
+The generated matrix is
+.sp
+.ce
+.EQ
+left ( ~~ down 130 { matrix {
+ ccol { {f over "aspect"} above 0 above 0 above 0 }
+ ccol { 0 above f above 0 above 0 }
+ ccol { 0 above 0 above {{"zFar" + "zNear"} over {"zNear" - "zFar"}} above -1 }
+ ccol { 0 above 0 above {{2 * "zFar" * "zNear"} over {"zNear" - "zFar"}} above 0}
+}} ~~~ right )
+.EN
+
+.SH NOTES
+Depth buffer precision is affected by the values specified for
+\f2zNear\fP and \f2zFar\fP.
+The greater the ratio of \f2zFar\fP to \f2zNear\fP is,
+the less effective the depth buffer will be at distinguishing between
+surfaces that are near each other.
+If
+.sp
+.ce
+$r ~=~ "zFar" over "zNear"$
+.sp
+.P
+roughly $log sub 2 r$ bits of depth buffer precision are lost.
+Because $r$ approaches infinity as \f2zNear\fP approaches 0,
+\f2zNear\fP must never be set to 0.
+.SH SEE ALSO
+\f3glFrustum(3G)\fP, \f3glLoadIdentity(3G)\fP,
+\f3glMultMatrix(3G)\fP, \%\f3gluOrtho2D(3G)\fP
diff --git a/doc/gl-docs/GLU/pickmatrix.3gl b/doc/gl-docs/GLU/pickmatrix.3gl
new file mode 100644
index 000000000..3b5a15018
--- /dev/null
+++ b/doc/gl-docs/GLU/pickmatrix.3gl
@@ -0,0 +1,94 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 pickmatri
+.ds Xs 64359 5 pickmatrix.gl
+.TH GLUPICKMATRIX 3G
+.SH NAME
+.B "gluPickMatrix
+\- define a picking region
+
+.SH C SPECIFICATION
+void \f3gluPickMatrix\fP(
+GLdouble \fIx\fP,
+.nf
+.ta \w'\f3void \fPgluPickMatrix( 'u
+ GLdouble \fIy\fP,
+ GLdouble \fIdelX\fP,
+ GLdouble \fIdelY\fP,
+ GLint \fI*viewport\fP )
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\f2x\fP\ \f2y\fP\ \ 'u
+\f2x\fP, \f2y\fP
+Specify the center of a picking region in window coordinates.
+.TP
+\f2delX\fP, \f2delY\fP
+Specify the width and height, respectively, of the picking region in window
+coordinates.
+.TP
+\f2viewport\fP
+Specifies the current viewport (as from a \f3glGetIntegerv\fP call).
+.SH DESCRIPTION
+\%\f3gluPickMatrix\fP creates a projection matrix that can be used to restrict drawing
+to a small region of the viewport.
+This is typically useful to
+determine what objects are being drawn near the cursor.
+Use \%\f3gluPickMatrix\fP to
+restrict drawing to a small region around the cursor.
+Then,
+enter selection mode (with \f3glRenderMode\fP) and rerender the scene.
+All primitives that would have been drawn near
+the cursor are identified and stored in the selection buffer.
+.P
+The matrix created by \%\f3gluPickMatrix\fP is multiplied by the current matrix just
+as if \f3glMultMatrix\fP is called with the generated matrix.
+To effectively use the generated pick matrix for picking,
+first call \f3glLoadIdentity\fP to load an identity matrix onto the
+perspective matrix stack.
+Then call \%\f3gluPickMatrix\fP,
+and finally, call a command (such as \%\f3gluPerspective\fP)
+to multiply the perspective matrix by the pick matrix.
+.P
+When using \%\f3gluPickMatrix\fP to pick NURBS, be careful to turn off the NURBS
+property
+\%\f3GLU_AUTO_LOAD_MATRIX\fP. If \%\f3GLU_AUTO_LOAD_MATRIX\fP is not
+turned off, then any NURBS surface rendered is subdivided differently with
+the pick matrix than the way it was subdivided without the pick matrix.
+.bp
+.SH EXAMPLE
+When rendering a scene as follows:
+.sp
+.Ex
+glMatrixMode(GL_PROJECTION);
+glLoadIdentity();
+gluPerspective(...);
+glMatrixMode(GL_MODELVIEW);
+/* Draw the scene */
+.Ee
+.sp
+a portion of the viewport can be selected as a pick region like this:
+.sp
+.Ex
+glMatrixMode(GL_PROJECTION);
+glLoadIdentity();
+gluPickMatrix(x, y, width, height, viewport);
+gluPerspective(...);
+glMatrixMode(GL_MODELVIEW);
+/* Draw the scene */
+.Ee
+.SH SEE ALSO
+\f3glGet(3G)\fP,
+\f3glLoadIndentity(3G)\fP,
+\f3glMultMatrix(3G)\fP,
+\f3glRenderMode(3G)\fP,
+\%\f3gluPerspective(3G)\fP
+
diff --git a/doc/gl-docs/GLU/project.3gl b/doc/gl-docs/GLU/project.3gl
new file mode 100644
index 000000000..2f6267c99
--- /dev/null
+++ b/doc/gl-docs/GLU/project.3gl
@@ -0,0 +1,88 @@
+.\" $XFree86$
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 project.g
+.ds Xs 21974 4 project.gl
+.TH GLUPROJECT 3G
+.SH NAME
+.B "gluProject
+\- map object coordinates to window coordinates
+
+.SH C SPECIFICATION
+GLint \f3gluProject\fP(
+GLdouble \fIobjX\fP,
+.nf
+.ta \w'\f3GLint \fPgluProject( 'u
+ GLdouble \fIobjY\fP,
+ GLdouble \fIobjZ\fP,
+ const GLdouble \fI*model\fP,
+ const GLdouble \fI*proj\fP,
+ const GLint \fI*view\fP,
+ GLdouble* \fIwinX\fP,
+ GLdouble* \fIwinY\fP,
+ GLdouble* \fIwinZ\fP )
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\f2objX\fP\ \f2objY\fP\ \f2objZ\fP\ \ 'u
+\f2objX\fP, \f2objY\fP, \f2objZ\fP
+Specify the object coordinates.
+.TP
+\f2model\fP
+Specifies the current modelview matrix (as from a \f3glGetDoublev\fP call).
+.TP
+\f2proj\fP
+Specifies the current projection matrix (as from a \f3glGetDoublev\fP call).
+.TP
+\f2view\fP
+Specifies the current viewport (as from a \f3glGetIntegerv\fP call).
+.TP
+\f2winX\fP, \f2winY\fP, \f2winZ\fP
+Return the computed window coordinates.
+.SH DESCRIPTION
+\%\f3gluProject\fP transforms the specified object coordinates into window coordinates
+using \f2model\fP, \f2proj\fP, and \f2view\fP. The result is stored
+in \f2winX\fP, \f2winY\fP, and \f2winZ\fP. A return value of
+\%\f3GL_TRUE\fP indicates success, a return value of \%\f3GL_FALSE\fP
+indicates failure.
+.P
+To compute the coordinates,
+let $v ~=~ ("objX", "objY", "objZ", 1.0)$
+represented as a matrix with 4 rows and 1 column.
+Then \%\f3gluProject\fP computes $v sup prime$
+as follows:
+.sp
+.EQ
+v sup prime ~=~ P ~times~ M ~times~ v
+.EN
+.sp
+where $P$ is the current projection matrix \f2proj\fP, $M$ is the current
+modelview matrix \f2model\fP (both represented as
+$4 times 4$ matrices in column-major order) and '$times$' represents
+matrix multiplication.
+.P
+The window coordinates are then computed as follows:
+.sp
+.EQ
+"winX" ~=~ "view" (0) ~+~ "view" (2) ~*~ (v sup prime (0) ~+~ 1)~/~2
+.EN
+.sp
+.EQ
+"winY" ~=~ "view" (1) ~+~ "view" (3)~*~(v sup prime (1) ~+~ 1)~/~2
+.EN
+.sp
+.EQ
+"winZ" ~=~ (v sup prime (2) ~+~ 1)~/~ 2
+.EN
+.sp
+.SH SEE ALSO
+\f3glGet(3G)\fP, \%\f3gluUnProject(3G)\fP
+
diff --git a/doc/gl-docs/GLU/pwlcurve.3gl b/doc/gl-docs/GLU/pwlcurve.3gl
new file mode 100644
index 000000000..a30b7726f
--- /dev/null
+++ b/doc/gl-docs/GLU/pwlcurve.3gl
@@ -0,0 +1,69 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 pwlcurve.
+.ds Xs 35475 4 pwlcurve.gl
+.TH GLUPWLCURVE 3G
+.SH NAME
+.B "gluPwlCurve
+\- describe a piecewise linear NURBS trimming curve
+
+.SH C SPECIFICATION
+void \f3gluPwlCurve\fP(
+GLUnurbs* \fInurb\fP,
+.nf
+.ta \w'\f3void \fPgluPwlCurve( 'u
+ GLint \fIcount\fP,
+ GLfloat* \fIdata\fP,
+ GLint \fIstride\fP,
+ GLenum \fItype\fP )
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\fIstride\fP\ \ 'u
+\f2nurb\fP
+Specifies the NURBS object (created with \%\f3gluNewNurbsRenderer\fP).
+.TP
+\f2count\fP
+Specifies the number of points on the curve.
+.TP
+\f2data\fP
+Specifies an array containing the curve points.
+.TP
+\f2stride\fP
+Specifies the offset (a number of single-precision floating-point values)
+between points on the curve.
+.TP
+\f2type\fP
+Specifies the type of curve.
+Must be either \%\f3GLU_MAP1_TRIM_2\fP or \%\f3GLU_MAP1_TRIM_3\fP.
+.SH DESCRIPTION
+\%\f3gluPwlCurve\fP describes a piecewise linear trimming curve for a NURBS surface.
+A piecewise linear curve consists of a list of
+coordinates of points in the parameter space for the
+NURBS surface to be trimmed. These points are connected
+with line segments to form a curve. If the curve is
+an approximation to a curve that is not piecewise linear,
+the points should be close enough in parameter space that the
+resulting path appears curved at the resolution used in the application.
+.P
+If \f2type\fP is
+\%\f3GLU_MAP1_TRIM_2\fP, then it describes a curve in two-dimensional (\f2u\fP
+and \f2v\fP) parameter space. If it is \%\f3GLU_MAP1_TRIM_3\fP, then it
+describes a curve in two-dimensional homogeneous (\f2u\fP, \f2v\fP,
+and \f2w\fP) parameter space.
+See the \%\f3gluBeginTrim\fP reference page for more information
+about trimming curves.
+.SH NOTES
+To describe a trim curve that closely follows the contours of a NURBS
+surface, call \%\f3gluNurbsCurve\fP.
+.SH SEE ALSO
+\%\f3gluBeginCurve(3G)\fP, \%\f3gluBeginTrim(3G)\fP, \%\f3gluNewNurbsRenderer(3G)\fP, \%\f3gluNurbsCurve(3G)\fP
+
diff --git a/doc/gl-docs/GLU/quadriccallback.3gl b/doc/gl-docs/GLU/quadriccallback.3gl
new file mode 100644
index 000000000..3976acf6d
--- /dev/null
+++ b/doc/gl-docs/GLU/quadriccallback.3gl
@@ -0,0 +1,51 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 quadricca
+.ds Xs 46833 3 quadriccallback.gl
+.TH GLUQUADRICCALLBACK 3G
+.SH NAME
+.B "gluQuadricCallback
+\- define a callback for a quadrics object
+
+.SH C SPECIFICATION
+void \f3gluQuadricCallback\fP(
+GLUquadric* \fIquad\fP,
+.nf
+.ta \w'\f3void \fPgluQuadricCallback( 'u
+ GLenum \fIwhich\fP,
+ _GLUfuncptr \fICallBackFunc\fP )
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\fICallBackFunc\fP\ \ 'u
+\f2quad\fP
+Specifies the quadrics object (created with \%\f3gluNewQuadric\fP).
+.TP
+\f2which\fP
+Specifies the callback being defined.
+The only valid value is \%\f3GLU_ERROR\fP.
+.TP
+\f2CallBackFunc\fP
+Specifies the function to be called.
+.SH DESCRIPTION
+\%\f3gluQuadricCallback\fP is used to define a new callback to be used by a quadrics object.
+If the specified callback is already defined, then it is replaced. If
+\f2CallBackFunc\fP is NULL, then any existing callback is erased.
+.P
+The one legal callback is \%\f3GLU_ERROR\fP:
+.TP 15
+\%\f3GLU_ERROR\fP
+The function is called when an error is encountered. Its single argument
+is of type GLenum, and it indicates the specific error that occurred.
+Character strings describing these errors can be retrieved with the
+\%\f3gluErrorString\fP call.
+.SH SEE ALSO
+\%\f3gluErrorString(3G)\fP, \%\f3gluNewQuadric(3G)\fP
diff --git a/doc/gl-docs/GLU/quadricdrawstyle.3gl b/doc/gl-docs/GLU/quadricdrawstyle.3gl
new file mode 100644
index 000000000..6fa2a3423
--- /dev/null
+++ b/doc/gl-docs/GLU/quadricdrawstyle.3gl
@@ -0,0 +1,57 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 quadricdr
+.ds Xs 39695 4 quadricdrawstyle.gl
+.TH GLUQUADRICDRAWSTYLE 3G
+.SH NAME
+.B "gluQuadricDrawStyle
+\- specify the draw style desired for quadrics
+
+.SH C SPECIFICATION
+void \f3gluQuadricDrawStyle\fP(
+GLUquadric* \fIquad\fP,
+.nf
+.ta \w'\f3void \fPgluQuadricDrawStyle( 'u
+ GLenum \fIdraw\fP )
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\f2quad\fP\ \ 'u
+\f2quad\fP
+Specifies the quadrics object (created with \%\f3gluNewQuadric\fP).
+.TP
+\f2draw\fP
+Specifies the desired draw style. Valid values are
+\%\f3GLU_FILL\fP,
+\%\f3GLU_LINE\fP,
+\%\f3GLU_SILHOUETTE\fP, and
+\%\f3GLU_POINT\fP.
+.SH DESCRIPTION
+\%\f3gluQuadricDrawStyle\fP specifies the draw style for quadrics rendered with
+\f2quad\fP. The legal values are as follows:
+.TP 15
+\%\f3GLU_FILL\fP
+Quadrics are rendered with polygon primitives. The polygons
+are drawn in a counterclockwise fashion with respect to their
+normals (as defined with \%\f3gluQuadricOrientation\fP).
+.TP
+\%\f3GLU_LINE\fP
+Quadrics are rendered as a set of lines.
+.TP
+\%\f3GLU_SILHOUETTE\fP
+Quadrics are rendered as a set of lines, except that edges separating
+coplanar faces will not be drawn.
+.TP
+\%\f3GLU_POINT\fP
+Quadrics are rendered as a set of points.
+.SH SEE ALSO
+\%\f3gluNewQuadric(3G)\fP, \%\f3gluQuadricNormals(3G)\fP, \%\f3gluQuadricOrientation(3G)\fP,
+\%\f3gluQuadricTexture(3G)\fP
diff --git a/doc/gl-docs/GLU/quadricnormals.3gl b/doc/gl-docs/GLU/quadricnormals.3gl
new file mode 100644
index 000000000..9e09fd439
--- /dev/null
+++ b/doc/gl-docs/GLU/quadricnormals.3gl
@@ -0,0 +1,51 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 quadricno
+.ds Xs 40719 3 quadricnormals.gl
+.TH GLUQUADRICNORMALS 3G
+.SH NAME
+.B "gluQuadricNormals
+\- specify what kind of normals are desired for quadrics
+
+.SH C SPECIFICATION
+void \f3gluQuadricNormals\fP(
+GLUquadric* \fIquad\fP,
+.nf
+.ta \w'\f3void \fPgluQuadricNormals( 'u
+ GLenum \fInormal\fP )
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\fInormal\fP\ \ 'u
+\f2quad\fP
+Specifes the quadrics object (created with \%\f3gluNewQuadric\fP).
+.TP
+\f2normal\fP
+Specifies the desired type of normals. Valid values are
+\%\f3GLU_NONE\fP,
+\%\f3GLU_FLAT\fP, and
+\%\f3GLU_SMOOTH\fP.
+.SH DESCRIPTION
+\%\f3gluQuadricNormals\fP specifies what kind of normals are desired for quadrics rendered with
+\f2quad\fP. The legal values are as follows:
+.TP 15
+\%\f3GLU_NONE\fP
+No normals are generated.
+.TP
+\%\f3GLU_FLAT\fP
+One normal is generated for every facet of a quadric.
+.TP
+\%\f3GLU_SMOOTH\fP
+One normal is generated for every vertex of a quadric. This is the
+initial value.
+.SH SEE ALSO
+\%\f3gluNewQuadric(3G)\fP, \%\f3gluQuadricDrawStyle(3G)\fP, \%\f3gluQuadricOrientation(3G)\fP,
+\%\f3gluQuadricTexture(3G)\fP
diff --git a/doc/gl-docs/GLU/quadricorientation.3gl b/doc/gl-docs/GLU/quadricorientation.3gl
new file mode 100644
index 000000000..1de2ad220
--- /dev/null
+++ b/doc/gl-docs/GLU/quadricorientation.3gl
@@ -0,0 +1,49 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 quadricor
+.ds Xs 27503 3 quadricorientation.gl
+.TH GLUQUADRICORIENTATION 3G
+.SH NAME
+.B "gluQuadricOrientation
+\- specify inside/outside orientation for quadrics
+
+.SH C SPECIFICATION
+void \f3gluQuadricOrientation\fP(
+GLUquadric* \fIquad\fP,
+.nf
+.ta \w'\f3void \fPgluQuadricOrientation( 'u
+ GLenum \fIorientation\fP )
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\fIorientation\fP\ \ 'u
+\f2quad\fP
+Specifies the quadrics object (created with \%\f3gluNewQuadric\fP).
+.TP
+\f2orientation\fP
+Specifies the desired orientation. Valid values are
+\%\f3GLU_OUTSIDE\fP and
+\%\f3GLU_INSIDE\fP.
+.SH DESCRIPTION
+\%\f3gluQuadricOrientation\fP specifies what kind of orientation is desired for quadrics rendered
+with \f2quad\fP. The \f2orientation\fP values are as follows:
+.TP 15
+\%\f3GLU_OUTSIDE\fP
+Quadrics are drawn with normals pointing outward (the initial value).
+.TP
+\%\f3GLU_INSIDE\fP
+Quadrics are drawn with normals pointing inward.
+.P
+Note that the interpretation of \f2outward\fP and \f2inward\fP depends on the
+quadric being drawn.
+.SH SEE ALSO
+\%\f3gluNewQuadric(3G)\fP, \%\f3gluQuadricDrawStyle(3G)\fP, \%\f3gluQuadricNormals(3G)\fP,
+\%\f3gluQuadricTexture(3G)\fP
diff --git a/doc/gl-docs/GLU/quadrictexture.3gl b/doc/gl-docs/GLU/quadrictexture.3gl
new file mode 100644
index 000000000..3f5c77f51
--- /dev/null
+++ b/doc/gl-docs/GLU/quadrictexture.3gl
@@ -0,0 +1,45 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 quadricte
+.ds Xs 18441 3 quadrictexture.gl
+.TH GLUQUADRICTEXTURE 3G
+.SH NAME
+.B "gluQuadricTexture
+\- specify if texturing is desired for quadrics
+
+.SH C SPECIFICATION
+void \f3gluQuadricTexture\fP(
+GLUquadric* \fIquad\fP,
+.nf
+.ta \w'\f3void \fPgluQuadricTexture( 'u
+ GLboolean \fItexture\fP )
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\fItexture\fP\ \ 'u
+\f2quad\fP
+Specifies the quadrics object (created with \%\f3gluNewQuadric\fP).
+.TP
+\f2texture\fP
+Specifies a flag indicating if texture coordinates should be generated.
+.SH DESCRIPTION
+\%\f3gluQuadricTexture\fP specifies if texture coordinates should be generated
+for quadrics rendered with \f2quad\fP.
+If the value of \f2texture\fP is \%\f3GL_TRUE\fP, then texture coordinates
+are generated, and if \f2texture\fP is \%\f3GL_FALSE\fP, they are not. The
+initial value is \%\f3GL_FALSE\fP.
+.P
+The manner in which texture coordinates are generated depends
+upon the specific quadric rendered.
+.SH SEE ALSO
+\%\f3gluNewQuadric(3G)\fP, \%\f3gluQuadricDrawStyle(3G)\fP, \%\f3gluQuadricNormals(3G)\fP,
+\%\f3gluQuadricOrientation(3G)\fP
+
diff --git a/doc/gl-docs/GLU/scaleimage.3gl b/doc/gl-docs/GLU/scaleimage.3gl
new file mode 100644
index 000000000..e71e1ab00
--- /dev/null
+++ b/doc/gl-docs/GLU/scaleimage.3gl
@@ -0,0 +1,172 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 scaleimag
+.ds Xs 38480 7 scaleimage.gl
+.TH GLUSCALEIMAGE 3G
+.SH NAME
+.B "gluScaleImage
+\- scale an image to an arbitrary size
+
+.SH C SPECIFICATION
+GLint \f3gluScaleImage\fP(
+GLenum \fIformat\fP,
+.nf
+.ta \w'\f3GLint \fPgluScaleImage( 'u
+ GLsizei \fIwIn\fP,
+ GLsizei \fIhIn\fP,
+ GLenum \fItypeIn\fP,
+ const void \fI*dataIn\fP,
+ GLsizei \fIwOut\fP,
+ GLsizei \fIhOut\fP,
+ GLenum \fItypeOut\fP,
+ GLvoid* \fIdataOut\fP )
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\fItypeOut\fP\ \ 'u
+\f2format\fP
+Specifies the of the pixel data.
+The following symbolic values are valid:
+\%\f3GL_COLOR_INDEX\fP,
+\%\f3GL_STENCIL_INDEX\fP,
+\%\f3GL_DEPTH_COMPONENT\fP,
+\%\f3GL_RED\fP,
+\%\f3GL_GREEN\fP,
+\%\f3GL_BLUE\fP,
+\%\f3GL_ALPHA\fP,
+\%\f3GL_RGB\fP,
+\%\f3GL_RGBA\fP,
+\%\f3GL_BGR\fP,
+\%\f3GL_BGRA\fP,
+\%\f3GL_LUMINANCE\fP, and
+\%\f3GL_LUMINANCE_ALPHA\fP.
+.TP
+\f2wIn\fP, \f2hIn\fP
+Specify in pixels the width and height, respectively, of the source image.
+.TP
+\f2typeIn\fP
+Specifies the data type for \f2dataIn\fP. Must be one of
+\%\f3GL_UNSIGNED_BYTE\fP,
+\%\f3GL_BYTE\fP,
+\%\f3GL_BITMAP\fP,
+\%\f3GL_UNSIGNED_SHORT\fP,
+\%\f3GL_SHORT\fP,
+\%\f3GL_UNSIGNED_INT\fP,
+\%\f3GL_INT\fP,
+\%\f3GL_FLOAT\fP,
+\%\f3GL_UNSIGNED_BYTE_3_3_2\fP,
+\%\f3GL_UNSIGNED_BYTE_2_3_3_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_5_6_5\fP,
+\%\f3GL_UNSIGNED_SHORT_5_6_5_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_4_4_4_4\fP,
+\%\f3GL_UNSIGNED_SHORT_4_4_4_4_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_5_5_5_1\fP,
+\%\f3GL_UNSIGNED_SHORT_1_5_5_5_REV\fP,
+\%\f3GL_UNSIGNED_INT_8_8_8_8\fP,
+\%\f3GL_UNSIGNED_INT_8_8_8_8_REV\fP,
+\%\f3GL_UNSIGNED_INT_10_10_10_2\fP, and
+\%\f3GL_UNSIGNED_INT_2_10_10_10_REV\fP.
+.TP
+\f2dataIn\fP
+Specifies a pointer to the source image.
+.TP
+\f2wOut\fP, \f2hOut\fP
+Specify the width and height, respectively, in pixels of the destination image.
+.TP
+\f2typeOut\fP
+Specifies the data type for \f2dataOut\fP. Must be one of
+\%\f3GL_UNSIGNED_BYTE\fP,
+\%\f3GL_BYTE\fP,
+\%\f3GL_BITMAP\fP,
+\%\f3GL_UNSIGNED_SHORT\fP,
+\%\f3GL_SHORT\fP,
+\%\f3GL_UNSIGNED_INT\fP,
+\%\f3GL_INT\fP,
+\%\f3GL_FLOAT\fP,
+\%\f3GL_UNSIGNED_BYTE_3_3_2\fP,
+\%\f3GL_UNSIGNED_BYTE_2_3_3_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_5_6_5\fP,
+\%\f3GL_UNSIGNED_SHORT_5_6_5_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_4_4_4_4\fP,
+\%\f3GL_UNSIGNED_SHORT_4_4_4_4_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_5_5_5_1\fP,
+\%\f3GL_UNSIGNED_SHORT_1_5_5_5_REV\fP,
+\%\f3GL_UNSIGNED_INT_8_8_8_8\fP,
+\%\f3GL_UNSIGNED_INT_8_8_8_8_REV\fP,
+\%\f3GL_UNSIGNED_INT_10_10_10_2\fP, or
+\%\f3GL_UNSIGNED_INT_2_10_10_10_REV\fP.
+.TP
+\f2dataOut\fP
+Specifies a pointer to the destination image.
+.SH DESCRIPTION
+\%\f3gluScaleImage\fP scales a pixel image using the appropriate pixel store modes to
+unpack data from the source image and pack data into the destination image.
+.P
+When shrinking an image, \%\f3gluScaleImage\fP uses a box filter to sample the source image
+and create pixels for the destination image. When magnifying an image,
+the pixels from the source image are linearly interpolated to create the
+destination image.
+.P
+A return value of zero indicates success, otherwise a GLU error code is returned (see \%\f3gluErrorString\fP).
+.P
+See the \f3glReadPixels\fP reference page for a description of
+the acceptable values for the \f2format\fP, \f2typeIn\fP, and \f2typeOut\fP parameters.
+.SH NOTES
+Formats \%\f3GL_BGR\fP, and \%\f3GL_BGRA\fP, and types
+\%\f3GL_UNSIGNED_BYTE_3_3_2\fP,
+\%\f3GL_UNSIGNED_BYTE_2_3_3_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_5_6_5\fP,
+\%\f3GL_UNSIGNED_SHORT_5_6_5_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_4_4_4_4\fP,
+\%\f3GL_UNSIGNED_SHORT_4_4_4_4_REV\fP,
+\%\f3GL_UNSIGNED_SHORT_5_5_5_1\fP,
+\%\f3GL_UNSIGNED_SHORT_1_5_5_5_REV\fP,
+\%\f3GL_UNSIGNED_INT_8_8_8_8\fP,
+\%\f3GL_UNSIGNED_INT_8_8_8_8_REV\fP,
+\%\f3GL_UNSIGNED_INT_10_10_10_2\fP, and
+\%\f3GL_UNSIGNED_INT_2_10_10_10_REV\fP are only available if the GL version
+is 1.2 or greater.
+.SH ERRORS
+\%\f3GLU_INVALID_VALUE\fP is returned if \f2wIn\fP, \f2hIn\fP, \f2wOut\fP, or \f2hOut\fP
+is negative.
+.P
+\%\f3GLU_INVALID_ENUM\fP is returned if \f2format\fP, \f2typeIn\fP, or \f2typeOut\fP is not
+legal.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2typeIn\fP or \f2typeOut\fP is
+\%\f3GL_UNSIGNED_BYTE_3_3_2\fP or \%\f3GL_UNSIGNED_BYTE_2_3_3_REV\fP
+and \f2format\fP is not \%\f3GL_RGB\fP.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2typeIn\fP or \f2typeOut\fP is
+\%\f3GL_UNSIGNED_SHORT_5_6_5\fP or \%\f3GL_UNSIGNED_SHORT_5_6_5_REV\fP
+and \f2format\fP is not \%\f3GL_RGB\fP.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2typeIn\fP or \f2typeOut\fP is
+\%\f3GL_UNSIGNED_SHORT_4_4_4_4\fP or \%\f3GL_UNSIGNED_SHORT_4_4_4_4_REV\fP
+and \f2format\fP is neither \%\f3GL_RGBA\fP nor \%\f3GL_BGRA\fP.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2typeIn\fP or \f2typeOut\fP is
+\%\f3GL_UNSIGNED_SHORT_5_5_5_1\fP or \%\f3GL_UNSIGNED_SHORT_1_5_5_5_REV\fP
+and \f2format\fP is neither \%\f3GL_RGBA\fP nor \%\f3GL_BGRA\fP.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2typeIn\fP or \f2typeOut\fP is
+\%\f3GL_UNSIGNED_INT_8_8_8_8\fP or \%\f3GL_UNSIGNED_INT_8_8_8_8_REV\fP
+and \f2format\fP is neither \%\f3GL_RGBA\fP nor \%\f3GL_BGRA\fP.
+.P
+\%\f3GLU_INVALID_OPERATION\fP is returned if \f2typeIn\fP or \f2typeOut\fP is
+\%\f3GL_UNSIGNED_INT_10_10_10_2\fP or \%\f3GL_UNSIGNED_INT_2_10_10_10_REV\fP
+and \f2format\fP is neither \%\f3GL_RGBA\fP nor \%\f3GL_BGRA\fP.
+.SH SEE ALSO
+\f3glDrawPixels(3G)\fP, \f3glReadPixels(3G)\fP, \%\f3gluBuild1DMipmaps(3G)\fP, \%\f3gluBuild2DMipmaps(3G)\fP,
+\%\f3gluBuild3DMipmaps(3G)\fP,
+.BR
+\%\f3gluErrorString(3G)\fP
+
diff --git a/doc/gl-docs/GLU/sphere.3gl b/doc/gl-docs/GLU/sphere.3gl
new file mode 100644
index 000000000..229cee65c
--- /dev/null
+++ b/doc/gl-docs/GLU/sphere.3gl
@@ -0,0 +1,66 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 sphere.gl
+.ds Xs 36748 4 sphere.gl
+.TH GLUSPHERE 3G
+.SH NAME
+.B "gluSphere
+\- draw a sphere
+
+.SH C SPECIFICATION
+void \f3gluSphere\fP(
+GLUquadric* \fIquad\fP,
+.nf
+.ta \w'\f3void \fPgluSphere( 'u
+ GLdouble \fIradius\fP,
+ GLint \fIslices\fP,
+ GLint \fIstacks\fP )
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\fIradius\fP\ \ 'u
+\f2quad\fP
+Specifies the quadrics object (created with \%\f3gluNewQuadric\fP).
+.TP
+\f2radius\fP
+Specifies the radius of the sphere.
+.TP
+\f2slices\fP
+Specifies the number of subdivisions around the \f2z\fP axis
+(similar to lines of longitude).
+.TP
+\f2stacks\fP
+Specifies the number of subdivisions along the \f2z\fP axis
+(similar to lines of latitude).
+.SH DESCRIPTION
+\%\f3gluSphere\fP draws a sphere of the given radius centered around the origin. The
+sphere is subdivided around the \f2z\fP axis into slices and along the
+\f2z\fP axis
+into stacks (similar to lines of longitude and latitude).
+.P
+If the orientation is set to \%\f3GLU_OUTSIDE\fP
+(with \%\f3gluQuadricOrientation\fP), then any normals generated
+point away from the center of the sphere.
+Otherwise, they point toward the center of the sphere.
+.P
+If texturing is turned on (with \%\f3gluQuadricTexture\fP), then texture
+coordinates are
+generated so that \f2t\fP ranges from 0.0 at $ z ~=~ -^"radius" $ to 1.0 at
+$ z ~=~ "radius" $ (\f2t\fP increases linearly along longitudinal
+lines),
+and \f2s\fP ranges from 0.0 at the +\f2y\fP axis, to 0.25 at the
++\f2x\fP axis,
+to 0.5 at the \-\f2y\fP axis, to 0.75 at the \-\f2x\fP axis, and back to 1.0
+at the +\f2y\fP axis.
+.SH SEE ALSO
+\%\f3gluCylinder(3G)\fP, \%\f3gluDisk(3G)\fP, \%\f3gluNewQuadric(3G)\fP,
+\%\f3gluPartialDisk(3G)\fP, \%\f3gluQuadricOrientation(3G)\fP,
+\%\f3gluQuadricTexture(3G)\fP
diff --git a/doc/gl-docs/GLU/tessbegincontour.3gl b/doc/gl-docs/GLU/tessbegincontour.3gl
new file mode 100644
index 000000000..0f0b7f07a
--- /dev/null
+++ b/doc/gl-docs/GLU/tessbegincontour.3gl
@@ -0,0 +1,44 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 tessbegin
+.ds Xs 52199 3 tessbegincontour.gl
+.TH GLUTESSBEGINCONTOUR 3G
+.SH NAME
+.B "gluTessBeginContour, gluTessEndContour
+\- delimit a contour description
+
+.SH C SPECIFICATION
+void \f3gluTessBeginContour\fP(
+GLUtesselator* \fItess\fP )
+.nf
+.fi
+
+void \f3gluTessEndContour\fP(
+GLUtesselator* \fItess\fP )
+.nf
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\f2tess\fP\ \ 'u
+\f2tess\fP
+Specifies the tessellation object (created with \%\f3gluNewTess\fP).
+.SH DESCRIPTION
+\%\f3gluTessBeginContour\fP and \%\f3gluTessEndContour\fP delimit the definition of a
+polygon contour. Within each \%\f3gluTessBeginContour\fP/\%\f3gluTessEndContour\fP
+pair, there can be zero or more calls to \%\f3gluTessVertex\fP. The vertices
+specify a closed contour (the last vertex of each contour is automatically linked
+to the first). See the \%\f3gluTessVertex\fP reference page for more details.
+\%\f3gluTessBeginContour\fP can only be called between \%\f3gluTessBeginPolygon\fP and \%\f3gluTessEndPolygon\fP.
+.SH SEE ALSO
+\%\f3gluNewTess(3G)\fP, \%\f3gluTessBeginPolygon(3G)\fP, \%\f3gluTessVertex(3G)\fP,
+\%\f3gluTessCallback(3G)\fP,
+\%\f3gluTessProperty(3G)\fP, \%\f3gluTessNormal(3G)\fP,
+\%\f3gluTessEndPolygon\fP
diff --git a/doc/gl-docs/GLU/tessbeginpolygon.3gl b/doc/gl-docs/GLU/tessbeginpolygon.3gl
new file mode 100644
index 000000000..8adf8550b
--- /dev/null
+++ b/doc/gl-docs/GLU/tessbeginpolygon.3gl
@@ -0,0 +1,73 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 tessbegin
+.ds Xs 55678 4 tessbeginpolygon.gl
+.TH GLUTESSBEGINPOLYGON 3G
+.SH NAME
+.B "gluTessBeginPolygon
+\- delimit a polygon description
+
+.SH C SPECIFICATION
+void \f3gluTessBeginPolygon\fP(
+GLUtesselator* \fItess\fP,
+.nf
+.ta \w'\f3void \fPgluTessBeginPolygon( 'u
+ GLvoid* \fIdata\fP )
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\f2tess\fP\ \ 'u
+\f2tess\fP
+Specifies the tessellation object (created with \%\f3gluNewTess\fP).
+.TP
+\f2data\fP
+Specifies a pointer to user polygon data.
+.SH DESCRIPTION
+\%\f3gluTessBeginPolygon\fP and \%\f3gluTessEndPolygon\fP delimit the definition of a
+convex, concave or self-intersecting polygon. Within each \%\f3gluTessBeginPolygon\fP/\%\f3gluTessEndPolygon\fP
+pair, there must be one or more calls to \%\f3gluTessBeginContour\fP/\%\f3gluTessEndContour\fP.
+Within each contour, there are zero or more calls to \%\f3gluTessVertex\fP. The vertices
+specify a closed contour (the last vertex of each contour is automatically linked
+to the first). See the \%\f3gluTessVertex\fP, \%\f3gluTessBeginContour\fP, and
+\%\f3gluTessEndContour\fP reference pages for more details.
+.P
+\f2data\fP is a pointer to a user-defined data structure. If the appropriate callback(s)
+are specified (see \%\f3gluTessCallback\fP), then this pointer is returned to the
+callback function(s). Thus, it is a convenient way to store per-polygon information.
+.P
+Once \%\f3gluTessEndPolygon\fP is called, the polygon is tessellated, and the
+resulting triangles are described through callbacks.
+See \%\f3gluTessCallback\fP for descriptions of the callback functions.
+.SH EXAMPLE
+A quadrilateral with a triangular hole in it can be described as follows:
+.sp
+.Ex
+gluTessBeginPolygon(tobj, NULL);
+ gluTessBeginContour(tobj);
+ gluTessVertex(tobj, v1, v1);
+ gluTessVertex(tobj, v2, v2);
+ gluTessVertex(tobj, v3, v3);
+ gluTessVertex(tobj, v4, v4);
+ gluTessEndContour(tobj);
+.bp
+ gluTessBeginContour(tobj);
+ gluTessVertex(tobj, v5, v5);
+ gluTessVertex(tobj, v6, v6);
+ gluTessVertex(tobj, v7, v7);
+ gluTessEndContour(tobj);
+gluTessEndPolygon(tobj);
+.Ee
+.sp
+.SH SEE ALSO
+\%\f3gluNewTess(3G)\fP, \%\f3gluTessBeginContour(3G)\fP, \%\f3gluTessVertex(3G)\fP,
+\%\f3gluTessCallback(3G)\fP,
+\%\f3gluTessProperty(3G)\fP, \%\f3gluTessNormal(3G)\fP,
+\%\f3gluTessEndPolygon(3G)\fP
diff --git a/doc/gl-docs/GLU/tesscallback.3gl b/doc/gl-docs/GLU/tesscallback.3gl
new file mode 100644
index 000000000..67325f6d6
--- /dev/null
+++ b/doc/gl-docs/GLU/tesscallback.3gl
@@ -0,0 +1,294 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 tesscallb
+.ds Xs 14825 12 tesscallback.gl
+.TH GLUTESSCALLBACK 3G
+.SH NAME
+.B "gluTessCallback
+\- define a callback for a tessellation object
+
+.SH C SPECIFICATION
+void \f3gluTessCallback\fP(
+GLUtesselator* \fItess\fP,
+.nf
+.ta \w'\f3void \fPgluTessCallback( 'u
+ GLenum \fIwhich\fP,
+ _GLUfuncptr \fICallBackFunc\fP )
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\fICallBackFunc\fP\ \ 'u
+\f2tess\fP
+Specifies the tessellation object (created with \%\f3gluNewTess\fP).
+.TP
+\f2which\fP
+Specifies the callback being defined. The following values are valid:
+\%\f3GLU_TESS_BEGIN\fP,
+\%\f3GLU_TESS_BEGIN_DATA\fP,
+\%\f3GLU_TESS_EDGE_FLAG\fP,
+\%\f3GLU_TESS_EDGE_FLAG_DATA\fP,
+\%\f3GLU_TESS_VERTEX\fP,
+\%\f3GLU_TESS_VERTEX_DATA\fP,
+\%\f3GLU_TESS_END\fP,
+\%\f3GLU_TESS_END_DATA\fP,
+\%\f3GLU_TESS_COMBINE\fP,
+\%\f3GLU_TESS_COMBINE_DATA\fP,
+\%\f3GLU_TESS_ERROR\fP, and
+\%\f3GLU_TESS_ERROR_DATA\fP.
+.TP
+\f2CallBackFunc\fP
+Specifies the function to be called.
+.SH DESCRIPTION
+\%\f3gluTessCallback\fP is used to indicate a callback to be used by a tessellation object.
+If the specified callback is already defined, then it is replaced. If
+\f2CallBackFunc\fP is NULL, then the existing callback becomes undefined.
+.P
+These callbacks are used by the tessellation object to describe how a
+polygon specified by the user is broken into triangles. Note that there
+are two versions of each callback: one with user-specified polygon data
+and one without. If both versions of a particular callback are specified,
+then the callback with user-specified polygon data will be used. Note
+that the \f2polygon_data\fP parameter used by some of the functions is
+a copy of the pointer that was specified when
+\%\f3gluTessBeginPolygon\fP was called. The legal callbacks are as follows:
+.TP 10
+\%\f3GLU_TESS_BEGIN\fP
+The begin callback is invoked like \f3glBegin\fP to indicate the start of
+a (triangle) primitive. The function takes a single argument of type
+GLenum. If the \%\f3GLU_TESS_BOUNDARY_ONLY\fP property is set to
+\%\f3GL_FALSE\fP, then the argument is set to either
+\%\f3GL_TRIANGLE_FAN\fP, \%\f3GL_TRIANGLE_STRIP\fP, or \%\f3GL_TRIANGLES\fP. If
+the \%\f3GLU_TESS_BOUNDARY_ONLY\fP property is set to \%\f3GL_TRUE\fP,
+then the argument will be set to \%\f3GL_LINE_LOOP\fP. The function
+prototype for this callback is:
+.RS
+.Ex
+void begin ( GLenum type );
+.Ee
+.RE
+.TP
+\%\f3GLU_TESS_BEGIN_DATA\fP
+The same as the \%\f3GLU_TESS_BEGIN\fP callback except that it
+takes an additional pointer argument. This pointer is identical to the
+opaque pointer provided when
+\%\f3gluTessBeginPolygon\fP was called. The function prototype for this callback
+is:
+.RS
+.Ex
+void beginData ( GLenum type, void *polygon_data );
+.Ee
+.RE
+.TP
+\%\f3GLU_TESS_EDGE_FLAG\fP
+The edge flag callback is similar to \f3glEdgeFlag\fP. The function
+takes a single boolean flag that indicates which edges lie on the
+polygon boundary. If the flag is \%\f3GL_TRUE\fP, then each vertex
+that follows begins an edge that lies on the polygon boundary, that is,
+an edge that separates an interior region from an exterior one.
+If the flag is \%\f3GL_FALSE\fP, then each vertex that follows begins an edge
+that lies in the polygon interior. The edge flag callback (if defined) is
+invoked before the first vertex callback.
+.IP
+Since triangle fans and triangle strips do not support edge flags, the begin
+callback is not called with \%\f3GL_TRIANGLE_FAN\fP or \%\f3GL_TRIANGLE_STRIP\fP
+if a non-NULL edge flag callback is provided. (If the callback is
+initialized to NULL, there is no impact on performance). Instead, the fans and
+strips are converted to independent triangles. The function prototype
+for this callback is:
+.RS
+.Ex
+void edgeFlag ( GLboolean flag );
+.Ee
+.RE
+.TP
+\%\f3GLU_TESS_EDGE_FLAG_DATA\fP
+The same as the \%\f3GLU_TESS_EDGE_FLAG\fP callback except that it takes an additional pointer
+argument. This pointer is identical to the opaque pointer provided when
+\%\f3gluTessBeginPolygon\fP was called. The function prototype for this callback
+is:
+.RS
+.Ex
+void edgeFlagData ( GLboolean flag, void *polygon_data );
+.Ee
+.RE
+.TP
+\%\f3GLU_TESS_VERTEX\fP
+The vertex callback is invoked between the begin and end callbacks.
+It is similar to \f3glVertex\fP, and it defines the vertices of the triangles
+created by the tessellation process. The function
+takes a pointer as its only argument. This pointer is identical to
+the opaque pointer provided by the user when the vertex was described
+(see \%\f3gluTessVertex\fP). The function prototype for this callback is:
+.RS
+.Ex
+void vertex ( void *vertex_data );
+.Ee
+.RE
+.TP
+\%\f3GLU_TESS_VERTEX_DATA\fP
+The same as the \%\f3GLU_TESS_VERTEX\fP callback except that it takes an additional pointer
+argument. This pointer is identical to the opaque pointer provided when
+\%\f3gluTessBeginPolygon\fP was called. The function prototype for this callback
+is:
+.RS
+.Ex
+void vertexData ( void *vertex_data, void *polygon_data );
+.Ee
+.RE
+.TP
+\%\f3GLU_TESS_END\fP
+The end callback serves the same purpose as \f3glEnd\fP. It indicates the
+end of a primitive and it takes no arguments. The function prototype for this
+callback is:
+.RS
+.Ex
+void end ( void );
+.Ee
+.RE
+.TP
+\%\f3GLU_TESS_END_DATA\fP
+The same as the \%\f3GLU_TESS_END\fP callback except that it takes an additional pointer
+argument. This pointer is identical to the opaque pointer provided when
+\%\f3gluTessBeginPolygon\fP was called. The function prototype for this callback
+is:
+.RS
+.Ex
+void endData ( void *polygon_data);
+.Ee
+.RE
+.TP 10
+\%\f3GLU_TESS_COMBINE\fP
+The combine callback is called to create a new vertex when the tessellation
+detects an intersection, or wishes to merge features. The function takes
+four arguments: an array of three elements each of type GLdouble, an array
+of four pointers, an array of four elements each of type GLfloat, and a
+pointer to a pointer. The prototype is:
+.RS
+.Ex
+void combine( GLdouble coords[3], void *vertex_data[4],
+ GLfloat weight[4], void **outData );
+.Ee
+.RE
+.IP
+The vertex is defined as a linear combination of up to four existing vertices,
+stored in \f2vertex_data\fP. The coefficients of the linear
+combination are given by \f2weight\fP; these weights always add up to 1.
+All vertex pointers are valid even when some of the weights are 0.
+\f2coords\fP gives the location of the new vertex.
+.IP
+The user must allocate another vertex, interpolate parameters using
+\f2vertex_data\fP and \f2weight\fP, and return the new vertex pointer in
+\f2outData\fP. This handle is supplied during rendering callbacks.
+The user is responsible for freeing the memory some time after
+\%\f3gluTessEndPolygon\fP is called.
+.IP
+For example, if the polygon lies in an arbitrary plane in 3-space,
+and a color is associated with each vertex, the
+\%\f3GLU_TESS_COMBINE\fP callback might look like this:
+.RS
+.Ex
+void myCombine( GLdouble coords[3], VERTEX *d[4],
+ GLfloat w[4], VERTEX **dataOut )
+{
+ VERTEX *new = new_vertex();
+
+ new->x = coords[0];
+ new->y = coords[1];
+ new->z = coords[2];
+ new->r = w[0]*d[0]->r + w[1]*d[1]->r + w[2]*d[2]->r + w[3]*d[3]->r;
+ new->g = w[0]*d[0]->g + w[1]*d[1]->g + w[2]*d[2]->g + w[3]*d[3]->g;
+ new->b = w[0]*d[0]->b + w[1]*d[1]->b + w[2]*d[2]->b + w[3]*d[3]->b;
+ new->a = w[0]*d[0]->a + w[1]*d[1]->a + w[2]*d[2]->a + w[3]*d[3]->a;
+ *dataOut = new;
+}
+.Ee
+.RE
+.IP
+If the tessellation detects an intersection, then the \%\f3GLU_TESS_COMBINE\fP or
+\%\f3GLU_TESS_COMBINE_DATA\fP callback (see below) must be defined, and it must
+write a non-NULL pointer into \f2dataOut\fP. Otherwise the
+\%\f3GLU_TESS_NEED_COMBINE_CALLBACK\fP error occurs, and no
+output is generated.
+.TP
+\%\f3GLU_TESS_COMBINE_DATA\fP
+The same as the \%\f3GLU_TESS_COMBINE\fP callback except that it takes an additional pointer
+argument. This pointer is identical to the opaque pointer provided when
+\%\f3gluTessBeginPolygon\fP was called. The function prototype for this callback
+is:
+.RS
+.Ex
+void combineData ( GLdouble coords[3], void *vertex_data[4],
+ GLfloat weight[4], void **outData,
+ void *polygon_data );
+.Ee
+.RE
+.TP 10
+\%\f3GLU_TESS_ERROR\fP
+The error callback is called when an error is encountered. The one argument
+is of type GLenum; it indicates the specific error that occurred and will be
+set to one of \%\f3GLU_TESS_MISSING_BEGIN_POLYGON\fP, \%\f3GLU_TESS_MISSING_END_POLYGON\fP,
+\%\f3GLU_TESS_MISSING_BEGIN_CONTOUR\fP, \%\f3GLU_TESS_MISSING_END_CONTOUR\fP,
+\%\f3GLU_TESS_COORD_TOO_LARGE\fP, \%\f3GLU_TESS_NEED_COMBINE_CALLBACK\fP or
+\%\f3GLU_OUT_OF_MEMORY\fP. Character
+strings describing these errors can be retrieved with the
+\%\f3gluErrorString\fP call. The function prototype for this callback is:
+.RS
+.Ex
+void error ( GLenum errno );
+.Ee
+.RE
+.IP
+The GLU library will recover from the first four
+errors by inserting the missing call(s).
+\%\f3GLU_TESS_COORD_TOO_LARGE\fP indicates that some vertex coordinate exceeded
+the predefined constant \%\f3GLU_TESS_MAX_COORD\fP in absolute value, and
+that the value has been clamped. (Coordinate values must be small
+enough so that two can be multiplied together without overflow.)
+\%\f3GLU_TESS_NEED_COMBINE_CALLBACK\fP indicates that the tessellation
+detected an intersection between two edges in the input data, and the
+\%\f3GLU_TESS_COMBINE\fP or \%\f3GLU_TESS_COMBINE_DATA\fP callback was
+not provided. No output is generated. \%\f3GLU_OUT_OF_MEMORY\fP indicates
+that there is not enough memory so no output is generated.
+.TP
+\%\f3GLU_TESS_ERROR_DATA\fP
+The same as the \%\f3GLU_TESS_ERROR\fP callback except that it takes an additional pointer
+argument. This pointer is identical to the opaque pointer provided when
+\%\f3gluTessBeginPolygon\fP was called. The function prototype for this callback
+is:
+.RS
+.Ex
+void errorData ( GLenum errno, void *polygon_data );
+.Ee
+.RE
+.SH EXAMPLE
+Polygons tessellated can be rendered directly like this:
+.sp
+.Ex
+gluTessCallback(tobj, GLU_TESS_BEGIN, glBegin);
+gluTessCallback(tobj, GLU_TESS_VERTEX, glVertex3dv);
+gluTessCallback(tobj, GLU_TESS_END, glEnd);
+gluTessCallback(tobj, GLU_TESS_COMBINE, myCombine);
+gluTessBeginPolygon(tobj, NULL);
+ gluTessBeginContour(tobj);
+ gluTessVertex(tobj, v, v);
+ ...
+ gluTessEndContour(tobj);
+gluTessEndPolygon(tobj);
+.Ee
+.sp
+Typically, the tessellated polygon should be stored in a display list so that
+it does not need to be retessellated every time it is rendered.
+.SH SEE ALSO
+\f3glBegin(3G)\fP, \f3glEdgeFlag(3G)\fP, \f3glVertex(3G)\fP, \%\f3gluNewTess(3G)\fP,
+\%\f3gluErrorString(3G)\fP, \%\f3gluTessVertex(3G)\fP,
+\%\f3gluTessBeginPolygon(3G)\fP,
+\%\f3gluTessBeginContour(3G)\fP, \%\f3gluTessProperty(3G)\fP, \%\f3gluTessNormal(3G)\fP
+
diff --git a/doc/gl-docs/GLU/tessendpolygon.3gl b/doc/gl-docs/GLU/tessendpolygon.3gl
new file mode 100644
index 000000000..e334e401a
--- /dev/null
+++ b/doc/gl-docs/GLU/tessendpolygon.3gl
@@ -0,0 +1,68 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 tessendpo
+.ds Xs 16616 4 tessendpolygon.gl
+.TH GLUTESSENDPOLYGON 3G
+.SH NAME
+.B "gluTessEndPolygon
+\- delimit a polygon description
+
+.SH C SPECIFICATION
+void \f3gluTessEndPolygon\fP(
+GLUtesselator* \fItess\fP )
+.nf
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\f2tess\fP\ \ 'u
+\f2tess\fP
+Specifies the tessellation object (created with \%\f3gluNewTess\fP).
+.SH DESCRIPTION
+\%\f3gluTessBeginPolygon\fP and \%\f3gluTessEndPolygon\fP delimit the definition of a
+convex, concave or self-intersecting polygon. Within each \%\f3gluTessBeginPolygon\fP/\%\f3gluTessEndPolygon\fP
+pair, there must be one or more calls to \%\f3gluTessBeginContour\fP/\%\f3gluTessEndContour\fP.
+Within each contour, there are zero or more calls to \%\f3gluTessVertex\fP. The vertices
+specify a closed contour (the last vertex of each contour is automatically linked
+to the first). See the \%\f3gluTessVertex\fP, \%\f3gluTessBeginContour\fP and
+\%\f3gluTessEndContour\fP reference pages for more details.
+.P
+Once \%\f3gluTessEndPolygon\fP is called, the polygon is tessellated, and the
+resulting triangles are described through callbacks.
+See \%\f3gluTessCallback\fP for descriptions of the callback functions.
+.SH EXAMPLE
+A quadrilateral with a triangular hole in it can be described like this:
+.sp
+.Ex
+gluTessBeginPolygon(tobj, NULL);
+ gluTessBeginContour(tobj);
+ gluTessVertex(tobj, v1, v1);
+ gluTessVertex(tobj, v2, v2);
+ gluTessVertex(tobj, v3, v3);
+ gluTessVertex(tobj, v4, v4);
+ gluTessEndContour(tobj);
+ gluTessBeginContour(tobj);
+ gluTessVertex(tobj, v5, v5);
+ gluTessVertex(tobj, v6, v6);
+ gluTessVertex(tobj, v7, v7);
+ gluTessEndContour(tobj);
+gluTessEndPolygon(tobj);
+.Ee
+.bp
+In the above example the pointers, $v1$ through $v7$,
+should point to different
+addresses,
+since the values stored at these addresses will not be read by
+the tesselator until \%\f3gluTessEndPolygon\fP is called.
+.SH SEE ALSO
+\%\f3gluNewTess(3G)\fP, \%\f3gluTessBeginContour(3G)\fP, \%\f3gluTessVertex(3G)\fP,
+\%\f3gluTessCallback(3G)\fP,
+\%\f3gluTessProperty(3G)\fP, \%\f3gluTessNormal(3G)\fP,
+\%\f3gluTessBeginPolygon(3G)\fP
diff --git a/doc/gl-docs/GLU/tessnormal.3gl b/doc/gl-docs/GLU/tessnormal.3gl
new file mode 100644
index 000000000..4d98298b4
--- /dev/null
+++ b/doc/gl-docs/GLU/tessnormal.3gl
@@ -0,0 +1,67 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 tessnorma
+.ds Xs 47097 4 tessnormal.gl
+.TH GLUTESSNORMAL 3G
+.SH NAME
+.B "gluTessNormal
+\- specify a normal for a polygon
+
+.SH C SPECIFICATION
+void \f3gluTessNormal\fP(
+GLUtesselator* \fItess\fP,
+.nf
+.ta \w'\f3void \fPgluTessNormal( 'u
+ GLdouble \fIvalueX\fP,
+ GLdouble \fIvalueY\fP,
+ GLdouble \fIvalueZ\fP )
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\fIvalueX\fP\ \ 'u
+\f2tess\fP
+Specifies the tessellation object (created with \%\f3gluNewTess\fP).
+.TP
+\f2valueX\fP
+Specifies the first component of the normal.
+.TP
+\f2valueY\fP
+Specifies the second component of the normal.
+.TP
+\f2valueZ\fP
+Specifies the third component of the normal.
+.SH DESCRIPTION
+\%\f3gluTessNormal\fP describes a normal for a polygon that the program is defining.
+All input data will be projected onto a plane perpendicular to one of
+the three coordinate axes before tessellation and all output triangles
+will be oriented CCW with
+respect to the normal (CW orientation can be obtained by reversing the
+sign of the supplied normal). For example, if you know that all polygons
+lie in the x-y plane, call \%\f3gluTessNormal\fP(tess, 0.0, 0.0, 1.0)
+before rendering any polygons.
+.P
+If the supplied normal is (0.0, 0.0, 0.0) (the initial value), the normal is
+determined as follows. The direction of the normal, up to its sign, is
+found by fitting a plane to the vertices, without regard to how the
+vertices are connected. It is expected that the input data lies approximately
+in the plane; otherwise, projection perpendicular to one of the three
+coordinate axes may substantially change the geometry. The sign of the
+normal is chosen so that the sum of the signed areas of all input
+contours is nonnegative (where a CCW contour has positive area).
+.P
+The supplied normal persists until it is changed by another call to
+\%\f3gluTessNormal\fP.
+.SH SEE ALSO
+\%\f3gluTessBeginPolygon(3G)\fP,
+\%\f3gluTessEndPolygon(3G)\fP
+
+
+
diff --git a/doc/gl-docs/GLU/tessproperty.3gl b/doc/gl-docs/GLU/tessproperty.3gl
new file mode 100644
index 000000000..d5a34f9c4
--- /dev/null
+++ b/doc/gl-docs/GLU/tessproperty.3gl
@@ -0,0 +1,99 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 tessprope
+.ds Xs 36693 6 tessproperty.gl
+.TH GLUTESSPROPERTY 3G
+.SH NAME
+.B "gluTessProperty
+\- set a tessellation object property
+
+.SH C SPECIFICATION
+void \f3gluTessProperty\fP(
+GLUtesselator* \fItess\fP,
+.nf
+.ta \w'\f3void \fPgluTessProperty( 'u
+ GLenum \fIwhich\fP,
+ GLdouble \fIdata\fP )
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\fIwhich\fP\ \ 'u
+\f2tess\fP
+Specifies the tessellation object (created with \%\f3gluNewTess\fP).
+.TP
+\f2which\fP
+Specifies the property to be set. Valid values are
+\%\f3GLU_TESS_WINDING_RULE\fP,
+\%\f3GLU_TESS_BOUNDARY_ONLY\fP,
+\%\f3GLU_TESS_TOLERANCE\fP.
+.TP
+\f2data\fP
+Specifies the value of the indicated property.
+.SH DESCRIPTION
+\%\f3gluTessProperty\fP is used to control properties stored in a tessellation object. These
+properties affect the way that the polygons are interpreted and rendered.
+The legal values for \f2which\fP are as follows:
+.TP 15
+\%\f3GLU_TESS_WINDING_RULE\fP
+Determines which parts of the polygon are on the "interior".
+\f2data\fP may be set to one of \%\f3GLU_TESS_WINDING_ODD\fP,
+\%\f3GLU_TESS_WINDING_NONZERO\fP, \%\f3GLU_TESS_WINDING_POSITIVE\fP, or
+\%\f3GLU_TESS_WINDING_NEGATIVE\fP, or \%\f3GLU_TESS_WINDING_ABS_GEQ_TWO\fP.
+.IP
+To understand how the winding rule works, consider that the input
+contours partition the plane into regions. The winding rule determines which
+of these regions are inside the polygon.
+.IP
+For a single contour C, the winding number of a point x is simply the signed
+number of revolutions we make around x as we travel once around C
+(where CCW is positive). When there are several contours, the individual
+winding numbers are summed. This procedure associates a signed integer
+value with each point x in the plane. Note that the winding number is the
+same for all points in a single region.
+.bp
+.IP
+The winding rule classifies a region as "inside" if its winding number
+belongs to the chosen category (odd, nonzero, positive, negative, or
+absolute value of at least two). The previous GLU tessellator (prior to
+GLU 1.2) used the "odd" rule. The "nonzero" rule is another common way to
+define the interior. The other three rules are useful for polygon CSG
+operations.
+.TP
+\%\f3GLU_TESS_BOUNDARY_ONLY\fP
+Is a boolean value ("value" should be set
+to GL_TRUE or GL_FALSE). When set to GL_TRUE, a set of closed contours
+separating the polygon interior and exterior are returned instead of a
+tessellation. Exterior contours are oriented CCW with respect to the
+normal; interior contours are oriented CW. The \%\f3GLU_TESS_BEGIN\fP
+and \%\f3GLU_TESS_BEGIN_DATA\fP callbacks use the type GL_LINE_LOOP for
+each contour.
+.TP
+\%\f3GLU_TESS_TOLERANCE\fP
+Specifies a tolerance for merging features to reduce the size of the output.
+For example, two vertices that are very close to each other might be
+replaced by a single vertex. The tolerance is multiplied by the largest
+coordinate magnitude of any input vertex; this specifies the maximum
+distance that any feature can move as the result of a single merge
+operation. If a single feature takes part in several merge operations, the
+total distance moved could be larger.
+.IP
+Feature merging is completely optional; the tolerance is only a hint.
+The implementation is free to merge in some cases and not in others, or to
+never merge features at all. The initial tolerance is 0.
+.IP
+The current implementation merges vertices only if they are exactly
+coincident, regardless of the current tolerance. A vertex is spliced into
+an edge only if the implementation is unable to distinguish which side of
+the edge the vertex lies on. Two edges are merged only when both endpoints
+are identical.
+.SH SEE ALSO
+\%\f3gluGetTessProperty(3G)\fP,
+\%\f3gluNewTess(3G)\fP
diff --git a/doc/gl-docs/GLU/tessvertex.3gl b/doc/gl-docs/GLU/tessvertex.3gl
new file mode 100644
index 000000000..dcfce2801
--- /dev/null
+++ b/doc/gl-docs/GLU/tessvertex.3gl
@@ -0,0 +1,99 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 tessverte
+.ds Xs 55990 5 tessvertex.gl
+.TH GLUTESSVERTEX 3G
+.SH NAME
+.B "gluTessVertex
+\- specify a vertex on a polygon
+
+.SH C SPECIFICATION
+void \f3gluTessVertex\fP(
+GLUtesselator* \fItess\fP,
+.nf
+.ta \w'\f3void \fPgluTessVertex( 'u
+ GLdouble \fI*location\fP,
+ GLvoid* \fIdata\fP )
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\fIlocation\fP\ \ 'u
+\f2tess\fP
+Specifies the tessellation object (created with \%\f3gluNewTess\fP).
+.TP
+\f2location\fP
+Specifies the location of the vertex.
+.TP
+\f2data\fP
+Specifies an opaque pointer passed back to the program with the vertex callback
+(as specified by \%\f3gluTessCallback\fP).
+.SH DESCRIPTION
+\%\f3gluTessVertex\fP describes a vertex on a polygon that the program defines. Successive
+\%\f3gluTessVertex\fP calls describe a closed contour. For example,
+to describe a quadrilateral \%\f3gluTessVertex\fP should be called four times.
+\%\f3gluTessVertex\fP can only be called between \%\f3gluTessBeginContour\fP and
+\%\f3gluTessEndContour\fP.
+.P
+\f2data\fP normally points to a structure containing the vertex
+location, as well as other per-vertex attributes such as color and normal.
+This pointer is passed back to the user through the \%\f3GLU_TESS_VERTEX\fP
+or \%\f3GLU_TESS_VERTEX_DATA\fP callback after tessellation
+(see the \%\f3gluTessCallback\fP reference page).
+.SH EXAMPLE
+A quadrilateral with a triangular hole in it can be described as follows:
+.sp
+.Ex
+gluTessBeginPolygon(tobj, NULL);
+ gluTessBeginContour(tobj);
+ gluTessVertex(tobj, v1, v1);
+ gluTessVertex(tobj, v2, v2);
+ gluTessVertex(tobj, v3, v3);
+ gluTessVertex(tobj, v4, v4);
+ gluTessEndContour(tobj);
+ gluTessBeginContour(tobj);
+ gluTessVertex(tobj, v5, v5);
+ gluTessVertex(tobj, v6, v6);
+ gluTessVertex(tobj, v7, v7);
+ gluTessEndContour(tobj);
+gluTessEndPolygon(tobj);
+.Ee
+.sp
+.SH NOTES
+It is a common error to use a local variable for \f2location\fP or \f2data\fP and store
+values into it as part of a loop.
+For example:
+.Ex
+for (i = 0; i < NVERTICES; ++i) {
+ GLdouble data[3];
+ data[0] = vertex[i][0];
+ data[1] = vertex[i][1];
+ data[2] = vertex[i][2];
+ gluTessVertex(tobj, data, data);
+ }
+.Ee
+.P
+This doesn't work.
+Because the pointers specified by \f2location\fP and \f2data\fP might not be
+dereferenced until \%\f3gluTessEndPolygon\fP is executed,
+all the vertex coordinates but the very last set could be overwritten
+before tessellation begins.
+.P
+Two common symptoms of this problem are consists of a single point
+(when a local variable is used for \f2data\fP) and a
+\%\f3GLU_TESS_NEED_COMBINE_CALLBACK\fP error (when a local variable is
+used for \f2location\fP).
+.SH SEE ALSO
+\%\f3gluTessBeginPolygon(3G)\fP, \%\f3gluNewTess(3G)\fP, \%\f3gluTessBeginContour(3G)\fP,
+\%\f3gluTessCallback(3G)\fP,
+\%\f3gluTessProperty(3G)\fP, \%\f3gluTessNormal(3G)\fP,
+\%\f3gluTessEndPolygon(3G)\fP
+
+
diff --git a/doc/gl-docs/GLU/unproject.3gl b/doc/gl-docs/GLU/unproject.3gl
new file mode 100644
index 000000000..8dafdcf6d
--- /dev/null
+++ b/doc/gl-docs/GLU/unproject.3gl
@@ -0,0 +1,78 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 unproject
+.ds Xs 63442 4 unproject.gl
+.TH GLUUNPROJECT 3G
+.SH NAME
+.B "gluUnProject
+\- map window coordinates to object coordinates
+
+.SH C SPECIFICATION
+GLint \f3gluUnProject\fP(
+GLdouble \fIwinX\fP,
+.nf
+.ta \w'\f3GLint \fPgluUnProject( 'u
+ GLdouble \fIwinY\fP,
+ GLdouble \fIwinZ\fP,
+ const GLdouble \fI*model\fP,
+ const GLdouble \fI*proj\fP,
+ const GLint \fI*view\fP,
+ GLdouble* \fIobjX\fP,
+ GLdouble* \fIobjY\fP,
+ GLdouble* \fIobjZ\fP )
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\f2winX\fP\ \f2winY\fP\ \f2winZ\fP\ \ 'u
+\f2winX\fP, \f2winY\fP, \f2winZ\fP
+Specify the window coordinates to be mapped.
+.TP
+\f2model\fP
+Specifies the modelview matrix (as from a \f3glGetDoublev\fP call).
+.TP
+\f2proj\fP
+Specifies the projection matrix (as from a \f3glGetDoublev\fP call).
+.TP
+\f2view\fP
+Specifies the viewport (as from a \f3glGetIntegerv\fP call).
+.TP
+\f2objX\fP, \f2objY\fP, \f2objZ\fP
+Returns the computed object coordinates.
+.SH DESCRIPTION
+\%\f3gluUnProject\fP maps the specified window coordinates into object
+coordinates using \f2model\fP, \f2proj\fP, and \f2view\fP.
+The result is stored in \f2objX\fP, \f2objY\fP, and \f2objZ\fP. A return value of
+\%\f3GL_TRUE\fP indicates success; a return value of \%\f3GL_FALSE\fP
+indicates failure.
+.P
+To compute the coordinates (\f2objX\fP, \f2objY\fP, and \f2objZ\fP),
+\%\f3gluUnProject\fP multiplies the normalized device coordinates by the inverse of
+\f2model\fP*\f2proj\fP as follows:
+
+.P
+.ce
+.EQ
+left ( down 70 {cpile { ~"objX" above ~"objY" above ~"objZ"
+above ~W}} ~~ right ) ~=~ INV(P M)
+left ( down 140 {cpile {
+{ {2("winX" ~-~ "view"[0])} over {"view" [2]} ~-~ 1 }
+above
+{ {2("winY" ~-~ "view"[1])} over {"view"[3]} ~-~ 1 }
+above
+{ 2("winZ") ~-~ 1 }
+above
+1}} ~~ right )
+.EN
+.bp
+$INV()$ denotes matrix inversion.
+W is an unused variable, included for consistent matrix notation.
+.SH SEE ALSO
+\f3glGet(3G)\fP, \%\f3gluProject(3G)\fP
diff --git a/doc/gl-docs/GLU/unproject4.3gl b/doc/gl-docs/GLU/unproject4.3gl
new file mode 100644
index 000000000..72e755d2c
--- /dev/null
+++ b/doc/gl-docs/GLU/unproject4.3gl
@@ -0,0 +1,103 @@
+'\" e
+'\"! eqn | mmdoc
+'\"macro stdmacro
+.ds Vn Version 1.2
+.ds Dt 6 March 1997
+.ds Re Release 1.2.0
+.ds Dp May 02 11:53
+.ds Dm 37 unproject
+.ds Xs 13294 5 unproject4.gl
+.TH GLUUNPROJECT4 3G
+.SH NAME
+.B "gluUnProject4
+\- map window and clip coordinates to object coordinates
+
+.SH C SPECIFICATION
+GLint \f3gluUnProject4\fP(
+GLdouble \fIwinX\fP,
+.nf
+.ta \w'\f3GLint \fPgluUnProject4( 'u
+ GLdouble \fIwinY\fP,
+ GLdouble \fIwinZ\fP,
+ GLdouble \fIclipW\fP,
+ const GLdouble \fI*model\fP,
+ const GLdouble \fI*proj\fP,
+ const GLint \fI*view\fP,
+ GLdouble \fInear\fP,
+ GLdouble \fIfar\fP,
+ GLdouble* \fIobjX\fP,
+ GLdouble* \fIobjY\fP,
+ GLdouble* \fIobjZ\fP,
+ GLdouble* \fIobjW\fP )
+.fi
+
+.EQ
+delim $$
+.EN
+.SH PARAMETERS
+.TP \w'\f2winX\fP\ \f2winY\fP\ \f2winZ\fP\ \ 'u
+\f2winX\fP, \f2winY\fP, \f2winZ\fP
+Specify the window coordinates to be mapped.
+.TP
+\f2clipW\fP
+Specify the clip w coordinate to be mapped.
+.TP
+\f2model\fP
+Specifies the modelview matrix (as from a \f3glGetDoublev\fP call).
+.TP
+\f2proj\fP
+Specifies the projection matrix (as from a \f3glGetDoublev\fP call).
+.TP
+\f2view\fP
+Specifies the viewport (as from a \f3glGetIntegerv\fP call).
+.TP
+\f2near\fP, \f2far\fP
+Specifies the near and far planes (as from a \f3glGetDoublev\fP call).
+.TP
+\f2objX\fP, \f2objY\fP, \f2objZ\fP, \f2objW\fP
+Returns the computed object coordinates.
+.SH DESCRIPTION
+\%\f3gluUnProject4\fP maps the specified window coordinates \f2winX\fP, \f2winY\fP and \f2winZ\fP
+and its clip w coordinate \f2clipW\fP
+into object
+coordinates (\f2objX\fP, \f2objY\fP, \f2objZ\fP, \f2objW\fP)
+using \f2model\fP, \f2proj\fP and \f2view\fP. \f2clipW\fP can be other than
+1 as for vertices in \f3glFeedbackBuffer\fP when data type
+\%\f3GL_4D_COLOR_TEXTURE\fP is returned.
+This also handles the case
+where the \f2near\fP and \f2far\fP planes are different from the default,
+0 and 1, respectively.
+A return
+value of \%\f3GL_TRUE\fP indicates success; a return value of \%\f3GL_FALSE\fP
+indicates failure.
+.P
+To compute the coordinates (\f2objX\fP, \f2objY\fP, \f2objZ\fP and \f2objW\fP),
+\%\f3gluUnProject4\fP multiplies the normalized device coordinates by the inverse of
+\f2model\fP*\f2proj\fP as follows:
+
+.P
+.ce
+.EQ
+left ( down 70 {cpile { ~"objX" above ~"objY" above ~"objZ"
+above ~"objW"}} ~~ right ) ~=~ INV(P M)
+left ( down 140 {cpile {
+{ {2("winX" ~-~ "view"[0])} over {"view"[2]} ~-~ 1 }
+above
+{ {2("winY" ~-~ "view"[1])} over {"view"[3]} ~-~ 1 }
+above
+{ {2("winZ" ~-~ "near")} over {("far" ~-~ "near")} ~-~ 1 }
+above
+"clipW"}} ~~ right )
+.EN
+.sp
+$INV()$ denotes matrix inversion.
+.P
+\%\f3gluUnProject4\fP is equivalent to \%\f3gluUnProject\fP when \f2clipW\fP is 1, \f2near\fP is 0 and
+\f2far\fP is 1.
+.SH NOTES
+\%\f3gluUnProject4\fP is available only if the GLU version is 1.3 or greater.
+.SH SEE ALSO
+\f3glGet(3G)\fP,
+\f3glFeedbackBuffer(3G)\fP,
+\%\f3gluProject(3G)\fP,
+\%\f3gluUnProject(3G)\fP