OSDN Git Service

Initial revision
authorjtg <jtg>
Thu, 19 Aug 1999 00:55:39 +0000 (00:55 +0000)
committerjtg <jtg>
Thu, 19 Aug 1999 00:55:39 +0000 (00:55 +0000)
359 files changed:
Make-config [new file with mode: 0644]
Makefile.X11 [new file with mode: 0644]
include/GL/Makefile.am [new file with mode: 0644]
include/GL/amesa.h [new file with mode: 0644]
include/GL/foomesa.h [new file with mode: 0644]
include/GL/fxmesa.h [new file with mode: 0644]
include/GL/ggimesa.h [new file with mode: 0644]
include/GL/gl.h [new file with mode: 0644]
include/GL/gl_mangle.h [new file with mode: 0644]
include/GL/glu.h [new file with mode: 0644]
include/GL/glu_mangle.h [new file with mode: 0644]
include/GL/glut.h [new file with mode: 0644]
include/GL/glut_h.dja [new file with mode: 0644]
include/GL/glutf90.h [new file with mode: 0644]
include/GL/glx.h [new file with mode: 0644]
include/GL/glx_mangle.h [new file with mode: 0644]
include/GL/mglmesa.h [new file with mode: 0644]
include/GL/osmesa.h [new file with mode: 0644]
include/GL/svgamesa.h [new file with mode: 0644]
include/GL/wmesa.h [new file with mode: 0644]
include/GL/xmesa.h [new file with mode: 0644]
include/GL/xmesa_x.h [new file with mode: 0644]
include/GL/xmesa_xf86.h [new file with mode: 0644]
progs/beos/Makefile [new file with mode: 0644]
progs/beos/demo.cpp [new file with mode: 0644]
progs/beos/sample.cpp [new file with mode: 0644]
progs/demos/Makefile.BeOS-R4 [new file with mode: 0644]
progs/demos/Makefile.X11 [new file with mode: 0644]
progs/demos/Makefile.cygnus [new file with mode: 0644]
progs/demos/bounce.c [new file with mode: 0644]
progs/demos/clearspd.c [new file with mode: 0644]
progs/demos/descrip.mms [new file with mode: 0644]
progs/demos/drawpix.c [new file with mode: 0644]
progs/demos/gamma.c [new file with mode: 0644]
progs/demos/gears.c [new file with mode: 0644]
progs/demos/glinfo.c [new file with mode: 0644]
progs/demos/glutfx.c [new file with mode: 0644]
progs/demos/isosurf.c [new file with mode: 0644]
progs/demos/isosurf.dat [new file with mode: 0644]
progs/demos/morph3d.c [new file with mode: 0644]
progs/demos/multiarb.c [new file with mode: 0644]
progs/demos/osdemo.c [new file with mode: 0644]
progs/demos/paltex.c [new file with mode: 0644]
progs/demos/pointblast.c [new file with mode: 0644]
progs/demos/reflect.c [new file with mode: 0644]
progs/demos/renormal.c [new file with mode: 0644]
progs/demos/spectex.c [new file with mode: 0644]
progs/demos/stex3d.c [new file with mode: 0644]
progs/demos/tessdemo.c [new file with mode: 0644]
progs/demos/texcyl.c [new file with mode: 0644]
progs/demos/texobj.c [new file with mode: 0644]
progs/demos/trispd.c [new file with mode: 0644]
progs/demos/winpos.c [new file with mode: 0644]
progs/images/girl.rgb [new file with mode: 0644]
progs/images/reflect.rgb [new file with mode: 0644]
progs/images/tile.rgb [new file with mode: 0644]
progs/redbook/Imakefile [new file with mode: 0644]
progs/redbook/Makefile.BeOS-R4 [new file with mode: 0644]
progs/redbook/Makefile.X11 [new file with mode: 0644]
progs/redbook/Makefile.win [new file with mode: 0644]
progs/redbook/README [new file with mode: 0644]
progs/redbook/aaindex.c [new file with mode: 0644]
progs/redbook/aapoly.c [new file with mode: 0644]
progs/redbook/aargb.c [new file with mode: 0644]
progs/redbook/accanti.c [new file with mode: 0644]
progs/redbook/accpersp.c [new file with mode: 0644]
progs/redbook/alpha.c [new file with mode: 0644]
progs/redbook/alpha3D.c [new file with mode: 0644]
progs/redbook/anti.c [new file with mode: 0644]
progs/redbook/bezcurve.c [new file with mode: 0644]
progs/redbook/bezmesh.c [new file with mode: 0644]
progs/redbook/checker.c [new file with mode: 0644]
progs/redbook/clip.c [new file with mode: 0644]
progs/redbook/colormat.c [new file with mode: 0644]
progs/redbook/cube.c [new file with mode: 0644]
progs/redbook/depthcue.c [new file with mode: 0644]
progs/redbook/dof.c [new file with mode: 0644]
progs/redbook/double.c [new file with mode: 0644]
progs/redbook/drawf.c [new file with mode: 0644]
progs/redbook/feedback.c [new file with mode: 0644]
progs/redbook/fog.c [new file with mode: 0644]
progs/redbook/fogindex.c [new file with mode: 0644]
progs/redbook/font.c [new file with mode: 0644]
progs/redbook/hello.c [new file with mode: 0644]
progs/redbook/image.c [new file with mode: 0644]
progs/redbook/jitter.h [new file with mode: 0644]
progs/redbook/light.c [new file with mode: 0644]
progs/redbook/lines.c [new file with mode: 0644]
progs/redbook/list.c [new file with mode: 0644]
progs/redbook/material.c [new file with mode: 0644]
progs/redbook/mipmap.c [new file with mode: 0644]
progs/redbook/model.c [new file with mode: 0644]
progs/redbook/movelight.c [new file with mode: 0644]
progs/redbook/nurbs.c [new file with mode: 0644]
progs/redbook/pickdepth.c [new file with mode: 0644]
progs/redbook/picksquare.c [new file with mode: 0644]
progs/redbook/plane.c [new file with mode: 0644]
progs/redbook/planet.c [new file with mode: 0644]
progs/redbook/polyoff.c [new file with mode: 0644]
progs/redbook/polys.c [new file with mode: 0644]
progs/redbook/quadric.c [new file with mode: 0644]
progs/redbook/robot.c [new file with mode: 0644]
progs/redbook/sccolorlight.c [new file with mode: 0644]
progs/redbook/scene.c [new file with mode: 0644]
progs/redbook/scenebamb.c [new file with mode: 0644]
progs/redbook/sceneflat.c [new file with mode: 0644]
progs/redbook/select.c [new file with mode: 0644]
progs/redbook/smooth.c [new file with mode: 0644]
progs/redbook/stencil.c [new file with mode: 0644]
progs/redbook/stroke.c [new file with mode: 0644]
progs/redbook/surface.c [new file with mode: 0644]
progs/redbook/teaambient.c [new file with mode: 0644]
progs/redbook/teapots.c [new file with mode: 0644]
progs/redbook/tess.c [new file with mode: 0644]
progs/redbook/tesswind.c [new file with mode: 0644]
progs/redbook/texbind.c [new file with mode: 0644]
progs/redbook/texgen.c [new file with mode: 0644]
progs/redbook/texprox.c [new file with mode: 0644]
progs/redbook/texsub.c [new file with mode: 0644]
progs/redbook/texturesurf.c [new file with mode: 0644]
progs/redbook/torus.c [new file with mode: 0644]
progs/redbook/trim.c [new file with mode: 0644]
progs/redbook/unproject.c [new file with mode: 0644]
progs/redbook/varray.c [new file with mode: 0644]
progs/redbook/wrap.c [new file with mode: 0644]
progs/samples/Imakefile [new file with mode: 0644]
progs/samples/Makefile.BeOS-R4 [new file with mode: 0644]
progs/samples/Makefile.DJ [new file with mode: 0644]
progs/samples/Makefile.X11 [new file with mode: 0644]
progs/samples/Makefile.dja [new file with mode: 0644]
progs/samples/README [new file with mode: 0644]
progs/samples/accum.c [new file with mode: 0644]
progs/samples/bitmap1.c [new file with mode: 0644]
progs/samples/bitmap2.c [new file with mode: 0644]
progs/samples/blendeq.c [new file with mode: 0644]
progs/samples/blendxor.c [new file with mode: 0644]
progs/samples/copy.c [new file with mode: 0644]
progs/samples/cursor.c [new file with mode: 0644]
progs/samples/depth.c [new file with mode: 0644]
progs/samples/eval.c [new file with mode: 0644]
progs/samples/fog.c [new file with mode: 0644]
progs/samples/font.c [new file with mode: 0644]
progs/samples/line.c [new file with mode: 0644]
progs/samples/loadppm.c [new file with mode: 0644]
progs/samples/logo.c [new file with mode: 0644]
progs/samples/nurb.c [new file with mode: 0644]
progs/samples/oglinfo.c [new file with mode: 0644]
progs/samples/olympic.c [new file with mode: 0644]
progs/samples/overlay.c [new file with mode: 0644]
progs/samples/point.c [new file with mode: 0644]
progs/samples/prim.c [new file with mode: 0644]
progs/samples/quad.c [new file with mode: 0644]
progs/samples/rgbtoppm.c [new file with mode: 0644]
progs/samples/select.c [new file with mode: 0644]
progs/samples/shape.c [new file with mode: 0644]
progs/samples/sphere.c [new file with mode: 0644]
progs/samples/star.c [new file with mode: 0644]
progs/samples/stencil.c [new file with mode: 0644]
progs/samples/stretch.c [new file with mode: 0644]
progs/samples/texture.c [new file with mode: 0644]
progs/samples/tkmap.c [new file with mode: 0644]
progs/samples/tri.c [new file with mode: 0644]
progs/samples/wave.c [new file with mode: 0644]
progs/util/README [new file with mode: 0644]
progs/util/dumpstate.c [new file with mode: 0644]
progs/util/errcheck.c [new file with mode: 0644]
progs/util/glstate.c [new file with mode: 0644]
progs/util/glstate.h [new file with mode: 0644]
progs/util/glutskel.c [new file with mode: 0644]
progs/util/idproj.c [new file with mode: 0644]
progs/util/imagesgi.cpp [new file with mode: 0644]
progs/util/imagesgi.h [new file with mode: 0644]
progs/util/mwmborder.c [new file with mode: 0644]
progs/util/readtex.c [new file with mode: 0644]
progs/util/sampleMakefile [new file with mode: 0644]
progs/util/showbuffer.c [new file with mode: 0644]
progs/util/showbuffer.h [new file with mode: 0644]
progs/util/winpos.c [new file with mode: 0644]
progs/xdemos/Makefile.X11 [new file with mode: 0644]
progs/xdemos/descrip.mms [new file with mode: 0644]
progs/xdemos/glxdemo.c [new file with mode: 0644]
progs/xdemos/glxpixmap.c [new file with mode: 0644]
progs/xdemos/offset.c [new file with mode: 0644]
progs/xdemos/shape.c [new file with mode: 0644]
progs/xdemos/vgears.c [new file with mode: 0644]
progs/xdemos/vindex.c [new file with mode: 0644]
progs/xdemos/vtest.c [new file with mode: 0644]
progs/xdemos/xdemo.c [new file with mode: 0644]
progs/xdemos/xfont.c [new file with mode: 0644]
src/glu/mesa/Makefile.BeOS [new file with mode: 0644]
src/glu/mesa/Makefile.BeOS-R4 [new file with mode: 0644]
src/glu/mesa/Makefile.X11 [new file with mode: 0644]
src/glu/mesa/MesaGLU.def [new file with mode: 0644]
src/glu/mesa/README1 [new file with mode: 0644]
src/glu/mesa/README2 [new file with mode: 0644]
src/glu/mesa/all.h [new file with mode: 0644]
src/glu/mesa/descrip.mms [new file with mode: 0644]
src/glu/mesa/glu.c [new file with mode: 0644]
src/glu/mesa/gluP.h [new file with mode: 0644]
src/glu/mesa/mipmap.c [new file with mode: 0644]
src/glu/mesa/mms_depend [new file with mode: 0644]
src/glu/mesa/nurbs.c [new file with mode: 0644]
src/glu/mesa/nurbs.h [new file with mode: 0644]
src/glu/mesa/nurbscrv.c [new file with mode: 0644]
src/glu/mesa/nurbssrf.c [new file with mode: 0644]
src/glu/mesa/nurbsutl.c [new file with mode: 0644]
src/glu/mesa/polytest.c [new file with mode: 0644]
src/glu/mesa/project.c [new file with mode: 0644]
src/glu/mesa/quadric.c [new file with mode: 0644]
src/glu/mesa/tess.c [new file with mode: 0644]
src/glu/mesa/tess.h [new file with mode: 0644]
src/glu/mesa/tesselat.c [new file with mode: 0644]
src/glw/GLwDrawA.c [new file with mode: 0644]
src/glw/GLwDrawA.h [new file with mode: 0644]
src/glw/GLwDrawAP.h [new file with mode: 0644]
src/glw/GLwMDrawA.c [new file with mode: 0644]
src/glw/GLwMDrawA.h [new file with mode: 0644]
src/glw/GLwMDrawAP.h [new file with mode: 0644]
src/glw/Makefile [new file with mode: 0644]
src/glw/README [new file with mode: 0644]
src/glw/boilerplate.c [new file with mode: 0644]
src/glw/depend [new file with mode: 0644]
src/mesa/Makefile.X11 [new file with mode: 0644]
src/mesa/drivers/allegro/amesa.c [new file with mode: 0644]
src/mesa/drivers/allegro/direct.h [new file with mode: 0644]
src/mesa/drivers/allegro/generic.h [new file with mode: 0644]
src/mesa/drivers/beos/GLView.cpp [new file with mode: 0644]
src/mesa/drivers/d3d/D3DCAPS.CPP [new file with mode: 0644]
src/mesa/drivers/d3d/D3DHAL.H [new file with mode: 0644]
src/mesa/drivers/d3d/D3DInit.cpp [new file with mode: 0644]
src/mesa/drivers/d3d/D3DMESA.H [new file with mode: 0644]
src/mesa/drivers/d3d/D3DRaster.cpp [new file with mode: 0644]
src/mesa/drivers/d3d/D3DShared.h [new file with mode: 0644]
src/mesa/drivers/d3d/D3DTEXT.CPP [new file with mode: 0644]
src/mesa/drivers/d3d/D3DTextureMgr.cpp [new file with mode: 0644]
src/mesa/drivers/d3d/D3DTextureMgr.h [new file with mode: 0644]
src/mesa/drivers/d3d/D3DUTILS.CPP [new file with mode: 0644]
src/mesa/drivers/d3d/D3Dvbrender.c [new file with mode: 0644]
src/mesa/drivers/d3d/DDrawPROCS.c [new file with mode: 0644]
src/mesa/drivers/d3d/DEBUG.C [new file with mode: 0644]
src/mesa/drivers/d3d/DEBUG.H [new file with mode: 0644]
src/mesa/drivers/d3d/DbgEnv.bat [new file with mode: 0644]
src/mesa/drivers/d3d/MAKEFILE [new file with mode: 0644]
src/mesa/drivers/d3d/NULLProcs.h [new file with mode: 0644]
src/mesa/drivers/d3d/NullProcs.c [new file with mode: 0644]
src/mesa/drivers/d3d/OPENGL32.DEF [new file with mode: 0644]
src/mesa/drivers/d3d/WGL.C [new file with mode: 0644]
src/mesa/drivers/d3d/d3dText.h [new file with mode: 0644]
src/mesa/drivers/dos/DEPEND.DOS [new file with mode: 0644]
src/mesa/drivers/dos/dosmesa.c [new file with mode: 0644]
src/mesa/drivers/ggi/ggimesa.conf.in [new file with mode: 0644]
src/mesa/drivers/glide/fxapi.c [new file with mode: 0644]
src/mesa/drivers/glide/fxdd.c [new file with mode: 0644]
src/mesa/drivers/glide/fxddspan.c [new file with mode: 0644]
src/mesa/drivers/glide/fxddtex.c [new file with mode: 0644]
src/mesa/drivers/glide/fxdrv.h [new file with mode: 0644]
src/mesa/drivers/glide/fxglidew.c [new file with mode: 0644]
src/mesa/drivers/glide/fxglidew.h [new file with mode: 0644]
src/mesa/drivers/glide/fxopengl.def [new file with mode: 0644]
src/mesa/drivers/glide/fxsetup.c [new file with mode: 0644]
src/mesa/drivers/glide/fxtexman.c [new file with mode: 0644]
src/mesa/drivers/glide/fxwgl.c [new file with mode: 0644]
src/mesa/drivers/osmesa/osmesa.c [new file with mode: 0644]
src/mesa/drivers/svga/svgamesa.c [new file with mode: 0644]
src/mesa/drivers/windows/colors.h [new file with mode: 0644]
src/mesa/drivers/windows/mesa_extend.c [new file with mode: 0644]
src/mesa/drivers/windows/mesa_extend.h [new file with mode: 0644]
src/mesa/drivers/windows/stereo.h [new file with mode: 0644]
src/mesa/drivers/windows/wgl.c [new file with mode: 0644]
src/mesa/drivers/windows/wing32.def [new file with mode: 0644]
src/mesa/drivers/windows/wmesa.c [new file with mode: 0644]
src/mesa/drivers/windows/wmesaBackup.c [new file with mode: 0644]
src/mesa/drivers/windows/wmesaOld.c [new file with mode: 0644]
src/mesa/drivers/windows/wmesa_stereo.c [new file with mode: 0644]
src/mesa/drivers/windows/wmesadef.h [new file with mode: 0644]
src/mesa/drivers/x11/fakeglx.c [new file with mode: 0644]
src/mesa/drivers/x11/glxapi.c [new file with mode: 0644]
src/mesa/drivers/x11/realglx.c [new file with mode: 0644]
src/mesa/drivers/x11/realglx.h [new file with mode: 0644]
src/mesa/drivers/x11/xfonts.c [new file with mode: 0644]
src/mesa/drivers/x11/xmesaP.h [new file with mode: 0644]
src/mesa/main/Imakefile [new file with mode: 0644]
src/mesa/main/KNOWN_BUGS [new file with mode: 0644]
src/mesa/main/Makefile.DJ [new file with mode: 0644]
src/mesa/main/Makefile.X11 [new file with mode: 0644]
src/mesa/main/accum.c [new file with mode: 0644]
src/mesa/main/accum.h [new file with mode: 0644]
src/mesa/main/attrib.c [new file with mode: 0644]
src/mesa/main/attrib.h [new file with mode: 0644]
src/mesa/main/blend.c [new file with mode: 0644]
src/mesa/main/blend.h [new file with mode: 0644]
src/mesa/main/clip.c [new file with mode: 0644]
src/mesa/main/clip.h [new file with mode: 0644]
src/mesa/main/colortab.c [new file with mode: 0644]
src/mesa/main/colortab.h [new file with mode: 0644]
src/mesa/main/config.h [new file with mode: 0644]
src/mesa/main/context.c [new file with mode: 0644]
src/mesa/main/context.h [new file with mode: 0644]
src/mesa/main/dd.h [new file with mode: 0644]
src/mesa/main/depth.c [new file with mode: 0644]
src/mesa/main/depth.h [new file with mode: 0644]
src/mesa/main/descrip.mms [new file with mode: 0644]
src/mesa/main/dlist.c [new file with mode: 0644]
src/mesa/main/dlist.h [new file with mode: 0644]
src/mesa/main/drawpix.c [new file with mode: 0644]
src/mesa/main/drawpix.h [new file with mode: 0644]
src/mesa/main/enable.c [new file with mode: 0644]
src/mesa/main/enable.h [new file with mode: 0644]
src/mesa/main/enums.c [new file with mode: 0644]
src/mesa/main/enums.h [new file with mode: 0644]
src/mesa/main/eval.c [new file with mode: 0644]
src/mesa/main/eval.h [new file with mode: 0644]
src/mesa/main/extensions.c [new file with mode: 0644]
src/mesa/main/extensions.h [new file with mode: 0644]
src/mesa/main/feedback.c [new file with mode: 0644]
src/mesa/main/feedback.h [new file with mode: 0644]
src/mesa/main/fog.c [new file with mode: 0644]
src/mesa/main/fog.h [new file with mode: 0644]
src/mesa/main/get.c [new file with mode: 0644]
src/mesa/main/get.h [new file with mode: 0644]
src/mesa/main/hash.c [new file with mode: 0644]
src/mesa/main/hash.h [new file with mode: 0644]
src/mesa/main/image.c [new file with mode: 0644]
src/mesa/main/image.h [new file with mode: 0644]
src/mesa/main/light.c [new file with mode: 0644]
src/mesa/main/light.h [new file with mode: 0644]
src/mesa/main/lines.c [new file with mode: 0644]
src/mesa/main/lines.h [new file with mode: 0644]
src/mesa/main/macros.h [new file with mode: 0644]
src/mesa/main/matrix.c [new file with mode: 0644]
src/mesa/main/matrix.h [new file with mode: 0644]
src/mesa/main/mesa.conf [new file with mode: 0644]
src/mesa/main/pixel.c [new file with mode: 0644]
src/mesa/main/pixel.h [new file with mode: 0644]
src/mesa/main/points.c [new file with mode: 0644]
src/mesa/main/points.h [new file with mode: 0644]
src/mesa/main/polygon.c [new file with mode: 0644]
src/mesa/main/polygon.h [new file with mode: 0644]
src/mesa/main/rastpos.c [new file with mode: 0644]
src/mesa/main/rastpos.h [new file with mode: 0644]
src/mesa/main/simple_list.h [new file with mode: 0644]
src/mesa/main/stencil.c [new file with mode: 0644]
src/mesa/main/stencil.h [new file with mode: 0644]
src/mesa/main/teximage.c [new file with mode: 0644]
src/mesa/main/teximage.h [new file with mode: 0644]
src/mesa/main/texobj.c [new file with mode: 0644]
src/mesa/main/texobj.h [new file with mode: 0644]
src/mesa/main/texstate.c [new file with mode: 0644]
src/mesa/main/texstate.h [new file with mode: 0644]
src/mesa/main/varray.c [new file with mode: 0644]
src/mesa/main/varray.h [new file with mode: 0644]
src/mesa/x86/3dnow.c [new file with mode: 0644]
src/mesa/x86/3dnow.h [new file with mode: 0644]
src/mesa/x86/assyntax.h [new file with mode: 0644]
src/mesa/x86/common_x86.c [new file with mode: 0644]
src/mesa/x86/mmx.h [new file with mode: 0644]
src/mesa/x86/mmx_blend.S [new file with mode: 0644]
src/mesa/x86/x86.c [new file with mode: 0644]
src/mesa/x86/x86.h [new file with mode: 0644]

diff --git a/Make-config b/Make-config
new file mode 100644 (file)
index 0000000..b03e723
--- /dev/null
@@ -0,0 +1,1265 @@
+# $Id: Make-config,v 1.1 1999/08/19 00:55:39 jtg Exp $
+
+MAJOR=3
+MINOR=1
+VERSION=$(MAJOR).$(MINOR)
+
+# Mesa 3-D graphics library
+# 
+# Copyright (C) 1999  Brian Paul   All Rights Reserved.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+# 
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+# BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+# The following variables are passed to each Makefile:
+#
+# GL_LIB      the name of the Mesa "GL" library file (usually libMesaGL.a)
+# GLU_LIB     the name of the Mesa "GLU" library file (usually libMesaGLU.a)
+# GLUT_LIB    the name of the GLUT library file (usually libglut.a)
+# CC          the C compiler (usually cc or gcc)
+# CFLAGS      flags to C compiler (usually -O)
+# MAKELIB     the script or command to make a library file
+# XLIBS       libraries needed to link X apps (at least -lX11)
+#
+# Optionally, you can add definitions for the INCDIR and LIBDIR variables
+# which specify where to find the Mesa include files and where to put the
+# Mesa libraries.  The defaults are ../include and ../lib.  This use of
+# overriding makefile macros on the command line should work with most
+# variants of make.
+#
+# To enable profiling add -DPROFILE to the CFLAGS line.  Be sure to set the
+# MESA_PROFILE environment variable to enable printing of the profile report.
+#
+# If your system supports the X Shared Memory extension add -DSHM to the
+# CFLAGS line and add -lXext to the XLIBS line.
+#
+# Some compilers complain about const parameters.  Adding -DNO_CONST to the
+# CFLAGS line should silence suth warnings.
+#
+#
+# To add a new system configuration just follow the examples below and update
+# the top-level Makefile.
+
+
+
+aix:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = cc" \
+       "CFLAGS = -O -DAIXV3" \
+       "MAKELIB = ../bin/mklib.ar-ruv" \
+       "XLIBS = -lX11 -lXext -lXmu -lXi"
+
+aix-sl:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = cc" \
+       "CFLAGS = -O -DAIXV3" \
+       "MAKELIB = ../bin/mklib.aix" \
+       "XLIBS = -lX11 -lXext -lXmu -lXi"
+
+# Make-config additions for the Amiga 3000 UX
+# Carlyn Voss Iuzzolino   5/8/95: 
+# Modified gcc part as follows:
+# Needed to take out -pedantic because that makes gcc complain about 
+# ANSI-CC not allowing #ident in Amiga's /usr/include/*.h files.
+# Took out -O2 (unrecognized option for gcc on the Amiga).
+# Needs /usr/lib/libsocket.a file. 
+amix:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = cc" \
+       "CFLAGS =" \
+       "MAKELIB = ../bin/mklib.ar-ruv" \
+       "XLIBS = -lX11 -lsocket -lnsl "
+
+beos-r4:
+       $(MAKE) -f Makefile.BeOS-R4 targets \
+       "GL_LIB = libGL.so" \
+       "GLU_LIB = libGLU.so" \
+       "GLUT_LIB = libglut.so" \
+       "GLW_LIB = libGLw.so" \
+       "CC = g++" \
+       "CFLAGS = -O -DNO_CONST" \
+       "MAKELIB = ../bin/mklib.beos-r4" \
+       "XLIBS = "
+
+bsdos:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = gcc" \
+       "CFLAGS = -I/usr/X11/include -O2" \
+       "MAKELIB = ../bin/mklib.ar-ruv" \
+       "XLIBS = -L/usr/X11/lib -lX11 -lipc"
+
+bsdos4:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = gcc" \
+       "CFLAGS = -I/usr/X11/include -O2 -fPIC" \
+       "MAKELIB = ../bin/mklib.bsdos4" \
+       "XLIBS = -L/usr/X11/lib -lX11 -lipc"
+
+cygnus:
+       $(MAKE) -f Makefile.cygnus $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = gcc" \
+       "DLLTOOL = dlltool" \
+       "WING_DIR= /wing" \
+       "LD = ld" \
+       "CFLAGS = -I. -DWIN32 -D__WIN32__ -D_WINDOWS \
+               -O2 -funroll-loops \
+               -fexpensive-optimizations -fomit-frame-pointer -ffast-math \
+               -malign-loops=2 -malign-jumps=2 -malign-functions=2" \
+       "MAKELIB = ../bin/mklib.ar-ruv" \
+       "WLIBS = ../lib/wing32.a -lkernel32 -luser32 -lgdi32"
+
+cygnus-linux:
+       $(MAKE) -f Makefile.cygnus $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = gnuwin32gcc" \
+       "DLLTOOL = gnuwin32dlltool --as gnuwin32as" \
+       "LD = gnuwin32ld" \
+       "WING_DIR= /dos/wing" \
+       "CFLAGS = -I. -DWIN32 -D__WIN32__ -D_WINDOWS \
+               -O2 -funroll-loops \
+               -fexpensive-optimizations -fomit-frame-pointer -ffast-math \
+               -malign-loops=2 -malign-jumps=2 -malign-functions=2" \
+       "MAKELIB = ../bin/mklib.cygnus-linux" \
+       "WLIBS = ../lib/wing32.a -lkernel32 -luser32 -lgdi32"
+
+dgux:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = gcc" \
+       "CFLAGS = -O" \
+       "MAKELIB = ../bin/mklib.ar-ruv" \
+       "XLIBS = -lX11"
+
+freebsd:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = gcc" \
+       "CFLAGS = -O2 -fPIC -pedantic -I/usr/X11R6/include -DSHM -DHZ=100" \
+       "MAKELIB = ../bin/mklib.freebsd" \
+       "XLIBS = -L/usr/X11R6/lib -lXext -lXmu -lXi -lX11"
+
+freebsd-386:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = gcc" \
+       "CFLAGS = -O3 -ffast-math -fPIC -pedantic -I/usr/X11R6/include -DSHM -DHZ=100 -DUSE_X86_ASM -DFREEBSD" \
+       "MAKELIB = ../bin/mklib.freebsd" \
+       "XLIBS = -L/usr/X11R6/lib -lXext -lXmu -lXi -lX11" \
+       "ASM_SOURCES = X86/x86a.S X86/common_x86asm.S"
+
+gcc:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = gcc" \
+       "CFLAGS = -pedantic -O2" \
+       "MAKELIB = ../bin/mklib.ar-ruv" \
+       "XLIBS = -lX11"
+
+hpux9:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = cc" \
+       "CFLAGS = +O3 -Aa -D_HPUX_SOURCE -I/usr/include/X11R5 -DSHM" \
+       "MAKELIB = ../bin/mklib.ar-ruv" \
+       "XLIBS = -L/usr/lib/X11R5 -lXext -lXmu -lXi -lX11"
+
+hpux9-gcc:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = gcc" \
+       "CFLAGS = -ansi -O3 -D_HPUX_SOURCE -I/usr/include/X11R5 -DSHM" \
+       "MAKELIB = ../bin/mklib.ar-ruv" \
+       "XLIBS = -L/usr/lib/X11R5 -lXext -lXmu -lXi -lX11"
+
+hpux9-sl:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.sl" \
+       "GLU_LIB = libGLU.sl" \
+       "GLUT_LIB = libglut.sl" \
+       "GLW_LIB = libGLw.sl" \
+       "CC = cc" \
+       "CFLAGS = +z +O3 +Olibcalls +ESlit -Aa +Onolimit -D_HPUX_SOURCE -I/usr/include/X11R5 -DSHM" \
+       "MAKELIB = ../bin/mklib.hpux" \
+       "XLIBS = -L/usr/lib/X11R5 -s -Wl,+s,-B,nonfatal,-B,immediate -lXext -lXmu -lXi -lX11"
+
+hpux9-gcc-sl:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.sl" \
+       "GLU_LIB = libGLU.sl" \
+       "GLUT_LIB = libglut.sl" \
+       "GLW_LIB = libGLw.sl" \
+       "CC = gcc" \
+       "CFLAGS = -fPIC -ansi -O3 -D_HPUX_SOURCE -I/usr/include/X11R5 -DSHM" \
+       "MAKELIB = ../bin/mklib.hpux" \
+       "XLIBS = -L/usr/lib/X11R5 -lXext -lXmu -lXi -lX11"
+
+hpux10:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = cc" \
+       "CFLAGS = +O3 +DAportable -Aa -D_HPUX_SOURCE -I/usr/include/X11R6 -I/usr/contrib/X11R6/include -DSHM" \
+       "MAKELIB = ../bin/mklib.ar-ruv" \
+       "XLIBS = -L/usr/lib/X11R6 -L/usr/contrib/X11R6/lib -lXext -lXmu -lXi -lX11"
+
+hpux10-sl:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL" \
+       "GLU_LIB = libGLU" \
+       "GLUT_LIB = libglut" \
+       "GLW_LIB = libGLw.a" \
+       "CC = cc" \
+       "CFLAGS = +z -Ae +O2 +Onolimit +Oaggressive -D_HPUX_SOURCE -I/usr/include/X11R6 -I/usr/contrib/X11R6/include -DSHM" \
+       "MAKELIB = ../bin/mklib.hpux" \
+       "XLIBS = -L/usr/lib/X11R6 -L/usr/contrib/X11R6/lib -lXext -lXmu -lXi -lX11"
+
+hpux10-gcc:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = gcc" \
+       "CFLAGS = -ansi -O3 -D_HPUX_SOURCE -I/usr/include/X11R6 -I/usr/contrib/X11R6/include  -DSHM" \
+       "MAKELIB = ../bin/mklib.ar-ruv" \
+       "XLIBS = -L/usr/lib/X11R6 -L/usr/contrib/X11R6/lib -lXext -lXmu -lXi -lX11"
+
+hpux10-gcc-sl:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.sl" \
+       "GLU_LIB = libGLU.sl" \
+       "GLUT_LIB = libglut.sl" \
+       "GLW_LIB = libGLw.a" \
+       "CC = gcc" \
+       "CFLAGS = -fPIC -ansi -O3 -D_HPUX_SOURCE -I/usr/include/X11R6 -I/usr/contrib/X11R6/include -DSHM" \
+       "MAKELIB = ../bin/mklib.hpux" \
+       "XLIBS = -L/usr/lib/X11R6 -L/usr/contrib/X11R6/lib -lXext -lXmu -lXi -lX11"
+
+
+# For IRIX 4: don't use -fullwarn because it causes too much garbage
+irix4:
+       pmake $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = cc" \
+       "CFLAGS = -O2 -ansi -prototypes -DSHM" \
+       "MAKELIB = ../bin/mklib.ar-rcv" \
+       "XLIBS = -lXext -lXmu -lXi -lX11"
+
+# On IRIX 5.3 -sopt causes a problem in drawpixels.c so we don't use it
+irix5:
+       pmake $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = cc" \
+       "CFLAGS = -O2 -ansi -fullwarn -DSHM -DNO_CONST" \
+       "MAKELIB = ../bin/mklib.ar-rcv" \
+       "XLIBS = -lX11 -lXext -lXmu -lXi"
+
+# On IRIX 5.2+gcc
+irix5-gcc:
+       make $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = gcc" \
+       "CFLAGS = -O2 -pedantic -DSHM" \
+       "MAKELIB = ../bin/mklib.ar-rcv" \
+       "XLIBS = -lX11 -lXext -lXmu -lXi"
+
+# IRIX 5 using Dynamic Shared Objects (DSO)
+irix5-dso:
+       pmake $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.so" \
+       "GLU_LIB = libGLU.so" \
+       "GLUT_LIB = libglut.so" \
+       "GLW_LIB = libGLw.so" \
+       "CC = cc" \
+       "CFLAGS = -O2 -ansi -fullwarn -DSHM -DNO_CONST" \
+       "MAKELIB = ../bin/mklib.irix5" \
+       "XLIBS = -rpath ../lib -lX11 -lXmu -lXi"
+
+irix6-o32:
+       pmake $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = cc" \
+       "CFLAGS = -32 -mips2 -O2 -ansi -DSHM -DNO_CONST" \
+       "MAKELIB = ../bin/mklib.ar-rcv" \
+       "XLIBS = -lX11 -lXext -lXmu -lXi"
+
+irix6-o32-dso:
+       pmake $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.so" \
+       "GLU_LIB = libGLU.so" \
+       "GLUT_LIB = libglut.so" \
+       "GLW_LIB = libGLw.so" \
+       "CC = cc" \
+       "CFLAGS = -32 -mips2 -O2 -ansi -DSHM -DNO_CONST" \
+       "MAKELIB = ../bin/mklib.irix6-32" \
+       "XLIBS = -rpath ../lib -lX11 -lXext -lXmu -lXi"
+
+# For IRIX 6: -woff:
+#   1209 - controlling expression is constant
+irix6-n32:
+       pmake $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "LIBDIR = ../lib32" \
+       "CC = cc" \
+       "CFLAGS = -n32 -mips3 -O3 -ansi -woff 1209,1521" \
+       "MAKELIB = ../bin/mklib.ar-rcv" \
+       "XLIBS = -lX11 -lXext -lXmu -lXi"
+
+irix6-n32-dso:
+       pmake $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.so" \
+       "GLU_LIB = libGLU.so" \
+       "GLUT_LIB = libglut.so" \
+       "GLW_LIB = libGLw.a" \
+       "LIBDIR = ../lib32" \
+       "CC = cc" \
+       "CFLAGS = -n32 -mips3 -O3 -ansi -DSHM -woff 1185,1521" \
+       "MAKELIB = ../bin/mklib.irix6-n32" \
+       "XLIBS = -rpath ../lib32 -lX11 -lXmu -lXi -lfpe"
+
+irix6-gcc-n32-sl:
+       make $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.so" \
+       "GLU_LIB = libGLU.so" \
+       "GLUT_LIB = libglut.so" \
+       "GLW_LIB = libGLw.so" \
+       "LIBDIR = ../lib32" \
+       "CC = gcc" \
+       "CFLAGS = -mabi=n32 -mips3 -O3 -DSHM" \
+       "MAKELIB = ../bin/mklib.irix6-n32" \
+       "XLIBS = -rpath ../lib32 -lX11 -lXmu -lXi"
+
+# For IRIX 6-64: -woff:
+#   1068 - integer conversion resulted in a change of sign
+#   1069 - integer conversion resulted in truncation
+#   1174 - variable was declared but never referenced
+#   1185 - enumerated type mixed with another type
+#   1209 - controlling expression is constant
+#   1474 - declaring a void parameter list with a typedef is nonstandard
+#   1552 - variable was set but never used
+irix6-64:
+       pmake $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "LIBDIR = ../lib64" \
+       "CC = cc" \
+       "CFLAGS = -64 -O3 -ansi -woff 1068,1069,1174,1185,1209,1474,1552 -DSHM" \
+       "MAKELIB = ../bin/mklib.ar-rcv" \
+       "XLIBS = -lX11 -lXext -lXmu -lXi"
+
+irix6-64-dso:
+       pmake $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.so" \
+       "GLU_LIB = libGLU.so" \
+       "GLUT_LIB = libglut.so" \
+       "GLW_LIB = libGLw.so" \
+       "LIBDIR = ../lib64" \
+       "CC = cc" \
+       "CFLAGS = -64 -O3 -ansi -woff 1068,1069,1174,1185,1209,1474,1552 -DSHM" \
+       "MAKELIB = ../bin/mklib.irix6-64" \
+       "XLIBS = -rpath ../lib64 -lX11 -lXmu -lXi"
+
+# May want to try these CFLAGS for better performance under Linux and GCC:
+# -fPIC -O2 -ansi -pedantic -mieee-fp -DSHM -funroll-loops
+# -fexpensive-optimizations -fomit-frame-pointer -ffast-math
+# and  -malign-loops=2 -malign-jumps=2 -malign-functions=2 for Pentium
+
+linux:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = gcc" \
+       "CFLAGS = -O2 -funroll-loops -ansi -pedantic -ffast-math -D_SVID_SOURCE -D_BSD_SOURCE -DSHM -I/usr/X11R6/include" \
+       "MAKELIB = ../bin/mklib.ar-ruv" \
+       "XLIBS = -L/usr/X11R6/lib -lX11 -lXext -lXmu -lXt -lXi -lSM -lICE"
+
+# One Linux user reports having to use these XLIBS:
+#    -lMrm -lXmu -lXi -lXt -lXext -lXmu -lXi -lSM -lICE -lX11
+
+linux-elf:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.so" \
+       "GLU_LIB = libGLU.so" \
+       "GLUT_LIB = libglut.so" \
+       "GLW_LIB = libGLw.so" \
+       "CC = gcc" \
+       "CFLAGS = -O3 -ansi -pedantic -fPIC -ffast-math -D_SVID_SOURCE -D_BSD_SOURCE -DSHM -I/usr/X11R6/include" \
+       "MAKELIB = ../bin/mklib.linux" \
+       "XLIBS = -L/usr/X11R6/lib -lX11 -lXext -lXmu -lXt -lXi -lSM -lICE"
+
+linux-glide:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.so" \
+       "GLU_LIB = libGLU.so" \
+       "GLUT_LIB = libglut.so" \
+       "GLW_LIB = libGLw.so" \
+       "CC = gcc" \
+       "CFLAGS = -O3 -ansi -pedantic -fPIC -ffast-math -D_SVID_SOURCE -D_BSD_SOURCE -DSHM -DFX -I/usr/X11R6/include -I/usr/include/glide -I/usr/local/glide/include" \
+       "MAKELIB = ../bin/mklib.linux" \
+       "XLIBS = -L/usr/X11R6/lib -lX11 -lXext -lXmu -lXt -lXi -lSM -lICE -L/usr/local/glide/lib -lglide2x -lm"
+
+# Linux on Intel X86: assembly language optimizations
+linux-386:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = gcc" \
+       "CFLAGS = -O2 -funroll-loops -ansi -pedantic -ffast-math -D_SVID_SOURCE -D_BSD_SOURCE -DSHM -DUSE_X86_ASM -I/usr/X11R6/include" \
+       "MAKELIB = ../bin/mklib.ar-ruv" \
+       "XLIBS = -L/usr/X11R6/lib -lX11 -lXext -lXmu -lXt -lXi -lSM -lICE -lm" \
+       "ASM_SOURCES = X86/x86a.S X86/common_x86asm.S"
+
+linux-386-elf:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.so" \
+       "GLU_LIB = libGLU.so" \
+       "GLUT_LIB = libglut.so" \
+       "GLW_LIB = libGLw.so" \
+       "CC = gcc" \
+       "CFLAGS = -O3 -ansi -pedantic -fPIC -ffast-math -D_SVID_SOURCE -D_BSD_SOURCE -DSHM -DUSE_X86_ASM -I/usr/X11R6/include" \
+       "MAKELIB = ../bin/mklib.linux" \
+       "XLIBS = -L/usr/X11R6/lib -lX11 -lXext -lXmu -lXt -lXi -lSM -lICE -lm" \
+       "ASM_SOURCES = X86/x86a.S X86/common_x86asm.S"
+
+linux-386-glide:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.so" \
+       "GLU_LIB = libGLU.so" \
+       "GLUT_LIB = libglut.so" \
+       "GLW_LIB = libGLw.so" \
+       "CC = gcc" \
+       "CFLAGS = -O3 -ansi -pedantic -fPIC -ffast-math -D_SVID_SOURCE -D_BSD_SOURCE -DUSE_X86_ASM -DSHM -DFX -I/usr/X11R6/include -I/usr/include/glide -I/usr/local/glide/include" \
+       "MAKELIB = ../bin/mklib.linux" \
+       "XLIBS = -L/usr/X11R6/lib -lX11 -lXext -lXmu -lXt -lXi -lSM -lICE -L/usr/local/glide/lib -lglide2x -lm" \
+       "ASM_SOURCES = X86/x86a.S X86/common_x86asm.S"
+
+linux-386-glide-mits:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.so" \
+       "GLU_LIB = libGLU.so" \
+       "GLUT_LIB = libglut.so" \
+       "GLW_LIB = libGLw.so" \
+       "CC = gcc" \
+       "CFLAGS = -O3 -ansi -pedantic -fPIC -ffast-math -D_SVID_SOURCE -D_BSD_SOURCE -DSHM -DFX -D_REENTRANT -DMITS -DUSE_X86_ASM -I/usr/X11R6/include -I/usr/include/glide -I/usr/local/glide/include" \
+       "MAKELIB = ../bin/mklib.linux" \
+       "XLIBS = -L/usr/X11R6/lib -lX11 -lXext -lXmu -lXt -lXi -lSM -lICE -L/usr/local/glide/lib -lglide2x -lm -lpthread" \
+       "ASM_SOURCES = X86/x86a.S X86/common_x86asm.S"
+
+linux-386-opt-V2-glide:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.so" \
+       "GLU_LIB = libGLU.so" \
+       "GLUT_LIB = libglut.so" \
+       "GLW_LIB = libGLw.so" \
+       "CC = gcc" \
+       "CFLAGS = -O3 -m486 -fomit-frame-pointer -pipe -ansi -pedantic -ffast-math -fexpensive-optimizations -malign-loops=2 -malign-jumps=2 -malign-functions=2 -D_SVID_SOURCE -D_BSD_SOURCE -DSHM -DFX -DFX_V2 -DUSE_X86_ASM -I/usr/X11R6/include -I/usr/include/glide -I/usr/local/glide/include"\
+       "MAKELIB = ../bin/mklib.linux" \
+       "XLIBS = -L/usr/X11R6/lib -lX11 -lXext -lXmu -lXt -lXi -lSM -lICE -L/usr/local/glide/lib -lglide2x -lm -lpthread" \
+       "ASM_SOURCES = X86/x86a.S X86/common_x86asm.S"
+
+linux-386-opt-glide:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.so" \
+       "GLU_LIB = libGLU.so" \
+       "GLUT_LIB = libglut.so" \
+       "GLW_LIB = libGLw.so" \
+       "CC = gcc" \
+       "CFLAGS = -O3 -m486 -fomit-frame-pointer -pipe -ansi -pedantic -ffast-math -fexpensive-optimizations -malign-loops=2 -malign-jumps=2 -malign-functions=2 -D_SVID_SOURCE -D_BSD_SOURCE -DSHM -DFX -DUSE_X86_ASM -I/usr/X11R6/include -I/usr/include/glide -I/usr/local/glide/include" \
+       "MAKELIB = ../bin/mklib.linux" \
+       "XLIBS = -L/usr/X11R6/lib -lX11 -lXext -lXmu -lXt -lXi -lSM -lICE -L/usr/local/glide/lib -lglide2x -lm" \
+       "ASM_SOURCES = X86/x86a.S X86/common_x86asm.S"
+
+linux-3dnow:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.so" \
+       "GLU_LIB = libGLU.so" \
+       "GLUT_LIB = libglut.so" \
+       "GLW_LIB = libGLw.so" \
+       "CC = gcc -malign-loops=2 -malign-jumps=2 -malign-functions=2" \
+       "CFLAGS = -Wall -O3 -ansi -pedantic -fPIC -ffast-math -funroll-loops -fomit-frame-pointer -D_SVID_SOURCE -D_BSD_SOURCE -DSHM -DUSE_X86_ASM -DUSE_MMX_ASM -DUSE_3DNOW_ASM -I/usr/X11R6/include" \
+       "MAKELIB = ../bin/mklib.linux" \
+       "XLIBS = -L/usr/X11R6/lib -lX11 -lXext -lXmu -lXt -lXi -lSM -lICE" \
+       "ASM_SOURCES = X86/x86a.S X86/common_x86asm.S \
+       X86/mmx_blend.S \
+       X86/3dnow_xform_raw1.S X86/3dnow_xform_raw2.S \
+       X86/3dnow_xform_raw3.S X86/3dnow_xform_raw4.S \
+       X86/3dnow_xform_masked1.S X86/3dnow_xform_masked2.S \
+       X86/3dnow_xform_masked3.S X86/3dnow_xform_masked4.S \
+       X86/3dnow_norm_raw.S"
+
+linux-3dnow-glide:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.so" \
+       "GLU_LIB = libGLU.so" \
+       "GLUT_LIB = libglut.so" \
+       "GLW_LIB = libGLw.so" \
+       "CC = gcc -malign-loops=2 -malign-jumps=2 -malign-functions=2" \
+       "CFLAGS = -O3 -ansi -pedantic -fPIC -ffast-math -funroll-loops -fomit-frame-pointer -D_SVID_SOURCE -D_BSD_SOURCE -DUSE_X86_ASM -DUSE_MMX_ASM -DUSE_3DNOW_ASM -DSHM -DFX -I/usr/X11R6/include -I/usr/include/glide -I/usr/local/glide/include -I/usr/src/mesa-glx/src/FX/X86" \
+       "MAKELIB = ../bin/mklib.linux" \
+       "XLIBS = -L/usr/X11R6/lib -lX11 -lXext -lXmu -lXt -lXi -lSM -lICE -L/usr/local/glide/lib -lglide2x -lm" \
+       "ASM_SOURCES = X86/x86a.S X86/common_x86asm.S \
+       X86/mmx_blend.S \
+       X86/3dnow_xform_raw1.S X86/3dnow_xform_raw2.S \
+       X86/3dnow_xform_raw3.S X86/3dnow_xform_raw4.S \
+       X86/3dnow_xform_masked1.S X86/3dnow_xform_masked2.S \
+       X86/3dnow_xform_masked3.S X86/3dnow_xform_masked4.S \
+       X86/3dnow_norm_raw.S \
+       FX/X86/fx_3dnow_fastpath.S"
+
+
+# Contributed by Uwe_Maurer@t-online.de
+linux-ggi:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.so" \
+       "GLU_LIB = libGLU.so" \
+       "GLUT_LIB = libglut.so" \
+       "GLW_LIB = libGLw.a" \
+       "CC = gcc"  \
+       "CFLAGS = -O3 -fPIC -ffast-math -D_SVID_SOURCE -D_BSD_SOURCE -I/usr/X11R6/include -DSHM -DGGI -DCDECL=" \
+       "MAKELIB = ../bin/mklib.ggi" \
+       "XLIBS = -L/usr/X11R6/lib -lX11 -lXext -lXmu -lXt -lXi -lSM -lICE -lggi"
+
+# Contributed by Emmanuel marty core@ggi-project.org
+linux-386-ggi:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.so" \
+       "GLU_LIB = libGLU.so" \
+       "GLUT_LIB = libglut.so" \
+       "GLW_LIB = libGLw.so" \
+       "CC = gcc"  \
+       "CFLAGS = -O3 -fPIC -ffast-math -D_SVID_SOURCE -D_BSD_SOURCE -I/usr/X11R6/include -DSHM -DUSE_X86_ASM -DGGI -DCDECL=" \
+       "MAKELIB = ../bin/mklib.ggi" \
+       "XLIBS = -L/usr/X11R6/lib -lX11 -lXext -lXmu -lXt -lXi -lSM -lICE -lggi" \
+       "ASM_SOURCES = X86/x86a.S X86/common_x86asm.S"
+
+# Linux on Alpha (based on email from John Ferguson ferguson@viz.tamu.edu)
+linux-alpha:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.so" \
+       "GLW_LIB = libGLw.a" \
+       "CC = gcc" \
+       "CFLAGS = -O2 -mieee -pedantic -L/usr/X11R6/lib -D_XOPEN_SOURCE -DSHM" \
+       "MAKELIB = ../bin/mklib.ar-ruv" \
+       "XLIBS = -L/usr/X11R6/lib -lX11"
+
+linux-alpha-elf:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.so" \
+       "GLU_LIB = libGLU.so" \
+       "GLUT_LIB = libglut.so" \
+       "GLW_LIB = libGLw.so" \
+       "CC = gcc" \
+       "CFLAGS = -ansi -mieee -pedantic -fPIC -D_XOPEN_SOURCE -DSHM" \
+       "MAKELIB = ../bin/mklib.linux" \
+       "XLIBS = -L/usr/X11R6/lib -lX11 -lXext -lXmu -lXi"
+
+# Not tested, but should be okay on any RedHat-based linux for PowerPC machines
+# If your linux supports shared libraries, you might want to build with the 
+# the "linux-ppc-shared" entry instead
+# You might want to change the mcpu flag appropriately for your 
+# processor (601, 603, 604, etc.), it but doesn't make much difference
+linux-ppc:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = gcc" \
+       "CFLAGS = -O3 -mcpu=603 -ansi -pedantic -fsigned-char -ffast-math -funroll-loops -D_SVID_SOURCE -D_BSD_SOURCE -I/usr/X11R6/include -DSHM" \
+       "MAKELIB = ../bin/mklib.ar-ruv" \
+       "XLIBS = -L/usr/X11R6/lib -lX11 -lXext -lXmu -lXt -lXi -lSM -lICE"
+
+# -O5 and -fexpensive-optimizations causes a compiler crash for Linux PPC R4
+linux-ppc-so:
+       $(MAKE) targets \
+       "GL_LIB = libGL.so" \
+       "GLU_LIB = libGLU.so" \
+       "GLUT_LIB = libglut.so" \
+       "GLW_LIB = libGLw.so" \
+       "CC = gcc" \
+       "CFLAGS = -O3 -mcpu=603 -ansi -pedantic -fPIC -fsigned-char -ffast-math -funroll-loops -D_SVID_SOURCE -D_BSD_SOURCE -I/usr/X11R6/include -DSHM" \
+       "MAKELIB = ../bin/mklib.linux" \
+       "XLIBS = -L/usr/X11R6/lib -lX11 -lXext -lXmu -lXt -lXi -lSM -lICE"
+
+# Contributed by John Stone
+linux-386-pthread:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "CC = gcc" \
+       "CFLAGS = -O2 -funroll-loops -ansi -pedantic -ffast-math -D_SVID_SOURCE -D_BSD_SOURCE -I/usr/X11R\6/include -DSHM -DUSE_X86_ASM -D_REENTRANT -DTHREADS -DPTHREADS" \
+       "MAKELIB = ../bin/mklib.ar-ruv" \
+       "XLIBS = -L/usr/X11R6/lib -lX11 -lXext -lXmu -lXt -lXi -lSM -lICE -lpthread" \
+       "ASM_SOURCES = asm_386.S"
+
+# Contributed by John Gotts
+linux-386-pthread-shared:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.so" \
+       "GLU_LIB = libGLU.so" \
+       "GLUT_LIB = libglut.so" \
+       "CC = gcc" \
+       "CFLAGS = -O3 -fPIC -funroll-loops -ansi -pedantic -ffast-math -D_SVID_SOURCE -D_BSD_SOURCE -I/us\r/X11R6/include -DSHM -DUSE_X86_ASM -D_REENTRANT -DTHREADS -DPTHREADS" \
+       "MAKELIB = ../bin/mklib.linux" \
+       "XLIBS = -L/usr/X11R6/lib -lX11 -lXext -lXmu -lXt -lXi -lSM -lICE -lpthread" \
+       "ASM_SOURCES = asm_386.S"
+
+linux-sparc:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = gcc" \
+       "CFLAGS = -pedantic -funroll-loops -O3 -DSHM" \
+       "MAKELIB = ../bin/mklib.ar-ruv" \
+       "XLIBS = -L/usr/X11R6/lib -lX11 -lXext -lXt -lSM -lICE -lXmu -lXi"
+
+# Replace -mv8 with -mcypress, -msupersparc or -msparclite as appropriate.
+linux-sparc5-elf:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.so" \
+       "GLU_LIB = libGLU.so" \
+       "GLUT_LIB = libglut.so" \
+       "GLW_LIB = libGLw.so" \
+       "CC = gcc" \
+       "CFLAGS = -mv8 -O2 -ffast-math -ansi -pedantic -fPIC -D_SVID_SOURCE -D_BSD_SOURCE -I/usr/X11R6/include -DSHM" \
+       "MAKELIB = ../bin/mklib.linux" \
+       "XLIBS = -L/usr/X11R6/lib -lX11 -lXext -lXmu -lXt -lXi -lSM -lICE"
+
+# 32-bit Sparc ELF userland, on UltraSparc
+linux-sparc-ultra:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.so" \
+       "GLU_LIB = libGLU.so" \
+       "GLUT_LIB = libglut.so" \
+       "GLW_LIB = libGLw.so" \
+       "CC = gcc" \
+       "CFLAGS = -mv8 -O2 -mtune=ultrasparc -ansi -pedantic -fPIC -D_SVID_SOURCE -D_BSD_SOURCE -I/usr/X11R6/include -DSHM" \
+       "MAKELIB = ../bin/mklib.linux" \
+       "XLIBS = -L/usr/X11R6/lib -lX11 -lXext -lXmu -lXt -lXi -lSM -lICE"
+
+# May want to add these CFLAGS for better performance under LynxOS and GCC:
+# -fPIC -O2 -ansi -pedantic -mieee-fp -DSHM -funroll-loops
+# -fexpensive-optimizations -fomit-frame-pointer -ffast-math
+# and  -malign-loops=2 -malign-jumps=2 -malign-functions=2 for Pentium
+
+lynxos:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = gcc" \
+       "CFLAGS = -O2 -ansi -pedantic -funroll-loops -ffast-math -DSHM" \
+       "MAKELIB = ../bin/mklib.ar-ruv" \
+       "XLIBS = -L/usr/X11/lib -lXext -lXi -lXmu -lX11 -lbsd"
+
+machten-2.2:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = gcc" \
+       "CFLAGS = -DTENON -D__MACHTEN__ -fstrength-reduce -m68881 -O2" \
+       "MAKELIB = ../bin/mklib.ar-rcv" \
+       "XLIBS = -L/usr/lib/X11 -lX11"
+
+machten-4.0:
+       $(MAKE) targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = gcc" \
+       "CFLAGS = -DTENON -D__MACHTEN__ -fstrength-reduce -O2" \
+       "MAKELIB = ../bin/mklib.ar-rcv" \
+       "XLIBS = -L/usr/X11R5/lib -lX11"
+
+mklinux:
+       $(MAKE) targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = gcc" \
+       "CFLAGS = -pedantic -O2" \
+       "MAKELIB = ../bin/mklib.ar-ruv" \
+       "XLIBS = -lmoto -L/usr/X11/lib -lXmu -lX11"
+
+netbsd:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.so" \
+       "GLU_LIB = libGLU.so" \
+       "GLUT_LIB = libglut.so" \
+       "GLW_LIB = libGLw.so" \
+       "CC = gcc" \
+       "CFLAGS = -O2 -fPIC -DSHM -I/usr/X11R6/include -DHZ=100"  \
+       "MAKELIB = ../bin/mklib.netbsd" \
+       "XLIBS = -L/usr/X11R6/lib -lXext -lXmu -lXi -lX11"
+
+next:  
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "DRIVER_SOURCES = OSmesa/osmesa.c" \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "CC = ${MYCC}" \
+       "CFLAGS = -traditional-cpp -DOPENSTEP -O4" \
+       "MAKELIB = ../bin/mklib.ar-ruv"
+
+openbsd:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.so" \
+       "GLU_LIB = libGLU.so" \
+       "GLUT_LIB = libglut.so" \
+       "GLW_LIB = libGLw.so" \
+       "CC = cc" \
+       "CFLAGS = -O2 -fPIC -I/usr/X11R6/include -DSHM -DHZ=100" \
+       "MAKELIB = ../bin/mklib.openbsd" \
+       "XLIBS = -L/usr/X11R6/lib -lX11 -lXext -lXmu -lXi"
+
+openstep:      
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "DRIVER_SOURCES = OSmesa/osmesa.c" \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "CC = ${MYCC}" \
+       "CFLAGS = -traditional-cpp -DOPENSTEP -O4" \
+       "MAKELIB = ../bin/mklib.openstep"
+
+openstep-win32:        
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "DRIVER_SOURCES = OSmesa/osmesa.c" \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "CC = gcc" \
+       "CFLAGS = -DOPENSTEP -O4" \
+       "MAKELIB = ../bin/mklib.openstep"
+
+os2-x11:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB   = MesaGL.a" \
+       "GLU_LIB  = MesaGLU.a" \
+       "GLUT_LIB = glut.a" \
+       "GLW_LIB = GLw.a" \
+       "CC = gcc" \
+       "CFLAGS = -Zmt -O3 -m486 -funroll-loops -Wall -Wno-unused -ansi -pedantic -ffast-math -DUSE_X86_ASM -D_SVID_SOURCE -D_BSD_SOURCE -I$(X11ROOT)/XFree86/include" \
+       "MAKELIB = ..\\bin\\mklib-emx.cmd " \
+       "XLIBS = -Zmt -Zcrtdll -Zexe -L$(X11ROOT)/XFree86/lib -lXt -lX11" \
+       "ASM_SOURCES = X86/x86a.S X86/common_x86asm.S"
+
+osf1:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = cc" \
+       "CFLAGS = -O2 -std1 -ieee_with_no_inexact -DSHM -DNO_CONST" \
+       "MAKELIB = ../bin/mklib.ar-ruv" \
+       "XLIBS = -lX11 -lXext -lXmu -lXi"
+
+osf1-sl:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.so" \
+       "GLU_LIB = libGLU.so" \
+       "GLUT_LIB = libglut.so" \
+       "GLW_LIB = libGLw.so" \
+       "CC = cc" \
+       "CFLAGS = -O2 -std1 -ieee_with_no_inexact -DSHM -DNO_CONST" \
+       "MAKELIB = ../bin/mklib.osf1" \
+       "XLIBS = -lX11 -lXext -lXmu -lXi"
+
+pgi-cygnus:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = pgcc" \
+       "CFLAGS = -fast -cyglibs -Munix -I. -DWIN32 -D__WIN32__ -D_WINDOWS " \
+       "MAKELIB = ../bin/mklib.ar-ruv" \
+       "XLIBS = -lX11"
+
+pgi-mingw32:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = pgcc" \
+       "CFLAGS = -fast -msvcrt -Munix -I. -DWIN32 -D__WIN32__ -D_WINDOWS " \
+       "MAKELIB = ../bin/mklib.ar-ruv" \
+       "XLIBS = -lX11"
+
+# QNX V4 & Watcom Compiler
+qnx:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = cc" \
+       "CFLAGS = -O" \
+       "MAKELIB = ../bin/mklib.qnx" \
+       "XLIBS = -L/usr/X11/lib -lX11"
+
+sco:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = gcc" \
+       "CFLAGS = -pedantic -O2 -mieee-fp" \
+       "MAKELIB = ../bin/mklib.ar-ruv" \
+       "XLIBS = -L/usr/X11/lib -lX11"
+
+solaris-x86:
+       $(MAKE) targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = cc" \
+       "CFLAGS = -Xa -xO3 -xpentium -KPIC -I/usr/openwin/include -DSHM" \
+       "MAKELIB = ../bin/mklib.solaris" \
+       "XLIBS = -L/usr/openwin/lib -R/usr/openwin/lib -lX11 -lXext -lXmu -lXi"
+
+solaris-x86-gcc:
+       $(MAKE) targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = gcc" \
+       "CFLAGS = -O3 -m486 -fPIC -I/usr/openwin/include -DSHM" \
+       "MAKELIB = ../bin/mklib.solaris" \
+       "XLIBS = -L/usr/openwin/lib -R/usr/openwin/lib -lX11 -lXext -lXmu -lXi"
+
+sunos4:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = acc" \
+       "CFLAGS = -O -DSHM -DSUNOS4" \
+       "MAKELIB = ../bin/mklib.ar-ruv" \
+       "XLIBS = -lX11 -lXext -lXmu -lXi"
+
+sunos4-sl:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.so" \
+       "GLU_LIB = libGLU.so" \
+       "GLUT_LIB = libglut.so" \
+       "GLW_LIB = libGLw.so" \
+       "CC = acc" \
+       "CFLAGS = -Kpic -O -I/usr/include/X11R5 -DSHM -DSUNOS4" \
+       "MAKELIB = ld -assert pure-text -o" \
+       "XLIBS = -L/usr/lib/X11R5 -lX11 -lXext -lXmu -lXi"
+
+sunos4-gcc:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = gcc" \
+       "CFLAGS = -O3 -DSHM -DSUNOS4 -I/usr/openwin/include" \
+       "MAKELIB = ../bin/mklib.ar-ruv" \
+       "XLIBS = -L/usr/openwin/lib -lX11 -lXext -lXmu -lXi"
+
+sunos4-gcc-sl:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.so.$(VERSION)" \
+       "GLU_LIB = libGLU.so.$(VERSION)" \
+       "GLUT_LIB = libglut.so" \
+       "GLW_LIB = libGLw.so" \
+       "CC = gcc" \
+       "CFLAGS = -fPIC -O3 -I/usr/openwin/include -I/usr/include/X11R5 -I/usr/include/X11R5 -DSHM -DSUNOS4 -DSOLARIS_2_4_BUG" \
+       "MAKELIB = ../bin/mklib.sunos4" \
+       "XLIBS = -L/usr/openwin/lib -lX11 -lXext -lXmu -lXi"
+
+sunos4-gcc-x11r6-sl:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.so.$(VERSION)" \
+       "GLU_LIB = libGLU.so.$(VERSION)" \
+       "GLUT_LIB = libglut.so" \
+       "GLW_LIB = libGLw.so" \
+       "CC = gcc" \
+       "CFLAGS = -fPIC -O3 -I/usr/X11R6.3/include -DSHM -DSUNOS4 -DSOLARIS_2_4_BUG" \
+       "MAKELIB = ../bin/mklib.sunos4" \
+       "XLIBS = -L/usr/X11R6.3/lib/X11 -lX11 -lXext -lXmu -lXi"
+
+sunos5:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = cc" \
+       "CFLAGS = -Xa -fast -xO4 -native -I/usr/openwin/include -I/usr/dt/include -DSHM -DSOLARIS_2_4_BUG" \
+       "MAKELIB = ../bin/mklib.ar-ruv" \
+       "XLIBS = -L/usr/openwin/lib -L/usr/dt/lib -R/usr/openwin/lib -lX11 -lXext -lXmu -lXi"
+
+sunos5-sl:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.so" \
+       "GLU_LIB = libGLU.so" \
+       "GLUT_LIB = libglut.so" \
+       "GLW_LIB = libGLw.so" \
+       "CC = cc" \
+       "CFLAGS = -KPIC -Xa -O -I/usr/openwin/include -I/usr/dt/include -DSHM -DSOLARIS_2_4_BUG" \
+       "MAKELIB = ../bin/mklib.sunos5" \
+       "XLIBS = -L/usr/openwin/lib -L/usr/dt/lib -R/usr/openwin/lib -lX11 -lXext -lXmu -lXi"
+
+sunos5-ultra:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = cc" \
+       "CFLAGS = -Xa -fast -xO5 -xtarget=ultra -I/usr/openwin/include -I/usr/dt/include -DSHM -DSOLARIS_2_4_BUG" \
+       "MAKELIB = ../bin/mklib.ar-ruv" \
+       "XLIBS = -L/usr/openwin/lib -L/usr/dt/lib -R/usr/openwin/lib -lX11 -lXext -lXmu -lXi"
+
+sunos5-ultra-sl:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.so" \
+       "GLU_LIB = libGLU.so" \
+       "GLUT_LIB = libglut.so" \
+       "GLW_LIB = libGLw.so" \
+       "CC = cc" \
+       "CFLAGS = -KPIC -Xa -fast -xO5 -xtarget=ultra -I/usr/openwin/include -I/usr/dt/include -DSHM -DSOLARIS_2_4_BUG" \
+       "MAKELIB = ../bin/mklib.sunos5" \
+       "XLIBS = -L/usr/openwin/lib -L/usr/dt/lib -R/usr/openwin/lib -lX11 -lXext -lXmu -lXi"
+
+sunos5-gcc:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = gcc" \
+       "CFLAGS = -O3 -I/usr/openwin/include -DSHM -DSOLARIS_2_4_BUG" \
+       "MAKELIB = ../bin/mklib.ar-ruv" \
+       "XLIBS = -L/usr/openwin/lib -lX11 -lXext -lXmu -lXi"
+
+sunos5-gcc-sl:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.so" \
+       "GLU_LIB = libGLU.so" \
+       "GLUT_LIB = libglut.so" \
+       "GLW_LIB = libGLw.so" \
+       "CC = gcc" \
+       "CFLAGS = -fPIC -O3 -I/usr/openwin/include -DSHM -DSOLARIS_2_4_BUG" \
+       "MAKELIB = ../bin/mklib.sunos5" \
+       "XLIBS = -L/usr/openwin/lib -R/usr/openwin/lib -lX11 -lXext -lXmu -lXi"
+
+sunos5-x11r6-gcc-sl:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.so" \
+       "GLU_LIB = libGLU.so" \
+       "GLUT_LIB = libglut.so" \
+       "GLW_LIB = libGLw.so" \
+       "CC = gcc" \
+       "CFLAGS = -fPIC -O3 -DSHM -DSOLARIS_2_4_BUG" \
+       "MAKELIB = ../bin/mklib.sunos5" \
+       "XLIBS = -lSM -lICE -lX11 -lXext -lXmu -lXi -lnsl -lsocket"
+
+# Contributed by John Stone
+sunos5-pthread:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "CC = cc" \
+       "CFLAGS = -mt -Xa -fast -xO4 -native -I/usr/openwin/include -I/usr/dt/include -DSHM -DSOLARIS_2_4\_BUG -DTHREADS -DPTHREADS" \
+       "MAKELIB = ../bin/mklib.ar-ruv" \
+       "XLIBS = -L/usr/openwin/lib -L/usr/dt/lib -R/usr/openwin/lib -lX11 -lXext -lXmu -lXi -lpthread"
+
+# Contributed by John Stone
+sunos5-thread:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "CC = cc" \
+       "CFLAGS = -mt -Xa -fast -xO4 -native -I/usr/openwin/include -I/usr/dt/include -DSHM -DSOLARIS_2_4\_BUG -DTHREADS -DSOLARIS_THREADS" \
+       "MAKELIB = ../bin/mklib.ar-ruv" \
+       "XLIBS = -L/usr/openwin/lib -L/usr/dt/lib -R/usr/openwin/lib -lX11 -lXext -lXmu -lXi -lthread"
+
+# Contributed by John Stone
+sunos5-gcc-thread:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "CC = gcc" \
+       "CFLAGS = -O3 -I/usr/openwin/include -DSHM -DSOLARIS_2_4_BUG -D_REENTRANT -DTHREADS -DSOLARIS_THR\EADS" \
+       "MAKELIB = ../bin/mklib.ar-ruv" \
+       "XLIBS = -L/usr/openwin/lib -lX11 -lXext -lXmu -lXi -lthread"
+
+# Contributed by John Stone
+sunos5-gcc-pthread:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "CC = gcc" \
+       "CFLAGS = -O3 -I/usr/openwin/include -DSHM -DSOLARIS_2_4_BUG -D_REENTRANT -DTHREADS -DPTHREADS" \
+       "MAKELIB = ../bin/mklib.ar-ruv" \
+       "XLIBS = -L/usr/openwin/lib -lX11 -lXext -lXmu -lXi -lpthread"
+
+# from Ron Metoyer (metoyer@iexist.flw.lucent.com)
+sunSolaris-CC:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = CC" \
+       "CFLAGS = -O -I/usr/openwin/include -DSHM -DSOLARIS_2_4_BUG" \
+       "MAKELIB = ../bin/mklib.ar-ruv" \
+       "XLIBS = -L/usr/openwin/lib -R/usr/openwin/lib -lX11 -lXext -lXmu -lXi"
+
+#This config doesn't work, Ultrix C compiler isn't ANSI compliant
+ultrix:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = cc" \
+       "CFLAGS = -O -Dconst=/**/" \
+       "MAKELIB = ../bin/mklib.ar-ruv" \
+       "XLIBS = -lXmu -lX11 -lXi"
+
+ultrix-gcc:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = gcc" \
+       "CFLAGS = -pedantic -O2" \
+       "MAKELIB = ../bin/mklib.ar-ruv" \
+       "XLIBS = -lXmu -lX11 -lXi"
+
+# tested on Cray C90 running UNICOS 8.0.4
+unicos:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = cc" \
+       "CFLAGS =" \
+       "MAKELIB = ../bin/mklib/ar-rcv" \
+       "XLIBS = -lX11 -lXext -lXmu -lXi"
+
+unixware:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = cc" \
+       "CFLAGS = -O -I/usr/X/include -DSHM" \
+       "MAKELIB = ../bin/mklib.ar-ruv" \
+       "XLIBS = -lX11 -lXext -lXmu -lXi -lsocket -lnsl"
+
+unixware-shared:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL" \
+       "GLU_LIB = libGLU" \
+       "GLUT_LIB = libglut" \
+       "GLW_LIB = libGLw" \
+       "CC = cc" \
+       "CFLAGS = -O -I/usr/X/include -KPIC,inline -DSHM" \
+       "MAKELIB = ../bin/mklib.solaris" \
+       "XLIBS = -lX11 -lXext -lXmu -lXi -lsocket -lnsl"
+
+uwin:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "CC = gcc" \
+       "CFLAGS = -pedantic -O2 -I/usr/X11/include " \
+       "MAKELIB = ../bin/mklib.ar-ruv" \
+       "XLIBS = -L/usr/X11/lib -lX11"
+
+vistra:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = gcc" \
+       "CFLAGS = -pedantic -O2" \
+       "MAKELIB = ../bin/mklib.ar-ruv" \
+       "XLIBS = -lX11 -lsocket -lnsl -lgen"
+
+
+# for debugging on IRIX 5.x systems
+# -woff 1209 = "controlling expression is constant"
+# -woff 1210 = "controlling expression is constant"
+# -woff 1506 = "implict conversion from unsigned long to smaller type"
+# -woff 1521 = "nonstandard preprocessing directive is used"
+# -woff 3496 = "bitwise operator precedence"
+irix-debug:
+       pmake $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "LIBDIR = ../lib32" \
+       "CC = cc" \
+       "CFLAGS = -g -n32 -ansi -fullwarn -DSHM -DDEBUG -woff 1209,1210,1506,1521,3496" \
+       "MAKELIB = ../bin/mklib.ar-rcv" \
+       "XLIBS = -rpath ../lib32 -lX11 -lXext -lXmu -lXi -lfpe -lXext -lXmu -lXi"
+
+DEBUG:
+       pmake $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = cc" \
+       "CFLAGS = -g -ansi -prototypes -fullwarn -DSHM -DDEBUG" \
+       "MAKELIB = ../bin/mklib.ar-rcv" \
+       "XLIBS = -lX11 -lXext -lXmu -lXi -lfpe"
+
+# for debugging on Linux systems
+linux-debug:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = gcc" \
+       "CFLAGS = -g -ansi -pedantic -Wall -DSHM -DDEBUG -DSVGA -DFX -D_SVID_SOURCE -D_BSD_SOURCE -DUSE_X86_ASM_not -I/usr/include/glide -I/usr/local/glide/include" \
+       "MAKELIB = ../bin/mklib.ar-ruv" \
+       "XLIBS = -L/usr/local/glide/lib -lglide2x -ltexus -L/usr/X11R6/lib -lX11 -lXext -lXmu -lXt -lXi -lSM -lICE -lvga" \
+       "ASM_SOURCES = X86/x86a.S X86/common_x86asm.S"
+
+linux-elf-debug:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.so" \
+       "GLU_LIB = libGLU.so" \
+       "GLUT_LIB = libglut.so" \
+       "GLW_LIB = libGLw.so" \
+       "CC = gcc" \
+       "CFLAGS = -g -ansi -pedantic -Wall -fPIC -ffast-math -D_SVID_SOURCE -D_BSD_SOURCE -I/usr/X11R6/include -DSHM -DFX -DDEBUG -I/usr/local/glide/include -I/usr/include/glide" \
+       "MAKELIB = ../bin/mklib.linux" \
+       "XLIBS = -L/usr/local/glide/lib -lglide2x -L/usr/X11R6/lib -lX11 -lXext -lXmu -lXt -lXi -lSM -lICE -lvga -L/usr/local/glide/lib -lglide2x -lm" \
+       "ASM_SOURCES = X86/x86a.S X86/common_x86asm.S"
+
+# for profiling on Linux systems
+linux-prof:
+       $(MAKE) $(MFLAGS) -f Makefile.X11 targets \
+       "GL_LIB = libGL.a" \
+       "GLU_LIB = libGLU.a" \
+       "GLUT_LIB = libglut.a" \
+       "GLW_LIB = libGLw.a" \
+       "CC = gcc" \
+       "CFLAGS = -O2 -pg -ansi -pedantic -Wall -DSHM -D_SVID_SOURCE -D_BSD_SOURCE -DUSE_X86_ASM -DUSE_MMX_ASM -DUSE_3DNOW_ASM -I/usr/include/glide -I/usr/local/glide/include" \
+       "MAKELIB = ../bin/mklib.ar-ruv" \
+       "XLIBS = -L/usr/local/glide/lib -lglide2x -L/usr/X11/lib -lX11 -lXext -lXmu -lXt -lXi -lSM -lICE" \
+       "ASM_SOURCES = X86/x86a.S X86/common_x86asm.S \
+       X86/mmx_blend.S \
+       X86/3dnow_xform_raw1.S X86/3dnow_xform_raw2.S \
+       X86/3dnow_xform_raw3.S X86/3dnow_xform_raw4.S \
+       X86/3dnow_xform_masked1.S X86/3dnow_xform_masked2.S \
+       X86/3dnow_xform_masked3.S X86/3dnow_xform_masked4.S \
+       X86/3dnow_norm_raw.S"
diff --git a/Makefile.X11 b/Makefile.X11
new file mode 100644 (file)
index 0000000..21f27e2
--- /dev/null
@@ -0,0 +1,521 @@
+# $Id: Makefile.X11,v 1.1 1999/08/19 00:55:39 jtg Exp $
+
+# Mesa 3-D graphics library
+# Version:  3.1
+# 
+# Copyright (C) 1999  Brian Paul   All Rights Reserved.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+# 
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+# BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+# Top-level makefile for Mesa
+# To add a new configuration for your system add it to the list below
+# then update the Make-config file.
+
+SHELL = /bin/sh
+
+
+
+default:
+       @echo "Type one of the following:"
+       @echo "  make aix                  for IBM RS/6000 with AIX"
+       @echo "  make aix-sl               for IBM RS/6000, make shared libs"
+       @echo "  make amiwin               for Amiga with SAS/C and AmiWin"
+       @echo "  make amix                 for Amiga 3000 UX  SVR4 v2.1 systems"
+       @echo "  make beos-r4              for BeOS R4"
+       @echo "  make bsdos                for BSD/OS from BSDI using GCC"
+       @echo "  make bsdos4               for BSD/OS 4.x, dynamic libraries"
+       @echo "  make cygnus               for Win95/NT using Cygnus-Win32"
+       @echo "  make cygnus-linux         for Win95/NT using Cygnus-Win32 under Linux"
+       @echo "  make dgux                 for Data General"
+       @echo "  make freebsd              for FreeBSD systems with GCC"
+       @echo "  make freebsd-386          for FreeBSD systems with GCC, w/ Intel assembly"
+       @echo "  make gcc                  for a generic system with GCC"
+       @echo "  make hpux9                for HP systems with HPUX 9.x"
+       @echo "  make hpux9-sl             for HP systems with HPUX 9.x, make shared libs"
+       @echo "  make hpux9-gcc            for HP systems with HPUX 9.x using GCC"
+       @echo "  make hpux9-gcc-sl         for HP systems with HPUX 9.x, GCC, make shared libs"
+       @echo "  make hpux10               for HP systems with HPUX 10.x"
+       @echo "  make hpux10-sl            for HP systems with HPUX 10.x, shared libs"
+       @echo "  make hpux10-gcc           for HP systems with HPUX 10.x w/ GCC"
+       @echo "  make hpux10-gcc-sl        for HP systems with HPUX 10.x w/ GCC, shared libs"
+       @echo "  make irix4                for SGI systems with IRIX 4.x"
+       @echo "  make irix5                for SGI systems with IRIX 5.x"
+       @echo "  make irix5-gcc            for SGI systems with IRIX 5.x using GCC"
+       @echo "  make irix5-dso            for SGI systems with IRIX 5.x, make DSOs"
+       @echo "  make irix6-o32            for SGI systems with IRIX 6.x, make o32-bit libs"
+       @echo "  make irix6-o32-dso        for SGI systems with IRIX 6.x, make o32-bit DSOs"
+       @echo "  make irix6-n32            for SGI systems with IRIX 6.x, make n32-bit libs"
+       @echo "  make irix6-n32-dso        for SGI systems with IRIX 6.x, make n32-bit DSOs"
+       @echo "  make irix6-gcc-n32-sl     for SGI systems with IRIX 6.x, GCC, make n32 DSOs"
+       @echo "  make irix6-64             for SGI systems with IRIX 6.x, make 64-bit libs"
+       @echo "  make irix6-64-dso         for SGI systems with IRIX 6.x, make 64-bit DSOs"
+
+       @echo "  make linux                for Linux systems, make static .a libs"
+       @echo "  make linux-elf            for Linux systems, make ELF shared libs"
+       @echo "  make linux-386            for Linux w/ Intel assembly"
+       @echo "  make linux-386-elf        for Linux w/ Intel assembly, make ELF shared libs"
+       @echo "  make linux-ggi            for Linux systems with libggi"
+       @echo "  make linux-386-ggi        for Linux systems with libggi w/ Intel assembly"
+       @echo "  make linux-alpha          for Linux on Alpha systems"
+       @echo "  make linux-alpha-elf      for Linux on Alpha systems, make ELF shared libs"
+       @echo "  make linux-ppc            for Linux on PowerPC systems"
+       @echo "  make linux-ppc-so         for Linux on PowerPC systems, make shared libs"
+       @echo "  make linux-glide          for Linux w/ 3Dfx Glide driver"
+       @echo "  make linux-386-glide      for Linux w/ 3Dfx Glide driver, Intel assembly"
+       @echo "  make linux-386-opt-glide  for Linux with 3Dfx Voodoo1 for GLQuake"
+       @echo "  make linux-386-opt-V2-glide  for Linux with 3Dfx Voodoo2 for GLQuake"
+       @echo "  make linux-3dnow          for Linux on AMD w/ 3DNow!"
+       @echo "  make linux-3dnow-glide    for Linux on AMD w/ 3DNow! for Glide"
+       @echo "  make linux-386-pthread    for Linux w/ Intel assembly and linuxthreads"
+       @echo "  make linux-386-pthread-shared  for Linux w/ Intel assembly and linuxthreads"
+       @echo "  make linux-sparc          for Linux on Sparc systems"
+       @echo "  make linux-sparc5-elf     for Sparc5 systems, make ELF shared libs"
+       @echo "  make linux-sparc-ultra    for UltraSparc systems, make ELF shared libs"
+       @echo "  make lynxos               for LynxOS systems with GCC"
+       @echo "  make macintosh            for Macintosh"
+       @echo "  make machten-2.2          for Macs w/ MachTen 2.2 (68k w/ FPU)"
+       @echo "  make machten-4.0          for Macs w/ MachTen 4.0.1 or newer with GNU make"
+       @echo "  make mklinux              for Linux on Power Macintosh"
+       @echo "  make netbsd               for NetBSD 1.0 systems with GCC"
+       @echo "  make next                 for NeXT systems with NEXTSTEP 3.3"
+       @echo "  make openbsd              for OpenBSD systems"
+       @echo "  make openstep             for OpenStep/MacOSX Server systems"
+       @echo "  make os2-x11              for OS/2 with XFree86"
+       @echo "  make osf1                 for DEC Alpha systems with OSF/1"
+       @echo "  make osf1-sl              for DEC Alpha systems with OSF/1, make shared libs"
+       @echo "  make pgi-cygnus           for Cygnus with Portland Group, Inc. compiler"
+       @echo "  make pgi-mingw32          for mingW32 with Portland Group, Inc. compiler"
+       @echo "  make qnx                  for QNX V4 systems with Watcom compiler"
+       @echo "  make sco                  for SCO Unix systems with ODT"
+       @echo "  make solaris-x86          for PCs with Solaris"
+       @echo "  make solaris-x86-gcc      for PCs with Solaris using GCC"
+       @echo "  make sunos4               for Suns with SunOS 4.x"
+       @echo "  make sunos4-sl            for Suns with SunOS 4.x, make shared libs"
+       @echo "  make sunos4-gcc           for Suns with SunOS 4.x and GCC"
+       @echo "  make sunos4-gcc-sl        for Suns with SunOS 4.x, GCC, make shared libs"
+       @echo "  make sunos5               for Suns with SunOS 5.x"
+       @echo "  make sunos5-sl            for Suns with SunOS 5.x, make shared libs"
+       @echo "  make sunos5-ultra         for Sun UltraSPARCs with SunOS 5.x"
+       @echo "  make sunos5-ultra-sl      for Sun UltraSPARCs with SunOS 5.x, make shared libs"
+       @echo "  make sunos5-thread        for Suns with SunOS 5.x, using Solaris threads"
+       @echo "  make sunos5-pthread       for Suns with SunOS 5.[56] using POSIX threads"
+       @echo "  make sunos5-gcc-thread    for Suns with SunOS 5.x and GCC, using Solaris threads"
+       @echo "  make sunos5-gcc-pthread   for Suns with SunOS 5.[56] and GCC, using POSIX threads"
+       @echo "  make sunos5-gcc           for Suns with SunOS 5.x and GCC"
+       @echo "  make sunos5-gcc-sl        for Suns with SunOS 5.x, GCC, make shared libs"
+       @echo "  make sunos5-x11r6-gcc-sl  for Suns with X11R6, GCC, make shared libs"
+       @echo "  make sunos5-gcc-thread    for Suns with SunOS 5.x and GCC, using Solaris threads"
+       @echo "  make sunos5-gcc-pthread   for Suns with SunOS 5.[56] and GCC, using POSIX threads"
+       @echo "  make sunSolaris-CC        for Solaris using C++ compiler"
+       @echo "  make ultrix-gcc           for DEC systems with Ultrix and GCC"
+       @echo "  make unicos               for Cray C90 (and other?) systems"
+       @echo "  make unixware             for PCs running UnixWare"
+       @echo "  make unixware-shared      for PCs running UnixWare, shared libs"
+       @echo "  make uwin                 for Windows NT with AT&T/Wipro UWIN"
+       @echo "  make vistra               for Stardent Vistra systems"
+       @echo "  make clean                remove .o files"
+       @echo "  make realclean            remove .o, library and executable files"
+
+
+
+aix aix-sl amix bsdos bsdos4 dgux freebsd freebsd-386 gcc \
+hpux9 hpux9-sl hpux9-gcc hpux9-gcc-sl \
+hpux10 hpux10-sl hpux10-gcc hpux10-gcc-sl \
+irix-debug irix4 irix5 irix5-gcc irix5-dso irix6-o32 irix6-o32-dso \
+linux linux-debug linux-prof linux-elf linux-elf-debug \
+linux-glide linux-386-glide linux-386-opt-glide \
+linux-386-opt-V2-glide \
+linux-386 linux-386-elf \
+linux-3dnow linux-3dnow-glide \
+linux-alpha linux-alpha-elf \
+linux-ppc linux-ppc-so \
+linux-386-pthread linux-386-pthread-shared \
+linux-sparc \
+linux-sparc5-elf \
+linux-sparc-ultra \
+lynxos machten-2.2 machten-4.0 \
+mklinux netbsd osf1 osf1-sl openbsd qnx sco \
+solaris-x86 solaris-x86-gcc sunSolaris-CC \
+sunos4 sunos4-sl sunos4-gcc sunos4-gcc-sl sunos4-gcc-x11r6-sl \
+sunos5 sunos5-sl sunos5-ultra sunos5-ultra-sl sunos5-gcc sunos5-gcc-sl \
+sunos5-thread sunos5-pthread sunos5-gcc-thread sunos5-gcc-pthread \
+sunos5-x11r6-gcc-sl ultrix-gcc unicos unixware uwin vistra:
+       -mkdir lib
+       touch src/depend
+       touch src-glu/depend
+       if [ -d src-glut ] ; then touch src-glut/depend ; fi
+       cd src ; $(MAKE) -f Makefile.X11 $@
+       cd src-glu ; $(MAKE) -f Makefile.X11 $@
+       if [ -d src-glut ] ; then cd src-glut ; $(MAKE) -f Makefile.X11 $@ ; fi
+       if [ -d demos ]    ; then cd demos    ; $(MAKE) -f Makefile.X11 $@ ; fi
+       if [ -d xdemos ]   ; then cd xdemos   ; $(MAKE) -f Makefile.X11 $@ ; fi
+       if [ -d samples ]  ; then cd samples  ; $(MAKE) -f Makefile.X11 $@ ; fi
+       if [ -d book ]     ; then cd book     ; $(MAKE) -f Makefile.X11 $@ ; fi
+
+
+irix6-n32 irix6-n32-dso irix6-gcc-n32-sl:
+       -mkdir lib32
+       touch src/depend
+       touch src-glu/depend
+       if [ -d src-glut ] ; then touch src-glut/depend ; fi
+       cd src ; $(MAKE) -f Makefile.X11 $@
+       cd src-glu ; $(MAKE) -f Makefile.X11 $@
+       if [ -d src-glut ] ; then cd src-glut ; $(MAKE) -f Makefile.X11 $@ ; fi
+       if [ -d demos ]    ; then cd demos    ; $(MAKE) -f Makefile.X11 $@ ; fi
+       if [ -d xdemos ]   ; then cd xdemos   ; $(MAKE) -f Makefile.X11 $@ ; fi
+       if [ -d samples ]  ; then cd samples  ; $(MAKE) -f Makefile.X11 $@ ; fi
+       if [ -d book ]     ; then cd book     ; $(MAKE) -f Makefile.X11 $@ ; fi
+
+
+irix6-64 irix6-64-dso:
+       -mkdir lib64
+       touch src/depend
+       touch src-glu/depend
+       if [ -d src-glut ] ; then touch src-glut/depend ; fi
+       cd src ; $(MAKE) -f Makefile.X11 $@
+       cd src-glu ; $(MAKE) -f Makefile.X11 $@
+       if [ -d src-glut ] ; then cd src-glut ; $(MAKE) -f Makefile.X11 $@ ; fi
+       if [ -d demos ]    ; then cd demos    ; $(MAKE) -f Makefile.X11 $@ ; fi
+       if [ -d xdemos ]   ; then cd xdemos   ; $(MAKE) -f Makefile.X11 $@ ; fi
+       if [ -d samples ]  ; then cd samples  ; $(MAKE) -f Makefile.X11 $@ ; fi
+       if [ -d book ]     ; then cd book     ; $(MAKE) -f Makefile.X11 $@ ; fi
+
+
+amiwin:
+       bin/mklib.amiwin
+
+
+beos-r4:
+       -mkdir lib
+       -rm src/depend
+       touch src/depend
+       -rm src-glu/depend
+       touch src-glu/depend
+       cd src ; $(MAKE) -f Makefile.BeOS-R4 $@
+       cd src-glu ; $(MAKE) -f Makefile.BeOS-R4 $@
+       if [ -d BeOS ]          ; then cd BeOS          ; $(MAKE) ; fi
+       if [ -d src-glut.beos ] ; then cd src-glut.beos ; $(MAKE) ; fi
+       if [ -d src-glut.beos ] ; then cp src-glut.beos/obj*/libglut.so lib  ; fi
+       if [ -d demos ]   ; then cd demos   ; $(MAKE) -f Makefile.BeOS-R4 $@ ; fi
+       if [ -d samples ] ; then cd samples ; $(MAKE) -f Makefile.BeOS-R4 $@ ; fi
+       if [ -d book ]    ; then cd book    ; $(MAKE) -f Makefile.BeOS-R4 $@ ; fi
+
+pgi-cygnus pgi-mingw32 \
+cygnus cygnus-linux:
+       -mkdir lib
+       touch src/depend
+       touch src-glu/depend
+       cd src ; $(MAKE) -f Makefile.X11 $@
+       cd src-glu ; $(MAKE) -f Makefile.X11 $@
+       cd src-glut ; $(MAKE) -f Makefile.X11 $@
+       cd demos ; $(MAKE) -f Makefile.X11 $@
+       if [ -d xdemos ]  ; then cd xdemos  ; $(MAKE) -f Makefile.X11 $@ ; fi
+
+macintosh:
+       @echo "See the README file for Macintosh intallation information"
+
+next:
+       -mkdir lib
+       cd src ; $(MAKE) -f Makefile.X11 "MYCC=${CC}" $@
+       cd src-glu ; $(MAKE) -f Makefile.X11 "MYCC=${CC}" $@
+
+openstep:
+       -mkdir lib
+       cd src ; $(MAKE) -f Makefile.X11 "MYCC=${CC}" $@
+       cd src-glu ; $(MAKE) -f Makefile.X11 "MYCC=${CC}" $@
+
+os2-x11:
+       if not EXIST .\lib md lib
+       touch src/depend
+       touch src-glu/depend
+       if exist src-glut touch src-glut/depend
+       cd src     & make -f Makefile.X11 $@
+       cd src-glu & make -f Makefile.X11 $@
+       if exist src-glut  cd src-glut & make -f Makefile.X11 $@
+       if exist demos     cd demos    & make -f Makefile.X11 $@
+       if exist xdemos    cd xdemos   & make -f Makefile.X11 $@
+       if exist samples   cd samples  & make -f Makefile.X11 $@
+       if exist book      cd book     & make -f Makefile.X11 $@
+
+linux-ggi linux-386-ggi:
+       -mkdir lib
+       touch src/depend
+       touch src-glu/depend
+       if [ -d src-glut ] ; then touch src-glut/depend ; fi
+       if [ -d ggi ] ; then touch ggi/depend ; fi
+       cd src ; $(MAKE) -f Makefile.X11 $@
+       cd src/GGI/default ; $(MAKE)
+       cd src/GGI/display ; $(MAKE)
+       cd src-glu ; $(MAKE) -f Makefile.X11 $@
+#      if [ -d src-glut ] ; then cd src-glut ; $(MAKE) -f Makefile.X11 $@ ; fi
+       if [ -d ggi ]      ; then cd ggi      ; $(MAKE) -f Makefile.X11 $@ ; fi
+       if [ -d ggi ]      ; then cd ggi/demos; $(MAKE)    ; fi
+       if [ -d demos ]    ; then cd demos    ; $(MAKE) -f Makefile.X11 $@ ; fi
+       if [ -d xdemos ]   ; then cd xdemos   ; $(MAKE) -f Makefile.X11 $@ ; fi
+       if [ -d samples ]  ; then cd samples  ; $(MAKE) -f Makefile.X11 $@ ; fi
+       if [ -d book ]     ; then cd book     ; $(MAKE) -f Makefile.X11 $@ ; fi
+
+# if you change GGI_DEST please change it in ggimesa.conf, too.
+DESTDIR=/usr/local
+GGI_DEST=lib/ggi/mesa
+
+linux-ggi-install linux-386-ggi-install:
+       install -d $(DESTDIR)/$(GGI_DEST)/default $(DESTDIR)/$(GGI_DEST)/display $(DESTDIR)/etc/ggi
+       install -m 0755 src/GGI/default/*.so $(DESTDIR)/$(GGI_DEST)/default
+       install -m 0755 src/GGI/display/*.so $(DESTDIR)/$(GGI_DEST)/display
+       install -m 0644 src/GGI/ggimesa.conf $(DESTDIR)/etc/ggi
+#      if [ -z "`grep ggimesa $(DESTDIR)/etc/ggi/libggi.conf`" ]; then \
+#      echo ".include $(DESTDIR)/etc/ggi/ggimesa.conf" >> $(DESTDIR)/etc/ggi/libggi.conf ; \
+#      fi
+
+# Remove .o files, emacs backup files, etc.
+clean:
+       -rm -f ggi/*~ *.o
+       -rm -f src/GGI/default/*~ *.so
+       -rm -f src/GGI/display/*~ *.so
+       -rm -f include/*~
+       -rm -f include/GL/*~
+       -rm -f src/*.o src/*~ src/*.a src/*/*.o src/*/*~
+       -rm -f src-glu/*.o src-glu/*~ src-glu/*.a
+       -rm -f src-glut/*.o
+       -rm -f demos/*.o
+       -rm -f book/*.o book/*~
+       -rm -f xdemos/*.o xdemos/*~
+       -rm -f samples/*.o samples/*~
+       -rm -f ggi/*.o ggi/demos/*.o ggi/*.a
+
+# Remove everything that can be remade
+realclean: clean
+       -rm -f lib/*
+       cd demos       && $(MAKE) -f Makefile.X11 realclean || true
+       cd xdemos      && $(MAKE) -f Makefile.X11 realclean || true
+       cd book        && $(MAKE) -f Makefile.X11 realclean || true
+       cd samples     && $(MAKE) -f Makefile.X11 realclean || true
+       cd ggi/demos   && ($MAKE) -f Makefile.X11 realclean || true
+       cd src/GGI/default && $(MAKE) -f Makefile.X11 realclean || true
+
+
+
+DIRECTORY = Mesa-3.1
+LIB_NAME = MesaLib-3.1beta2
+DEMO_NAME = MesaDemos-3.1beta2
+
+
+LIB_FILES =    \
+       $(DIRECTORY)/Makefile*                  \
+       $(DIRECTORY)/Make-config                \
+       $(DIRECTORY)/acconfig.h                 \
+       $(DIRECTORY)/acinclude.m4               \
+       $(DIRECTORY)/aclocal.m4                 \
+       $(DIRECTORY)/conf.h.in                  \
+       $(DIRECTORY)/config.guess               \
+       $(DIRECTORY)/config.sub                 \
+       $(DIRECTORY)/configure                  \
+       $(DIRECTORY)/configure.in               \
+       $(DIRECTORY)/install-sh                 \
+       $(DIRECTORY)/ltconfig                   \
+       $(DIRECTORY)/ltmain.sh                  \
+       $(DIRECTORY)/missing                    \
+       $(DIRECTORY)/mkinstalldirs              \
+       $(DIRECTORY)/stamp-h.in                 \
+       $(DIRECTORY)/INSTALL                    \
+       $(DIRECTORY)/INSTALL.GNU                \
+       $(DIRECTORY)/configure                  \
+       $(DIRECTORY)/docs/CONFIG                \
+       $(DIRECTORY)/docs/CONFORM               \
+       $(DIRECTORY)/docs/COPYRIGHT             \
+       $(DIRECTORY)/docs/IAFA-PACKAGE          \
+       $(DIRECTORY)/docs/LICENSE               \
+       $(DIRECTORY)/docs/README                \
+       $(DIRECTORY)/docs/README.*              \
+       $(DIRECTORY)/docs/RELNOTES              \
+       $(DIRECTORY)/docs/VERSIONS              \
+       $(DIRECTORY)/bin/mklib*                 \
+       $(DIRECTORY)/*.BAT                      \
+       $(DIRECTORY)/*.bat                      \
+       $(DIRECTORY)/descrip.mms                \
+       $(DIRECTORY)/mms-config                 \
+       $(DIRECTORY)/xlib.opt                   \
+       $(DIRECTORY)/STARTUP.MK                 \
+       $(DIRECTORY)/mesawin32.mak              \
+       $(DIRECTORY)/Names.win                  \
+       $(DIRECTORY)/win32-openstep.sh          \
+       $(DIRECTORY)/*.dja                      \
+       $(DIRECTORY)/include/GL/dosmesa.h       \
+       $(DIRECTORY)/include/GL/foomesa.h       \
+       $(DIRECTORY)/include/GL/fxmesa.h        \
+       $(DIRECTORY)/include/GL/ggimesa.h       \
+       $(DIRECTORY)/include/GL/gl.h            \
+       $(DIRECTORY)/include/GL/gl_mangle.h     \
+       $(DIRECTORY)/include/GL/glu.h           \
+       $(DIRECTORY)/include/GL/glu_mangle.h    \
+       $(DIRECTORY)/include/GL/glx.h           \
+       $(DIRECTORY)/include/GL/glx_mangle.h    \
+       $(DIRECTORY)/include/GL/mglmesa.h       \
+       $(DIRECTORY)/include/GL/osmesa.h        \
+       $(DIRECTORY)/include/GL/svgamesa.h      \
+       $(DIRECTORY)/include/GL/wmesa.h         \
+       $(DIRECTORY)/include/GL/xmesa.h         \
+       $(DIRECTORY)/include/GL/xmesa_x.h       \
+       $(DIRECTORY)/include/GL/xmesa_xf86.h    \
+       $(DIRECTORY)/include/GLView.h           \
+       $(DIRECTORY)/src/Makefile*              \
+       $(DIRECTORY)/src/descrip.mms            \
+       $(DIRECTORY)/src/mms_depend             \
+       $(DIRECTORY)/src/*.def                  \
+       $(DIRECTORY)/src/depend                 \
+       $(DIRECTORY)/src/*.[chS]                \
+       $(DIRECTORY)/src/Allegro/*.[ch]         \
+       $(DIRECTORY)/src/BeOS/*.cpp             \
+       $(DIRECTORY)/src/D3D/*.cpp              \
+       $(DIRECTORY)/src/D3D/*.CPP              \
+       $(DIRECTORY)/src/D3D/*.h                \
+       $(DIRECTORY)/src/D3D/*.H                \
+       $(DIRECTORY)/src/D3D/*.c                \
+       $(DIRECTORY)/src/D3D/*.C                \
+       $(DIRECTORY)/src/D3D/MAKEFILE           \
+       $(DIRECTORY)/src/D3D/*bat               \
+       $(DIRECTORY)/src/D3D/*DEF               \
+       $(DIRECTORY)/src/DOS/DEPEND.DOS         \
+       $(DIRECTORY)/src/DOS/*.c                \
+       $(DIRECTORY)/src/FX/*.[ch]              \
+       $(DIRECTORY)/src/FX/*.def               \
+       $(DIRECTORY)/src/GGI/*.[ch]             \
+       $(DIRECTORY)/src/GGI/ggimesa.conf       \
+       $(DIRECTORY)/src/GGI/default/*.c        \
+       $(DIRECTORY)/src/GGI/default/Makefile   \
+       $(DIRECTORY)/src/GGI/display/*.c        \
+       $(DIRECTORY)/src/GGI/display/Makefile   \
+       $(DIRECTORY)/src/KNOWN_BUGS             \
+       $(DIRECTORY)/src/MGL/*.[ch]             \
+       $(DIRECTORY)/src/MGL/*.txt              \
+       $(DIRECTORY)/src/OSmesa/*.[ch]          \
+       $(DIRECTORY)/src/S3/*.[ch]              \
+       $(DIRECTORY)/src/S3/*.def               \
+       $(DIRECTORY)/src/S3/*.mak               \
+       $(DIRECTORY)/src/S3/*.rc                \
+       $(DIRECTORY)/src/SVGA/*.[ch]            \
+       $(DIRECTORY)/src/Windows/*.[ch]         \
+       $(DIRECTORY)/src/Windows/*.def          \
+       $(DIRECTORY)/src/X/*.[ch]               \
+       $(DIRECTORY)/src/X86/*.[ch]             \
+       $(DIRECTORY)/src/X86/Makefile           \
+       $(DIRECTORY)/src/X86/*.m4               \
+       $(DIRECTORY)/src/X86/*.S                \
+       $(DIRECTORY)/src/*.dja                  \
+       $(DIRECTORY)/src-glu/README[12]         \
+       $(DIRECTORY)/src-glu/Makefile*          \
+       $(DIRECTORY)/src-glu/descrip.mms        \
+       $(DIRECTORY)/src-glu/mms_depend         \
+       $(DIRECTORY)/src-glu/*.def              \
+       $(DIRECTORY)/src-glu/*.dja              \
+       $(DIRECTORY)/src-glu/depend             \
+       $(DIRECTORY)/src-glu/*.[ch]             \
+       $(DIRECTORY)/widgets-mesa               \
+       $(DIRECTORY)/widgets-sgi                \
+       $(DIRECTORY)/util/README                \
+       $(DIRECTORY)/util/*.[ch]                \
+       $(DIRECTORY)/util/sampleMakefile        \
+       $(DIRECTORY)/BeOS/Makefile              \
+       $(DIRECTORY)/BeOS/*.cpp                 
+
+# old stuff
+#      $(DIRECTORY)/Win32                      \
+#      $(DIRECTORY)/win32
+
+#      $(DIRECTORY)/OpenStep                   \
+#
+#
+
+
+DEMO_FILES =   \
+       $(DIRECTORY)/include/GL/glut.h          \
+       $(DIRECTORY)/include/GL/glutf90.h       \
+       $(DIRECTORY)/include/GL/glut_h.dja      \
+       $(DIRECTORY)/src-glut/Makefile*         \
+       $(DIRECTORY)/src-glut/depend            \
+       $(DIRECTORY)/src-glut/*def              \
+       $(DIRECTORY)/src-glut/descrip.mms       \
+       $(DIRECTORY)/src-glut/mms_depend        \
+       $(DIRECTORY)/src-glut/*.[ch]            \
+       $(DIRECTORY)/src-glut.dja/*             \
+       $(DIRECTORY)/src-glut.beos/Makefile     \
+       $(DIRECTORY)/src-glut.beos/*.cpp        \
+       $(DIRECTORY)/src-glut.beos/*.h          \
+       $(DIRECTORY)/images/*                   \
+       $(DIRECTORY)/demos/Makefile*            \
+       $(DIRECTORY)/demos/descrip.mms          \
+       $(DIRECTORY)/demos/*.[ch]               \
+       $(DIRECTORY)/demos/*.dat                \
+       $(DIRECTORY)/xdemos/Makefile*           \
+       $(DIRECTORY)/xdemos/descrip.mms         \
+       $(DIRECTORY)/xdemos/*.[cf]              \
+       $(DIRECTORY)/book/Makefile*             \
+       $(DIRECTORY)/book/README                \
+       $(DIRECTORY)/book/*.[ch]                \
+       $(DIRECTORY)/samples/Makefile*          \
+       $(DIRECTORY)/samples/README             \
+       $(DIRECTORY)/samples/*.c                \
+       $(DIRECTORY)/samples/*.dja              \
+       $(DIRECTORY)/3Dfx                       \
+       $(DIRECTORY)/mtdemos                    \
+       $(DIRECTORY)/ggi
+
+
+lib_tar:
+       cd .. ; \
+       tar -cvf $(LIB_NAME).tar $(LIB_FILES) ; \
+       gzip $(LIB_NAME).tar ; \
+       mv $(LIB_NAME).tar.gz $(DIRECTORY)
+
+demo_tar:
+       cd .. ; \
+       tar -cvf $(DEMO_NAME).tar $(DEMO_FILES) ; \
+       gzip $(DEMO_NAME).tar ; \
+       mv $(DEMO_NAME).tar.gz $(DIRECTORY)
+
+lib_zip:
+       -rm $(LIB_NAME).zip
+       cd .. ; \
+       zip -r $(LIB_NAME).zip $(LIB_FILES) ; \
+       mv $(LIB_NAME).zip $(DIRECTORY)
+
+demo_zip:
+       -rm $(DEMO_NAME).zip
+       cd .. ; \
+       zip -r $(DEMO_NAME).zip $(DEMO_FILES) ; \
+       mv $(DEMO_NAME).zip $(DIRECTORY)
+
+
+
+SRC_FILES =    \
+       RELNOTES                \
+       src/Makefile*           \
+       src/depend              \
+       src/*.[chS]             \
+       src/*/*.[ch]            \
+       include/GL/*.h
+
+srctar:
+       tar -cvf src.tar $(SRC_FILES) ; \
+       gzip src.tar
+
+srctar.zip:
+       -rm src.zip
+       zip -r src.zip $(SRC_FILES) ; \
diff --git a/include/GL/Makefile.am b/include/GL/Makefile.am
new file mode 100644 (file)
index 0000000..61af039
--- /dev/null
@@ -0,0 +1,30 @@
+## Process this file with automake to produce Makefile.in
+
+GLincludedir = $(includedir)/GL
+
+if HAVE_FX
+INC_FX = fxmesa.h
+endif
+
+if HAVE_GGI
+INC_GGI = ggimesa.h
+endif
+
+if HAVE_OSMESA
+INC_OSMESA = osmesa.h
+endif
+
+if HAVE_SVGA
+INC_SVGA = svgamesa.h
+endif
+
+if HAVE_X11
+INC_X11 = glx.h glx_mangle.h xmesa.h xmesa_x.h xmesa_xf86.h
+endif
+
+EXTRA_DIST = fxmesa.h ggimesa.h osmesa.h svgamesa.h \
+       glx.h glx_mangle.h xmesa.h xmesa_x.h xmesa_xf86.h
+
+GLinclude_HEADERS = gl.h gl_mangle.h glu.h glu_mangle.h \
+       $(INC_FX) $(INC_GGI) $(INC_OSMESA) $(INC_SVGA) $(INC_X11)
+
diff --git a/include/GL/amesa.h b/include/GL/amesa.h
new file mode 100644 (file)
index 0000000..b4a1867
--- /dev/null
@@ -0,0 +1,75 @@
+/* $Id: amesa.h,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/*
+ * $Log: amesa.h,v $
+ * Revision 1.1  1999/08/19 00:55:40  jtg
+ * Initial revision
+ *
+ * Revision 1.1  1999/03/16 01:24:13  brianp
+ * initial check-in
+ *
+ */
+
+
+/* Allegro (DJGPP) driver by Bernhard Tschirren (bernie-t@geocities.com) */
+
+
+
+#ifndef AMESA_H
+#define AMESA_H
+
+
+typedef struct amesa_visual  *AMesaVisual;
+typedef struct amesa_buffer  *AMesaBuffer;
+typedef struct amesa_context *AMesaContext;
+
+
+extern AMesaVisual AMesaCreateVisual(GLboolean dbFlag, GLint depth,
+                                     GLint depthSize,
+                                     GLint stencilSize,
+                                     GLint accumSize);
+
+extern void AMesaDestroyVisual(AMesaVisual visual);
+
+extern AMesaBuffer AMesaCreateBuffer(AMesaVisual visual,
+                                     GLint width, GLint height);
+
+extern void AMesaDestroyBuffer(AMesaBuffer buffer);
+
+
+extern AMesaContext AMesaCreateContext(AMesaVisual visual,
+                                       AMesaContext sharelist);
+
+extern void AMesaDestroyContext(AMesaContext context);
+
+extern GLboolean AMesaMakeCurrent(AMesaContext context, AMesaBuffer buffer);
+
+extern void AMesaSwapBuffers(AMesaBuffer buffer);
+
+
+#endif /* AMESA_H */
diff --git a/include/GL/foomesa.h b/include/GL/foomesa.h
new file mode 100644 (file)
index 0000000..8874629
--- /dev/null
@@ -0,0 +1,89 @@
+/* $Id: foomesa.h,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.0
+ * Copyright (C) 1995-1998  Brian Paul
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/*
+ * $Log: foomesa.h,v $
+ * Revision 1.1  1999/08/19 00:55:40  jtg
+ * Initial revision
+ *
+ * Revision 1.1  1998/06/02 01:34:18  brianp
+ * Initial revision
+ *
+ */
+
+
+/*
+ * Example Foo/Mesa interface.  See src/ddsample.c for more info.
+ */
+
+
+
+#ifndef FOOMESA_H
+#define FOOMESA_H
+
+
+
+typedef struct foo_mesa_visual  *FooMesaVisual;
+
+typedef struct foo_mesa_buffer  *FooMesaBuffer;
+
+typedef struct foo_mesa_context *FooMesaContext;
+
+
+
+#ifdef BEOS
+#pragma export on
+#endif
+
+
+extern FooMesaVisual FooMesaChooseVisual( /* your params */ );
+
+extern void FooMesaDestroyVisual( FooMesaVisual visual );
+
+
+extern FooMesaBuffer FooMesaCreateBuffer( FooMesaVisual visual,
+                                          void *your_window_id );
+
+extern void FooMesaDestroyBuffer( FooMesaBuffer buffer );
+
+
+extern FooMesaContext FooMesaCreateContext( FooMesaVisual visual,
+                                            FooMesaContext sharelist );
+
+extern void FooMesaDestroyContext( FooMesaContext context );
+
+
+extern void FooMesaMakeCurrent( FooMesaContext context, FooMesaBuffer buffer );
+
+
+extern void FooMesaSwapBuffers( FooMesaBuffer buffer );
+
+
+/* Probably some more functions... */
+
+
+#ifdef BEOS
+#pragma export off
+#endif
+
+#endif
diff --git a/include/GL/fxmesa.h b/include/GL/fxmesa.h
new file mode 100644 (file)
index 0000000..68f15eb
--- /dev/null
@@ -0,0 +1,120 @@
+/* $Id: fxmesa.h,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * Copyright (C) 1995-1999  Brian Paul
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/*
+ * $Log: fxmesa.h,v $
+ * Revision 1.1  1999/08/19 00:55:40  jtg
+ * Initial revision
+ *
+ * Revision 3.2  1999/01/03 02:46:31  brianp
+ * now using GLAPI and GLAPIENTRY keywords (Ted Jump)
+ *
+ * Revision 3.1  1998/04/01 03:00:28  brianp
+ * updated for v0.24 of 3Dfx/Glide driver
+ *
+ * Revision 3.0  1998/02/20 05:04:45  brianp
+ * initial rev
+ *
+ */
+
+
+/*
+ * FXMesa - 3Dfx Glide driver for Mesa.  Contributed by David Bucciarelli
+ *
+ * NOTE: This version requires Glide 2.3 or later.
+ */
+
+
+#ifndef FXMESA_H
+#define FXMESA_H
+
+
+#include <glide.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define FXMESA_MAJOR_VERSION 3
+#define FXMESA_MINOR_VERSION 0
+
+
+/*
+ * Values for attribList parameter to fxMesaCreateContext():
+ */
+#define FXMESA_NONE            0       /* to terminate attribList */
+#define FXMESA_DOUBLEBUFFER    10
+#define FXMESA_ALPHA_SIZE      11      /* followed by an integer */
+#define FXMESA_DEPTH_SIZE      12      /* followed by an integer */
+#define FXMESA_STENCIL_SIZE    13      /* followed by an integer */
+#define FXMESA_ACCUM_SIZE      14      /* followed by an integer */
+
+
+
+typedef struct tfxMesaContext *fxMesaContext;
+
+
+#if defined (__BEOS__)
+#pragma export on
+#endif
+
+
+GLAPI fxMesaContext GLAPIENTRY fxMesaCreateContext(GLuint win, GrScreenResolution_t,
+                                                 GrScreenRefresh_t,
+                                                 const GLint attribList[]);
+
+GLAPI fxMesaContext GLAPIENTRY fxMesaCreateBestContext(GLuint win,
+                                                     GLint width, GLint height,
+                                                     const GLint attribList[]);
+GLAPI void GLAPIENTRY fxMesaDestroyContext(fxMesaContext ctx);
+
+GLAPI GLboolean GLAPIENTRY fxMesaSelectCurrentBoard(int n);
+
+GLAPI void GLAPIENTRY fxMesaMakeCurrent(fxMesaContext ctx);
+
+GLAPI fxMesaContext GLAPIENTRY fxMesaGetCurrentContext(void);
+
+GLAPI void GLAPIENTRY fxMesaSwapBuffers(void);
+
+GLAPI void GLAPIENTRY fxMesaSetNearFar(GLfloat nearVal, GLfloat farVal);
+
+GLAPI void GLAPIENTRY fxMesaUpdateScreenSize(fxMesaContext ctx);
+
+GLAPI int GLAPIENTRY fxQueryHardware(void);
+
+GLAPI void GLAPIENTRY fxCloseHardware(void);
+
+
+#if defined (__BEOS__)
+#pragma export off
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/include/GL/ggimesa.h b/include/GL/ggimesa.h
new file mode 100644 (file)
index 0000000..b7f9379
--- /dev/null
@@ -0,0 +1,67 @@
+/* $Id: ggimesa.h,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * Copyright (C) 1995-1998  Brian Paul
+ * Copyright (C) 1998  Uwe Maurer
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/*
+ * $Log: ggimesa.h,v $
+ * Revision 1.1  1999/08/19 00:55:40  jtg
+ * Initial revision
+ *
+ * Revision 1.2  1998/09/29 01:46:40  brianp
+ * applied Emmanuel Marty's patches for latest GGI
+ *
+ */
+
+
+#ifndef GGIMESA_H
+#define GGIMESA_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "GL/gl.h"
+
+
+typedef struct ggi_mesa_context *GGIMesaContext;
+
+#include <ggi/ggi.h>
+
+extern GGIMesaContext GGIMesaCreateContext(void);
+
+extern void GGIMesaDestroyContext( GGIMesaContext ctx );
+
+extern void GGIMesaMakeCurrent(GGIMesaContext ctx );
+
+extern GGIMesaContext GGIMesaGetCurrentContext( void );
+
+extern void GGIMesaSwapBuffers( void );
+
+extern int GGIMesaSetVisual(GGIMesaContext ctx,ggi_visual_t vis,
+                               GLboolean rgb_flag,GLboolean db_flag);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/GL/gl.h b/include/GL/gl.h
new file mode 100644 (file)
index 0000000..58b51d5
--- /dev/null
@@ -0,0 +1,2235 @@
+/* $Id: gl.h,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ *
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+#ifndef GL_H
+#define GL_H
+
+#if defined(USE_MGL_NAMESPACE)
+#include "gl_mangle.h"
+#endif
+
+
+#if defined(__BEOS__)
+#include <stdlib.h>     /* to get some BeOS-isms */
+#endif
+
+
+#if !defined(OPENSTEP) && (defined(NeXT) || defined(NeXT_PDO))
+#define OPENSTEP
+#endif
+
+
+#if defined(_WIN32) && !defined(__WIN32__)
+#      define __WIN32__
+#endif
+
+#if !defined(OPENSTEP) && (defined(__WIN32__) || defined(__CYGWIN32__))
+#      pragma warning( disable : 4244 ) /* '=' : conversion from 'const double ' to 'float ', possible loss of data */
+#      pragma warning( disable : 4018 ) /* '<' : signed/unsigned mismatch */
+#      pragma warning( disable : 4305 ) /* '=' : truncation from 'const double ' to 'float ' */
+#      pragma warning( disable : 4550 ) /* 'function' undefined; assuming extern returning int */
+#      pragma warning( disable : 4761 ) /* integral size mismatch in argument; conversion supplied */
+#      if defined(_MSC_VER) && defined(BUILD_GL32) /* tag specify we're building mesa as a DLL */
+#              define GLAPI __declspec(dllexport)
+#      elif defined(_MSC_VER) && defined(_DLL) /* tag specifying we're building for DLL runtime support */
+#              define GLAPI __declspec(dllimport)
+#      else /* for use with static link lib build of Win32 edition only */
+#              define GLAPI extern
+#      endif /* _STATIC_MESA support */
+#      define GLAPIENTRY __stdcall
+#      define GLCALLBACK __stdcall
+#      define GLWINAPI __stdcall
+#      define GLWINAPIV __cdecl
+#else
+/* non-Windows compilation */
+#      define GLAPI extern
+#      define GLAPIENTRY
+#      define GLCALLBACK
+#      define GLWINAPI
+#      define GLWINAPIV
+#endif /* WIN32 / CYGWIN32 bracket */
+
+/* compatability guard so we don't need to change client code */
+
+#if defined(_WIN32) && !defined(_WINDEF_) && !defined(OPENSTEP)
+#      if !defined(MESA_MINWARN)
+#              pragma message( "note: WINDOWS.H not included, providing Mesa definition of CALLBACK macro" )
+#              pragma message( "----: and PROC typedef. If you receive compiler warnings about either ")
+#              pragma message( "----: being multiply defined you should include WINDOWS.H priot to gl/gl.h" )
+#      endif
+#      define CALLBACK GLCALLBACK
+typedef int (GLAPIENTRY *PROC)();
+typedef void *HGLRC;
+typedef void *HDC;
+typedef unsigned long COLORREF;
+#endif
+
+#if defined(_WIN32) && !defined(_WINGDI_) && !defined(OPENSTEP)
+#      if !defined(MESA_MINWARN)
+#              pragma message( "note: WINDOWS.H not included, providing Mesa definition of wgl functions" )
+#              pragma message( "----: and macros. If you receive compiler warnings about any being multiply ")
+#              pragma message( "----: defined you should include WINDOWS.H priot to gl/gl.h" )
+#      endif
+#      define WGL_FONT_LINES      0
+#      define WGL_FONT_POLYGONS   1
+#      ifdef UNICODE
+#              define wglUseFontBitmaps  wglUseFontBitmapsW
+#              define wglUseFontOutlines  wglUseFontOutlinesW
+#      else
+#              define wglUseFontBitmaps  wglUseFontBitmapsA
+#              define wglUseFontOutlines  wglUseFontOutlinesA
+#      endif /* !UNICODE */
+typedef struct tagLAYERPLANEDESCRIPTOR LAYERPLANEDESCRIPTOR, *PLAYERPLANEDESCRIPTOR, *LPLAYERPLANEDESCRIPTOR;
+typedef struct _GLYPHMETRICSFLOAT GLYPHMETRICSFLOAT, *PGLYPHMETRICSFLOAT, *LPGLYPHMETRICSFLOAT;
+GLAPI int   GLAPIENTRY wglCopyContext(HGLRC, HGLRC, unsigned int);
+GLAPI HGLRC GLAPIENTRY wglCreateContext(HDC);
+GLAPI HGLRC GLAPIENTRY wglCreateLayerContext(HDC, int);
+GLAPI int   GLAPIENTRY wglDeleteContext(HGLRC);
+GLAPI HGLRC GLAPIENTRY wglGetCurrentContext(void);
+GLAPI HDC   GLAPIENTRY wglGetCurrentDC(void);
+GLAPI PROC  GLAPIENTRY wglGetProcAddress(char*);
+GLAPI int   GLAPIENTRY wglMakeCurrent(HDC, HGLRC);
+GLAPI int   GLAPIENTRY wglShareLists(HGLRC, HGLRC);
+GLAPI int   GLAPIENTRY wglUseFontBitmapsA(HDC, unsigned long, unsigned long, unsigned long);
+GLAPI int   GLAPIENTRY wglUseFontBitmapsW(HDC, unsigned long, unsigned long, unsigned long);
+GLAPI int   GLAPIENTRY wglUseFontOutlinesA(HDC, unsigned long, unsigned long, unsigned long, float,float, int, LPGLYPHMETRICSFLOAT);
+GLAPI int   GLAPIENTRY wglUseFontOutlinesW(HDC, unsigned long, unsigned long, unsigned long, float,float, int, LPGLYPHMETRICSFLOAT);
+GLAPI int   GLAPIENTRY wglDescribeLayerPlane(HDC, int, int, unsigned int,LPLAYERPLANEDESCRIPTOR);
+GLAPI int   GLAPIENTRY wglSetLayerPaletteEntries(HDC, int, int, int,const COLORREF *);
+GLAPI int   GLAPIENTRY wglGetLayerPaletteEntries(HDC, int, int, int,COLORREF *);
+GLAPI int   GLAPIENTRY wglRealizeLayerPalette(HDC, int, int);
+GLAPI int   GLAPIENTRY wglSwapLayerBuffers(HDC, unsigned int);
+GLAPI int   GLAPIENTRY SwapBuffers(HDC);
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#ifdef macintosh
+       #pragma enumsalwaysint on
+       #if PRAGMA_IMPORT_SUPPORTED
+       #pragma import on
+       #endif
+#endif
+
+
+
+/*
+ * Apps can test for this symbol to do conditional compilation if needed.
+ */
+#define MESA
+
+#define MESA_MAJOR_VERSION 3
+#define MESA_MINOR_VERSION 1
+
+
+#define GL_VERSION_1_1   1
+#define GL_VERSION_1_2   1
+
+
+/*
+ *
+ * Enumerations
+ *
+ */
+
+typedef enum {
+       /* Boolean values */
+       GL_FALSE                        = 0,
+       GL_TRUE                         = 1,
+
+       /* Data types */
+       GL_BYTE                         = 0x1400,
+       GL_UNSIGNED_BYTE                = 0x1401,
+       GL_SHORT                        = 0x1402,
+       GL_UNSIGNED_SHORT               = 0x1403,
+       GL_INT                          = 0x1404,
+       GL_UNSIGNED_INT                 = 0x1405,
+       GL_FLOAT                        = 0x1406,
+       GL_DOUBLE                       = 0x140A,
+       GL_2_BYTES                      = 0x1407,
+       GL_3_BYTES                      = 0x1408,
+       GL_4_BYTES                      = 0x1409,
+
+       /* Primitives */
+       GL_POINTS                       = 0x0000,
+       GL_LINES                        = 0x0001,
+       GL_LINE_LOOP                    = 0x0002,
+       GL_LINE_STRIP                   = 0x0003,
+       GL_TRIANGLES                    = 0x0004,
+       GL_TRIANGLE_STRIP               = 0x0005,
+       GL_TRIANGLE_FAN                 = 0x0006,
+       GL_QUADS                        = 0x0007,
+       GL_QUAD_STRIP                   = 0x0008,
+       GL_POLYGON                      = 0x0009,
+
+       /* Vertex Arrays */
+       GL_VERTEX_ARRAY                 = 0x8074,
+       GL_NORMAL_ARRAY                 = 0x8075,
+       GL_COLOR_ARRAY                  = 0x8076,
+       GL_INDEX_ARRAY                  = 0x8077,
+       GL_TEXTURE_COORD_ARRAY          = 0x8078,
+       GL_EDGE_FLAG_ARRAY              = 0x8079,
+       GL_VERTEX_ARRAY_SIZE            = 0x807A,
+       GL_VERTEX_ARRAY_TYPE            = 0x807B,
+       GL_VERTEX_ARRAY_STRIDE          = 0x807C,
+       GL_NORMAL_ARRAY_TYPE            = 0x807E,
+       GL_NORMAL_ARRAY_STRIDE          = 0x807F,
+       GL_COLOR_ARRAY_SIZE             = 0x8081,
+       GL_COLOR_ARRAY_TYPE             = 0x8082,
+       GL_COLOR_ARRAY_STRIDE           = 0x8083,
+       GL_INDEX_ARRAY_TYPE             = 0x8085,
+       GL_INDEX_ARRAY_STRIDE           = 0x8086,
+       GL_TEXTURE_COORD_ARRAY_SIZE     = 0x8088,
+       GL_TEXTURE_COORD_ARRAY_TYPE     = 0x8089,
+       GL_TEXTURE_COORD_ARRAY_STRIDE   = 0x808A,
+       GL_EDGE_FLAG_ARRAY_STRIDE       = 0x808C,
+       GL_VERTEX_ARRAY_POINTER         = 0x808E,
+       GL_NORMAL_ARRAY_POINTER         = 0x808F,
+       GL_COLOR_ARRAY_POINTER          = 0x8090,
+       GL_INDEX_ARRAY_POINTER          = 0x8091,
+       GL_TEXTURE_COORD_ARRAY_POINTER  = 0x8092,
+       GL_EDGE_FLAG_ARRAY_POINTER      = 0x8093,
+       GL_V2F                          = 0x2A20,
+       GL_V3F                          = 0x2A21,
+       GL_C4UB_V2F                     = 0x2A22,
+       GL_C4UB_V3F                     = 0x2A23,
+       GL_C3F_V3F                      = 0x2A24,
+       GL_N3F_V3F                      = 0x2A25,
+       GL_C4F_N3F_V3F                  = 0x2A26,
+       GL_T2F_V3F                      = 0x2A27,
+       GL_T4F_V4F                      = 0x2A28,
+       GL_T2F_C4UB_V3F                 = 0x2A29,
+       GL_T2F_C3F_V3F                  = 0x2A2A,
+       GL_T2F_N3F_V3F                  = 0x2A2B,
+       GL_T2F_C4F_N3F_V3F              = 0x2A2C,
+       GL_T4F_C4F_N3F_V4F              = 0x2A2D,
+
+       /* Matrix Mode */
+       GL_MATRIX_MODE                  = 0x0BA0,
+       GL_MODELVIEW                    = 0x1700,
+       GL_PROJECTION                   = 0x1701,
+       GL_TEXTURE                      = 0x1702,
+
+       /* Points */
+       GL_POINT_SMOOTH                 = 0x0B10,
+       GL_POINT_SIZE                   = 0x0B11,
+       GL_POINT_SIZE_GRANULARITY       = 0x0B13,
+       GL_POINT_SIZE_RANGE             = 0x0B12,
+
+       /* Lines */
+       GL_LINE_SMOOTH                  = 0x0B20,
+       GL_LINE_STIPPLE                 = 0x0B24,
+       GL_LINE_STIPPLE_PATTERN         = 0x0B25,
+       GL_LINE_STIPPLE_REPEAT          = 0x0B26,
+       GL_LINE_WIDTH                   = 0x0B21,
+       GL_LINE_WIDTH_GRANULARITY       = 0x0B23,
+       GL_LINE_WIDTH_RANGE             = 0x0B22,
+
+       /* Polygons */
+       GL_POINT                        = 0x1B00,
+       GL_LINE                         = 0x1B01,
+       GL_FILL                         = 0x1B02,
+       GL_CW                           = 0x0900,
+       GL_CCW                          = 0x0901,
+       GL_FRONT                        = 0x0404,
+       GL_BACK                         = 0x0405,
+       GL_POLYGON_MODE                 = 0x0B40,
+       GL_POLYGON_SMOOTH               = 0x0B41,
+       GL_POLYGON_STIPPLE              = 0x0B42,
+       GL_EDGE_FLAG                    = 0x0B43,
+       GL_CULL_FACE                    = 0x0B44,
+       GL_CULL_FACE_MODE               = 0x0B45,
+       GL_FRONT_FACE                   = 0x0B46,
+       GL_POLYGON_OFFSET_FACTOR        = 0x8038,
+       GL_POLYGON_OFFSET_UNITS         = 0x2A00,
+       GL_POLYGON_OFFSET_POINT         = 0x2A01,
+       GL_POLYGON_OFFSET_LINE          = 0x2A02,
+       GL_POLYGON_OFFSET_FILL          = 0x8037,
+
+       /* Display Lists */
+       GL_COMPILE                      = 0x1300,
+       GL_COMPILE_AND_EXECUTE          = 0x1301,
+       GL_LIST_BASE                    = 0x0B32,
+       GL_LIST_INDEX                   = 0x0B33,
+       GL_LIST_MODE                    = 0x0B30,
+
+       /* Depth buffer */
+       GL_NEVER                        = 0x0200,
+       GL_LESS                         = 0x0201,
+       GL_GEQUAL                       = 0x0206,
+       GL_LEQUAL                       = 0x0203,
+       GL_GREATER                      = 0x0204,
+       GL_NOTEQUAL                     = 0x0205,
+       GL_EQUAL                        = 0x0202,
+       GL_ALWAYS                       = 0x0207,
+       GL_DEPTH_TEST                   = 0x0B71,
+       GL_DEPTH_BITS                   = 0x0D56,
+       GL_DEPTH_CLEAR_VALUE            = 0x0B73,
+       GL_DEPTH_FUNC                   = 0x0B74,
+       GL_DEPTH_RANGE                  = 0x0B70,
+       GL_DEPTH_WRITEMASK              = 0x0B72,
+       GL_DEPTH_COMPONENT              = 0x1902,
+
+       /* Lighting */
+       GL_LIGHTING                     = 0x0B50,
+       GL_LIGHT0                       = 0x4000,
+       GL_LIGHT1                       = 0x4001,
+       GL_LIGHT2                       = 0x4002,
+       GL_LIGHT3                       = 0x4003,
+       GL_LIGHT4                       = 0x4004,
+       GL_LIGHT5                       = 0x4005,
+       GL_LIGHT6                       = 0x4006,
+       GL_LIGHT7                       = 0x4007,
+       GL_SPOT_EXPONENT                = 0x1205,
+       GL_SPOT_CUTOFF                  = 0x1206,
+       GL_CONSTANT_ATTENUATION         = 0x1207,
+       GL_LINEAR_ATTENUATION           = 0x1208,
+       GL_QUADRATIC_ATTENUATION        = 0x1209,
+       GL_AMBIENT                      = 0x1200,
+       GL_DIFFUSE                      = 0x1201,
+       GL_SPECULAR                     = 0x1202,
+       GL_SHININESS                    = 0x1601,
+       GL_EMISSION                     = 0x1600,
+       GL_POSITION                     = 0x1203,
+       GL_SPOT_DIRECTION               = 0x1204,
+       GL_AMBIENT_AND_DIFFUSE          = 0x1602,
+       GL_COLOR_INDEXES                = 0x1603,
+       GL_LIGHT_MODEL_TWO_SIDE         = 0x0B52,
+       GL_LIGHT_MODEL_LOCAL_VIEWER     = 0x0B51,
+       GL_LIGHT_MODEL_AMBIENT          = 0x0B53,
+       GL_FRONT_AND_BACK               = 0x0408,
+       GL_SHADE_MODEL                  = 0x0B54,
+       GL_FLAT                         = 0x1D00,
+       GL_SMOOTH                       = 0x1D01,
+       GL_COLOR_MATERIAL               = 0x0B57,
+       GL_COLOR_MATERIAL_FACE          = 0x0B55,
+       GL_COLOR_MATERIAL_PARAMETER     = 0x0B56,
+       GL_NORMALIZE                    = 0x0BA1,
+
+       /* User clipping planes */
+       GL_CLIP_PLANE0                  = 0x3000,
+       GL_CLIP_PLANE1                  = 0x3001,
+       GL_CLIP_PLANE2                  = 0x3002,
+       GL_CLIP_PLANE3                  = 0x3003,
+       GL_CLIP_PLANE4                  = 0x3004,
+       GL_CLIP_PLANE5                  = 0x3005,
+
+       /* Accumulation buffer */
+       GL_ACCUM_RED_BITS               = 0x0D58,
+       GL_ACCUM_GREEN_BITS             = 0x0D59,
+       GL_ACCUM_BLUE_BITS              = 0x0D5A,
+       GL_ACCUM_ALPHA_BITS             = 0x0D5B,
+       GL_ACCUM_CLEAR_VALUE            = 0x0B80,
+       GL_ACCUM                        = 0x0100,
+       GL_ADD                          = 0x0104,
+       GL_LOAD                         = 0x0101,
+       GL_MULT                         = 0x0103,
+       GL_RETURN                       = 0x0102,
+
+       /* Alpha testing */
+       GL_ALPHA_TEST                   = 0x0BC0,
+       GL_ALPHA_TEST_REF               = 0x0BC2,
+       GL_ALPHA_TEST_FUNC              = 0x0BC1,
+
+       /* Blending */
+       GL_BLEND                        = 0x0BE2,
+       GL_BLEND_SRC                    = 0x0BE1,
+       GL_BLEND_DST                    = 0x0BE0,
+       GL_ZERO                         = 0,
+       GL_ONE                          = 1,
+       GL_SRC_COLOR                    = 0x0300,
+       GL_ONE_MINUS_SRC_COLOR          = 0x0301,
+       GL_DST_COLOR                    = 0x0306,
+       GL_ONE_MINUS_DST_COLOR          = 0x0307,
+       GL_SRC_ALPHA                    = 0x0302,
+       GL_ONE_MINUS_SRC_ALPHA          = 0x0303,
+       GL_DST_ALPHA                    = 0x0304,
+       GL_ONE_MINUS_DST_ALPHA          = 0x0305,
+       GL_SRC_ALPHA_SATURATE           = 0x0308,
+       GL_CONSTANT_COLOR               = 0x8001,
+       GL_ONE_MINUS_CONSTANT_COLOR     = 0x8002,
+       GL_CONSTANT_ALPHA               = 0x8003,
+       GL_ONE_MINUS_CONSTANT_ALPHA     = 0x8004,
+
+       /* Render Mode */
+       GL_FEEDBACK                     = 0x1C01,
+       GL_RENDER                       = 0x1C00,
+       GL_SELECT                       = 0x1C02,
+
+       /* Feedback */
+       GL_2D                           = 0x0600,
+       GL_3D                           = 0x0601,
+       GL_3D_COLOR                     = 0x0602,
+       GL_3D_COLOR_TEXTURE             = 0x0603,
+       GL_4D_COLOR_TEXTURE             = 0x0604,
+       GL_POINT_TOKEN                  = 0x0701,
+       GL_LINE_TOKEN                   = 0x0702,
+       GL_LINE_RESET_TOKEN             = 0x0707,
+       GL_POLYGON_TOKEN                = 0x0703,
+       GL_BITMAP_TOKEN                 = 0x0704,
+       GL_DRAW_PIXEL_TOKEN             = 0x0705,
+       GL_COPY_PIXEL_TOKEN             = 0x0706,
+       GL_PASS_THROUGH_TOKEN           = 0x0700,
+       GL_FEEDBACK_BUFFER_POINTER      = 0x0DF0,
+       GL_FEEDBACK_BUFFER_SIZE         = 0x0DF1,
+       GL_FEEDBACK_BUFFER_TYPE         = 0x0DF2,
+
+       /* Selection */
+       GL_SELECTION_BUFFER_POINTER     = 0x0DF3,
+       GL_SELECTION_BUFFER_SIZE        = 0x0DF4,
+
+       /* Fog */
+       GL_FOG                          = 0x0B60,
+       GL_FOG_MODE                     = 0x0B65,
+       GL_FOG_DENSITY                  = 0x0B62,
+       GL_FOG_COLOR                    = 0x0B66,
+       GL_FOG_INDEX                    = 0x0B61,
+       GL_FOG_START                    = 0x0B63,
+       GL_FOG_END                      = 0x0B64,
+       GL_LINEAR                       = 0x2601,
+       GL_EXP                          = 0x0800,
+       GL_EXP2                         = 0x0801,
+
+       /* Logic Ops */
+       GL_LOGIC_OP                     = 0x0BF1,
+       GL_INDEX_LOGIC_OP               = 0x0BF1,
+       GL_COLOR_LOGIC_OP               = 0x0BF2,
+       GL_LOGIC_OP_MODE                = 0x0BF0,
+       GL_CLEAR                        = 0x1500,
+       GL_SET                          = 0x150F,
+       GL_COPY                         = 0x1503,
+       GL_COPY_INVERTED                = 0x150C,
+       GL_NOOP                         = 0x1505,
+       GL_INVERT                       = 0x150A,
+       GL_AND                          = 0x1501,
+       GL_NAND                         = 0x150E,
+       GL_OR                           = 0x1507,
+       GL_NOR                          = 0x1508,
+       GL_XOR                          = 0x1506,
+       GL_EQUIV                        = 0x1509,
+       GL_AND_REVERSE                  = 0x1502,
+       GL_AND_INVERTED                 = 0x1504,
+       GL_OR_REVERSE                   = 0x150B,
+       GL_OR_INVERTED                  = 0x150D,
+
+       /* Stencil */
+       GL_STENCIL_TEST                 = 0x0B90,
+       GL_STENCIL_WRITEMASK            = 0x0B98,
+       GL_STENCIL_BITS                 = 0x0D57,
+       GL_STENCIL_FUNC                 = 0x0B92,
+       GL_STENCIL_VALUE_MASK           = 0x0B93,
+       GL_STENCIL_REF                  = 0x0B97,
+       GL_STENCIL_FAIL                 = 0x0B94,
+       GL_STENCIL_PASS_DEPTH_PASS      = 0x0B96,
+       GL_STENCIL_PASS_DEPTH_FAIL      = 0x0B95,
+       GL_STENCIL_CLEAR_VALUE          = 0x0B91,
+       GL_STENCIL_INDEX                = 0x1901,
+       GL_KEEP                         = 0x1E00,
+       GL_REPLACE                      = 0x1E01,
+       GL_INCR                         = 0x1E02,
+       GL_DECR                         = 0x1E03,
+
+       /* Buffers, Pixel Drawing/Reading */
+       GL_NONE                         = 0,
+       GL_LEFT                         = 0x0406,
+       GL_RIGHT                        = 0x0407,
+       /*GL_FRONT                      = 0x0404, */
+       /*GL_BACK                       = 0x0405, */
+       /*GL_FRONT_AND_BACK             = 0x0408, */
+       GL_FRONT_LEFT                   = 0x0400,
+       GL_FRONT_RIGHT                  = 0x0401,
+       GL_BACK_LEFT                    = 0x0402,
+       GL_BACK_RIGHT                   = 0x0403,
+       GL_AUX0                         = 0x0409,
+       GL_AUX1                         = 0x040A,
+       GL_AUX2                         = 0x040B,
+       GL_AUX3                         = 0x040C,
+       GL_COLOR_INDEX                  = 0x1900,
+       GL_RED                          = 0x1903,
+       GL_GREEN                        = 0x1904,
+       GL_BLUE                         = 0x1905,
+       GL_ALPHA                        = 0x1906,
+       GL_LUMINANCE                    = 0x1909,
+       GL_LUMINANCE_ALPHA              = 0x190A,
+       GL_ALPHA_BITS                   = 0x0D55,
+       GL_RED_BITS                     = 0x0D52,
+       GL_GREEN_BITS                   = 0x0D53,
+       GL_BLUE_BITS                    = 0x0D54,
+       GL_INDEX_BITS                   = 0x0D51,
+       GL_SUBPIXEL_BITS                = 0x0D50,
+       GL_AUX_BUFFERS                  = 0x0C00,
+       GL_READ_BUFFER                  = 0x0C02,
+       GL_DRAW_BUFFER                  = 0x0C01,
+       GL_DOUBLEBUFFER                 = 0x0C32,
+       GL_STEREO                       = 0x0C33,
+       GL_BITMAP                       = 0x1A00,
+       GL_COLOR                        = 0x1800,
+       GL_DEPTH                        = 0x1801,
+       GL_STENCIL                      = 0x1802,
+       GL_DITHER                       = 0x0BD0,
+       GL_RGB                          = 0x1907,
+       GL_RGBA                         = 0x1908,
+
+       /* Implementation limits */
+       GL_MAX_LIST_NESTING             = 0x0B31,
+       GL_MAX_ATTRIB_STACK_DEPTH       = 0x0D35,
+       GL_MAX_MODELVIEW_STACK_DEPTH    = 0x0D36,
+       GL_MAX_NAME_STACK_DEPTH         = 0x0D37,
+       GL_MAX_PROJECTION_STACK_DEPTH   = 0x0D38,
+       GL_MAX_TEXTURE_STACK_DEPTH      = 0x0D39,
+       GL_MAX_EVAL_ORDER               = 0x0D30,
+       GL_MAX_LIGHTS                   = 0x0D31,
+       GL_MAX_CLIP_PLANES              = 0x0D32,
+       GL_MAX_TEXTURE_SIZE             = 0x0D33,
+       GL_MAX_PIXEL_MAP_TABLE          = 0x0D34,
+       GL_MAX_VIEWPORT_DIMS            = 0x0D3A,
+       GL_MAX_CLIENT_ATTRIB_STACK_DEPTH= 0x0D3B,
+
+       /* Gets */
+       GL_ATTRIB_STACK_DEPTH           = 0x0BB0,
+       GL_CLIENT_ATTRIB_STACK_DEPTH    = 0x0BB1,
+       GL_COLOR_CLEAR_VALUE            = 0x0C22,
+       GL_COLOR_WRITEMASK              = 0x0C23,
+       GL_CURRENT_INDEX                = 0x0B01,
+       GL_CURRENT_COLOR                = 0x0B00,
+       GL_CURRENT_NORMAL               = 0x0B02,
+       GL_CURRENT_RASTER_COLOR         = 0x0B04,
+       GL_CURRENT_RASTER_DISTANCE      = 0x0B09,
+       GL_CURRENT_RASTER_INDEX         = 0x0B05,
+       GL_CURRENT_RASTER_POSITION      = 0x0B07,
+       GL_CURRENT_RASTER_TEXTURE_COORDS = 0x0B06,
+       GL_CURRENT_RASTER_POSITION_VALID = 0x0B08,
+       GL_CURRENT_TEXTURE_COORDS       = 0x0B03,
+       GL_INDEX_CLEAR_VALUE            = 0x0C20,
+       GL_INDEX_MODE                   = 0x0C30,
+       GL_INDEX_WRITEMASK              = 0x0C21,
+       GL_MODELVIEW_MATRIX             = 0x0BA6,
+       GL_MODELVIEW_STACK_DEPTH        = 0x0BA3,
+       GL_NAME_STACK_DEPTH             = 0x0D70,
+       GL_PROJECTION_MATRIX            = 0x0BA7,
+       GL_PROJECTION_STACK_DEPTH       = 0x0BA4,
+       GL_RENDER_MODE                  = 0x0C40,
+       GL_RGBA_MODE                    = 0x0C31,
+       GL_TEXTURE_MATRIX               = 0x0BA8,
+       GL_TEXTURE_STACK_DEPTH          = 0x0BA5,
+       GL_VIEWPORT                     = 0x0BA2,
+
+       /* Evaluators */
+       GL_AUTO_NORMAL                  = 0x0D80,
+       GL_MAP1_COLOR_4                 = 0x0D90,
+       GL_MAP1_GRID_DOMAIN             = 0x0DD0,
+       GL_MAP1_GRID_SEGMENTS           = 0x0DD1,
+       GL_MAP1_INDEX                   = 0x0D91,
+       GL_MAP1_NORMAL                  = 0x0D92,
+       GL_MAP1_TEXTURE_COORD_1         = 0x0D93,
+       GL_MAP1_TEXTURE_COORD_2         = 0x0D94,
+       GL_MAP1_TEXTURE_COORD_3         = 0x0D95,
+       GL_MAP1_TEXTURE_COORD_4         = 0x0D96,
+       GL_MAP1_VERTEX_3                = 0x0D97,
+       GL_MAP1_VERTEX_4                = 0x0D98,
+       GL_MAP2_COLOR_4                 = 0x0DB0,
+       GL_MAP2_GRID_DOMAIN             = 0x0DD2,
+       GL_MAP2_GRID_SEGMENTS           = 0x0DD3,
+       GL_MAP2_INDEX                   = 0x0DB1,
+       GL_MAP2_NORMAL                  = 0x0DB2,
+       GL_MAP2_TEXTURE_COORD_1         = 0x0DB3,
+       GL_MAP2_TEXTURE_COORD_2         = 0x0DB4,
+       GL_MAP2_TEXTURE_COORD_3         = 0x0DB5,
+       GL_MAP2_TEXTURE_COORD_4         = 0x0DB6,
+       GL_MAP2_VERTEX_3                = 0x0DB7,
+       GL_MAP2_VERTEX_4                = 0x0DB8,
+       GL_COEFF                        = 0x0A00,
+       GL_DOMAIN                       = 0x0A02,
+       GL_ORDER                        = 0x0A01,
+
+       /* Hints */
+       GL_FOG_HINT                     = 0x0C54,
+       GL_LINE_SMOOTH_HINT             = 0x0C52,
+       GL_PERSPECTIVE_CORRECTION_HINT  = 0x0C50,
+       GL_POINT_SMOOTH_HINT            = 0x0C51,
+       GL_POLYGON_SMOOTH_HINT          = 0x0C53,
+       GL_DONT_CARE                    = 0x1100,
+       GL_FASTEST                      = 0x1101,
+       GL_NICEST                       = 0x1102,
+
+       /* Scissor box */
+       GL_SCISSOR_TEST                 = 0x0C11,
+       GL_SCISSOR_BOX                  = 0x0C10,
+
+       /* Pixel Mode / Transfer */
+       GL_MAP_COLOR                    = 0x0D10,
+       GL_MAP_STENCIL                  = 0x0D11,
+       GL_INDEX_SHIFT                  = 0x0D12,
+       GL_INDEX_OFFSET                 = 0x0D13,
+       GL_RED_SCALE                    = 0x0D14,
+       GL_RED_BIAS                     = 0x0D15,
+       GL_GREEN_SCALE                  = 0x0D18,
+       GL_GREEN_BIAS                   = 0x0D19,
+       GL_BLUE_SCALE                   = 0x0D1A,
+       GL_BLUE_BIAS                    = 0x0D1B,
+       GL_ALPHA_SCALE                  = 0x0D1C,
+       GL_ALPHA_BIAS                   = 0x0D1D,
+       GL_DEPTH_SCALE                  = 0x0D1E,
+       GL_DEPTH_BIAS                   = 0x0D1F,
+       GL_PIXEL_MAP_S_TO_S_SIZE        = 0x0CB1,
+       GL_PIXEL_MAP_I_TO_I_SIZE        = 0x0CB0,
+       GL_PIXEL_MAP_I_TO_R_SIZE        = 0x0CB2,
+       GL_PIXEL_MAP_I_TO_G_SIZE        = 0x0CB3,
+       GL_PIXEL_MAP_I_TO_B_SIZE        = 0x0CB4,
+       GL_PIXEL_MAP_I_TO_A_SIZE        = 0x0CB5,
+       GL_PIXEL_MAP_R_TO_R_SIZE        = 0x0CB6,
+       GL_PIXEL_MAP_G_TO_G_SIZE        = 0x0CB7,
+       GL_PIXEL_MAP_B_TO_B_SIZE        = 0x0CB8,
+       GL_PIXEL_MAP_A_TO_A_SIZE        = 0x0CB9,
+       GL_PIXEL_MAP_S_TO_S             = 0x0C71,
+       GL_PIXEL_MAP_I_TO_I             = 0x0C70,
+       GL_PIXEL_MAP_I_TO_R             = 0x0C72,
+       GL_PIXEL_MAP_I_TO_G             = 0x0C73,
+       GL_PIXEL_MAP_I_TO_B             = 0x0C74,
+       GL_PIXEL_MAP_I_TO_A             = 0x0C75,
+       GL_PIXEL_MAP_R_TO_R             = 0x0C76,
+       GL_PIXEL_MAP_G_TO_G             = 0x0C77,
+       GL_PIXEL_MAP_B_TO_B             = 0x0C78,
+       GL_PIXEL_MAP_A_TO_A             = 0x0C79,
+       GL_PACK_ALIGNMENT               = 0x0D05,
+       GL_PACK_LSB_FIRST               = 0x0D01,
+       GL_PACK_ROW_LENGTH              = 0x0D02,
+       GL_PACK_SKIP_PIXELS             = 0x0D04,
+       GL_PACK_SKIP_ROWS               = 0x0D03,
+       GL_PACK_SWAP_BYTES              = 0x0D00,
+       GL_UNPACK_ALIGNMENT             = 0x0CF5,
+       GL_UNPACK_LSB_FIRST             = 0x0CF1,
+       GL_UNPACK_ROW_LENGTH            = 0x0CF2,
+       GL_UNPACK_SKIP_PIXELS           = 0x0CF4,
+       GL_UNPACK_SKIP_ROWS             = 0x0CF3,
+       GL_UNPACK_SWAP_BYTES            = 0x0CF0,
+       GL_ZOOM_X                       = 0x0D16,
+       GL_ZOOM_Y                       = 0x0D17,
+
+       /* Texture mapping */
+       GL_TEXTURE_ENV                  = 0x2300,
+       GL_TEXTURE_ENV_MODE             = 0x2200,
+       GL_TEXTURE_1D                   = 0x0DE0,
+       GL_TEXTURE_2D                   = 0x0DE1,
+       GL_TEXTURE_WRAP_S               = 0x2802,
+       GL_TEXTURE_WRAP_T               = 0x2803,
+       GL_TEXTURE_MAG_FILTER           = 0x2800,
+       GL_TEXTURE_MIN_FILTER           = 0x2801,
+       GL_TEXTURE_ENV_COLOR            = 0x2201,
+       GL_TEXTURE_GEN_S                = 0x0C60,
+       GL_TEXTURE_GEN_T                = 0x0C61,
+       GL_TEXTURE_GEN_MODE             = 0x2500,
+       GL_TEXTURE_BORDER_COLOR         = 0x1004,
+       GL_TEXTURE_WIDTH                = 0x1000,
+       GL_TEXTURE_HEIGHT               = 0x1001,
+       GL_TEXTURE_BORDER               = 0x1005,
+       GL_TEXTURE_COMPONENTS           = 0x1003,
+       GL_TEXTURE_RED_SIZE             = 0x805C,
+       GL_TEXTURE_GREEN_SIZE           = 0x805D,
+       GL_TEXTURE_BLUE_SIZE            = 0x805E,
+       GL_TEXTURE_ALPHA_SIZE           = 0x805F,
+       GL_TEXTURE_LUMINANCE_SIZE       = 0x8060,
+       GL_TEXTURE_INTENSITY_SIZE       = 0x8061,
+       GL_NEAREST_MIPMAP_NEAREST       = 0x2700,
+       GL_NEAREST_MIPMAP_LINEAR        = 0x2702,
+       GL_LINEAR_MIPMAP_NEAREST        = 0x2701,
+       GL_LINEAR_MIPMAP_LINEAR         = 0x2703,
+       GL_OBJECT_LINEAR                = 0x2401,
+       GL_OBJECT_PLANE                 = 0x2501,
+       GL_EYE_LINEAR                   = 0x2400,
+       GL_EYE_PLANE                    = 0x2502,
+       GL_SPHERE_MAP                   = 0x2402,
+       GL_DECAL                        = 0x2101,
+       GL_MODULATE                     = 0x2100,
+       GL_NEAREST                      = 0x2600,
+       GL_REPEAT                       = 0x2901,
+       GL_CLAMP                        = 0x2900,
+       GL_S                            = 0x2000,
+       GL_T                            = 0x2001,
+       GL_R                            = 0x2002,
+       GL_Q                            = 0x2003,
+       GL_TEXTURE_GEN_R                = 0x0C62,
+       GL_TEXTURE_GEN_Q                = 0x0C63,
+
+       /* GL 1.1 texturing */
+       GL_PROXY_TEXTURE_1D             = 0x8063,
+       GL_PROXY_TEXTURE_2D             = 0x8064,
+       GL_TEXTURE_PRIORITY             = 0x8066,
+       GL_TEXTURE_RESIDENT             = 0x8067,
+       GL_TEXTURE_BINDING_1D           = 0x8068,
+       GL_TEXTURE_BINDING_2D           = 0x8069,
+       GL_TEXTURE_INTERNAL_FORMAT      = 0x1003,
+
+       /* GL 1.2 texturing */
+       GL_PACK_SKIP_IMAGES             = 0x806B,
+       GL_PACK_IMAGE_HEIGHT            = 0x806C,
+       GL_UNPACK_SKIP_IMAGES           = 0x806D,
+       GL_UNPACK_IMAGE_HEIGHT          = 0x806E,
+       GL_TEXTURE_3D                   = 0x806F,
+       GL_PROXY_TEXTURE_3D             = 0x8070,
+       GL_TEXTURE_DEPTH                = 0x8071,
+       GL_TEXTURE_WRAP_R               = 0x8072,
+       GL_MAX_3D_TEXTURE_SIZE          = 0x8073,
+       GL_TEXTURE_BINDING_3D           = 0x806A,
+
+       /* Internal texture formats (GL 1.1) */
+       GL_ALPHA4                       = 0x803B,
+       GL_ALPHA8                       = 0x803C,
+       GL_ALPHA12                      = 0x803D,
+       GL_ALPHA16                      = 0x803E,
+       GL_LUMINANCE4                   = 0x803F,
+       GL_LUMINANCE8                   = 0x8040,
+       GL_LUMINANCE12                  = 0x8041,
+       GL_LUMINANCE16                  = 0x8042,
+       GL_LUMINANCE4_ALPHA4            = 0x8043,
+       GL_LUMINANCE6_ALPHA2            = 0x8044,
+       GL_LUMINANCE8_ALPHA8            = 0x8045,
+       GL_LUMINANCE12_ALPHA4           = 0x8046,
+       GL_LUMINANCE12_ALPHA12          = 0x8047,
+       GL_LUMINANCE16_ALPHA16          = 0x8048,
+       GL_INTENSITY                    = 0x8049,
+       GL_INTENSITY4                   = 0x804A,
+       GL_INTENSITY8                   = 0x804B,
+       GL_INTENSITY12                  = 0x804C,
+       GL_INTENSITY16                  = 0x804D,
+       GL_R3_G3_B2                     = 0x2A10,
+       GL_RGB4                         = 0x804F,
+       GL_RGB5                         = 0x8050,
+       GL_RGB8                         = 0x8051,
+       GL_RGB10                        = 0x8052,
+       GL_RGB12                        = 0x8053,
+       GL_RGB16                        = 0x8054,
+       GL_RGBA2                        = 0x8055,
+       GL_RGBA4                        = 0x8056,
+       GL_RGB5_A1                      = 0x8057,
+       GL_RGBA8                        = 0x8058,
+       GL_RGB10_A2                     = 0x8059,
+       GL_RGBA12                       = 0x805A,
+       GL_RGBA16                       = 0x805B,
+
+       /* Utility */
+       GL_VENDOR                       = 0x1F00,
+       GL_RENDERER                     = 0x1F01,
+       GL_VERSION                      = 0x1F02,
+       GL_EXTENSIONS                   = 0x1F03,
+
+       /* Errors */
+       GL_INVALID_VALUE                = 0x0501,
+       GL_INVALID_ENUM                 = 0x0500,
+       GL_INVALID_OPERATION            = 0x0502,
+       GL_STACK_OVERFLOW               = 0x0503,
+       GL_STACK_UNDERFLOW              = 0x0504,
+       GL_OUT_OF_MEMORY                = 0x0505,
+
+       /*
+        * Extensions
+        */
+
+       /* GL_EXT_blend_minmax and GL_EXT_blend_color */
+       GL_CONSTANT_COLOR_EXT                   = 0x8001,
+       GL_ONE_MINUS_CONSTANT_COLOR_EXT         = 0x8002,
+       GL_CONSTANT_ALPHA_EXT                   = 0x8003,
+       GL_ONE_MINUS_CONSTANT_ALPHA_EXT         = 0x8004,
+       GL_BLEND_EQUATION_EXT                   = 0x8009,
+       GL_MIN_EXT                              = 0x8007,
+       GL_MAX_EXT                              = 0x8008,
+       GL_FUNC_ADD_EXT                         = 0x8006,
+       GL_FUNC_SUBTRACT_EXT                    = 0x800A,
+       GL_FUNC_REVERSE_SUBTRACT_EXT            = 0x800B,
+       GL_BLEND_COLOR_EXT                      = 0x8005,
+
+       /* GL_EXT_polygon_offset */
+       GL_POLYGON_OFFSET_EXT                   = 0x8037,
+       GL_POLYGON_OFFSET_FACTOR_EXT            = 0x8038,
+       GL_POLYGON_OFFSET_BIAS_EXT              = 0x8039,
+
+       /* GL_EXT_vertex_array */
+       GL_VERTEX_ARRAY_EXT                     = 0x8074,
+       GL_NORMAL_ARRAY_EXT                     = 0x8075,
+       GL_COLOR_ARRAY_EXT                      = 0x8076,
+       GL_INDEX_ARRAY_EXT                      = 0x8077,
+       GL_TEXTURE_COORD_ARRAY_EXT              = 0x8078,
+       GL_EDGE_FLAG_ARRAY_EXT                  = 0x8079,
+       GL_VERTEX_ARRAY_SIZE_EXT                = 0x807A,
+       GL_VERTEX_ARRAY_TYPE_EXT                = 0x807B,
+       GL_VERTEX_ARRAY_STRIDE_EXT              = 0x807C,
+       GL_VERTEX_ARRAY_COUNT_EXT               = 0x807D,
+       GL_NORMAL_ARRAY_TYPE_EXT                = 0x807E,
+       GL_NORMAL_ARRAY_STRIDE_EXT              = 0x807F,
+       GL_NORMAL_ARRAY_COUNT_EXT               = 0x8080,
+       GL_COLOR_ARRAY_SIZE_EXT                 = 0x8081,
+       GL_COLOR_ARRAY_TYPE_EXT                 = 0x8082,
+       GL_COLOR_ARRAY_STRIDE_EXT               = 0x8083,
+       GL_COLOR_ARRAY_COUNT_EXT                = 0x8084,
+       GL_INDEX_ARRAY_TYPE_EXT                 = 0x8085,
+       GL_INDEX_ARRAY_STRIDE_EXT               = 0x8086,
+       GL_INDEX_ARRAY_COUNT_EXT                = 0x8087,
+       GL_TEXTURE_COORD_ARRAY_SIZE_EXT         = 0x8088,
+       GL_TEXTURE_COORD_ARRAY_TYPE_EXT         = 0x8089,
+       GL_TEXTURE_COORD_ARRAY_STRIDE_EXT       = 0x808A,
+       GL_TEXTURE_COORD_ARRAY_COUNT_EXT        = 0x808B,
+       GL_EDGE_FLAG_ARRAY_STRIDE_EXT           = 0x808C,
+       GL_EDGE_FLAG_ARRAY_COUNT_EXT            = 0x808D,
+       GL_VERTEX_ARRAY_POINTER_EXT             = 0x808E,
+       GL_NORMAL_ARRAY_POINTER_EXT             = 0x808F,
+       GL_COLOR_ARRAY_POINTER_EXT              = 0x8090,
+       GL_INDEX_ARRAY_POINTER_EXT              = 0x8091,
+       GL_TEXTURE_COORD_ARRAY_POINTER_EXT      = 0x8092,
+       GL_EDGE_FLAG_ARRAY_POINTER_EXT          = 0x8093,
+
+       /* GL_EXT_texture_object */
+       GL_TEXTURE_PRIORITY_EXT                 = 0x8066,
+       GL_TEXTURE_RESIDENT_EXT                 = 0x8067,
+       GL_TEXTURE_1D_BINDING_EXT               = 0x8068,
+       GL_TEXTURE_2D_BINDING_EXT               = 0x8069,
+
+       /* GL_EXT_texture3D */
+       GL_PACK_SKIP_IMAGES_EXT                 = 0x806B,
+       GL_PACK_IMAGE_HEIGHT_EXT                = 0x806C,
+       GL_UNPACK_SKIP_IMAGES_EXT               = 0x806D,
+       GL_UNPACK_IMAGE_HEIGHT_EXT              = 0x806E,
+       GL_TEXTURE_3D_EXT                       = 0x806F,
+       GL_PROXY_TEXTURE_3D_EXT                 = 0x8070,
+       GL_TEXTURE_DEPTH_EXT                    = 0x8071,
+       GL_TEXTURE_WRAP_R_EXT                   = 0x8072,
+       GL_MAX_3D_TEXTURE_SIZE_EXT              = 0x8073,
+       GL_TEXTURE_3D_BINDING_EXT               = 0x806A,
+
+       /* GL_EXT_paletted_texture */
+       GL_TABLE_TOO_LARGE_EXT                  = 0x8031,
+       GL_COLOR_TABLE_FORMAT_EXT               = 0x80D8,
+       GL_COLOR_TABLE_WIDTH_EXT                = 0x80D9,
+       GL_COLOR_TABLE_RED_SIZE_EXT             = 0x80DA,
+       GL_COLOR_TABLE_GREEN_SIZE_EXT           = 0x80DB,
+       GL_COLOR_TABLE_BLUE_SIZE_EXT            = 0x80DC,
+       GL_COLOR_TABLE_ALPHA_SIZE_EXT           = 0x80DD,
+       GL_COLOR_TABLE_LUMINANCE_SIZE_EXT       = 0x80DE,
+       GL_COLOR_TABLE_INTENSITY_SIZE_EXT       = 0x80DF,
+       GL_TEXTURE_INDEX_SIZE_EXT               = 0x80ED,
+       GL_COLOR_INDEX1_EXT                     = 0x80E2,
+       GL_COLOR_INDEX2_EXT                     = 0x80E3,
+       GL_COLOR_INDEX4_EXT                     = 0x80E4,
+       GL_COLOR_INDEX8_EXT                     = 0x80E5,
+       GL_COLOR_INDEX12_EXT                    = 0x80E6,
+       GL_COLOR_INDEX16_EXT                    = 0x80E7,
+
+       /* GL_EXT_shared_texture_palette */
+       GL_SHARED_TEXTURE_PALETTE_EXT           = 0x81FB,
+
+       /* GL_EXT_point_parameters */
+       GL_POINT_SIZE_MIN_EXT                   = 0x8126,
+       GL_POINT_SIZE_MAX_EXT                   = 0x8127,
+       GL_POINT_FADE_THRESHOLD_SIZE_EXT        = 0x8128,
+       GL_DISTANCE_ATTENUATION_EXT             = 0x8129,
+
+       /* GL_EXT_rescale_normal */
+       GL_RESCALE_NORMAL_EXT                   = 0x803A,
+
+       /* GL_EXT_abgr */
+       GL_ABGR_EXT                             = 0x8000,
+
+       /* GL_EXT_stencil_wrap */
+       GL_INCR_WRAP_EXT                        = 0x8507,
+       GL_DECR_WRAP_EXT                        = 0x8508,
+
+       /* GL_SGIS_texture_edge_clamp */
+       GL_CLAMP_TO_EDGE_SGIS                   = 0x812F,
+
+       /* GL_INGR_blend_func_separate */
+       GL_BLEND_DST_RGB_INGR                   = 0x80C8,
+       GL_BLEND_SRC_RGB_INGR                   = 0x80C9,
+       GL_BLEND_DST_ALPHA_INGR                 = 0x80CA,
+       GL_BLEND_SRC_ALPHA_INGR                 = 0x80CB,
+
+       /* OpenGL 1.2 */
+       GL_RESCALE_NORMAL                       = 0x803A,
+       GL_CLAMP_TO_EDGE                        = 0x812F,
+       GL_MAX_ELEMENTS_VERTICES                = 0xF0E8,
+       GL_MAX_ELEMENTS_INDICES                 = 0xF0E9,
+       GL_BGR                                  = 0x80E0,
+       GL_BGRA                                 = 0x80E1,
+       GL_UNSIGNED_BYTE_3_3_2                  = 0x8032,
+       GL_UNSIGNED_BYTE_2_3_3_REV              = 0x8362,
+       GL_UNSIGNED_SHORT_5_6_5                 = 0x8363,
+       GL_UNSIGNED_SHORT_5_6_5_REV             = 0x8364,
+       GL_UNSIGNED_SHORT_4_4_4_4               = 0x8033,
+       GL_UNSIGNED_SHORT_4_4_4_4_REV           = 0x8365,
+       GL_UNSIGNED_SHORT_5_5_5_1               = 0x8034,
+       GL_UNSIGNED_SHORT_1_5_5_5_REV           = 0x8366,
+       GL_UNSIGNED_INT_8_8_8_8                 = 0x8035,
+       GL_UNSIGNED_INT_8_8_8_8_REV             = 0x8367,
+       GL_UNSIGNED_INT_10_10_10_2              = 0x8036,
+       GL_UNSIGNED_INT_2_10_10_10_REV          = 0x8368,
+       GL_LIGHT_MODEL_COLOR_CONTROL            = 0x81F8,
+       GL_SINGLE_COLOR                         = 0x81F9,
+       GL_SEPARATE_SPECULAR_COLOR              = 0x81FA,
+       GL_TEXTURE_MIN_LOD                      = 0x813A,
+       GL_TEXTURE_MAX_LOD                      = 0x813B,
+       GL_TEXTURE_BASE_LEVEL                   = 0x813C,
+       GL_TEXTURE_MAX_LEVEL                    = 0x813D,
+
+       /* GL_ARB_multitexture */
+       GL_TEXTURE0_ARB                         = 0x84C0,
+       GL_TEXTURE1_ARB                         = 0x84C1,
+       GL_TEXTURE2_ARB                         = 0x84C2,
+       GL_TEXTURE3_ARB                         = 0x84C3,
+       GL_TEXTURE4_ARB                         = 0x84C4,
+       GL_TEXTURE5_ARB                         = 0x84C5,
+       GL_TEXTURE6_ARB                         = 0x84C6,
+       GL_TEXTURE7_ARB                         = 0x84C7,
+       GL_TEXTURE8_ARB                         = 0x84C8,
+       GL_TEXTURE9_ARB                         = 0x84C9,
+       GL_TEXTURE10_ARB                        = 0x84CA,
+       GL_TEXTURE11_ARB                        = 0x84CB,
+       GL_TEXTURE12_ARB                        = 0x84CC,
+       GL_TEXTURE13_ARB                        = 0x84CD,
+       GL_TEXTURE14_ARB                        = 0x84CE,
+       GL_TEXTURE15_ARB                        = 0x84CF,
+       GL_TEXTURE16_ARB                        = 0x84D0,
+       GL_TEXTURE17_ARB                        = 0x84D1,
+       GL_TEXTURE18_ARB                        = 0x84D2,
+       GL_TEXTURE19_ARB                        = 0x84D3,
+       GL_TEXTURE20_ARB                        = 0x84D4,
+       GL_TEXTURE21_ARB                        = 0x84D5,
+       GL_TEXTURE22_ARB                        = 0x84D6,
+       GL_TEXTURE23_ARB                        = 0x84D7,
+       GL_TEXTURE24_ARB                        = 0x84D8,
+       GL_TEXTURE25_ARB                        = 0x84D9,
+       GL_TEXTURE26_ARB                        = 0x84DA,
+       GL_TEXTURE27_ARB                        = 0x84DB,
+       GL_TEXTURE28_ARB                        = 0x84DC,
+       GL_TEXTURE29_ARB                        = 0x84DD,
+       GL_TEXTURE30_ARB                        = 0x84DE,
+       GL_TEXTURE31_ARB                        = 0x84DF,
+       GL_ACTIVE_TEXTURE_ARB                   = 0x84E0,
+       GL_CLIENT_ACTIVE_TEXTURE_ARB            = 0x84E1,
+       GL_MAX_TEXTURE_UNITS_ARB                = 0x84E2,
+
+       /*
+        * OpenGL 1.2 imaging subset (NOT IMPLEMENTED BY MESA)
+        */
+       /* GL_EXT_color_table */
+       GL_COLOR_TABLE                          = 0x80D0,
+       GL_POST_CONVOLUTION_COLOR_TABLE         = 0x80D1,
+       GL_POST_COLOR_MATRIX_COLOR_TABLE        = 0x80D2,
+       GL_PROXY_COLOR_TABLE                    = 0x80D3,
+       GL_PROXY_POST_CONVOLUTION_COLOR_TABLE   = 0x80D4,
+       GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE  = 0x80D5,
+       GL_COLOR_TABLE_SCALE                    = 0x80D6,
+       GL_COLOR_TABLE_BIAS                     = 0x80D7,
+       GL_COLOR_TABLE_FORMAT                   = 0x80D8,
+       GL_COLOR_TABLE_WIDTH                    = 0x80D9,
+       GL_COLOR_TABLE_RED_SIZE                 = 0x80DA,
+       GL_COLOR_TABLE_GREEN_SIZE               = 0x80DB,
+       GL_COLOR_TABLE_BLUE_SIZE                = 0x80DC,
+       GL_COLOR_TABLE_ALPHA_SIZE               = 0x80DD,
+       GL_COLOR_TABLE_LUMINANCE_SIZE           = 0x80DE,
+       GL_COLOR_TABLE_INTENSITY_SIZE           = 0x80DF,
+
+       /* GL_EXT_convolution and GL_HP_convolution_border_modes */
+       GL_CONVOLUTION_1D                       = 0x8010,
+       GL_CONVOLUTION_2D                       = 0x8011,
+       GL_SEPARABLE_2D                         = 0x8012,
+       GL_CONVOLUTION_BORDER_MODE              = 0x8013,
+       GL_CONVOLUTION_FILTER_SCALE             = 0x8014,
+       GL_CONVOLUTION_FILTER_BIAS              = 0x8015,
+       GL_REDUCE                               = 0x8016,
+       GL_CONVOLUTION_FORMAT                   = 0x8017,
+       GL_CONVOLUTION_WIDTH                    = 0x8018,
+       GL_CONVOLUTION_HEIGHT                   = 0x8019,
+       GL_MAX_CONVOLUTION_WIDTH                = 0x801A,
+       GL_MAX_CONVOLUTION_HEIGHT               = 0x801B,
+       GL_POST_CONVOLUTION_RED_SCALE           = 0x801C,
+       GL_POST_CONVOLUTION_GREEN_SCALE         = 0x801D,
+       GL_POST_CONVOLUTION_BLUE_SCALE          = 0x801E,
+       GL_POST_CONVOLUTION_ALPHA_SCALE         = 0x801F,
+       GL_POST_CONVOLUTION_RED_BIAS            = 0x8020,
+       GL_POST_CONVOLUTION_GREEN_BIAS          = 0x8021,
+       GL_POST_CONVOLUTION_BLUE_BIAS           = 0x8022,
+       GL_POST_CONVOLUTION_ALPHA_BIAS          = 0x8023,
+       GL_CONSTANT_BORDER                      = 0x8151,
+       GL_REPLICATE_BORDER                     = 0x8153,
+       GL_CONVOLUTION_BORDER_COLOR             = 0x8154,
+
+       /* GL_SGI_color_matrix */
+       GL_COLOR_MATRIX                         = 0x80B1,
+       GL_COLOR_MATRIX_STACK_DEPTH             = 0x80B2,
+       GL_MAX_COLOR_MATRIX_STACK_DEPTH         = 0x80B3,
+       GL_POST_COLOR_MATRIX_RED_SCALE          = 0x80B4,
+       GL_POST_COLOR_MATRIX_GREEN_SCALE        = 0x80B5,
+       GL_POST_COLOR_MATRIX_BLUE_SCALE         = 0x80B6,
+       GL_POST_COLOR_MATRIX_ALPHA_SCALE        = 0x80B7,
+       GL_POST_COLOR_MATRIX_RED_BIAS           = 0x80B8,
+       GL_POST_COLOR_MATRIX_GREEN_BIAS         = 0x80B9,
+       GL_POST_COLOR_MATRIX_BLUE_BIAS          = 0x80BA,
+       GL_POST_COLOR_MATRIX_ALPHA_BIAS         = 0x80BB,
+
+       /* GL_EXT_histogram */
+       GL_HISTOGRAM                            = 0x8024,
+       GL_PROXY_HISTOGRAM                      = 0x8025,
+       GL_HISTOGRAM_WIDTH                      = 0x8026,
+       GL_HISTOGRAM_FORMAT                     = 0x8027,
+       GL_HISTOGRAM_RED_SIZE                   = 0x8028,
+       GL_HISTOGRAM_GREEN_SIZE                 = 0x8029,
+       GL_HISTOGRAM_BLUE_SIZE                  = 0x802A,
+       GL_HISTOGRAM_ALPHA_SIZE                 = 0x802B,
+       GL_HISTOGRAM_LUMINANCE_SIZE             = 0x802C,
+       GL_HISTOGRAM_SINK                       = 0x802D,
+       GL_MINMAX                               = 0x802E,
+       GL_MINMAX_FORMAT                        = 0x802F,
+       GL_MINMAX_SINK                          = 0x8030,
+       GL_TABLE_TOO_LARGE                      = 0x8031,
+
+       /* GL_NV_texgen_reflection (nVidia) */
+       GL_NORMAL_MAP_NV                        = 0x8511,
+       GL_REFLECTION_MAP_NV                    = 0x8512,
+
+       /* GL_PGI_misc_hints */
+       GL_PREFER_DOUBLEBUFFER_HINT_PGI         = 107000,
+       GL_STRICT_DEPTHFUNC_HINT_PGI            = 107030,
+       GL_STRICT_LIGHTING_HINT_PGI             = 107031,
+       GL_STRICT_SCISSOR_HINT_PGI              = 107032,
+       GL_FULL_STIPPLE_HINT_PGI                = 107033,
+       GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI       = 107011,
+       GL_NATIVE_GRAPHICS_END_HINT_PGI         = 107012,
+       GL_CONSERVE_MEMORY_HINT_PGI             = 107005,
+       GL_RECLAIM_MEMORY_HINT_PGI              = 107006,
+       GL_ALWAYS_FAST_HINT_PGI                 = 107020,
+       GL_ALWAYS_SOFT_HINT_PGI                 = 107021,
+       GL_ALLOW_DRAW_OBJ_HINT_PGI              = 107022,
+       GL_ALLOW_DRAW_WIN_HINT_PGI              = 107023,
+       GL_ALLOW_DRAW_FRG_HINT_PGI              = 107024,
+       GL_ALLOW_DRAW_SPN_HINT_PGI              = 107024,
+       GL_ALLOW_DRAW_MEM_HINT_PGI              = 107025,
+       GL_CLIP_NEAR_HINT_PGI                   = 107040,
+       GL_CLIP_FAR_HINT_PGI                    = 107041,
+       GL_WIDE_LINE_HINT_PGI                   = 107042,
+       GL_BACK_NORMALS_HINT_PGI                = 107043,
+       GL_NATIVE_GRAPHICS_HANDLE_PGI           = 107010,
+
+       /* GL_EXT_compiled_vertex_array */
+       GL_ARRAY_ELEMENT_LOCK_FIRST_SGI         = 0x81A8,
+       GL_ARRAY_ELEMENT_LOCK_COUNT_SGI         = 0x81A9,
+
+       /* GL_EXT_clip_volume_hint */
+       GL_CLIP_VOLUME_CLIPPING_HINT_EXT        = 0x80F0
+
+
+/* When you add new enums, please make sure you update the strings
+ * in enums.c as well...
+ */
+
+}
+#ifdef CENTERLINE_CLPP
+  /* CenterLine C++ workaround: */
+  gl_enum;
+  typedef int GLenum;
+#else
+  /* all other compilers */
+  GLenum;
+#endif
+
+
+/* GL_NO_ERROR must be zero */
+#define GL_NO_ERROR 0
+
+
+
+enum {
+       GL_CURRENT_BIT          = 0x00000001,
+       GL_POINT_BIT            = 0x00000002,
+       GL_LINE_BIT             = 0x00000004,
+       GL_POLYGON_BIT          = 0x00000008,
+       GL_POLYGON_STIPPLE_BIT  = 0x00000010,
+       GL_PIXEL_MODE_BIT       = 0x00000020,
+       GL_LIGHTING_BIT         = 0x00000040,
+       GL_FOG_BIT              = 0x00000080,
+       GL_DEPTH_BUFFER_BIT     = 0x00000100,
+       GL_ACCUM_BUFFER_BIT     = 0x00000200,
+       GL_STENCIL_BUFFER_BIT   = 0x00000400,
+       GL_VIEWPORT_BIT         = 0x00000800,
+       GL_TRANSFORM_BIT        = 0x00001000,
+       GL_ENABLE_BIT           = 0x00002000,
+       GL_COLOR_BUFFER_BIT     = 0x00004000,
+       GL_HINT_BIT             = 0x00008000,
+       GL_EVAL_BIT             = 0x00010000,
+       GL_LIST_BIT             = 0x00020000,
+       GL_TEXTURE_BIT          = 0x00040000,
+       GL_SCISSOR_BIT          = 0x00080000,
+       GL_ALL_ATTRIB_BITS      = 0x000FFFFF
+};
+
+
+enum {
+       GL_CLIENT_PIXEL_STORE_BIT       = 0x00000001,
+       GL_CLIENT_VERTEX_ARRAY_BIT      = 0x00000002
+};
+#define GL_CLIENT_ALL_ATTRIB_BITS 0xFFFFFFFF
+
+
+typedef unsigned int GLbitfield;
+
+
+#ifdef CENTERLINE_CLPP
+#define signed
+#endif
+
+
+/*
+ *
+ * Data types (may be architecture dependent in some cases)
+ *
+ */
+
+/*  C type             GL type         storage                            */
+/*-------------------------------------------------------------------------*/
+typedef void           GLvoid;
+typedef unsigned char  GLboolean;
+typedef signed char    GLbyte;         /* 1-byte signed */
+typedef short          GLshort;        /* 2-byte signed */
+typedef int            GLint;          /* 4-byte signed */
+typedef unsigned char  GLubyte;        /* 1-byte unsigned */
+typedef unsigned short GLushort;       /* 2-byte unsigned */
+typedef unsigned int   GLuint;         /* 4-byte unsigned */
+typedef int            GLsizei;        /* 4-byte signed */
+typedef float          GLfloat;        /* single precision float */
+typedef float          GLclampf;       /* single precision float in [0,1] */
+typedef double         GLdouble;       /* double precision float */
+typedef double         GLclampd;       /* double precision float in [0,1] */
+
+
+
+#if defined(__BEOS__) || defined(__QUICKDRAW__)
+#pragma export on
+#endif
+
+
+/*
+ * Miscellaneous
+ */
+
+GLAPI void GLAPIENTRY glClearIndex( GLfloat c );
+
+GLAPI void GLAPIENTRY glClearColor( GLclampf red,
+                         GLclampf green,
+                         GLclampf blue,
+                         GLclampf alpha );
+
+GLAPI void GLAPIENTRY glClear( GLbitfield mask );
+
+GLAPI void GLAPIENTRY glIndexMask( GLuint mask );
+
+GLAPI void GLAPIENTRY glColorMask( GLboolean red, GLboolean green,
+                        GLboolean blue, GLboolean alpha );
+
+GLAPI void GLAPIENTRY glAlphaFunc( GLenum func, GLclampf ref );
+
+GLAPI void GLAPIENTRY glBlendFunc( GLenum sfactor, GLenum dfactor );
+
+GLAPI void GLAPIENTRY glLogicOp( GLenum opcode );
+
+GLAPI void GLAPIENTRY glCullFace( GLenum mode );
+
+GLAPI void GLAPIENTRY glFrontFace( GLenum mode );
+
+GLAPI void GLAPIENTRY glPointSize( GLfloat size );
+
+GLAPI void GLAPIENTRY glLineWidth( GLfloat width );
+
+GLAPI void GLAPIENTRY glLineStipple( GLint factor, GLushort pattern );
+
+GLAPI void GLAPIENTRY glPolygonMode( GLenum face, GLenum mode );
+
+GLAPI void GLAPIENTRY glPolygonOffset( GLfloat factor, GLfloat units );
+
+GLAPI void GLAPIENTRY glPolygonStipple( const GLubyte *mask );
+
+GLAPI void GLAPIENTRY glGetPolygonStipple( GLubyte *mask );
+
+GLAPI void GLAPIENTRY glEdgeFlag( GLboolean flag );
+
+GLAPI void GLAPIENTRY glEdgeFlagv( const GLboolean *flag );
+
+GLAPI void GLAPIENTRY glScissor( GLint x, GLint y,
+                                   GLsizei width, GLsizei height);
+
+GLAPI void GLAPIENTRY glClipPlane( GLenum plane, const GLdouble *equation );
+
+GLAPI void GLAPIENTRY glGetClipPlane( GLenum plane, GLdouble *equation );
+
+GLAPI void GLAPIENTRY glDrawBuffer( GLenum mode );
+
+GLAPI void GLAPIENTRY glReadBuffer( GLenum mode );
+
+GLAPI void GLAPIENTRY glEnable( GLenum cap );
+
+GLAPI void GLAPIENTRY glDisable( GLenum cap );
+
+GLAPI GLboolean GLAPIENTRY glIsEnabled( GLenum cap );
+
+
+GLAPI void GLAPIENTRY glEnableClientState( GLenum cap );  /* 1.1 */
+
+GLAPI void GLAPIENTRY glDisableClientState( GLenum cap );  /* 1.1 */
+
+
+GLAPI void GLAPIENTRY glGetBooleanv( GLenum pname, GLboolean *params );
+
+GLAPI void GLAPIENTRY glGetDoublev( GLenum pname, GLdouble *params );
+
+GLAPI void GLAPIENTRY glGetFloatv( GLenum pname, GLfloat *params );
+
+GLAPI void GLAPIENTRY glGetIntegerv( GLenum pname, GLint *params );
+
+
+GLAPI void GLAPIENTRY glPushAttrib( GLbitfield mask );
+
+GLAPI void GLAPIENTRY glPopAttrib( void );
+
+
+GLAPI void GLAPIENTRY glPushClientAttrib( GLbitfield mask );  /* 1.1 */
+
+GLAPI void GLAPIENTRY glPopClientAttrib( void );  /* 1.1 */
+
+
+GLAPI GLint GLAPIENTRY glRenderMode( GLenum mode );
+
+GLAPI GLenum GLAPIENTRY glGetError( void );
+
+GLAPI const GLubyte* GLAPIENTRY glGetString( GLenum name );
+
+GLAPI void GLAPIENTRY glFinish( void );
+
+GLAPI void GLAPIENTRY glFlush( void );
+
+GLAPI void GLAPIENTRY glHint( GLenum target, GLenum mode );
+
+
+
+/*
+ * Depth Buffer
+ */
+
+GLAPI void GLAPIENTRY glClearDepth( GLclampd depth );
+
+GLAPI void GLAPIENTRY glDepthFunc( GLenum func );
+
+GLAPI void GLAPIENTRY glDepthMask( GLboolean flag );
+
+GLAPI void GLAPIENTRY glDepthRange( GLclampd near_val, GLclampd far_val );
+
+
+/*
+ * Accumulation Buffer
+ */
+
+GLAPI void GLAPIENTRY glClearAccum( GLfloat red, GLfloat green,
+                                      GLfloat blue, GLfloat alpha );
+
+GLAPI void GLAPIENTRY glAccum( GLenum op, GLfloat value );
+
+
+
+/*
+ * Transformation
+ */
+
+GLAPI void GLAPIENTRY glMatrixMode( GLenum mode );
+
+GLAPI void GLAPIENTRY glOrtho( GLdouble left, GLdouble right,
+                                 GLdouble bottom, GLdouble top,
+                                 GLdouble near_val, GLdouble far_val );
+
+GLAPI void GLAPIENTRY glFrustum( GLdouble left, GLdouble right,
+                                   GLdouble bottom, GLdouble top,
+                                   GLdouble near_val, GLdouble far_val );
+
+GLAPI void GLAPIENTRY glViewport( GLint x, GLint y,
+                                    GLsizei width, GLsizei height );
+
+GLAPI void GLAPIENTRY glPushMatrix( void );
+
+GLAPI void GLAPIENTRY glPopMatrix( void );
+
+GLAPI void GLAPIENTRY glLoadIdentity( void );
+
+GLAPI void GLAPIENTRY glLoadMatrixd( const GLdouble *m );
+GLAPI void GLAPIENTRY glLoadMatrixf( const GLfloat *m );
+
+GLAPI void GLAPIENTRY glMultMatrixd( const GLdouble *m );
+GLAPI void GLAPIENTRY glMultMatrixf( const GLfloat *m );
+
+GLAPI void GLAPIENTRY glRotated( GLdouble angle,
+                                   GLdouble x, GLdouble y, GLdouble z );
+GLAPI void GLAPIENTRY glRotatef( GLfloat angle,
+                                   GLfloat x, GLfloat y, GLfloat z );
+
+GLAPI void GLAPIENTRY glScaled( GLdouble x, GLdouble y, GLdouble z );
+GLAPI void GLAPIENTRY glScalef( GLfloat x, GLfloat y, GLfloat z );
+
+GLAPI void GLAPIENTRY glTranslated( GLdouble x, GLdouble y, GLdouble z );
+GLAPI void GLAPIENTRY glTranslatef( GLfloat x, GLfloat y, GLfloat z );
+
+
+
+/*
+ * Display Lists
+ */
+
+GLAPI GLboolean GLAPIENTRY glIsList( GLuint list );
+
+GLAPI void GLAPIENTRY glDeleteLists( GLuint list, GLsizei range );
+
+GLAPI GLuint GLAPIENTRY glGenLists( GLsizei range );
+
+GLAPI void GLAPIENTRY glNewList( GLuint list, GLenum mode );
+
+GLAPI void GLAPIENTRY glEndList( void );
+
+GLAPI void GLAPIENTRY glCallList( GLuint list );
+
+GLAPI void GLAPIENTRY glCallLists( GLsizei n, GLenum type,
+                                     const GLvoid *lists );
+
+GLAPI void GLAPIENTRY glListBase( GLuint base );
+
+
+
+/*
+ * Drawing Functions
+ */
+
+GLAPI void GLAPIENTRY glBegin( GLenum mode );
+
+GLAPI void GLAPIENTRY glEnd( void );
+
+
+GLAPI void GLAPIENTRY glVertex2d( GLdouble x, GLdouble y );
+GLAPI void GLAPIENTRY glVertex2f( GLfloat x, GLfloat y );
+GLAPI void GLAPIENTRY glVertex2i( GLint x, GLint y );
+GLAPI void GLAPIENTRY glVertex2s( GLshort x, GLshort y );
+
+GLAPI void GLAPIENTRY glVertex3d( GLdouble x, GLdouble y, GLdouble z );
+GLAPI void GLAPIENTRY glVertex3f( GLfloat x, GLfloat y, GLfloat z );
+GLAPI void GLAPIENTRY glVertex3i( GLint x, GLint y, GLint z );
+GLAPI void GLAPIENTRY glVertex3s( GLshort x, GLshort y, GLshort z );
+
+GLAPI void GLAPIENTRY glVertex4d( GLdouble x, GLdouble y, GLdouble z, GLdouble w );
+GLAPI void GLAPIENTRY glVertex4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w );
+GLAPI void GLAPIENTRY glVertex4i( GLint x, GLint y, GLint z, GLint w );
+GLAPI void GLAPIENTRY glVertex4s( GLshort x, GLshort y, GLshort z, GLshort w );
+
+GLAPI void GLAPIENTRY glVertex2dv( const GLdouble *v );
+GLAPI void GLAPIENTRY glVertex2fv( const GLfloat *v );
+GLAPI void GLAPIENTRY glVertex2iv( const GLint *v );
+GLAPI void GLAPIENTRY glVertex2sv( const GLshort *v );
+
+GLAPI void GLAPIENTRY glVertex3dv( const GLdouble *v );
+GLAPI void GLAPIENTRY glVertex3fv( const GLfloat *v );
+GLAPI void GLAPIENTRY glVertex3iv( const GLint *v );
+GLAPI void GLAPIENTRY glVertex3sv( const GLshort *v );
+
+GLAPI void GLAPIENTRY glVertex4dv( const GLdouble *v );
+GLAPI void GLAPIENTRY glVertex4fv( const GLfloat *v );
+GLAPI void GLAPIENTRY glVertex4iv( const GLint *v );
+GLAPI void GLAPIENTRY glVertex4sv( const GLshort *v );
+
+
+GLAPI void GLAPIENTRY glNormal3b( GLbyte nx, GLbyte ny, GLbyte nz );
+GLAPI void GLAPIENTRY glNormal3d( GLdouble nx, GLdouble ny, GLdouble nz );
+GLAPI void GLAPIENTRY glNormal3f( GLfloat nx, GLfloat ny, GLfloat nz );
+GLAPI void GLAPIENTRY glNormal3i( GLint nx, GLint ny, GLint nz );
+GLAPI void GLAPIENTRY glNormal3s( GLshort nx, GLshort ny, GLshort nz );
+
+GLAPI void GLAPIENTRY glNormal3bv( const GLbyte *v );
+GLAPI void GLAPIENTRY glNormal3dv( const GLdouble *v );
+GLAPI void GLAPIENTRY glNormal3fv( const GLfloat *v );
+GLAPI void GLAPIENTRY glNormal3iv( const GLint *v );
+GLAPI void GLAPIENTRY glNormal3sv( const GLshort *v );
+
+
+GLAPI void GLAPIENTRY glIndexd( GLdouble c );
+GLAPI void GLAPIENTRY glIndexf( GLfloat c );
+GLAPI void GLAPIENTRY glIndexi( GLint c );
+GLAPI void GLAPIENTRY glIndexs( GLshort c );
+GLAPI void GLAPIENTRY glIndexub( GLubyte c );  /* 1.1 */
+
+GLAPI void GLAPIENTRY glIndexdv( const GLdouble *c );
+GLAPI void GLAPIENTRY glIndexfv( const GLfloat *c );
+GLAPI void GLAPIENTRY glIndexiv( const GLint *c );
+GLAPI void GLAPIENTRY glIndexsv( const GLshort *c );
+GLAPI void GLAPIENTRY glIndexubv( const GLubyte *c );  /* 1.1 */
+
+GLAPI void GLAPIENTRY glColor3b( GLbyte red, GLbyte green, GLbyte blue );
+GLAPI void GLAPIENTRY glColor3d( GLdouble red, GLdouble green, GLdouble blue );
+GLAPI void GLAPIENTRY glColor3f( GLfloat red, GLfloat green, GLfloat blue );
+GLAPI void GLAPIENTRY glColor3i( GLint red, GLint green, GLint blue );
+GLAPI void GLAPIENTRY glColor3s( GLshort red, GLshort green, GLshort blue );
+GLAPI void GLAPIENTRY glColor3ub( GLubyte red, GLubyte green, GLubyte blue );
+GLAPI void GLAPIENTRY glColor3ui( GLuint red, GLuint green, GLuint blue );
+GLAPI void GLAPIENTRY glColor3us( GLushort red, GLushort green, GLushort blue );
+
+GLAPI void GLAPIENTRY glColor4b( GLbyte red, GLbyte green,
+                                   GLbyte blue, GLbyte alpha );
+GLAPI void GLAPIENTRY glColor4d( GLdouble red, GLdouble green,
+                                   GLdouble blue, GLdouble alpha );
+GLAPI void GLAPIENTRY glColor4f( GLfloat red, GLfloat green,
+                                   GLfloat blue, GLfloat alpha );
+GLAPI void GLAPIENTRY glColor4i( GLint red, GLint green,
+                                   GLint blue, GLint alpha );
+GLAPI void GLAPIENTRY glColor4s( GLshort red, GLshort green,
+                                   GLshort blue, GLshort alpha );
+GLAPI void GLAPIENTRY glColor4ub( GLubyte red, GLubyte green,
+                                    GLubyte blue, GLubyte alpha );
+GLAPI void GLAPIENTRY glColor4ui( GLuint red, GLuint green,
+                                    GLuint blue, GLuint alpha );
+GLAPI void GLAPIENTRY glColor4us( GLushort red, GLushort green,
+                                    GLushort blue, GLushort alpha );
+
+
+GLAPI void GLAPIENTRY glColor3bv( const GLbyte *v );
+GLAPI void GLAPIENTRY glColor3dv( const GLdouble *v );
+GLAPI void GLAPIENTRY glColor3fv( const GLfloat *v );
+GLAPI void GLAPIENTRY glColor3iv( const GLint *v );
+GLAPI void GLAPIENTRY glColor3sv( const GLshort *v );
+GLAPI void GLAPIENTRY glColor3ubv( const GLubyte *v );
+GLAPI void GLAPIENTRY glColor3uiv( const GLuint *v );
+GLAPI void GLAPIENTRY glColor3usv( const GLushort *v );
+
+GLAPI void GLAPIENTRY glColor4bv( const GLbyte *v );
+GLAPI void GLAPIENTRY glColor4dv( const GLdouble *v );
+GLAPI void GLAPIENTRY glColor4fv( const GLfloat *v );
+GLAPI void GLAPIENTRY glColor4iv( const GLint *v );
+GLAPI void GLAPIENTRY glColor4sv( const GLshort *v );
+GLAPI void GLAPIENTRY glColor4ubv( const GLubyte *v );
+GLAPI void GLAPIENTRY glColor4uiv( const GLuint *v );
+GLAPI void GLAPIENTRY glColor4usv( const GLushort *v );
+
+
+GLAPI void GLAPIENTRY glTexCoord1d( GLdouble s );
+GLAPI void GLAPIENTRY glTexCoord1f( GLfloat s );
+GLAPI void GLAPIENTRY glTexCoord1i( GLint s );
+GLAPI void GLAPIENTRY glTexCoord1s( GLshort s );
+
+GLAPI void GLAPIENTRY glTexCoord2d( GLdouble s, GLdouble t );
+GLAPI void GLAPIENTRY glTexCoord2f( GLfloat s, GLfloat t );
+GLAPI void GLAPIENTRY glTexCoord2i( GLint s, GLint t );
+GLAPI void GLAPIENTRY glTexCoord2s( GLshort s, GLshort t );
+
+GLAPI void GLAPIENTRY glTexCoord3d( GLdouble s, GLdouble t, GLdouble r );
+GLAPI void GLAPIENTRY glTexCoord3f( GLfloat s, GLfloat t, GLfloat r );
+GLAPI void GLAPIENTRY glTexCoord3i( GLint s, GLint t, GLint r );
+GLAPI void GLAPIENTRY glTexCoord3s( GLshort s, GLshort t, GLshort r );
+
+GLAPI void GLAPIENTRY glTexCoord4d( GLdouble s, GLdouble t, GLdouble r, GLdouble q );
+GLAPI void GLAPIENTRY glTexCoord4f( GLfloat s, GLfloat t, GLfloat r, GLfloat q );
+GLAPI void GLAPIENTRY glTexCoord4i( GLint s, GLint t, GLint r, GLint q );
+GLAPI void GLAPIENTRY glTexCoord4s( GLshort s, GLshort t, GLshort r, GLshort q );
+
+GLAPI void GLAPIENTRY glTexCoord1dv( const GLdouble *v );
+GLAPI void GLAPIENTRY glTexCoord1fv( const GLfloat *v );
+GLAPI void GLAPIENTRY glTexCoord1iv( const GLint *v );
+GLAPI void GLAPIENTRY glTexCoord1sv( const GLshort *v );
+
+GLAPI void GLAPIENTRY glTexCoord2dv( const GLdouble *v );
+GLAPI void GLAPIENTRY glTexCoord2fv( const GLfloat *v );
+GLAPI void GLAPIENTRY glTexCoord2iv( const GLint *v );
+GLAPI void GLAPIENTRY glTexCoord2sv( const GLshort *v );
+
+GLAPI void GLAPIENTRY glTexCoord3dv( const GLdouble *v );
+GLAPI void GLAPIENTRY glTexCoord3fv( const GLfloat *v );
+GLAPI void GLAPIENTRY glTexCoord3iv( const GLint *v );
+GLAPI void GLAPIENTRY glTexCoord3sv( const GLshort *v );
+
+GLAPI void GLAPIENTRY glTexCoord4dv( const GLdouble *v );
+GLAPI void GLAPIENTRY glTexCoord4fv( const GLfloat *v );
+GLAPI void GLAPIENTRY glTexCoord4iv( const GLint *v );
+GLAPI void GLAPIENTRY glTexCoord4sv( const GLshort *v );
+
+
+GLAPI void GLAPIENTRY glRasterPos2d( GLdouble x, GLdouble y );
+GLAPI void GLAPIENTRY glRasterPos2f( GLfloat x, GLfloat y );
+GLAPI void GLAPIENTRY glRasterPos2i( GLint x, GLint y );
+GLAPI void GLAPIENTRY glRasterPos2s( GLshort x, GLshort y );
+
+GLAPI void GLAPIENTRY glRasterPos3d( GLdouble x, GLdouble y, GLdouble z );
+GLAPI void GLAPIENTRY glRasterPos3f( GLfloat x, GLfloat y, GLfloat z );
+GLAPI void GLAPIENTRY glRasterPos3i( GLint x, GLint y, GLint z );
+GLAPI void GLAPIENTRY glRasterPos3s( GLshort x, GLshort y, GLshort z );
+
+GLAPI void GLAPIENTRY glRasterPos4d( GLdouble x, GLdouble y, GLdouble z, GLdouble w );
+GLAPI void GLAPIENTRY glRasterPos4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w );
+GLAPI void GLAPIENTRY glRasterPos4i( GLint x, GLint y, GLint z, GLint w );
+GLAPI void GLAPIENTRY glRasterPos4s( GLshort x, GLshort y, GLshort z, GLshort w );
+
+GLAPI void GLAPIENTRY glRasterPos2dv( const GLdouble *v );
+GLAPI void GLAPIENTRY glRasterPos2fv( const GLfloat *v );
+GLAPI void GLAPIENTRY glRasterPos2iv( const GLint *v );
+GLAPI void GLAPIENTRY glRasterPos2sv( const GLshort *v );
+
+GLAPI void GLAPIENTRY glRasterPos3dv( const GLdouble *v );
+GLAPI void GLAPIENTRY glRasterPos3fv( const GLfloat *v );
+GLAPI void GLAPIENTRY glRasterPos3iv( const GLint *v );
+GLAPI void GLAPIENTRY glRasterPos3sv( const GLshort *v );
+
+GLAPI void GLAPIENTRY glRasterPos4dv( const GLdouble *v );
+GLAPI void GLAPIENTRY glRasterPos4fv( const GLfloat *v );
+GLAPI void GLAPIENTRY glRasterPos4iv( const GLint *v );
+GLAPI void GLAPIENTRY glRasterPos4sv( const GLshort *v );
+
+
+GLAPI void GLAPIENTRY glRectd( GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2 );
+GLAPI void GLAPIENTRY glRectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 );
+GLAPI void GLAPIENTRY glRecti( GLint x1, GLint y1, GLint x2, GLint y2 );
+GLAPI void GLAPIENTRY glRects( GLshort x1, GLshort y1, GLshort x2, GLshort y2 );
+
+
+GLAPI void GLAPIENTRY glRectdv( const GLdouble *v1, const GLdouble *v2 );
+GLAPI void GLAPIENTRY glRectfv( const GLfloat *v1, const GLfloat *v2 );
+GLAPI void GLAPIENTRY glRectiv( const GLint *v1, const GLint *v2 );
+GLAPI void GLAPIENTRY glRectsv( const GLshort *v1, const GLshort *v2 );
+
+
+
+/*
+ * Vertex Arrays  (1.1)
+ */
+
+GLAPI void GLAPIENTRY glVertexPointer( GLint size, GLenum type,
+                                       GLsizei stride, const GLvoid *ptr );
+
+GLAPI void GLAPIENTRY glNormalPointer( GLenum type, GLsizei stride,
+                                       const GLvoid *ptr );
+
+GLAPI void GLAPIENTRY glColorPointer( GLint size, GLenum type,
+                                      GLsizei stride, const GLvoid *ptr );
+
+GLAPI void GLAPIENTRY glIndexPointer( GLenum type, GLsizei stride,
+                                      const GLvoid *ptr );
+
+GLAPI void GLAPIENTRY glTexCoordPointer( GLint size, GLenum type,
+                                         GLsizei stride, const GLvoid *ptr );
+
+GLAPI void GLAPIENTRY glEdgeFlagPointer( GLsizei stride, const GLvoid *ptr );
+
+GLAPI void GLAPIENTRY glGetPointerv( GLenum pname, void **params );
+
+GLAPI void GLAPIENTRY glArrayElement( GLint i );
+
+GLAPI void GLAPIENTRY glDrawArrays( GLenum mode, GLint first, GLsizei count );
+
+GLAPI void GLAPIENTRY glDrawElements( GLenum mode, GLsizei count,
+                                      GLenum type, const GLvoid *indices );
+
+GLAPI void GLAPIENTRY glInterleavedArrays( GLenum format, GLsizei stride,
+                                           const GLvoid *pointer );
+
+
+/*
+ * Lighting
+ */
+
+GLAPI void GLAPIENTRY glShadeModel( GLenum mode );
+
+GLAPI void GLAPIENTRY glLightf( GLenum light, GLenum pname, GLfloat param );
+GLAPI void GLAPIENTRY glLighti( GLenum light, GLenum pname, GLint param );
+GLAPI void GLAPIENTRY glLightfv( GLenum light, GLenum pname,
+                                 const GLfloat *params );
+GLAPI void GLAPIENTRY glLightiv( GLenum light, GLenum pname,
+                                 const GLint *params );
+
+GLAPI void GLAPIENTRY glGetLightfv( GLenum light, GLenum pname,
+                                    GLfloat *params );
+GLAPI void GLAPIENTRY glGetLightiv( GLenum light, GLenum pname,
+                                    GLint *params );
+
+GLAPI void GLAPIENTRY glLightModelf( GLenum pname, GLfloat param );
+GLAPI void GLAPIENTRY glLightModeli( GLenum pname, GLint param );
+GLAPI void GLAPIENTRY glLightModelfv( GLenum pname, const GLfloat *params );
+GLAPI void GLAPIENTRY glLightModeliv( GLenum pname, const GLint *params );
+
+GLAPI void GLAPIENTRY glMaterialf( GLenum face, GLenum pname, GLfloat param );
+GLAPI void GLAPIENTRY glMateriali( GLenum face, GLenum pname, GLint param );
+GLAPI void GLAPIENTRY glMaterialfv( GLenum face, GLenum pname, const GLfloat *params );
+GLAPI void GLAPIENTRY glMaterialiv( GLenum face, GLenum pname, const GLint *params );
+
+GLAPI void GLAPIENTRY glGetMaterialfv( GLenum face, GLenum pname, GLfloat *params );
+GLAPI void GLAPIENTRY glGetMaterialiv( GLenum face, GLenum pname, GLint *params );
+
+GLAPI void GLAPIENTRY glColorMaterial( GLenum face, GLenum mode );
+
+
+
+
+/*
+ * Raster functions
+ */
+
+GLAPI void GLAPIENTRY glPixelZoom( GLfloat xfactor, GLfloat yfactor );
+
+GLAPI void GLAPIENTRY glPixelStoref( GLenum pname, GLfloat param );
+GLAPI void GLAPIENTRY glPixelStorei( GLenum pname, GLint param );
+
+GLAPI void GLAPIENTRY glPixelTransferf( GLenum pname, GLfloat param );
+GLAPI void GLAPIENTRY glPixelTransferi( GLenum pname, GLint param );
+
+GLAPI void GLAPIENTRY glPixelMapfv( GLenum map, GLint mapsize,
+                                    const GLfloat *values );
+GLAPI void GLAPIENTRY glPixelMapuiv( GLenum map, GLint mapsize,
+                                     const GLuint *values );
+GLAPI void GLAPIENTRY glPixelMapusv( GLenum map, GLint mapsize,
+                                     const GLushort *values );
+
+GLAPI void GLAPIENTRY glGetPixelMapfv( GLenum map, GLfloat *values );
+GLAPI void GLAPIENTRY glGetPixelMapuiv( GLenum map, GLuint *values );
+GLAPI void GLAPIENTRY glGetPixelMapusv( GLenum map, GLushort *values );
+
+GLAPI void GLAPIENTRY glBitmap( GLsizei width, GLsizei height,
+                                GLfloat xorig, GLfloat yorig,
+                                GLfloat xmove, GLfloat ymove,
+                                const GLubyte *bitmap );
+
+GLAPI void GLAPIENTRY glReadPixels( GLint x, GLint y,
+                                    GLsizei width, GLsizei height,
+                                    GLenum format, GLenum type,
+                                    GLvoid *pixels );
+
+GLAPI void GLAPIENTRY glDrawPixels( GLsizei width, GLsizei height,
+                                    GLenum format, GLenum type,
+                                    const GLvoid *pixels );
+
+GLAPI void GLAPIENTRY glCopyPixels( GLint x, GLint y,
+                                    GLsizei width, GLsizei height,
+                                    GLenum type );
+
+
+
+/*
+ * Stenciling
+ */
+
+GLAPI void GLAPIENTRY glStencilFunc( GLenum func, GLint ref, GLuint mask );
+
+GLAPI void GLAPIENTRY glStencilMask( GLuint mask );
+
+GLAPI void GLAPIENTRY glStencilOp( GLenum fail, GLenum zfail, GLenum zpass );
+
+GLAPI void GLAPIENTRY glClearStencil( GLint s );
+
+
+
+/*
+ * Texture mapping
+ */
+
+GLAPI void GLAPIENTRY glTexGend( GLenum coord, GLenum pname, GLdouble param );
+GLAPI void GLAPIENTRY glTexGenf( GLenum coord, GLenum pname, GLfloat param );
+GLAPI void GLAPIENTRY glTexGeni( GLenum coord, GLenum pname, GLint param );
+
+GLAPI void GLAPIENTRY glTexGendv( GLenum coord, GLenum pname, const GLdouble *params );
+GLAPI void GLAPIENTRY glTexGenfv( GLenum coord, GLenum pname, const GLfloat *params );
+GLAPI void GLAPIENTRY glTexGeniv( GLenum coord, GLenum pname, const GLint *params );
+
+GLAPI void GLAPIENTRY glGetTexGendv( GLenum coord, GLenum pname, GLdouble *params );
+GLAPI void GLAPIENTRY glGetTexGenfv( GLenum coord, GLenum pname, GLfloat *params );
+GLAPI void GLAPIENTRY glGetTexGeniv( GLenum coord, GLenum pname, GLint *params );
+
+
+GLAPI void GLAPIENTRY glTexEnvf( GLenum target, GLenum pname, GLfloat param );
+GLAPI void GLAPIENTRY glTexEnvi( GLenum target, GLenum pname, GLint param );
+
+GLAPI void GLAPIENTRY glTexEnvfv( GLenum target, GLenum pname, const GLfloat *params );
+GLAPI void GLAPIENTRY glTexEnviv( GLenum target, GLenum pname, const GLint *params );
+
+GLAPI void GLAPIENTRY glGetTexEnvfv( GLenum target, GLenum pname, GLfloat *params );
+GLAPI void GLAPIENTRY glGetTexEnviv( GLenum target, GLenum pname, GLint *params );
+
+
+GLAPI void GLAPIENTRY glTexParameterf( GLenum target, GLenum pname, GLfloat param );
+GLAPI void GLAPIENTRY glTexParameteri( GLenum target, GLenum pname, GLint param );
+
+GLAPI void GLAPIENTRY glTexParameterfv( GLenum target, GLenum pname,
+                                          const GLfloat *params );
+GLAPI void GLAPIENTRY glTexParameteriv( GLenum target, GLenum pname,
+                                          const GLint *params );
+
+GLAPI void GLAPIENTRY glGetTexParameterfv( GLenum target,
+                                           GLenum pname, GLfloat *params);
+GLAPI void GLAPIENTRY glGetTexParameteriv( GLenum target,
+                                           GLenum pname, GLint *params );
+
+GLAPI void GLAPIENTRY glGetTexLevelParameterfv( GLenum target, GLint level,
+                                                GLenum pname, GLfloat *params );
+GLAPI void GLAPIENTRY glGetTexLevelParameteriv( GLenum target, GLint level,
+                                                GLenum pname, GLint *params );
+
+
+GLAPI void GLAPIENTRY glTexImage1D( GLenum target, GLint level,
+                                    GLint internalFormat,
+                                    GLsizei width, GLint border,
+                                    GLenum format, GLenum type,
+                                    const GLvoid *pixels );
+
+GLAPI void GLAPIENTRY glTexImage2D( GLenum target, GLint level,
+                                    GLint internalFormat,
+                                    GLsizei width, GLsizei height,
+                                    GLint border, GLenum format, GLenum type,
+                                    const GLvoid *pixels );
+
+GLAPI void GLAPIENTRY glGetTexImage( GLenum target, GLint level,
+                                     GLenum format, GLenum type,
+                                     GLvoid *pixels );
+
+
+
+/* 1.1 functions */
+
+GLAPI void GLAPIENTRY glGenTextures( GLsizei n, GLuint *textures );
+
+GLAPI void GLAPIENTRY glDeleteTextures( GLsizei n, const GLuint *textures);
+
+GLAPI void GLAPIENTRY glBindTexture( GLenum target, GLuint texture );
+
+GLAPI void GLAPIENTRY glPrioritizeTextures( GLsizei n,
+                                            const GLuint *textures,
+                                            const GLclampf *priorities );
+
+GLAPI GLboolean GLAPIENTRY glAreTexturesResident( GLsizei n,
+                                                  const GLuint *textures,
+                                                  GLboolean *residences );
+
+GLAPI GLboolean GLAPIENTRY glIsTexture( GLuint texture );
+
+
+GLAPI void GLAPIENTRY glTexSubImage1D( GLenum target, GLint level,
+                                       GLint xoffset,
+                                       GLsizei width, GLenum format,
+                                       GLenum type, const GLvoid *pixels );
+
+
+GLAPI void GLAPIENTRY glTexSubImage2D( GLenum target, GLint level,
+                                       GLint xoffset, GLint yoffset,
+                                       GLsizei width, GLsizei height,
+                                       GLenum format, GLenum type,
+                                       const GLvoid *pixels );
+
+
+GLAPI void GLAPIENTRY glCopyTexImage1D( GLenum target, GLint level,
+                                        GLenum internalformat,
+                                        GLint x, GLint y,
+                                        GLsizei width, GLint border );
+
+
+GLAPI void GLAPIENTRY glCopyTexImage2D( GLenum target, GLint level,
+                                        GLenum internalformat,
+                                        GLint x, GLint y,
+                                        GLsizei width, GLsizei height,
+                                        GLint border );
+
+
+GLAPI void GLAPIENTRY glCopyTexSubImage1D( GLenum target, GLint level,
+                                           GLint xoffset, GLint x, GLint y,
+                                           GLsizei width );
+
+
+GLAPI void GLAPIENTRY glCopyTexSubImage2D( GLenum target, GLint level,
+                                           GLint xoffset, GLint yoffset,
+                                           GLint x, GLint y,
+                                           GLsizei width, GLsizei height );
+
+
+
+
+/*
+ * Evaluators
+ */
+
+GLAPI void GLAPIENTRY glMap1d( GLenum target, GLdouble u1, GLdouble u2,
+                               GLint stride,
+                               GLint order, const GLdouble *points );
+GLAPI void GLAPIENTRY glMap1f( GLenum target, GLfloat u1, GLfloat u2,
+                               GLint stride,
+                               GLint order, const GLfloat *points );
+
+GLAPI void GLAPIENTRY glMap2d( GLenum target,
+                    GLdouble u1, GLdouble u2, GLint ustride, GLint uorder,
+                    GLdouble v1, GLdouble v2, GLint vstride, GLint vorder,
+                    const GLdouble *points );
+GLAPI void GLAPIENTRY glMap2f( GLenum target,
+                    GLfloat u1, GLfloat u2, GLint ustride, GLint uorder,
+                    GLfloat v1, GLfloat v2, GLint vstride, GLint vorder,
+                    const GLfloat *points );
+
+GLAPI void GLAPIENTRY glGetMapdv( GLenum target, GLenum query, GLdouble *v );
+GLAPI void GLAPIENTRY glGetMapfv( GLenum target, GLenum query, GLfloat *v );
+GLAPI void GLAPIENTRY glGetMapiv( GLenum target, GLenum query, GLint *v );
+
+GLAPI void GLAPIENTRY glEvalCoord1d( GLdouble u );
+GLAPI void GLAPIENTRY glEvalCoord1f( GLfloat u );
+
+GLAPI void GLAPIENTRY glEvalCoord1dv( const GLdouble *u );
+GLAPI void GLAPIENTRY glEvalCoord1fv( const GLfloat *u );
+
+GLAPI void GLAPIENTRY glEvalCoord2d( GLdouble u, GLdouble v );
+GLAPI void GLAPIENTRY glEvalCoord2f( GLfloat u, GLfloat v );
+
+GLAPI void GLAPIENTRY glEvalCoord2dv( const GLdouble *u );
+GLAPI void GLAPIENTRY glEvalCoord2fv( const GLfloat *u );
+
+GLAPI void GLAPIENTRY glMapGrid1d( GLint un, GLdouble u1, GLdouble u2 );
+GLAPI void GLAPIENTRY glMapGrid1f( GLint un, GLfloat u1, GLfloat u2 );
+
+GLAPI void GLAPIENTRY glMapGrid2d( GLint un, GLdouble u1, GLdouble u2,
+                                   GLint vn, GLdouble v1, GLdouble v2 );
+GLAPI void GLAPIENTRY glMapGrid2f( GLint un, GLfloat u1, GLfloat u2,
+                                   GLint vn, GLfloat v1, GLfloat v2 );
+
+GLAPI void GLAPIENTRY glEvalPoint1( GLint i );
+
+GLAPI void GLAPIENTRY glEvalPoint2( GLint i, GLint j );
+
+GLAPI void GLAPIENTRY glEvalMesh1( GLenum mode, GLint i1, GLint i2 );
+
+GLAPI void GLAPIENTRY glEvalMesh2( GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 );
+
+
+
+/*
+ * Fog
+ */
+
+GLAPI void GLAPIENTRY glFogf( GLenum pname, GLfloat param );
+
+GLAPI void GLAPIENTRY glFogi( GLenum pname, GLint param );
+
+GLAPI void GLAPIENTRY glFogfv( GLenum pname, const GLfloat *params );
+
+GLAPI void GLAPIENTRY glFogiv( GLenum pname, const GLint *params );
+
+
+
+/*
+ * Selection and Feedback
+ */
+
+GLAPI void GLAPIENTRY glFeedbackBuffer( GLsizei size, GLenum type, GLfloat *buffer );
+
+GLAPI void GLAPIENTRY glPassThrough( GLfloat token );
+
+GLAPI void GLAPIENTRY glSelectBuffer( GLsizei size, GLuint *buffer );
+
+GLAPI void GLAPIENTRY glInitNames( void );
+
+GLAPI void GLAPIENTRY glLoadName( GLuint name );
+
+GLAPI void GLAPIENTRY glPushName( GLuint name );
+
+GLAPI void GLAPIENTRY glPopName( void );
+
+
+
+/*
+ * 1.0 Extensions
+ */
+
+/* GL_EXT_blend_minmax */
+GLAPI void GLAPIENTRY glBlendEquationEXT( GLenum mode );
+
+
+
+/* GL_EXT_blend_color */
+GLAPI void GLAPIENTRY glBlendColorEXT( GLclampf red, GLclampf green,
+                                       GLclampf blue, GLclampf alpha );
+
+
+
+/* GL_EXT_polygon_offset */
+GLAPI void GLAPIENTRY glPolygonOffsetEXT( GLfloat factor, GLfloat bias );
+
+
+
+/* GL_EXT_vertex_array */
+
+GLAPI void GLAPIENTRY glVertexPointerEXT( GLint size, GLenum type,
+                                          GLsizei stride,
+                                          GLsizei count, const GLvoid *ptr );
+
+GLAPI void GLAPIENTRY glNormalPointerEXT( GLenum type, GLsizei stride,
+                                          GLsizei count, const GLvoid *ptr );
+
+GLAPI void GLAPIENTRY glColorPointerEXT( GLint size, GLenum type,
+                                         GLsizei stride,
+                                         GLsizei count, const GLvoid *ptr );
+
+GLAPI void GLAPIENTRY glIndexPointerEXT( GLenum type, GLsizei stride,
+                                         GLsizei count, const GLvoid *ptr );
+
+GLAPI void GLAPIENTRY glTexCoordPointerEXT( GLint size, GLenum type,
+                                            GLsizei stride, GLsizei count,
+                                            const GLvoid *ptr );
+
+GLAPI void GLAPIENTRY glEdgeFlagPointerEXT( GLsizei stride, GLsizei count,
+                                            const GLboolean *ptr );
+
+GLAPI void GLAPIENTRY glGetPointervEXT( GLenum pname, void **params );
+
+GLAPI void GLAPIENTRY glArrayElementEXT( GLint i );
+
+GLAPI void GLAPIENTRY glDrawArraysEXT( GLenum mode, GLint first,
+                                       GLsizei count );
+
+
+
+/* GL_EXT_texture_object */
+
+GLAPI void GLAPIENTRY glGenTexturesEXT( GLsizei n, GLuint *textures );
+
+GLAPI void GLAPIENTRY glDeleteTexturesEXT( GLsizei n, const GLuint *textures);
+
+GLAPI void GLAPIENTRY glBindTextureEXT( GLenum target, GLuint texture );
+
+GLAPI void GLAPIENTRY glPrioritizeTexturesEXT( GLsizei n,
+                                               const GLuint *textures,
+                                               const GLclampf *priorities );
+
+GLAPI GLboolean GLAPIENTRY glAreTexturesResidentEXT( GLsizei n,
+                                                     const GLuint *textures,
+                                                     GLboolean *residences );
+
+GLAPI GLboolean GLAPIENTRY glIsTextureEXT( GLuint texture );
+
+
+
+/* GL_EXT_texture3D */
+
+GLAPI void GLAPIENTRY glTexImage3DEXT( GLenum target, GLint level,
+                                       GLenum internalFormat,
+                                       GLsizei width, GLsizei height,
+                                       GLsizei depth, GLint border,
+                                       GLenum format, GLenum type,
+                                       const GLvoid *pixels );
+
+GLAPI void GLAPIENTRY glTexSubImage3DEXT( GLenum target, GLint level,
+                                          GLint xoffset, GLint yoffset,
+                                          GLint zoffset, GLsizei width,
+                                          GLsizei height, GLsizei depth,
+                                          GLenum format,
+                                          GLenum type, const GLvoid *pixels);
+
+GLAPI void GLAPIENTRY glCopyTexSubImage3DEXT( GLenum target, GLint level,
+                                              GLint xoffset, GLint yoffset,
+                                              GLint zoffset, GLint x,
+                                              GLint y, GLsizei width,
+                                              GLsizei height );
+
+
+
+/* GL_EXT_color_table */
+
+GLAPI void GLAPIENTRY glColorTableEXT( GLenum target, GLenum internalformat,
+                                       GLsizei width, GLenum format,
+                                       GLenum type, const GLvoid *table );
+
+GLAPI void GLAPIENTRY glColorSubTableEXT( GLenum target,
+                                          GLsizei start, GLsizei count,
+                                          GLenum format, GLenum type,
+                                          const GLvoid *data );
+
+GLAPI void GLAPIENTRY glGetColorTableEXT( GLenum target, GLenum format,
+                                          GLenum type, GLvoid *table );
+
+GLAPI void GLAPIENTRY glGetColorTableParameterfvEXT( GLenum target,
+                                                     GLenum pname,
+                                                     GLfloat *params );
+
+GLAPI void GLAPIENTRY glGetColorTableParameterivEXT( GLenum target,
+                                                     GLenum pname,
+                                                     GLint *params );
+
+
+/* GL_ARB_multitexture */
+
+GLAPI void GLAPIENTRY glActiveTextureARB(GLenum texture);
+GLAPI void GLAPIENTRY glClientActiveTextureARB(GLenum texture);
+GLAPI void GLAPIENTRY glMultiTexCoord1dARB(GLenum target, GLdouble s);
+GLAPI void GLAPIENTRY glMultiTexCoord1dvARB(GLenum target, const GLdouble *v);
+GLAPI void GLAPIENTRY glMultiTexCoord1fARB(GLenum target, GLfloat s);
+GLAPI void GLAPIENTRY glMultiTexCoord1fvARB(GLenum target, const GLfloat *v);
+GLAPI void GLAPIENTRY glMultiTexCoord1iARB(GLenum target, GLint s);
+GLAPI void GLAPIENTRY glMultiTexCoord1ivARB(GLenum target, const GLint *v);
+GLAPI void GLAPIENTRY glMultiTexCoord1sARB(GLenum target, GLshort s);
+GLAPI void GLAPIENTRY glMultiTexCoord1svARB(GLenum target, const GLshort *v);
+GLAPI void GLAPIENTRY glMultiTexCoord2dARB(GLenum target, GLdouble s, GLdouble t);
+GLAPI void GLAPIENTRY glMultiTexCoord2dvARB(GLenum target, const GLdouble *v);
+GLAPI void GLAPIENTRY glMultiTexCoord2fARB(GLenum target, GLfloat s, GLfloat t);
+GLAPI void GLAPIENTRY glMultiTexCoord2fvARB(GLenum target, const GLfloat *v);
+GLAPI void GLAPIENTRY glMultiTexCoord2iARB(GLenum target, GLint s, GLint t);
+GLAPI void GLAPIENTRY glMultiTexCoord2ivARB(GLenum target, const GLint *v);
+GLAPI void GLAPIENTRY glMultiTexCoord2sARB(GLenum target, GLshort s, GLshort t);
+GLAPI void GLAPIENTRY glMultiTexCoord2svARB(GLenum target, const GLshort *v);
+GLAPI void GLAPIENTRY glMultiTexCoord3dARB(GLenum target, GLdouble s, GLdouble t, GLdouble r);
+GLAPI void GLAPIENTRY glMultiTexCoord3dvARB(GLenum target, const GLdouble *v);
+GLAPI void GLAPIENTRY glMultiTexCoord3fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r);
+GLAPI void GLAPIENTRY glMultiTexCoord3fvARB(GLenum target, const GLfloat *v);
+GLAPI void GLAPIENTRY glMultiTexCoord3iARB(GLenum target, GLint s, GLint t, GLint r);
+GLAPI void GLAPIENTRY glMultiTexCoord3ivARB(GLenum target, const GLint *v);
+GLAPI void GLAPIENTRY glMultiTexCoord3sARB(GLenum target, GLshort s, GLshort t, GLshort r);
+GLAPI void GLAPIENTRY glMultiTexCoord3svARB(GLenum target, const GLshort *v);
+GLAPI void GLAPIENTRY glMultiTexCoord4dARB(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q);
+GLAPI void GLAPIENTRY glMultiTexCoord4dvARB(GLenum target, const GLdouble *v);
+GLAPI void GLAPIENTRY glMultiTexCoord4fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+GLAPI void GLAPIENTRY glMultiTexCoord4fvARB(GLenum target, const GLfloat *v);
+GLAPI void GLAPIENTRY glMultiTexCoord4iARB(GLenum target, GLint s, GLint t, GLint r, GLint q);
+GLAPI void GLAPIENTRY glMultiTexCoord4ivARB(GLenum target, const GLint *v);
+GLAPI void GLAPIENTRY glMultiTexCoord4sARB(GLenum target, GLshort s, GLshort t, GLshort r, GLshort q);
+GLAPI void GLAPIENTRY glMultiTexCoord4svARB(GLenum target, const GLshort *v);
+
+
+
+/* GL_EXT_point_parameters */
+GLAPI void GLAPIENTRY glPointParameterfEXT( GLenum pname, GLfloat param );
+GLAPI void GLAPIENTRY glPointParameterfvEXT( GLenum pname,
+                                               const GLfloat *params );
+
+
+
+/* GL_INGR_blend_func_separate */
+GLAPI void GLAPIENTRY glBlendFuncSeparateINGR( GLenum sfactorRGB,
+                                               GLenum dfactorRGB,
+                                               GLenum sfactorAlpha,
+                                               GLenum dfactorAlpha );
+
+
+
+/* GL_MESA_window_pos */
+
+GLAPI void GLAPIENTRY glWindowPos2iMESA( GLint x, GLint y );
+GLAPI void GLAPIENTRY glWindowPos2sMESA( GLshort x, GLshort y );
+GLAPI void GLAPIENTRY glWindowPos2fMESA( GLfloat x, GLfloat y );
+GLAPI void GLAPIENTRY glWindowPos2dMESA( GLdouble x, GLdouble y );
+
+GLAPI void GLAPIENTRY glWindowPos2ivMESA( const GLint *p );
+GLAPI void GLAPIENTRY glWindowPos2svMESA( const GLshort *p );
+GLAPI void GLAPIENTRY glWindowPos2fvMESA( const GLfloat *p );
+GLAPI void GLAPIENTRY glWindowPos2dvMESA( const GLdouble *p );
+
+GLAPI void GLAPIENTRY glWindowPos3iMESA( GLint x, GLint y, GLint z );
+GLAPI void GLAPIENTRY glWindowPos3sMESA( GLshort x, GLshort y, GLshort z );
+GLAPI void GLAPIENTRY glWindowPos3fMESA( GLfloat x, GLfloat y, GLfloat z );
+GLAPI void GLAPIENTRY glWindowPos3dMESA( GLdouble x, GLdouble y, GLdouble z );
+
+GLAPI void GLAPIENTRY glWindowPos3ivMESA( const GLint *p );
+GLAPI void GLAPIENTRY glWindowPos3svMESA( const GLshort *p );
+GLAPI void GLAPIENTRY glWindowPos3fvMESA( const GLfloat *p );
+GLAPI void GLAPIENTRY glWindowPos3dvMESA( const GLdouble *p );
+
+GLAPI void GLAPIENTRY glWindowPos4iMESA( GLint x, GLint y, GLint z, GLint w );
+GLAPI void GLAPIENTRY glWindowPos4sMESA( GLshort x, GLshort y, GLshort z, GLshort w );
+GLAPI void GLAPIENTRY glWindowPos4fMESA( GLfloat x, GLfloat y, GLfloat z, GLfloat w );
+GLAPI void GLAPIENTRY glWindowPos4dMESA( GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+
+GLAPI void GLAPIENTRY glWindowPos4ivMESA( const GLint *p );
+GLAPI void GLAPIENTRY glWindowPos4svMESA( const GLshort *p );
+GLAPI void GLAPIENTRY glWindowPos4fvMESA( const GLfloat *p );
+GLAPI void GLAPIENTRY glWindowPos4dvMESA( const GLdouble *p );
+
+
+/* GL_MESA_resize_buffers */
+
+GLAPI void GLAPIENTRY glResizeBuffersMESA( void );
+
+
+/* 1.2 functions */
+GLAPI void GLAPIENTRY glDrawRangeElements( GLenum mode, GLuint start,
+       GLuint end, GLsizei count, GLenum type, const GLvoid *indices );
+
+GLAPI void GLAPIENTRY glTexImage3D( GLenum target, GLint level,
+                                      GLint internalFormat,
+                                      GLsizei width, GLsizei height,
+                                      GLsizei depth, GLint border,
+                                      GLenum format, GLenum type,
+                                      const GLvoid *pixels );
+
+GLAPI void GLAPIENTRY glTexSubImage3D( GLenum target, GLint level,
+                                         GLint xoffset, GLint yoffset,
+                                         GLint zoffset, GLsizei width,
+                                         GLsizei height, GLsizei depth,
+                                         GLenum format,
+                                         GLenum type, const GLvoid *pixels);
+
+GLAPI void GLAPIENTRY glCopyTexSubImage3D( GLenum target, GLint level,
+                                             GLint xoffset, GLint yoffset,
+                                             GLint zoffset, GLint x,
+                                             GLint y, GLsizei width,
+                                             GLsizei height );
+
+
+/* 1.2 imaging extension functions */
+
+GLAPI void GLAPIENTRY glBlendEquation( GLenum mode );
+
+GLAPI void GLAPIENTRY glBlendColor( GLclampf red, GLclampf green,
+                                    GLclampf blue, GLclampf alpha );
+
+GLAPI void GLAPIENTRY glHistogram( GLenum target, GLsizei width,
+                                  GLenum internalformat, GLboolean sink );
+
+GLAPI void GLAPIENTRY glResetHistogram( GLenum target );
+
+GLAPI void GLAPIENTRY glGetHistogram( GLenum target, GLboolean reset,
+                                     GLenum format, GLenum type,
+                                     GLvoid *values );
+
+GLAPI void GLAPIENTRY glGetHistogramParameterfv( GLenum target, GLenum pname,
+                                                GLfloat *params );
+
+GLAPI void GLAPIENTRY glGetHistogramParameteriv( GLenum target, GLenum pname,
+                                                GLint *params );
+
+GLAPI void GLAPIENTRY glMinmax( GLenum target, GLenum internalformat,
+                               GLboolean sink );
+
+GLAPI void GLAPIENTRY glResetMinmax( GLenum target );
+
+GLAPI void GLAPIENTRY glGetMinMax( GLenum target, GLboolean reset,
+                                   GLenum format, GLenum types,
+                                   GLvoid *values );
+
+GLAPI void GLAPIENTRY glGetMinmaxParameterfv( GLenum target, GLenum pname,
+                                             GLfloat *params );
+
+GLAPI void GLAPIENTRY glGetMinmaxParameteriv( GLenum target, GLenum pname,
+                                             GLint *params );
+
+GLAPI void GLAPIENTRY glConvolutionFilter1D( GLenum target,
+       GLenum internalformat, GLsizei width, GLenum format, GLenum type,
+       const GLvoid *image );
+
+GLAPI void GLAPIENTRY glConvolutionFilter2D( GLenum target,
+       GLenum internalformat, GLsizei width, GLsizei height, GLenum format,
+       GLenum type, const GLvoid *image );
+
+GLAPI void GLAPIENTRY glConvolutionParameterf( GLenum target, GLenum pname,
+       GLfloat params );
+
+GLAPI void GLAPIENTRY glConvolutionParameterfv( GLenum target, GLenum pname,
+       const GLfloat *params );
+
+GLAPI void GLAPIENTRY glConvolutionParameteri( GLenum target, GLenum pname,
+       GLint params );
+
+GLAPI void GLAPIENTRY glConvolutionParameteriv( GLenum target, GLenum pname,
+       const GLint *params );
+
+GLAPI void GLAPIENTRY glCopyConvolutionFilter1D( GLenum target,
+       GLenum internalformat, GLint x, GLint y, GLsizei width );
+
+GLAPI void GLAPIENTRY glCopyConvolutionFilter2D( GLenum target,
+       GLenum internalformat, GLint x, GLint y, GLsizei width,
+       GLsizei height);
+
+GLAPI void GLAPIENTRY glGetConvolutionFilter( GLenum target, GLenum format,
+       GLenum type, GLvoid *image );
+
+GLAPI void GLAPIENTRY glGetConvolutionParameterfv( GLenum target, GLenum pname,
+       GLfloat *params );
+
+GLAPI void GLAPIENTRY glGetConvolutionParameteriv( GLenum target, GLenum pname,
+       GLint *params );
+
+GLAPI void GLAPIENTRY glSeparableFilter2D( GLenum target,
+       GLenum internalformat, GLsizei width, GLsizei height, GLenum format,
+       GLenum type, const GLvoid *row, const GLvoid *column );
+
+GLAPI void GLAPIENTRY glGetSeparableFilter( GLenum target, GLenum format,
+       GLenum type, GLvoid *row, GLvoid *column, GLvoid *span );
+
+GLAPI void GLAPIENTRY glCopyColorSubTable( GLenum target, GLsizei start,
+       GLint x, GLint y, GLsizei width );
+
+GLAPI void GLAPIENTRY glCopyColorTable( GLenum target, GLenum internalformat,
+       GLint x, GLint y, GLsizei width );
+
+
+
+/* GL_EXT_compiled_vertex_array */
+GLAPI void GLAPIENTRY glLockArraysEXT( GLint first, GLsizei count );
+GLAPI void GLAPIENTRY glUnlockArraysEXT( void );
+
+
+#if defined(__BEOS__) || defined(__QUICKDRAW__)
+#pragma export off
+#endif
+
+
+/*
+ * Compile-time tests for extensions:
+ */
+#define GL_EXT_blend_color             1
+#define GL_EXT_blend_logic_op          1
+#define GL_EXT_blend_minmax            1
+#define GL_EXT_blend_subtract          1
+#define GL_EXT_polygon_offset          1
+#define GL_EXT_vertex_array            1
+#define GL_EXT_texture_object          1
+#define GL_EXT_texture3D               1
+#define GL_EXT_paletted_texture                1
+#define GL_EXT_shared_texture_palette  1
+#define GL_EXT_point_parameters                1
+#define GL_EXT_rescale_normal          1
+#define GL_EXT_abgr                    1
+#define GL_EXT_stencil_wrap            1
+#define GL_MESA_window_pos             1
+#define GL_MESA_resize_buffers         1
+#define GL_SGIS_texture_edge_clamp     1
+#define GL_INGR_blend_func_separate    1
+#define GL_ARB_multitexture            1
+#define GL_NV_texgen_reflection                1
+#define GL_PGI_misc_hints               1
+#define GL_EXT_compiled_vertex_array    1
+#define GL_EXT_clip_volume_hint         1
+
+
+#ifdef macintosh
+       #pragma enumsalwaysint reset
+       #if PRAGMA_IMPORT_SUPPORTED
+       #pragma import off
+       #endif
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/GL/gl_mangle.h b/include/GL/gl_mangle.h
new file mode 100644 (file)
index 0000000..8ab25a9
--- /dev/null
@@ -0,0 +1,531 @@
+/* $Id: gl_mangle.h,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/*
+ * If you compile Mesa with USE_MGL_NAMESPACE defined then you can link
+ * your application both with OpenGL and Mesa.  The Mesa functions will
+ * be redefined so they are prefixed with "mgl" instead of "gl".
+ * Contributed by Randy Frank (rfrank@rsinc.com)
+ */
+
+#ifndef GL_MANGLE_H
+#define GL_MANGLE_H
+
+#define glClearIndex mglClearIndex
+#define glClearColor mglClearColor
+#define glClear  mglClear
+#define glIndexMask mglIndexMask
+#define glColorMask mglColorMask
+#define glAlphaFunc mglAlphaFunc
+#define glBlendFunc mglBlendFunc
+#define glLogicOp mglLogicOp
+#define glCullFace  mglCullFace
+#define glFrontFace mglFrontFace
+#define glPointSize mglPointSize
+#define glLineWidth mglLineWidth
+#define glLineStipple mglLineStipple
+#define glPolygonMode mglPolygonMode
+#define glPolygonOffset mglPolygonOffset
+#define glPolygonStipple mglPolygonStipple
+#define glGetPolygonStipple mglGetPolygonStipple
+#define glEdgeFlag mglEdgeFlag
+#define glEdgeFlagv mglEdgeFlagv
+#define glScissor  mglScissor
+#define glClipPlane mglClipPlane
+#define glGetClipPlane mglGetClipPlane
+#define glDrawBuffer mglDrawBuffer
+#define glReadBuffer mglReadBuffer
+#define glEnable mglEnable
+#define glDisable mglDisable
+#define glIsEnabled mglIsEnabled
+#define glEnableClientState mglEnableClientState
+#define glDisableClientState mglDisableClientState
+#define glGetBooleanv mglGetBooleanv
+#define glGetDoublev mglGetDoublev
+#define glGetFloatv mglGetFloatv
+#define glGetIntegerv mglGetIntegerv
+#define glPushAttrib mglPushAttrib
+#define glPopAttrib mglPopAttrib
+#define glPushClientAttrib mglPushClientAttrib
+#define glPopClientAttrib mglPopClientAttrib
+#define glRenderMode mglRenderMode
+#define glGetError mglGetError
+#define glGetString mglGetString
+#define glFinish mglFinish
+#define glFlush mglFlush
+#define glHint mglHint
+#define glClearDepth mglClearDepth
+#define glDepthFunc mglDepthFunc
+#define glDepthMask mglDepthMask
+#define glDepthRange mglDepthRange
+#define glClearAccum mglClearAccum
+#define glAccum mglAccum
+#define glMatrixMode mglMatrixMode
+#define glOrtho mglOrtho
+#define glFrustum mglFrustum
+#define glViewport mglViewport
+#define glPushMatrix mglPushMatrix
+#define glPopMatrix mglPopMatrix
+#define glLoadIdentity mglLoadIdentity
+#define glLoadMatrixd mglLoadMatrixd
+#define glLoadMatrixf mglLoadMatrixf
+#define glMultMatrixd mglMultMatrixd
+#define glMultMatrixf mglMultMatrixf
+#define glRotated mglRotated
+#define glRotatef mglRotatef
+#define glScaled mglScaled
+#define glScalef mglScalef
+#define glTranslated mglTranslated
+#define glTranslatef mglTranslatef
+#define glIsList mglIsList
+#define glDeleteLists mglDeleteLists
+#define glGenLists mglGenLists
+#define glNewList mglNewList
+#define glEndList mglEndList
+#define glCallList mglCallList
+#define glCallLists mglCallLists
+#define glListBase mglListBase
+#define glBegin mglBegin
+#define glEnd mglEnd
+#define glVertex2d mglVertex2d
+#define glVertex2f mglVertex2f
+#define glVertex2i mglVertex2i
+#define glVertex2s mglVertex2s
+#define glVertex3d mglVertex3d
+#define glVertex3f mglVertex3f
+#define glVertex3i mglVertex3i
+#define glVertex3s mglVertex3s
+#define glVertex4d mglVertex4d
+#define glVertex4f mglVertex4f
+#define glVertex4i mglVertex4i
+#define glVertex4s mglVertex4s
+#define glVertex2dv mglVertex2dv
+#define glVertex2fv mglVertex2fv
+#define glVertex2iv mglVertex2iv
+#define glVertex2sv mglVertex2sv
+#define glVertex3dv mglVertex3dv
+#define glVertex3fv mglVertex3fv
+#define glVertex3iv mglVertex3iv
+#define glVertex3sv mglVertex3sv
+#define glVertex4dv mglVertex4dv
+#define glVertex4fv mglVertex4fv
+#define glVertex4iv mglVertex4iv
+#define glVertex4sv mglVertex4sv
+#define glNormal3b mglNormal3b
+#define glNormal3d mglNormal3d
+#define glNormal3f mglNormal3f
+#define glNormal3i mglNormal3i
+#define glNormal3s mglNormal3s
+#define glNormal3bv mglNormal3bv
+#define glNormal3dv mglNormal3dv
+#define glNormal3fv mglNormal3fv
+#define glNormal3iv mglNormal3iv
+#define glNormal3sv mglNormal3sv
+#define glIndexd mglIndexd
+#define glIndexf mglIndexf
+#define glIndexi mglIndexi
+#define glIndexs mglIndexs
+#define glIndexub mglIndexub
+#define glIndexdv mglIndexdv
+#define glIndexfv mglIndexfv
+#define glIndexiv mglIndexiv
+#define glIndexsv mglIndexsv
+#define glIndexubv mglIndexubv
+#define glColor3b mglColor3b
+#define glColor3d mglColor3d
+#define glColor3f mglColor3f
+#define glColor3i mglColor3i
+#define glColor3s mglColor3s
+#define glColor3ub mglColor3ub
+#define glColor3ui mglColor3ui
+#define glColor3us mglColor3us
+#define glColor4b mglColor4b
+#define glColor4d mglColor4d
+#define glColor4f mglColor4f
+#define glColor4i mglColor4i
+#define glColor4s mglColor4s
+#define glColor4ub mglColor4ub
+#define glColor4ui mglColor4ui
+#define glColor4us mglColor4us
+#define glColor3bv mglColor3bv
+#define glColor3dv mglColor3dv
+#define glColor3fv mglColor3fv
+#define glColor3iv mglColor3iv
+#define glColor3sv mglColor3sv
+#define glColor3ubv mglColor3ubv
+#define glColor3uiv mglColor3uiv
+#define glColor3usv mglColor3usv
+#define glColor4bv mglColor4bv
+#define glColor4dv mglColor4dv
+#define glColor4fv mglColor4fv
+#define glColor4iv mglColor4iv
+#define glColor4sv mglColor4sv
+#define glColor4ubv mglColor4ubv
+#define glColor4uiv mglColor4uiv
+#define glColor4usv mglColor4usv
+#define glTexCoord1d mglTexCoord1d
+#define glTexCoord1f mglTexCoord1f
+#define glTexCoord1i mglTexCoord1i
+#define glTexCoord1s mglTexCoord1s
+#define glTexCoord2d mglTexCoord2d
+#define glTexCoord2f mglTexCoord2f
+#define glTexCoord2i mglTexCoord2i
+#define glTexCoord2s mglTexCoord2s
+#define glTexCoord3d mglTexCoord3d
+#define glTexCoord3f mglTexCoord3f
+#define glTexCoord3i mglTexCoord3i
+#define glTexCoord3s mglTexCoord3s
+#define glTexCoord4d mglTexCoord4d
+#define glTexCoord4f mglTexCoord4f
+#define glTexCoord4i mglTexCoord4i
+#define glTexCoord4s mglTexCoord4s
+#define glTexCoord1dv mglTexCoord1dv
+#define glTexCoord1fv mglTexCoord1fv
+#define glTexCoord1iv mglTexCoord1iv
+#define glTexCoord1sv mglTexCoord1sv
+#define glTexCoord2dv mglTexCoord2dv
+#define glTexCoord2fv mglTexCoord2fv
+#define glTexCoord2iv mglTexCoord2iv
+#define glTexCoord2sv mglTexCoord2sv
+#define glTexCoord3dv mglTexCoord3dv
+#define glTexCoord3fv mglTexCoord3fv
+#define glTexCoord3iv mglTexCoord3iv
+#define glTexCoord3sv mglTexCoord3sv
+#define glTexCoord4dv mglTexCoord4dv
+#define glTexCoord4fv mglTexCoord4fv
+#define glTexCoord4iv mglTexCoord4iv
+#define glTexCoord4sv mglTexCoord4sv
+#define glRasterPos2d mglRasterPos2d
+#define glRasterPos2f mglRasterPos2f
+#define glRasterPos2i mglRasterPos2i
+#define glRasterPos2s mglRasterPos2s
+#define glRasterPos3d mglRasterPos3d
+#define glRasterPos3f mglRasterPos3f
+#define glRasterPos3i mglRasterPos3i
+#define glRasterPos3s mglRasterPos3s
+#define glRasterPos4d mglRasterPos4d
+#define glRasterPos4f mglRasterPos4f
+#define glRasterPos4i mglRasterPos4i
+#define glRasterPos4s mglRasterPos4s
+#define glRasterPos2dv mglRasterPos2dv
+#define glRasterPos2fv mglRasterPos2fv
+#define glRasterPos2iv mglRasterPos2iv
+#define glRasterPos2sv mglRasterPos2sv
+#define glRasterPos3dv mglRasterPos3dv
+#define glRasterPos3fv mglRasterPos3fv
+#define glRasterPos3iv mglRasterPos3iv
+#define glRasterPos3sv mglRasterPos3sv
+#define glRasterPos4dv mglRasterPos4dv
+#define glRasterPos4fv mglRasterPos4fv
+#define glRasterPos4iv mglRasterPos4iv
+#define glRasterPos4sv mglRasterPos4sv
+#define glRectd mglRectd
+#define glRectf mglRectf
+#define glRecti mglRecti
+#define glRects mglRects
+#define glRectdv mglRectdv
+#define glRectfv mglRectfv
+#define glRectiv mglRectiv
+#define glRectsv mglRectsv
+#define glVertexPointer mglVertexPointer
+#define glNormalPointer mglNormalPointer
+#define glColorPointer mglColorPointer
+#define glIndexPointer mglIndexPointer
+#define glTexCoordPointer mglTexCoordPointer
+#define glEdgeFlagPointer mglEdgeFlagPointer
+#define glGetPointerv mglGetPointerv
+#define glArrayElement mglArrayElement
+#define glDrawArrays mglDrawArrays
+#define glDrawElements mglDrawElements
+#define glInterleavedArrays mglInterleavedArrays
+#define glShadeModel mglShadeModel
+#define glLightf mglLightf
+#define glLighti mglLighti
+#define glLightfv mglLightfv
+#define glLightiv mglLightiv
+#define glGetLightfv mglGetLightfv
+#define glGetLightiv mglGetLightiv
+#define glLightModelf mglLightModelf
+#define glLightModeli mglLightModeli
+#define glLightModelfv mglLightModelfv
+#define glLightModeliv mglLightModeliv
+#define glMaterialf mglMaterialf
+#define glMateriali mglMateriali
+#define glMaterialfv mglMaterialfv
+#define glMaterialiv mglMaterialiv
+#define glGetMaterialfv mglGetMaterialfv
+#define glGetMaterialiv mglGetMaterialiv
+#define glColorMaterial mglColorMaterial
+#define glPixelZoom mglPixelZoom
+#define glPixelStoref mglPixelStoref
+#define glPixelStorei mglPixelStorei
+#define glPixelTransferf mglPixelTransferf
+#define glPixelTransferi mglPixelTransferi
+#define glPixelMapfv mglPixelMapfv
+#define glPixelMapuiv mglPixelMapuiv
+#define glPixelMapusv mglPixelMapusv
+#define glGetPixelMapfv mglGetPixelMapfv
+#define glGetPixelMapuiv mglGetPixelMapuiv
+#define glGetPixelMapusv mglGetPixelMapusv
+#define glBitmap mglBitmap
+#define glReadPixels mglReadPixels
+#define glDrawPixels mglDrawPixels
+#define glCopyPixels mglCopyPixels
+#define glStencilFunc mglStencilFunc
+#define glStencilMask mglStencilMask
+#define glStencilOp mglStencilOp
+#define glClearStencil mglClearStencil
+#define glTexGend mglTexGend
+#define glTexGenf mglTexGenf
+#define glTexGeni mglTexGeni
+#define glTexGendv mglTexGendv
+#define glTexGenfv mglTexGenfv
+#define glTexGeniv mglTexGeniv
+#define glGetTexGendv mglGetTexGendv
+#define glGetTexGenfv mglGetTexGenfv
+#define glGetTexGeniv mglGetTexGeniv
+#define glTexEnvf mglTexEnvf
+#define glTexEnvi mglTexEnvi
+#define glTexEnvfv mglTexEnvfv
+#define glTexEnviv mglTexEnviv
+#define glGetTexEnvfv mglGetTexEnvfv
+#define glGetTexEnviv mglGetTexEnviv
+#define glTexParameterf mglTexParameterf
+#define glTexParameteri mglTexParameteri
+#define glTexParameterfv mglTexParameterfv
+#define glTexParameteriv mglTexParameteriv
+#define glGetTexParameterfv mglGetTexParameterfv
+#define glGetTexParameteriv mglGetTexParameteriv
+#define glGetTexLevelParameterfv mglGetTexLevelParameterfv
+#define glGetTexLevelParameteriv mglGetTexLevelParameteriv
+#define glTexImage1D mglTexImage1D
+#define glTexImage2D mglTexImage2D
+#define glGetTexImage mglGetTexImage
+#define glGenTextures mglGenTextures
+#define glDeleteTextures mglDeleteTextures
+#define glBindTexture mglBindTexture
+#define glPrioritizeTextures mglPrioritizeTextures
+#define glAreTexturesResident mglAreTexturesResident
+#define glIsTexture mglIsTexture
+#define glTexSubImage1D mglTexSubImage1D
+#define glTexSubImage2D mglTexSubImage2D
+#define glCopyTexImage1D mglCopyTexImage1D
+#define glCopyTexImage2D mglCopyTexImage2D
+#define glCopyTexSubImage1D mglCopyTexSubImage1D
+#define glCopyTexSubImage2D mglCopyTexSubImage2D
+#define glMap1d mglMap1d
+#define glMap1f mglMap1f
+#define glMap2d mglMap2d
+#define glMap2f mglMap2f
+#define glGetMapdv mglGetMapdv
+#define glGetMapfv mglGetMapfv
+#define glGetMapiv mglGetMapiv
+#define glEvalCoord1d mglEvalCoord1d
+#define glEvalCoord1f mglEvalCoord1f
+#define glEvalCoord1dv mglEvalCoord1dv
+#define glEvalCoord1fv mglEvalCoord1fv
+#define glEvalCoord2d mglEvalCoord2d
+#define glEvalCoord2f mglEvalCoord2f
+#define glEvalCoord2dv mglEvalCoord2dv
+#define glEvalCoord2fv mglEvalCoord2fv
+#define glMapGrid1d mglMapGrid1d
+#define glMapGrid1f mglMapGrid1f
+#define glMapGrid2d mglMapGrid2d
+#define glMapGrid2f mglMapGrid2f
+#define glEvalPoint1 mglEvalPoint1
+#define glEvalPoint2 mglEvalPoint2
+#define glEvalMesh1 mglEvalMesh1
+#define glEvalMesh2 mglEvalMesh2
+#define glFogf mglFogf
+#define glFogi mglFogi
+#define glFogfv mglFogfv
+#define glFogiv mglFogiv
+#define glFeedbackBuffer mglFeedbackBuffer
+#define glPassThrough mglPassThrough
+#define glSelectBuffer mglSelectBuffer
+#define glInitNames mglInitNames
+#define glLoadName mglLoadName
+#define glPushName mglPushName
+#define glPopName mglPopName
+#define glBlendEquation mglBlendEquation
+#define glBlendEquationEXT mglBlendEquationEXT
+#define glBlendColor mglBlendColor
+#define glBlendColorEXT mglBlendColorEXT
+#define glPolygonOffsetEXT mglPolygonOffsetEXT
+#define glVertexPointerEXT mglVertexPointerEXT
+#define glNormalPointerEXT mglNormalPointerEXT
+#define glColorPointerEXT mglColorPointerEXT
+#define glIndexPointerEXT mglIndexPointerEXT
+#define glTexCoordPointerEXT mglTexCoordPointerEXT
+#define glEdgeFlagPointerEXT mglEdgeFlagPointerEXT
+#define glGetPointervEXT mglGetPointervEXT
+#define glArrayElementEXT mglArrayElementEXT
+#define glDrawArraysEXT mglDrawArraysEXT
+#define glGenTexturesEXT mglGenTexturesEXT
+#define glDeleteTexturesEXT mglDeleteTexturesEXT
+#define glBindTextureEXT mglBindTextureEXT
+#define glPrioritizeTexturesEXT mglPrioritizeTexturesEXT
+#define glAreTexturesResidentEXT mglAreTexturesResidentEXT
+#define glIsTextureEXT mglIsTextureEXT
+#define glTexImage3DEXT mglTexImage3DEXT
+#define glTexSubImage3DEXT mglTexSubImage3DEXT
+#define glCopyTexSubImage3DEXT mglCopyTexSubImage3DEXT
+#define glColorTableEXT mglColorTableEXT
+#define glColorSubTableEXT mglColorSubTableEXT
+#define glGetColorTableEXT mglGetColorTableEXT
+#define glGetColorTableParameterfvEXT mglGetColorTableParameterfvEXT
+#define glGetColorTableParameterivEXT mglGetColorTableParameterivEXT
+#define glGetMinMax mglGetMinMax
+#define glMultiTexCoord1dSGIS mglMultiTexCoord1dSGIS
+#define glMultiTexCoord1dvSGIS mglMultiTexCoord1dvSGIS
+#define glMultiTexCoord1fSGIS mglMultiTexCoord1fSGIS
+#define glMultiTexCoord1fvSGIS mglMultiTexCoord1fvSGIS
+#define glMultiTexCoord1iSGIS mglMultiTexCoord1iSGIS
+#define glMultiTexCoord1ivSGIS mglMultiTexCoord1ivSGIS
+#define glMultiTexCoord1sSGIS mglMultiTexCoord1sSGIS
+#define glMultiTexCoord1svSGIS mglMultiTexCoord1svSGIS
+#define glMultiTexCoord2dSGIS mglMultiTexCoord2dSGIS
+#define glMultiTexCoord2dvSGIS mglMultiTexCoord2dvSGIS
+#define glMultiTexCoord2fSGIS mglMultiTexCoord2fSGIS
+#define glMultiTexCoord2fvSGIS mglMultiTexCoord2fvSGIS
+#define glMultiTexCoord2iSGIS mglMultiTexCoord2iSGIS
+#define glMultiTexCoord2ivSGIS mglMultiTexCoord2ivSGIS
+#define glMultiTexCoord2sSGIS mglMultiTexCoord2sSGIS
+#define glMultiTexCoord2svSGIS mglMultiTexCoord2svSGIS
+#define glMultiTexCoord3dSGIS mglMultiTexCoord3dSGIS
+#define glMultiTexCoord3dvSGIS mglMultiTexCoord3dvSGIS
+#define glMultiTexCoord3fSGIS mglMultiTexCoord3fSGIS
+#define glMultiTexCoord3fvSGIS mglMultiTexCoord3fvSGIS
+#define glMultiTexCoord3iSGIS mglMultiTexCoord3iSGIS
+#define glMultiTexCoord3ivSGIS mglMultiTexCoord3ivSGIS
+#define glMultiTexCoord3sSGIS mglMultiTexCoord3sSGIS
+#define glMultiTexCoord3svSGIS mglMultiTexCoord3svSGIS
+#define glMultiTexCoord4dSGIS mglMultiTexCoord4dSGIS
+#define glMultiTexCoord4dvSGIS mglMultiTexCoord4dvSGIS
+#define glMultiTexCoord4fSGIS mglMultiTexCoord4fSGIS
+#define glMultiTexCoord4fvSGIS mglMultiTexCoord4fvSGIS
+#define glMultiTexCoord4iSGIS mglMultiTexCoord4iSGIS
+#define glMultiTexCoord4ivSGIS mglMultiTexCoord4ivSGIS
+#define glMultiTexCoord4sSGIS mglMultiTexCoord4sSGIS
+#define glMultiTexCoord4svSGIS mglMultiTexCoord4svSGIS
+#define glMultiTexCoordPointerSGIS mglMultiTexCoordPointerSGIS
+#define glSelectTextureSGIS mglSelectTextureSGIS
+#define glSelectTextureCoordSetSGIS mglSelectTextureCoordSetSGIS
+#define glActiveTextureARB mglActiveTextureARB
+#define glClientActiveTextureARB mglClientActiveTextureARB
+#define glMultiTexCoord1dARB mglMultiTexCoord1dARB
+#define glMultiTexCoord1dvARB mglMultiTexCoord1dvARB
+#define glMultiTexCoord1fARB mglMultiTexCoord1fARB
+#define glMultiTexCoord1fvARB mglMultiTexCoord1fvARB
+#define glMultiTexCoord1iARB mglMultiTexCoord1iARB
+#define glMultiTexCoord1ivARB mglMultiTexCoord1ivARB
+#define glMultiTexCoord1sARB mglMultiTexCoord1sARB
+#define glMultiTexCoord1svARB mglMultiTexCoord1svARB
+#define glMultiTexCoord2dARB mglMultiTexCoord2dARB
+#define glMultiTexCoord2dvARB mglMultiTexCoord2dvARB
+#define glMultiTexCoord2fARB mglMultiTexCoord2fARB
+#define glMultiTexCoord2fvARB mglMultiTexCoord2fvARB
+#define glMultiTexCoord2iARB mglMultiTexCoord2iARB
+#define glMultiTexCoord2ivARB mglMultiTexCoord2ivARB
+#define glMultiTexCoord2sARB mglMultiTexCoord2sARB
+#define glMultiTexCoord2svARB mglMultiTexCoord2svARB
+#define glMultiTexCoord3dARB mglMultiTexCoord3dARB
+#define glMultiTexCoord3dvARB mglMultiTexCoord3dvARB
+#define glMultiTexCoord3fARB mglMultiTexCoord3fARB
+#define glMultiTexCoord3fvARB mglMultiTexCoord3fvARB
+#define glMultiTexCoord3iARB mglMultiTexCoord3iARB
+#define glMultiTexCoord3ivARB mglMultiTexCoord3ivARB
+#define glMultiTexCoord3sARB mglMultiTexCoord3sARB
+#define glMultiTexCoord3svARB mglMultiTexCoord3svARB
+#define glMultiTexCoord4dARB mglMultiTexCoord4dARB
+#define glMultiTexCoord4dvARB mglMultiTexCoord4dvARB
+#define glMultiTexCoord4fARB mglMultiTexCoord4fARB
+#define glMultiTexCoord4fvARB mglMultiTexCoord4fvARB
+#define glMultiTexCoord4iARB mglMultiTexCoord4iARB
+#define glMultiTexCoord4ivARB mglMultiTexCoord4ivARB
+#define glMultiTexCoord4sARB mglMultiTexCoord4sARB
+#define glMultiTexCoord4svARB mglMultiTexCoord4svARB
+#define glPointParameterfEXT mglPointParameterfEXT
+#define glPointParameterfvEXT mglPointParameterfvEXT
+#define glBlendFuncSeparateINGR mglBlendFuncSeparateINGR
+#define glWindowPos2iMESA mglWindowPos2iMESA
+#define glWindowPos2sMESA mglWindowPos2sMESA
+#define glWindowPos2fMESA mglWindowPos2fMESA
+#define glWindowPos2dMESA mglWindowPos2dMESA
+#define glWindowPos2ivMESA mglWindowPos2ivMESA
+#define glWindowPos2svMESA mglWindowPos2svMESA
+#define glWindowPos2fvMESA mglWindowPos2fvMESA
+#define glWindowPos2dvMESA mglWindowPos2dvMESA
+#define glWindowPos3iMESA mglWindowPos3iMESA
+#define glWindowPos3sMESA mglWindowPos3sMESA
+#define glWindowPos3fMESA mglWindowPos3fMESA
+#define glWindowPos3dMESA mglWindowPos3dMESA
+#define glWindowPos3ivMESA mglWindowPos3ivMESA
+#define glWindowPos3svMESA mglWindowPos3svMESA
+#define glWindowPos3fvMESA mglWindowPos3fvMESA
+#define glWindowPos3dvMESA mglWindowPos3dvMESA
+#define glWindowPos4iMESA mglWindowPos4iMESA
+#define glWindowPos4sMESA mglWindowPos4sMESA
+#define glWindowPos4fMESA mglWindowPos4fMESA
+#define glWindowPos4dMESA mglWindowPos4dMESA
+#define glWindowPos4ivMESA mglWindowPos4ivMESA
+#define glWindowPos4svMESA mglWindowPos4svMESA
+#define glWindowPos4fvMESA mglWindowPos4fvMESA
+#define glWindowPos4dvMESA mglWindowPos4dvMESA
+#define glResizeBuffersMESA mglResizeBuffersMESA
+#define glDrawRangeElements mglDrawRangeElements
+#define glTexImage3D mglTexImage3D
+#define glTexSubImage3D mglTexSubImage3D
+#define glCopyTexSubImage3D mglCopyTexSubImage3D
+#define glHistogram mglHistogram
+#define glResetHistogram mglResetHistogram
+#define glGetHistogram mglGetHistogram
+#define glGetHistogramParameterfv mglGetHistogramParameterfv
+#define glGetHistogramParameteriv mglGetHistogramParameteriv
+#define glMinmax mglMinmax
+#define glResetMinmax mglResetMinmax
+#define glGetMinmaxParameterfv mglGetMinmaxParameterfv
+#define glGetMinmaxParameteriv mglGetMinmaxParameteriv
+#define glConvolutionFilter1D mglConvolutionFilter1D
+#define glConvolutionFilter2D mglConvolutionFilter2D
+#define glConvolutionParameterf mglConvolutionParameterf
+#define glConvolutionParameterfv mglConvolutionParameterfv
+#define glConvolutionParameteri mglConvolutionParameteri
+#define glConvolutionParameteriv mglConvolutionParameteriv
+#define glCopyConvolutionFilter1D mglCopyConvolutionFilter1D
+#define glCopyConvolutionFilter2D mglCopyConvolutionFilter2D
+#define glGetConvolutionFilter mglGetConvolutionFilter
+#define glGetConvolutionParameterfv mglGetConvolutionParameterfv
+#define glGetConvolutionParameteriv mglGetConvolutionParameteriv
+#define glSeparableFilter2D mglSeparableFilter2D
+#define glGetSeparableFilter mglGetSeparableFilter
+#define glCopyColorSubTable mglCopyColorSubTable
+#define glCopyColorTable mglCopyColorTable
+#define glLockArraysEXT mglLockArraysEXT
+#define glUnlockArraysEXT mglUnlockArraysEXT
+
+#endif
diff --git a/include/GL/glu.h b/include/GL/glu.h
new file mode 100644 (file)
index 0000000..b1321c0
--- /dev/null
@@ -0,0 +1,444 @@
+/* $Id: glu.h,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * Copyright (C) 1995-1999  Brian Paul
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/*
+ * $Log: glu.h,v $
+ * Revision 1.1  1999/08/19 00:55:40  jtg
+ * Initial revision
+ *
+ * Revision 3.6  1999/02/14 03:39:45  brianp
+ * updated for BeOS R4
+ *
+ * Revision 3.5  1999/01/03 03:02:55  brianp
+ * now using GLAPI and GLAPIENTRY keywords, misc Windows changes (Ted Jump)
+ *
+ * Revision 3.4  1998/12/01 02:34:27  brianp
+ * applied Mark Kilgard's patches from November 30, 1998
+ *
+ * Revision 3.3  1998/11/17 01:14:02  brianp
+ * minor changes for OpenStep compilation (pete@ohm.york.ac.uk)
+ *
+ * Revision 3.2  1998/07/26 01:36:27  brianp
+ * changes for Windows compilation per Ted Jump
+ *
+ * Revision 3.1  1998/06/23 00:33:08  brianp
+ * added some WIN32 APIENTRY, CALLBACK stuff (Eric Lassauge)
+ *
+ * Revision 3.0  1998/02/20 05:06:01  brianp
+ * initial rev
+ *
+ */
+
+
+#ifndef GLU_H
+#define GLU_H
+
+
+#if defined(USE_MGL_NAMESPACE)
+#include "glu_mangle.h"
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#include "GL/gl.h"
+
+       /* to facilitate clean DLL building ... */
+#if !defined(OPENSTEP) && (defined(__WIN32__) || defined(__CYGWIN32__))
+#      if defined(_MSC_VER) && defined(BUILD_GLU32) /* tag specify we're building mesa as a DLL */
+#              define GLUAPI __declspec(dllexport)
+#      elif defined(_MSC_VER) && defined(_DLL) /* tag specifying we're building for DLL runtime support */
+#              define GLUAPI __declspec(dllimport)
+#      else /* for use with static link lib build of Win32 edition only */
+#              define GLUAPI extern
+#      endif /* _STATIC_MESA support */
+#else
+#      define GLUAPI extern
+#endif /* WIN32 / CYGWIN32 bracket */
+
+#ifdef macintosh
+       #pragma enumsalwaysint on
+       #if PRAGMA_IMPORT_SUPPORTED
+       #pragma import on
+       #endif
+#endif
+
+
+#define GLU_VERSION_1_1                1
+
+
+#define GLU_TRUE   GL_TRUE
+#define GLU_FALSE  GL_FALSE
+
+
+enum {
+       /* Normal vectors */
+       GLU_SMOOTH      = 100000,
+       GLU_FLAT        = 100001,
+       GLU_NONE        = 100002,
+
+       /* Quadric draw styles */
+       GLU_POINT       = 100010,
+       GLU_LINE        = 100011,
+       GLU_FILL        = 100012,
+       GLU_SILHOUETTE  = 100013,
+
+       /* Quadric orientation */
+       GLU_OUTSIDE     = 100020,
+       GLU_INSIDE      = 100021,
+
+       /* Tesselator */
+       GLU_BEGIN       = 100100,
+       GLU_VERTEX      = 100101,
+       GLU_END         = 100102,
+       GLU_ERROR       = 100103,
+       GLU_EDGE_FLAG   = 100104,
+
+       /* Contour types */
+       GLU_CW          = 100120,
+       GLU_CCW         = 100121,
+       GLU_INTERIOR    = 100122,
+       GLU_EXTERIOR    = 100123,
+       GLU_UNKNOWN     = 100124,
+
+       /* Tesselation errors */
+       GLU_TESS_ERROR1 = 100151,  /* missing gluEndPolygon */
+       GLU_TESS_ERROR2 = 100152,  /* missing gluBeginPolygon */
+       GLU_TESS_ERROR3 = 100153,  /* misoriented contour */
+       GLU_TESS_ERROR4 = 100154,  /* vertex/edge intersection */
+       GLU_TESS_ERROR5 = 100155,  /* misoriented or self-intersecting loops */
+       GLU_TESS_ERROR6 = 100156,  /* coincident vertices */
+       GLU_TESS_ERROR7 = 100157,  /* all vertices collinear */
+       GLU_TESS_ERROR8 = 100158,  /* intersecting edges */
+       GLU_TESS_ERROR9 = 100159,  /* not coplanar contours */
+
+       /* NURBS */
+       GLU_AUTO_LOAD_MATRIX    = 100200,
+       GLU_CULLING             = 100201,
+       GLU_PARAMETRIC_TOLERANCE= 100202,
+       GLU_SAMPLING_TOLERANCE  = 100203,
+       GLU_DISPLAY_MODE        = 100204,
+       GLU_SAMPLING_METHOD     = 100205,
+       GLU_U_STEP              = 100206,
+       GLU_V_STEP              = 100207,
+
+       GLU_PATH_LENGTH         = 100215,
+       GLU_PARAMETRIC_ERROR    = 100216,
+       GLU_DOMAIN_DISTANCE     = 100217,
+
+       GLU_MAP1_TRIM_2         = 100210,
+       GLU_MAP1_TRIM_3         = 100211,
+
+       GLU_OUTLINE_POLYGON     = 100240,
+       GLU_OUTLINE_PATCH       = 100241,
+
+       GLU_NURBS_ERROR1  = 100251,   /* spline order un-supported */
+       GLU_NURBS_ERROR2  = 100252,   /* too few knots */
+       GLU_NURBS_ERROR3  = 100253,   /* valid knot range is empty */
+       GLU_NURBS_ERROR4  = 100254,   /* decreasing knot sequence */
+       GLU_NURBS_ERROR5  = 100255,   /* knot multiplicity > spline order */
+       GLU_NURBS_ERROR6  = 100256,   /* endcurve() must follow bgncurve() */
+       GLU_NURBS_ERROR7  = 100257,   /* bgncurve() must precede endcurve() */
+       GLU_NURBS_ERROR8  = 100258,   /* ctrlarray or knot vector is NULL */
+       GLU_NURBS_ERROR9  = 100259,   /* can't draw pwlcurves */
+       GLU_NURBS_ERROR10 = 100260,   /* missing gluNurbsCurve() */
+       GLU_NURBS_ERROR11 = 100261,   /* missing gluNurbsSurface() */
+       GLU_NURBS_ERROR12 = 100262,   /* endtrim() must precede endsurface() */
+       GLU_NURBS_ERROR13 = 100263,   /* bgnsurface() must precede endsurface() */
+       GLU_NURBS_ERROR14 = 100264,   /* curve of improper type passed as trim curve */
+       GLU_NURBS_ERROR15 = 100265,   /* bgnsurface() must precede bgntrim() */
+       GLU_NURBS_ERROR16 = 100266,   /* endtrim() must follow bgntrim() */
+       GLU_NURBS_ERROR17 = 100267,   /* bgntrim() must precede endtrim()*/
+       GLU_NURBS_ERROR18 = 100268,   /* invalid or missing trim curve*/
+       GLU_NURBS_ERROR19 = 100269,   /* bgntrim() must precede pwlcurve() */
+       GLU_NURBS_ERROR20 = 100270,   /* pwlcurve referenced twice*/
+       GLU_NURBS_ERROR21 = 100271,   /* pwlcurve and nurbscurve mixed */
+       GLU_NURBS_ERROR22 = 100272,   /* improper usage of trim data type */
+       GLU_NURBS_ERROR23 = 100273,   /* nurbscurve referenced twice */
+       GLU_NURBS_ERROR24 = 100274,   /* nurbscurve and pwlcurve mixed */
+       GLU_NURBS_ERROR25 = 100275,   /* nurbssurface referenced twice */
+       GLU_NURBS_ERROR26 = 100276,   /* invalid property */
+       GLU_NURBS_ERROR27 = 100277,   /* endsurface() must follow bgnsurface() */
+       GLU_NURBS_ERROR28 = 100278,   /* intersecting or misoriented trim curves */
+       GLU_NURBS_ERROR29 = 100279,   /* intersecting trim curves */
+       GLU_NURBS_ERROR30 = 100280,   /* UNUSED */
+       GLU_NURBS_ERROR31 = 100281,   /* unconnected trim curves */
+       GLU_NURBS_ERROR32 = 100282,   /* unknown knot error */
+       GLU_NURBS_ERROR33 = 100283,   /* negative vertex count encountered */
+       GLU_NURBS_ERROR34 = 100284,   /* negative byte-stride */
+       GLU_NURBS_ERROR35 = 100285,   /* unknown type descriptor */
+       GLU_NURBS_ERROR36 = 100286,   /* null control point reference */
+       GLU_NURBS_ERROR37 = 100287,   /* duplicate point on pwlcurve */
+
+       /* Errors */
+       GLU_INVALID_ENUM                = 100900,
+       GLU_INVALID_VALUE               = 100901,
+       GLU_OUT_OF_MEMORY               = 100902,
+       GLU_INCOMPATIBLE_GL_VERSION     = 100903,
+
+       /* New in GLU 1.1 */
+       GLU_VERSION     = 100800,
+       GLU_EXTENSIONS  = 100801
+};
+
+
+/*
+ * These are the GLU 1.1 typedefs.  GLU 1.2 has different ones!
+ */
+#if defined(__BEOS__)
+   /* The BeOS does something funky and makes these typedefs in one
+    * of its system headers.
+    */
+#else
+   typedef struct GLUquadric GLUquadricObj;
+   typedef struct GLUtesselator GLUtriangulatorObj;
+   typedef struct GLUnurbs GLUnurbsObj;
+#endif
+
+
+
+#if defined(__BEOS__) || defined(__QUICKDRAW__)
+#pragma export on
+#endif
+
+
+/*
+ *
+ * Miscellaneous functions
+ *
+ */
+
+GLUAPI void GLAPIENTRY gluLookAt( GLdouble eyex, GLdouble eyey, GLdouble eyez,
+                                GLdouble centerx, GLdouble centery,
+                                GLdouble centerz,
+                                GLdouble upx, GLdouble upy, GLdouble upz );
+
+
+GLUAPI void GLAPIENTRY gluOrtho2D( GLdouble left, GLdouble right,
+                                 GLdouble bottom, GLdouble top );
+
+
+GLUAPI void GLAPIENTRY gluPerspective( GLdouble fovy, GLdouble aspect,
+                                     GLdouble zNear, GLdouble zFar );
+
+
+GLUAPI void GLAPIENTRY gluPickMatrix( GLdouble x, GLdouble y,
+                                    GLdouble width, GLdouble height,
+                                    const GLint viewport[4] );
+
+GLUAPI GLint GLAPIENTRY gluProject( GLdouble objx, GLdouble objy, GLdouble objz,
+                                  const GLdouble modelMatrix[16],
+                                  const GLdouble projMatrix[16],
+                                  const GLint viewport[4],
+                                  GLdouble *winx, GLdouble *winy,
+                                  GLdouble *winz );
+
+GLUAPI GLint GLAPIENTRY gluUnProject( GLdouble winx, GLdouble winy,
+                                    GLdouble winz,
+                                    const GLdouble modelMatrix[16],
+                                    const GLdouble projMatrix[16],
+                                    const GLint viewport[4],
+                                    GLdouble *objx, GLdouble *objy,
+                                    GLdouble *objz );
+
+GLUAPI const GLubyte* GLAPIENTRY gluErrorString( GLenum errorCode );
+
+
+
+/*
+ *
+ * Mipmapping and image scaling
+ *
+ */
+
+GLUAPI GLint GLAPIENTRY gluScaleImage( GLenum format,
+                                     GLint widthin, GLint heightin,
+                                     GLenum typein, const void *datain,
+                                     GLint widthout, GLint heightout,
+                                     GLenum typeout, void *dataout );
+
+GLUAPI GLint GLAPIENTRY gluBuild1DMipmaps( GLenum target, GLint components,
+                                         GLint width, GLenum format,
+                                         GLenum type, const void *data );
+
+GLUAPI GLint GLAPIENTRY gluBuild2DMipmaps( GLenum target, GLint components,
+                                         GLint width, GLint height,
+                                         GLenum format,
+                                         GLenum type, const void *data );
+
+
+
+/*
+ *
+ * Quadrics
+ *
+ */
+
+GLUAPI GLUquadricObj* GLAPIENTRY gluNewQuadric( void );
+
+GLUAPI void GLAPIENTRY gluDeleteQuadric( GLUquadricObj *state );
+
+GLUAPI void GLAPIENTRY gluQuadricDrawStyle( GLUquadricObj *quadObject,
+                                          GLenum drawStyle );
+
+GLUAPI void GLAPIENTRY gluQuadricOrientation( GLUquadricObj *quadObject,
+                                            GLenum orientation );
+
+GLUAPI void GLAPIENTRY gluQuadricNormals( GLUquadricObj *quadObject,
+                                        GLenum normals );
+
+GLUAPI void GLAPIENTRY gluQuadricTexture( GLUquadricObj *quadObject,
+                                        GLboolean textureCoords );
+
+GLUAPI void GLAPIENTRY gluQuadricCallback( GLUquadricObj *qobj,
+                                         GLenum which, void (GLCALLBACK *fn)() );
+
+GLUAPI void GLAPIENTRY gluCylinder( GLUquadricObj *qobj,
+                                  GLdouble baseRadius,
+                                  GLdouble topRadius,
+                                  GLdouble height,
+                                  GLint slices, GLint stacks );
+
+GLUAPI void GLAPIENTRY gluSphere( GLUquadricObj *qobj,
+                                GLdouble radius, GLint slices, GLint stacks );
+
+GLUAPI void GLAPIENTRY gluDisk( GLUquadricObj *qobj,
+                              GLdouble innerRadius, GLdouble outerRadius,
+                              GLint slices, GLint loops );
+
+GLUAPI void GLAPIENTRY gluPartialDisk( GLUquadricObj *qobj, GLdouble innerRadius,
+                                     GLdouble outerRadius, GLint slices,
+                                     GLint loops, GLdouble startAngle,
+                                     GLdouble sweepAngle );
+
+
+
+/*
+ *
+ * Nurbs
+ *
+ */
+
+GLUAPI GLUnurbsObj* GLAPIENTRY gluNewNurbsRenderer( void );
+
+GLUAPI void GLAPIENTRY gluDeleteNurbsRenderer( GLUnurbsObj *nobj );
+
+GLUAPI void GLAPIENTRY gluLoadSamplingMatrices( GLUnurbsObj *nobj,
+                                              const GLfloat modelMatrix[16],
+                                              const GLfloat projMatrix[16],
+                                              const GLint viewport[4] );
+
+GLUAPI void GLAPIENTRY gluNurbsProperty( GLUnurbsObj *nobj, GLenum property,
+                                       GLfloat value );
+
+GLUAPI void GLAPIENTRY gluGetNurbsProperty( GLUnurbsObj *nobj, GLenum property,
+                                          GLfloat *value );
+
+GLUAPI void GLAPIENTRY gluBeginCurve( GLUnurbsObj *nobj );
+
+GLUAPI void GLAPIENTRY gluEndCurve( GLUnurbsObj * nobj );
+
+GLUAPI void GLAPIENTRY gluNurbsCurve( GLUnurbsObj *nobj, GLint nknots,
+                                    GLfloat *knot, GLint stride,
+                                    GLfloat *ctlarray, GLint order,
+                                    GLenum type );
+
+GLUAPI void GLAPIENTRY gluBeginSurface( GLUnurbsObj *nobj );
+
+GLUAPI void GLAPIENTRY gluEndSurface( GLUnurbsObj * nobj );
+
+GLUAPI void GLAPIENTRY gluNurbsSurface( GLUnurbsObj *nobj,
+                                      GLint sknot_count, GLfloat *sknot,
+                                      GLint tknot_count, GLfloat *tknot,
+                                      GLint s_stride, GLint t_stride,
+                                      GLfloat *ctlarray,
+                                      GLint sorder, GLint torder,
+                                      GLenum type );
+
+GLUAPI void GLAPIENTRY gluBeginTrim( GLUnurbsObj *nobj );
+
+GLUAPI void GLAPIENTRY gluEndTrim( GLUnurbsObj *nobj );
+
+GLUAPI void GLAPIENTRY gluPwlCurve( GLUnurbsObj *nobj, GLint count,
+                                  GLfloat *array, GLint stride, GLenum type );
+
+GLUAPI void GLAPIENTRY gluNurbsCallback( GLUnurbsObj *nobj, GLenum which,
+                                       void (GLCALLBACK *fn)() );
+
+
+
+/*
+ *
+ * Polygon tesselation
+ *
+ */
+
+GLUAPI GLUtriangulatorObj* GLAPIENTRY gluNewTess( void );
+
+GLUAPI void GLAPIENTRY gluTessCallback( GLUtriangulatorObj *tobj, GLenum which,
+                                      void (GLCALLBACK *fn)() );
+
+GLUAPI void GLAPIENTRY gluDeleteTess( GLUtriangulatorObj *tobj );
+
+GLUAPI void GLAPIENTRY gluBeginPolygon( GLUtriangulatorObj *tobj );
+
+GLUAPI void GLAPIENTRY gluEndPolygon( GLUtriangulatorObj *tobj );
+
+GLUAPI void GLAPIENTRY gluNextContour( GLUtriangulatorObj *tobj, GLenum type );
+
+GLUAPI void GLAPIENTRY gluTessVertex( GLUtriangulatorObj *tobj, GLdouble v[3],
+                                    void *data );
+
+
+
+/*
+ *
+ * New functions in GLU 1.1
+ *
+ */
+
+GLUAPI const GLubyte* GLAPIENTRY gluGetString( GLenum name );
+
+
+#if defined(__BEOS__) || defined(__QUICKDRAW__)
+#pragma export off
+#endif
+
+
+#ifdef macintosh
+       #pragma enumsalwaysint reset
+       #if PRAGMA_IMPORT_SUPPORTED
+       #pragma import off
+       #endif
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/include/GL/glu_mangle.h b/include/GL/glu_mangle.h
new file mode 100644 (file)
index 0000000..ed3944c
--- /dev/null
@@ -0,0 +1,86 @@
+/* $Id: glu_mangle.h,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.0
+ * Copyright (C) 1995-1998  Brian Paul
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/*
+ * $Log: glu_mangle.h,v $
+ * Revision 1.1  1999/08/19 00:55:40  jtg
+ * Initial revision
+ *
+ * Revision 3.1  1999/06/21 22:00:42  brianp
+ * added #ifndef GLU_MANGLE_H stuff
+ *
+ * Revision 3.0  1998/02/20 05:04:45  brianp
+ * initial rev
+ *
+ */
+
+#ifndef GLU_MANGLE_H
+#define GLU_MANGLE_H
+
+
+#define gluLookAt mgluLookAt
+#define gluOrtho2D mgluOrtho2D
+#define gluPerspective mgluPerspective
+#define gluPickMatrix mgluPickMatrix
+#define gluProject mgluProject
+#define gluUnProject mgluUnProject
+#define gluErrorString mgluErrorString
+#define gluScaleImage mgluScaleImage
+#define gluBuild1DMipmaps mgluBuild1DMipmaps
+#define gluBuild2DMipmaps mgluBuild2DMipmaps
+#define gluNewQuadric mgluNewQuadric
+#define gluDeleteQuadric mgluDeleteQuadric
+#define gluQuadricDrawStyle mgluQuadricDrawStyle
+#define gluQuadricOrientation mgluQuadricOrientation
+#define gluQuadricNormals mgluQuadricNormals
+#define gluQuadricTexture mgluQuadricTexture
+#define gluQuadricCallback mgluQuadricCallback
+#define gluCylinder mgluCylinder
+#define gluSphere mgluSphere
+#define gluDisk mgluDisk
+#define gluPartialDisk mgluPartialDisk
+#define gluNewNurbsRenderer mgluNewNurbsRenderer
+#define gluDeleteNurbsRenderer mgluDeleteNurbsRenderer
+#define gluLoadSamplingMatrices mgluLoadSamplingMatrices
+#define gluNurbsProperty mgluNurbsProperty
+#define gluGetNurbsProperty mgluGetNurbsProperty
+#define gluBeginCurve mgluBeginCurve
+#define gluEndCurve mgluEndCurve
+#define gluNurbsCurve mgluNurbsCurve
+#define gluBeginSurface mgluBeginSurface
+#define gluEndSurface mgluEndSurface
+#define gluNurbsSurface mgluNurbsSurface
+#define gluBeginTrim mgluBeginTrim
+#define gluEndTrim mgluEndTrim
+#define gluPwlCurve mgluPwlCurve
+#define gluNurbsCallback mgluNurbsCallback
+#define gluNewTess mgluNewTess
+#define gluTessCallback mgluTessCallback
+#define gluDeleteTess mgluDeleteTess
+#define gluBeginPolygon mgluBeginPolygon
+#define gluEndPolygon mgluEndPolygon
+#define gluNextContour mgluNextContour
+#define gluTessVertex mgluTessVertex
+#define gluGetString mgluGetString
+
+#endif
diff --git a/include/GL/glut.h b/include/GL/glut.h
new file mode 100644 (file)
index 0000000..1b7fc43
--- /dev/null
@@ -0,0 +1,751 @@
+#ifndef __glut_h__
+#define __glut_h__
+
+/* Copyright (c) Mark J. Kilgard, 1994, 1995, 1996, 1998. */
+
+/* This program is freely distributable without licensing fees  and is
+   provided without guarantee or warrantee expressed or  implied. This
+   program is -not- in the public domain. */
+
+#include <GL/gl.h>
+#include <GL/glu.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(_WIN32)
+
+/* GLUT 3.7 now tries to avoid including <windows.h>
+   to avoid name space pollution, but Win32's <GL/gl.h>
+   needs APIENTRY and WINGDIAPI defined properly.
+
+   tjump@spgs.com contributes:
+   If users are building glut code on MS Windows, then they should
+   make sure they include windows.h early, let's not get into a
+   header definitions war since MS has proven it's capability to
+   change header dependencies w/o publishing they have done so.
+
+   So, let's not include windows.h here, as it's not really required and
+   MS own gl/gl.h *should* include it if the dependency is there. */
+
+/* To disable automatic library usage for GLUT, define GLUT_NO_LIB_PRAGMA
+   in your compile preprocessor options. */
+# if !defined(GLUT_BUILDING_LIB) && !defined(GLUT_NO_LIB_PRAGMA)
+#  pragma comment (lib, "winmm.lib")      /* link with Windows MultiMedia lib */
+/* To enable automatic SGI OpenGL for Windows library usage for GLUT,
+   define GLUT_USE_SGI_OPENGL in your compile preprocessor options.  */
+#  ifdef GLUT_USE_SGI_OPENGL
+#   pragma comment (lib, "opengl.lib")    /* link with SGI OpenGL for Windows lib */
+#   pragma comment (lib, "glu.lib")       /* link with SGI OpenGL Utility lib */
+#   pragma comment (lib, "glut.lib")      /* link with Win32 GLUT for SGI OpenGL lib */
+#  else
+#   pragma comment (lib, "opengl32.lib")  /* link with Microsoft OpenGL lib */
+#   pragma comment (lib, "glu32.lib")     /* link with Microsoft OpenGL Utility lib */
+#   pragma comment (lib, "glut32.lib")    /* link with Win32 GLUT lib */
+#  endif
+# endif
+
+/* To disable supression of annoying warnings about floats being promoted
+   to doubles, define GLUT_NO_WARNING_DISABLE in your compile preprocessor
+   options. */
+# ifndef GLUT_NO_WARNING_DISABLE
+#  pragma warning (disable:4244)  /* Disable bogus VC++ 4.2 conversion warnings. */
+#  pragma warning (disable:4305)  /* VC++ 5.0 version of above warning. */
+# endif
+
+/* Win32 has an annoying issue where there are multiple C run-time
+   libraries (CRTs).  If the executable is linked with a different CRT
+   from the GLUT DLL, the GLUT DLL will not share the same CRT static
+   data seen by the executable.  In particular, atexit callbacks registered
+   in the executable will not be called if GLUT calls its (different)
+   exit routine).  GLUT is typically built with the
+   "/MD" option (the CRT with multithreading DLL support), but the Visual
+   C++ linker default is "/ML" (the single threaded CRT).
+
+   One workaround to this issue is requiring users to always link with
+   the same CRT as GLUT is compiled with.  That requires users supply a
+   non-standard option.  GLUT 3.7 has its own built-in workaround where
+   the executable's "exit" function pointer is covertly passed to GLUT.
+   GLUT then calls the executable's exit function pointer to ensure that
+   any "atexit" calls registered by the application are called if GLUT
+   needs to exit.
+
+   Note that the __glut*WithExit routines should NEVER be called directly.
+   To avoid the atexit workaround, #define GLUT_DISABLE_ATEXIT_HACK. */
+
+/* XXX This is from Win32's <process.h> */
+# if !defined(_MSC_VER) && !defined(__cdecl)
+   /* Define __cdecl for non-Microsoft compilers. */
+#  define __cdecl
+#  define GLUT_DEFINED___CDECL
+# endif
+# ifndef _CRTIMP
+#  ifdef _NTSDK
+    /* Definition compatible with NT SDK */
+#   define _CRTIMP
+#  else
+    /* Current definition */
+#   ifdef _DLL
+#    define _CRTIMP __declspec(dllimport)
+#   else
+#    define _CRTIMP
+#   endif
+#  endif
+#  define GLUT_DEFINED__CRTIMP
+# endif
+# ifndef GLUT_BUILDING_LIB
+extern _CRTIMP void __cdecl exit(int);
+# endif
+
+/* GLUT callback calling convention for Win32. */
+# define GLUTCALLBACK __cdecl
+
+/* for callback/function pointer defs */
+# define GLUTAPIENTRYV __cdecl
+
+/* glut-win32 specific macros, defined to prevent collision with
+   and redifinition of Windows system defs, also removes requirement of
+   pretty much any standard windows header from this file */
+
+#if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED)
+#      define GLUTAPIENTRY __stdcall
+#else
+#      define GLUTAPIENTRY
+#endif
+
+/* GLUT API entry point declarations for Win32. */
+#if defined(GLUT_BUILDING_LIB) && defined(_DLL)
+#      define GLUTAPI __declspec(dllexport)
+#elif defined(_DLL)
+#   define GLUTAPI __declspec(dllimport)
+#else
+#      define GLUTAPI extern
+#endif
+
+#if defined(_WIN32) && !defined(_WINDEF_) && !defined(MESA)
+#      if !defined(MESA_MINWARN)
+#              pragma message( "note: WINDOWS.H not included, providing Mesa definition of CALLBACK macro" )
+#              pragma message( "----: and PROC typedef. If you receive compiler warnings about either ")
+#              pragma message( "----: being multiply defined you should include WINDOWS.H priot to gl/glut.h" )
+#      endif
+#      define CALLBACK __stdcall
+typedef int (GLUTAPIENTRY *PROC)();
+typedef void *HGLRC;
+typedef void *HDC;
+typedef unsigned long COLORREF;
+#endif
+
+#if defined(_WIN32) && !defined(_WINGDI_) && !defined(MESA)
+#      if !defined(MESA_MINWARN)
+#              pragma message( "note: WINDOWS.H not included, providing Mesa definition of wgl functions" )
+#              pragma message( "----: and macros. If you receive compiler warnings about any being multiply ")
+#              pragma message( "----: defined you should include WINDOWS.H priot to gl/glut.h" )
+#      endif
+#      define WGL_FONT_LINES      0
+#      define WGL_FONT_POLYGONS   1
+#      ifdef UNICODE
+#              define wglUseFontBitmaps  wglUseFontBitmapsW
+#              define wglUseFontOutlines  wglUseFontOutlinesW
+#      else
+#              define wglUseFontBitmaps  wglUseFontBitmapsA
+#              define wglUseFontOutlines  wglUseFontOutlinesA
+#      endif /* !UNICODE */
+typedef struct tagLAYERPLANEDESCRIPTOR LAYERPLANEDESCRIPTOR, *PLAYERPLANEDESCRIPTOR, *LPLAYERPLANEDESCRIPTOR;
+typedef struct _GLYPHMETRICSFLOAT GLYPHMETRICSFLOAT, *PGLYPHMETRICSFLOAT, *LPGLYPHMETRICSFLOAT;
+GLUTAPI int   GLUTAPIENTRY wglCopyContext(HGLRC, HGLRC, unsigned int);
+GLUTAPI HGLRC GLUTAPIENTRY wglCreateContext(HDC);
+GLUTAPI HGLRC GLUTAPIENTRY wglCreateLayerContext(HDC, int);
+GLUTAPI int   GLUTAPIENTRY wglDeleteContext(HGLRC);
+GLUTAPI HGLRC GLUTAPIENTRY wglGetCurrentContext(void);
+GLUTAPI HDC   GLUTAPIENTRY wglGetCurrentDC(void);
+GLUTAPI PROC  GLUTAPIENTRY wglGetProcAddress(char*);
+GLUTAPI int   GLUTAPIENTRY wglMakeCurrent(HDC, HGLRC);
+GLUTAPI int   GLUTAPIENTRY wglShareLists(HGLRC, HGLRC);
+GLUTAPI int   GLUTAPIENTRY wglUseFontBitmapsA(HDC, unsigned long, unsigned long, unsigned long);
+GLUTAPI int   GLUTAPIENTRY wglUseFontBitmapsW(HDC, unsigned long, unsigned long, unsigned long);
+GLUTAPI int   GLUTAPIENTRY wglUseFontOutlinesA(HDC, unsigned long, unsigned long, unsigned long, float,float, int, LPGLYPHMETRICSFLOAT);
+GLUTAPI int   GLUTAPIENTRY wglUseFontOutlinesW(HDC, unsigned long, unsigned long, unsigned long, float,float, int, LPGLYPHMETRICSFLOAT);
+GLUTAPI int   GLUTAPIENTRY wglDescribeLayerPlane(HDC, int, int, unsigned int,LPLAYERPLANEDESCRIPTOR);
+GLUTAPI int   GLUTAPIENTRY wglSetLayerPaletteEntries(HDC, int, int, int,const COLORREF *);
+GLUTAPI int   GLUTAPIENTRY wglGetLayerPaletteEntries(HDC, int, int, int,COLORREF *);
+GLUTAPI int   GLUTAPIENTRY wglRealizeLayerPalette(HDC, int, int);
+GLUTAPI int   GLUTAPIENTRY wglSwapLayerBuffers(HDC, unsigned int);
+GLUTAPI int   GLUTAPIENTRY SwapBuffers(HDC);
+#endif
+
+#else /* _WIN32 not defined */
+
+/* Define GLUTAPIENTRY and GLUTCALLBACK to nothing if we aren't on Win32. */
+#  define GLUTAPIENTRY
+#  define GLUTAPIENTRYV
+#  define GLUT_APIENTRY_DEFINED
+#  define GLUTCALLBACK
+#  define GLUTAPI extern
+/* Prototype exit for the non-Win32 case (see above). */
+extern void exit(int);
+#endif
+
+
+/**
+ GLUT API revision history:
+
+ GLUT_API_VERSION is updated to reflect incompatible GLUT
+ API changes (interface changes, semantic changes, deletions,
+ or additions).
+
+ GLUT_API_VERSION=1  First public release of GLUT.  11/29/94
+
+ GLUT_API_VERSION=2  Added support for OpenGL/GLX multisampling,
+ extension.  Supports new input devices like tablet, dial and button
+ box, and Spaceball.  Easy to query OpenGL extensions.
+
+ GLUT_API_VERSION=3  glutMenuStatus added.
+
+ GLUT_API_VERSION=4  glutInitDisplayString, glutWarpPointer,
+ glutBitmapLength, glutStrokeLength, glutWindowStatusFunc, dynamic
+ video resize subAPI, glutPostWindowRedisplay, glutKeyboardUpFunc,
+ glutSpecialUpFunc, glutIgnoreKeyRepeat, glutSetKeyRepeat,
+ glutJoystickFunc, glutForceJoystickFunc (NOT FINALIZED!).
+**/
+#ifndef GLUT_API_VERSION  /* allow this to be overriden */
+#define GLUT_API_VERSION               3
+#endif
+
+/**
+ GLUT implementation revision history:
+
+ GLUT_XLIB_IMPLEMENTATION is updated to reflect both GLUT
+ API revisions and implementation revisions (ie, bug fixes).
+
+ GLUT_XLIB_IMPLEMENTATION=1  mjk's first public release of
+ GLUT Xlib-based implementation.  11/29/94
+
+ GLUT_XLIB_IMPLEMENTATION=2  mjk's second public release of
+ GLUT Xlib-based implementation providing GLUT version 2
+ interfaces.
+
+ GLUT_XLIB_IMPLEMENTATION=3  mjk's GLUT 2.2 images. 4/17/95
+
+ GLUT_XLIB_IMPLEMENTATION=4  mjk's GLUT 2.3 images. 6/?/95
+
+ GLUT_XLIB_IMPLEMENTATION=5  mjk's GLUT 3.0 images. 10/?/95
+
+ GLUT_XLIB_IMPLEMENTATION=7  mjk's GLUT 3.1+ with glutWarpPoitner.  7/24/96
+
+ GLUT_XLIB_IMPLEMENTATION=8  mjk's GLUT 3.1+ with glutWarpPoitner
+ and video resize.  1/3/97
+
+ GLUT_XLIB_IMPLEMENTATION=9 mjk's GLUT 3.4 release with early GLUT 4 routines.
+
+ GLUT_XLIB_IMPLEMENTATION=11 Mesa 2.5's GLUT 3.6 release.
+
+ GLUT_XLIB_IMPLEMENTATION=12 mjk's GLUT 3.6 release with early GLUT 4 routines + signal handling.
+
+ GLUT_XLIB_IMPLEMENTATION=13 mjk's GLUT 3.7 beta with GameGLUT support.
+
+ GLUT_XLIB_IMPLEMENTATION=14 mjk's GLUT 3.7 beta with f90gl friend interface.
+
+ GLUT_XLIB_IMPLEMENTATION=15 mjk's GLUT 3.7 beta sync'ed with Mesa <GL/glut.h>
+**/
+#ifndef GLUT_XLIB_IMPLEMENTATION  /* Allow this to be overriden. */
+#define GLUT_XLIB_IMPLEMENTATION       15
+#endif
+
+/* Display mode bit masks. */
+#define GLUT_RGB                       0
+#define GLUT_RGBA                      GLUT_RGB
+#define GLUT_INDEX                     1
+#define GLUT_SINGLE                    0
+#define GLUT_DOUBLE                    2
+#define GLUT_ACCUM                     4
+#define GLUT_ALPHA                     8
+#define GLUT_DEPTH                     16
+#define GLUT_STENCIL                   32
+#if (GLUT_API_VERSION >= 2)
+#define GLUT_MULTISAMPLE               128
+#define GLUT_STEREO                    256
+#endif
+#if (GLUT_API_VERSION >= 3)
+#define GLUT_LUMINANCE                 512
+#endif
+
+/* Mouse buttons. */
+#define GLUT_LEFT_BUTTON               0
+#define GLUT_MIDDLE_BUTTON             1
+#define GLUT_RIGHT_BUTTON              2
+
+/* Mouse button  state. */
+#define GLUT_DOWN                      0
+#define GLUT_UP                                1
+
+#if (GLUT_API_VERSION >= 2)
+/* function keys */
+#define GLUT_KEY_F1                    1
+#define GLUT_KEY_F2                    2
+#define GLUT_KEY_F3                    3
+#define GLUT_KEY_F4                    4
+#define GLUT_KEY_F5                    5
+#define GLUT_KEY_F6                    6
+#define GLUT_KEY_F7                    7
+#define GLUT_KEY_F8                    8
+#define GLUT_KEY_F9                    9
+#define GLUT_KEY_F10                   10
+#define GLUT_KEY_F11                   11
+#define GLUT_KEY_F12                   12
+/* directional keys */
+#define GLUT_KEY_LEFT                  100
+#define GLUT_KEY_UP                    101
+#define GLUT_KEY_RIGHT                 102
+#define GLUT_KEY_DOWN                  103
+#define GLUT_KEY_PAGE_UP               104
+#define GLUT_KEY_PAGE_DOWN             105
+#define GLUT_KEY_HOME                  106
+#define GLUT_KEY_END                   107
+#define GLUT_KEY_INSERT                        108
+#endif
+
+/* Entry/exit  state. */
+#define GLUT_LEFT                      0
+#define GLUT_ENTERED                   1
+
+/* Menu usage  state. */
+#define GLUT_MENU_NOT_IN_USE           0
+#define GLUT_MENU_IN_USE               1
+
+/* Visibility  state. */
+#define GLUT_NOT_VISIBLE               0
+#define GLUT_VISIBLE                   1
+
+/* Window status  state. */
+#define GLUT_HIDDEN                    0
+#define GLUT_FULLY_RETAINED            1
+#define GLUT_PARTIALLY_RETAINED                2
+#define GLUT_FULLY_COVERED             3
+
+/* Color index component selection values. */
+#define GLUT_RED                       0
+#define GLUT_GREEN                     1
+#define GLUT_BLUE                      2
+
+/* Layers for use. */
+#define GLUT_NORMAL                    0
+#define GLUT_OVERLAY                   1
+
+#if defined(_WIN32)
+/* Stroke font constants (use these in GLUT program). */
+#define GLUT_STROKE_ROMAN              ((void*)0)
+#define GLUT_STROKE_MONO_ROMAN         ((void*)1)
+
+/* Bitmap font constants (use these in GLUT program). */
+#define GLUT_BITMAP_9_BY_15            ((void*)2)
+#define GLUT_BITMAP_8_BY_13            ((void*)3)
+#define GLUT_BITMAP_TIMES_ROMAN_10     ((void*)4)
+#define GLUT_BITMAP_TIMES_ROMAN_24     ((void*)5)
+#if (GLUT_API_VERSION >= 3)
+#define GLUT_BITMAP_HELVETICA_10       ((void*)6)
+#define GLUT_BITMAP_HELVETICA_12       ((void*)7)
+#define GLUT_BITMAP_HELVETICA_18       ((void*)8)
+#endif
+#else
+/* Stroke font opaque addresses (use constants instead in source code). */
+GLUTAPI void *glutStrokeRoman;
+GLUTAPI void *glutStrokeMonoRoman;
+
+/* Stroke font constants (use these in GLUT program). */
+#define GLUT_STROKE_ROMAN              (&glutStrokeRoman)
+#define GLUT_STROKE_MONO_ROMAN         (&glutStrokeMonoRoman)
+
+/* Bitmap font opaque addresses (use constants instead in source code). */
+GLUTAPI void *glutBitmap9By15;
+GLUTAPI void *glutBitmap8By13;
+GLUTAPI void *glutBitmapTimesRoman10;
+GLUTAPI void *glutBitmapTimesRoman24;
+GLUTAPI void *glutBitmapHelvetica10;
+GLUTAPI void *glutBitmapHelvetica12;
+GLUTAPI void *glutBitmapHelvetica18;
+
+/* Bitmap font constants (use these in GLUT program). */
+#define GLUT_BITMAP_9_BY_15            (&glutBitmap9By15)
+#define GLUT_BITMAP_8_BY_13            (&glutBitmap8By13)
+#define GLUT_BITMAP_TIMES_ROMAN_10     (&glutBitmapTimesRoman10)
+#define GLUT_BITMAP_TIMES_ROMAN_24     (&glutBitmapTimesRoman24)
+#if (GLUT_API_VERSION >= 3)
+#define GLUT_BITMAP_HELVETICA_10       (&glutBitmapHelvetica10)
+#define GLUT_BITMAP_HELVETICA_12       (&glutBitmapHelvetica12)
+#define GLUT_BITMAP_HELVETICA_18       (&glutBitmapHelvetica18)
+#endif
+#endif
+
+/* glutGet parameters. */
+#define GLUT_WINDOW_X                  100
+#define GLUT_WINDOW_Y                  101
+#define GLUT_WINDOW_WIDTH              102
+#define GLUT_WINDOW_HEIGHT             103
+#define GLUT_WINDOW_BUFFER_SIZE                104
+#define GLUT_WINDOW_STENCIL_SIZE       105
+#define GLUT_WINDOW_DEPTH_SIZE         106
+#define GLUT_WINDOW_RED_SIZE           107
+#define GLUT_WINDOW_GREEN_SIZE         108
+#define GLUT_WINDOW_BLUE_SIZE          109
+#define GLUT_WINDOW_ALPHA_SIZE         110
+#define GLUT_WINDOW_ACCUM_RED_SIZE     111
+#define GLUT_WINDOW_ACCUM_GREEN_SIZE   112
+#define GLUT_WINDOW_ACCUM_BLUE_SIZE    113
+#define GLUT_WINDOW_ACCUM_ALPHA_SIZE   114
+#define GLUT_WINDOW_DOUBLEBUFFER       115
+#define GLUT_WINDOW_RGBA               116
+#define GLUT_WINDOW_PARENT             117
+#define GLUT_WINDOW_NUM_CHILDREN       118
+#define GLUT_WINDOW_COLORMAP_SIZE      119
+#if (GLUT_API_VERSION >= 2)
+#define GLUT_WINDOW_NUM_SAMPLES                120
+#define GLUT_WINDOW_STEREO             121
+#endif
+#if (GLUT_API_VERSION >= 3)
+#define GLUT_WINDOW_CURSOR             122
+#endif
+#define GLUT_SCREEN_WIDTH              200
+#define GLUT_SCREEN_HEIGHT             201
+#define GLUT_SCREEN_WIDTH_MM           202
+#define GLUT_SCREEN_HEIGHT_MM          203
+#define GLUT_MENU_NUM_ITEMS            300
+#define GLUT_DISPLAY_MODE_POSSIBLE     400
+#define GLUT_INIT_WINDOW_X             500
+#define GLUT_INIT_WINDOW_Y             501
+#define GLUT_INIT_WINDOW_WIDTH         502
+#define GLUT_INIT_WINDOW_HEIGHT                503
+#define GLUT_INIT_DISPLAY_MODE         504
+#if (GLUT_API_VERSION >= 2)
+#define GLUT_ELAPSED_TIME              700
+#endif
+#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13)
+#define GLUT_WINDOW_FORMAT_ID          123
+#endif
+
+#if (GLUT_API_VERSION >= 2)
+/* glutDeviceGet parameters. */
+#define GLUT_HAS_KEYBOARD              600
+#define GLUT_HAS_MOUSE                 601
+#define GLUT_HAS_SPACEBALL             602
+#define GLUT_HAS_DIAL_AND_BUTTON_BOX   603
+#define GLUT_HAS_TABLET                        604
+#define GLUT_NUM_MOUSE_BUTTONS         605
+#define GLUT_NUM_SPACEBALL_BUTTONS     606
+#define GLUT_NUM_BUTTON_BOX_BUTTONS    607
+#define GLUT_NUM_DIALS                 608
+#define GLUT_NUM_TABLET_BUTTONS                609
+#endif
+#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13)
+#define GLUT_DEVICE_IGNORE_KEY_REPEAT   610
+#define GLUT_DEVICE_KEY_REPEAT          611
+#define GLUT_HAS_JOYSTICK              612
+#define GLUT_OWNS_JOYSTICK             613
+#define GLUT_JOYSTICK_BUTTONS          614
+#define GLUT_JOYSTICK_AXES             615
+#define GLUT_JOYSTICK_POLL_RATE                616
+#endif
+
+#if (GLUT_API_VERSION >= 3)
+/* glutLayerGet parameters. */
+#define GLUT_OVERLAY_POSSIBLE           800
+#define GLUT_LAYER_IN_USE              801
+#define GLUT_HAS_OVERLAY               802
+#define GLUT_TRANSPARENT_INDEX         803
+#define GLUT_NORMAL_DAMAGED            804
+#define GLUT_OVERLAY_DAMAGED           805
+
+#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9)
+/* glutVideoResizeGet parameters. */
+#define GLUT_VIDEO_RESIZE_POSSIBLE     900
+#define GLUT_VIDEO_RESIZE_IN_USE       901
+#define GLUT_VIDEO_RESIZE_X_DELTA      902
+#define GLUT_VIDEO_RESIZE_Y_DELTA      903
+#define GLUT_VIDEO_RESIZE_WIDTH_DELTA  904
+#define GLUT_VIDEO_RESIZE_HEIGHT_DELTA 905
+#define GLUT_VIDEO_RESIZE_X            906
+#define GLUT_VIDEO_RESIZE_Y            907
+#define GLUT_VIDEO_RESIZE_WIDTH                908
+#define GLUT_VIDEO_RESIZE_HEIGHT       909
+#endif
+
+/* glutUseLayer parameters. */
+#define GLUT_NORMAL                    0
+#define GLUT_OVERLAY                   1
+
+/* glutGetModifiers return mask. */
+#define GLUT_ACTIVE_SHIFT               1
+#define GLUT_ACTIVE_CTRL                2
+#define GLUT_ACTIVE_ALT                 4
+
+/* glutSetCursor parameters. */
+/* Basic arrows. */
+#define GLUT_CURSOR_RIGHT_ARROW                0
+#define GLUT_CURSOR_LEFT_ARROW         1
+/* Symbolic cursor shapes. */
+#define GLUT_CURSOR_INFO               2
+#define GLUT_CURSOR_DESTROY            3
+#define GLUT_CURSOR_HELP               4
+#define GLUT_CURSOR_CYCLE              5
+#define GLUT_CURSOR_SPRAY              6
+#define GLUT_CURSOR_WAIT               7
+#define GLUT_CURSOR_TEXT               8
+#define GLUT_CURSOR_CROSSHAIR          9
+/* Directional cursors. */
+#define GLUT_CURSOR_UP_DOWN            10
+#define GLUT_CURSOR_LEFT_RIGHT         11
+/* Sizing cursors. */
+#define GLUT_CURSOR_TOP_SIDE           12
+#define GLUT_CURSOR_BOTTOM_SIDE                13
+#define GLUT_CURSOR_LEFT_SIDE          14
+#define GLUT_CURSOR_RIGHT_SIDE         15
+#define GLUT_CURSOR_TOP_LEFT_CORNER    16
+#define GLUT_CURSOR_TOP_RIGHT_CORNER   17
+#define GLUT_CURSOR_BOTTOM_RIGHT_CORNER        18
+#define GLUT_CURSOR_BOTTOM_LEFT_CORNER 19
+/* Inherit from parent window. */
+#define GLUT_CURSOR_INHERIT            100
+/* Blank cursor. */
+#define GLUT_CURSOR_NONE               101
+/* Fullscreen crosshair (if available). */
+#define GLUT_CURSOR_FULL_CROSSHAIR     102
+#endif
+
+/* GLUT initialization sub-API. */
+GLUTAPI void GLUTAPIENTRY glutInit(int *argcp, char **argv);
+#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK)
+GLUTAPI void GLUTAPIENTRY __glutInitWithExit(int *argcp, char **argv, void (__cdecl *exitfunc)(int));
+#ifndef GLUT_BUILDING_LIB
+static void GLUTAPIENTRY glutInit_ATEXIT_HACK(int *argcp, char **argv) { __glutInitWithExit(argcp, argv, exit); }
+#define glutInit glutInit_ATEXIT_HACK
+#endif
+#endif
+GLUTAPI void GLUTAPIENTRY glutInitDisplayMode(unsigned int mode);
+#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9)
+GLUTAPI void GLUTAPIENTRY glutInitDisplayString(const char *string);
+#endif
+GLUTAPI void GLUTAPIENTRY glutInitWindowPosition(int x, int y);
+GLUTAPI void GLUTAPIENTRY glutInitWindowSize(int width, int height);
+GLUTAPI void GLUTAPIENTRY glutMainLoop(void);
+
+/* GLUT window sub-API. */
+GLUTAPI int GLUTAPIENTRY glutCreateWindow(const char *title);
+#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK)
+GLUTAPI int GLUTAPIENTRY __glutCreateWindowWithExit(const char *title, void (__cdecl *exitfunc)(int));
+#ifndef GLUT_BUILDING_LIB
+static int GLUTAPIENTRY glutCreateWindow_ATEXIT_HACK(const char *title) { return __glutCreateWindowWithExit(title, exit); }
+#define glutCreateWindow glutCreateWindow_ATEXIT_HACK
+#endif
+#endif
+GLUTAPI int GLUTAPIENTRY glutCreateSubWindow(int win, int x, int y, int width, int height);
+GLUTAPI void GLUTAPIENTRY glutDestroyWindow(int win);
+GLUTAPI void GLUTAPIENTRY glutPostRedisplay(void);
+#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 11)
+GLUTAPI void GLUTAPIENTRY glutPostWindowRedisplay(int win);
+#endif
+GLUTAPI void GLUTAPIENTRY glutSwapBuffers(void);
+GLUTAPI int GLUTAPIENTRY glutGetWindow(void);
+GLUTAPI void GLUTAPIENTRY glutSetWindow(int win);
+GLUTAPI void GLUTAPIENTRY glutSetWindowTitle(const char *title);
+GLUTAPI void GLUTAPIENTRY glutSetIconTitle(const char *title);
+GLUTAPI void GLUTAPIENTRY glutPositionWindow(int x, int y);
+GLUTAPI void GLUTAPIENTRY glutReshapeWindow(int width, int height);
+GLUTAPI void GLUTAPIENTRY glutPopWindow(void);
+GLUTAPI void GLUTAPIENTRY glutPushWindow(void);
+GLUTAPI void GLUTAPIENTRY glutIconifyWindow(void);
+GLUTAPI void GLUTAPIENTRY glutShowWindow(void);
+GLUTAPI void GLUTAPIENTRY glutHideWindow(void);
+#if (GLUT_API_VERSION >= 3)
+GLUTAPI void GLUTAPIENTRY glutFullScreen(void);
+GLUTAPI void GLUTAPIENTRY glutSetCursor(int cursor);
+#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9)
+GLUTAPI void GLUTAPIENTRY glutWarpPointer(int x, int y);
+#endif
+
+/* GLUT overlay sub-API. */
+GLUTAPI void GLUTAPIENTRY glutEstablishOverlay(void);
+GLUTAPI void GLUTAPIENTRY glutRemoveOverlay(void);
+GLUTAPI void GLUTAPIENTRY glutUseLayer(GLenum layer);
+GLUTAPI void GLUTAPIENTRY glutPostOverlayRedisplay(void);
+#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 11)
+GLUTAPI void GLUTAPIENTRY glutPostWindowOverlayRedisplay(int win);
+#endif
+GLUTAPI void GLUTAPIENTRY glutShowOverlay(void);
+GLUTAPI void GLUTAPIENTRY glutHideOverlay(void);
+#endif
+
+/* GLUT menu sub-API. */
+GLUTAPI int GLUTAPIENTRY glutCreateMenu(void (GLUTCALLBACK *func)(int));
+#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK)
+GLUTAPI int GLUTAPIENTRY __glutCreateMenuWithExit(void (GLUTCALLBACK *func)(int), void (__cdecl *exitfunc)(int));
+#ifndef GLUT_BUILDING_LIB
+static int GLUTAPIENTRY glutCreateMenu_ATEXIT_HACK(void (GLUTCALLBACK *func)(int)) { return __glutCreateMenuWithExit(func, exit); }
+#define glutCreateMenu glutCreateMenu_ATEXIT_HACK
+#endif
+#endif
+GLUTAPI void GLUTAPIENTRY glutDestroyMenu(int menu);
+GLUTAPI int GLUTAPIENTRY glutGetMenu(void);
+GLUTAPI void GLUTAPIENTRY glutSetMenu(int menu);
+GLUTAPI void GLUTAPIENTRY glutAddMenuEntry(const char *label, int value);
+GLUTAPI void GLUTAPIENTRY glutAddSubMenu(const char *label, int submenu);
+GLUTAPI void GLUTAPIENTRY glutChangeToMenuEntry(int item, const char *label, int value);
+GLUTAPI void GLUTAPIENTRY glutChangeToSubMenu(int item, const char *label, int submenu);
+GLUTAPI void GLUTAPIENTRY glutRemoveMenuItem(int item);
+GLUTAPI void GLUTAPIENTRY glutAttachMenu(int button);
+GLUTAPI void GLUTAPIENTRY glutDetachMenu(int button);
+
+/* GLUT window callback sub-API. */
+GLUTAPI void GLUTAPIENTRY glutDisplayFunc(void (GLUTCALLBACK *func)(void));
+GLUTAPI void GLUTAPIENTRY glutReshapeFunc(void (GLUTCALLBACK *func)(int width, int height));
+GLUTAPI void GLUTAPIENTRY glutKeyboardFunc(void (GLUTCALLBACK *func)(unsigned char key, int x, int y));
+GLUTAPI void GLUTAPIENTRY glutMouseFunc(void (GLUTCALLBACK *func)(int button, int state, int x, int y));
+GLUTAPI void GLUTAPIENTRY glutMotionFunc(void (GLUTCALLBACK *func)(int x, int y));
+GLUTAPI void GLUTAPIENTRY glutPassiveMotionFunc(void (GLUTCALLBACK *func)(int x, int y));
+GLUTAPI void GLUTAPIENTRY glutEntryFunc(void (GLUTCALLBACK *func)(int state));
+GLUTAPI void GLUTAPIENTRY glutVisibilityFunc(void (GLUTCALLBACK *func)(int state));
+GLUTAPI void GLUTAPIENTRY glutIdleFunc(void (GLUTCALLBACK *func)(void));
+GLUTAPI void GLUTAPIENTRY glutTimerFunc(unsigned int millis, void (GLUTCALLBACK *func)(int value), int value);
+GLUTAPI void GLUTAPIENTRY glutMenuStateFunc(void (GLUTCALLBACK *func)(int state));
+#if (GLUT_API_VERSION >= 2)
+GLUTAPI void GLUTAPIENTRY glutSpecialFunc(void (GLUTCALLBACK *func)(int key, int x, int y));
+GLUTAPI void GLUTAPIENTRY glutSpaceballMotionFunc(void (GLUTCALLBACK *func)(int x, int y, int z));
+GLUTAPI void GLUTAPIENTRY glutSpaceballRotateFunc(void (GLUTCALLBACK *func)(int x, int y, int z));
+GLUTAPI void GLUTAPIENTRY glutSpaceballButtonFunc(void (GLUTCALLBACK *func)(int button, int state));
+GLUTAPI void GLUTAPIENTRY glutButtonBoxFunc(void (GLUTCALLBACK *func)(int button, int state));
+GLUTAPI void GLUTAPIENTRY glutDialsFunc(void (GLUTCALLBACK *func)(int dial, int value));
+GLUTAPI void GLUTAPIENTRY glutTabletMotionFunc(void (GLUTCALLBACK *func)(int x, int y));
+GLUTAPI void GLUTAPIENTRY glutTabletButtonFunc(void (GLUTCALLBACK *func)(int button, int state, int x, int y));
+#if (GLUT_API_VERSION >= 3)
+GLUTAPI void GLUTAPIENTRY glutMenuStatusFunc(void (GLUTCALLBACK *func)(int status, int x, int y));
+GLUTAPI void GLUTAPIENTRY glutOverlayDisplayFunc(void (GLUTCALLBACK *func)(void));
+#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9)
+GLUTAPI void GLUTAPIENTRY glutWindowStatusFunc(void (GLUTCALLBACK *func)(int state));
+#endif
+#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13)
+GLUTAPI void GLUTAPIENTRY glutKeyboardUpFunc(void (GLUTCALLBACK *func)(unsigned char key, int x, int y));
+GLUTAPI void GLUTAPIENTRY glutSpecialUpFunc(void (GLUTCALLBACK *func)(int key, int x, int y));
+GLUTAPI void GLUTAPIENTRY glutJoystickFunc(void (GLUTCALLBACK *func)(unsigned int buttonMask, int x, int y, int z), int pollInterval);
+#endif
+#endif
+#endif
+
+/* GLUT color index sub-API. */
+GLUTAPI void GLUTAPIENTRY glutSetColor(int, GLfloat red, GLfloat green, GLfloat blue);
+GLUTAPI GLfloat GLUTAPIENTRY glutGetColor(int ndx, int component);
+GLUTAPI void GLUTAPIENTRY glutCopyColormap(int win);
+
+/* GLUT state retrieval sub-API. */
+GLUTAPI int GLUTAPIENTRY glutGet(GLenum type);
+GLUTAPI int GLUTAPIENTRY glutDeviceGet(GLenum type);
+#if (GLUT_API_VERSION >= 2)
+/* GLUT extension support sub-API */
+GLUTAPI int GLUTAPIENTRY glutExtensionSupported(const char *name);
+#endif
+#if (GLUT_API_VERSION >= 3)
+GLUTAPI int GLUTAPIENTRY glutGetModifiers(void);
+GLUTAPI int GLUTAPIENTRY glutLayerGet(GLenum type);
+#endif
+
+/* GLUT font sub-API */
+GLUTAPI void GLUTAPIENTRY glutBitmapCharacter(void *font, int character);
+GLUTAPI int GLUTAPIENTRY glutBitmapWidth(void *font, int character);
+GLUTAPI void GLUTAPIENTRY glutStrokeCharacter(void *font, int character);
+GLUTAPI int GLUTAPIENTRY glutStrokeWidth(void *font, int character);
+#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9)
+GLUTAPI int GLUTAPIENTRY glutBitmapLength(void *font, const unsigned char *string);
+GLUTAPI int GLUTAPIENTRY glutStrokeLength(void *font, const unsigned char *string);
+#endif
+
+/* GLUT pre-built models sub-API */
+GLUTAPI void GLUTAPIENTRY glutWireSphere(GLdouble radius, GLint slices, GLint stacks);
+GLUTAPI void GLUTAPIENTRY glutSolidSphere(GLdouble radius, GLint slices, GLint stacks);
+GLUTAPI void GLUTAPIENTRY glutWireCone(GLdouble base, GLdouble height, GLint slices, GLint stacks);
+GLUTAPI void GLUTAPIENTRY glutSolidCone(GLdouble base, GLdouble height, GLint slices, GLint stacks);
+GLUTAPI void GLUTAPIENTRY glutWireCube(GLdouble size);
+GLUTAPI void GLUTAPIENTRY glutSolidCube(GLdouble size);
+GLUTAPI void GLUTAPIENTRY glutWireTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings);
+GLUTAPI void GLUTAPIENTRY glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings);
+GLUTAPI void GLUTAPIENTRY glutWireDodecahedron(void);
+GLUTAPI void GLUTAPIENTRY glutSolidDodecahedron(void);
+GLUTAPI void GLUTAPIENTRY glutWireTeapot(GLdouble size);
+GLUTAPI void GLUTAPIENTRY glutSolidTeapot(GLdouble size);
+GLUTAPI void GLUTAPIENTRY glutWireOctahedron(void);
+GLUTAPI void GLUTAPIENTRY glutSolidOctahedron(void);
+GLUTAPI void GLUTAPIENTRY glutWireTetrahedron(void);
+GLUTAPI void GLUTAPIENTRY glutSolidTetrahedron(void);
+GLUTAPI void GLUTAPIENTRY glutWireIcosahedron(void);
+GLUTAPI void GLUTAPIENTRY glutSolidIcosahedron(void);
+
+#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9)
+/* GLUT video resize sub-API. */
+GLUTAPI int GLUTAPIENTRY glutVideoResizeGet(GLenum param);
+GLUTAPI void GLUTAPIENTRY glutSetupVideoResizing(void);
+GLUTAPI void GLUTAPIENTRY glutStopVideoResizing(void);
+GLUTAPI void GLUTAPIENTRY glutVideoResize(int x, int y, int width, int height);
+GLUTAPI void GLUTAPIENTRY glutVideoPan(int x, int y, int width, int height);
+
+/* GLUT debugging sub-API. */
+GLUTAPI void GLUTAPIENTRY glutReportErrors(void);
+#endif
+
+#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13)
+/* GLUT device control sub-API. */
+/* glutSetKeyRepeat modes. */
+#define GLUT_KEY_REPEAT_OFF            0
+#define GLUT_KEY_REPEAT_ON             1
+#define GLUT_KEY_REPEAT_DEFAULT                2
+
+/* Joystick button masks. */
+#define GLUT_JOYSTICK_BUTTON_A         1
+#define GLUT_JOYSTICK_BUTTON_B         2
+#define GLUT_JOYSTICK_BUTTON_C         4
+#define GLUT_JOYSTICK_BUTTON_D         8
+
+GLUTAPI void GLUTAPIENTRY glutIgnoreKeyRepeat(int ignore);
+GLUTAPI void GLUTAPIENTRY glutSetKeyRepeat(int repeatMode);
+GLUTAPI void GLUTAPIENTRY glutForceJoystickFunc(void);
+
+/* GLUT game mode sub-API. */
+/* glutGameModeGet. */
+#define GLUT_GAME_MODE_ACTIVE           0
+#define GLUT_GAME_MODE_POSSIBLE         1
+#define GLUT_GAME_MODE_WIDTH            2
+#define GLUT_GAME_MODE_HEIGHT           3
+#define GLUT_GAME_MODE_PIXEL_DEPTH      4
+#define GLUT_GAME_MODE_REFRESH_RATE     5
+#define GLUT_GAME_MODE_DISPLAY_CHANGED  6
+
+GLUTAPI void GLUTAPIENTRY glutGameModeString(const char *string);
+GLUTAPI int GLUTAPIENTRY glutEnterGameMode(void);
+GLUTAPI void GLUTAPIENTRY glutLeaveGameMode(void);
+GLUTAPI int GLUTAPIENTRY glutGameModeGet(GLenum mode);
+#endif
+
+#ifdef __cplusplus
+}
+
+#endif
+
+#if 0
+#ifdef GLUT_APIENTRY_DEFINED
+# undef GLUT_APIENTRY_DEFINED
+# undef APIENTRY
+#endif
+
+#ifdef GLUT_WINGDIAPI_DEFINED
+# undef GLUT_WINGDIAPI_DEFINED
+# undef WINGDIAPI
+#endif
+
+#ifdef GLUT_DEFINED___CDECL
+# undef GLUT_DEFINED___CDECL
+# undef __cdecl
+#endif
+
+#ifdef GLUT_DEFINED__CRTIMP
+# undef GLUT_DEFINED__CRTIMP
+# undef _CRTIMP
+#endif
+#endif
+
+#endif                  /* __glut_h__ */
diff --git a/include/GL/glut_h.dja b/include/GL/glut_h.dja
new file mode 100644 (file)
index 0000000..d5713f0
--- /dev/null
@@ -0,0 +1,352 @@
+/* $Id*/
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * Copyright (C) 1995-1998  Brian Paul
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/*
+ * $Log: glut_h.dja,v $
+ * Revision 1.1  1999/08/19 00:55:40  jtg
+ * Initial revision
+ *
+ * Revision 1.1  1999/06/23 00:51:27  brianp
+ * initial check-in
+ *
+ */
+
+
+/*
+ * This header file is based on the REAL glut.h by Mark J. Kilgard.
+ *
+ * The DJGPP/ALLEGRO (DJA) GLUT implementation was written by
+ * Bernhard Tschirren (bernie-t@geocities.com) for the sole purpose
+ * of compiling all the sample programs (which use GLUT). Therefore,
+ * is NOT AT ALL a complete version of GLUT!
+ */
+
+
+#ifndef __AGLUT_H__
+#define __AGLUT_H__
+
+#include <GL/gl.h>
+#include <GL/glu.h>
+
+#define GLUTCALLBACK
+#define APIENTRY
+#define GLUTAPI             extern
+
+#define GLUT_RGB                       0
+#define GLUT_RGBA                      GLUT_RGB
+#define GLUT_INDEX                     1
+#define GLUT_SINGLE                    0
+#define GLUT_DOUBLE                    2
+#define GLUT_ACCUM                     4
+#define GLUT_ALPHA                     8
+#define GLUT_DEPTH                     16
+#define GLUT_STENCIL        32
+
+/* Mouse buttons. */
+#define GLUT_LEFT_BUTTON    0
+#define GLUT_MIDDLE_BUTTON  1
+#define GLUT_RIGHT_BUTTON   2
+
+/* Mouse button  state. */
+#define GLUT_DOWN                      0
+#define GLUT_UP                                1
+
+/* function keys */
+#define GLUT_KEY_F1                    1
+#define GLUT_KEY_F2                    2
+#define GLUT_KEY_F3                    3
+#define GLUT_KEY_F4                    4
+#define GLUT_KEY_F5                    5
+#define GLUT_KEY_F6                    6
+#define GLUT_KEY_F7                    7
+#define GLUT_KEY_F8                    8
+#define GLUT_KEY_F9                    9
+#define GLUT_KEY_F10        10
+#define GLUT_KEY_F11        11
+#define GLUT_KEY_F12        12
+
+/* directional keys */
+#define GLUT_KEY_LEFT       100
+#define GLUT_KEY_UP                    101
+#define GLUT_KEY_RIGHT      102
+#define GLUT_KEY_DOWN       103
+#define GLUT_KEY_PAGE_UP    104
+#define GLUT_KEY_PAGE_DOWN  105
+#define GLUT_KEY_HOME       106
+#define GLUT_KEY_END        107
+#define GLUT_KEY_INSERT     108
+
+/* Entry/exit  state. */
+#define GLUT_LEFT                      0
+#define GLUT_ENTERED        1
+
+/* Visibility  state. */
+#define GLUT_NOT_VISIBLE    0
+#define GLUT_VISIBLE        1
+
+/* Color index component selection values. */
+#define GLUT_RED                       0
+#define GLUT_GREEN                     1
+#define GLUT_BLUE                      2
+
+/* Layers for use. */
+#define GLUT_NORMAL                    0
+#define GLUT_OVERLAY        1
+
+/* Stroke font constants (use these in GLUT program). */
+#define GLUT_STROKE_ROMAN           ((void*)0)
+#define GLUT_STROKE_MONO_ROMAN         ((void*)1)
+
+/* Bitmap font constants (use these in GLUT program). */
+#define GLUT_BITMAP_9_BY_15         ((void*)2)
+#define GLUT_BITMAP_8_BY_13         ((void*)3)
+#define GLUT_BITMAP_TIMES_ROMAN_10     ((void*)4)
+#define GLUT_BITMAP_TIMES_ROMAN_24     ((void*)5)
+#define GLUT_BITMAP_HELVETICA_10       ((void*)6)
+#define GLUT_BITMAP_HELVETICA_12       ((void*)7)
+#define GLUT_BITMAP_HELVETICA_18    ((void*)8)
+
+/* glutGet parameters. */
+#define GLUT_WINDOW_X                   100
+#define GLUT_WINDOW_Y                   101
+#define GLUT_WINDOW_WIDTH               102
+#define GLUT_WINDOW_HEIGHT              103
+#define GLUT_WINDOW_BUFFER_SIZE         104
+#define GLUT_WINDOW_STENCIL_SIZE        105
+#define GLUT_WINDOW_DEPTH_SIZE          106
+#define GLUT_WINDOW_RED_SIZE            107
+#define GLUT_WINDOW_GREEN_SIZE          108
+#define GLUT_WINDOW_BLUE_SIZE           109
+#define GLUT_WINDOW_ALPHA_SIZE          110
+#define GLUT_WINDOW_ACCUM_RED_SIZE      111
+#define GLUT_WINDOW_ACCUM_GREEN_SIZE   112
+#define GLUT_WINDOW_ACCUM_BLUE_SIZE     113
+#define GLUT_WINDOW_ACCUM_ALPHA_SIZE   114
+#define GLUT_WINDOW_DOUBLEBUFFER        115
+#define GLUT_WINDOW_RGBA                116
+#define GLUT_WINDOW_PARENT              117
+#define GLUT_WINDOW_NUM_CHILDREN        118
+#define GLUT_WINDOW_COLORMAP_SIZE       119
+#define GLUT_WINDOW_NUM_SAMPLES         120
+#define GLUT_WINDOW_STEREO              121
+#define GLUT_WINDOW_CURSOR              122
+#define GLUT_SCREEN_WIDTH               200
+#define GLUT_SCREEN_HEIGHT              201
+#define GLUT_SCREEN_WIDTH_MM            202
+#define GLUT_SCREEN_HEIGHT_MM           203
+#define GLUT_MENU_NUM_ITEMS             300
+#define GLUT_DISPLAY_MODE_POSSIBLE      400
+#define GLUT_INIT_WINDOW_X              500
+#define GLUT_INIT_WINDOW_Y              501
+#define GLUT_INIT_WINDOW_WIDTH          502
+#define GLUT_INIT_WINDOW_HEIGHT         503
+#define GLUT_INIT_DISPLAY_MODE          504
+#define GLUT_ELAPSED_TIME               700
+#define GLUT_WINDOW_FORMAT_ID           123
+
+/* glutDeviceGet parameters. */
+#define GLUT_HAS_KEYBOARD               600
+#define GLUT_HAS_MOUSE                  601
+#define GLUT_HAS_SPACEBALL              602
+#define GLUT_HAS_DIAL_AND_BUTTON_BOX   603
+#define GLUT_HAS_TABLET                 604
+#define GLUT_NUM_MOUSE_BUTTONS          605
+#define GLUT_NUM_SPACEBALL_BUTTONS      606
+#define GLUT_NUM_BUTTON_BOX_BUTTONS     607
+#define GLUT_NUM_DIALS                  608
+#define GLUT_NUM_TABLET_BUTTONS         609
+#define GLUT_DEVICE_IGNORE_KEY_REPEAT   610
+#define GLUT_DEVICE_KEY_REPEAT          611
+#define GLUT_HAS_JOYSTICK               612
+#define GLUT_OWNS_JOYSTICK              613
+#define GLUT_JOYSTICK_BUTTONS           614
+#define GLUT_JOYSTICK_AXES              615
+#define GLUT_JOYSTICK_POLL_RATE         616
+
+/* glutLayerGet parameters. */
+#define GLUT_OVERLAY_POSSIBLE           800
+#define GLUT_LAYER_IN_USE               801
+#define GLUT_HAS_OVERLAY                802
+#define GLUT_TRANSPARENT_INDEX          803
+#define GLUT_NORMAL_DAMAGED             804
+#define GLUT_OVERLAY_DAMAGED            805
+
+/* glutVideoResizeGet parameters. */
+#define GLUT_VIDEO_RESIZE_POSSIBLE      900
+#define GLUT_VIDEO_RESIZE_IN_USE        901
+#define GLUT_VIDEO_RESIZE_X_DELTA       902
+#define GLUT_VIDEO_RESIZE_Y_DELTA       903
+#define GLUT_VIDEO_RESIZE_WIDTH_DELTA  904
+#define GLUT_VIDEO_RESIZE_HEIGHT_DELTA 905
+#define GLUT_VIDEO_RESIZE_X             906
+#define GLUT_VIDEO_RESIZE_Y             907
+#define GLUT_VIDEO_RESIZE_WIDTH         908
+#define GLUT_VIDEO_RESIZE_HEIGHT        909
+
+/* glutUseLayer parameters. */
+#define GLUT_NORMAL                     0
+#define GLUT_OVERLAY                    1
+
+/* glutGetModifiers return mask. */
+#define GLUT_ACTIVE_SHIFT               1
+#define GLUT_ACTIVE_CTRL                2
+#define GLUT_ACTIVE_ALT                 4
+
+/* glutSetCursor parameters. */
+/* Basic arrows. */
+#define GLUT_CURSOR_RIGHT_ARROW         0
+#define GLUT_CURSOR_LEFT_ARROW          1
+/* Symbolic cursor shapes. */
+#define GLUT_CURSOR_INFO                2
+#define GLUT_CURSOR_DESTROY             3
+#define GLUT_CURSOR_HELP                4
+#define GLUT_CURSOR_CYCLE               5
+#define GLUT_CURSOR_SPRAY               6
+#define GLUT_CURSOR_WAIT                7
+#define GLUT_CURSOR_TEXT                8
+#define GLUT_CURSOR_CROSSHAIR           9
+/* Directional cursors. */
+#define GLUT_CURSOR_UP_DOWN             10
+#define GLUT_CURSOR_LEFT_RIGHT          11
+/* Sizing cursors. */
+#define GLUT_CURSOR_TOP_SIDE            12
+#define GLUT_CURSOR_BOTTOM_SIDE         13
+#define GLUT_CURSOR_LEFT_SIDE           14
+#define GLUT_CURSOR_RIGHT_SIDE          15
+#define GLUT_CURSOR_TOP_LEFT_CORNER     16
+#define GLUT_CURSOR_TOP_RIGHT_CORNER   17
+#define GLUT_CURSOR_BOTTOM_RIGHT_CORNER        18
+#define GLUT_CURSOR_BOTTOM_LEFT_CORNER 19
+/* Inherit from parent window. */
+#define GLUT_CURSOR_INHERIT             100
+/* Blank cursor. */
+#define GLUT_CURSOR_NONE                101
+/* Fullscreen crosshair (if available). */
+#define GLUT_CURSOR_FULL_CROSSHAIR      102
+
+/* GLUT initialization sub-API. */
+GLUTAPI void APIENTRY glutInit(int *argcp, char **argv);
+GLUTAPI void APIENTRY glutInitDisplayMode(unsigned int mode);
+GLUTAPI void APIENTRY glutInitWindowPosition(int x, int y);
+GLUTAPI void APIENTRY glutInitWindowSize(int width, int height);
+GLUTAPI void APIENTRY glutMainLoop(void);
+
+/* GLUT window sub-API. */
+GLUTAPI int APIENTRY glutCreateWindow(const char *title);
+GLUTAPI int APIENTRY glutCreateSubWindow(int win, int x, int y, int width, int height);
+GLUTAPI void APIENTRY glutDestroyWindow(int win);
+GLUTAPI void APIENTRY glutPostRedisplay(void);
+GLUTAPI void APIENTRY glutSwapBuffers(void);
+GLUTAPI int APIENTRY glutGetWindow(void);
+GLUTAPI void APIENTRY glutSetWindow(int win);
+GLUTAPI void APIENTRY glutSetWindowTitle(const char *title);
+GLUTAPI void APIENTRY glutSetIconTitle(const char *title);
+GLUTAPI void APIENTRY glutPositionWindow(int x, int y);
+GLUTAPI void APIENTRY glutReshapeWindow(int width, int height);
+GLUTAPI void APIENTRY glutPopWindow(void);
+GLUTAPI void APIENTRY glutPushWindow(void);
+GLUTAPI void APIENTRY glutIconifyWindow(void);
+GLUTAPI void APIENTRY glutShowWindow(void);
+GLUTAPI void APIENTRY glutHideWindow(void);
+
+/* GLUT overlay sub-API. */
+GLUTAPI void APIENTRY glutEstablishOverlay(void);
+GLUTAPI void APIENTRY glutRemoveOverlay(void);
+GLUTAPI void APIENTRY glutUseLayer(GLenum layer);
+GLUTAPI void APIENTRY glutPostOverlayRedisplay(void);
+GLUTAPI void APIENTRY glutShowOverlay(void);
+GLUTAPI void APIENTRY glutHideOverlay(void);
+
+/* GLUT menu sub-API. */
+GLUTAPI int APIENTRY glutCreateMenu(void (GLUTCALLBACK *)(int));
+GLUTAPI void APIENTRY glutDestroyMenu(int menu);
+GLUTAPI int APIENTRY glutGetMenu(void);
+GLUTAPI void APIENTRY glutSetMenu(int menu);
+GLUTAPI void APIENTRY glutAddMenuEntry(const char *label, int value);
+GLUTAPI void APIENTRY glutAddSubMenu(const char *label, int submenu);
+GLUTAPI void APIENTRY glutChangeToMenuEntry(int item, const char *label, int value);
+GLUTAPI void APIENTRY glutChangeToSubMenu(int item, const char *label, int submenu);
+GLUTAPI void APIENTRY glutRemoveMenuItem(int item);
+GLUTAPI void APIENTRY glutAttachMenu(int button);
+GLUTAPI void APIENTRY glutDetachMenu(int button);
+
+/* GLUT window callback sub-API. */
+GLUTAPI void APIENTRY glutDisplayFunc(void (GLUTCALLBACK * func)(void));
+GLUTAPI void APIENTRY glutReshapeFunc(void (GLUTCALLBACK * func)(int width, int height));
+GLUTAPI void APIENTRY glutKeyboardFunc(void (GLUTCALLBACK * func)(unsigned char key, int x, int y));
+GLUTAPI void APIENTRY glutMouseFunc(void (GLUTCALLBACK * func)(int button, int state, int x, int y));
+GLUTAPI void APIENTRY glutMotionFunc(void (GLUTCALLBACK * func)(int x, int y));
+GLUTAPI void APIENTRY glutPassiveMotionFunc(void (GLUTCALLBACK * func)(int x, int y));
+GLUTAPI void APIENTRY glutEntryFunc(void (GLUTCALLBACK * func)(int state));
+GLUTAPI void APIENTRY glutVisibilityFunc(void (GLUTCALLBACK * func)(int state));
+GLUTAPI void APIENTRY glutIdleFunc(void (GLUTCALLBACK * func)(void));
+GLUTAPI void APIENTRY glutTimerFunc(unsigned int millis, void (GLUTCALLBACK * func)(int value), int value);
+GLUTAPI void APIENTRY glutMenuStateFunc(void (GLUTCALLBACK * func)(int state));
+GLUTAPI void APIENTRY glutSpecialFunc(void (GLUTCALLBACK * func)(int key, int x, int y));
+GLUTAPI void APIENTRY glutSpaceballMotionFunc(void (GLUTCALLBACK * func)(int x, int y, int z));
+GLUTAPI void APIENTRY glutSpaceballRotateFunc(void (GLUTCALLBACK * func)(int x, int y, int z));
+GLUTAPI void APIENTRY glutSpaceballButtonFunc(void (GLUTCALLBACK * func)(int button, int state));
+GLUTAPI void APIENTRY glutButtonBoxFunc(void (GLUTCALLBACK * func)(int button, int state));
+GLUTAPI void APIENTRY glutDialsFunc(void (GLUTCALLBACK * func)(int dial, int value));
+GLUTAPI void APIENTRY glutTabletMotionFunc(void (GLUTCALLBACK * func)(int x, int y));
+GLUTAPI void APIENTRY glutTabletButtonFunc(void (GLUTCALLBACK * func)(int button, int state, int x, int y));
+GLUTAPI void APIENTRY glutMenuStatusFunc(void (GLUTCALLBACK * func)(int status, int x, int y));
+GLUTAPI void APIENTRY glutOverlayDisplayFunc(void (GLUTCALLBACK * func)(void));
+GLUTAPI void APIENTRY glutWindowStatusFunc(void (GLUTCALLBACK * func)(int state));
+
+/* GLUT color index sub-API. */
+GLUTAPI void APIENTRY glutSetColor(int, GLfloat red, GLfloat green, GLfloat blue);
+GLUTAPI GLfloat APIENTRY glutGetColor(int ndx, int component);
+GLUTAPI void APIENTRY glutCopyColormap(int win);
+
+/* GLUT state retrieval sub-API. */
+GLUTAPI int APIENTRY glutGet(GLenum type);
+GLUTAPI int APIENTRY glutDeviceGet(GLenum type);
+
+/* GLUT font sub-API */
+GLUTAPI void APIENTRY glutBitmapCharacter(void *font, int character);
+GLUTAPI int APIENTRY glutBitmapWidth(void *font, int character);
+GLUTAPI void APIENTRY glutStrokeCharacter(void *font, int character);
+GLUTAPI int APIENTRY glutStrokeWidth(void *font, int character);
+
+/* GLUT pre-built models sub-API */
+GLUTAPI void APIENTRY glutWireSphere(GLdouble radius, GLint slices, GLint stacks);
+GLUTAPI void APIENTRY glutSolidSphere(GLdouble radius, GLint slices, GLint stacks);
+GLUTAPI void APIENTRY glutWireCone(GLdouble base, GLdouble height, GLint slices, GLint stacks);
+GLUTAPI void APIENTRY glutSolidCone(GLdouble base, GLdouble height, GLint slices, GLint stacks);
+GLUTAPI void APIENTRY glutWireCube(GLdouble size);
+GLUTAPI void APIENTRY glutSolidCube(GLdouble size);
+GLUTAPI void APIENTRY glutWireTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings);
+GLUTAPI void APIENTRY glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings);
+GLUTAPI void APIENTRY glutWireDodecahedron(void);
+GLUTAPI void APIENTRY glutSolidDodecahedron(void);
+GLUTAPI void APIENTRY glutWireTeapot(GLdouble size);
+GLUTAPI void APIENTRY glutSolidTeapot(GLdouble size);
+GLUTAPI void APIENTRY glutWireOctahedron(void);
+GLUTAPI void APIENTRY glutSolidOctahedron(void);
+GLUTAPI void APIENTRY glutWireTetrahedron(void);
+GLUTAPI void APIENTRY glutSolidTetrahedron(void);
+GLUTAPI void APIENTRY glutWireIcosahedron(void);
+GLUTAPI void APIENTRY glutSolidIcosahedron(void);
+
+#endif /* __AGLUT_H__ */
diff --git a/include/GL/glutf90.h b/include/GL/glutf90.h
new file mode 100644 (file)
index 0000000..46f1979
--- /dev/null
@@ -0,0 +1,81 @@
+#ifndef __glutf90_h__
+#define __glutf90_h__
+
+/* Copyright (c) Mark J. Kilgard & Willam F. Mitchell, 1998. */
+
+/* This program is freely distributable without licensing fees
+   and is provided without guarantee or warrantee expressed or
+   implied. This program is -not- in the public domain. */
+
+/* This header provides the binding interface for William Mitchell's
+   f90gl Fortran 90 GLUT binding.  Other GLUT language bindings
+   can and should use this interace. */
+
+/* I appreciate the guidance from William Mitchell
+   (mitchell@cam.nist.gov) in developing this friend interface
+   for use by the f90gl package.  See ../../README.fortran */
+
+#include <GL/glut.h>
+
+/* Which callback enumerants for the __glutSetFCB/__glutGetFCB routines. */
+/* NOTE These values are part of a binary interface for the f90gl Fortran
+   90 binding and so must NOT changes (additions are allowed). */
+
+/* GLUTwindow callbacks. */
+#define GLUT_FCB_DISPLAY         0    /* GLUTdisplayFCB */
+#define GLUT_FCB_RESHAPE         1    /* GLUTreshapeFCB */
+#define GLUT_FCB_MOUSE           2    /* GLUTmouseFCB */
+#define GLUT_FCB_MOTION          3    /* GLUTmotionFCB */
+#define GLUT_FCB_PASSIVE         4    /* GLUTpassiveFCB */
+#define GLUT_FCB_ENTRY           5    /* GLUTentryFCB */
+#define GLUT_FCB_KEYBOARD        6    /* GLUTkeyboardFCB */
+#define GLUT_FCB_KEYBOARD_UP     7    /* GLUTkeyboardFCB */
+#define GLUT_FCB_WINDOW_STATUS   8    /* GLUTwindowStatusFCB */
+#define GLUT_FCB_VISIBILITY      9    /* GLUTvisibilityFCB */
+#define GLUT_FCB_SPECIAL         10   /* GLUTspecialFCB */
+#define GLUT_FCB_SPECIAL_UP      11   /* GLUTspecialFCB */
+#define GLUT_FCB_BUTTON_BOX      12   /* GLUTbuttonBoxFCB */
+#define GLUT_FCB_DIALS           13   /* GLUTdialsFCB */
+#define GLUT_FCB_SPACE_MOTION    14   /* GLUTspaceMotionFCB */
+#define GLUT_FCB_SPACE_ROTATE    15   /* GLUTspaceRotateFCB */
+#define GLUT_FCB_SPACE_BUTTON    16   /* GLUTspaceButtonFCB */
+#define GLUT_FCB_TABLET_MOTION   17   /* GLUTtabletMotionFCB */
+#define GLUT_FCB_TABLET_BUTTON   18   /* GLUTtabletButtonFCB */
+#define GLUT_FCB_JOYSTICK        19   /* GLUTjoystickFCB */
+/* Non-GLUTwindow callbacks. */
+#define GLUT_FCB_OVERLAY_DISPLAY 100  /* GLUTdisplayFCB */
+#define GLUT_FCB_SELECT          101  /* GLUTselectFCB */
+#define GLUT_FCB_TIMER           102  /* GLUTtimerFCB */
+
+/* GLUT Fortran callback function types. */
+typedef void (GLUTCALLBACK *GLUTdisplayFCB) (void);
+typedef void (GLUTCALLBACK *GLUTreshapeFCB) (int *, int *);
+/* NOTE the pressed key is int, not unsigned char for Fortran! */
+typedef void (GLUTCALLBACK *GLUTkeyboardFCB) (int *, int *, int *);
+typedef void (GLUTCALLBACK *GLUTmouseFCB) (int *, int *, int *, int *);
+typedef void (GLUTCALLBACK *GLUTmotionFCB) (int *, int *);
+typedef void (GLUTCALLBACK *GLUTpassiveFCB) (int *, int *);
+typedef void (GLUTCALLBACK *GLUTentryFCB) (int *);
+typedef void (GLUTCALLBACK *GLUTwindowStatusFCB) (int *);
+typedef void (GLUTCALLBACK *GLUTvisibilityFCB) (int *);
+typedef void (GLUTCALLBACK *GLUTspecialFCB) (int *, int *, int *);
+typedef void (GLUTCALLBACK *GLUTbuttonBoxFCB) (int *, int *);
+typedef void (GLUTCALLBACK *GLUTdialsFCB) (int *, int *);
+typedef void (GLUTCALLBACK *GLUTspaceMotionFCB) (int *, int *, int *);
+typedef void (GLUTCALLBACK *GLUTspaceRotateFCB) (int *, int *, int *);
+typedef void (GLUTCALLBACK *GLUTspaceButtonFCB) (int *, int *);
+typedef void (GLUTCALLBACK *GLUTtabletMotionFCB) (int *, int *);
+typedef void (GLUTCALLBACK *GLUTtabletButtonFCB) (int *, int *, int *, int *);
+typedef void (GLUTCALLBACK *GLUTjoystickFCB) (unsigned int *buttonMask, int *x, int *y, int *z);
+
+typedef void (GLUTCALLBACK *GLUTselectFCB) (int *);
+typedef void (GLUTCALLBACK *GLUTtimerFCB) (int *);
+typedef void (GLUTCALLBACK *GLUTmenuStateFCB) (int *);  /* DEPRICATED. */
+typedef void (GLUTCALLBACK *GLUTmenuStatusFCB) (int *, int *, int *);
+typedef void (GLUTCALLBACK *GLUTidleFCB) (void);
+
+/* Functions that set and return Fortran callback functions. */
+extern void* GLUTAPIENTRY __glutGetFCB(int which);
+extern void GLUTAPIENTRY __glutSetFCB(int which, void *func);
+
+#endif  /* __glutf90_h__ */
diff --git a/include/GL/glx.h b/include/GL/glx.h
new file mode 100644 (file)
index 0000000..4b27880
--- /dev/null
@@ -0,0 +1,261 @@
+/* $Id: glx.h,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/*
+ * $Log: glx.h,v $
+ * Revision 1.1  1999/08/19 00:55:40  jtg
+ * Initial revision
+ *
+ * Revision 3.3  1999/02/14 03:39:09  brianp
+ * new copyright
+ *
+ * Revision 3.2  1998/06/18 03:44:00  brianp
+ * replaced "uint" with "unsigned int"
+ *
+ * Revision 3.1  1998/06/01 00:00:17  brianp
+ * added GLX_SGI_video_sync extension
+ *
+ * Revision 3.0  1998/02/20 05:06:01  brianp
+ * initial rev
+ *
+ */
+
+
+#ifndef GLX_H
+#define GLX_H
+
+
+/*
+ * A pseudo-GLX implementation to allow GLX-based OpenGL programs to
+ * work with Mesa.
+ *
+ * Notes:
+ *   1. If the visual passed to glXGetConfig was not one returned by
+ *      glXChooseVisual then the GLX_RGBA and GLX_DOUBLEBUFFER queries
+ *      will always return True and the GLX_DEPTH_SIZE query will always
+ *      return non-zero.
+ *   2. The glXIsDirect() function always returns True.
+ */
+
+
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include "GL/gl.h"
+#ifdef MESA
+#include "GL/xmesa.h"
+#endif
+
+
+#if defined(USE_MGL_NAMESPACE)
+#include "glx_mangle.h"
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define GLX_VERSION_1_1                1
+
+
+/*
+ * Tokens for glXChooseVisual and glXGetConfig:
+ */
+enum _GLX_CONFIGS {
+       GLX_USE_GL              = 1,
+       GLX_BUFFER_SIZE         = 2,
+       GLX_LEVEL               = 3,
+       GLX_RGBA                = 4,
+       GLX_DOUBLEBUFFER        = 5, 
+       GLX_STEREO              = 6,
+       GLX_AUX_BUFFERS         = 7,
+       GLX_RED_SIZE            = 8,
+       GLX_GREEN_SIZE          = 9,
+       GLX_BLUE_SIZE           = 10,
+       GLX_ALPHA_SIZE          = 11,
+       GLX_DEPTH_SIZE          = 12,
+       GLX_STENCIL_SIZE        = 13,
+       GLX_ACCUM_RED_SIZE      = 14,
+       GLX_ACCUM_GREEN_SIZE    = 15,
+       GLX_ACCUM_BLUE_SIZE     = 16,
+       GLX_ACCUM_ALPHA_SIZE    = 17,
+
+       /* GLX_EXT_visual_info extension */
+       GLX_X_VISUAL_TYPE_EXT           = 0x22,
+       GLX_TRANSPARENT_TYPE_EXT        = 0x23,
+       GLX_TRANSPARENT_INDEX_VALUE_EXT = 0x24,
+       GLX_TRANSPARENT_RED_VALUE_EXT   = 0x25,
+       GLX_TRANSPARENT_GREEN_VALUE_EXT = 0x26,
+       GLX_TRANSPARENT_BLUE_VALUE_EXT  = 0x27,
+       GLX_TRANSPARENT_ALPHA_VALUE_EXT = 0x28
+};
+
+
+/*
+ * Error codes returned by glXGetConfig:
+ */
+#define GLX_BAD_SCREEN         1
+#define GLX_BAD_ATTRIBUTE      2
+#define GLX_NO_EXTENSION       3
+#define GLX_BAD_VISUAL         4
+#define GLX_BAD_CONTEXT                5
+#define GLX_BAD_VALUE          6
+#define GLX_BAD_ENUM           7
+
+
+/*
+ * GLX 1.1 and later:
+ */
+#define GLX_VENDOR             1
+#define GLX_VERSION            2
+#define GLX_EXTENSIONS                 3
+
+
+/*
+ * GLX_visual_info extension
+ */
+#define GLX_TRUE_COLOR_EXT             0x8002
+#define GLX_DIRECT_COLOR_EXT           0x8003
+#define GLX_PSEUDO_COLOR_EXT           0x8004
+#define GLX_STATIC_COLOR_EXT           0x8005
+#define GLX_GRAY_SCALE_EXT             0x8006
+#define GLX_STATIC_GRAY_EXT            0x8007
+#define GLX_NONE_EXT                   0x8000
+#define GLX_TRANSPARENT_RGB_EXT                0x8008
+#define GLX_TRANSPARENT_INDEX_EXT      0x8009
+
+
+/*
+ * Compile-time extension tests
+ */
+#ifdef MESA
+#define GLX_EXT_visual_info            1
+#define GLX_MESA_pixmap_colormap       1
+#define GLX_MESA_release_buffers       1
+#define GLX_MESA_copy_sub_buffer       1
+#define GLX_SGI_video_sync             1
+#endif
+
+
+
+#ifdef MESA
+   typedef XMesaContext GLXContext;
+   typedef Pixmap GLXPixmap;
+   typedef Drawable GLXDrawable;
+#else
+   typedef void * GLXContext;
+   typedef XID GLXPixmap;
+   typedef XID GLXDrawable;
+#endif
+typedef XID GLXContextID;
+
+
+
+extern XVisualInfo* glXChooseVisual( Display *dpy, int screen,
+                                    int *attribList );
+
+extern GLXContext glXCreateContext( Display *dpy, XVisualInfo *vis,
+                                   GLXContext shareList, Bool direct );
+
+extern void glXDestroyContext( Display *dpy, GLXContext ctx );
+
+extern Bool glXMakeCurrent( Display *dpy, GLXDrawable drawable,
+                           GLXContext ctx);
+
+extern void glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
+                           GLuint mask );
+
+extern void glXSwapBuffers( Display *dpy, GLXDrawable drawable );
+
+extern GLXPixmap glXCreateGLXPixmap( Display *dpy, XVisualInfo *visual,
+                                    Pixmap pixmap );
+
+extern void glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap );
+
+extern Bool glXQueryExtension( Display *dpy, int *errorb, int *event );
+
+extern Bool glXQueryVersion( Display *dpy, int *maj, int *min );
+
+extern Bool glXIsDirect( Display *dpy, GLXContext ctx );
+
+extern int glXGetConfig( Display *dpy, XVisualInfo *visual,
+                        int attrib, int *value );
+
+extern GLXContext glXGetCurrentContext( void );
+
+extern GLXDrawable glXGetCurrentDrawable( void );
+
+extern void glXWaitGL( void );
+
+extern void glXWaitX( void );
+
+extern void glXUseXFont( Font font, int first, int count, int list );
+
+
+
+/* GLX 1.1 and later */
+extern const char *glXQueryExtensionsString( Display *dpy, int screen );
+
+extern const char *glXQueryServerString( Display *dpy, int screen, int name );
+
+extern const char *glXGetClientString( Display *dpy, int name );
+
+
+
+/*
+ * Mesa GLX Extensions
+ */
+
+#ifdef GLX_MESA_pixmap_colormap
+extern GLXPixmap glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visual,
+                                         Pixmap pixmap, Colormap cmap );
+#endif
+
+#ifdef GLX_MESA_release_buffers
+extern Bool glXReleaseBuffersMESA( Display *dpy, GLXDrawable d );
+#endif
+
+#ifdef GLX_MESA_copy_sub_buffer
+extern void glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable,
+                                  int x, int y, int width, int height );
+#endif
+
+#ifdef GLX_SGI_video_sync
+extern int glXGetVideoSyncSGI(unsigned int *count);
+extern int glXWaitVideoSyncSGI(int divisor, int remainder,
+                               unsigned int *count);
+#endif
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/GL/glx_mangle.h b/include/GL/glx_mangle.h
new file mode 100644 (file)
index 0000000..e246801
--- /dev/null
@@ -0,0 +1,72 @@
+/* $Id: glx_mangle.h,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.0
+ * Copyright (C) 1995-1998  Brian Paul
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/*
+ * $Log: glx_mangle.h,v $
+ * Revision 1.1  1999/08/19 00:55:40  jtg
+ * Initial revision
+ *
+ * Revision 3.3  1999/06/21 22:01:00  brianp
+ * added #ifndef GLX_MANGLE_H stuff, video sync extension functions
+ *
+ * Revision 3.2  1998/03/26 02:44:53  brianp
+ * removed ^M characters
+ *
+ * Revision 3.1  1998/03/17 02:41:19  brianp
+ * updated by Randy Frank
+ *
+ * Revision 3.0  1998/02/20 05:04:45  brianp
+ * initial rev
+ *
+ */
+
+#ifndef GLX_MANGLE_H
+#define GLX_MANGLE_H
+
+#define glXChooseVisual mglXChooseVisual
+#define glXCreateContext mglXCreateContext
+#define glXDestroyContext mglXDestroyContext
+#define glXMakeCurrent mglXMakeCurrent
+#define glXCopyContext mglXCopyContext
+#define glXSwapBuffers mglXSwapBuffers
+#define glXCreateGLXPixmap mglXCreateGLXPixmap
+#define glXDestroyGLXPixmap mglXDestroyGLXPixmap
+#define glXQueryExtension mglXQueryExtension
+#define glXQueryVersion mglXQueryVersion
+#define glXIsDirect mglXIsDirect
+#define glXGetConfig mglXGetConfig
+#define glXGetCurrentContext mglXGetCurrentContext
+#define glXGetCurrentDrawable mglXGetCurrentDrawable
+#define glXWaitGL mglXWaitGL
+#define glXWaitX mglXWaitX
+#define glXUseXFont mglXUseXFont
+#define glXQueryExtensionsString mglXQueryExtensionsString
+#define glXQueryServerString mglXQueryServerString
+#define glXGetClientString mglXGetClientString
+#define glXCreateGLXPixmapMESA mglXCreateGLXPixmapMESA
+#define glXReleaseBuffersMESA mglXReleaseBuffersMESA
+#define glXCopySubBufferMESA mglXCopySubBufferMESA
+#define glXGetVideoSyncSGI mglXGetVideoSyncSGI
+#define glXWaitVideoSyncSGI mglXWaitVideoSyncSGI
+
+#endif
diff --git a/include/GL/mglmesa.h b/include/GL/mglmesa.h
new file mode 100644 (file)
index 0000000..76deb33
--- /dev/null
@@ -0,0 +1,80 @@
+/****************************************************************************\r
+*\r
+*                      Mesa bindings for SciTech MGL\r
+*\r
+*                   Copyright (C) 1996 SciTech Software.\r
+*                           All rights reserved.\r
+*\r
+* Filename:     $Workfile:   mglmesa.h  $\r
+* Version:      $Revision: 1.1 $\r
+*\r
+* Language:     ANSI C\r
+* Environment:  Any\r
+*\r
+* Description:  Header file for the Mesa/OpenGL interface bindings for the\r
+*               SciTech MGL graphics library. Uses the MGL internal\r
+*               device context structures to get direct access to the\r
+*               high performance MGL rasterization functions for maximum\r
+*               performance. Utilizes the VESA VBE/AF Accelerator Functions\r
+*               via the MGL's accelerated device driver functions, as well\r
+*               as basic DirectDraw accelerated functions provided by the\r
+*               MGL.\r
+*\r
+* This library is free software; you can redistribute it and/or\r
+* modify it under the terms of the GNU Library General Public\r
+* License as published by the Free Software Foundation; either\r
+* version 2 of the License, or (at your option) any later version.\r
+*\r
+* This library is distributed in the hope that it will be useful,\r
+* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+* Library General Public License for more details.\r
+*\r
+* You should have received a copy of the GNU Library General Public\r
+* License along with this library; if not, write to the Free\r
+* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
+*\r
+* $Date: 1999/08/19 00:55:40 $ $Author: jtg $\r
+*\r
+****************************************************************************/\r
+\r
+#ifndef __MGLMESA_H\r
+#define __MGLMESA_H\r
+\r
+#include "mgraph.h"\r
+\r
+/*------------------------- Function Prototypes ---------------------------*/\r
+\r
+#ifdef  __cplusplus\r
+extern "C" {            /* Use "C" linkage when in C++ mode */\r
+#endif\r
+\r
+#ifndef __WINDOWS__\r
+#define GLAPIENTRY\r
+#endif\r
+\r
+#ifdef  __WINDOWS__\r
+bool    GLAPIENTRY MGLMesaInitDLL(MGLCallbacks *cb,char *version);\r
+#endif\r
+void    GLAPIENTRY MGLMesaChooseVisual(MGLDC *dc,MGLVisual *visual);\r
+bool    GLAPIENTRY MGLMesaSetVisual(MGLDC *dc,MGLVisual *visual);\r
+bool    GLAPIENTRY MGLMesaCreateContext(MGLDC *dc,bool forceMemDC);\r
+void    GLAPIENTRY MGLMesaDestroyContext(MGLDC *dc);\r
+void    GLAPIENTRY MGLMesaMakeCurrent(MGLDC *dc);\r
+void    GLAPIENTRY MGLMesaSwapBuffers(MGLDC *dc,bool waitVRT);\r
+\r
+/* Palette manipulation support. The reason we provide palette manipulation\r
+ * routines is so that when rendering in double buffered modes with a\r
+ * software backbuffer, the palette for the backbuffer is kept consistent\r
+ * with the hardware front buffer.\r
+ */\r
+\r
+void    GLAPIENTRY MGLMesaSetPaletteEntry(MGLDC *dc,int entry,uchar red,uchar green,uchar blue);\r
+void    GLAPIENTRY MGLMesaSetPalette(MGLDC *dc,palette_t *pal,int numColors,int startIndex);\r
+void    GLAPIENTRY MGLMesaRealizePalette(MGLDC *dc,int numColors,int startIndex,int waitVRT);\r
+\r
+#ifdef  __cplusplus\r
+}                       /* End of "C" linkage for C++   */\r
+#endif  /* __cplusplus */\r
+\r
+#endif  /* __MGLMESA_H */\r
diff --git a/include/GL/osmesa.h b/include/GL/osmesa.h
new file mode 100644 (file)
index 0000000..11423a8
--- /dev/null
@@ -0,0 +1,256 @@
+/* $Id: osmesa.h,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/*
+ * $Log: osmesa.h,v $
+ * Revision 1.1  1999/08/19 00:55:40  jtg
+ * Initial revision
+ *
+ * Revision 1.4  1999/02/14 03:39:09  brianp
+ * new copyright
+ *
+ * Revision 1.3  1999/01/03 02:52:30  brianp
+ * now using GLAPI and GLAPIENTRY keywords (Ted Jump)
+ *
+ * Revision 1.2  1998/07/26 01:33:51  brianp
+ * added WINGDIAPI and APIENTRY keywords per Ted Jump
+ *
+ * Revision 1.1  1998/02/13 03:17:50  brianp
+ * Initial revision
+ *
+ */
+
+
+/*
+ * Mesa Off-Screen rendering interface.
+ *
+ * This is an operating system and window system independent interface to
+ * Mesa which allows one to render images into a client-supplied buffer in
+ * main memory.  Such images may manipulated or saved in whatever way the
+ * client wants.
+ *
+ * These are the API functions:
+ *   OSMesaCreateContext - create a new Off-Screen Mesa rendering context
+ *   OSMesaMakeCurrent - bind an OSMesaContext to a client's image buffer
+ *                       and make the specified context the current one.
+ *   OSMesaDestroyContext - destroy an OSMesaContext
+ *   OSMesaGetCurrentContext - return thread's current context ID
+ *   OSMesaPixelStore - controls how pixels are stored in image buffer
+ *   OSMesaGetIntegerv - return OSMesa state parameters
+ *
+ *
+ * The limits on the width and height of an image buffer are MAX_WIDTH and
+ * MAX_HEIGHT as defined in Mesa/src/config.h.  Defaults are 1280 and 1024.
+ * You can increase them as needed but beware that many temporary arrays in
+ * Mesa are dimensioned by MAX_WIDTH or MAX_HEIGHT.
+ */
+
+
+
+#ifndef OSMESA_H
+#define OSMESA_H
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#include "GL/gl.h"
+
+
+
+#define OSMESA_MAJOR_VERSION 3
+#define OSMESA_MINOR_VERSION 0
+
+
+
+/*
+ * Values for the format parameter of OSMesaCreateContext()
+ * New in version 2.0.
+ */
+#define OSMESA_COLOR_INDEX     GL_COLOR_INDEX
+#define OSMESA_RGBA            GL_RGBA
+#define OSMESA_BGRA            0x1
+#define OSMESA_ARGB            0x2
+#define OSMESA_RGB             GL_RGB
+#define OSMESA_BGR             0x4
+
+
+/*
+ * OSMesaPixelStore() parameters:
+ * New in version 2.0.
+ */
+#define OSMESA_ROW_LENGTH      0x10
+#define OSMESA_Y_UP            0x11
+
+
+/*
+ * Accepted by OSMesaGetIntegerv:
+ */
+#define OSMESA_WIDTH           0x20
+#define OSMESA_HEIGHT          0x21
+#define OSMESA_FORMAT          0x22
+#define OSMESA_TYPE            0x23
+
+
+
+typedef struct osmesa_context *OSMesaContext;
+
+
+#if defined(__BEOS__) || defined(__QUICKDRAW__)
+#pragma export on
+#endif
+
+
+/*
+ * Create an Off-Screen Mesa rendering context.  The only attribute needed is
+ * an RGBA vs Color-Index mode flag.
+ *
+ * Input:  format - one of OSMESA_COLOR_INDEX, OSMESA_RGBA, OSMESA_BGRA,
+ *                  OSMESA_ARGB, OSMESA_RGB, or OSMESA_BGR.
+ *         sharelist - specifies another OSMesaContext with which to share
+ *                     display lists.  NULL indicates no sharing.
+ * Return:  an OSMesaContext or 0 if error
+ */
+GLAPI OSMesaContext GLAPIENTRY OSMesaCreateContext( GLenum format,
+                                          OSMesaContext sharelist );
+
+
+
+
+/*
+ * Destroy an Off-Screen Mesa rendering context.
+ *
+ * Input:  ctx - the context to destroy
+ */
+GLAPI void GLAPIENTRY OSMesaDestroyContext( OSMesaContext ctx );
+
+
+
+/*
+ * Bind an OSMesaContext to an image buffer.  The image buffer is just a
+ * block of memory which the client provides.  Its size must be at least
+ * as large as width*height*sizeof(type).  Its address should be a multiple
+ * of 4 if using RGBA mode.
+ *
+ * Image data is stored in the order of glDrawPixels:  row-major order
+ * with the lower-left image pixel stored in the first array position
+ * (ie. bottom-to-top).
+ *
+ * Since the only type initially supported is GL_UNSIGNED_BYTE, if the
+ * context is in RGBA mode, each pixel will be stored as a 4-byte RGBA
+ * value.  If the context is in color indexed mode, each pixel will be
+ * stored as a 1-byte value.
+ *
+ * If the context's viewport hasn't been initialized yet, it will now be
+ * initialized to (0,0,width,height).
+ *
+ * Input:  ctx - the rendering context
+ *         buffer - the image buffer memory
+ *         type - data type for pixel components, only GL_UNSIGNED_BYTE
+ *                supported now
+ *         width, height - size of image buffer in pixels, at least 1
+ * Return:  GL_TRUE if success, GL_FALSE if error because of invalid ctx,
+ *          invalid buffer address, type!=GL_UNSIGNED_BYTE, width<1, height<1,
+ *          width>internal limit or height>internal limit.
+ */
+GLAPI GLboolean GLAPIENTRY OSMesaMakeCurrent( OSMesaContext ctx,
+                                    void *buffer, GLenum type,
+                                    GLsizei width, GLsizei height );
+
+
+
+
+/*
+ * Return the current Off-Screen Mesa rendering context handle.
+ */
+GLAPI OSMesaContext GLAPIENTRY OSMesaGetCurrentContext( void );
+
+
+
+/*
+ * Set pixel store/packing parameters for the current context.
+ * This is similar to glPixelStore.
+ * Input:  pname - OSMESA_ROW_LENGTH
+ *                    specify actual pixels per row in image buffer
+ *                    0 = same as image width (default)
+ *                 OSMESA_Y_UP
+ *                    zero = Y coordinates increase downward
+ *                    non-zero = Y coordinates increase upward (default)
+ *         value - the value for the parameter pname
+ *
+ * New in version 2.0.
+ */
+GLAPI void GLAPIENTRY OSMesaPixelStore( GLint pname, GLint value );
+
+
+
+/*
+ * Return context info.  This is like glGetIntegerv.
+ * Input:  pname -
+ *                 OSMESA_WIDTH  return current image width
+ *                 OSMESA_HEIGHT  return current image height
+ *                 OSMESA_FORMAT  return image format
+ *                 OSMESA_TYPE  return color component data type
+ *                 OSMESA_ROW_LENGTH return row length in pixels
+ *                 OSMESA_Y_UP returns 1 or 0 to indicate Y axis direction
+ *         value - pointer to integer in which to return result.
+ */
+GLAPI void GLAPIENTRY OSMesaGetIntegerv( GLint pname, GLint *value );
+
+
+
+/*
+ * Return the depth buffer associated with an OSMesa context.
+ * Input:  c - the OSMesa context
+ * Output:  width, height - size of buffer in pixels
+ *          bytesPerValue - bytes per depth value (2 or 4)
+ *          buffer - pointer to depth buffer values
+ * Return:  GL_TRUE or GL_FALSE to indicate success or failure.
+ *
+ * New in Mesa 2.4.
+ */
+GLAPI GLboolean GLAPIENTRY OSMesaGetDepthBuffer( OSMesaContext c,
+                                       GLint *width, GLint *height,
+                                       GLint *bytesPerValue, void **buffer );
+
+
+
+
+#if defined(__BEOS__) || defined(__QUICKDRAW__)
+#pragma export off
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/include/GL/svgamesa.h b/include/GL/svgamesa.h
new file mode 100644 (file)
index 0000000..9625a5b
--- /dev/null
@@ -0,0 +1,106 @@
+/* $Id: svgamesa.h,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.0
+ * Copyright (C) 1995-1998  Brian Paul
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/*
+ * $Log: svgamesa.h,v $
+ * Revision 1.1  1999/08/19 00:55:40  jtg
+ * Initial revision
+ *
+ * Revision 3.0  1998/02/20 05:07:24  brianp
+ * initial rev
+ *
+ */
+
+
+
+/*
+ * SVGA/Mesa interface for Linux.
+ */
+
+
+/*
+ * Intro to using the VGA/Mesa interface
+ *
+ * 1. #include the <vga.h> file
+ * 2. Call vga_init() to initialize the SVGA library.
+ * 3. Call vga_setmode() to specify the screen size and color depth.
+ * 4. Call SVGAMesaCreateContext() to setup a Mesa context.  If using 8-bit
+ *    color Mesa assumes color index mode, if using 16-bit or deeper color
+ *    Mesa assumes RGB mode.
+ * 5. Call SVGAMesaMakeCurrent() to activate the Mesa context.
+ * 6. You can now use the Mesa API functions.
+ * 7. Before exiting, call SVGAMesaDestroyContext() then vga_setmode(TEXT)
+ *    to restore the original text screen.
+ *
+ * Notes
+ * 1. You must run your executable as root (or use the set UID-bit) because
+ *    the SVGA library requires it.
+ * 2. The SVGA driver is not fully implemented yet.  See svgamesa.c for what
+ *    has to be done yet.
+ */
+
+
+#ifndef SVGAMESA_H
+#define SVGAMESA_H
+
+
+#define SVGAMESA_MAJOR_VERSION 3
+#define SVGAMESA_MINOR_VERSION 0
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#include "GL/gl.h"
+
+
+
+/*
+ * This is the SVGAMesa context 'handle':
+ */
+typedef struct svgamesa_context *SVGAMesaContext;
+
+
+
+/*
+ * doubleBuffer flag new in version 2.4
+ */
+extern SVGAMesaContext SVGAMesaCreateContext( GLboolean doubleBuffer );
+
+extern void SVGAMesaDestroyContext( SVGAMesaContext ctx );
+
+extern void SVGAMesaMakeCurrent( SVGAMesaContext ctx );
+
+extern SVGAMesaContext SVGAMesaGetCurrentContext( void );
+
+extern void SVGAMesaSwapBuffers( void );
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/include/GL/wmesa.h b/include/GL/wmesa.h
new file mode 100644 (file)
index 0000000..94b6197
--- /dev/null
@@ -0,0 +1,155 @@
+/* $Id: wmesa.h,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.0
+ * Copyright (C) 1995-1998  Brian Paul
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+
+/*
+ * $Log: wmesa.h,v $
+ * Revision 1.1  1999/08/19 00:55:40  jtg
+ * Initial revision
+ *
+ * Revision 3.2  1999/01/03 02:54:45  brianp
+ * updated per Ted Jump
+ *
+ * Revision 3.1  1998/12/01 02:34:27  brianp
+ * applied Mark Kilgard's patches from November 30, 1998
+ *
+ * Revision 3.0  1998/02/20 05:06:59  brianp
+ * initial rev
+ *
+ */
+
+
+/*
+ * Windows driver by: Mark E. Peterson (markp@ic.mankato.mn.us)
+ * Updated by Li Wei (liwei@aiar.xjtu.edu.cn)
+ *
+ *
+ ***************************************************************
+ *                     WMesa                                   *
+ *                     version 2.3                             *       
+ *                                                             *
+ *                        By                                   *
+ *                      Li Wei                                 *
+ *       Institute of Artificial Intelligence & Robotics       *
+ *       Xi'an Jiaotong University                             *
+ *       Email: liwei@aiar.xjtu.edu.cn                         * 
+ *       Web page: http://sun.aiar.xjtu.edu.cn                 *
+ *                                                             *
+ *            July 7th, 1997                                  *
+ ***************************************************************
+ */
+
+
+#ifndef WMESA_H
+#define WMESA_H
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#include "gl\gl.h"
+
+#pragma warning (disable:4273)
+#pragma warning( disable : 4244 ) /* '=' : conversion from 'const double ' to 'float ', possible loss of data */
+#pragma warning( disable : 4018 ) /* '<' : signed/unsigned mismatch */
+#pragma warning( disable : 4305 ) /* '=' : truncation from 'const double ' to 'float ' */
+#pragma warning( disable : 4013 ) /* 'function' undefined; assuming extern returning int */
+#pragma warning( disable : 4761 ) /* integral size mismatch in argument; conversion supplied */
+#pragma warning( disable : 4273 ) /* 'identifier' : inconsistent DLL linkage. dllexport assumed */
+#if (MESA_WARNQUIET>1)
+#      pragma warning( disable : 4146 ) /* unary minus operator applied to unsigned type, result still unsigned */
+#endif
+
+/*
+ * This is the WMesa context 'handle':
+ */
+typedef struct wmesa_context *WMesaContext;
+
+
+
+/*
+ * Create a new WMesaContext for rendering into a window.  You must
+ * have already created the window of correct visual type and with an
+ * appropriate colormap.
+ *
+ * Input:
+ *         hWnd - Window handle
+ *         Pal  - Palette to use
+ *         rgb_flag - GL_TRUE = RGB mode,
+ *                    GL_FALSE = color index mode
+ *         db_flag - GL_TRUE = double-buffered,
+ *                   GL_FALSE = single buffered
+ *
+ * Note: Indexed mode requires double buffering under Windows.
+ *
+ * Return:  a WMesa_context or NULL if error.
+ */
+extern WMesaContext WMesaCreateContext(HWND hWnd,HPALETTE* pPal,
+                                       GLboolean rgb_flag,GLboolean db_flag);
+
+
+/*
+ * Destroy a rendering context as returned by WMesaCreateContext()
+ */
+/*extern void WMesaDestroyContext( WMesaContext ctx );*/
+extern void WMesaDestroyContext( void );
+
+
+
+/*
+ * Make the specified context the current one.
+ */
+extern void WMesaMakeCurrent( WMesaContext ctx );
+
+
+/*
+ * Return a handle to the current context.
+ */
+extern WMesaContext WMesaGetCurrentContext( void );
+
+
+/*
+ * Swap the front and back buffers for the current context.  No action
+ * taken if the context is not double buffered.
+ */
+extern void WMesaSwapBuffers(void);
+
+
+/*
+ * In indexed color mode we need to know when the palette changes.
+ */
+extern void WMesaPaletteChange(HPALETTE Pal);
+
+extern void WMesaMove(void);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
+
diff --git a/include/GL/xmesa.h b/include/GL/xmesa.h
new file mode 100644 (file)
index 0000000..b25a2ac
--- /dev/null
@@ -0,0 +1,357 @@
+/* $Id: xmesa.h,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/*
+ * $Log: xmesa.h,v $
+ * Revision 1.1  1999/08/19 00:55:40  jtg
+ * Initial revision
+ *
+ * Revision 1.3  1999/02/24 22:43:27  jens
+ * Name changes to get XMesa to compile standalone inside XFree86
+ *
+ * Revision 1.2  1999/02/14 03:39:09  brianp
+ * new copyright
+ *
+ * Revision 1.1  1998/02/13 03:17:32  brianp
+ * Initial revision
+ *
+ */
+
+
+/*
+ * Mesa/X11 interface.  This header file serves as the documentation for
+ * the Mesa/X11 interface functions.
+ *
+ * Note: this interface isn't intended for user programs.  It's primarily
+ * just for implementing the pseudo-GLX interface.
+ */
+
+
+/* Sample Usage:
+
+In addition to the usual X calls to select a visual, create a colormap
+and create a window, you must do the following to use the X/Mesa interface:
+
+1. Call XMesaCreateVisual() to make an XMesaVisual from an XVisualInfo.
+
+2. Call XMesaCreateContext() to create an X/Mesa rendering context, given
+   the XMesaVisual.
+
+3. Call XMesaCreateWindowBuffer() to create an XMesaBuffer from an X window
+   and XMesaVisual.
+
+4. Call XMesaMakeCurrent() to bind the XMesaBuffer to an XMesaContext and
+   to make the context the current one.
+
+5. Make gl* calls to render your graphics.
+
+6. Use XMesaSwapBuffers() when double buffering to swap front/back buffers.
+
+7. Before the X window is destroyed, call XMesaDestroyBuffer().
+
+8. Before exiting, call XMesaDestroyVisual and XMesaDestroyContext.
+
+See the demos/xdemo.c and xmesa1.c files for examples.
+*/
+
+
+
+
+#ifndef XMESA_H
+#define XMESA_H
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#ifdef XFree86Server
+#include "xmesa_xf86.h"
+#else
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include "xmesa_x.h"
+#endif
+#include "GL/gl.h"
+
+#ifdef AMIWIN
+#include <pragmas/xlib_pragmas.h>
+extern struct Library *XLibBase;
+#endif
+
+
+#define XMESA_MAJOR_VERSION 3
+#define XMESA_MINOR_VERSION 0
+
+
+
+/*
+ * Values passed to XMesaGetString:
+ */
+#define XMESA_VERSION 1
+#define XMESA_EXTENSIONS 2
+
+
+/*
+ * Values passed to XMesaSetFXmode:
+ */
+#define XMESA_FX_WINDOW       1
+#define XMESA_FX_FULLSCREEN   2
+
+
+
+typedef struct xmesa_context *XMesaContext;
+
+typedef struct xmesa_visual *XMesaVisual;
+
+typedef struct xmesa_buffer *XMesaBuffer;
+
+
+
+
+/*
+ * Create a new X/Mesa visual.
+ * Input:  display - X11 display
+ *         visinfo - an XVisualInfo pointer
+ *         rgb_flag - GL_TRUE = RGB mode,
+ *                    GL_FALSE = color index mode
+ *         alpha_flag - alpha buffer requested?
+ *         db_flag - GL_TRUE = double-buffered,
+ *                   GL_FALSE = single buffered
+ *         stereo_flag - stereo visual?
+ *         depth_size - requested bits/depth values, or zero
+ *         stencil_size - requested bits/stencil values, or zero
+ *         accum_size - requested bits/component values, or zero
+ *         ximage_flag - GL_TRUE = use an XImage for back buffer,
+ *                       GL_FALSE = use an off-screen pixmap for back buffer
+ * Return;  a new XMesaVisual or 0 if error.
+ */
+extern XMesaVisual XMesaCreateVisual( XMesaDisplay *display,
+                                     XMesaVisualInfo visinfo,
+                                     GLboolean rgb_flag,
+                                     GLboolean alpha_flag,
+                                     GLboolean db_flag,
+                                     GLboolean stereo_flag,
+                                     GLboolean ximage_flag,
+                                     GLint depth_size,
+                                     GLint stencil_size,
+                                     GLint accum_size,
+                                     GLint level );
+
+/*
+ * Destroy an XMesaVisual, but not the associated XVisualInfo.
+ */
+extern void XMesaDestroyVisual( XMesaVisual v );
+
+
+
+/*
+ * Create a new XMesaContext for rendering into an X11 window.
+ *
+ * Input:  visual - an XMesaVisual
+ *         share_list - another XMesaContext with which to share display
+ *                      lists or NULL if no sharing is wanted.
+ * Return:  an XMesaContext or NULL if error.
+ */
+extern XMesaContext XMesaCreateContext( XMesaVisual v,
+                                       XMesaContext share_list );
+
+
+/*
+ * Destroy a rendering context as returned by XMesaCreateContext()
+ */
+extern void XMesaDestroyContext( XMesaContext c );
+
+
+/*
+ * Create an XMesaBuffer from an X window.
+ */
+extern XMesaBuffer XMesaCreateWindowBuffer( XMesaVisual v,
+                                           XMesaWindow w );
+
+
+/*
+ * Create an XMesaBuffer from an X pixmap.
+ */
+extern XMesaBuffer XMesaCreatePixmapBuffer( XMesaVisual v,
+                                           XMesaPixmap p,
+                                           XMesaColormap cmap );
+
+
+/*
+ * Destroy an XMesaBuffer, but not the corresponding window or pixmap.
+ */
+extern void XMesaDestroyBuffer( XMesaBuffer b );
+
+
+/*
+ * Return the XMesaBuffer handle which corresponds to an X drawable, if any.
+ *
+ * New in Mesa 2.3.
+ */
+extern XMesaBuffer XMesaFindBuffer( XMesaDisplay *dpy,
+                                   XMesaDrawable d );
+
+
+
+/*
+ * Bind a buffer to a context and make the context the current one.
+ */
+extern GLboolean XMesaMakeCurrent( XMesaContext c,
+                                  XMesaBuffer b );
+
+
+/*
+ * Return a handle to the current context.
+ */
+extern XMesaContext XMesaGetCurrentContext( void );
+
+
+/*
+ * Return handle to the current buffer.
+ */
+extern XMesaBuffer XMesaGetCurrentBuffer( void );
+
+
+/*
+ * Swap the front and back buffers for the given buffer.  No action is
+ * taken if the buffer is not double buffered.
+ */
+extern void XMesaSwapBuffers( XMesaBuffer b );
+
+
+/*
+ * Copy a sub-region of the back buffer to the front buffer.
+ *
+ * New in Mesa 2.6
+ */
+extern void XMesaCopySubBuffer( XMesaBuffer b,
+                               int x,
+                               int y,
+                               int width,
+                               int height );
+
+
+/*
+ * Return a pointer to the the Pixmap or XImage being used as the back
+ * color buffer of an XMesaBuffer.  This function is a way to get "under
+ * the hood" of X/Mesa so one can manipulate the back buffer directly.
+ * Input:  b - the XMesaBuffer
+ * Output:  pixmap - pointer to back buffer's Pixmap, or 0
+ *          ximage - pointer to back buffer's XImage, or NULL
+ * Return:  GL_TRUE = context is double buffered
+ *          GL_FALSE = context is single buffered
+ */
+extern GLboolean XMesaGetBackBuffer( XMesaBuffer b,
+                                    XMesaPixmap *pixmap,
+                                    XMesaImage **ximage );
+
+
+
+/*
+ * Return the depth buffer associated with an XMesaBuffer.
+ * Input:  b - the XMesa buffer handle
+ * Output:  width, height - size of buffer in pixels
+ *          bytesPerValue - bytes per depth value (2 or 4)
+ *          buffer - pointer to depth buffer values
+ * Return:  GL_TRUE or GL_FALSE to indicate success or failure.
+ *
+ * New in Mesa 2.4.
+ */
+extern GLboolean XMesaGetDepthBuffer( XMesaBuffer b,
+                                     GLint *width,
+                                     GLint *height,
+                                     GLint *bytesPerValue,
+                                     void **buffer );
+
+
+
+/*
+ * Flush/sync a context
+ */
+extern void XMesaFlush( XMesaContext c );
+
+
+
+/*
+ * Get an X/Mesa-specific string.
+ * Input:  name - either XMESA_VERSION or XMESA_EXTENSIONS
+ */
+extern const char *XMesaGetString( XMesaContext c, int name );
+
+
+
+/*
+ * Scan for XMesaBuffers whose window/pixmap has been destroyed, then free
+ * any memory used by that buffer.
+ *
+ * New in Mesa 2.3.
+ */
+extern void XMesaGarbageCollect( void );
+
+
+
+/*
+ * Return a dithered pixel value.
+ * Input:  c - XMesaContext
+ *         x, y - window coordinate
+ *         red, green, blue, alpha - color components in [0,1]
+ * Return:  pixel value
+ *
+ * New in Mesa 2.3.
+ */
+extern unsigned long XMesaDitherColor( XMesaContext xmesa,
+                                      GLint x,
+                                      GLint y,
+                                      GLfloat red,
+                                      GLfloat green,
+                                      GLfloat blue,
+                                      GLfloat alpha );
+
+
+
+/*
+ * 3Dfx Glide driver only!
+ * Set 3Dfx/Glide full-screen or window rendering mode.
+ * Input:  mode - either XMESA_FX_WINDOW (window rendering mode) or
+ *                XMESA_FX_FULLSCREEN (full-screen rendering mode)
+ * Return:  GL_TRUE if success
+ *          GL_FALSE if invalid mode or if not using 3Dfx driver
+ *
+ * New in Mesa 2.6.
+ */
+extern GLboolean XMesaSetFXmode( GLint mode );
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/include/GL/xmesa_x.h b/include/GL/xmesa_x.h
new file mode 100644 (file)
index 0000000..c9bb17a
--- /dev/null
@@ -0,0 +1,92 @@
+
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ *   Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ * $Header: /home/krh/git/sync/mesa-cvs-repo/Mesa/include/GL/xmesa_x.h,v 1.1 1999/08/19 00:55:40 jtg Exp $
+ */
+
+#ifndef _XMESA_X_H_
+#define _XMESA_X_H_
+
+typedef Display      XMesaDisplay;
+typedef Pixmap       XMesaPixmap;
+typedef Colormap     XMesaColormap;
+typedef Drawable     XMesaDrawable;
+typedef Window       XMesaWindow;
+typedef GC           XMesaGC;
+typedef XVisualInfo *XMesaVisualInfo;
+typedef XImage       XMesaImage;
+typedef XPoint       XMesaPoint;
+typedef XColor       XMesaColor;
+
+#define XMesaDestroyImage      XDestroyImage
+
+#define XMesaPutPixel          XPutPixel
+#define XMesaGetPixel          XGetPixel
+
+#define XMesaSetForeground     XSetForeground
+#define XMesaSetBackground     XSetBackground
+#define XMesaSetPlaneMask      XSetPlaneMask
+#define XMesaSetFunction       XSetFunction
+#define XMesaSetDashes         XSetDashes
+#define XMesaSetLineAttributes XSetLineAttributes
+#define XMesaSetFillStyle      XSetFillStyle
+#define XMesaSetTile           XSetTile
+#define XMesaSetStipple        XSetStipple
+
+#define XMesaDrawPoint         XDrawPoint
+#define XMesaDrawPoints        XDrawPoints
+#define XMesaDrawLine          XDrawLine
+#define XMesaFillRectangle     XFillRectangle
+#define XMesaPutImage          XPutImage
+#define XMesaCopyArea          XCopyArea
+#define XMesaFillPolygon       XFillPolygon
+
+#define XMesaCreatePixmap      XCreatePixmap
+#define XMesaFreePixmap        XFreePixmap
+#define XMesaFreeGC            XFreeGC
+
+#define GET_COLORMAP_SIZE(__v)  __v->visinfo->colormap_size
+#define GET_REDMASK(__v)        __v->visinfo->red_mask
+#define GET_GREENMASK(__v)      __v->visinfo->green_mask
+#define GET_BLUEMASK(__v)       __v->visinfo->blue_mask
+#define GET_BITS_PER_PIXEL(__v) bits_per_pixel(__v->display, __v->visinfo)
+#if defined(__cplusplus) || defined(c_plusplus)
+#define GET_VISUAL_CLASS(__v)   __v->visinfo->c_class
+#else
+#define GET_VISUAL_CLASS(__v)   __v->visinfo->class
+#endif
+#define GET_VISUAL_DEPTH(__v)   __v->visinfo->depth
+#define GET_BLACK_PIXEL(__v)    BlackPixel(__v->display, __v->visinfo->screen)
+#define CHECK_BYTE_ORDER(__v)   host_byte_order()==ImageByteOrder(__v->display)
+#define CHECK_FOR_HPCR(__v)     XInternAtom(__v->display, "_HP_RGB_SMOOTH_MAP_LIST", True)
+
+#endif
diff --git a/include/GL/xmesa_xf86.h b/include/GL/xmesa_xf86.h
new file mode 100644 (file)
index 0000000..5c1af7a
--- /dev/null
@@ -0,0 +1,189 @@
+
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ *   Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ * $Header: /home/krh/git/sync/mesa-cvs-repo/Mesa/include/GL/xmesa_xf86.h,v 1.1 1999/08/19 00:55:40 jtg Exp $
+ */
+
+#ifndef _XMESA_XF86_H_
+#define _XMESA_XF86_H_
+
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+
+typedef struct _XMesaImageRec XMesaImage;
+
+typedef ScreenRec   XMesaDisplay;
+typedef PixmapPtr   XMesaPixmap;
+typedef ColormapPtr XMesaColormap;
+typedef DrawablePtr XMesaDrawable;
+typedef WindowPtr   XMesaWindow;
+typedef GCPtr       XMesaGC;
+typedef VisualPtr   XMesaVisualInfo;
+typedef DDXPointRec XMesaPoint;
+typedef xColorItem  XMesaColor;
+
+#define XMesaSetGeneric(__d,__gc,__val,__mask) \
+{ \
+    CARD32 __v[1]; \
+    (void) __d; \
+    __v[0] = __val; \
+    dixChangeGC(NullClient, __gc, __mask, __v, NULL); \
+}
+
+#define XMesaSetGenericPtr(__d,__gc,__pval,__mask) \
+{ \
+    ChangeGCVal __v[1]; \
+    (void) __d; \
+    __v[0].ptr = __pval; \
+    dixChangeGC(NullClient, __gc, __mask, NULL, __v); \
+}
+
+#define XMesaSetDashes(__d,__gc,__do,__dl,__n) \
+{ \
+    (void) __d; \
+    SetDashes(__gc, __do, __n, (unsigned char *)__dl); \
+}
+
+#define XMesaSetLineAttributes(__d,__gc,__lw,__ls,__cs,__js) \
+{ \
+    CARD32 __v[4]; \
+    (void) __d; \
+    __v[0] = __lw; \
+    __v[1] = __ls; \
+    __v[2] = __cs; \
+    __v[3] = __js; \
+    dixChangeGC(NullClient, __gc, \
+               GCLineWidth|GCLineStyle|GCCapStyle|GCJoinStyle, \
+               __v, NULL); \
+}
+
+#define XMesaSetForeground(d,gc,v) XMesaSetGeneric(d,gc,v,GCForeground)
+#define XMesaSetBackground(d,gc,v) XMesaSetGeneric(d,gc,v,GCBackground)
+#define XMesaSetPlaneMask(d,gc,v)  XMesaSetGeneric(d,gc,v,GCPlaneMask)
+#define XMesaSetFunction(d,gc,v)   XMesaSetGeneric(d,gc,v,GCFunction)
+#define XMesaSetFillStyle(d,gc,v)  XMesaSetGeneric(d,gc,v,GCFillStyle)
+
+#define XMesaSetTile(d,gc,v)       XMesaSetGenericPtr(d,gc,v,GCTile)
+#define XMesaSetStipple(d,gc,v)    XMesaSetGenericPtr(d,gc,v,GCStipple)
+
+#define XMesaDrawPoint(__d,__b,__gc,__x,__y) \
+{ \
+    XMesaPoint __p[1]; \
+    (void) __d; \
+    __p[0].x = __x; \
+    __p[0].y = __y; \
+    ValidateGC(__b, __gc); \
+    (*gc->ops->PolyPoint)(__b, __gc, CoordModeOrigin, 1, __p); \
+}
+
+#define XMesaDrawPoints(__d,__b,__gc,__p,__n,__m) \
+{ \
+    (void) __d; \
+    ValidateGC(__b, __gc); \
+    (*gc->ops->PolyPoint)(__b, __gc, __m, __n, __p); \
+}
+
+#define XMesaDrawLine(__d,__b,__gc,__x0,__y0,__x1,__y1) \
+{ \
+    XMesaPoint __p[2]; \
+    (void) __d; \
+    ValidateGC(__b, __gc); \
+    __p[0].x = __x0; \
+    __p[0].y = __y0; \
+    __p[1].x = __x1; \
+    __p[1].y = __y1; \
+    (*__gc->ops->Polylines)(__b, __gc, CoordModeOrigin, 2, __p); \
+}
+
+#define XMesaFillRectangle(__d,__b,__gc,__x,__y,__w,__h) \
+{ \
+    xRectangle __r[1]; \
+    (void) __d; \
+    ValidateGC(__b, __gc); \
+    __r[0].x = __x; \
+    __r[0].y = __y; \
+    __r[0].width = __w; \
+    __r[0].height = __h; \
+    (*__gc->ops->PolyFillRect)(__b, __gc, 1, __r); \
+}
+
+#define XMesaPutImage(__d,__b,__gc,__i,__sx,__sy,__x,__y,__w,__h) \
+{ \
+    /* Assumes: Images are always in ZPixmap format */ \
+    (void) __d; \
+    if (__sx || __sy) /* The non-trivial case */ \
+       XMesaPutImageHelper(__d,__b,__gc,__i,__sx,__sy,__x,__y,__w,__h); \
+    ValidateGC(__b, __gc); \
+    (*__gc->ops->PutImage)(__b, __gc, ((XMesaDrawable)(__b))->depth, \
+                          __x, __y, __w, __h, 0, ZPixmap, \
+                          ((XMesaImage *)(__i))->data); \
+}
+
+#define XMesaCopyArea(__d,__sb,__db,__gc,__sx,__sy,__w,__h,__x,__y) \
+{ \
+    (void) __d; \
+    ValidateGC(__db, __gc); \
+    (*__gc->ops->CopyArea)((DrawablePtr)__sb, __db, __gc, \
+                          __sx, __sy, __w, __h, __x, __y); \
+}
+
+#define XMesaFillPolygon(__d,__b,__gc,__p,__n,__s,__m) \
+{ \
+    (void) __d; \
+    ValidateGC(__b, __gc); \
+    (*__gc->ops->FillPolygon)(__b, __gc, __s, __m, __n, __p); \
+}
+
+/* CreatePixmap returns a PixmapPtr; so, it cannot be inside braces */
+#define XMesaCreatePixmap(__d,__b,__w,__h,__depth) \
+    (*__d->CreatePixmap)(__d, __w, __h, __depth)
+#define XMesaFreePixmap(__d,__b) \
+    (*__d->DestroyPixmap)(__b)
+
+#define XMesaFreeGC(__d,__gc) \
+{ \
+    (void) __d; \
+    FreeScratchGC(__gc); \
+}
+
+#define GET_COLORMAP_SIZE(__v)  __v->visinfo->ColormapEntries
+#define GET_REDMASK(__v)        __v->visinfo->redMask
+#define GET_GREENMASK(__v)      __v->visinfo->greenMask
+#define GET_BLUEMASK(__v)       __v->visinfo->blueMask
+#define GET_BITS_PER_PIXEL(__v) __v->visinfo->bitsPerRGBValue
+#define GET_VISUAL_CLASS(__v)   __v->visinfo->class
+#define GET_VISUAL_DEPTH(__v)   __v->visinfo->nplanes
+#define GET_BLACK_PIXEL(__v)    __v->display->blackPixel
+#define CHECK_BYTE_ORDER(__v)   GL_TRUE
+#define CHECK_FOR_HPCR(__v)     GL_FALSE
+
+#endif
diff --git a/progs/beos/Makefile b/progs/beos/Makefile
new file mode 100644 (file)
index 0000000..0d9c27b
--- /dev/null
@@ -0,0 +1,42 @@
+# $Id: Makefile,v 1.1 1999/08/19 00:55:40 jtg Exp $
+
+# Makefile for BeOS demos
+
+# Written by Brian Paul
+# This file is in the public domain.
+
+
+
+CC = g++
+
+# Use Mesa:
+CFLAGS = -I../include -c -g
+LFLAGS = -L../lib  -Xlinker -rpath ../lib -lbe -lMesaGL
+
+# Use BeOS OpenGL:
+#CFLAGS = -I/boot/develop/headers/be/opengl -c -g
+#LFLAGS = -L../lib  -Xlinker -rpath ../lib -lbe -lGL
+
+
+PROGRAMS = demo sample
+
+default: $(PROGRAMS)
+
+
+clean:
+       rm -f demo sample
+       rm -f *.o
+
+
+demo: demo.o
+       $(CC) demo.o $(LFLAGS) -o $@
+
+demo.o: demo.cpp
+       $(CC) $(CFLAGS) demo.cpp
+
+
+sample: sample.o
+       $(CC) sample.o $(LFLAGS) -o $@
+
+sample.o: sample.cpp
+       $(CC) $(CFLAGS) sample.cpp
diff --git a/progs/beos/demo.cpp b/progs/beos/demo.cpp
new file mode 100644 (file)
index 0000000..c25eb93
--- /dev/null
@@ -0,0 +1,153 @@
+// $Id: demo.cpp,v 1.1 1999/08/19 00:55:40 jtg Exp $
+
+// Simple BeOS GLView demo
+// Written by Brian Paul
+// This file is in the public domain.
+
+
+
+#include <stdio.h>
+#include <Application.h>
+#include <Window.h>
+#include <GLView.h>
+
+
+class MyWindow : public BWindow
+{
+public:
+   MyWindow(BRect frame);
+   virtual bool QuitRequested();
+};
+
+
+MyWindow::MyWindow(BRect frame)
+   : BWindow(frame, "demo", B_TITLED_WINDOW, B_NOT_ZOOMABLE)
+{
+   // no-op
+}
+
+bool MyWindow::QuitRequested()
+{
+   be_app->PostMessage(B_QUIT_REQUESTED);
+   return true;
+}
+
+
+class MyGL : public BGLView
+{
+public:
+   MyGL(BRect rect, char *name, ulong options);
+
+//     virtual void AttachedToWindow();
+   virtual void Draw(BRect updateRect);
+   virtual void Pulse();
+   virtual void FrameResized(float w, float h);
+private:
+   float mAngle;
+};
+
+
+MyGL::MyGL(BRect rect, char *name, ulong options)
+   : BGLView(rect, name, B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP_BOTTOM, 0, options)
+{
+   mAngle = 0.0;
+}
+
+
+#if 0
+void MyGL::AttachedToWindow()
+{
+   BGLView::AttachedToWindow();
+   LockGL();
+   glClearColor(.7, .7, 0, 0);
+   UnlockGL();
+}
+#endif
+
+
+void MyGL::FrameResized(float w, float h)
+{
+    BGLView::FrameResized(w, h);
+
+    printf("FrameResized\n");
+    LockGL();
+    BGLView::FrameResized(w,h);
+    glViewport(0, 0, (int) (w + 1), (int) (h + 1));
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    glFrustum(-1, 1, -1, 1, 10, 30);
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
+    glTranslatef(0, 0, -18);
+    UnlockGL();
+}
+
+
+
+void MyGL::Draw(BRect r)
+{
+    printf("MyGL::Draw\n");
+    BGLView::Draw(r);
+    LockGL();
+    glClear(GL_COLOR_BUFFER_BIT);
+    glPushMatrix();
+    glRotatef(mAngle, 0, 0, 1);
+    glColor3f(0, 0, 1);
+    glBegin(GL_POLYGON);
+    glVertex2f(-1, -1);
+    glVertex2f( 1, -1);
+    glVertex2f( 1,  1);
+    glVertex2f(-1,  1);
+    glEnd();
+    SwapBuffers();
+    UnlockGL();
+}
+
+
+void MyGL::Pulse()
+{
+   printf("pulse\n");
+   BGLView::Pulse();
+   mAngle += 1.0;
+
+   LockGL();
+   glClear(GL_COLOR_BUFFER_BIT);
+   glPushMatrix();
+   glRotatef(mAngle, 0, 0, 1);
+   glColor3f(0, 0, 1);
+   glBegin(GL_POLYGON);
+   glVertex2f(-1, -1);
+   glVertex2f( 1, -1);
+   glVertex2f( 1,  1);
+   glVertex2f(-1,  1);
+   glEnd();
+   SwapBuffers();
+   UnlockGL();
+}
+
+
+
+int main(int argc, char *argv[])
+{
+   BApplication *app = new BApplication("application/demo");
+
+   // make top-level window
+   int x = 500, y = 500;
+   int w = 400, h = 400;
+   MyWindow *win = new MyWindow(BRect(x, y, x + w, y + h));
+   //  win->Lock();
+   //  win->Unlock();
+   win->Show();
+
+   // Make OpenGL view and put it in the window
+   MyGL *gl = new MyGL(BRect(5, 5, w-10, h-10), "GL", BGL_RGB | BGL_DOUBLE);
+   //  MyGL *gl = new MyGL(BRect(5, 5, w-10, h-10), "GL", BGL_RGB );
+   win->AddChild(gl);
+
+   printf("calling app->Run\n");       
+   app->Run();
+
+   delete app;
+
+   return 0;
+}
diff --git a/progs/beos/sample.cpp b/progs/beos/sample.cpp
new file mode 100644 (file)
index 0000000..2310b33
--- /dev/null
@@ -0,0 +1,212 @@
+// sample BGLView app from the Be Book
+
+
+#include <stdio.h>
+#include <Application.h>
+#include <Window.h>
+#include <GLView.h>
+
+
+class SampleGLView : public BGLView
+{
+public:
+   SampleGLView(BRect frame, uint32 type);
+   virtual void   AttachedToWindow(void);
+   virtual void   FrameResized(float newWidth, float newHeight);
+   virtual void   ErrorCallback(GLenum which);
+   
+   void         Render(void);
+   
+private:
+   void         gInit(void);
+   void         gDraw(void);
+   void         gReshape(int width, int height);
+         
+   float         width;
+   float         height;
+};
+
+
+
+class SampleGLWindow : public BWindow 
+{
+public:
+   SampleGLWindow(BRect frame, uint32 type);
+   virtual bool   QuitRequested() { return true; }
+   
+private:
+   SampleGLView   *theView;
+};
+
+
+class SampleGLApp : public BApplication
+{
+public:
+   SampleGLApp();
+private:
+   SampleGLWindow      *theWindow;
+};
+
+
+SampleGLApp::SampleGLApp()
+   : BApplication("application/x-vnd.sample")
+{
+   BRect windowRect;
+   uint32 type = BGL_RGB|BGL_DOUBLE;
+
+   windowRect.Set(50, 50, 350, 350);
+
+   theWindow = new SampleGLWindow(windowRect, type);
+}
+
+
+
+SampleGLWindow::SampleGLWindow(BRect frame, uint32 type)
+   : BWindow(frame, "OpenGL Test", B_TITLED_WINDOW, 0)
+{
+   theView = new SampleGLView(Bounds(), type);
+   AddChild(theView);
+   Show();
+   theView->Render();
+}
+
+
+
+SampleGLView::SampleGLView(BRect frame, uint32 type)
+   : BGLView(frame, "SampleGLView", B_FOLLOW_ALL_SIDES, 0, type)
+{
+   width = frame.right-frame.left;
+   height = frame.bottom-frame.top;
+}
+
+
+void SampleGLView::AttachedToWindow(void)
+{
+   LockGL();
+   BGLView::AttachedToWindow();
+   gInit();
+   gReshape(width, height);
+   UnlockGL();
+}
+
+
+void SampleGLView::FrameResized(float newWidth, float newHeight) 
+{
+   LockGL();
+   BGLView::FrameResized(width, height);
+   width = newWidth;
+   height = newHeight;
+   
+   gReshape(width,height);
+      
+   UnlockGL();
+   Render();
+}
+
+
+void SampleGLView::ErrorCallback(GLenum whichError) 
+{
+//      fprintf(stderr, "Unexpected error occured (%d):\\n", whichError);
+//      fprintf(stderr, "    %s\\n", gluErrorString(whichError));
+}
+
+
+
+// globals
+GLenum use_stipple_mode;    // GL_TRUE to use dashed lines
+GLenum use_smooth_mode;     // GL_TRUE to use anti-aliased lines
+GLint linesize;             // Line width
+GLint pointsize;            // Point diameter
+   
+float pntA[3] = {
+   -160.0, 0.0, 0.0
+};
+float pntB[3] = {
+   -130.0, 0.0, 0.0
+};
+
+
+
+void SampleGLView::gInit(void) 
+{
+   glClearColor(0.0, 0.0, 0.0, 0.0);
+   glLineStipple(1, 0xF0E0);
+   glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+   use_stipple_mode = GL_FALSE;
+   use_smooth_mode = GL_TRUE;
+   linesize = 2;
+   pointsize = 4;
+}
+
+
+
+void SampleGLView::gDraw(void)
+{
+   GLint i;
+   
+   glClear(GL_COLOR_BUFFER_BIT);
+   glLineWidth(linesize);
+   
+   if (use_stipple_mode) {
+      glEnable(GL_LINE_STIPPLE);
+   } else {
+      glDisable(GL_LINE_STIPPLE);
+   }
+   
+   if (use_smooth_mode) {
+      glEnable(GL_LINE_SMOOTH);
+      glEnable(GL_BLEND);
+   } else {
+      glDisable(GL_LINE_SMOOTH);
+      glDisable(GL_BLEND);
+   }
+   
+   glPushMatrix();
+   
+   for (i = 0; i < 360; i += 5) {
+      glRotatef(5.0, 0,0,1);         // Rotate right 5 degrees
+      glColor3f(1.0, 1.0, 0.0);      // Set color for line
+      glBegin(GL_LINE_STRIP);         // And create the line
+      glVertex3fv(pntA);
+      glVertex3fv(pntB);
+      glEnd();
+      
+      glPointSize(pointsize);         // Set size for point
+      glColor3f(0.0, 1.0, 0.0);      // Set color for point
+      glBegin(GL_POINTS);
+      glVertex3fv(pntA);         // Draw point at one end
+      glVertex3fv(pntB);         // Draw point at other end
+      glEnd();
+   }
+   
+   glPopMatrix();                  // Done with matrix
+}
+
+
+void SampleGLView::gReshape(int width, int height)
+{
+   glViewport(0, 0, width, height);
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   glOrtho(-175, 175, -175, 175, -1, 1);
+   glMatrixMode(GL_MODELVIEW);
+}
+
+
+void SampleGLView::Render(void)
+{
+   LockGL();
+   gDraw();
+   SwapBuffers();
+   UnlockGL();
+}
+
+
+
+int main(int argc, char *argv[])
+{
+   SampleGLApp *app = new SampleGLApp;
+   app->Run();
+   delete app;
+   return 0;
+}
diff --git a/progs/demos/Makefile.BeOS-R4 b/progs/demos/Makefile.BeOS-R4
new file mode 100644 (file)
index 0000000..c0d990e
--- /dev/null
@@ -0,0 +1,96 @@
+# $Id: Makefile.BeOS-R4,v 1.1 1999/08/19 00:55:40 jtg Exp $
+
+# Mesa 3-D graphics library
+# Version:  3.1
+# Copyright (C) 1995-1999  Brian Paul
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the Free
+# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+# Makefile for GLUT-based demo programs for BeOS R4
+
+
+# $Log: Makefile.BeOS-R4,v $
+# Revision 1.1  1999/08/19 00:55:40  jtg
+# Initial revision
+#
+# Revision 1.5  1999/06/22 12:50:11  brianp
+# removed multitex demo
+#
+# Revision 1.4  1999/02/03 03:57:26  brianp
+# replace multiext with multiarb
+#
+# Revision 1.3  1999/02/02 04:47:45  brianp
+# removed glutfx from targets
+#
+# Revision 1.2  1999/02/02 04:46:23  brianp
+# removed tessdemo from targets
+#
+# Revision 1.1  1999/02/02 04:43:27  brianp
+# Initial revision
+#
+
+
+
+##### MACROS #####
+
+INCDIR = ../include
+LIBDIR = ../lib
+
+GL_LIBS = -L$(LIBDIR) -L/boot/home/config/lib -Xlinker -rpath $(LIBDIR) -lbe -lglut -lMesaGLU -lMesaGL $(XLIBS)
+
+LIB_DEP = $(LIBDIR)/$(GL_LIB) $(LIBDIR)/$(GLU_LIB) $(LIBDIR)/$(GLUT_LIB)
+
+PROGS = bounce clearspd drawpix gamma gears glinfo isosurf \
+       morph3d multiarb osdemo paltex pointblast reflect \
+       renormal spectex stex3d texcyl texobj trispd winpos
+
+
+##### RULES #####
+
+.SUFFIXES:
+.SUFFIXES: .c
+
+.c: $(LIB_DEP)
+       $(CC) -I$(INCDIR) $(CFLAGS) $< $(GL_LIBS) -o $@
+
+
+
+##### TARGETS #####
+
+default:
+       @echo "Specify a target configuration"
+
+clean:
+       -rm *.o *~
+
+realclean:
+       -rm $(PROGS)
+       -rm *.o *~
+
+targets: $(PROGS)
+
+# execute all programs
+exec: $(PROGS)
+       @for prog in $(PROGS) ;                 \
+       do                                      \
+               echo -n "Running $$prog ..." ;  \
+               $$prog ;                        \
+               echo ;                          \
+       done
+
+
+include ../Make-config
+
diff --git a/progs/demos/Makefile.X11 b/progs/demos/Makefile.X11
new file mode 100644 (file)
index 0000000..9d475a6
--- /dev/null
@@ -0,0 +1,60 @@
+# $Id: Makefile.X11,v 1.1 1999/08/19 00:55:40 jtg Exp $
+
+# Mesa 3-D graphics library
+# Version:  3.1
+# Copyright (C) 1995-1998  Brian Paul
+
+
+# Makefile for GLUT-based demo programs for Unix/X11
+
+
+##### MACROS #####
+
+INCDIR = ../include
+LIBDIR = ../lib
+
+GL_LIBS = -L$(LIBDIR) -lglut -lGLU -lGL -lm $(XLIBS)
+
+LIB_DEP = $(LIBDIR)/$(GL_LIB) $(LIBDIR)/$(GLU_LIB) $(LIBDIR)/$(GLUT_LIB)
+
+PROGS = bounce clearspd drawpix gamma gears glinfo glutfx isosurf \
+       morph3d multiarb osdemo paltex pointblast reflect \
+       renormal spectex stex3d tessdemo texcyl texobj trispd winpos
+
+
+##### RULES #####
+
+.SUFFIXES:
+.SUFFIXES: .c
+
+.c: $(LIB_DEP)
+       $(CC) -I$(INCDIR) $(CFLAGS) $< $(GL_LIBS) -o $@
+
+
+
+##### TARGETS #####
+
+default:
+       @echo "Specify a target configuration"
+
+clean:
+       -rm *.o *~
+
+realclean:
+       -rm $(PROGS)
+       -rm *.o *~
+
+targets: $(PROGS)
+
+# execute all programs
+exec: $(PROGS)
+       @for prog in $(PROGS) ;                 \
+       do                                      \
+               echo -n "Running $$prog ..." ;  \
+               $$prog ;                        \
+               echo ;                          \
+       done
+
+
+include ../Make-config
+
diff --git a/progs/demos/Makefile.cygnus b/progs/demos/Makefile.cygnus
new file mode 100644 (file)
index 0000000..69012b1
--- /dev/null
@@ -0,0 +1,76 @@
+# Makefile for demo programs
+# Stephane Rehel (rehel@worldnet.fr) April 13 1997
+
+# Mesa 3-D graphics library
+# Version:  3.0
+# Copyright (C) 1995-1998  Brian Paul
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the Free
+# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+# $Id: Makefile.cygnus,v 1.1 1999/08/19 00:55:40 jtg Exp $
+
+# $Log: Makefile.cygnus,v $
+# Revision 1.1  1999/08/19 00:55:40  jtg
+# Initial revision
+#
+# Revision 3.1  1999/06/22 12:50:29  brianp
+# removed multitex demo
+#
+# Revision 3.0  1998/06/10 02:55:51  brianp
+# initial revision
+#
+
+
+##### MACROS #####
+
+INCDIR = ../include
+LIBDIR = ../lib
+
+GL_LIBS = -L$(LIBDIR) -lglut -lMesaGLU -lMesaGL -lm $(WLIBS)
+
+LIB_DEP = $(LIBDIR)/$(GL_LIB) $(LIBDIR)/$(GLU_LIB) $(LIBDIR)/$(GLUT_LIB)
+
+PROGS = clearspd drawpix gamma gears glinfo glutfx isosurf \
+       morph3d multiext osdemo paltex pointblast reflect \
+       renormal spectex stex3d tessdemo texcyl texobj trispd winpos
+
+
+##### RULES #####
+
+.SUFFIXES:
+.SUFFIXES: .c
+
+.c: $(LIB_DEP)
+       $(CC) -I$(INCDIR) $(CFLAGS) $< $(GL_LIBS) -o $@
+
+
+##### TARGETS #####
+
+default:
+       @echo "Specify a target configuration"
+
+clean:
+       -rm *.o *~
+
+realclean:
+       -rm $(PROGS:=.exe)
+       -rm *.o *~
+
+targets: $(PROGS)
+
+include ../Make-config
+
+
diff --git a/progs/demos/bounce.c b/progs/demos/bounce.c
new file mode 100644 (file)
index 0000000..876ce58
--- /dev/null
@@ -0,0 +1,240 @@
+/* $Id: bounce.c,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
+
+/*
+ * Bouncing ball demo.  Color index mode only!
+ *
+ * This program is in the public domain
+ *
+ * Brian Paul
+ */
+
+/* Conversion to GLUT by Mark J. Kilgard */
+
+/*
+ * $Log: bounce.c,v $
+ * Revision 1.1  1999/08/19 00:55:40  jtg
+ * Initial revision
+ *
+ * Revision 3.3  1999/03/18 08:16:14  joukj
+ *
+ *     cmpstr needs string.h to included to avoid warnings
+ *
+ * Revision 3.2  1998/11/28 01:13:02  brianp
+ * now sets an initial window position and size
+ *
+ * Revision 3.1  1998/11/28 01:06:57  brianp
+ * now works in RGB mode by default
+ *
+ * Revision 3.0  1998/02/14 18:42:29  brianp
+ * initial rev
+ *
+ */
+
+
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include <GL/glut.h>
+
+#define COS(X)   cos( (X) * 3.14159/180.0 )
+#define SIN(X)   sin( (X) * 3.14159/180.0 )
+
+#define RED 1
+#define WHITE 2
+#define CYAN 3
+
+GLboolean IndexMode = GL_FALSE;
+GLuint Ball;
+GLenum Mode;
+GLfloat Zrot = 0.0, Zstep = 6.0;
+GLfloat Xpos = 0.0, Ypos = 1.0;
+GLfloat Xvel = 0.2, Yvel = 0.0;
+GLfloat Xmin = -4.0, Xmax = 4.0;
+GLfloat Ymin = -3.8, Ymax = 4.0;
+GLfloat G = -0.1;
+
+static GLuint 
+make_ball(void)
+{
+  GLuint list;
+  GLfloat a, b;
+  GLfloat da = 18.0, db = 18.0;
+  GLfloat radius = 1.0;
+  GLuint color;
+  GLfloat x, y, z;
+
+  list = glGenLists(1);
+
+  glNewList(list, GL_COMPILE);
+
+  color = 0;
+  for (a = -90.0; a + da <= 90.0; a += da) {
+
+    glBegin(GL_QUAD_STRIP);
+    for (b = 0.0; b <= 360.0; b += db) {
+
+      if (color) {
+       glIndexi(RED);
+        glColor3f(1, 0, 0);
+      } else {
+       glIndexi(WHITE);
+        glColor3f(1, 1, 1);
+      }
+
+      x = COS(b) * COS(a);
+      y = SIN(b) * COS(a);
+      z = SIN(a);
+      glVertex3f(x, y, z);
+
+      x = radius * COS(b) * COS(a + da);
+      y = radius * SIN(b) * COS(a + da);
+      z = radius * SIN(a + da);
+      glVertex3f(x, y, z);
+
+      color = 1 - color;
+    }
+    glEnd();
+
+  }
+
+  glEndList();
+
+  return list;
+}
+
+static void 
+reshape(int width, int height)
+{
+  float aspect = (float) width / (float) height;
+  glViewport(0, 0, (GLint) width, (GLint) height);
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+  glOrtho(-6.0 * aspect, 6.0 * aspect, -6.0, 6.0, -6.0, 6.0);
+  glMatrixMode(GL_MODELVIEW);
+}
+
+/* ARGSUSED1 */
+static void
+key(unsigned char k, int x, int y)
+{
+  switch (k) {
+  case 27:  /* Escape */
+    exit(0);
+  }
+}
+
+static void 
+draw(void)
+{
+  GLint i;
+
+  glClear(GL_COLOR_BUFFER_BIT);
+
+  glIndexi(CYAN);
+  glColor3f(0, 1, 1);
+  glBegin(GL_LINES);
+  for (i = -5; i <= 5; i++) {
+    glVertex2i(i, -5);
+    glVertex2i(i, 5);
+  }
+  for (i = -5; i <= 5; i++) {
+    glVertex2i(-5, i);
+    glVertex2i(5, i);
+  }
+  for (i = -5; i <= 5; i++) {
+    glVertex2i(i, -5);
+    glVertex2f(i * 1.15, -5.9);
+  }
+  glVertex2f(-5.3, -5.35);
+  glVertex2f(5.3, -5.35);
+  glVertex2f(-5.75, -5.9);
+  glVertex2f(5.75, -5.9);
+  glEnd();
+
+  glPushMatrix();
+  glTranslatef(Xpos, Ypos, 0.0);
+  glScalef(2.0, 2.0, 2.0);
+  glRotatef(8.0, 0.0, 0.0, 1.0);
+  glRotatef(90.0, 1.0, 0.0, 0.0);
+  glRotatef(Zrot, 0.0, 0.0, 1.0);
+
+  glCallList(Ball);
+
+  glPopMatrix();
+
+  glFlush();
+  glutSwapBuffers();
+}
+
+static void 
+idle(void)
+{
+  static float vel0 = -100.0;
+
+  Zrot += Zstep;
+
+  Xpos += Xvel;
+  if (Xpos >= Xmax) {
+    Xpos = Xmax;
+    Xvel = -Xvel;
+    Zstep = -Zstep;
+  }
+  if (Xpos <= Xmin) {
+    Xpos = Xmin;
+    Xvel = -Xvel;
+    Zstep = -Zstep;
+  }
+  Ypos += Yvel;
+  Yvel += G;
+  if (Ypos < Ymin) {
+    Ypos = Ymin;
+    if (vel0 == -100.0)
+      vel0 = fabs(Yvel);
+    Yvel = vel0;
+  }
+  glutPostRedisplay();
+}
+
+void 
+visible(int vis)
+{
+  if (vis == GLUT_VISIBLE)
+    glutIdleFunc(idle);
+  else
+    glutIdleFunc(NULL);
+}
+
+int main(int argc, char *argv[])
+{
+  glutInit(&argc, argv);
+  glutInitWindowPosition(0, 0);
+  glutInitWindowSize(600, 450);
+
+
+  IndexMode = argc > 1 && strcmp(argv[1], "-ci") == 0;
+  if (IndexMode)
+     glutInitDisplayMode(GLUT_INDEX | GLUT_DOUBLE);
+  else
+     glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
+
+  glutCreateWindow("Bounce");
+  Ball = make_ball();
+  glCullFace(GL_BACK);
+  glEnable(GL_CULL_FACE);
+  glDisable(GL_DITHER);
+  glShadeModel(GL_FLAT);
+
+  glutDisplayFunc(draw);
+  glutReshapeFunc(reshape);
+  glutVisibilityFunc(visible);
+  glutKeyboardFunc(key);
+
+  if (IndexMode) {
+    glutSetColor(RED, 1.0, 0.0, 0.0);
+    glutSetColor(WHITE, 1.0, 1.0, 1.0);
+    glutSetColor(CYAN, 0.0, 1.0, 1.0);
+  }
+
+  glutMainLoop();
+  return 0;             /* ANSI C requires main to return int. */
+}
diff --git a/progs/demos/clearspd.c b/progs/demos/clearspd.c
new file mode 100644 (file)
index 0000000..b2edf32
--- /dev/null
@@ -0,0 +1,221 @@
+/* $Id: clearspd.c,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
+
+/*
+ * Simple GLUT program to measure glClear() and glutSwapBuffers() speed.
+ * Brian Paul  February 15, 1997  This file in public domain.
+ */
+
+/*
+ * $Log: clearspd.c,v $
+ * Revision 1.1  1999/08/19 00:55:40  jtg
+ * Initial revision
+ *
+ * Revision 3.3  1999/03/28 18:18:33  brianp
+ * minor clean-up
+ *
+ * Revision 3.2  1999/03/18 08:16:34  joukj
+ *
+ *     cmpstr needs string.h to included to avoid warnings
+ *
+ * Revision 3.1  1998/06/29 02:38:30  brianp
+ * removed unneeded includes
+ *
+ * Revision 3.0  1998/02/14 18:42:29  brianp
+ * initial rev
+ *
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+#include <GL/glut.h>
+
+
+static float MinPeriod = 2.0;   /* 2 seconds */
+static int ColorMode = GLUT_RGB;
+static int Width = 400.0;
+static int Height = 400.0;
+static int Loops = 100;
+static float ClearColor = 0.0;
+static GLbitfield BufferMask = GL_COLOR_BUFFER_BIT;
+static GLboolean SwapFlag = GL_FALSE;
+
+
+
+static void Idle( void )
+{
+   glutPostRedisplay();
+}
+
+
+static void Display( void )
+{
+   double t0, t1;
+   double clearRate;
+   double pixelRate;
+   int i;
+
+   glClearColor( ClearColor, ClearColor, ClearColor, 0.0 );
+   ClearColor += 0.1;
+   if (ClearColor>1.0)
+      ClearColor = 0.0;
+
+   if (SwapFlag) {
+      t0 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
+      for (i=0;i<Loops;i++) {
+         glClear( BufferMask );
+         glutSwapBuffers();
+      }
+      t1 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
+   }
+   else {
+      t0 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
+      for (i=0;i<Loops;i++) {
+         glClear( BufferMask );
+      }
+      t1 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
+      glutSwapBuffers();
+   }
+
+   if (t1-t0 < MinPeriod) {
+      /* Next time do more clears to get longer elapsed time */
+      Loops *= 2;
+      return;
+   }
+
+   clearRate = Loops / (t1-t0);
+   pixelRate = clearRate * Width * Height;
+   if (SwapFlag) {
+      printf("Rate: %d clears+swaps in %gs = %g clears+swaps/s   %d pixels/s\n",
+             Loops, t1-t0, clearRate, (int)pixelRate );
+   }
+   else {
+      printf("Rate: %d clears in %gs = %g clears/s   %d pixels/s\n",
+             Loops, t1-t0, clearRate, (int)pixelRate);
+   }
+}
+
+
+static void Reshape( int width, int height )
+{
+   Width = width;
+   Height = height;
+   glViewport( 0, 0, width, height );
+   glMatrixMode( GL_PROJECTION );
+   glLoadIdentity();
+   glOrtho(0.0, width, 0.0, height, -1.0, 1.0);
+   glMatrixMode( GL_MODELVIEW );
+   glLoadIdentity();
+}
+
+
+static void Key( unsigned char key, int x, int y )
+{
+   (void) x;
+   (void) y;
+   switch (key) {
+      case 27:
+         exit(0);
+         break;
+   }
+   glutPostRedisplay();
+}
+
+
+static void Init( int argc, char *argv[] )
+{
+   int i;
+   for (i=1; i<argc; i++) {
+      if (strcmp(argv[i],"+rgb")==0)
+         ColorMode = GLUT_RGB;
+      else if (strcmp(argv[i],"+ci")==0)
+         ColorMode = GLUT_INDEX;
+      else if (strcmp(argv[i],"-color")==0)
+         BufferMask = 0;
+      else if (strcmp(argv[i],"+depth")==0)
+         BufferMask |= GL_DEPTH_BUFFER_BIT;
+      else if (strcmp(argv[i],"+alpha")==0)
+         ColorMode = GLUT_RGB | GLUT_ALPHA;
+      else if (strcmp(argv[i],"+stencil")==0)
+         BufferMask |= GL_STENCIL_BUFFER_BIT;
+      else if (strcmp(argv[i],"+accum")==0)
+         BufferMask |= GL_ACCUM_BUFFER_BIT;
+      else if (strcmp(argv[i],"-width")==0) {
+         Width = atoi(argv[i+1]);
+         i++;
+      }
+      else if (strcmp(argv[i],"-height")==0) {
+         Height = atoi(argv[i+1]);
+         i++;
+      }
+      else if (strcmp(argv[i],"+swap")==0) {
+         SwapFlag = GL_TRUE;
+      }
+      else if (strcmp(argv[i],"-swap")==0) {
+         SwapFlag = GL_FALSE;
+      }
+      else
+         printf("Unknown option: %s\n", argv[i]);
+   }
+
+   if (ColorMode & GLUT_ALPHA)
+      printf("Mode:  RGB + Alpha\n");
+   else if (ColorMode==GLUT_RGB)
+      printf("Mode:  RGB\n");
+   else
+      printf("Mode:  Color Index\n");
+   printf("SwapBuffers: %s\n", SwapFlag ? "yes" : "no" );
+   printf("Size: %d x %d\n", Width, Height);
+   printf("Buffers: ");
+   if (BufferMask & GL_COLOR_BUFFER_BIT)  printf("color ");
+   if (BufferMask & GL_DEPTH_BUFFER_BIT)  printf("depth ");
+   if (BufferMask & GL_STENCIL_BUFFER_BIT)  printf("stencil ");
+   if (BufferMask & GL_ACCUM_BUFFER_BIT)  printf("accum ");
+   printf("\n");
+}
+
+
+static void Help( const char *program )
+{
+   printf("%s options:\n", program);
+   printf("  +rgb       RGB mode\n");
+   printf("  +ci        color index mode\n");
+   printf("  -color     don't clear color buffer\n");
+   printf("  +alpha     clear alpha buffer\n");
+   printf("  +depth     clear depth buffer\n");
+   printf("  +stencil   clear stencil buffer\n");
+   printf("  +accum     clear accum buffer\n");
+   printf("  +swap      also do SwapBuffers\n");
+   printf("  -swap      don't do SwapBuffers\n");
+}
+
+
+int main( int argc, char *argv[] )
+{
+   printf("For options:  %s -help\n", argv[0]);
+
+   Init( argc, argv );
+
+   glutInit( &argc, argv );
+   glutInitWindowSize( (int) Width, (int) Height );
+   glutInitWindowPosition( 0, 0 );
+
+   glutInitDisplayMode( ColorMode | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL | GLUT_ACCUM );
+
+   glutCreateWindow( argv[0] );
+
+   if (argc==2 && strcmp(argv[1],"-help")==0) {
+      Help(argv[0]);
+      return 0;
+   }
+
+   glutReshapeFunc( Reshape );
+   glutKeyboardFunc( Key );
+   glutDisplayFunc( Display );
+   glutIdleFunc( Idle );
+
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/demos/descrip.mms b/progs/demos/descrip.mms
new file mode 100644 (file)
index 0000000..a705f17
--- /dev/null
@@ -0,0 +1,63 @@
+# Makefile for GLUT-based demo programs for VMS
+# contributed by Jouk Jansen  joukj@crys.chem.uva.nl
+
+
+.first
+       define gl [-.include.gl]
+
+.include [-]mms-config.
+
+##### MACROS #####
+
+INCDIR = [-.include]
+CFLAGS = /include=$(INCDIR)/prefix=all
+
+.ifdef SHARE
+GL_LIBS = $(XLIBS)
+.else
+GL_LIBS = [-.lib]libGLUT/l,libMesaGLU/l,libMesaGL/l,$(XLIBS)
+.endif
+
+LIB_DEP = [-.lib]$(GL_LIB) [-.lib]$(GLU_LIB) [-.lib]$(GLUT_LIB)
+
+PROGS = bounce.exe;,clearspd.exe;,drawpix.exe;,gamma.exe;,gears.exe;,\
+       glinfo.exe;,glutfx.exe;,isosurf.exe;,morph3d.exe;,osdemo.exe;,\
+       paltex.exe;,pointblast.exe;,reflect.exe;,spectex.exe;,stex3d.exe;,\
+       tessdemo.exe;,texcyl.exe;,texobj.exe;,trispd.exe;,winpos.exe;
+
+
+##### RULES #####
+.obj.exe :
+       link $(MMS$TARGET_NAME),$(GL_LIBS)
+
+##### TARGETS #####
+default :
+       $(MMS)$(MMSQUALIFIERS) $(PROGS)
+
+clean :
+       delete *.obj;*
+
+realclean :
+       delete $(PROGS)
+       delete *.obj;*
+
+bounce.exe; : bounce.obj $(LIB_DEP)
+clearspd.exe; : clearspd.obj $(LIB_DEP)
+drawpix.exe; : drawpix.obj $(LIB_DEP)
+gamma.exe; : gamma.obj $(LIB_DEP)
+gears.exe; : gears.obj $(LIB_DEP)
+glinfo.exe; : glinfo.obj $(LIB_DEP)
+glutfx.exe; : glutfx.obj $(LIB_DEP)
+isosurf.exe; : isosurf.obj $(LIB_DEP)
+morph3d.exe; : morph3d.obj $(LIB_DEP)
+osdemo.exe; : osdemo.obj $(LIB_DEP)
+paltex.exe; : paltex.obj $(LIB_DEP)
+pointblast.exe; : pointblast.obj $(LIB_DEP)
+reflect.exe; : reflect.obj $(LIB_DEP)
+spectex.exe; : spectex.obj $(LIB_DEP)
+stex3d.exe; : stex3d.obj $(LIB_DEP)
+tessdemo.exe; : tessdemo.obj $(LIB_DEP)
+texcyl.exe; : texcyl.obj $(LIB_DEP)
+texobj.exe; : texobj.obj $(LIB_DEP)
+trispd.exe; : trispd.obj $(LIB_DEP)
+winpos.exe; : winpos.obj $(LIB_DEP)
diff --git a/progs/demos/drawpix.c b/progs/demos/drawpix.c
new file mode 100644 (file)
index 0000000..264df71
--- /dev/null
@@ -0,0 +1,307 @@
+/* $Id: drawpix.c,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
+
+/*
+ * glDrawPixels demo/test/benchmark
+ * 
+ * Brian Paul   September 25, 1997  This file is in the public domain.
+ */
+
+/*
+ * $Log: drawpix.c,v $
+ * Revision 1.1  1999/08/19 00:55:40  jtg
+ * Initial revision
+ *
+ * Revision 3.3  1999/03/28 18:18:33  brianp
+ * minor clean-up
+ *
+ * Revision 3.2  1998/11/05 04:34:04  brianp
+ * moved image files to ../images/ directory
+ *
+ * Revision 3.1  1998/02/22 16:43:17  brianp
+ * added a few casts to silence compiler warnings
+ *
+ * Revision 3.0  1998/02/14 18:42:29  brianp
+ * initial rev
+ *
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <GL/glut.h>
+
+#include "../util/readtex.c"  /* a hack, I know */
+
+#define IMAGE_FILE "../images/girl.rgb"
+
+static int ImgWidth, ImgHeight;
+static GLenum ImgFormat;
+static GLubyte *Image = NULL;
+
+static int Xpos, Ypos;
+static int SkipPixels, SkipRows;
+static int DrawWidth, DrawHeight;
+static int Scissor = 0;
+static float Xzoom, Yzoom;
+
+
+
+static void Reset( void )
+{
+   Xpos = Ypos = 20;
+   DrawWidth = ImgWidth;
+   DrawHeight = ImgHeight;
+   SkipPixels = SkipRows = 0;
+   Scissor = 0;
+   Xzoom = Yzoom = 1.0;
+}
+
+
+static void Display( void )
+{
+   glClear( GL_COLOR_BUFFER_BIT );
+
+#if 0
+   glRasterPos2i(Xpos, Ypos);
+#else
+   /* This allows negative raster positions: */
+   glRasterPos2i(0, 0);
+   glBitmap(0, 0, 0, 0, Xpos, Ypos, NULL);
+#endif
+
+   glPixelStorei(GL_UNPACK_SKIP_PIXELS, SkipPixels);
+   glPixelStorei(GL_UNPACK_SKIP_ROWS, SkipRows);
+
+   glPixelZoom( Xzoom, Yzoom );
+
+   if (Scissor)
+      glEnable(GL_SCISSOR_TEST);
+
+   glDrawPixels(DrawWidth, DrawHeight, ImgFormat, GL_UNSIGNED_BYTE, Image);
+
+   glDisable(GL_SCISSOR_TEST);
+
+   glutSwapBuffers();
+}
+
+
+static void Benchmark( void )
+{
+   int startTime, endTime;
+   int draws = 500;
+   double seconds, pixelsPerSecond;
+
+   printf("Benchmarking...\n");
+   /* GL set-up */
+   glPixelStorei(GL_UNPACK_SKIP_PIXELS, SkipPixels);
+   glPixelStorei(GL_UNPACK_SKIP_ROWS, SkipRows);
+   glPixelZoom( Xzoom, Yzoom );
+   if (Scissor)
+      glEnable(GL_SCISSOR_TEST);
+
+   /* Run timing test */
+   draws = 0;
+   startTime = glutGet(GLUT_ELAPSED_TIME);
+   do {
+      glDrawPixels(DrawWidth, DrawHeight, ImgFormat, GL_UNSIGNED_BYTE, Image);
+      draws++;
+      endTime = glutGet(GLUT_ELAPSED_TIME);
+   } while (endTime - startTime < 4000);   /* 4 seconds */
+
+   /* GL clean-up */
+   glDisable(GL_SCISSOR_TEST);
+
+   /* Results */
+   seconds = (double) (endTime - startTime) / 1000.0;
+   pixelsPerSecond = draws * DrawWidth * DrawHeight / seconds;
+   printf("Result:  %d draws in %f seconds = %f pixels/sec\n",
+          draws, seconds, pixelsPerSecond);
+}
+
+
+static void Reshape( int width, int height )
+{
+   glViewport( 0, 0, width, height );
+   glMatrixMode( GL_PROJECTION );
+   glLoadIdentity();
+   glOrtho( 0.0, width, 0.0, height, -1.0, 1.0 );
+   glMatrixMode( GL_MODELVIEW );
+   glLoadIdentity();
+
+   glScissor(width/4, height/4, width/2, height/2);
+}
+
+
+static void Key( unsigned char key, int x, int y )
+{
+   (void) x;
+   (void) y;
+   switch (key) {
+      case ' ':
+         Reset();
+         break;
+      case 'w':
+         if (DrawWidth > 0)
+            DrawWidth--;
+         break;
+      case 'W':
+         DrawWidth++;
+         break;
+      case 'h':
+         if (DrawHeight > 0)
+            DrawHeight--;
+         break;
+      case 'H':
+         DrawHeight++;
+         break;
+      case 'p':
+         if (SkipPixels > 0)
+             SkipPixels--;
+         break;
+      case 'P':
+         SkipPixels++;
+         break;
+      case 'r':
+         if (SkipRows > 0)
+             SkipRows--;
+         break;
+      case 'R':
+         SkipRows++;
+         break;
+      case 's':
+         Scissor = !Scissor;
+         break;
+      case 'x':
+         Xzoom -= 0.1;
+         break;
+      case 'X':
+         Xzoom += 0.1;
+         break;
+      case 'y':
+         Yzoom -= 0.1;
+         break;
+      case 'Y':
+         Yzoom += 0.1;
+         break;
+      case 'b':
+         Benchmark();
+         break;
+      case 27:
+         exit(0);
+         break;
+   }
+   glutPostRedisplay();
+}
+
+
+static void SpecialKey( int key, int x, int y )
+{
+   (void) x;
+   (void) y;
+   switch (key) {
+      case GLUT_KEY_UP:
+         Ypos += 1;
+         break;
+      case GLUT_KEY_DOWN:
+         Ypos -= 1;
+         break;
+      case GLUT_KEY_LEFT:
+         Xpos -= 1;
+         break;
+      case GLUT_KEY_RIGHT:
+         Xpos += 1;
+         break;
+   }
+   glutPostRedisplay();
+}
+
+
+static void Init( GLboolean ciMode )
+{
+   printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
+   printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
+
+   Image = LoadRGBImage( IMAGE_FILE, &ImgWidth, &ImgHeight, &ImgFormat );
+   if (!Image) {
+      printf("Couldn't read %s\n", IMAGE_FILE);
+      exit(0);
+   }
+
+   if (ciMode) {
+      /* Convert RGB image to grayscale */
+      GLubyte *indexImage = malloc( ImgWidth * ImgHeight );
+      GLint i;
+      for (i=0; i<ImgWidth*ImgHeight; i++) {
+         int gray = Image[i*3] + Image[i*3+1] + Image[i*3+2];
+         indexImage[i] = gray / 3;
+      }
+      free(Image);
+      Image = indexImage;
+      ImgFormat = GL_COLOR_INDEX;
+
+      for (i=0;i<255;i++) {
+         float g = i / 255.0;
+         glutSetColor(i, g, g, g);
+      }
+   }
+
+   printf("Loaded %d by %d image\n", ImgWidth, ImgHeight );
+
+   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+   glPixelStorei(GL_UNPACK_ROW_LENGTH, ImgWidth);
+
+   Reset();
+}
+
+
+static void Usage(void)
+{
+   printf("Keys:\n");
+   printf("       SPACE  Reset\n");
+   printf("     Up/Down  Move image up/down\n");
+   printf("  Left/Right  Move image left/right\n");
+   printf("           w  Decrease glDrawPixels width\n");
+   printf("           W  Increase glDrawPixels width\n");
+   printf("           h  Decrease glDrawPixels height\n");
+   printf("           H  Increase glDrawPixels height\n");
+   printf("           p  Decrease GL_UNPACK_SKIP_PIXELS\n");
+   printf("           P  Increase GL_UNPACK_SKIP_PIXELS\n");
+   printf("           r  Decrease GL_UNPACK_SKIP_ROWS\n");
+   printf("           R  Increase GL_UNPACK_SKIP_ROWS\n");
+   printf("           s  Toggle GL_SCISSOR_TEST\n");
+   printf("           b  Benchmark test\n");
+   printf("         ESC  Exit\n");
+}
+
+
+int main( int argc, char *argv[] )
+{
+   GLboolean ciMode = GL_FALSE;
+
+   if (argc > 1 && strcmp(argv[1], "-ci")==0) {
+      ciMode = GL_TRUE;
+   }
+
+   glutInit( &argc, argv );
+   glutInitWindowPosition( 0, 0 );
+   glutInitWindowSize( 500, 400 );
+
+   if (ciMode)
+      glutInitDisplayMode( GLUT_INDEX | GLUT_DOUBLE );
+   else
+      glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
+
+   glutCreateWindow(argv[0]);
+
+   Init(ciMode);
+   Usage();
+
+   glutReshapeFunc( Reshape );
+   glutKeyboardFunc( Key );
+   glutSpecialFunc( SpecialKey );
+   glutDisplayFunc( Display );
+
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/demos/gamma.c b/progs/demos/gamma.c
new file mode 100644 (file)
index 0000000..a3b0bd8
--- /dev/null
@@ -0,0 +1,176 @@
+
+/* $Id: gamma.c,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
+
+/* Draw test patterns to help determine correct gamma value for a display.
+   When the intensities of the inner squares nearly match the intensities
+   of their frames (from some distance the borders should disappear) then
+   you've found the right gamma value.
+
+   You can set Mesa's gamma values (for red, green and blue) with the
+   MESA_GAMMA environment variable.  But only on X windows!
+   For example:
+        setenv MESA_GAMMA 1.5 1.6 1.4
+   Sets the red gamma value to 1.5, green to 1.6 and blue to 1.4.
+   See the main README file for more information.
+
+   For more info about gamma correction see:
+   http://www.inforamp.net/~poynton/notes/colour_and_gamma/GammaFAQ.html
+
+   This program is in the public domain
+
+   Brian Paul  19 Oct 1995
+   Kai Schuetz 05 Jun 1999 */
+
+/* Conversion to GLUT by Mark J. Kilgard */
+
+/*
+ * $Log: gamma.c,v $
+ * Revision 1.1  1999/08/19 00:55:40  jtg
+ * Initial revision
+ *
+ * Revision 3.1  1999/06/19 01:35:38  brianp
+ * merged in Kai Schuetz's RGB changes
+ *
+ * Revision 3.0  1998/02/14 18:42:29  brianp
+ * initial rev
+ *
+ */
+
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <GL/glut.h>
+
+static void
+Reshape(int width, int height)
+{
+  glViewport(0, 0, (GLint) width, (GLint) height);
+
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+  glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
+  glMatrixMode(GL_MODELVIEW);
+  glShadeModel(GL_FLAT);
+}
+
+/* ARGSUSED1 */
+static void
+key_esc(unsigned char key, int x, int y)
+{
+  if(key == 27) exit(0);  /* Exit on Escape */
+}
+
+static GLubyte p25[] = {
+  0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00,
+  0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00,
+  0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00,
+  0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00,
+  0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00,
+  0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00,
+  0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00,
+  0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00,
+  0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00,
+  0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00,
+  0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00,
+  0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00,
+  0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00,
+  0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00,
+  0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00,
+  0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00,
+};
+
+static GLubyte p50[] = {
+  0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
+  0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
+  0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
+  0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
+  0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
+  0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
+  0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
+  0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
+  0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
+  0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
+  0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
+  0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
+  0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
+  0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
+  0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
+  0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
+};
+
+static GLubyte p75[] = {
+  0xaa, 0xaa, 0xaa, 0xaa, 0xff, 0xff, 0xff, 0xff,
+  0xaa, 0xaa, 0xaa, 0xaa, 0xff, 0xff, 0xff, 0xff,
+  0xaa, 0xaa, 0xaa, 0xaa, 0xff, 0xff, 0xff, 0xff,
+  0xaa, 0xaa, 0xaa, 0xaa, 0xff, 0xff, 0xff, 0xff,
+  0xaa, 0xaa, 0xaa, 0xaa, 0xff, 0xff, 0xff, 0xff,
+  0xaa, 0xaa, 0xaa, 0xaa, 0xff, 0xff, 0xff, 0xff,
+  0xaa, 0xaa, 0xaa, 0xaa, 0xff, 0xff, 0xff, 0xff,
+  0xaa, 0xaa, 0xaa, 0xaa, 0xff, 0xff, 0xff, 0xff,
+  0xaa, 0xaa, 0xaa, 0xaa, 0xff, 0xff, 0xff, 0xff,
+  0xaa, 0xaa, 0xaa, 0xaa, 0xff, 0xff, 0xff, 0xff,
+  0xaa, 0xaa, 0xaa, 0xaa, 0xff, 0xff, 0xff, 0xff,
+  0xaa, 0xaa, 0xaa, 0xaa, 0xff, 0xff, 0xff, 0xff,
+  0xaa, 0xaa, 0xaa, 0xaa, 0xff, 0xff, 0xff, 0xff,
+  0xaa, 0xaa, 0xaa, 0xaa, 0xff, 0xff, 0xff, 0xff,
+  0xaa, 0xaa, 0xaa, 0xaa, 0xff, 0xff, 0xff, 0xff,
+  0xaa, 0xaa, 0xaa, 0xaa, 0xff, 0xff, 0xff, 0xff,
+};
+
+static GLubyte *stippletab[4] = {NULL, p25, p50, p75};
+
+static void
+gamma_ramp(GLfloat yoffs, GLfloat r, GLfloat g, GLfloat b)
+{
+  GLint d;
+
+  glColor3f(0.0, 0.0, 0.0);     /* solid black, no stipple */
+  glRectf(-1.0, yoffs, -0.6, yoffs + 0.5);
+
+  for(d = 1; d < 4; d++) {  /* increasing density from 25% to 75% */
+    GLfloat xcoord = (-1.0 + d*0.4);
+
+    glColor3f(r*d / 5.0, g*d / 5.0, b*d / 5.0); /* draw outer rect */
+    glRectf(xcoord, yoffs, xcoord+0.4, yoffs + 0.5);
+
+    glColor3f(0.0, 0.0, 0.0);   /* "clear" inner rect */
+    glRectf(xcoord + 0.1, yoffs + 0.125, xcoord + 0.3, yoffs + 0.375);
+
+    glColor3f(r, g, b);         /* draw stippled inner rect */
+    glEnable(GL_POLYGON_STIPPLE);
+    glPolygonStipple(stippletab[d]);
+    glRectf(xcoord + 0.1, yoffs + 0.125, xcoord + 0.3, yoffs + 0.375);
+    glDisable(GL_POLYGON_STIPPLE);
+  }
+  glColor3f(r, g, b);           /* solid color, no stipple */
+  glRectf(0.6, yoffs, 1.0, yoffs + 0.5);
+}
+
+static void
+display(void)
+{
+  gamma_ramp( 0.5, 1.0, 1.0, 1.0); /* white ramp */
+  gamma_ramp( 0.0, 1.0, 0.0, 0.0); /* red ramp */
+  gamma_ramp(-0.5, 0.0, 1.0, 0.0); /* green ramp */
+  gamma_ramp(-1.0, 0.0, 0.0, 1.0); /* blue ramp */
+  glFlush();
+}
+
+int
+main(int argc, char **argv)
+{
+  glutInit(&argc, argv);
+  glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
+
+  glutInitWindowPosition(50, 50);
+  glutInitWindowSize(500, 400);
+
+  glutCreateWindow("gamma test patterns");
+  glutReshapeFunc(Reshape);
+  glutDisplayFunc(display);
+  glutKeyboardFunc(key_esc);
+
+  glutMainLoop();
+  return 0;             /* ANSI C requires main to return int. */
+}
diff --git a/progs/demos/gears.c b/progs/demos/gears.c
new file mode 100644 (file)
index 0000000..8d99a8d
--- /dev/null
@@ -0,0 +1,356 @@
+/* $Id: gears.c,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
+
+/*
+ * 3-D gear wheels.  This program is in the public domain.
+ *
+ * Brian Paul
+ */
+
+/* Conversion to GLUT by Mark J. Kilgard */
+
+/*
+ * $Log: gears.c,v $
+ * Revision 1.1  1999/08/19 00:55:40  jtg
+ * Initial revision
+ *
+ * Revision 3.2  1999/06/03 17:07:36  brianp
+ * an extra quad was being drawn in front and back faces
+ *
+ * Revision 3.1  1998/11/03 02:49:10  brianp
+ * added fps output
+ *
+ * Revision 3.0  1998/02/14 18:42:29  brianp
+ * initial rev
+ *
+ */
+
+
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <GL/glut.h>
+
+#ifndef M_PI
+#define M_PI 3.14159265
+#endif
+
+static GLint T0 = 0;
+static GLint Frames = 0;
+
+
+/**
+
+  Draw a gear wheel.  You'll probably want to call this function when
+  building a display list since we do a lot of trig here.
+  Input:  inner_radius - radius of hole at center
+          outer_radius - radius at center of teeth
+          width - width of gear
+          teeth - number of teeth
+          tooth_depth - depth of tooth
+
+ **/
+
+static void
+gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
+  GLint teeth, GLfloat tooth_depth)
+{
+  GLint i;
+  GLfloat r0, r1, r2;
+  GLfloat angle, da;
+  GLfloat u, v, len;
+
+  r0 = inner_radius;
+  r1 = outer_radius - tooth_depth / 2.0;
+  r2 = outer_radius + tooth_depth / 2.0;
+
+  da = 2.0 * M_PI / teeth / 4.0;
+
+  glShadeModel(GL_FLAT);
+
+  glNormal3f(0.0, 0.0, 1.0);
+
+  /* draw front face */
+  glBegin(GL_QUAD_STRIP);
+  for (i = 0; i <= teeth; i++) {
+    angle = i * 2.0 * M_PI / teeth;
+    glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
+    glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
+    if (i < teeth) {
+      glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
+      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
+    }
+  }
+  glEnd();
+
+  /* draw front sides of teeth */
+  glBegin(GL_QUADS);
+  da = 2.0 * M_PI / teeth / 4.0;
+  for (i = 0; i < teeth; i++) {
+    angle = i * 2.0 * M_PI / teeth;
+
+    glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
+    glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
+    glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5);
+    glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
+  }
+  glEnd();
+
+  glNormal3f(0.0, 0.0, -1.0);
+
+  /* draw back face */
+  glBegin(GL_QUAD_STRIP);
+  for (i = 0; i <= teeth; i++) {
+    angle = i * 2.0 * M_PI / teeth;
+    glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
+    glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
+    if (i < teeth) {
+      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
+      glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
+    }
+  }
+  glEnd();
+
+  /* draw back sides of teeth */
+  glBegin(GL_QUADS);
+  da = 2.0 * M_PI / teeth / 4.0;
+  for (i = 0; i < teeth; i++) {
+    angle = i * 2.0 * M_PI / teeth;
+
+    glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
+    glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5);
+    glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
+    glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
+  }
+  glEnd();
+
+  /* draw outward faces of teeth */
+  glBegin(GL_QUAD_STRIP);
+  for (i = 0; i < teeth; i++) {
+    angle = i * 2.0 * M_PI / teeth;
+
+    glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
+    glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
+    u = r2 * cos(angle + da) - r1 * cos(angle);
+    v = r2 * sin(angle + da) - r1 * sin(angle);
+    len = sqrt(u * u + v * v);
+    u /= len;
+    v /= len;
+    glNormal3f(v, -u, 0.0);
+    glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
+    glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
+    glNormal3f(cos(angle), sin(angle), 0.0);
+    glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5);
+    glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5);
+    u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da);
+    v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da);
+    glNormal3f(v, -u, 0.0);
+    glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
+    glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
+    glNormal3f(cos(angle), sin(angle), 0.0);
+  }
+
+  glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5);
+  glVertex3f(r1 * cos(0), r1 * sin(0), -width * 0.5);
+
+  glEnd();
+
+  glShadeModel(GL_SMOOTH);
+
+  /* draw inside radius cylinder */
+  glBegin(GL_QUAD_STRIP);
+  for (i = 0; i <= teeth; i++) {
+    angle = i * 2.0 * M_PI / teeth;
+    glNormal3f(-cos(angle), -sin(angle), 0.0);
+    glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
+    glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
+  }
+  glEnd();
+
+}
+
+static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
+static GLint gear1, gear2, gear3;
+static GLfloat angle = 0.0;
+
+static void
+draw(void)
+{
+  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+  glPushMatrix();
+  glRotatef(view_rotx, 1.0, 0.0, 0.0);
+  glRotatef(view_roty, 0.0, 1.0, 0.0);
+  glRotatef(view_rotz, 0.0, 0.0, 1.0);
+
+  glPushMatrix();
+  glTranslatef(-3.0, -2.0, 0.0);
+  glRotatef(angle, 0.0, 0.0, 1.0);
+  glCallList(gear1);
+  glPopMatrix();
+
+  glPushMatrix();
+  glTranslatef(3.1, -2.0, 0.0);
+  glRotatef(-2.0 * angle - 9.0, 0.0, 0.0, 1.0);
+  glCallList(gear2);
+  glPopMatrix();
+
+  glPushMatrix();
+  glTranslatef(-3.1, 4.2, 0.0);
+  glRotatef(-2.0 * angle - 25.0, 0.0, 0.0, 1.0);
+  glCallList(gear3);
+  glPopMatrix();
+
+  glPopMatrix();
+
+  glutSwapBuffers();
+
+  Frames++;
+  {
+     GLint t = glutGet(GLUT_ELAPSED_TIME);
+     if (t - T0 >= 5000) {
+        GLfloat seconds = (t - T0) / 1000.0;
+        GLfloat fps = Frames / seconds;
+        printf("%d frames in %g seconds = %g FPS\n", Frames, seconds, fps);
+        T0 = t;
+        Frames = 0;
+     }
+  }
+}
+
+
+static void
+idle(void)
+{
+  angle += 2.0;
+  glutPostRedisplay();
+}
+
+/* change view angle, exit upon ESC */
+/* ARGSUSED1 */
+static void
+key(unsigned char k, int x, int y)
+{
+  switch (k) {
+  case 'z':
+    view_rotz += 5.0;
+    break;
+  case 'Z':
+    view_rotz -= 5.0;
+    break;
+  case 27:  /* Escape */
+    exit(0);
+    break;
+  default:
+    return;
+  }
+  glutPostRedisplay();
+}
+
+/* change view angle */
+/* ARGSUSED1 */
+static void
+special(int k, int x, int y)
+{
+  switch (k) {
+  case GLUT_KEY_UP:
+    view_rotx += 5.0;
+    break;
+  case GLUT_KEY_DOWN:
+    view_rotx -= 5.0;
+    break;
+  case GLUT_KEY_LEFT:
+    view_roty += 5.0;
+    break;
+  case GLUT_KEY_RIGHT:
+    view_roty -= 5.0;
+    break;
+  default:
+    return;
+  }
+  glutPostRedisplay();
+}
+
+/* new window size or exposure */
+static void
+reshape(int width, int height)
+{
+  GLfloat h = (GLfloat) height / (GLfloat) width;
+
+  glViewport(0, 0, (GLint) width, (GLint) height);
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+  glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0);
+  glMatrixMode(GL_MODELVIEW);
+  glLoadIdentity();
+  glTranslatef(0.0, 0.0, -40.0);
+}
+
+static void
+init(void)
+{
+  static GLfloat pos[4] =
+  {5.0, 5.0, 10.0, 0.0};
+  static GLfloat red[4] =
+  {0.8, 0.1, 0.0, 1.0};
+  static GLfloat green[4] =
+  {0.0, 0.8, 0.2, 1.0};
+  static GLfloat blue[4] =
+  {0.2, 0.2, 1.0, 1.0};
+
+  glLightfv(GL_LIGHT0, GL_POSITION, pos);
+  glEnable(GL_CULL_FACE);
+  glEnable(GL_LIGHTING);
+  glEnable(GL_LIGHT0);
+  glEnable(GL_DEPTH_TEST);
+
+  /* make the gears */
+  gear1 = glGenLists(1);
+  glNewList(gear1, GL_COMPILE);
+  glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
+  gear(1.0, 4.0, 1.0, 20, 0.7);
+  glEndList();
+
+  gear2 = glGenLists(1);
+  glNewList(gear2, GL_COMPILE);
+  glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
+  gear(0.5, 2.0, 2.0, 10, 0.7);
+  glEndList();
+
+  gear3 = glGenLists(1);
+  glNewList(gear3, GL_COMPILE);
+  glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
+  gear(1.3, 2.0, 0.5, 10, 0.7);
+  glEndList();
+
+  glEnable(GL_NORMALIZE);
+}
+
+void 
+visible(int vis)
+{
+  if (vis == GLUT_VISIBLE)
+    glutIdleFunc(idle);
+  else
+    glutIdleFunc(NULL);
+}
+
+int main(int argc, char *argv[])
+{
+  glutInit(&argc, argv);
+  glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
+
+  glutInitWindowPosition(0, 0);
+  glutInitWindowSize(300, 300);
+  glutCreateWindow("Gears");
+  init();
+
+  glutDisplayFunc(draw);
+  glutReshapeFunc(reshape);
+  glutKeyboardFunc(key);
+  glutSpecialFunc(special);
+  glutVisibilityFunc(visible);
+
+  glutMainLoop();
+  return 0;             /* ANSI C requires main to return int. */
+}
diff --git a/progs/demos/glinfo.c b/progs/demos/glinfo.c
new file mode 100644 (file)
index 0000000..a61e365
--- /dev/null
@@ -0,0 +1,50 @@
+/* $Id: glinfo.c,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
+
+/*
+ * Print GL, GLU and GLUT version and extension info
+ *
+ * Brian Paul  This file in public domain.
+ * October 3, 1997
+ */
+
+
+/*
+ * $Log: glinfo.c,v $
+ * Revision 1.1  1999/08/19 00:55:40  jtg
+ * Initial revision
+ *
+ * Revision 3.2  1999/02/02 04:45:49  brianp
+ * include stdio.h before glut.h
+ *
+ * Revision 3.1  1998/02/22 16:42:54  brianp
+ * added casts to prevent compiler warnings
+ *
+ * Revision 3.0  1998/02/14 18:42:29  brianp
+ * initial rev
+ *
+ */
+
+
+#include <stdio.h>
+#include <GL/glut.h>
+
+
+int main( int argc, char *argv[] )
+{
+   glutInit( &argc, argv );
+   glutInitDisplayMode( GLUT_RGB );
+   glutCreateWindow(argv[0]);
+
+   printf("GL_VERSION: %s\n", (char *) glGetString(GL_VERSION));
+   printf("GL_EXTENSIONS: %s\n", (char *) glGetString(GL_EXTENSIONS));
+   printf("GL_RENDERER: %s\n", (char *) glGetString(GL_RENDERER));
+   printf("GL_VENDOR: %s\n", (char *) glGetString(GL_VENDOR));
+   printf("GLU_VERSION: %s\n", (char *) gluGetString(GLU_VERSION));
+   printf("GLU_EXTENSIONS: %s\n", (char *) gluGetString(GLU_EXTENSIONS));
+   printf("GLUT_API_VERSION: %d\n", GLUT_API_VERSION);
+#ifdef GLUT_XLIB_IMPLEMENTATION
+   printf("GLUT_XLIB_IMPLEMENTATION: %d\n", GLUT_XLIB_IMPLEMENTATION);
+#endif
+
+   return 0;
+}
diff --git a/progs/demos/glutfx.c b/progs/demos/glutfx.c
new file mode 100644 (file)
index 0000000..278d726
--- /dev/null
@@ -0,0 +1,207 @@
+/* $Id: glutfx.c,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
+
+/*
+ * Example of how one might use GLUT with the 3Dfx driver in full-screen mode.
+ * Note: this only works with X since we're using Mesa's GLX "hack" for
+ * using Glide.
+ *
+ * Goals:
+ *   easy setup and input event handling with GLUT
+ *   use 3Dfx hardware
+ *   automatically set MESA environment variables
+ *   don't lose mouse input focus
+ *
+ * Brian Paul   This file is in the public domain.
+ */
+
+/*
+ * $Log: glutfx.c,v $
+ * Revision 1.1  1999/08/19 00:55:40  jtg
+ * Initial revision
+ *
+ * Revision 3.2  1999/03/28 18:18:33  brianp
+ * minor clean-up
+ *
+ * Revision 3.1  1998/06/29 02:37:30  brianp
+ * minor changes for Windows (Ted Jump)
+ *
+ * Revision 3.0  1998/02/14 18:42:29  brianp
+ * initial rev
+ *
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <GL/glut.h>
+
+
+#define WIDTH 640
+#define HEIGHT 480
+
+
+static int Window = 0;
+static int ScreenWidth, ScreenHeight;
+static GLuint Torus = 0;
+static GLfloat Xrot = 0.0, Yrot = 0.0;
+
+
+
+static void Display( void )
+{
+   static GLfloat blue[4] = {0.2, 0.2, 1.0, 1.0};
+   static GLfloat red[4] = {1.0, 0.2, 0.2, 1.0};
+   static GLfloat green[4] = {0.2, 1.0, 0.2, 1.0};
+
+   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+
+   glPushMatrix();
+   glRotatef(Xrot, 1, 0, 0);
+   glRotatef(Yrot, 0, 1, 0);
+
+   glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blue);
+   glCallList(Torus);
+
+   glRotatef(90.0, 1, 0, 0);
+   glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, red);
+   glCallList(Torus);
+
+   glRotatef(90.0, 0, 1, 0);
+   glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, green);
+   glCallList(Torus);
+
+   glPopMatrix();
+
+   glutSwapBuffers();
+}
+
+
+static void Reshape( int width, int height )
+{
+   float ratio = (float) width / (float) height;
+
+   ScreenWidth = width;
+   ScreenHeight = height;
+
+   /*
+    * The 3Dfx driver is limited to 640 x 480 but the X window may be larger.
+    * Enforce that here.
+    */
+   if (width > WIDTH)
+      width = WIDTH;
+   if (height > HEIGHT)
+      height = HEIGHT;
+
+   glViewport( 0, 0, width, height );
+   glMatrixMode( GL_PROJECTION );
+   glLoadIdentity();
+   glFrustum( -ratio, ratio, -1.0, 1.0, 5.0, 30.0 );
+   glMatrixMode( GL_MODELVIEW );
+   glLoadIdentity();
+   glTranslatef( 0.0, 0.0, -20.0 );
+}
+
+
+static void Key( unsigned char key, int x, int y )
+{
+   (void) x;
+   (void) y;
+   switch (key) {
+      case 27:
+         glutDestroyWindow(Window);
+         exit(0);
+         break;
+   }
+   glutPostRedisplay();
+}
+
+
+static void SpecialKey( int key, int x, int y )
+{
+   (void) x;
+   (void) y;
+   switch (key) {
+      case GLUT_KEY_UP:
+         break;
+      case GLUT_KEY_DOWN:
+         break;
+      case GLUT_KEY_LEFT:
+         break;
+      case GLUT_KEY_RIGHT:
+         break;
+   }
+   glutPostRedisplay();
+}
+
+
+static void MouseMove( int x, int y )
+{
+   Xrot = y - ScreenWidth / 2;
+   Yrot = x - ScreenHeight / 2;
+   glutPostRedisplay();
+}
+
+
+static void Init( void )
+{
+   Torus = glGenLists(1);
+   glNewList(Torus, GL_COMPILE);
+   glutSolidTorus(0.5, 2.0, 10, 20);
+   glEndList();
+
+   glEnable(GL_LIGHTING);
+   glEnable(GL_LIGHT0);
+
+   glEnable(GL_DEPTH_TEST);
+   glEnable(GL_CULL_FACE);
+}
+
+
+int main( int argc, char *argv[] )
+{
+#ifndef _WIN32
+   printf("NOTE: if you've got 3Dfx VooDoo hardware you must run this");
+   printf(" program as root.\n\n");
+   printf("Move the mouse.  Press ESC to exit.\n\n");
+   sleep(2);
+#endif
+
+   /* Tell Mesa GLX to use 3Dfx driver in fullscreen mode. */
+   putenv("MESA_GLX_FX=fullscreen");
+
+   /* Disable 3Dfx Glide splash screen */
+   putenv("FX_GLIDE_NO_SPLASH=");
+
+   /* Give an initial size and position so user doesn't have to place window */
+   glutInitWindowPosition(0, 0);
+   glutInitWindowSize(WIDTH, HEIGHT);
+   glutInit( &argc, argv );
+
+   glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
+
+   Window = glutCreateWindow(argv[0]);
+   if (!Window) {
+      printf("Error, couldn't open window\n");
+      exit(1);
+   }
+
+   /*
+    * Want the X window to fill the screen so that we don't have to
+    * worry about losing the mouse input focus.
+    * Note that we won't actually see the X window since we never draw
+    * to it, hence, the original X screen's contents aren't disturbed.
+    */
+   glutFullScreen();
+
+   Init();
+
+   glutReshapeFunc( Reshape );
+   glutKeyboardFunc( Key );
+   glutSpecialFunc( SpecialKey );
+   glutDisplayFunc( Display );
+   glutPassiveMotionFunc( MouseMove );
+
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/demos/isosurf.c b/progs/demos/isosurf.c
new file mode 100644 (file)
index 0000000..393197f
--- /dev/null
@@ -0,0 +1,821 @@
+/* $Id: isosurf.c,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
+
+/*
+ * Display an isosurface of 3-D wind speed volume.  Use arrow keys to
+ * rotate, S toggles smooth shading, L toggles lighting
+ * Brian Paul  This file in public domain.
+ */
+
+/*
+ * $Log: isosurf.c,v $
+ * Revision 1.1  1999/08/19 00:55:40  jtg
+ * Initial revision
+ *
+ * Revision 3.4  1999/04/24 01:10:47  keithw
+ * clip planes, materials
+ *
+ * Revision 3.3  1999/03/31 19:42:14  keithw
+ * support for cva
+ *
+ * Revision 3.1  1998/11/01 20:30:20  brianp
+ * added benchmark feature (b key)
+ *
+ * Revision 3.0  1998/02/14 18:42:29  brianp
+ * initial rev
+ *
+ */
+
+
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+#include "GL/glut.h"
+
+#include "../util/readtex.c"   /* I know, this is a hack.  KW: me too. */
+#define TEXTURE_FILE "../images/reflect.rgb"
+
+#define LIT                 0x1
+#define UNLIT               0x2
+#define TEXTURE             0x4
+#define NO_TEXTURE          0x8
+#define REFLECT             0x10
+#define NO_REFLECT          0x20
+#define POINT_FILTER        0x40
+#define LINEAR_FILTER       0x80
+#define IMMEDIATE           0x100
+#define DRAW_ARRAYS         0x200 /* or draw_elts, if compiled */
+#define ARRAY_ELT           0x400
+#define COMPILED            0x800
+#define NOT_COMPILED        0x1000
+#define SHADE_SMOOTH        0x2000
+#define SHADE_FLAT          0x4000
+#define TRIANGLES           0x8000
+#define STRIPS              0x10000
+#define USER_CLIP           0x20000
+#define NO_USER_CLIP        0x40000
+#define MATERIALS           0x80000
+#define NO_MATERIALS        0x100000
+#define QUIT                0x800000
+
+#define LIGHT_MASK  (LIT|UNLIT)
+#define TEXTURE_MASK (TEXTURE|NO_TEXTURE)
+#define REFLECT_MASK (REFLECT|NO_REFLECT)
+#define FILTER_MASK (POINT_FILTER|LINEAR_FILTER)
+#define RENDER_STYLE_MASK (IMMEDIATE|DRAW_ARRAYS|ARRAY_ELT)
+#define COMPILED_MASK (COMPILED|NOT_COMPILED)
+#define MATERIAL_MASK (MATERIALS|NO_MATERIALS)
+#define PRIMITIVE_MASK (TRIANGLES|STRIPS)
+#define CLIP_MASK (USER_CLIP|NO_USER_CLIP)
+#define SHADE_MASK (SHADE_SMOOTH|SHADE_FLAT)
+
+#define MAXVERTS 10000
+static float data[MAXVERTS][6];
+static float compressed_data[MAXVERTS][6];
+static GLuint indices[MAXVERTS];
+static GLuint tri_indices[MAXVERTS*3];
+static GLfloat col[100][4];
+static GLint numverts, num_tri_verts, numuniq;
+
+static GLfloat xrot;
+static GLfloat yrot;
+static GLint state, allowed = ~0;
+static GLboolean doubleBuffer = GL_TRUE;
+static GLdouble plane[4] = {1.0, 0.0, -1.0, 0.0};
+
+
+static void read_surface( char *filename )
+{
+   FILE *f;
+
+   f = fopen(filename,"r");
+   if (!f) {
+      printf("couldn't read %s\n", filename);
+      exit(1);
+   }
+
+   numverts = 0;
+   while (!feof(f) && numverts<MAXVERTS) {
+      fscanf( f, "%f %f %f  %f %f %f",
+             &data[numverts][0], &data[numverts][1], &data[numverts][2],
+             &data[numverts][3], &data[numverts][4], &data[numverts][5] );
+      numverts++;
+   }
+   numverts--;
+
+   printf("%d vertices, %d triangles\n", numverts, numverts-2);
+   fclose(f);
+}
+
+
+
+
+struct data_idx {
+   float *data;
+   int idx;
+   int uniq_idx;
+};
+
+
+#define COMPARE_FUNC( AXIS )                            \
+int compare_axis_##AXIS( const void *a, const void *b )        \
+{                                                      \
+   float t = ( (*(struct data_idx *)a).data[AXIS] -    \
+              (*(struct data_idx *)b).data[AXIS] );    \
+                                                       \
+   if (t < 0) return -1;                               \
+   if (t > 0) return 1;                                        \
+   return 0;                                           \
+}
+
+COMPARE_FUNC(0)
+COMPARE_FUNC(1)
+COMPARE_FUNC(2)
+COMPARE_FUNC(3)
+COMPARE_FUNC(4)
+COMPARE_FUNC(5)
+COMPARE_FUNC(6)
+
+int (*(compare[7]))( const void *a, const void *b ) =
+{
+   compare_axis_0,
+   compare_axis_1,
+   compare_axis_2,
+   compare_axis_3,
+   compare_axis_4,
+   compare_axis_5,
+   compare_axis_6,
+};
+
+
+#define VEC_ELT(f, s, i)  (float *)(((char *)f) + s * i)
+
+static int sort_axis( int axis, 
+                     int vec_size,
+                     int vec_stride,
+                     struct data_idx *indices,
+                     int start,
+                     int finish,
+                     float *out,
+                     int uniq,
+                     const float fudge )
+{
+   int i;
+
+   if (finish-start > 2) 
+   {
+      qsort( indices+start, finish-start, sizeof(*indices), compare[axis] );
+   } 
+   else if (indices[start].data[axis] > indices[start+1].data[axis]) 
+   {
+      struct data_idx tmp = indices[start];
+      indices[start] = indices[start+1];
+      indices[start+1] = tmp;
+   }
+        
+   if (axis == vec_size-1) {
+      for (i = start ; i < finish ; ) {
+        float max = indices[i].data[axis] + fudge;
+        float *dest = VEC_ELT(out, vec_stride, uniq);
+        int j;
+       
+        for (j = 0 ; j < vec_size ; j++)
+           dest[j] = indices[i].data[j];
+
+        for ( ; i < finish && max >= indices[i].data[axis]; i++) 
+           indices[i].uniq_idx = uniq;
+
+        uniq++;
+      }
+   } else {
+      for (i = start ; i < finish ; ) {
+        int j = i + 1;
+        float max = indices[i].data[axis] + fudge;
+        while (j < finish && max >= indices[j].data[axis]) j++;
+        if (j == i+1) {
+           float *dest = VEC_ELT(out, vec_stride, uniq);
+           int k;
+
+           indices[i].uniq_idx = uniq;
+       
+           for (k = 0 ; k < vec_size ; k++)
+              dest[k] = indices[i].data[k];
+
+           uniq++;
+        } else {
+           uniq = sort_axis( axis+1, vec_size, vec_stride,
+                             indices, i, j, out, uniq, fudge );
+        }
+        i = j;
+      }
+   }
+
+   return uniq;
+}
+
+
+static void extract_indices1( const struct data_idx *in, unsigned int *out, 
+                             int n )
+{
+   int i;
+   for ( i = 0 ; i < n ; i++ ) {
+      out[in[i].idx] = in[i].uniq_idx;
+   }
+}
+
+
+static void compactify_arrays()
+{
+   int i;
+   struct data_idx *ind;
+
+   ind = (struct data_idx *) malloc( sizeof(struct data_idx) * numverts );
+
+   for (i = 0 ; i < numverts ; i++) {
+      ind[i].idx = i;
+      ind[i].data = data[i];
+   }
+
+   numuniq = sort_axis(0, 
+                      sizeof(compressed_data[0])/sizeof(float), 
+                      sizeof(compressed_data[0]),
+                      ind, 
+                      0, 
+                      numverts, 
+                      (float *)compressed_data, 
+                      0,
+                      1e-6);
+
+   printf("Nr unique vertex/normal pairs: %d\n", numuniq);
+
+   extract_indices1( ind, indices, numverts );
+   free( ind );
+}
+
+static float myrand( float max )
+{
+   return max*rand()/(RAND_MAX+1.0);
+}
+
+
+static void make_tri_indices( void )
+{
+   unsigned int *v = tri_indices;
+   unsigned int parity = 0;
+   unsigned int i, j;
+
+   for (j=2;j<numverts;j++,parity^=1) {
+      if (parity) {
+        *v++ = indices[j-1];
+        *v++ = indices[j-2]; 
+        *v++ = indices[j];
+      } else {
+        *v++ = indices[j-2];
+        *v++ = indices[j-1];
+        *v++ = indices[j];
+      }
+   }
+   
+   num_tri_verts = v - tri_indices;
+   printf("num_tri_verts: %d\n", num_tri_verts);
+
+   for (i = j = 0 ; i < num_tri_verts ; i += 600, j++) {
+      col[j][3] = 1;
+      col[j][2] = myrand(1);
+      col[j][1] = myrand(1);
+      col[j][0] = myrand(1);
+   }
+}
+
+#define MIN(x,y) (x < y) ? x : y
+
+static void draw_surface( void )
+{
+   GLuint i, j;
+
+   switch (state & (COMPILED_MASK|RENDER_STYLE_MASK|PRIMITIVE_MASK)) {
+#ifdef GL_EXT_vertex_array
+
+   case (COMPILED|DRAW_ARRAYS|STRIPS):
+      glDrawElements( GL_TRIANGLE_STRIP, numverts, GL_UNSIGNED_INT, indices );
+      break;
+
+
+   case (COMPILED|ARRAY_ELT|STRIPS):
+      glBegin( GL_TRIANGLE_STRIP );
+      for (i = 0 ; i < numverts ; i++) 
+        glArrayElement( indices[i] );      
+      glEnd();
+      break;
+
+   case (COMPILED|DRAW_ARRAYS|TRIANGLES):
+   case (NOT_COMPILED|DRAW_ARRAYS|TRIANGLES):
+      if (state & MATERIALS) {
+        for (j = i = 0 ; i < num_tri_verts ; i += 600, j++) {
+           GLuint nr = MIN(num_tri_verts-i, 600);
+           glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, col[j]);
+           glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col[j]);
+           glDrawElements( GL_TRIANGLES, nr, GL_UNSIGNED_INT, tri_indices+i );
+        }
+      } else {
+        glDrawElements( GL_TRIANGLES, num_tri_verts, GL_UNSIGNED_INT, 
+                        tri_indices );
+      }
+
+      break;
+
+      /* Uses the original arrays (including duplicate elements):
+       */
+   case (NOT_COMPILED|DRAW_ARRAYS|STRIPS):
+      glDrawArraysEXT( GL_TRIANGLE_STRIP, 0, numverts );
+      break;
+
+      /* Uses the original arrays (including duplicate elements):
+       */
+   case (NOT_COMPILED|ARRAY_ELT|STRIPS):
+      glBegin( GL_TRIANGLE_STRIP );
+      for (i = 0 ; i < numverts ; i++)
+        glArrayElement( i );
+      glEnd();
+      break;
+
+   case (NOT_COMPILED|ARRAY_ELT|TRIANGLES):
+   case (COMPILED|ARRAY_ELT|TRIANGLES):
+      if (state & MATERIALS) {
+        for (j = i = 0 ; i < num_tri_verts ; i += 600, j++) {
+           GLuint nr = MIN(num_tri_verts-i, 600);
+           GLuint k;
+           glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, col[j]);
+           glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col[j]);
+           glBegin( GL_TRIANGLES );
+           for (k = 0 ; k < nr ; k++)
+              glArrayElement( tri_indices[i+k] );
+           glEnd();
+        }
+      } else {
+        glBegin( GL_TRIANGLES );
+        for (i = 0 ; i < num_tri_verts ; i++)
+           glArrayElement( tri_indices[i] );
+        glEnd();
+      }         
+      break;
+
+   case (NOT_COMPILED|IMMEDIATE|TRIANGLES):
+      if (state & MATERIALS) {
+        for (j = i = 0 ; i < num_tri_verts ; i += 600, j++) {
+           GLuint nr = MIN(num_tri_verts-i, 600);
+           GLuint k;
+           glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, col[j]);
+           glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col[j]);
+           glBegin( GL_TRIANGLES );
+           for (k = 0 ; k < nr ; k++) {
+              glNormal3fv( &compressed_data[tri_indices[i+k]][3] );
+              glVertex3fv( &compressed_data[tri_indices[i+k]][0] );
+           }
+           glEnd();
+        }
+      } else {
+        glBegin( GL_TRIANGLES );
+        for (i = 0 ; i < num_tri_verts ; i++) {
+           glNormal3fv( &compressed_data[tri_indices[i]][3] );
+           glVertex3fv( &compressed_data[tri_indices[i]][0] );
+        }
+        glEnd();
+      }         
+      break;
+
+#endif
+
+      /* Uses the original arrays (including duplicate elements):
+       */
+   default:
+      glBegin( GL_TRIANGLE_STRIP );
+      for (i=0;i<numverts;i++) {
+         glNormal3fv( &data[i][3] );
+         glVertex3fv( &data[i][0] );
+      }
+      glEnd();
+   }
+}
+
+
+
+static void Display(void)
+{
+    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+    draw_surface();
+    glFlush();
+    if (doubleBuffer) glutSwapBuffers();    
+}
+
+/* KW: only do this when necessary, so CVA can re-use results.
+ */
+static void set_matrix( void )
+{
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+   glTranslatef( 0.0, 0.0, -6.0 );
+   glRotatef( yrot, 0.0, 1.0, 0.0 );
+   glRotatef( xrot, 1.0, 0.0, 0.0 );
+}
+
+static void Benchmark( float xdiff, float ydiff )
+{
+   int startTime, endTime;
+   int draws;
+   double seconds, fps, triPerSecond;
+
+   printf("Benchmarking...\n");
+
+   draws = 0;
+   startTime = glutGet(GLUT_ELAPSED_TIME);
+   xrot = 0.0;
+   do {
+      xrot += xdiff;
+      yrot += ydiff;
+      set_matrix();
+      Display();
+      draws++;
+      endTime = glutGet(GLUT_ELAPSED_TIME);
+   } while (endTime - startTime < 5000);   /* 5 seconds */
+
+   /* Results */
+   seconds = (double) (endTime - startTime) / 1000.0;
+   triPerSecond = (numverts - 2) * draws / seconds;
+   fps = draws / seconds;
+   printf("Result:  triangles/sec: %g  fps: %g\n", triPerSecond, fps);
+}
+
+
+static void InitMaterials(void)
+{
+    static float ambient[] = {0.1, 0.1, 0.1, 1.0};
+    static float diffuse[] = {0.5, 1.0, 1.0, 1.0};
+    static float position0[] = {0.0, 0.0, 20.0, 0.0};
+    static float position1[] = {0.0, 0.0, -20.0, 0.0};
+    static float front_mat_shininess[] = {60.0};
+    static float front_mat_specular[] = {0.2, 0.2, 0.2, 1.0};
+    static float front_mat_diffuse[] = {0.5, 0.28, 0.38, 1.0};
+    /*
+    static float back_mat_shininess[] = {60.0};
+    static float back_mat_specular[] = {0.5, 0.5, 0.2, 1.0};
+    static float back_mat_diffuse[] = {1.0, 1.0, 0.2, 1.0};
+    */
+    static float lmodel_ambient[] = {1.0, 1.0, 1.0, 1.0};
+    static float lmodel_twoside[] = {GL_FALSE};
+
+    glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
+    glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
+    glLightfv(GL_LIGHT0, GL_POSITION, position0);
+    glEnable(GL_LIGHT0);
+    
+    glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
+    glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
+    glLightfv(GL_LIGHT1, GL_POSITION, position1);
+    glEnable(GL_LIGHT1);
+    
+    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
+    glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
+
+    glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, front_mat_shininess);
+    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, front_mat_specular);
+    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, front_mat_diffuse);
+}
+
+
+
+#define UPDATE(o,n,mask) (o&=~mask, o|=n&mask)
+#define CHANGED(o,n,mask) ((n&mask) && \
+                           (n&mask) != (o&mask) ? UPDATE(o,n,mask) : 0)
+
+static void ModeMenu(int m)
+{
+   m &= allowed;
+
+   if (!m) return;
+
+   if (m==QUIT) 
+      exit(0);
+
+   if (CHANGED(state, m, FILTER_MASK)) {
+      if (m & LINEAR_FILTER) {
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+      } else {
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+      }
+   }
+
+   if (CHANGED(state, m, LIGHT_MASK)) {
+      if (m & LIT)
+        glEnable(GL_LIGHTING);
+      else
+        glDisable(GL_LIGHTING);
+   }
+
+   if (CHANGED(state, m, SHADE_MASK)) {
+      if (m & SHADE_SMOOTH)
+        glShadeModel(GL_SMOOTH);
+      else
+        glShadeModel(GL_FLAT);
+   }
+
+
+   if (CHANGED(state, m, TEXTURE_MASK)) {
+      if (m & TEXTURE) 
+        glEnable(GL_TEXTURE_2D);
+      else
+        glDisable(GL_TEXTURE_2D);
+   }
+
+   if (CHANGED(state, m, REFLECT_MASK)) {
+      if (m & REFLECT) {
+        glEnable(GL_TEXTURE_GEN_S);
+        glEnable(GL_TEXTURE_GEN_T);
+      } else {
+        glDisable(GL_TEXTURE_GEN_S);
+        glDisable(GL_TEXTURE_GEN_T);
+      }
+   }
+
+   if (CHANGED(state, m, CLIP_MASK)) {
+      if (m & USER_CLIP) {
+        glEnable(GL_CLIP_PLANE0);
+      } else {
+        glDisable(GL_CLIP_PLANE0);
+      }
+   }
+
+#ifdef GL_EXT_vertex_array
+   if (CHANGED(state, m, (COMPILED_MASK|RENDER_STYLE_MASK|PRIMITIVE_MASK))) 
+   {
+      if ((m & (COMPILED_MASK|PRIMITIVE_MASK)) == (NOT_COMPILED|STRIPS))
+      {
+        glVertexPointerEXT( 3, GL_FLOAT, sizeof(data[0]), numverts, data );
+        glNormalPointerEXT( GL_FLOAT, sizeof(data[0]), numverts, &data[0][3]);
+      }
+      else 
+      {
+        glVertexPointerEXT( 3, GL_FLOAT, sizeof(data[0]), numuniq, 
+                            compressed_data );
+        glNormalPointerEXT( GL_FLOAT, sizeof(data[0]), numuniq, 
+                            &compressed_data[0][3]);
+      }
+#ifdef GL_EXT_compiled_vertex_array
+      if (m & COMPILED) {
+        glLockArraysEXT( 0, numuniq );
+      } else {
+        glUnlockArraysEXT();
+      }
+#endif
+   }
+#endif
+
+   if (m & (RENDER_STYLE_MASK|PRIMITIVE_MASK)) {
+      UPDATE(state, m, (RENDER_STYLE_MASK|PRIMITIVE_MASK));
+   }
+   
+   if (m & MATERIAL_MASK) {
+      UPDATE(state, m, MATERIAL_MASK);
+   }
+
+   glutPostRedisplay();
+}
+
+
+
+static void Init(void)
+{
+   glClearColor(0.0, 0.0, 0.0, 0.0);
+   glEnable( GL_DEPTH_TEST );
+   glEnable( GL_VERTEX_ARRAY_EXT );
+   glEnable( GL_NORMAL_ARRAY_EXT );
+
+   InitMaterials();
+
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   glFrustum( -1.0, 1.0, -1.0, 1.0, 5, 25 );
+
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+   glClipPlane(GL_CLIP_PLANE0, plane); 
+
+   set_matrix();
+
+   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
+   glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
+
+   glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
+   glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
+
+   if (!LoadRGBMipmaps(TEXTURE_FILE, GL_RGB)) {
+      printf("Error: couldn't load texture image\n");
+      exit(1);
+   }
+
+   if (allowed & COMPILED) {
+      compactify_arrays();
+      make_tri_indices();
+   }
+
+   ModeMenu(SHADE_SMOOTH|
+           LIT|
+           NO_TEXTURE|
+           NO_REFLECT|
+           POINT_FILTER|
+           NOT_COMPILED|
+           NO_USER_CLIP|
+           NO_MATERIALS|
+           IMMEDIATE);
+}
+
+
+
+static void Reshape(int width, int height)
+{
+    glViewport(0, 0, (GLint)width, (GLint)height);
+}
+
+
+
+static void Key( unsigned char key, int x, int y )
+{
+   switch (key) {
+      case 27:
+         exit(0);
+      case 's':
+        ModeMenu((state ^ SHADE_MASK) & SHADE_MASK);
+         break;
+      case 'l':
+        ModeMenu((state ^ LIGHT_MASK) & LIGHT_MASK);
+         break;
+      case 'm':
+        ModeMenu((state ^ MATERIAL_MASK) & MATERIAL_MASK);
+         break;
+      case 'c':
+        ModeMenu((state ^ CLIP_MASK) & CLIP_MASK);
+         break;
+      case 'b':
+         Benchmark(5.0, 0);
+         break;
+      case 'B':
+         Benchmark(0, 5.0);
+         break;
+      case '-':
+      case '_':
+       plane[3] += 2.0;
+       glMatrixMode(GL_MODELVIEW);
+       glLoadIdentity();
+       glClipPlane(GL_CLIP_PLANE0, plane);
+       set_matrix();
+       glutPostRedisplay();
+       break;
+      case '+':
+      case '=':
+       plane[3] -= 2.0;
+       glMatrixMode(GL_MODELVIEW);
+       glLoadIdentity();
+       glClipPlane(GL_CLIP_PLANE0, plane);
+       set_matrix();
+       glutPostRedisplay();
+       break;
+
+   }
+}
+
+
+static void SpecialKey( int key, int x, int y )
+{
+   switch (key) {
+   case GLUT_KEY_LEFT:
+      yrot -= 15.0;
+      break;
+   case GLUT_KEY_RIGHT:
+      yrot += 15.0;
+      break;
+   case GLUT_KEY_UP:
+      xrot += 15.0;
+      break;
+   case GLUT_KEY_DOWN:
+      xrot -= 15.0;
+      break;
+   default:
+      return;
+   }
+   set_matrix();
+   glutPostRedisplay();
+}
+
+
+
+static GLint Args(int argc, char **argv)
+{
+   GLint i;
+   GLint mode = 0;
+
+   for (i = 1; i < argc; i++) {
+      if (strcmp(argv[i], "-sb") == 0) {
+         doubleBuffer = GL_FALSE;
+      }
+      else if (strcmp(argv[i], "-db") == 0) {
+         doubleBuffer = GL_TRUE;
+      }
+      else {
+         printf("%s (Bad option).\n", argv[i]);
+        return QUIT;
+      }
+   }
+
+   return mode;
+}
+
+int main(int argc, char **argv)
+{
+   GLenum type;
+   char *extensions;
+
+   GLuint arg_mode = Args(argc, argv);
+
+   if (arg_mode & QUIT)
+      exit(0);
+
+   read_surface( "isosurf.dat" );
+
+   glutInitWindowPosition(0, 0);
+   glutInitWindowSize(400, 400);
+   
+   type = GLUT_DEPTH;
+   type |= GLUT_RGB;
+   type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
+   glutInitDisplayMode(type);
+
+   if (glutCreateWindow("Isosurface") <= 0) {
+      exit(0);
+   }
+
+   /* Make sure server supports the vertex array extension */
+   extensions = (char *) glGetString( GL_EXTENSIONS );
+
+   if (!strstr( extensions, "GL_EXT_vertex_array" )) 
+   {
+      printf("Vertex arrays not supported by this renderer\n");
+      allowed &= ~(COMPILED|DRAW_ARRAYS|ARRAY_ELT);
+   }
+   else if (!strstr( extensions, "GL_EXT_compiled_vertex_array" )) 
+   {
+      printf("Compiled vertex arrays not supported by this renderer\n");
+      allowed &= ~COMPILED;
+   }
+
+   Init();
+   ModeMenu(arg_mode);
+   
+   glutCreateMenu(ModeMenu);
+   glutAddMenuEntry("Lit",                   LIT|NO_TEXTURE|NO_REFLECT);
+   glutAddMenuEntry("Unlit",                 UNLIT|NO_TEXTURE|NO_REFLECT);
+/*    glutAddMenuEntry("Textured", TEXTURE); */
+   glutAddMenuEntry("Reflect",               TEXTURE|REFLECT);
+   glutAddMenuEntry("", 0);   
+   glutAddMenuEntry("Smooth",                SHADE_SMOOTH);
+   glutAddMenuEntry("Flat",                  SHADE_FLAT);
+   glutAddMenuEntry("", 0);   
+   glutAddMenuEntry("Point Filtered",        POINT_FILTER);
+   glutAddMenuEntry("Linear Filtered",       LINEAR_FILTER);
+   glutAddMenuEntry("", 0);   
+   glutAddMenuEntry("Immediate (STRIPS)",    NOT_COMPILED|IMMEDIATE|STRIPS);
+   glutAddMenuEntry("Immediate (TRIANGLES)", NOT_COMPILED|IMMEDIATE|TRIANGLES);
+   glutAddMenuEntry("", 0);   
+   if (allowed & DRAW_ARRAYS) {
+      glutAddMenuEntry("DrawArrays (STRIPS)",
+                      NOT_COMPILED|DRAW_ARRAYS|STRIPS);
+      glutAddMenuEntry("ArrayElement (STRIPS)",  
+                      NOT_COMPILED|ARRAY_ELT|STRIPS);
+      glutAddMenuEntry("DrawElements (TRIANGLES)", 
+                      NOT_COMPILED|DRAW_ARRAYS|TRIANGLES);
+      glutAddMenuEntry("ArrayElement (TRIANGLES)", 
+                      NOT_COMPILED|ARRAY_ELT|TRIANGLES);
+      glutAddMenuEntry("", 0);   
+
+   }
+   if (allowed & COMPILED) {
+      glutAddMenuEntry("Compiled DrawElements (TRIANGLES)", 
+                      COMPILED|DRAW_ARRAYS|TRIANGLES);
+      glutAddMenuEntry("Compiled DrawElements (STRIPS)", 
+                      COMPILED|DRAW_ARRAYS|STRIPS);
+      glutAddMenuEntry("Compiled ArrayElement", 
+                      COMPILED|ARRAY_ELT|STRIPS);   
+      glutAddMenuEntry("", 0);   
+   }
+   glutAddMenuEntry("Quit",                  QUIT);
+   glutAttachMenu(GLUT_RIGHT_BUTTON);
+
+   glutReshapeFunc(Reshape);
+   glutKeyboardFunc(Key);
+   glutSpecialFunc(SpecialKey);
+   glutDisplayFunc(Display);
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/demos/isosurf.dat b/progs/demos/isosurf.dat
new file mode 100644 (file)
index 0000000..5cadecd
--- /dev/null
@@ -0,0 +1,7179 @@
+-1.000000 0.050200 0.254800  0.280000 0.504000 0.808000
+-1.000000 0.061400 0.243900  0.248000 0.608000 0.744000
+-0.973900 0.050200 0.243900  0.312000 0.448000 0.832000
+-1.000000 0.100400 0.207000  0.040000 0.608000 0.784000
+-0.950000 0.050200 0.232900  0.312000 0.424000 0.840000
+-0.950000 0.100400 0.204500  0.176000 0.504000 0.840000
+-0.900000 0.050200 0.202100  0.368000 0.256000 0.888000
+-0.900000 0.100400 0.184100  0.296000 0.408000 0.856000
+-0.865600 0.050200 0.182900  0.480000 0.256000 0.832000
+-0.897500 0.100400 0.182900  0.392000 0.408000 0.816000
+-0.850000 0.050200 0.170400  0.488000 0.296000 0.816000
+-0.850000 0.100400 0.150400  0.488000 0.512000 0.696000
+-0.800000 0.050200 0.139800  0.504000 0.392000 0.760000
+-0.820700 0.100400 0.121900  0.496000 0.488000 0.704000
+-0.800000 0.077200 0.121900  0.512000 0.416000 0.744000
+-0.800000 0.100400 0.105500  0.480000 0.456000 0.736000
+-0.781300 0.050200 0.121900  0.536000 0.400000 0.736000
+-0.750000 0.100400 0.065100  0.488000 0.448000 0.736000
+-0.750000 0.050200 0.097600  0.464000 0.408000 0.776000
+-0.744800 0.100400 0.060900  0.496000 0.456000 0.728000
+-0.700000 0.050200 0.061900  0.536000 0.368000 0.752000
+-0.700000 0.051600 0.060900  0.528000 0.416000 0.728000
+-0.699000 0.050200 0.060900  0.608000 0.360000 0.696000
+-0.700000 0.100400 0.019100  0.504000 0.504000 0.688000
+-0.650000 0.050200 0.008200  0.568000 0.384000 0.720000
+-0.680200 0.100400 0.000000  0.600000 0.440000 0.656000
+-0.650000 0.063100 0.000000  0.592000 0.392000 0.696000
+-0.650000 0.100400 -0.043200  0.600000 0.608000 0.496000
+-0.641800 0.050200 0.000000  0.616000 0.400000 0.664000
+-0.638000 0.100400 -0.060900  0.672000 0.632000 0.368000
+-0.600000 0.050200 -0.054100  0.640000 0.448000 0.616000
+-0.600000 0.057600 -0.060900  0.728000 0.536000 0.408000
+-0.594700 0.050200 -0.060900  0.744000 0.504000 0.416000
+-0.600000 0.050200 -0.083400  0.800000 0.528000 -0.248000
+-0.573200 0.000000 -0.060900  0.920000 0.296000 -0.248000
+-0.600000 0.000000 -0.117700  0.848000 0.200000 -0.488000
+-0.554400 -0.050200 -0.060900  0.944000 0.280000 0.128000
+-0.600000 -0.008200 -0.121900  0.848000 0.208000 -0.472000
+-0.586600 -0.050200 -0.121900  0.872000 0.224000 -0.424000
+-0.600000 -0.050200 -0.162700  0.904000 0.232000 -0.344000
+-0.578300 -0.100400 -0.121900  0.848000 0.312000 -0.424000
+-0.600000 -0.077900 -0.182900  0.856000 0.208000 -0.464000
+-0.594100 -0.100400 -0.182900  0.816000 0.296000 -0.480000
+-0.600000 -0.100400 -0.193800  0.776000 0.296000 -0.544000
+-0.561800 -0.150600 -0.182900  0.544000 0.784000 -0.280000
+-0.600000 -0.150600 -0.229400  0.416000 0.744000 -0.512000
+-0.550000 -0.155500 -0.182900  0.296000 0.920000 -0.232000
+-0.600000 -0.160400 -0.243900  0.432000 0.688000 -0.576000
+-0.550000 -0.172700 -0.243900  0.008000 0.856000 -0.512000
+-0.600000 -0.200800 -0.299500  0.000000 0.872000 -0.480000
+-0.550000 -0.200800 -0.303600  -0.040000 0.880000 -0.464000
+-0.600000 -0.203400 -0.304800  0.008000 0.768000 -0.632000
+-0.550000 -0.201300 -0.304800  -0.032000 0.864000 -0.488000
+-0.600000 -0.251000 -0.360600  -0.120000 0.624000 -0.760000
+-0.550000 -0.245600 -0.365800  -0.104000 0.680000 -0.720000
+-0.576800 -0.251000 -0.365800  -0.136000 0.624000 -0.760000
+-0.550000 -0.251000 -0.371400  -0.120000 0.616000 -0.768000
+-0.600000 -0.256300 -0.365800  -0.112000 0.608000 -0.776000
+-0.550000 -0.301200 -0.401000  0.000000 0.424000 -0.904000
+-0.600000 -0.301200 -0.399100  0.008000 0.480000 -0.872000
+-0.550000 -0.349500 -0.426800  0.056000 0.416000 -0.904000
+-0.600000 -0.340300 -0.426800  0.032000 0.512000 -0.848000
+-0.600000 -0.301200 -0.399100  0.008000 0.480000 -0.872000
+-0.650000 -0.337200 -0.426800  0.016000 0.520000 -0.848000
+-0.650000 -0.301200 -0.398600  0.000000 0.528000 -0.840000
+-0.700000 -0.338200 -0.426800  -0.192000 0.592000 -0.776000
+-0.700000 -0.301200 -0.401600  0.016000 0.504000 -0.856000
+-0.736800 -0.351500 -0.426800  -0.240000 0.480000 -0.832000
+-0.750000 -0.301200 -0.392900  -0.104000 0.352000 -0.928000
+-0.750000 -0.351500 -0.422100  -0.312000 0.448000 -0.824000
+-0.800000 -0.301200 -0.380800  -0.264000 0.104000 -0.952000
+-0.800000 -0.351500 -0.388300  -0.664000 -0.152000 -0.728000
+-0.826000 -0.301200 -0.365800  -0.648000 -0.448000 -0.600000
+-0.812200 -0.351500 -0.365800  -0.856000 -0.296000 -0.408000
+-0.850000 -0.301200 -0.321900  -0.728000 -0.616000 -0.280000
+-0.821000 -0.351500 -0.304800  -0.824000 -0.504000 0.232000
+-0.850000 -0.306900 -0.304800  -0.768000 -0.624000 0.072000
+-0.807300 -0.351500 -0.243900  -0.864000 -0.472000 0.152000
+-0.850000 -0.301200 -0.293400  -0.744000 -0.560000 0.336000
+-0.834700 -0.301200 -0.243900  -0.840000 -0.504000 0.184000
+-0.850000 -0.276800 -0.243900  -0.792000 -0.552000 0.248000
+-0.831100 -0.301200 -0.182900  -0.848000 -0.520000 0.016000
+-0.850000 -0.271300 -0.182900  -0.816000 -0.568000 0.032000
+-0.832400 -0.301200 -0.121900  -0.840000 -0.528000 0.048000
+-0.850000 -0.274400 -0.121900  -0.816000 -0.568000 0.008000
+-0.826600 -0.301200 -0.060900  -0.824000 -0.544000 0.120000
+-0.850000 -0.265600 -0.060900  -0.808000 -0.568000 0.104000
+-0.817700 -0.301200 0.000000  -0.808000 -0.560000 0.168000
+-0.850000 -0.254700 0.000000  -0.800000 -0.568000 0.168000
+-0.805900 -0.301200 0.060900  -0.800000 -0.536000 0.232000
+-0.850000 -0.251000 0.014600  -0.800000 -0.560000 0.176000
+-0.838400 -0.251000 0.060900  -0.808000 -0.528000 0.248000
+-0.850000 -0.233200 0.060900  -0.816000 -0.512000 0.248000
+-0.819200 -0.251000 0.121900  -0.760000 -0.496000 0.400000
+-0.850000 -0.203500 0.121900  -0.792000 -0.528000 0.288000
+-0.800000 -0.251000 0.157900  -0.576000 -0.400000 0.696000
+-0.850000 -0.200800 0.125700  -0.776000 -0.360000 0.504000
+-0.800000 -0.206500 0.182900  -0.304000 -0.264000 0.912000
+-0.803100 -0.200800 0.182900  -0.456000 -0.168000 0.864000
+-0.800000 -0.200800 0.184500  -0.256000 -0.128000 0.952000
+-0.836800 -0.150600 0.182900  -0.304000 -0.304000 0.896000
+-0.800000 -0.150600 0.189500  -0.240000 -0.056000 0.960000
+-0.850000 -0.137400 0.182900  -0.304000 -0.312000 0.896000
+-0.800000 -0.100400 0.186900  0.104000 0.048000 0.992000
+-0.850000 -0.100400 0.192600  -0.136000 -0.312000 0.936000
+-0.800000 -0.063400 0.182900  0.240000 0.160000 0.952000
+-0.850000 -0.050200 0.193400  0.200000 0.072000 0.968000
+-0.809300 -0.050200 0.182900  0.232000 0.160000 0.952000
+-0.850000 0.000000 0.186200  0.256000 0.144000 0.952000
+-0.839600 0.000000 0.182900  0.264000 0.152000 0.944000
+-0.850000 0.016800 0.182900  0.328000 0.184000 0.920000
+-0.800000 0.000000 0.163200  0.400000 0.288000 0.864000
+-0.850000 0.050200 0.170400  0.488000 0.296000 0.816000
+-0.800000 0.050200 0.139800  0.504000 0.392000 0.760000
+-0.800000 0.000000 0.163200  0.400000 0.288000 0.864000
+-0.781300 0.050200 0.121900  0.536000 0.400000 0.736000
+-0.750000 0.000000 0.129400  0.496000 0.360000 0.776000
+-0.750000 0.012900 0.121900  0.496000 0.384000 0.768000
+-0.740500 0.000000 0.121900  0.504000 0.352000 0.784000
+-0.750000 0.050200 0.097600  0.464000 0.408000 0.776000
+-0.700000 0.000000 0.089700  0.584000 0.336000 0.736000
+-0.700000 0.050200 0.061900  0.536000 0.368000 0.752000
+-0.666100 0.000000 0.060900  0.560000 0.376000 0.728000
+-0.699000 0.050200 0.060900  0.608000 0.360000 0.696000
+-0.650000 0.000000 0.045200  0.576000 0.400000 0.704000
+-0.650000 0.050200 0.008200  0.568000 0.384000 0.720000
+-0.609800 0.000000 0.000000  0.696000 0.384000 0.592000
+-0.641800 0.050200 0.000000  0.616000 0.400000 0.664000
+-0.600000 0.000000 -0.017800  0.736000 0.384000 0.544000
+-0.600000 0.050200 -0.054100  0.640000 0.448000 0.616000
+-0.573200 0.000000 -0.060900  0.920000 0.296000 -0.248000
+-0.594700 0.050200 -0.060900  0.744000 0.504000 0.416000
+-0.594700 0.050200 -0.060900  0.744000 0.504000 0.416000
+-1.000000 0.050200 0.254800  0.280000 0.504000 0.808000
+-1.000000 0.050200 0.254800  0.280000 0.504000 0.808000
+-1.000000 0.000000 0.260200  0.424000 -0.312000 0.840000
+-0.973900 0.050200 0.243900  0.312000 0.448000 0.832000
+-0.976100 0.000000 0.243900  0.464000 -0.432000 0.768000
+-0.950000 0.050200 0.232900  0.312000 0.424000 0.840000
+-0.950000 0.000000 0.224500  0.344000 -0.144000 0.920000
+-0.900000 0.050200 0.202100  0.368000 0.256000 0.888000
+-0.900000 0.000000 0.204000  0.296000 0.088000 0.944000
+-0.865600 0.050200 0.182900  0.480000 0.256000 0.832000
+-0.850000 0.000000 0.186200  0.256000 0.144000 0.952000
+-0.850000 0.016800 0.182900  0.328000 0.184000 0.920000
+-0.865600 0.050200 0.182900  0.480000 0.256000 0.832000
+-0.850000 0.050200 0.170400  0.488000 0.296000 0.816000
+-0.850000 0.050200 0.170400  0.488000 0.296000 0.816000
+-1.000000 0.000000 0.260200  0.424000 -0.312000 0.840000
+-1.000000 0.000000 0.260200  0.424000 -0.312000 0.840000
+-0.976100 0.000000 0.243900  0.464000 -0.432000 0.768000
+-1.000000 -0.016700 0.243900  0.424000 -0.608000 0.656000
+-0.950000 0.000000 0.224500  0.344000 -0.144000 0.920000
+-1.000000 -0.050200 0.185900  -0.256000 -0.768000 0.576000
+-0.950000 -0.050200 0.212200  0.160000 -0.384000 0.904000
+-1.000000 -0.052000 0.182900  -0.336000 -0.760000 0.544000
+-0.950000 -0.074300 0.182900  -0.344000 -0.776000 0.520000
+-1.000000 -0.075600 0.121900  -0.328000 -0.896000 0.264000
+-0.950000 -0.095300 0.121900  -0.400000 -0.864000 0.280000
+-1.000000 -0.090800 0.060900  -0.320000 -0.912000 0.248000
+-0.950000 -0.100400 0.101700  -0.400000 -0.872000 0.264000
+-0.973400 -0.100400 0.060900  -0.344000 -0.904000 0.240000
+-0.950000 -0.110600 0.060900  -0.432000 -0.856000 0.248000
+-1.000000 -0.100400 0.014600  -0.304000 -0.920000 0.208000
+-0.950000 -0.123700 0.000000  -0.488000 -0.840000 0.216000
+-1.000000 -0.103100 0.000000  -0.304000 -0.920000 0.208000
+-0.950000 -0.136200 -0.060900  -0.528000 -0.832000 0.152000
+-1.000000 -0.112800 -0.060900  -0.376000 -0.912000 0.144000
+-0.950000 -0.144800 -0.121900  -0.536000 -0.832000 0.120000
+-1.000000 -0.120900 -0.121900  -0.400000 -0.904000 0.136000
+-0.950000 -0.150600 -0.169000  -0.584000 -0.792000 0.136000
+-1.000000 -0.129600 -0.182900  -0.400000 -0.904000 0.136000
+-0.952800 -0.150600 -0.182900  -0.568000 -0.808000 0.136000
+-1.000000 -0.135800 -0.243900  -0.400000 -0.904000 0.096000
+-0.966700 -0.150600 -0.243900  -0.472000 -0.864000 0.152000
+-1.000000 -0.142300 -0.304800  -0.328000 -0.456000 -0.824000
+-0.989000 -0.150600 -0.304800  -0.440000 -0.624000 -0.640000
+-1.000000 -0.100400 -0.332000  -0.256000 -0.392000 -0.880000
+-0.950000 -0.150600 -0.330800  -0.416000 -0.432000 -0.792000
+-0.950000 -0.100400 -0.349400  -0.088000 -0.160000 -0.976000
+-0.900000 -0.150600 -0.338300  -0.216000 -0.104000 -0.968000
+-0.900000 -0.100400 -0.346700  0.112000 -0.048000 -0.984000
+-0.850000 -0.150600 -0.349400  0.072000 0.056000 -0.992000
+-0.850000 -0.100400 -0.332400  0.280000 0.112000 -0.952000
+-0.800000 -0.150600 -0.340500  0.312000 0.288000 -0.896000
+-0.800000 -0.100400 -0.313000  0.368000 0.216000 -0.896000
+-0.750000 -0.150600 -0.317800  0.416000 0.384000 -0.816000
+-0.785000 -0.100400 -0.304800  0.328000 0.224000 -0.912000
+-0.750000 -0.129200 -0.304800  0.392000 0.376000 -0.832000
+-0.750000 -0.100400 -0.291100  0.336000 0.256000 -0.896000
+-0.731900 -0.150600 -0.304800  0.424000 0.400000 -0.808000
+-0.700000 -0.100400 -0.274700  0.392000 0.112000 -0.904000
+-0.700000 -0.150600 -0.284500  0.376000 0.392000 -0.832000
+-0.650000 -0.100400 -0.251900  0.448000 0.224000 -0.856000
+-0.650000 -0.150600 -0.267500  0.376000 0.464000 -0.792000
+-0.638400 -0.100400 -0.243900  0.560000 0.160000 -0.808000
+-0.612700 -0.150600 -0.243900  0.496000 0.576000 -0.640000
+-0.600000 -0.100400 -0.193800  0.776000 0.296000 -0.544000
+-0.600000 -0.150600 -0.229400  0.416000 0.744000 -0.512000
+-0.612700 -0.150600 -0.243900  0.496000 0.576000 -0.640000
+-0.600000 -0.160400 -0.243900  0.432000 0.688000 -0.576000
+-0.650000 -0.150600 -0.267500  0.376000 0.464000 -0.792000
+-0.600000 -0.200800 -0.299500  0.000000 0.872000 -0.480000
+-0.650000 -0.200800 -0.303800  0.136000 0.680000 -0.712000
+-0.600000 -0.203400 -0.304800  0.008000 0.768000 -0.632000
+-0.650000 -0.201600 -0.304800  0.104000 0.688000 -0.704000
+-0.600000 -0.251000 -0.360600  -0.120000 0.624000 -0.760000
+-0.650000 -0.251000 -0.354800  0.152000 0.632000 -0.752000
+-0.600000 -0.256300 -0.365800  -0.112000 0.608000 -0.776000
+-0.650000 -0.261300 -0.365800  0.088000 0.568000 -0.808000
+-0.600000 -0.301200 -0.399100  0.008000 0.480000 -0.872000
+-0.650000 -0.301200 -0.398600  0.000000 0.528000 -0.840000
+-0.650000 -0.261300 -0.365800  0.088000 0.568000 -0.808000
+-0.700000 -0.301200 -0.401600  0.016000 0.504000 -0.856000
+-0.700000 -0.252100 -0.365800  0.096000 0.552000 -0.824000
+-0.750000 -0.301200 -0.392900  -0.104000 0.352000 -0.928000
+-0.707800 -0.251000 -0.365800  0.064000 0.432000 -0.896000
+-0.750000 -0.251000 -0.369800  0.056000 0.280000 -0.952000
+-0.750000 -0.240500 -0.365800  0.056000 0.272000 -0.952000
+-0.800000 -0.251000 -0.370300  -0.064000 0.200000 -0.976000
+-0.800000 -0.234100 -0.365800  -0.112000 0.264000 -0.952000
+-0.828000 -0.251000 -0.365800  -0.248000 0.216000 -0.936000
+-0.800000 -0.200800 -0.355700  0.080000 0.256000 -0.960000
+-0.850000 -0.251000 -0.359600  -0.320000 0.248000 -0.912000
+-0.850000 -0.200800 -0.351200  -0.168000 0.112000 -0.976000
+-0.891700 -0.251000 -0.304800  -0.808000 -0.512000 -0.264000
+-0.900000 -0.200800 -0.331500  -0.576000 -0.328000 -0.736000
+-0.900000 -0.236500 -0.304800  -0.680000 -0.456000 -0.560000
+-0.931500 -0.200800 -0.304800  -0.648000 -0.520000 -0.544000
+-0.900000 -0.212400 -0.243900  -0.672000 -0.712000 0.176000
+-0.914100 -0.200800 -0.243900  -0.664000 -0.728000 0.128000
+-0.900000 -0.206900 -0.182900  -0.648000 -0.752000 0.056000
+-0.907400 -0.200800 -0.182900  -0.688000 -0.712000 0.072000
+-0.900000 -0.204500 -0.121900  -0.688000 -0.712000 0.104000
+-0.903800 -0.200800 -0.121900  -0.696000 -0.704000 0.120000
+-0.900000 -0.200800 -0.096200  -0.752000 -0.632000 0.128000
+-0.943100 -0.150600 -0.121900  -0.672000 -0.720000 0.120000
+-0.900000 -0.192500 -0.060900  -0.856000 -0.488000 0.144000
+-0.932400 -0.150600 -0.060900  -0.688000 -0.696000 0.176000
+-0.900000 -0.169600 0.000000  -0.800000 -0.552000 0.224000
+-0.915700 -0.150600 0.000000  -0.696000 -0.672000 0.232000
+-0.900000 -0.150600 0.057700  -0.744000 -0.616000 0.232000
+-0.950000 -0.123700 0.000000  -0.488000 -0.840000 0.216000
+-0.900000 -0.149700 0.060900  -0.696000 -0.664000 0.232000
+-0.950000 -0.110600 0.060900  -0.432000 -0.856000 0.248000
+-0.900000 -0.127600 0.121900  -0.608000 -0.704000 0.344000
+-0.950000 -0.100400 0.101700  -0.400000 -0.872000 0.264000
+-0.939400 -0.100400 0.121900  -0.456000 -0.816000 0.336000
+-0.950000 -0.095300 0.121900  -0.400000 -0.864000 0.280000
+-0.900000 -0.100400 0.174900  -0.400000 -0.624000 0.656000
+-0.950000 -0.074300 0.182900  -0.344000 -0.776000 0.520000
+-0.900000 -0.094400 0.182900  -0.312000 -0.608000 0.720000
+-0.950000 -0.050200 0.212200  0.160000 -0.384000 0.904000
+-0.900000 -0.050200 0.208600  0.200000 -0.168000 0.960000
+-0.950000 0.000000 0.224500  0.344000 -0.144000 0.920000
+-0.900000 0.000000 0.204000  0.296000 0.088000 0.944000
+-0.900000 -0.050200 0.208600  0.200000 -0.168000 0.960000
+-0.850000 0.000000 0.186200  0.256000 0.144000 0.952000
+-0.850000 -0.050200 0.193400  0.200000 0.072000 0.968000
+-0.900000 -0.050200 0.208600  0.200000 -0.168000 0.960000
+-0.850000 -0.100400 0.192600  -0.136000 -0.312000 0.936000
+-0.900000 -0.094400 0.182900  -0.312000 -0.608000 0.720000
+-0.886800 -0.100400 0.182900  -0.288000 -0.576000 0.752000
+-0.900000 -0.100400 0.174900  -0.400000 -0.624000 0.656000
+-0.850000 -0.137400 0.182900  -0.304000 -0.312000 0.896000
+-0.900000 -0.127600 0.121900  -0.608000 -0.704000 0.344000
+-0.850000 -0.150600 0.175600  -0.632000 -0.392000 0.664000
+-0.878400 -0.150600 0.121900  -0.736000 -0.560000 0.368000
+-0.850000 -0.200800 0.125700  -0.776000 -0.360000 0.504000
+-0.851500 -0.200800 0.121900  -0.832000 -0.360000 0.408000
+-0.850000 -0.203500 0.121900  -0.792000 -0.528000 0.288000
+-0.869300 -0.200800 0.060900  -0.824000 -0.496000 0.248000
+-0.850000 -0.233200 0.060900  -0.816000 -0.512000 0.248000
+-0.882700 -0.200800 0.000000  -0.840000 -0.496000 0.192000
+-0.850000 -0.251000 0.014600  -0.800000 -0.560000 0.176000
+-0.852600 -0.251000 0.000000  -0.800000 -0.568000 0.168000
+-0.850000 -0.254700 0.000000  -0.800000 -0.568000 0.168000
+-0.860100 -0.251000 -0.060900  -0.808000 -0.568000 0.112000
+-0.850000 -0.265600 -0.060900  -0.808000 -0.568000 0.104000
+-0.866600 -0.251000 -0.121900  -0.808000 -0.576000 0.072000
+-0.850000 -0.274400 -0.121900  -0.816000 -0.568000 0.008000
+-0.864200 -0.251000 -0.182900  -0.800000 -0.592000 0.000000
+-0.850000 -0.271300 -0.182900  -0.816000 -0.568000 0.032000
+-0.869200 -0.251000 -0.243900  -0.768000 -0.600000 0.200000
+-0.850000 -0.276800 -0.243900  -0.792000 -0.552000 0.248000
+-0.891700 -0.251000 -0.304800  -0.808000 -0.512000 -0.264000
+-0.850000 -0.301200 -0.293400  -0.744000 -0.560000 0.336000
+-0.854400 -0.301200 -0.304800  -0.776000 -0.608000 0.112000
+-0.850000 -0.306900 -0.304800  -0.768000 -0.624000 0.072000
+-0.850000 -0.301200 -0.321900  -0.728000 -0.616000 -0.280000
+-0.854400 -0.301200 -0.304800  -0.776000 -0.608000 0.112000
+-0.850000 -0.251000 -0.359600  -0.320000 0.248000 -0.912000
+-0.891700 -0.251000 -0.304800  -0.808000 -0.512000 -0.264000
+-0.891700 -0.251000 -0.304800  -0.808000 -0.512000 -0.264000
+-1.000000 0.100400 0.207000  0.040000 0.608000 0.784000
+-1.000000 0.100400 0.207000  0.040000 0.608000 0.784000
+-0.950000 0.100400 0.204500  0.176000 0.504000 0.840000
+-1.000000 0.136100 0.182900  0.152000 0.600000 0.776000
+-0.950000 0.127100 0.182900  0.248000 0.536000 0.800000
+-1.000000 0.150600 0.170300  0.208000 0.568000 0.792000
+-0.950000 0.150600 0.154300  0.208000 0.640000 0.736000
+-1.000000 0.192500 0.121900  0.192000 0.664000 0.720000
+-0.950000 0.178500 0.121900  0.272000 0.648000 0.704000
+-1.000000 0.200800 0.112700  0.192000 0.656000 0.720000
+-0.950000 0.200800 0.096100  0.208000 0.672000 0.704000
+-1.000000 0.241600 0.060900  0.248000 0.768000 0.584000
+-0.950000 0.226300 0.060900  0.264000 0.760000 0.584000
+-1.000000 0.251000 0.045400  0.264000 0.768000 0.568000
+-0.950000 0.251000 0.016800  0.288000 0.808000 0.504000
+-1.000000 0.274600 0.000000  0.264000 0.848000 0.448000
+-0.950000 0.258900 0.000000  0.296000 0.848000 0.432000
+-1.000000 0.294800 -0.060900  0.312000 0.944000 0.080000
+-0.950000 0.277400 -0.060900  0.336000 0.928000 0.080000
+-1.000000 0.286500 -0.121900  0.328000 0.872000 -0.344000
+-0.950000 0.267200 -0.121900  0.344000 0.864000 -0.336000
+-1.000000 0.256900 -0.182900  0.288000 0.752000 -0.584000
+-0.950000 0.251000 -0.157200  0.320000 0.808000 -0.480000
+-0.985000 0.251000 -0.182900  0.288000 0.752000 -0.576000
+-0.950000 0.237800 -0.182900  0.296000 0.760000 -0.568000
+-1.000000 0.251000 -0.191500  0.280000 0.728000 -0.616000
+-0.950000 0.200800 -0.231900  0.272000 0.640000 -0.704000
+-1.000000 0.207900 -0.243900  0.232000 0.640000 -0.728000
+-0.980800 0.200800 -0.243900  0.232000 0.632000 -0.736000
+-1.000000 0.200800 -0.251300  0.232000 0.624000 -0.736000
+-0.950000 0.189400 -0.243900  0.264000 0.616000 -0.728000
+-1.000000 0.150600 -0.296000  0.168000 0.544000 -0.816000
+-0.950000 0.150600 -0.281200  0.240000 0.600000 -0.752000
+-1.000000 0.137800 -0.304800  0.104000 0.472000 -0.872000
+-0.950000 0.126000 -0.304800  0.168000 0.528000 -0.824000
+-1.000000 0.100400 -0.326700  0.072000 0.384000 -0.912000
+-0.950000 0.100400 -0.325900  0.192000 0.384000 -0.896000
+-1.000000 0.050200 -0.349300  0.080000 0.216000 -0.968000
+-0.950000 0.050200 -0.340200  0.184000 0.072000 -0.976000
+-1.000000 0.000000 -0.357700  0.216000 -0.064000 -0.968000
+-0.950000 0.000000 -0.337100  0.184000 -0.088000 -0.976000
+-1.000000 -0.050200 -0.339100  0.152000 -0.176000 -0.968000
+-0.950000 -0.050200 -0.337400  0.088000 0.008000 -0.992000
+-1.000000 -0.100400 -0.332000  -0.256000 -0.392000 -0.880000
+-0.950000 -0.100400 -0.349400  -0.088000 -0.160000 -0.976000
+-0.950000 -0.050200 -0.337400  0.088000 0.008000 -0.992000
+-0.900000 -0.100400 -0.346700  0.112000 -0.048000 -0.984000
+-0.900000 -0.050200 -0.330000  0.160000 0.128000 -0.976000
+-0.850000 -0.100400 -0.332400  0.280000 0.112000 -0.952000
+-0.850000 -0.050200 -0.323400  0.248000 0.176000 -0.944000
+-0.800000 -0.100400 -0.313000  0.368000 0.216000 -0.896000
+-0.808200 -0.050200 -0.304800  0.280000 0.136000 -0.944000
+-0.800000 -0.066700 -0.304800  0.296000 0.144000 -0.936000
+-0.800000 -0.050200 -0.302200  0.264000 0.120000 -0.952000
+-0.785000 -0.100400 -0.304800  0.328000 0.224000 -0.912000
+-0.750000 -0.050200 -0.287100  0.288000 0.040000 -0.952000
+-0.750000 -0.100400 -0.291100  0.336000 0.256000 -0.896000
+-0.700000 -0.050200 -0.272000  0.360000 0.104000 -0.920000
+-0.700000 -0.100400 -0.274700  0.392000 0.112000 -0.904000
+-0.650000 -0.050200 -0.249300  0.496000 0.208000 -0.840000
+-0.650000 -0.100400 -0.251900  0.448000 0.224000 -0.856000
+-0.642900 -0.050200 -0.243900  0.560000 0.208000 -0.792000
+-0.638400 -0.100400 -0.243900  0.560000 0.160000 -0.808000
+-0.606100 -0.050200 -0.182900  0.864000 0.248000 -0.424000
+-0.600000 -0.100400 -0.193800  0.776000 0.296000 -0.544000
+-0.600000 -0.077900 -0.182900  0.856000 0.208000 -0.464000
+-0.606100 -0.050200 -0.182900  0.864000 0.248000 -0.424000
+-0.600000 -0.050200 -0.162700  0.904000 0.232000 -0.344000
+-0.621400 0.000000 -0.182900  0.848000 0.280000 -0.440000
+-0.600000 -0.008200 -0.121900  0.848000 0.208000 -0.472000
+-0.601900 0.000000 -0.121900  0.848000 0.208000 -0.472000
+-0.600000 0.000000 -0.117700  0.848000 0.200000 -0.488000
+-0.614300 0.050200 -0.121900  0.720000 0.480000 -0.480000
+-0.600000 0.050200 -0.083400  0.800000 0.528000 -0.248000
+-0.650000 0.089500 -0.121900  0.728000 0.552000 -0.384000
+-0.600000 0.057600 -0.060900  0.728000 0.536000 0.408000
+-0.650000 0.100400 -0.098000  0.720000 0.624000 -0.288000
+-0.638000 0.100400 -0.060900  0.672000 0.632000 0.368000
+-0.650000 0.112000 -0.060900  0.672000 0.704000 0.200000
+-0.650000 0.100400 -0.043200  0.600000 0.608000 0.496000
+-0.689800 0.150600 -0.060900  0.640000 0.736000 0.192000
+-0.680200 0.100400 0.000000  0.600000 0.440000 0.656000
+-0.700000 0.150600 -0.043600  0.552000 0.712000 0.424000
+-0.700000 0.121800 0.000000  0.536000 0.544000 0.632000
+-0.734000 0.150600 0.000000  0.496000 0.640000 0.576000
+-0.700000 0.100400 0.019100  0.504000 0.504000 0.688000
+-0.750000 0.150600 0.014500  0.472000 0.624000 0.608000
+-0.744800 0.100400 0.060900  0.496000 0.456000 0.728000
+-0.750000 0.106000 0.060900  0.496000 0.464000 0.728000
+-0.750000 0.100400 0.065100  0.488000 0.448000 0.736000
+-0.796300 0.150600 0.060900  0.512000 0.584000 0.616000
+-0.800000 0.100400 0.105500  0.480000 0.456000 0.736000
+-0.800000 0.150600 0.064100  0.424000 0.560000 0.704000
+-0.820700 0.100400 0.121900  0.496000 0.488000 0.704000
+-0.850000 0.150600 0.098600  0.360000 0.600000 0.704000
+-0.850000 0.127100 0.121900  0.424000 0.560000 0.704000
+-0.892900 0.150600 0.121900  0.360000 0.624000 0.680000
+-0.850000 0.100400 0.150400  0.488000 0.512000 0.696000
+-0.900000 0.150600 0.126400  0.344000 0.632000 0.688000
+-0.897500 0.100400 0.182900  0.392000 0.408000 0.816000
+-0.900000 0.101900 0.182900  0.304000 0.552000 0.768000
+-0.900000 0.100400 0.184100  0.296000 0.408000 0.856000
+-0.950000 0.127100 0.182900  0.248000 0.536000 0.800000
+-0.950000 0.100400 0.204500  0.176000 0.504000 0.840000
+-0.950000 0.100400 0.204500  0.176000 0.504000 0.840000
+-0.886800 -0.100400 0.182900  -0.288000 -0.576000 0.752000
+-0.886800 -0.100400 0.182900  -0.288000 -0.576000 0.752000
+-0.850000 -0.100400 0.192600  -0.136000 -0.312000 0.936000
+-0.850000 -0.137400 0.182900  -0.304000 -0.312000 0.896000
+-0.850000 -0.137400 0.182900  -0.304000 -0.312000 0.896000
+-0.800000 -0.100400 0.186900  0.104000 0.048000 0.992000
+-0.800000 -0.100400 0.186900  0.104000 0.048000 0.992000
+-0.800000 -0.063400 0.182900  0.240000 0.160000 0.952000
+-0.776900 -0.100400 0.182900  0.184000 0.120000 0.968000
+-0.800000 -0.050200 0.179900  0.264000 0.176000 0.944000
+-0.750000 -0.100400 0.174700  0.320000 0.192000 0.920000
+-0.750000 -0.050200 0.155100  0.464000 0.288000 0.832000
+-0.700000 -0.100400 0.138900  0.488000 0.288000 0.816000
+-0.708600 -0.050200 0.121900  0.496000 0.344000 0.784000
+-0.700000 -0.062200 0.121900  0.504000 0.344000 0.784000
+-0.700000 -0.050200 0.115300  0.496000 0.344000 0.792000
+-0.677900 -0.100400 0.121900  0.528000 0.328000 0.776000
+-0.650000 -0.050200 0.076400  0.576000 0.320000 0.744000
+-0.650000 -0.100400 0.096100  0.592000 0.288000 0.744000
+-0.635700 -0.050200 0.060900  0.640000 0.304000 0.696000
+-0.612900 -0.100400 0.060900  0.624000 0.376000 0.672000
+-0.600000 -0.050200 0.018400  0.648000 0.320000 0.688000
+-0.600000 -0.100400 0.044600  0.672000 0.336000 0.656000
+-0.584800 -0.050200 0.000000  0.744000 0.336000 0.568000
+-0.565600 -0.100400 0.000000  0.744000 0.440000 0.496000
+-0.554400 -0.050200 -0.060900  0.944000 0.280000 0.128000
+-0.550000 -0.100400 -0.036900  0.792000 0.376000 0.464000
+-0.550000 -0.066800 -0.060900  0.944000 0.320000 -0.008000
+-0.533200 -0.100400 -0.060900  0.712000 0.696000 -0.024000
+-0.550000 -0.100400 -0.079500  0.552000 0.552000 -0.616000
+-0.500000 -0.119500 -0.060900  -0.160000 0.976000 0.112000
+-0.550000 -0.145600 -0.121900  0.512000 0.792000 -0.312000
+-0.500000 -0.144400 -0.121900  -0.376000 0.880000 -0.280000
+-0.550000 -0.150600 -0.142400  0.376000 0.896000 -0.200000
+-0.500000 -0.150600 -0.154000  -0.424000 0.880000 -0.160000
+-0.550000 -0.155500 -0.182900  0.296000 0.920000 -0.232000
+-0.500000 -0.154300 -0.182900  -0.320000 0.920000 -0.176000
+-0.550000 -0.172700 -0.243900  0.008000 0.856000 -0.512000
+-0.500000 -0.169200 -0.243900  -0.328000 0.880000 -0.312000
+-0.550000 -0.200800 -0.303600  -0.040000 0.880000 -0.464000
+-0.500000 -0.196700 -0.304800  -0.120000 0.848000 -0.504000
+-0.544700 -0.200800 -0.304800  -0.080000 0.824000 -0.552000
+-0.500000 -0.200800 -0.313000  -0.112000 0.824000 -0.544000
+-0.550000 -0.201300 -0.304800  -0.032000 0.864000 -0.488000
+-0.500000 -0.238600 -0.365800  -0.072000 0.656000 -0.744000
+-0.550000 -0.245600 -0.365800  -0.104000 0.680000 -0.720000
+-0.500000 -0.251000 -0.377000  -0.032000 0.528000 -0.840000
+-0.550000 -0.251000 -0.371400  -0.120000 0.616000 -0.768000
+-0.500000 -0.301200 -0.402500  0.040000 0.344000 -0.936000
+-0.550000 -0.301200 -0.401000  0.000000 0.424000 -0.904000
+-0.500000 -0.351500 -0.423900  0.056000 0.504000 -0.856000
+-0.550000 -0.349500 -0.426800  0.056000 0.416000 -0.904000
+-0.538500 -0.351500 -0.426800  0.048000 0.480000 -0.872000
+-0.500000 -0.351500 -0.423900  0.056000 0.504000 -0.856000
+-0.500000 -0.355300 -0.426800  0.056000 0.520000 -0.848000
+-0.450000 -0.351500 -0.418600  0.080000 0.512000 -0.848000
+-0.450000 -0.362400 -0.426800  0.064000 0.520000 -0.848000
+-0.400000 -0.351500 -0.411400  0.000000 0.616000 -0.784000
+-0.400000 -0.368700 -0.426800  0.024000 0.560000 -0.824000
+-0.350000 -0.351500 -0.416300  -0.176000 0.600000 -0.768000
+-0.350000 -0.360100 -0.426800  -0.128000 0.680000 -0.712000
+-0.319100 -0.351500 -0.426800  -0.216000 0.568000 -0.784000
+-0.350000 -0.351500 -0.416300  -0.176000 0.600000 -0.768000
+-0.300000 -0.341100 -0.426800  -0.128000 0.536000 -0.832000
+-0.350000 -0.301200 -0.377400  0.232000 0.208000 -0.944000
+-0.300000 -0.301200 -0.369600  0.320000 0.544000 -0.768000
+-0.350000 -0.251000 -0.367200  0.240000 0.168000 -0.952000
+-0.300000 -0.296900 -0.365800  0.296000 0.528000 -0.784000
+-0.345700 -0.251000 -0.365800  0.320000 0.336000 -0.880000
+-0.300000 -0.251000 -0.348000  0.192000 0.248000 -0.944000
+-0.350000 -0.248400 -0.365800  0.184000 0.424000 -0.880000
+-0.300000 -0.200800 -0.340600  0.016000 0.280000 -0.952000
+-0.350000 -0.200800 -0.339000  0.200000 0.416000 -0.880000
+-0.300000 -0.150600 -0.319300  -0.256000 0.480000 -0.832000
+-0.350000 -0.159400 -0.304800  -0.248000 0.528000 -0.808000
+-0.331500 -0.150600 -0.304800  -0.256000 0.464000 -0.840000
+-0.350000 -0.150600 -0.298700  -0.264000 0.464000 -0.840000
+-0.300000 -0.118900 -0.304800  -0.376000 0.264000 -0.880000
+-0.350000 -0.100400 -0.248500  -0.576000 0.440000 -0.680000
+-0.300000 -0.100400 -0.298100  -0.480000 0.288000 -0.824000
+-0.350000 -0.093900 -0.243900  -0.600000 0.408000 -0.680000
+-0.300000 -0.050200 -0.270300  -0.824000 0.232000 -0.512000
+-0.321700 -0.050200 -0.243900  -0.656000 0.344000 -0.656000
+-0.300000 0.000000 -0.248500  -0.656000 0.560000 -0.488000
+-0.301700 0.000000 -0.243900  -0.744000 0.392000 -0.536000
+-0.300000 0.001800 -0.243900  -0.496000 0.680000 -0.520000
+-0.340600 0.000000 -0.182900  -0.696000 0.480000 -0.520000
+-0.300000 0.050200 -0.185100  -0.648000 0.560000 -0.504000
+-0.301000 0.050200 -0.182900  -0.704000 0.472000 -0.512000
+-0.300000 0.052000 -0.182900  -0.664000 0.464000 -0.568000
+-0.335400 0.050200 -0.121900  -0.752000 0.472000 -0.456000
+-0.300000 0.100400 -0.141500  -0.560000 0.512000 -0.640000
+-0.317300 0.100400 -0.121900  -0.712000 0.264000 -0.640000
+-0.300000 0.144000 -0.121900  -0.728000 0.496000 -0.456000
+-0.350000 0.100400 -0.076700  -0.736000 0.256000 -0.616000
+-0.300000 0.150600 -0.105900  -0.768000 0.536000 -0.320000
+-0.350000 0.148000 -0.060900  -0.504000 0.552000 0.656000
+-0.346000 0.150600 -0.060900  -0.768000 -0.144000 0.616000
+-0.350000 0.100400 -0.017600  -0.744000 0.352000 0.552000
+-0.300000 0.150600 -0.036000  -0.360000 0.064000 0.920000
+-0.321000 0.100400 0.000000  -0.264000 0.416000 0.864000
+-0.300000 0.112500 0.000000  -0.064000 0.472000 0.872000
+-0.300000 0.100400 0.006400  -0.200000 0.408000 0.880000
+-0.250000 0.104200 0.000000  0.144000 0.480000 0.856000
+-0.250000 0.100400 0.002600  0.144000 0.496000 0.848000
+-0.238500 0.100400 0.000000  0.152000 0.496000 0.848000
+-0.250000 0.050200 0.048300  0.000000 0.552000 0.832000
+-0.200000 0.089800 0.000000  0.216000 0.544000 0.800000
+-0.200000 0.050200 0.037800  0.512000 0.448000 0.720000
+-0.163800 0.050200 0.000000  0.704000 0.216000 0.664000
+-0.200000 0.020500 0.060900  0.664000 0.440000 0.600000
+-0.150800 0.000000 0.000000  0.744000 0.072000 0.656000
+-0.190300 0.000000 0.060900  0.816000 0.200000 0.536000
+-0.152800 -0.050200 0.000000  0.848000 0.032000 0.520000
+-0.193200 -0.050200 0.060900  0.808000 0.008000 0.584000
+-0.150600 -0.100400 0.000000  0.800000 0.040000 0.592000
+-0.190200 -0.100400 0.060900  0.752000 -0.248000 0.600000
+-0.150000 -0.104300 0.000000  0.496000 0.120000 0.848000
+-0.200000 -0.121800 0.060900  0.728000 -0.328000 0.592000
+-0.150000 -0.150600 0.010200  0.376000 0.208000 0.896000
+-0.200000 -0.150600 0.042600  0.640000 -0.096000 0.752000
+-0.150000 -0.200800 0.013600  0.104000 0.200000 0.968000
+-0.200000 -0.200800 0.045500  0.568000 -0.152000 0.808000
+-0.150000 -0.251000 0.002400  -0.056000 -0.176000 0.976000
+-0.200000 -0.251000 0.018200  0.408000 -0.392000 0.816000
+-0.150000 -0.301200 0.010200  -0.304000 -0.280000 0.904000
+-0.200000 -0.279600 0.000000  -0.016000 -0.496000 0.864000
+-0.169100 -0.301200 0.000000  -0.376000 -0.392000 0.832000
+-0.200000 -0.301200 -0.017500  -0.064000 -0.432000 0.896000
+-0.150000 -0.346200 0.000000  -0.392000 -0.160000 0.904000
+-0.200000 -0.351500 -0.031500  -0.320000 -0.128000 0.936000
+-0.150000 -0.351500 -0.001100  -0.192000 -0.352000 0.912000
+-0.200000 -0.401700 -0.023400  -0.056000 -0.008000 0.992000
+-0.150000 -0.401700 -0.019000  0.408000 -0.232000 0.880000
+-0.200000 -0.451900 -0.018000  0.376000 -0.112000 0.912000
+-0.150000 -0.451900 -0.041900  0.560000 -0.440000 0.696000
+-0.200000 -0.502100 -0.039000  0.512000 -0.608000 0.592000
+-0.150000 -0.470000 -0.060900  0.568000 -0.552000 0.600000
+-0.181900 -0.502100 -0.060900  0.504000 -0.680000 0.520000
+-0.150000 -0.502100 -0.111600  0.592000 -0.752000 0.280000
+-0.200000 -0.511900 -0.060900  0.416000 -0.800000 0.424000
+-0.150000 -0.505100 -0.121900  0.584000 -0.768000 0.240000
+-0.200000 -0.534300 -0.121900  0.456000 -0.832000 0.296000
+-0.150000 -0.510100 -0.182900  0.616000 -0.760000 0.168000
+-0.200000 -0.549300 -0.182900  0.504000 -0.784000 0.344000
+-0.150000 -0.530700 -0.243900  0.632000 -0.664000 0.392000
+-0.200000 -0.552300 -0.190900  0.520000 -0.768000 0.360000
+-0.172800 -0.552300 -0.243900  0.592000 -0.568000 0.560000
+-0.200000 -0.579600 -0.243900  0.568000 -0.648000 0.496000
+-0.150000 -0.552300 -0.270100  0.544000 -0.504000 0.656000
+-0.200000 -0.602500 -0.268600  0.488000 -0.432000 0.752000
+-0.150000 -0.602500 -0.302600  0.392000 -0.240000 0.880000
+-0.200000 -0.652700 -0.286600  0.488000 -0.272000 0.824000
+-0.150000 -0.609400 -0.304800  0.840000 -0.512000 0.152000
+-0.171500 -0.652700 -0.304800  0.576000 -0.304000 0.752000
+-0.150000 -0.602500 -0.307600  0.456000 -0.280000 -0.840000
+-0.200000 -0.652700 -0.326500  0.488000 -0.272000 -0.824000
+-0.200000 -0.602500 -0.345500  0.488000 -0.272000 -0.824000
+-0.250000 -0.652700 -0.361600  0.240000 -0.216000 -0.944000
+-0.229500 -0.602500 -0.365800  0.408000 -0.240000 -0.872000
+-0.250000 -0.639500 -0.365800  0.216000 -0.224000 -0.944000
+-0.250000 -0.602500 -0.376000  0.360000 -0.328000 -0.872000
+-0.282800 -0.652700 -0.365800  0.080000 -0.160000 -0.976000
+-0.300000 -0.602500 -0.397300  -0.248000 -0.488000 -0.832000
+-0.300000 -0.652700 -0.367500  0.064000 -0.112000 -0.984000
+-0.328400 -0.602500 -0.365800  -0.832000 -0.248000 -0.488000
+-0.350000 -0.652700 -0.376000  0.560000 0.160000 -0.808000
+-0.350000 -0.629600 -0.365800  0.056000 0.640000 -0.760000
+-0.400000 -0.652700 -0.368100  -0.128000 -0.872000 -0.456000
+-0.357100 -0.602500 -0.365800  0.904000 0.256000 -0.312000
+-0.400000 -0.621700 -0.426800  0.392000 -0.856000 -0.304000
+-0.370300 -0.602500 -0.426800  0.624000 -0.760000 -0.160000
+-0.357100 -0.602500 -0.365800  0.904000 0.256000 -0.312000
+-0.350000 -0.582100 -0.426800  0.344000 -0.808000 -0.456000
+-0.350000 -0.585900 -0.365800  0.168000 -0.792000 -0.576000
+-0.300000 -0.582000 -0.426800  0.336000 -0.608000 -0.712000
+-0.328400 -0.602500 -0.365800  -0.832000 -0.248000 -0.488000
+-0.300000 -0.602500 -0.397300  -0.248000 -0.488000 -0.832000
+-0.300000 -0.582000 -0.426800  0.336000 -0.608000 -0.712000
+-0.250000 -0.602500 -0.376000  0.360000 -0.328000 -0.872000
+-0.275900 -0.552300 -0.426800  0.528000 -0.480000 -0.696000
+-0.250000 -0.552300 -0.402600  0.504000 -0.312000 -0.792000
+-0.250000 -0.526200 -0.426800  0.576000 -0.448000 -0.672000
+-0.200000 -0.552300 -0.367100  0.360000 -0.232000 -0.896000
+-0.235700 -0.502100 -0.426800  0.696000 -0.464000 -0.536000
+-0.200000 -0.502100 -0.370700  0.184000 -0.352000 -0.912000
+-0.200000 -0.459900 -0.426800  0.560000 -0.592000 -0.576000
+-0.150000 -0.502100 -0.367300  0.088000 -0.320000 -0.936000
+-0.191200 -0.451900 -0.426800  0.664000 -0.480000 -0.560000
+-0.150000 -0.451900 -0.368100  0.456000 -0.056000 -0.880000
+-0.194300 -0.401700 -0.426800  0.792000 0.416000 -0.432000
+-0.150000 -0.417500 -0.365800  0.544000 0.056000 -0.832000
+-0.151700 -0.401700 -0.365800  0.568000 0.104000 -0.808000
+-0.150000 -0.401700 -0.364300  0.552000 0.080000 -0.824000
+-0.200000 -0.365300 -0.365800  0.504000 0.768000 -0.376000
+-0.150000 -0.351500 -0.350300  0.512000 0.192000 -0.832000
+-0.200000 -0.351500 -0.343300  0.312000 0.640000 -0.696000
+-0.150000 -0.301200 -0.318500  -0.024000 0.504000 -0.856000
+-0.200000 -0.301200 -0.313400  0.328000 0.152000 -0.928000
+-0.150000 -0.286300 -0.304800  -0.184000 0.480000 -0.848000
+-0.200000 -0.251000 -0.307600  0.408000 0.096000 -0.904000
+-0.195100 -0.251000 -0.304800  0.376000 0.112000 -0.912000
+-0.200000 -0.200800 -0.306700  0.368000 -0.184000 -0.904000
+-0.196100 -0.200800 -0.304800  0.360000 -0.200000 -0.904000
+-0.200000 -0.150600 -0.333300  0.216000 -0.272000 -0.936000
+-0.150000 -0.159100 -0.304800  0.152000 -0.400000 -0.896000
+-0.150000 -0.150600 -0.309500  -0.032000 -0.400000 -0.912000
+-0.108400 -0.200800 -0.304800  -0.496000 -0.048000 -0.856000
+-0.100000 -0.150600 -0.315000  -0.456000 -0.064000 -0.880000
+-0.100000 -0.200800 -0.311700  -0.496000 0.128000 -0.856000
+-0.050000 -0.150600 -0.332400  0.016000 -0.080000 -0.992000
+-0.050000 -0.200800 -0.320900  -0.056000 0.280000 -0.952000
+0.000000 -0.150600 -0.318000  0.160000 0.016000 -0.984000
+0.000000 -0.200800 -0.332000  -0.296000 0.528000 -0.784000
+0.050000 -0.150600 -0.318000  0.352000 0.312000 -0.872000
+0.050000 -0.200800 -0.360800  -0.016000 0.576000 -0.808000
+0.096000 -0.150600 -0.304800  0.176000 0.336000 -0.920000
+0.100000 -0.200800 -0.352600  0.240000 0.528000 -0.800000
+0.100000 -0.151600 -0.304800  -0.176000 0.536000 -0.816000
+0.150000 -0.200800 -0.325200  0.160000 0.176000 -0.968000
+0.101900 -0.150600 -0.304800  -0.296000 0.368000 -0.872000
+0.150000 -0.150600 -0.323600  -0.232000 0.464000 -0.848000
+0.114400 -0.100400 -0.304800  -0.344000 0.128000 -0.928000
+0.150000 -0.100400 -0.322200  0.000000 0.224000 -0.968000
+0.150000 -0.064700 -0.304800  -0.200000 0.328000 -0.912000
+0.185500 -0.100400 -0.304800  0.296000 0.104000 -0.944000
+0.150000 -0.050200 -0.298400  -0.176000 0.328000 -0.920000
+0.200000 -0.100400 -0.298900  0.088000 0.040000 -0.992000
+0.188500 -0.050200 -0.304800  -0.128000 0.184000 -0.968000
+0.200000 -0.061600 -0.304800  0.000000 -0.144000 -0.984000
+0.200000 -0.050200 -0.307000  0.000000 0.192000 -0.976000
+0.211400 -0.050200 -0.304800  0.152000 0.184000 -0.968000
+0.200000 -0.045300 -0.304800  -0.008000 0.344000 -0.936000
+0.250000 -0.050200 -0.297000  0.000000 0.040000 -0.992000
+0.200000 0.000000 -0.277300  0.080000 0.528000 -0.840000
+0.250000 0.000000 -0.271900  -0.336000 0.528000 -0.776000
+0.200000 0.025700 -0.243900  0.016000 0.752000 -0.648000
+0.250000 0.018500 -0.243900  -0.144000 0.856000 -0.480000
+0.200000 0.019700 -0.182900  0.160000 0.648000 0.736000
+0.250000 0.002800 -0.182900  0.128000 0.640000 0.752000
+0.200000 0.000000 -0.161400  0.032000 0.656000 0.752000
+0.250000 0.000000 -0.180400  0.176000 0.568000 0.792000
+0.200000 -0.041200 -0.121900  0.160000 0.488000 0.856000
+0.250000 -0.050200 -0.132500  0.192000 0.528000 0.816000
+0.222300 -0.050200 -0.121900  0.200000 0.432000 0.872000
+0.250000 -0.068700 -0.121900  0.096000 0.400000 0.904000
+0.200000 -0.050200 -0.116900  0.136000 0.368000 0.912000
+0.250000 -0.100400 -0.106800  0.080000 0.336000 0.936000
+0.200000 -0.100400 -0.095800  0.064000 0.272000 0.952000
+0.250000 -0.150600 -0.087200  0.040000 0.104000 0.992000
+0.200000 -0.150600 -0.099300  0.040000 0.104000 0.992000
+0.250000 -0.200800 -0.084100  0.120000 -0.168000 0.976000
+0.200000 -0.200800 -0.086600  0.112000 -0.336000 0.928000
+0.250000 -0.237200 -0.121900  0.048000 -0.656000 0.744000
+0.200000 -0.240500 -0.121900  0.152000 -0.656000 0.728000
+0.250000 -0.251000 -0.140300  -0.072000 -0.512000 0.848000
+0.200000 -0.251000 -0.134700  0.128000 -0.784000 0.600000
+0.250000 -0.301200 -0.149400  -0.376000 -0.584000 0.712000
+0.200000 -0.290700 -0.182900  -0.520000 -0.680000 0.512000
+0.211500 -0.301200 -0.182900  -0.568000 -0.672000 0.464000
+0.200000 -0.301200 -0.206400  -0.600000 -0.688000 0.384000
+0.250000 -0.319600 -0.182900  -0.280000 -0.832000 0.472000
+0.200000 -0.319700 -0.243900  -0.624000 -0.696000 0.328000
+0.250000 -0.343100 -0.243900  -0.320000 -0.920000 0.208000
+0.200000 -0.340400 -0.304800  -0.480000 -0.448000 -0.744000
+0.250000 -0.348300 -0.304800  -0.128000 -0.736000 -0.656000
+0.200000 -0.301200 -0.321600  -0.488000 -0.368000 -0.784000
+0.250000 -0.313600 -0.365800  -0.336000 -0.640000 -0.680000
+0.236200 -0.301200 -0.365800  -0.608000 -0.320000 -0.712000
+0.250000 -0.301200 -0.379400  -0.536000 -0.264000 -0.792000
+0.250000 -0.271800 -0.365800  -0.320000 0.360000 -0.872000
+0.300000 -0.301200 -0.372900  0.128000 -0.472000 -0.864000
+0.300000 -0.284400 -0.365800  0.136000 0.360000 -0.920000
+0.333500 -0.301200 -0.365800  0.208000 -0.080000 -0.968000
+0.300000 -0.251000 -0.347800  0.304000 0.384000 -0.864000
+0.350000 -0.301200 -0.360500  0.376000 0.184000 -0.904000
+0.350000 -0.251000 -0.329500  0.536000 0.472000 -0.688000
+0.400000 -0.301200 -0.307300  0.704000 0.496000 -0.496000
+0.366700 -0.251000 -0.304800  0.704000 0.488000 -0.496000
+0.400000 -0.299100 -0.304800  0.736000 0.472000 -0.472000
+0.399000 -0.251000 -0.243900  0.912000 -0.008000 -0.392000
+0.400000 -0.252300 -0.243900  0.744000 0.488000 -0.440000
+0.398900 -0.251000 -0.182900  0.896000 -0.160000 0.400000
+0.400000 -0.252800 -0.182900  0.760000 0.464000 0.440000
+0.354900 -0.251000 -0.121900  0.704000 -0.304000 0.632000
+0.400000 -0.301200 -0.149800  0.528000 0.376000 0.752000
+0.350000 -0.260400 -0.121900  0.448000 -0.472000 0.752000
+0.350000 -0.301200 -0.148100  0.392000 -0.048000 0.912000
+0.328900 -0.251000 -0.121900  -0.264000 -0.304000 0.912000
+0.300000 -0.301200 -0.149800  -0.024000 -0.480000 0.872000
+0.300000 -0.251000 -0.132800  -0.224000 -0.464000 0.856000
+0.250000 -0.301200 -0.149400  -0.376000 -0.584000 0.712000
+0.250000 -0.251000 -0.140300  -0.072000 -0.512000 0.848000
+0.300000 -0.251000 -0.132800  -0.224000 -0.464000 0.856000
+0.250000 -0.237200 -0.121900  0.048000 -0.656000 0.744000
+0.300000 -0.234400 -0.121900  0.104000 -0.472000 0.872000
+0.250000 -0.200800 -0.084100  0.120000 -0.168000 0.976000
+0.300000 -0.200800 -0.101500  0.424000 -0.216000 0.872000
+0.250000 -0.150600 -0.087200  0.040000 0.104000 0.992000
+0.300000 -0.150600 -0.090800  0.240000 -0.024000 0.968000
+0.250000 -0.100400 -0.106800  0.080000 0.336000 0.936000
+0.300000 -0.100400 -0.098900  -0.360000 0.344000 0.856000
+0.250000 -0.068700 -0.121900  0.096000 0.400000 0.904000
+0.300000 -0.060700 -0.121900  -0.512000 0.456000 0.720000
+0.250000 -0.050200 -0.132500  0.192000 0.528000 0.816000
+0.300000 -0.050200 -0.130700  -0.504000 0.472000 0.720000
+0.250000 0.000000 -0.180400  0.176000 0.568000 0.792000
+0.300000 0.000000 -0.166100  -0.488000 0.464000 0.728000
+0.250000 0.002800 -0.182900  0.128000 0.640000 0.752000
+0.300000 0.018000 -0.182900  -0.296000 0.768000 0.552000
+0.250000 0.018500 -0.243900  -0.144000 0.856000 -0.480000
+0.300000 0.032100 -0.243900  -0.576000 0.680000 -0.432000
+0.250000 0.000000 -0.271900  -0.336000 0.528000 -0.776000
+0.300000 0.000000 -0.302400  -0.544000 0.608000 -0.568000
+0.250000 -0.050200 -0.297000  0.000000 0.040000 -0.992000
+0.300000 -0.003100 -0.304800  -0.376000 0.424000 -0.816000
+0.266500 -0.050200 -0.304800  -0.280000 0.064000 -0.952000
+0.300000 -0.050200 -0.319900  -0.536000 0.224000 -0.808000
+0.278900 -0.100400 -0.304800  -0.176000 0.256000 -0.944000
+0.300000 -0.100400 -0.310000  -0.248000 0.072000 -0.960000
+0.250000 -0.114900 -0.304800  -0.104000 0.280000 -0.952000
+0.300000 -0.150600 -0.312600  0.312000 -0.200000 -0.920000
+0.250000 -0.150600 -0.317700  0.024000 0.336000 -0.936000
+0.300000 -0.200800 -0.324200  0.480000 0.248000 -0.832000
+0.250000 -0.200800 -0.343100  0.104000 0.232000 -0.960000
+0.300000 -0.251000 -0.347800  0.304000 0.384000 -0.864000
+0.250000 -0.251000 -0.353900  0.064000 0.384000 -0.920000
+0.300000 -0.284400 -0.365800  0.136000 0.360000 -0.920000
+0.250000 -0.271800 -0.365800  -0.320000 0.360000 -0.872000
+0.250000 -0.251000 -0.353900  0.064000 0.384000 -0.920000
+0.236200 -0.301200 -0.365800  -0.608000 -0.320000 -0.712000
+0.200000 -0.251000 -0.346500  -0.184000 0.088000 -0.976000
+0.200000 -0.301200 -0.321600  -0.488000 -0.368000 -0.784000
+0.150000 -0.251000 -0.336000  0.080000 -0.336000 -0.928000
+0.170700 -0.301200 -0.304800  -0.520000 -0.608000 -0.592000
+0.150000 -0.287400 -0.304800  0.000000 -0.712000 -0.688000
+0.176900 -0.301200 -0.243900  -0.504000 -0.800000 0.304000
+0.150000 -0.287700 -0.243900  -0.208000 -0.968000 0.064000
+0.200000 -0.301200 -0.206400  -0.600000 -0.688000 0.384000
+0.150000 -0.278000 -0.182900  -0.064000 -0.936000 0.328000
+0.200000 -0.290700 -0.182900  -0.520000 -0.680000 0.512000
+0.150000 -0.253200 -0.121900  0.192000 -0.808000 0.552000
+0.200000 -0.251000 -0.134700  0.128000 -0.784000 0.600000
+0.161400 -0.251000 -0.121900  0.152000 -0.792000 0.576000
+0.200000 -0.240500 -0.121900  0.152000 -0.656000 0.728000
+0.150000 -0.251000 -0.118100  0.224000 -0.792000 0.560000
+0.200000 -0.200800 -0.086600  0.112000 -0.336000 0.928000
+0.150000 -0.200800 -0.071800  0.312000 -0.208000 0.920000
+0.200000 -0.150600 -0.099300  0.040000 0.104000 0.992000
+0.150000 -0.150600 -0.071000  0.136000 0.176000 0.968000
+0.200000 -0.100400 -0.095800  0.064000 0.272000 0.952000
+0.150000 -0.100400 -0.080500  0.184000 0.336000 0.920000
+0.200000 -0.050200 -0.116900  0.136000 0.368000 0.912000
+0.150000 -0.050200 -0.113700  0.032000 0.448000 0.888000
+0.200000 -0.041200 -0.121900  0.160000 0.488000 0.856000
+0.150000 -0.036300 -0.121900  0.008000 0.488000 0.864000
+0.200000 0.000000 -0.161400  0.032000 0.656000 0.752000
+0.150000 0.000000 -0.166100  -0.096000 0.688000 0.712000
+0.200000 0.019700 -0.182900  0.160000 0.648000 0.736000
+0.150000 0.016800 -0.182900  -0.152000 0.840000 0.520000
+0.200000 0.025700 -0.243900  0.016000 0.752000 -0.648000
+0.150000 0.015400 -0.243900  -0.208000 0.728000 -0.640000
+0.200000 0.000000 -0.277300  0.080000 0.528000 -0.840000
+0.150000 0.000000 -0.257100  -0.208000 0.552000 -0.800000
+0.200000 -0.045300 -0.304800  -0.008000 0.344000 -0.936000
+0.150000 -0.050200 -0.298400  -0.176000 0.328000 -0.920000
+0.188500 -0.050200 -0.304800  -0.128000 0.184000 -0.968000
+0.200000 -0.045300 -0.304800  -0.008000 0.344000 -0.936000
+0.200000 -0.050200 -0.307000  0.000000 0.192000 -0.976000
+0.200000 -0.050200 -0.307000  0.000000 0.192000 -0.976000
+-0.800000 -0.100400 0.186900  0.104000 0.048000 0.992000
+-0.800000 -0.100400 0.186900  0.104000 0.048000 0.992000
+-0.776900 -0.100400 0.182900  0.184000 0.120000 0.968000
+-0.800000 -0.150600 0.189500  -0.240000 -0.056000 0.960000
+-0.750000 -0.136500 0.182900  0.216000 0.112000 0.968000
+-0.750000 -0.150600 0.184600  0.192000 0.080000 0.976000
+-0.743500 -0.150600 0.182900  0.192000 0.096000 0.968000
+-0.750000 -0.200800 0.187200  0.064000 -0.048000 0.992000
+-0.703900 -0.200800 0.182900  0.128000 0.064000 0.984000
+-0.750000 -0.251000 0.186100  -0.160000 -0.136000 0.976000
+-0.700000 -0.208700 0.182900  0.176000 0.120000 0.968000
+-0.700000 -0.251000 0.184700  0.008000 -0.024000 0.992000
+-0.650000 -0.249200 0.182900  0.176000 0.464000 0.864000
+-0.650000 -0.251000 0.183700  0.152000 0.272000 0.944000
+-0.638500 -0.251000 0.182900  0.072000 0.424000 0.896000
+-0.650000 -0.301200 0.185200  -0.152000 0.008000 0.984000
+-0.600000 -0.260000 0.182900  0.056000 0.320000 0.944000
+-0.600000 -0.301200 0.196400  -0.152000 0.176000 0.968000
+-0.550000 -0.264400 0.182900  -0.072000 0.456000 0.880000
+-0.550000 -0.301200 0.200100  -0.040000 0.312000 0.944000
+-0.512000 -0.251000 0.182900  -0.112000 0.632000 0.760000
+-0.500000 -0.301200 0.199600  -0.128000 0.216000 0.960000
+-0.500000 -0.251000 0.185100  -0.112000 0.632000 0.760000
+-0.450000 -0.301200 0.203900  0.032000 0.168000 0.984000
+-0.450000 -0.251000 0.195400  -0.152000 0.392000 0.904000
+-0.400000 -0.301200 0.211000  0.416000 0.000000 0.904000
+-0.400000 -0.251000 0.203200  0.024000 0.208000 0.976000
+-0.369700 -0.301200 0.182900  0.552000 -0.328000 0.752000
+-0.350000 -0.251000 0.206900  0.584000 -0.272000 0.760000
+-0.350000 -0.276800 0.182900  0.600000 -0.432000 0.664000
+-0.334800 -0.251000 0.182900  0.672000 -0.480000 0.552000
+-0.350000 -0.301200 0.167500  0.592000 -0.368000 0.712000
+-0.300000 -0.251000 0.131000  0.632000 -0.616000 0.464000
+-0.327200 -0.301200 0.121900  0.792000 -0.368000 0.472000
+-0.300000 -0.256400 0.121900  0.624000 -0.624000 0.456000
+-0.300000 -0.301200 0.065200  0.504000 -0.568000 0.640000
+-0.294600 -0.251000 0.121900  0.616000 -0.600000 0.488000
+-0.295000 -0.301200 0.060900  0.472000 -0.584000 0.648000
+-0.250000 -0.251000 0.071500  0.528000 -0.408000 0.736000
+-0.250000 -0.262800 0.060900  0.496000 -0.520000 0.688000
+-0.236900 -0.251000 0.060900  0.464000 -0.480000 0.728000
+-0.250000 -0.301200 0.006000  0.344000 -0.608000 0.704000
+-0.200000 -0.251000 0.018200  0.408000 -0.392000 0.816000
+-0.235900 -0.301200 0.000000  0.272000 -0.568000 0.768000
+-0.200000 -0.279600 0.000000  -0.016000 -0.496000 0.864000
+-0.200000 -0.301200 -0.017500  -0.064000 -0.432000 0.896000
+-0.235900 -0.301200 0.000000  0.272000 -0.568000 0.768000
+-0.200000 -0.351500 -0.031500  -0.320000 -0.128000 0.936000
+-0.250000 -0.307700 0.000000  0.288000 -0.576000 0.760000
+-0.250000 -0.351500 -0.038300  0.104000 -0.504000 0.848000
+-0.300000 -0.343500 0.000000  0.832000 -0.408000 0.360000
+-0.300000 -0.351500 -0.012600  0.872000 -0.352000 0.320000
+-0.303300 -0.351500 0.000000  0.888000 -0.344000 0.288000
+-0.300000 -0.401700 -0.045100  0.792000 -0.248000 0.544000
+-0.319500 -0.401700 0.000000  0.536000 -0.584000 0.592000
+-0.300000 -0.435300 -0.060900  -0.192000 -0.360000 0.912000
+-0.350000 -0.427600 0.000000  0.560000 -0.752000 0.336000
+-0.338500 -0.451900 -0.060900  0.112000 -0.632000 0.760000
+-0.350000 -0.451900 -0.058800  0.248000 -0.624000 0.728000
+-0.350000 -0.453900 -0.060900  0.248000 -0.624000 0.728000
+-0.400000 -0.451900 -0.009600  0.744000 -0.536000 0.376000
+-0.380200 -0.502100 -0.060900  0.648000 -0.616000 0.432000
+-0.400000 -0.502100 -0.024700  0.848000 -0.224000 0.464000
+-0.400000 -0.527700 -0.060900  0.080000 -0.768000 0.624000
+-0.450000 -0.502100 -0.045100  0.560000 -0.696000 0.432000
+-0.450000 -0.512800 -0.060900  0.208000 -0.760000 0.608000
+-0.466200 -0.502100 0.000000  0.712000 -0.616000 0.320000
+-0.478800 -0.552300 -0.060900  0.704000 -0.592000 0.376000
+-0.500000 -0.548400 0.000000  0.368000 -0.816000 0.432000
+-0.500000 -0.552300 -0.009400  0.352000 -0.840000 0.400000
+-0.509600 -0.552300 0.000000  0.320000 -0.840000 0.424000
+-0.500000 -0.570000 -0.060900  0.480000 -0.800000 0.328000
+-0.550000 -0.565800 0.000000  0.224000 -0.872000 0.424000
+-0.550000 -0.588500 -0.060900  0.224000 -0.888000 0.384000
+-0.600000 -0.566300 0.000000  -0.184000 -0.816000 0.544000
+-0.600000 -0.601900 -0.060900  -0.072000 -0.808000 0.568000
+-0.633400 -0.552300 0.000000  -0.384000 -0.672000 0.624000
+-0.650000 -0.594800 -0.060900  -0.368000 -0.640000 0.664000
+-0.650000 -0.552300 -0.012600  -0.496000 -0.592000 0.624000
+-0.685200 -0.552300 -0.060900  -0.696000 -0.384000 0.592000
+-0.650000 -0.541900 0.000000  -0.528000 -0.600000 0.592000
+-0.700000 -0.507800 -0.060900  -0.864000 -0.200000 0.448000
+-0.674300 -0.502100 0.000000  -0.656000 -0.632000 0.384000
+-0.700000 -0.502100 -0.057900  -0.752000 -0.512000 0.400000
+-0.700000 -0.478200 0.000000  -0.704000 -0.632000 0.312000
+-0.701200 -0.502100 -0.060900  -0.816000 -0.416000 0.392000
+-0.719800 -0.451900 0.000000  -0.816000 -0.520000 0.240000
+-0.735400 -0.451900 -0.060900  -0.768000 -0.512000 0.360000
+-0.750000 -0.403200 0.000000  -0.832000 -0.504000 0.216000
+-0.750000 -0.426100 -0.060900  -0.864000 -0.448000 0.200000
+-0.750800 -0.401700 0.000000  -0.816000 -0.520000 0.208000
+-0.762700 -0.401700 -0.060900  -0.840000 -0.496000 0.168000
+-0.782800 -0.351500 0.000000  -0.816000 -0.536000 0.208000
+-0.794800 -0.351500 -0.060900  -0.816000 -0.552000 0.144000
+-0.800000 -0.327900 0.000000  -0.800000 -0.560000 0.176000
+-0.800000 -0.343900 -0.060900  -0.816000 -0.552000 0.128000
+-0.817700 -0.301200 0.000000  -0.808000 -0.560000 0.168000
+-0.826600 -0.301200 -0.060900  -0.824000 -0.544000 0.120000
+-0.800000 -0.343900 -0.060900  -0.816000 -0.552000 0.128000
+-0.832400 -0.301200 -0.121900  -0.840000 -0.528000 0.048000
+-0.800000 -0.351500 -0.101400  -0.840000 -0.528000 0.104000
+-0.802000 -0.351500 -0.121900  -0.840000 -0.520000 0.096000
+-0.800000 -0.354700 -0.121900  -0.848000 -0.512000 0.080000
+-0.802200 -0.351500 -0.182900  -0.872000 -0.480000 0.016000
+-0.800000 -0.355500 -0.182900  -0.872000 -0.472000 0.032000
+-0.807300 -0.351500 -0.243900  -0.864000 -0.472000 0.152000
+-0.800000 -0.365300 -0.243900  -0.880000 -0.440000 0.160000
+-0.821000 -0.351500 -0.304800  -0.824000 -0.504000 0.232000
+-0.800000 -0.395700 -0.304800  -0.920000 -0.376000 0.000000
+-0.812200 -0.351500 -0.365800  -0.856000 -0.296000 -0.408000
+-0.800000 -0.388500 -0.365800  -0.864000 -0.288000 -0.400000
+-0.800000 -0.351500 -0.388300  -0.664000 -0.152000 -0.728000
+-0.796500 -0.401700 -0.365800  -0.952000 -0.168000 -0.232000
+-0.750000 -0.351500 -0.422100  -0.312000 0.448000 -0.824000
+-0.777800 -0.401700 -0.426800  -0.928000 0.040000 -0.360000
+-0.750000 -0.359700 -0.426800  -0.368000 0.408000 -0.832000
+-0.750000 -0.351500 -0.422100  -0.312000 0.448000 -0.824000
+-0.736800 -0.351500 -0.426800  -0.240000 0.480000 -0.832000
+-0.736800 -0.351500 -0.426800  -0.240000 0.480000 -0.832000
+-0.750000 -0.150600 0.184600  0.192000 0.080000 0.976000
+-0.750000 -0.150600 0.184600  0.192000 0.080000 0.976000
+-0.800000 -0.150600 0.189500  -0.240000 -0.056000 0.960000
+-0.750000 -0.200800 0.187200  0.064000 -0.048000 0.992000
+-0.800000 -0.200800 0.184500  -0.256000 -0.128000 0.952000
+-0.750000 -0.251000 0.186100  -0.160000 -0.136000 0.976000
+-0.800000 -0.206500 0.182900  -0.304000 -0.264000 0.912000
+-0.762000 -0.251000 0.182900  -0.256000 -0.192000 0.936000
+-0.800000 -0.251000 0.157900  -0.576000 -0.400000 0.696000
+-0.750000 -0.267900 0.182900  -0.232000 -0.192000 0.944000
+-0.800000 -0.280700 0.121900  -0.736000 -0.528000 0.408000
+-0.750000 -0.301200 0.168400  -0.360000 -0.432000 0.816000
+-0.783300 -0.301200 0.121900  -0.688000 -0.568000 0.440000
+-0.750000 -0.342500 0.121900  -0.536000 -0.592000 0.592000
+-0.800000 -0.301200 0.085900  -0.768000 -0.544000 0.304000
+-0.750000 -0.351500 0.110100  -0.600000 -0.584000 0.536000
+-0.800000 -0.310100 0.060900  -0.800000 -0.544000 0.224000
+-0.767900 -0.351500 0.060900  -0.760000 -0.568000 0.296000
+-0.800000 -0.327900 0.000000  -0.800000 -0.560000 0.176000
+-0.782800 -0.351500 0.000000  -0.816000 -0.536000 0.208000
+-0.767900 -0.351500 0.060900  -0.760000 -0.568000 0.296000
+-0.750800 -0.401700 0.000000  -0.816000 -0.520000 0.208000
+-0.750000 -0.377100 0.060900  -0.760000 -0.552000 0.320000
+-0.750000 -0.401700 0.004100  -0.816000 -0.520000 0.232000
+-0.731300 -0.401700 0.060900  -0.784000 -0.496000 0.344000
+-0.750000 -0.403200 0.000000  -0.832000 -0.504000 0.216000
+-0.701000 -0.451900 0.060900  -0.792000 -0.480000 0.344000
+-0.719800 -0.451900 0.000000  -0.816000 -0.520000 0.240000
+-0.700000 -0.453200 0.060900  -0.560000 -0.720000 0.392000
+-0.700000 -0.478200 0.000000  -0.704000 -0.632000 0.312000
+-0.650000 -0.495900 0.060900  -0.528000 -0.720000 0.432000
+-0.674300 -0.502100 0.000000  -0.656000 -0.632000 0.384000
+-0.650000 -0.502100 0.048300  -0.536000 -0.712000 0.440000
+-0.650000 -0.541900 0.000000  -0.528000 -0.600000 0.592000
+-0.640700 -0.502100 0.060900  -0.496000 -0.728000 0.456000
+-0.633400 -0.552300 0.000000  -0.384000 -0.672000 0.624000
+-0.600000 -0.531600 0.060900  -0.448000 -0.736000 0.496000
+-0.600000 -0.552300 0.023900  -0.224000 -0.776000 0.584000
+-0.550000 -0.532000 0.060900  0.080000 -0.776000 0.624000
+-0.550000 -0.552300 0.031000  0.256000 -0.800000 0.528000
+-0.500000 -0.517700 0.060900  0.632000 -0.632000 0.440000
+-0.509600 -0.552300 0.000000  0.320000 -0.840000 0.424000
+-0.500000 -0.548400 0.000000  0.368000 -0.816000 0.432000
+-0.500000 -0.517700 0.060900  0.632000 -0.632000 0.440000
+-0.466200 -0.502100 0.000000  0.712000 -0.616000 0.320000
+-0.489100 -0.502100 0.060900  0.704000 -0.616000 0.328000
+-0.450000 -0.489500 0.000000  0.584000 -0.760000 0.264000
+-0.450000 -0.471900 0.060900  0.592000 -0.752000 0.272000
+-0.403800 -0.451900 0.000000  0.744000 -0.560000 0.352000
+-0.425300 -0.451900 0.060900  0.696000 -0.640000 0.304000
+-0.400000 -0.447100 0.000000  0.720000 -0.584000 0.344000
+-0.400000 -0.423000 0.060900  0.616000 -0.696000 0.360000
+-0.350000 -0.427600 0.000000  0.560000 -0.752000 0.336000
+-0.350000 -0.406300 0.060900  0.592000 -0.728000 0.320000
+-0.319500 -0.401700 0.000000  0.536000 -0.584000 0.592000
+-0.344500 -0.401700 0.060900  0.632000 -0.688000 0.328000
+-0.303300 -0.351500 0.000000  0.888000 -0.344000 0.288000
+-0.319700 -0.351500 0.060900  0.864000 -0.376000 0.328000
+-0.300000 -0.343500 0.000000  0.832000 -0.408000 0.360000
+-0.300000 -0.305300 0.060900  0.512000 -0.568000 0.632000
+-0.250000 -0.307700 0.000000  0.288000 -0.576000 0.760000
+-0.295000 -0.301200 0.060900  0.472000 -0.584000 0.648000
+-0.250000 -0.301200 0.006000  0.344000 -0.608000 0.704000
+-0.250000 -0.262800 0.060900  0.496000 -0.520000 0.688000
+-0.250000 -0.262800 0.060900  0.496000 -0.520000 0.688000
+-0.762000 -0.251000 0.182900  -0.256000 -0.192000 0.936000
+-0.762000 -0.251000 0.182900  -0.256000 -0.192000 0.936000
+-0.750000 -0.251000 0.186100  -0.160000 -0.136000 0.976000
+-0.750000 -0.267900 0.182900  -0.232000 -0.192000 0.944000
+-0.700000 -0.251000 0.184700  0.008000 -0.024000 0.992000
+-0.700000 -0.272200 0.182900  -0.072000 -0.128000 0.984000
+-0.650000 -0.251000 0.183700  0.152000 0.272000 0.944000
+-0.671000 -0.301200 0.182900  -0.120000 -0.104000 0.984000
+-0.650000 -0.301200 0.185200  -0.152000 0.008000 0.984000
+-0.663400 -0.351500 0.182900  -0.304000 -0.080000 0.944000
+-0.650000 -0.351500 0.187800  -0.272000 -0.048000 0.952000
+-0.650000 -0.385200 0.182900  -0.496000 -0.152000 0.848000
+-0.600000 -0.351500 0.201700  -0.216000 0.016000 0.968000
+-0.644900 -0.401700 0.182900  -0.528000 -0.240000 0.808000
+-0.600000 -0.401700 0.205900  -0.320000 -0.144000 0.928000
+-0.600000 -0.446800 0.182900  -0.240000 -0.464000 0.848000
+-0.550000 -0.401700 0.218500  0.000000 -0.272000 0.960000
+-0.583500 -0.451900 0.182900  -0.128000 -0.544000 0.824000
+-0.550000 -0.451900 0.188900  -0.024000 -0.624000 0.776000
+-0.550000 -0.456500 0.182900  0.056000 -0.736000 0.672000
+-0.523100 -0.451900 0.182900  0.136000 -0.648000 0.744000
+-0.550000 -0.494000 0.121900  0.024000 -0.832000 0.536000
+-0.500000 -0.451900 0.177400  0.160000 -0.648000 0.736000
+-0.500000 -0.486900 0.121900  0.296000 -0.800000 0.504000
+-0.450000 -0.451900 0.126400  0.752000 -0.472000 0.448000
+-0.450000 -0.453600 0.121900  0.584000 -0.744000 0.288000
+-0.447800 -0.451900 0.121900  0.672000 -0.648000 0.344000
+-0.450000 -0.471900 0.060900  0.592000 -0.752000 0.272000
+-0.425300 -0.451900 0.060900  0.696000 -0.640000 0.304000
+-0.447800 -0.451900 0.121900  0.672000 -0.648000 0.344000
+-0.400000 -0.423000 0.060900  0.616000 -0.696000 0.360000
+-0.404400 -0.401700 0.121900  0.648000 -0.656000 0.368000
+-0.400000 -0.401700 0.111300  0.640000 -0.680000 0.336000
+-0.400000 -0.397400 0.121900  0.632000 -0.672000 0.368000
+-0.350000 -0.401700 0.073400  0.632000 -0.688000 0.344000
+-0.350000 -0.369000 0.121900  0.736000 -0.464000 0.480000
+-0.344500 -0.401700 0.060900  0.632000 -0.688000 0.328000
+-0.341600 -0.351500 0.121900  0.808000 -0.352000 0.456000
+-0.319700 -0.351500 0.060900  0.864000 -0.376000 0.328000
+-0.327200 -0.301200 0.121900  0.792000 -0.368000 0.472000
+-0.300000 -0.305300 0.060900  0.512000 -0.568000 0.632000
+-0.300000 -0.301200 0.065200  0.504000 -0.568000 0.640000
+-0.295000 -0.301200 0.060900  0.472000 -0.584000 0.648000
+-0.295000 -0.301200 0.060900  0.472000 -0.584000 0.648000
+-0.650000 -0.301200 0.185200  -0.152000 0.008000 0.984000
+-0.650000 -0.301200 0.185200  -0.152000 0.008000 0.984000
+-0.650000 -0.351500 0.187800  -0.272000 -0.048000 0.952000
+-0.600000 -0.301200 0.196400  -0.152000 0.176000 0.968000
+-0.600000 -0.351500 0.201700  -0.216000 0.016000 0.968000
+-0.550000 -0.301200 0.200100  -0.040000 0.312000 0.944000
+-0.550000 -0.351500 0.211500  0.000000 0.128000 0.984000
+-0.500000 -0.301200 0.199600  -0.128000 0.216000 0.960000
+-0.500000 -0.351500 0.209200  0.072000 0.104000 0.984000
+-0.450000 -0.301200 0.203900  0.032000 0.168000 0.984000
+-0.450000 -0.351500 0.215900  0.592000 -0.216000 0.768000
+-0.400000 -0.301200 0.211000  0.416000 0.000000 0.904000
+-0.400000 -0.351500 0.196700  0.560000 -0.576000 0.584000
+-0.369700 -0.301200 0.182900  0.552000 -0.328000 0.752000
+-0.389000 -0.351500 0.182900  0.544000 -0.632000 0.536000
+-0.350000 -0.301200 0.167500  0.592000 -0.368000 0.712000
+-0.350000 -0.351500 0.138600  0.680000 -0.440000 0.568000
+-0.327200 -0.301200 0.121900  0.792000 -0.368000 0.472000
+-0.341600 -0.351500 0.121900  0.808000 -0.352000 0.456000
+-0.350000 -0.351500 0.138600  0.680000 -0.440000 0.568000
+-0.350000 -0.369000 0.121900  0.736000 -0.464000 0.480000
+-0.389000 -0.351500 0.182900  0.544000 -0.632000 0.536000
+-0.400000 -0.397400 0.121900  0.632000 -0.672000 0.368000
+-0.400000 -0.359600 0.182900  0.520000 -0.680000 0.496000
+-0.404400 -0.401700 0.121900  0.648000 -0.656000 0.368000
+-0.445800 -0.401700 0.182900  0.648000 -0.488000 0.568000
+-0.447800 -0.451900 0.121900  0.672000 -0.648000 0.344000
+-0.450000 -0.407300 0.182900  0.664000 -0.488000 0.552000
+-0.450000 -0.451900 0.126400  0.752000 -0.472000 0.448000
+-0.500000 -0.444100 0.182900  0.168000 -0.480000 0.848000
+-0.500000 -0.451900 0.177400  0.160000 -0.648000 0.736000
+-0.523100 -0.451900 0.182900  0.136000 -0.648000 0.744000
+-0.500000 -0.444100 0.182900  0.168000 -0.480000 0.848000
+-0.550000 -0.451900 0.188900  -0.024000 -0.624000 0.776000
+-0.500000 -0.401700 0.210500  0.208000 -0.296000 0.928000
+-0.550000 -0.401700 0.218500  0.000000 -0.272000 0.960000
+-0.500000 -0.351500 0.209200  0.072000 0.104000 0.984000
+-0.550000 -0.351500 0.211500  0.000000 0.128000 0.984000
+-0.550000 -0.401700 0.218500  0.000000 -0.272000 0.960000
+-0.600000 -0.351500 0.201700  -0.216000 0.016000 0.968000
+-0.600000 -0.401700 0.205900  -0.320000 -0.144000 0.928000
+-0.600000 -0.401700 0.205900  -0.320000 -0.144000 0.928000
+-0.512000 -0.251000 0.182900  -0.112000 0.632000 0.760000
+-0.512000 -0.251000 0.182900  -0.112000 0.632000 0.760000
+-0.500000 -0.249000 0.182900  -0.112000 0.656000 0.744000
+-0.500000 -0.251000 0.185100  -0.112000 0.632000 0.760000
+-0.450000 -0.233700 0.182900  -0.216000 0.472000 0.848000
+-0.450000 -0.251000 0.195400  -0.152000 0.392000 0.904000
+-0.400000 -0.206800 0.182900  -0.168000 0.424000 0.880000
+-0.400000 -0.251000 0.203200  0.024000 0.208000 0.976000
+-0.383500 -0.200800 0.182900  -0.152000 0.448000 0.872000
+-0.350000 -0.251000 0.206900  0.584000 -0.272000 0.760000
+-0.350000 -0.200800 0.190300  -0.112000 0.384000 0.912000
+-0.334800 -0.251000 0.182900  0.672000 -0.480000 0.552000
+-0.300000 -0.200800 0.189700  0.744000 -0.432000 0.496000
+-0.300000 -0.205800 0.182900  0.768000 -0.472000 0.416000
+-0.296900 -0.200800 0.182900  0.792000 -0.440000 0.408000
+-0.300000 -0.251000 0.131000  0.632000 -0.616000 0.464000
+-0.278100 -0.200800 0.121900  0.816000 -0.432000 0.368000
+-0.294600 -0.251000 0.121900  0.616000 -0.600000 0.488000
+-0.250000 -0.200800 0.078600  0.664000 -0.312000 0.672000
+-0.250000 -0.251000 0.071500  0.528000 -0.408000 0.736000
+-0.222100 -0.200800 0.060900  0.488000 -0.184000 0.848000
+-0.236900 -0.251000 0.060900  0.464000 -0.480000 0.728000
+-0.200000 -0.200800 0.045500  0.568000 -0.152000 0.808000
+-0.200000 -0.251000 0.018200  0.408000 -0.392000 0.816000
+-0.200000 -0.251000 0.018200  0.408000 -0.392000 0.816000
+-0.450000 -0.351500 0.215900  0.592000 -0.216000 0.768000
+-0.450000 -0.351500 0.215900  0.592000 -0.216000 0.768000
+-0.500000 -0.351500 0.209200  0.072000 0.104000 0.984000
+-0.450000 -0.401700 0.188700  0.656000 -0.464000 0.584000
+-0.500000 -0.401700 0.210500  0.208000 -0.296000 0.928000
+-0.450000 -0.407300 0.182900  0.664000 -0.488000 0.552000
+-0.500000 -0.444100 0.182900  0.168000 -0.480000 0.848000
+-0.500000 -0.444100 0.182900  0.168000 -0.480000 0.848000
+-0.400000 -0.351500 0.196700  0.560000 -0.576000 0.584000
+-0.400000 -0.351500 0.196700  0.560000 -0.576000 0.584000
+-0.400000 -0.359600 0.182900  0.520000 -0.680000 0.496000
+-0.450000 -0.351500 0.215900  0.592000 -0.216000 0.768000
+-0.445800 -0.401700 0.182900  0.648000 -0.488000 0.568000
+-0.450000 -0.401700 0.188700  0.656000 -0.464000 0.584000
+-0.450000 -0.407300 0.182900  0.664000 -0.488000 0.552000
+-0.450000 -0.407300 0.182900  0.664000 -0.488000 0.552000
+-0.383500 -0.200800 0.182900  -0.152000 0.448000 0.872000
+-0.383500 -0.200800 0.182900  -0.152000 0.448000 0.872000
+-0.350000 -0.189600 0.182900  -0.288000 0.472000 0.824000
+-0.350000 -0.200800 0.190300  -0.112000 0.384000 0.912000
+-0.311100 -0.150600 0.182900  -0.424000 0.464000 0.768000
+-0.300000 -0.200800 0.189700  0.744000 -0.432000 0.496000
+-0.300000 -0.150600 0.190700  0.000000 0.520000 0.848000
+-0.296900 -0.200800 0.182900  0.792000 -0.440000 0.408000
+-0.288800 -0.150600 0.182900  0.600000 0.360000 0.712000
+-0.278100 -0.200800 0.121900  0.816000 -0.432000 0.368000
+-0.252800 -0.150600 0.121900  0.720000 -0.296000 0.616000
+-0.250000 -0.200800 0.078600  0.664000 -0.312000 0.672000
+-0.250000 -0.150600 0.117900  0.712000 -0.320000 0.616000
+-0.222100 -0.200800 0.060900  0.488000 -0.184000 0.848000
+-0.212600 -0.150600 0.060900  0.712000 -0.216000 0.664000
+-0.200000 -0.200800 0.045500  0.568000 -0.152000 0.808000
+-0.200000 -0.150600 0.042600  0.640000 -0.096000 0.752000
+-0.212600 -0.150600 0.060900  0.712000 -0.216000 0.664000
+-0.200000 -0.121800 0.060900  0.728000 -0.328000 0.592000
+-0.250000 -0.150600 0.117900  0.712000 -0.320000 0.616000
+-0.200000 -0.100400 0.076800  0.784000 -0.136000 0.600000
+-0.250000 -0.144000 0.121900  0.720000 -0.312000 0.608000
+-0.230200 -0.100400 0.121900  0.776000 -0.176000 0.600000
+-0.250000 -0.100400 0.155000  0.480000 0.160000 0.856000
+-0.247100 -0.050200 0.121900  0.488000 0.512000 0.696000
+-0.250000 -0.050200 0.123600  0.200000 0.440000 0.864000
+-0.250000 -0.048000 0.121900  0.272000 0.640000 0.704000
+-0.255700 -0.050200 0.121900  -0.192000 0.512000 0.832000
+-0.250000 0.000000 0.079500  -0.144000 0.552000 0.816000
+-0.300000 -0.050200 0.104800  -0.312000 0.512000 0.792000
+-0.300000 0.000000 0.088800  -0.240000 0.432000 0.864000
+-0.350000 -0.050200 0.083200  -0.416000 0.344000 0.832000
+-0.348200 0.000000 0.060900  -0.376000 0.448000 0.800000
+-0.350000 -0.001900 0.060900  -0.656000 0.280000 0.688000
+-0.350000 0.000000 0.059800  -0.688000 0.400000 0.592000
+-0.367400 -0.050200 0.060900  -0.696000 0.408000 0.584000
+-0.373100 0.000000 0.000000  -0.880000 0.240000 0.392000
+-0.399300 -0.050200 0.000000  -0.696000 0.680000 0.184000
+-0.377800 0.000000 -0.060900  -0.864000 0.424000 -0.248000
+-0.400000 -0.050200 -0.003200  -0.712000 0.672000 0.168000
+-0.400000 -0.037800 -0.060900  -0.728000 0.664000 0.152000
+-0.406900 -0.050200 -0.060900  -0.848000 0.520000 0.000000
+-0.400000 -0.050200 -0.118700  -0.832000 0.528000 -0.160000
+-0.450000 -0.099400 -0.060900  -0.760000 0.616000 0.160000
+-0.400000 -0.050900 -0.121900  -0.736000 0.536000 -0.408000
+-0.450000 -0.100400 -0.065100  -0.512000 0.824000 -0.200000
+-0.434900 -0.100400 -0.121900  -0.608000 0.744000 -0.256000
+-0.450000 -0.111500 -0.121900  -0.376000 0.896000 -0.224000
+-0.403600 -0.100400 -0.182900  -0.616000 0.592000 -0.512000
+-0.450000 -0.128500 -0.182900  -0.504000 0.800000 -0.296000
+-0.400000 -0.100400 -0.188300  -0.616000 0.576000 -0.520000
+-0.450000 -0.150600 -0.239400  -0.408000 0.792000 -0.448000
+-0.400000 -0.131400 -0.243900  -0.384000 0.744000 -0.536000
+-0.444500 -0.150600 -0.243900  -0.312000 0.784000 -0.528000
+-0.400000 -0.150600 -0.272200  -0.312000 0.624000 -0.704000
+-0.450000 -0.152500 -0.243900  -0.384000 0.800000 -0.448000
+-0.400000 -0.174400 -0.304800  -0.224000 0.736000 -0.632000
+-0.450000 -0.186700 -0.304800  -0.216000 0.808000 -0.528000
+-0.400000 -0.200800 -0.333600  -0.064000 0.568000 -0.816000
+-0.450000 -0.200800 -0.327900  -0.112000 0.704000 -0.696000
+-0.400000 -0.239300 -0.365800  0.048000 0.512000 -0.848000
+-0.450000 -0.235000 -0.365800  -0.016000 0.592000 -0.800000
+-0.400000 -0.251000 -0.373300  0.080000 0.400000 -0.904000
+-0.450000 -0.251000 -0.376500  0.032000 0.432000 -0.896000
+-0.400000 -0.301200 -0.390900  0.144000 0.296000 -0.936000
+-0.450000 -0.301200 -0.399100  0.080000 0.320000 -0.936000
+-0.400000 -0.351500 -0.411400  0.000000 0.616000 -0.784000
+-0.450000 -0.351500 -0.418600  0.080000 0.512000 -0.848000
+-0.450000 -0.301200 -0.399100  0.080000 0.320000 -0.936000
+-0.500000 -0.351500 -0.423900  0.056000 0.504000 -0.856000
+-0.500000 -0.301200 -0.402500  0.040000 0.344000 -0.936000
+-0.450000 -0.301200 -0.399100  0.080000 0.320000 -0.936000
+-0.500000 -0.251000 -0.377000  -0.032000 0.528000 -0.840000
+-0.450000 -0.251000 -0.376500  0.032000 0.432000 -0.896000
+-0.500000 -0.238600 -0.365800  -0.072000 0.656000 -0.744000
+-0.450000 -0.235000 -0.365800  -0.016000 0.592000 -0.800000
+-0.500000 -0.200800 -0.313000  -0.112000 0.824000 -0.544000
+-0.450000 -0.200800 -0.327900  -0.112000 0.704000 -0.696000
+-0.500000 -0.196700 -0.304800  -0.120000 0.848000 -0.504000
+-0.450000 -0.186700 -0.304800  -0.216000 0.808000 -0.528000
+-0.500000 -0.169200 -0.243900  -0.328000 0.880000 -0.312000
+-0.450000 -0.152500 -0.243900  -0.384000 0.800000 -0.448000
+-0.500000 -0.154300 -0.182900  -0.320000 0.920000 -0.176000
+-0.450000 -0.150600 -0.239400  -0.408000 0.792000 -0.448000
+-0.491700 -0.150600 -0.182900  -0.448000 0.848000 -0.264000
+-0.450000 -0.128500 -0.182900  -0.504000 0.800000 -0.296000
+-0.500000 -0.150600 -0.154000  -0.424000 0.880000 -0.160000
+-0.450000 -0.111500 -0.121900  -0.376000 0.896000 -0.224000
+-0.500000 -0.144400 -0.121900  -0.376000 0.880000 -0.280000
+-0.450000 -0.100400 -0.065100  -0.512000 0.824000 -0.200000
+-0.500000 -0.119500 -0.060900  -0.160000 0.976000 0.112000
+-0.452400 -0.100400 -0.060900  -0.344000 0.936000 -0.016000
+-0.500000 -0.141000 0.000000  -0.040000 0.880000 0.456000
+-0.450000 -0.100400 -0.057100  -0.400000 0.872000 0.264000
+-0.450000 -0.112700 0.000000  -0.520000 0.784000 0.320000
+-0.434300 -0.100400 0.000000  -0.648000 0.720000 0.208000
+-0.450000 -0.136300 0.060900  -0.512000 0.720000 0.448000
+-0.405500 -0.100400 0.060900  -0.712000 0.456000 0.520000
+-0.450000 -0.150600 0.089400  -0.440000 0.744000 0.496000
+-0.400000 -0.100400 0.069600  -0.688000 0.456000 0.552000
+-0.414900 -0.150600 0.121900  -0.424000 0.616000 0.648000
+-0.400000 -0.140400 0.121900  -0.448000 0.624000 0.632000
+-0.400000 -0.150600 0.133500  -0.392000 0.600000 0.688000
+-0.351400 -0.100400 0.121900  -0.608000 0.368000 0.696000
+-0.350000 -0.150600 0.151300  -0.584000 0.352000 0.720000
+-0.350000 -0.100400 0.123500  -0.608000 0.328000 0.712000
+-0.311100 -0.150600 0.182900  -0.424000 0.464000 0.768000
+-0.300000 -0.100400 0.149000  -0.304000 0.432000 0.840000
+-0.300000 -0.142200 0.182900  0.000000 0.616000 0.776000
+-0.250000 -0.100400 0.155000  0.480000 0.160000 0.856000
+-0.288800 -0.150600 0.182900  0.600000 0.360000 0.712000
+-0.250000 -0.144000 0.121900  0.720000 -0.312000 0.608000
+-0.252800 -0.150600 0.121900  0.720000 -0.296000 0.616000
+-0.250000 -0.150600 0.117900  0.712000 -0.320000 0.616000
+-0.250000 -0.150600 0.117900  0.712000 -0.320000 0.616000
+-0.400000 -0.351500 0.196700  0.560000 -0.576000 0.584000
+-0.400000 -0.351500 0.196700  0.560000 -0.576000 0.584000
+-0.389000 -0.351500 0.182900  0.544000 -0.632000 0.536000
+-0.400000 -0.359600 0.182900  0.520000 -0.680000 0.496000
+-0.400000 -0.359600 0.182900  0.520000 -0.680000 0.496000
+-0.311100 -0.150600 0.182900  -0.424000 0.464000 0.768000
+-0.311100 -0.150600 0.182900  -0.424000 0.464000 0.768000
+-0.300000 -0.142200 0.182900  0.000000 0.616000 0.776000
+-0.300000 -0.150600 0.190700  0.000000 0.520000 0.848000
+-0.288800 -0.150600 0.182900  0.600000 0.360000 0.712000
+-0.288800 -0.150600 0.182900  0.600000 0.360000 0.712000
+0.577700 0.301200 0.182900  -0.536000 0.272000 0.792000
+0.577700 0.301200 0.182900  -0.536000 0.272000 0.792000
+0.600000 0.327100 0.182900  -0.144000 0.552000 0.816000
+0.600000 0.301200 0.199900  -0.528000 0.136000 0.832000
+0.650000 0.311500 0.182900  0.424000 0.496000 0.752000
+0.650000 0.301200 0.190400  0.408000 0.464000 0.776000
+0.660200 0.301200 0.182900  0.480000 0.488000 0.720000
+0.650000 0.251000 0.217300  -0.016000 0.232000 0.968000
+0.700000 0.263400 0.182900  0.512000 0.536000 0.664000
+0.700000 0.251000 0.193900  0.488000 0.504000 0.704000
+0.711700 0.251000 0.182900  0.560000 0.528000 0.624000
+0.700000 0.200800 0.226400  0.328000 0.432000 0.832000
+0.750000 0.208300 0.182900  0.448000 0.624000 0.632000
+0.750000 0.200800 0.191100  0.424000 0.552000 0.712000
+0.761100 0.200800 0.182900  0.432000 0.472000 0.760000
+0.750000 0.150600 0.201100  0.320000 0.240000 0.912000
+0.797300 0.150600 0.182900  0.336000 0.288000 0.888000
+0.750000 0.100400 0.207000  0.032000 -0.192000 0.976000
+0.800000 0.148000 0.182900  0.424000 0.336000 0.832000
+0.800000 0.100400 0.199400  -0.032000 0.024000 0.992000
+0.850000 0.129700 0.182900  0.408000 0.752000 0.504000
+0.850000 0.100400 0.222500  0.440000 0.584000 0.672000
+0.891700 0.100400 0.182900  0.576000 0.688000 0.424000
+0.850000 0.050200 0.216300  -0.184000 -0.272000 0.936000
+0.900000 0.093100 0.182900  0.568000 0.672000 0.464000
+0.900000 0.050200 0.226800  0.488000 0.496000 0.712000
+0.940200 0.050200 0.182900  0.624000 0.528000 0.568000
+0.900000 0.000000 0.237100  -0.176000 -0.616000 0.760000
+0.950000 0.037400 0.182900  0.520000 0.504000 0.680000
+0.950000 0.000000 0.206500  0.400000 0.008000 0.912000
+1.000000 0.004900 0.182900  0.336000 0.520000 0.776000
+1.000000 0.000000 0.186800  0.376000 0.128000 0.912000
+0.950000 0.000000 0.206500  0.400000 0.008000 0.912000
+1.000000 -0.012000 0.182900  0.384000 -0.248000 0.880000
+0.950000 -0.050200 0.197900  0.336000 -0.192000 0.920000
+0.975800 -0.050200 0.182900  0.464000 -0.232000 0.848000
+0.950000 -0.100400 0.196500  0.208000 -0.704000 0.672000
+0.959000 -0.100400 0.182900  0.616000 -0.584000 0.520000
+0.950000 -0.108800 0.182900  0.232000 -0.768000 0.584000
+1.000000 -0.100400 0.134700  0.432000 -0.528000 0.720000
+0.950000 -0.142500 0.121900  -0.608000 -0.672000 0.392000
+1.000000 -0.126300 0.121900  0.016000 -0.480000 0.872000
+0.950000 -0.150600 0.094900  -0.648000 -0.696000 0.272000
+1.000000 -0.150600 0.101600  -0.080000 -0.576000 0.808000
+0.950000 -0.158100 0.060900  -0.608000 -0.760000 0.200000
+1.000000 -0.176100 0.060900  -0.688000 -0.632000 0.336000
+0.950000 -0.168100 0.000000  -0.640000 -0.744000 0.184000
+1.000000 -0.200800 0.012500  -0.656000 -0.696000 0.264000
+0.995800 -0.200800 0.000000  -0.648000 -0.704000 0.264000
+1.000000 -0.204500 0.000000  -0.624000 -0.728000 0.256000
+0.973000 -0.200800 -0.060900  -0.584000 -0.760000 0.264000
+1.000000 -0.224100 -0.060900  -0.616000 -0.728000 0.280000
+0.950500 -0.200800 -0.121900  -0.632000 -0.744000 0.192000
+1.000000 -0.243600 -0.121900  -0.640000 -0.736000 0.184000
+0.950000 -0.200800 -0.124000  -0.680000 -0.712000 0.160000
+1.000000 -0.251000 -0.154300  -0.728000 -0.648000 0.200000
+0.950000 -0.211700 -0.182900  -0.704000 -0.680000 0.176000
+0.993400 -0.251000 -0.182900  -0.736000 -0.640000 0.200000
+0.950000 -0.224400 -0.243900  -0.688000 -0.640000 0.328000
+0.978600 -0.251000 -0.243900  -0.696000 -0.616000 0.352000
+0.950000 -0.251000 -0.295200  -0.640000 -0.496000 0.576000
+1.000000 -0.277900 -0.243900  -0.712000 -0.592000 0.360000
+0.950000 -0.261400 -0.304800  -0.752000 -0.584000 0.288000
+1.000000 -0.301200 -0.291200  -0.640000 -0.488000 0.576000
+0.989600 -0.301200 -0.304800  -0.816000 -0.560000 0.128000
+1.000000 -0.316200 -0.304800  -0.800000 -0.552000 0.224000
+1.000000 -0.301200 -0.328200  -0.784000 -0.440000 -0.424000
+0.989600 -0.301200 -0.304800  -0.816000 -0.560000 0.128000
+1.000000 -0.251000 -0.355700  -0.816000 -0.248000 -0.504000
+0.950000 -0.261400 -0.304800  -0.752000 -0.584000 0.288000
+0.950000 -0.251000 -0.328200  -0.712000 -0.568000 -0.392000
+0.942100 -0.251000 -0.304800  -0.752000 -0.552000 0.344000
+0.950000 -0.200800 -0.357000  -0.272000 -0.104000 -0.952000
+0.911900 -0.200800 -0.304800  -0.864000 -0.480000 -0.128000
+0.950000 -0.150600 -0.345500  -0.032000 0.064000 -0.992000
+0.900000 -0.181100 -0.304800  -0.768000 -0.440000 -0.448000
+0.900000 -0.150600 -0.332000  -0.672000 -0.328000 -0.656000
+0.883200 -0.150600 -0.304800  -0.864000 -0.368000 -0.320000
+0.900000 -0.100400 -0.341700  -0.464000 -0.104000 -0.872000
+0.869700 -0.100400 -0.304800  -0.880000 -0.248000 -0.400000
+0.900000 -0.050200 -0.348300  -0.256000 0.192000 -0.944000
+0.867300 -0.050200 -0.304800  -0.784000 -0.136000 -0.600000
+0.900000 0.000000 -0.329500  -0.080000 0.648000 -0.744000
+0.877300 0.000000 -0.304800  -0.592000 0.480000 -0.632000
+0.900000 0.016700 -0.304800  -0.152000 0.720000 -0.664000
+0.850000 0.000000 -0.279000  -0.536000 0.488000 -0.680000
+0.900000 0.050200 -0.268900  0.208000 0.672000 -0.696000
+0.850000 0.042400 -0.243900  -0.408000 0.528000 -0.736000
+0.858900 0.050200 -0.243900  -0.424000 0.568000 -0.696000
+0.850000 0.050200 -0.237100  -0.376000 0.576000 -0.720000
+0.900000 0.070800 -0.243900  -0.096000 0.744000 -0.656000
+0.850000 0.100400 -0.218500  0.128000 0.592000 -0.784000
+0.900000 0.100400 -0.203200  0.536000 0.688000 -0.472000
+0.850000 0.127100 -0.182900  0.192000 0.744000 -0.632000
+0.900000 0.111100 -0.182900  0.552000 0.712000 -0.416000
+0.850000 0.150600 -0.140900  0.432000 0.840000 -0.304000
+0.900000 0.127900 -0.121900  0.560000 0.776000 -0.264000
+0.859300 0.150600 -0.121900  0.456000 0.840000 -0.272000
+0.900000 0.143500 -0.060900  0.528000 0.808000 -0.240000
+0.888500 0.150600 -0.060900  0.504000 0.856000 -0.040000
+0.900000 0.131100 0.000000  0.480000 0.848000 0.192000
+0.867700 0.150600 0.000000  0.552000 0.816000 0.152000
+0.900000 0.118900 0.060900  0.472000 0.856000 0.184000
+0.855400 0.150600 0.060900  0.680000 0.720000 0.072000
+0.900000 0.107300 0.121900  0.512000 0.832000 0.184000
+0.850900 0.150600 0.121900  0.704000 0.704000 0.080000
+0.900000 0.100400 0.165200  0.584000 0.744000 0.296000
+0.850000 0.150600 0.126500  0.640000 0.560000 0.512000
+0.891700 0.100400 0.182900  0.576000 0.688000 0.424000
+0.850000 0.129700 0.182900  0.408000 0.752000 0.504000
+0.850000 0.150600 0.126500  0.640000 0.560000 0.512000
+0.800000 0.148000 0.182900  0.424000 0.336000 0.832000
+0.800000 0.150600 0.181400  0.520000 0.336000 0.776000
+0.797300 0.150600 0.182900  0.336000 0.288000 0.888000
+0.800000 0.190400 0.121900  0.624000 0.752000 0.168000
+0.761100 0.200800 0.182900  0.432000 0.472000 0.760000
+0.788900 0.200800 0.121900  0.632000 0.744000 0.184000
+0.750000 0.208300 0.182900  0.448000 0.624000 0.632000
+0.750000 0.233400 0.121900  0.720000 0.680000 -0.080000
+0.711700 0.251000 0.182900  0.560000 0.528000 0.624000
+0.736800 0.251000 0.121900  0.752000 0.632000 0.144000
+0.700000 0.263400 0.182900  0.512000 0.536000 0.664000
+0.700000 0.297800 0.121900  0.728000 0.680000 -0.032000
+0.660200 0.301200 0.182900  0.480000 0.488000 0.720000
+0.696500 0.301200 0.121900  0.712000 0.672000 0.168000
+0.650000 0.311500 0.182900  0.424000 0.496000 0.752000
+0.653800 0.351500 0.121900  0.656000 0.616000 0.424000
+0.650000 0.351500 0.128300  0.616000 0.616000 0.480000
+0.650000 0.355500 0.121900  0.632000 0.632000 0.432000
+0.600000 0.351500 0.157200  -0.376000 0.584000 0.704000
+0.600000 0.382600 0.121900  0.272000 0.776000 0.560000
+0.566500 0.351500 0.121900  -0.632000 0.576000 0.496000
+0.600000 0.401700 0.085900  0.096000 0.928000 0.336000
+0.550000 0.351500 0.078000  -0.616000 0.672000 0.392000
+0.584600 0.401700 0.060900  -0.416000 0.872000 0.248000
+0.550000 0.359900 0.060900  -0.592000 0.640000 0.480000
+0.568400 0.401700 0.000000  -0.472000 0.832000 -0.264000
+0.550000 0.388900 0.000000  -0.392000 0.856000 0.320000
+0.600000 0.401700 -0.057700  0.168000 0.920000 -0.344000
+0.550000 0.398000 -0.060900  0.000000 0.968000 -0.216000
+0.600000 0.400600 -0.060900  -0.072000 0.912000 -0.384000
+0.550000 0.362300 -0.121900  0.400000 0.656000 -0.632000
+0.600000 0.351500 -0.101600  0.448000 0.496000 -0.736000
+0.566700 0.351500 -0.121900  0.448000 0.536000 -0.704000
+0.600000 0.310600 -0.121900  0.480000 0.424000 -0.760000
+0.550000 0.351500 -0.135900  0.456000 0.632000 -0.616000
+0.600000 0.301200 -0.128700  0.472000 0.520000 -0.704000
+0.550000 0.301200 -0.167400  0.408000 0.504000 -0.752000
+0.600000 0.256700 -0.182900  0.328000 0.496000 -0.792000
+0.550000 0.283200 -0.182900  0.320000 0.472000 -0.816000
+0.600000 0.251000 -0.187000  0.320000 0.456000 -0.816000
+0.550000 0.251000 -0.199600  0.176000 0.288000 -0.936000
+0.600000 0.200800 -0.209200  0.248000 0.288000 -0.920000
+0.550000 0.200800 -0.211100  0.016000 0.048000 -0.992000
+0.600000 0.150600 -0.225200  0.008000 0.128000 -0.984000
+0.550000 0.150600 -0.215400  -0.144000 0.080000 -0.984000
+0.600000 0.100400 -0.237100  -0.096000 0.168000 -0.976000
+0.550000 0.100400 -0.212600  -0.200000 0.352000 -0.904000
+0.600000 0.076600 -0.243900  -0.096000 0.360000 -0.920000
+0.550000 0.067800 -0.243900  0.024000 0.672000 -0.728000
+0.600000 0.050200 -0.251100  0.248000 0.344000 -0.896000
+0.550000 0.050200 -0.258400  0.160000 0.632000 -0.752000
+0.600000 0.000000 -0.284600  0.512000 0.112000 -0.840000
+0.550000 0.015600 -0.304800  0.472000 0.712000 -0.512000
+0.578400 0.000000 -0.304800  0.536000 0.480000 -0.688000
+0.550000 0.000000 -0.335900  0.576000 0.464000 -0.664000
+0.587300 -0.050200 -0.304800  0.688000 0.056000 -0.712000
+0.550000 -0.050200 -0.345500  0.192000 -0.560000 -0.792000
+0.550000 -0.083700 -0.304800  0.088000 -0.736000 -0.664000
+0.500000 -0.050200 -0.339600  -0.136000 -0.672000 -0.720000
+0.500000 -0.082600 -0.304800  0.216000 -0.680000 -0.688000
+0.450000 -0.050200 -0.325200  -0.120000 -0.568000 -0.808000
+0.475800 -0.100400 -0.304800  0.512000 -0.104000 -0.848000
+0.450000 -0.100400 -0.322200  0.392000 -0.360000 -0.840000
+0.500000 -0.127100 -0.304800  0.480000 0.456000 -0.744000
+0.450000 -0.150600 -0.321300  -0.008000 0.120000 -0.992000
+0.500000 -0.150600 -0.319100  0.336000 0.504000 -0.792000
+0.450000 -0.200800 -0.331300  -0.472000 -0.400000 -0.776000
+0.500000 -0.200800 -0.334200  -0.376000 -0.448000 -0.800000
+0.450000 -0.217600 -0.304800  -0.352000 -0.736000 -0.560000
+0.500000 -0.222600 -0.304800  -0.320000 -0.704000 -0.624000
+0.450000 -0.248400 -0.243900  -0.224000 -0.888000 -0.384000
+0.500000 -0.251000 -0.264200  -0.272000 -0.744000 -0.600000
+0.459300 -0.251000 -0.243900  -0.280000 -0.864000 -0.400000
+0.500000 -0.282700 -0.243900  -0.568000 -0.592000 -0.560000
+0.450000 -0.251000 -0.203800  -0.216000 -0.960000 -0.144000
+0.500000 -0.288400 -0.182900  -0.520000 -0.656000 0.528000
+0.450000 -0.255300 -0.182900  -0.208000 -0.656000 0.712000
+0.500000 -0.251000 -0.123800  -0.544000 -0.688000 0.456000
+0.450000 -0.251000 -0.179900  -0.288000 -0.680000 0.664000
+0.500000 -0.250100 -0.121900  -0.432000 -0.712000 0.536000
+0.450000 -0.227100 -0.121900  -0.296000 -0.712000 0.624000
+0.500000 -0.203100 -0.060900  -0.256000 -0.616000 0.736000
+0.450000 -0.200800 -0.072200  -0.256000 -0.536000 0.800000
+0.491400 -0.200800 -0.060900  -0.168000 -0.584000 0.784000
+0.450000 -0.150600 -0.064700  -0.192000 0.128000 0.968000
+0.463100 -0.150600 -0.060900  -0.168000 0.352000 0.912000
+0.450000 -0.100400 -0.078400  -0.088000 0.200000 0.968000
+0.500000 -0.139000 -0.060900  0.080000 0.536000 0.832000
+0.500000 -0.100400 -0.086800  -0.048000 0.256000 0.960000
+0.530700 -0.150600 -0.060900  0.208000 0.504000 0.832000
+0.550000 -0.100400 -0.076900  0.056000 0.056000 0.992000
+0.550000 -0.150600 -0.067100  0.240000 0.480000 0.840000
+0.600000 -0.100400 -0.077400  0.584000 0.048000 0.800000
+0.600000 -0.150600 -0.093600  0.304000 0.568000 0.752000
+0.626600 -0.100400 -0.121900  0.848000 0.208000 0.472000
+0.650000 -0.150600 -0.116200  0.720000 0.480000 0.488000
+0.650000 -0.146100 -0.121900  0.720000 0.504000 0.464000
+0.652900 -0.150600 -0.121900  0.752000 0.456000 0.464000
+0.650000 -0.117900 -0.182900  0.792000 0.600000 0.024000
+0.675300 -0.150600 -0.182900  0.768000 0.552000 0.296000
+0.650000 -0.120200 -0.243900  0.704000 0.520000 -0.472000
+0.674200 -0.150600 -0.243900  0.696000 0.600000 -0.384000
+0.650000 -0.150600 -0.274900  0.544000 0.464000 -0.688000
+0.700000 -0.175300 -0.243900  0.752000 0.600000 -0.240000
+0.650000 -0.200800 -0.297000  0.088000 0.616000 -0.776000
+0.700000 -0.200800 -0.294000  0.576000 0.608000 -0.536000
+0.650000 -0.208600 -0.304800  0.024000 0.680000 -0.728000
+0.700000 -0.211400 -0.304800  0.288000 0.624000 -0.720000
+0.650000 -0.245700 -0.365800  0.168000 0.856000 -0.480000
+0.700000 -0.251000 -0.357800  0.296000 0.496000 -0.808000
+0.678000 -0.251000 -0.365800  0.264000 0.520000 -0.808000
+0.700000 -0.301200 -0.354900  0.160000 -0.240000 -0.952000
+0.650000 -0.267900 -0.365800  0.280000 -0.440000 -0.848000
+0.650000 -0.301200 -0.350300  0.016000 -0.440000 -0.888000
+0.600000 -0.288400 -0.365800  -0.376000 -0.712000 -0.584000
+0.600000 -0.301200 -0.352300  -0.528000 -0.312000 -0.776000
+0.573000 -0.251000 -0.365800  -0.696000 0.544000 -0.464000
+0.567500 -0.301200 -0.304800  -0.696000 0.400000 -0.584000
+0.550000 -0.251000 -0.326800  -0.648000 -0.504000 -0.560000
+0.550000 -0.272400 -0.304800  -0.680000 -0.440000 -0.576000
+0.535300 -0.251000 -0.304800  -0.648000 -0.480000 -0.576000
+0.550000 -0.301200 -0.279200  -0.712000 0.120000 -0.680000
+0.500000 -0.251000 -0.264200  -0.272000 -0.744000 -0.600000
+0.513800 -0.301200 -0.243900  -0.728000 0.592000 -0.328000
+0.500000 -0.282700 -0.243900  -0.568000 -0.592000 -0.560000
+0.511800 -0.301200 -0.182900  -0.912000 0.352000 0.176000
+0.500000 -0.288400 -0.182900  -0.520000 -0.656000 0.528000
+0.550000 -0.301200 -0.123600  -0.624000 -0.440000 0.632000
+0.500000 -0.251000 -0.123800  -0.544000 -0.688000 0.456000
+0.550000 -0.300100 -0.121900  -0.624000 -0.616000 0.472000
+0.501100 -0.251000 -0.121900  -0.552000 -0.624000 0.544000
+0.550000 -0.251000 -0.069700  -0.416000 -0.584000 0.688000
+0.500000 -0.250100 -0.121900  -0.432000 -0.712000 0.536000
+0.550000 -0.242100 -0.060900  -0.400000 -0.536000 0.736000
+0.500000 -0.203100 -0.060900  -0.256000 -0.616000 0.736000
+0.550000 -0.200800 -0.034900  0.016000 -0.040000 0.992000
+0.500000 -0.200800 -0.058700  -0.200000 -0.576000 0.784000
+0.550000 -0.159500 -0.060900  0.248000 0.472000 0.840000
+0.500000 -0.150600 -0.051600  0.024000 0.352000 0.928000
+0.530700 -0.150600 -0.060900  0.208000 0.504000 0.832000
+0.500000 -0.139000 -0.060900  0.080000 0.536000 0.832000
+0.500000 -0.150600 -0.051600  0.024000 0.352000 0.928000
+0.463100 -0.150600 -0.060900  -0.168000 0.352000 0.912000
+0.500000 -0.200800 -0.058700  -0.200000 -0.576000 0.784000
+0.491400 -0.200800 -0.060900  -0.168000 -0.584000 0.784000
+0.500000 -0.203100 -0.060900  -0.256000 -0.616000 0.736000
+0.500000 -0.203100 -0.060900  -0.256000 -0.616000 0.736000
+0.600000 0.251000 0.198700  -0.584000 -0.144000 0.792000
+0.600000 0.251000 0.198700  -0.584000 -0.144000 0.792000
+0.600000 0.301200 0.199900  -0.528000 0.136000 0.832000
+0.586200 0.251000 0.182900  -0.672000 -0.144000 0.720000
+0.577700 0.301200 0.182900  -0.536000 0.272000 0.792000
+0.550000 0.251000 0.125100  -0.872000 -0.184000 0.440000
+0.550000 0.301200 0.149100  -0.896000 -0.096000 0.416000
+0.548800 0.251000 0.121900  -0.912000 -0.176000 0.360000
+0.538800 0.301200 0.121900  -0.912000 0.128000 0.376000
+0.533200 0.251000 0.060900  -0.856000 0.032000 0.512000
+0.526500 0.301200 0.060900  -0.896000 0.008000 0.432000
+0.500800 0.251000 0.000000  -0.792000 -0.016000 0.608000
+0.500000 0.301200 0.002700  -0.768000 -0.080000 0.624000
+0.500000 0.266900 0.000000  -0.760000 -0.040000 0.640000
+0.497900 0.301200 0.000000  -0.728000 -0.144000 0.664000
+0.500000 0.251000 -0.000900  -0.496000 0.112000 0.856000
+0.450000 0.301200 -0.039700  -0.448000 -0.256000 0.848000
+0.450000 0.251000 -0.039600  -0.400000 -0.080000 0.904000
+0.400000 0.301200 -0.051900  -0.168000 -0.472000 0.856000
+0.400000 0.251000 -0.058700  -0.328000 -0.176000 0.920000
+0.353900 0.301200 -0.060900  -0.128000 -0.544000 0.824000
+0.395100 0.251000 -0.060900  -0.344000 -0.184000 0.912000
+0.350000 0.301200 -0.062100  -0.176000 -0.704000 0.680000
+0.350000 0.251000 -0.088400  -0.448000 -0.320000 0.824000
+0.300000 0.301200 -0.077400  -0.160000 -0.712000 0.680000
+0.300000 0.251000 -0.114600  -0.168000 -0.536000 0.824000
+0.250000 0.301200 -0.083600  -0.096000 -0.744000 0.648000
+0.271900 0.251000 -0.121900  -0.240000 -0.760000 0.592000
+0.250000 0.256500 -0.121900  -0.200000 -0.800000 0.552000
+0.300000 0.251000 -0.156100  -0.368000 -0.808000 -0.448000
+0.250000 0.284000 -0.182900  -0.096000 -0.256000 -0.952000
+0.300000 0.284000 -0.182900  -0.168000 -0.184000 -0.960000
+0.250000 0.301200 -0.184400  -0.080000 -0.056000 -0.992000
+0.300000 0.301200 -0.184400  -0.064000 -0.072000 -0.992000
+0.250000 0.351500 -0.189100  -0.160000 0.168000 -0.968000
+0.300000 0.351500 -0.193900  -0.008000 0.064000 -0.992000
+0.250000 0.370000 -0.182900  -0.184000 0.304000 -0.928000
+0.300000 0.379400 -0.182900  -0.016000 0.272000 -0.960000
+0.250000 0.401700 -0.172700  -0.016000 0.288000 -0.952000
+0.300000 0.401700 -0.174800  0.040000 0.368000 -0.920000
+0.250000 0.451900 -0.137900  0.128000 0.536000 -0.824000
+0.300000 0.451900 -0.131100  0.200000 0.712000 -0.664000
+0.250000 0.466900 -0.121900  0.232000 0.968000 0.016000
+0.300000 0.458100 -0.121900  0.224000 0.952000 -0.176000
+0.250000 0.451900 -0.094000  0.248000 0.784000 0.552000
+0.300000 0.451900 -0.106900  0.184000 0.864000 0.456000
+0.250000 0.432000 -0.060900  0.224000 0.624000 0.736000
+0.300000 0.430700 -0.060900  0.128000 0.808000 0.568000
+0.250000 0.401700 -0.026800  -0.216000 0.176000 0.952000
+0.300000 0.401700 -0.022200  0.096000 0.472000 0.864000
+0.250000 0.351500 -0.020200  -0.488000 -0.416000 0.760000
+0.300000 0.351500 -0.009100  -0.016000 -0.144000 0.984000
+0.250000 0.317900 -0.060900  -0.432000 -0.680000 0.584000
+0.300000 0.310700 -0.060900  -0.072000 -0.760000 0.640000
+0.250000 0.301200 -0.083600  -0.096000 -0.744000 0.648000
+0.300000 0.301200 -0.077400  -0.160000 -0.712000 0.680000
+0.300000 0.310700 -0.060900  -0.072000 -0.760000 0.640000
+0.350000 0.301200 -0.062100  -0.176000 -0.704000 0.680000
+0.350000 0.302200 -0.060900  -0.144000 -0.624000 0.760000
+0.353900 0.301200 -0.060900  -0.128000 -0.544000 0.824000
+0.350000 0.351500 -0.021800  0.032000 -0.048000 0.992000
+0.400000 0.301200 -0.051900  -0.168000 -0.472000 0.856000
+0.400000 0.351500 -0.018700  -0.136000 -0.208000 0.960000
+0.450000 0.301200 -0.039700  -0.448000 -0.256000 0.848000
+0.450000 0.351500 -0.003200  -0.296000 0.344000 0.888000
+0.497900 0.301200 0.000000  -0.728000 -0.144000 0.664000
+0.458200 0.351500 0.000000  -0.280000 0.520000 0.800000
+0.500000 0.301200 0.002700  -0.768000 -0.080000 0.624000
+0.500000 0.351500 0.029100  -0.680000 0.048000 0.728000
+0.526500 0.301200 0.060900  -0.896000 0.008000 0.432000
+0.540600 0.351500 0.060900  -0.584000 0.632000 0.496000
+0.538800 0.301200 0.121900  -0.912000 0.128000 0.376000
+0.550000 0.351500 0.078000  -0.616000 0.672000 0.392000
+0.550000 0.331800 0.121900  -0.696000 0.536000 0.456000
+0.566500 0.351500 0.121900  -0.632000 0.576000 0.496000
+0.550000 0.301200 0.149100  -0.896000 -0.096000 0.416000
+0.600000 0.351500 0.157200  -0.376000 0.584000 0.704000
+0.577700 0.301200 0.182900  -0.536000 0.272000 0.792000
+0.600000 0.327100 0.182900  -0.144000 0.552000 0.816000
+0.600000 0.351500 0.157200  -0.376000 0.584000 0.704000
+0.650000 0.311500 0.182900  0.424000 0.496000 0.752000
+0.650000 0.351500 0.128300  0.616000 0.616000 0.480000
+0.650000 0.351500 0.128300  0.616000 0.616000 0.480000
+0.586200 0.251000 0.182900  -0.672000 -0.144000 0.720000
+0.586200 0.251000 0.182900  -0.672000 -0.144000 0.720000
+0.600000 0.251000 0.198700  -0.584000 -0.144000 0.792000
+0.600000 0.211800 0.182900  -0.672000 -0.280000 0.672000
+0.650000 0.251000 0.217300  -0.016000 0.232000 0.968000
+0.604600 0.200800 0.182900  -0.672000 -0.288000 0.664000
+0.650000 0.200800 0.219700  -0.496000 -0.256000 0.824000
+0.641000 0.150600 0.182900  -0.528000 -0.464000 0.696000
+0.650000 0.150600 0.191100  -0.504000 -0.472000 0.720000
+0.650000 0.141000 0.182900  -0.512000 -0.488000 0.704000
+0.700000 0.150600 0.220800  -0.264000 -0.416000 0.864000
+0.685300 0.100400 0.182900  -0.504000 -0.560000 0.648000
+0.700000 0.100400 0.197200  -0.456000 -0.560000 0.680000
+0.700000 0.088000 0.182900  -0.464000 -0.608000 0.640000
+0.750000 0.100400 0.207000  0.032000 -0.192000 0.976000
+0.750000 0.062100 0.182900  -0.416000 -0.632000 0.648000
+0.800000 0.100400 0.199400  -0.032000 0.024000 0.992000
+0.762700 0.050200 0.182900  -0.512000 -0.672000 0.520000
+0.800000 0.050200 0.211000  -0.336000 -0.552000 0.752000
+0.800000 0.035400 0.182900  -0.432000 -0.808000 0.384000
+0.850000 0.050200 0.216300  -0.184000 -0.272000 0.936000
+0.846600 0.000000 0.182900  -0.736000 -0.616000 0.264000
+0.850000 0.000000 0.194300  -0.704000 -0.640000 0.296000
+0.850000 -0.004200 0.182900  -0.720000 -0.616000 0.288000
+0.900000 0.000000 0.237100  -0.176000 -0.616000 0.760000
+0.880500 -0.050200 0.182900  -0.744000 -0.528000 0.384000
+0.900000 -0.050200 0.230400  -0.448000 -0.568000 0.680000
+0.900000 -0.076800 0.182900  -0.504000 -0.624000 0.592000
+0.950000 -0.050200 0.197900  0.336000 -0.192000 0.920000
+0.934300 -0.100400 0.182900  -0.392000 -0.752000 0.520000
+0.950000 -0.100400 0.196500  0.208000 -0.704000 0.672000
+0.950000 -0.108800 0.182900  0.232000 -0.768000 0.584000
+0.934300 -0.100400 0.182900  -0.392000 -0.752000 0.520000
+0.950000 -0.142500 0.121900  -0.608000 -0.672000 0.392000
+0.900000 -0.100400 0.145900  -0.608000 -0.728000 0.304000
+0.900000 -0.107100 0.121900  -0.584000 -0.768000 0.240000
+0.892500 -0.100400 0.121900  -0.688000 -0.680000 0.240000
+0.900000 -0.117100 0.060900  -0.656000 -0.736000 0.136000
+0.881900 -0.100400 0.060900  -0.752000 -0.632000 0.152000
+0.900000 -0.125700 0.000000  -0.664000 -0.728000 0.136000
+0.873300 -0.100400 0.000000  -0.752000 -0.632000 0.120000
+0.900000 -0.135500 -0.060900  -0.672000 -0.712000 0.168000
+0.865600 -0.100400 -0.060900  -0.776000 -0.616000 0.120000
+0.900000 -0.148200 -0.121900  -0.664000 -0.728000 0.088000
+0.858300 -0.100400 -0.121900  -0.792000 -0.600000 0.056000
+0.900000 -0.150600 -0.145400  -0.696000 -0.704000 0.104000
+0.858100 -0.100400 -0.182900  -0.824000 -0.552000 0.000000
+0.895100 -0.150600 -0.182900  -0.744000 -0.648000 0.104000
+0.860900 -0.100400 -0.243900  -0.856000 -0.496000 -0.072000
+0.890800 -0.150600 -0.243900  -0.848000 -0.512000 0.064000
+0.869700 -0.100400 -0.304800  -0.880000 -0.248000 -0.400000
+0.883200 -0.150600 -0.304800  -0.864000 -0.368000 -0.320000
+0.890800 -0.150600 -0.243900  -0.848000 -0.512000 0.064000
+0.900000 -0.181100 -0.304800  -0.768000 -0.440000 -0.448000
+0.900000 -0.163000 -0.243900  -0.816000 -0.552000 0.128000
+0.911900 -0.200800 -0.304800  -0.864000 -0.480000 -0.128000
+0.928800 -0.200800 -0.243900  -0.736000 -0.616000 0.240000
+0.942100 -0.251000 -0.304800  -0.752000 -0.552000 0.344000
+0.950000 -0.224400 -0.243900  -0.688000 -0.640000 0.328000
+0.950000 -0.251000 -0.295200  -0.640000 -0.496000 0.576000
+0.942100 -0.251000 -0.304800  -0.752000 -0.552000 0.344000
+0.950000 -0.261400 -0.304800  -0.752000 -0.584000 0.288000
+0.950000 -0.261400 -0.304800  -0.752000 -0.584000 0.288000
+0.650000 0.251000 0.217300  -0.016000 0.232000 0.968000
+0.650000 0.251000 0.217300  -0.016000 0.232000 0.968000
+0.600000 0.251000 0.198700  -0.584000 -0.144000 0.792000
+0.650000 0.301200 0.190400  0.408000 0.464000 0.776000
+0.600000 0.301200 0.199900  -0.528000 0.136000 0.832000
+0.600000 0.301200 0.199900  -0.528000 0.136000 0.832000
+0.700000 0.251000 0.193900  0.488000 0.504000 0.704000
+0.700000 0.251000 0.193900  0.488000 0.504000 0.704000
+0.650000 0.251000 0.217300  -0.016000 0.232000 0.968000
+0.700000 0.200800 0.226400  0.328000 0.432000 0.832000
+0.650000 0.200800 0.219700  -0.496000 -0.256000 0.824000
+0.700000 0.150600 0.220800  -0.264000 -0.416000 0.864000
+0.650000 0.150600 0.191100  -0.504000 -0.472000 0.720000
+0.650000 0.150600 0.191100  -0.504000 -0.472000 0.720000
+0.750000 0.200800 0.191100  0.424000 0.552000 0.712000
+0.750000 0.200800 0.191100  0.424000 0.552000 0.712000
+0.700000 0.200800 0.226400  0.328000 0.432000 0.832000
+0.750000 0.150600 0.201100  0.320000 0.240000 0.912000
+0.700000 0.150600 0.220800  -0.264000 -0.416000 0.864000
+0.750000 0.100400 0.207000  0.032000 -0.192000 0.976000
+0.700000 0.100400 0.197200  -0.456000 -0.560000 0.680000
+0.700000 0.100400 0.197200  -0.456000 -0.560000 0.680000
+0.850000 0.050200 0.216300  -0.184000 -0.272000 0.936000
+0.850000 0.050200 0.216300  -0.184000 -0.272000 0.936000
+0.800000 0.050200 0.211000  -0.336000 -0.552000 0.752000
+0.850000 0.100400 0.222500  0.440000 0.584000 0.672000
+0.800000 0.100400 0.199400  -0.032000 0.024000 0.992000
+0.800000 0.100400 0.199400  -0.032000 0.024000 0.992000
+0.900000 0.000000 0.237100  -0.176000 -0.616000 0.760000
+0.900000 0.000000 0.237100  -0.176000 -0.616000 0.760000
+0.850000 0.000000 0.194300  -0.704000 -0.640000 0.296000
+0.900000 0.050200 0.226800  0.488000 0.496000 0.712000
+0.850000 0.050200 0.216300  -0.184000 -0.272000 0.936000
+0.850000 0.050200 0.216300  -0.184000 -0.272000 0.936000
+0.950000 -0.050200 0.197900  0.336000 -0.192000 0.920000
+0.950000 -0.050200 0.197900  0.336000 -0.192000 0.920000
+0.900000 -0.050200 0.230400  -0.448000 -0.568000 0.680000
+0.950000 0.000000 0.206500  0.400000 0.008000 0.912000
+0.900000 0.000000 0.237100  -0.176000 -0.616000 0.760000
+0.900000 0.000000 0.237100  -0.176000 -0.616000 0.760000
+-0.950000 0.150600 0.154300  0.208000 0.640000 0.736000
+-0.950000 0.150600 0.154300  0.208000 0.640000 0.736000
+-0.900000 0.150600 0.126400  0.344000 0.632000 0.688000
+-0.950000 0.178500 0.121900  0.272000 0.648000 0.704000
+-0.900000 0.154600 0.121900  0.352000 0.624000 0.688000
+-0.950000 0.200800 0.096100  0.208000 0.672000 0.704000
+-0.900000 0.200800 0.074800  0.296000 0.712000 0.624000
+-0.950000 0.226300 0.060900  0.264000 0.760000 0.584000
+-0.900000 0.210300 0.060900  0.312000 0.744000 0.576000
+-0.950000 0.251000 0.016800  0.288000 0.808000 0.504000
+-0.900000 0.240500 0.000000  0.368000 0.840000 0.376000
+-0.928700 0.251000 0.000000  0.312000 0.848000 0.408000
+-0.900000 0.251000 -0.035000  0.384000 0.864000 0.312000
+-0.950000 0.258900 0.000000  0.296000 0.848000 0.432000
+-0.900000 0.258900 -0.060900  0.400000 0.896000 0.144000
+-0.950000 0.277400 -0.060900  0.336000 0.928000 0.080000
+-0.900000 0.251000 -0.101700  0.376000 0.896000 -0.216000
+-0.950000 0.267200 -0.121900  0.344000 0.864000 -0.336000
+-0.910500 0.251000 -0.121900  0.344000 0.880000 -0.304000
+-0.950000 0.251000 -0.157200  0.320000 0.808000 -0.480000
+-0.900000 0.246900 -0.121900  0.360000 0.872000 -0.304000
+-0.950000 0.237800 -0.182900  0.296000 0.760000 -0.568000
+-0.900000 0.214200 -0.182900  0.360000 0.720000 -0.576000
+-0.950000 0.200800 -0.231900  0.272000 0.640000 -0.704000
+-0.900000 0.200800 -0.201400  0.352000 0.680000 -0.640000
+-0.950000 0.189400 -0.243900  0.264000 0.616000 -0.728000
+-0.900000 0.162400 -0.243900  0.336000 0.616000 -0.704000
+-0.950000 0.150600 -0.281200  0.240000 0.600000 -0.752000
+-0.900000 0.150600 -0.256300  0.328000 0.616000 -0.704000
+-0.950000 0.126000 -0.304800  0.168000 0.528000 -0.824000
+-0.900000 0.104600 -0.304800  0.304000 0.568000 -0.760000
+-0.950000 0.100400 -0.325900  0.192000 0.384000 -0.896000
+-0.900000 0.100400 -0.308600  0.312000 0.536000 -0.776000
+-0.950000 0.050200 -0.340200  0.184000 0.072000 -0.976000
+-0.900000 0.050200 -0.331200  0.320000 0.232000 -0.912000
+-0.950000 0.000000 -0.337100  0.184000 -0.088000 -0.976000
+-0.900000 0.000000 -0.328400  0.216000 0.000000 -0.968000
+-0.950000 -0.050200 -0.337400  0.088000 0.008000 -0.992000
+-0.900000 -0.050200 -0.330000  0.160000 0.128000 -0.976000
+-0.900000 0.000000 -0.328400  0.216000 0.000000 -0.968000
+-0.850000 -0.050200 -0.323400  0.248000 0.176000 -0.944000
+-0.850000 0.000000 -0.313800  0.264000 0.064000 -0.960000
+-0.808200 -0.050200 -0.304800  0.280000 0.136000 -0.944000
+-0.823600 0.000000 -0.304800  0.296000 0.080000 -0.944000
+-0.800000 -0.050200 -0.302200  0.264000 0.120000 -0.952000
+-0.800000 0.000000 -0.298500  0.248000 0.080000 -0.960000
+-0.750000 -0.050200 -0.287100  0.288000 0.040000 -0.952000
+-0.750000 0.000000 -0.285200  0.328000 0.160000 -0.920000
+-0.700000 -0.050200 -0.272000  0.360000 0.104000 -0.920000
+-0.700000 0.000000 -0.262900  0.392000 0.288000 -0.864000
+-0.650000 -0.050200 -0.249300  0.496000 0.208000 -0.840000
+-0.669700 0.000000 -0.243900  0.480000 0.312000 -0.808000
+-0.650000 -0.035200 -0.243900  0.544000 0.264000 -0.792000
+-0.650000 0.000000 -0.224600  0.632000 0.368000 -0.672000
+-0.642900 -0.050200 -0.243900  0.560000 0.208000 -0.792000
+-0.621400 0.000000 -0.182900  0.848000 0.280000 -0.440000
+-0.606100 -0.050200 -0.182900  0.864000 0.248000 -0.424000
+-0.606100 -0.050200 -0.182900  0.864000 0.248000 -0.424000
+-0.950000 0.127100 0.182900  0.248000 0.536000 0.800000
+-0.950000 0.127100 0.182900  0.248000 0.536000 0.800000
+-0.950000 0.150600 0.154300  0.208000 0.640000 0.736000
+-0.900000 0.101900 0.182900  0.304000 0.552000 0.768000
+-0.900000 0.150600 0.126400  0.344000 0.632000 0.688000
+-0.900000 0.150600 0.126400  0.344000 0.632000 0.688000
+-0.939400 -0.100400 0.121900  -0.456000 -0.816000 0.336000
+-0.939400 -0.100400 0.121900  -0.456000 -0.816000 0.336000
+-0.900000 -0.100400 0.174900  -0.400000 -0.624000 0.656000
+-0.900000 -0.127600 0.121900  -0.608000 -0.704000 0.344000
+-0.900000 -0.127600 0.121900  -0.608000 -0.704000 0.344000
+-0.900000 0.150600 0.126400  0.344000 0.632000 0.688000
+-0.900000 0.150600 0.126400  0.344000 0.632000 0.688000
+-0.900000 0.154600 0.121900  0.352000 0.624000 0.688000
+-0.892900 0.150600 0.121900  0.360000 0.624000 0.680000
+-0.900000 0.200800 0.074800  0.296000 0.712000 0.624000
+-0.850000 0.150600 0.098600  0.360000 0.600000 0.704000
+-0.879600 0.200800 0.060900  0.352000 0.712000 0.600000
+-0.850000 0.184100 0.060900  0.376000 0.632000 0.664000
+-0.850000 0.200800 0.035600  0.384000 0.744000 0.536000
+-0.800000 0.153700 0.060900  0.432000 0.632000 0.632000
+-0.811000 0.200800 0.000000  0.408000 0.816000 0.392000
+-0.800000 0.195100 0.000000  0.456000 0.768000 0.432000
+-0.800000 0.200800 -0.016800  0.416000 0.840000 0.336000
+-0.750000 0.162200 0.000000  0.464000 0.672000 0.560000
+-0.768900 0.200800 -0.060900  0.424000 0.888000 0.160000
+-0.750000 0.191300 -0.060900  0.496000 0.856000 0.072000
+-0.800000 0.200800 -0.113900  0.392000 0.880000 -0.256000
+-0.750000 0.174400 -0.121900  0.448000 0.824000 -0.336000
+-0.800000 0.198900 -0.121900  0.384000 0.872000 -0.288000
+-0.750000 0.150600 -0.159200  0.432000 0.664000 -0.600000
+-0.800000 0.163000 -0.182900  0.392000 0.688000 -0.600000
+-0.779100 0.150600 -0.182900  0.400000 0.664000 -0.616000
+-0.800000 0.150600 -0.199200  0.384000 0.648000 -0.648000
+-0.750000 0.132600 -0.182900  0.408000 0.656000 -0.624000
+-0.800000 0.108800 -0.243900  0.352000 0.608000 -0.704000
+-0.750000 0.100400 -0.222000  0.432000 0.576000 -0.680000
+-0.785800 0.100400 -0.243900  0.360000 0.584000 -0.720000
+-0.750000 0.077000 -0.243900  0.368000 0.552000 -0.744000
+-0.800000 0.100400 -0.252800  0.360000 0.584000 -0.720000
+-0.750000 0.050200 -0.267100  0.368000 0.432000 -0.816000
+-0.800000 0.050200 -0.288900  0.352000 0.360000 -0.856000
+-0.750000 0.000000 -0.285200  0.328000 0.160000 -0.920000
+-0.800000 0.000000 -0.298500  0.248000 0.080000 -0.960000
+-0.800000 0.050200 -0.288900  0.352000 0.360000 -0.856000
+-0.823600 0.000000 -0.304800  0.296000 0.080000 -0.944000
+-0.836500 0.050200 -0.304800  0.336000 0.344000 -0.872000
+-0.850000 0.000000 -0.313800  0.264000 0.064000 -0.960000
+-0.850000 0.050200 -0.311100  0.336000 0.328000 -0.872000
+-0.900000 0.000000 -0.328400  0.216000 0.000000 -0.968000
+-0.900000 0.050200 -0.331200  0.320000 0.232000 -0.912000
+-0.850000 0.050200 -0.311100  0.336000 0.328000 -0.872000
+-0.900000 0.100400 -0.308600  0.312000 0.536000 -0.776000
+-0.850000 0.061400 -0.304800  0.336000 0.392000 -0.848000
+-0.892300 0.100400 -0.304800  0.320000 0.536000 -0.776000
+-0.850000 0.100400 -0.281200  0.344000 0.488000 -0.792000
+-0.900000 0.104600 -0.304800  0.304000 0.568000 -0.760000
+-0.850000 0.135500 -0.243900  0.320000 0.608000 -0.712000
+-0.900000 0.150600 -0.256300  0.328000 0.616000 -0.704000
+-0.878700 0.150600 -0.243900  0.328000 0.616000 -0.704000
+-0.900000 0.162400 -0.243900  0.336000 0.616000 -0.704000
+-0.850000 0.150600 -0.229000  0.320000 0.608000 -0.720000
+-0.900000 0.200800 -0.201400  0.352000 0.680000 -0.640000
+-0.850000 0.188600 -0.182900  0.360000 0.712000 -0.592000
+-0.874200 0.200800 -0.182900  0.360000 0.712000 -0.584000
+-0.850000 0.200800 -0.163600  0.360000 0.768000 -0.512000
+-0.900000 0.214200 -0.182900  0.360000 0.720000 -0.576000
+-0.850000 0.222300 -0.121900  0.408000 0.856000 -0.296000
+-0.900000 0.246900 -0.121900  0.360000 0.872000 -0.304000
+-0.850000 0.235300 -0.060900  0.408000 0.904000 0.008000
+-0.900000 0.251000 -0.101700  0.376000 0.896000 -0.216000
+-0.884300 0.251000 -0.060900  0.432000 0.880000 0.144000
+-0.900000 0.258900 -0.060900  0.400000 0.896000 0.144000
+-0.900000 0.251000 -0.035000  0.384000 0.864000 0.312000
+-0.884300 0.251000 -0.060900  0.432000 0.880000 0.144000
+-0.900000 0.240500 0.000000  0.368000 0.840000 0.376000
+-0.850000 0.235300 -0.060900  0.408000 0.904000 0.008000
+-0.850000 0.219100 0.000000  0.368000 0.824000 0.424000
+-0.800000 0.214400 -0.060900  0.400000 0.896000 0.176000
+-0.811000 0.200800 0.000000  0.408000 0.816000 0.392000
+-0.800000 0.200800 -0.016800  0.416000 0.840000 0.336000
+-0.800000 0.214400 -0.060900  0.400000 0.896000 0.176000
+-0.768900 0.200800 -0.060900  0.424000 0.888000 0.160000
+-0.800000 0.200800 -0.113900  0.392000 0.880000 -0.256000
+-0.800000 0.214400 -0.060900  0.400000 0.896000 0.176000
+-0.804300 0.200800 -0.121900  0.384000 0.872000 -0.288000
+-0.850000 0.235300 -0.060900  0.408000 0.904000 0.008000
+-0.850000 0.222300 -0.121900  0.408000 0.856000 -0.296000
+-0.804300 0.200800 -0.121900  0.384000 0.872000 -0.288000
+-0.850000 0.200800 -0.163600  0.360000 0.768000 -0.512000
+-0.800000 0.198900 -0.121900  0.384000 0.872000 -0.288000
+-0.850000 0.188600 -0.182900  0.360000 0.712000 -0.592000
+-0.800000 0.163000 -0.182900  0.392000 0.688000 -0.600000
+-0.850000 0.150600 -0.229000  0.320000 0.608000 -0.720000
+-0.800000 0.150600 -0.199200  0.384000 0.648000 -0.648000
+-0.850000 0.135500 -0.243900  0.320000 0.608000 -0.712000
+-0.800000 0.108800 -0.243900  0.352000 0.608000 -0.704000
+-0.850000 0.100400 -0.281200  0.344000 0.488000 -0.792000
+-0.800000 0.100400 -0.252800  0.360000 0.584000 -0.720000
+-0.850000 0.061400 -0.304800  0.336000 0.392000 -0.848000
+-0.800000 0.050200 -0.288900  0.352000 0.360000 -0.856000
+-0.836500 0.050200 -0.304800  0.336000 0.344000 -0.872000
+-0.850000 0.061400 -0.304800  0.336000 0.392000 -0.848000
+-0.850000 0.050200 -0.311100  0.336000 0.328000 -0.872000
+-0.850000 0.050200 -0.311100  0.336000 0.328000 -0.872000
+-0.850000 0.127100 0.121900  0.424000 0.560000 0.704000
+-0.850000 0.127100 0.121900  0.424000 0.560000 0.704000
+-0.820700 0.100400 0.121900  0.496000 0.488000 0.704000
+-0.850000 0.100400 0.150400  0.488000 0.512000 0.696000
+-0.850000 0.100400 0.150400  0.488000 0.512000 0.696000
+-0.839600 0.000000 0.182900  0.264000 0.152000 0.944000
+-0.839600 0.000000 0.182900  0.264000 0.152000 0.944000
+-0.809300 -0.050200 0.182900  0.232000 0.160000 0.952000
+-0.800000 0.000000 0.163200  0.400000 0.288000 0.864000
+-0.800000 -0.050200 0.179900  0.264000 0.176000 0.944000
+-0.750000 0.000000 0.129400  0.496000 0.360000 0.776000
+-0.750000 -0.050200 0.155100  0.464000 0.288000 0.832000
+-0.740500 0.000000 0.121900  0.504000 0.352000 0.784000
+-0.708600 -0.050200 0.121900  0.496000 0.344000 0.784000
+-0.700000 0.000000 0.089700  0.584000 0.336000 0.736000
+-0.700000 -0.050200 0.115300  0.496000 0.344000 0.792000
+-0.666100 0.000000 0.060900  0.560000 0.376000 0.728000
+-0.650000 -0.050200 0.076400  0.576000 0.320000 0.744000
+-0.650000 -0.023500 0.060900  0.576000 0.360000 0.720000
+-0.635700 -0.050200 0.060900  0.640000 0.304000 0.696000
+-0.650000 0.000000 0.045200  0.576000 0.400000 0.704000
+-0.600000 -0.050200 0.018400  0.648000 0.320000 0.688000
+-0.609800 0.000000 0.000000  0.696000 0.384000 0.592000
+-0.600000 -0.018300 0.000000  0.712000 0.368000 0.584000
+-0.600000 0.000000 -0.017800  0.736000 0.384000 0.544000
+-0.584800 -0.050200 0.000000  0.744000 0.336000 0.568000
+-0.573200 0.000000 -0.060900  0.920000 0.296000 -0.248000
+-0.554400 -0.050200 -0.060900  0.944000 0.280000 0.128000
+-0.554400 -0.050200 -0.060900  0.944000 0.280000 0.128000
+-0.800000 -0.063400 0.182900  0.240000 0.160000 0.952000
+-0.800000 -0.063400 0.182900  0.240000 0.160000 0.952000
+-0.809300 -0.050200 0.182900  0.232000 0.160000 0.952000
+-0.800000 -0.050200 0.179900  0.264000 0.176000 0.944000
+-0.800000 -0.050200 0.179900  0.264000 0.176000 0.944000
+-0.850000 -0.137400 0.182900  -0.304000 -0.312000 0.896000
+-0.850000 -0.137400 0.182900  -0.304000 -0.312000 0.896000
+-0.836800 -0.150600 0.182900  -0.304000 -0.304000 0.896000
+-0.850000 -0.150600 0.175600  -0.632000 -0.392000 0.664000
+-0.803100 -0.200800 0.182900  -0.456000 -0.168000 0.864000
+-0.850000 -0.200800 0.125700  -0.776000 -0.360000 0.504000
+-0.850000 -0.200800 0.125700  -0.776000 -0.360000 0.504000
+-0.800000 -0.251000 0.157900  -0.576000 -0.400000 0.696000
+-0.800000 -0.251000 0.157900  -0.576000 -0.400000 0.696000
+-0.800000 -0.280700 0.121900  -0.736000 -0.528000 0.408000
+-0.819200 -0.251000 0.121900  -0.760000 -0.496000 0.400000
+-0.800000 -0.301200 0.085900  -0.768000 -0.544000 0.304000
+-0.838400 -0.251000 0.060900  -0.808000 -0.528000 0.248000
+-0.805900 -0.301200 0.060900  -0.800000 -0.536000 0.232000
+-0.800000 -0.301200 0.085900  -0.768000 -0.544000 0.304000
+-0.800000 -0.310100 0.060900  -0.800000 -0.544000 0.224000
+-0.805900 -0.301200 0.060900  -0.800000 -0.536000 0.232000
+-0.800000 -0.327900 0.000000  -0.800000 -0.560000 0.176000
+-0.817700 -0.301200 0.000000  -0.808000 -0.560000 0.168000
+-0.817700 -0.301200 0.000000  -0.808000 -0.560000 0.168000
+-0.800000 0.077200 0.121900  0.512000 0.416000 0.744000
+-0.800000 0.077200 0.121900  0.512000 0.416000 0.744000
+-0.781300 0.050200 0.121900  0.536000 0.400000 0.736000
+-0.800000 0.050200 0.139800  0.504000 0.392000 0.760000
+-0.800000 0.050200 0.139800  0.504000 0.392000 0.760000
+-0.776900 -0.100400 0.182900  0.184000 0.120000 0.968000
+-0.776900 -0.100400 0.182900  0.184000 0.120000 0.968000
+-0.750000 -0.100400 0.174700  0.320000 0.192000 0.920000
+-0.750000 -0.136500 0.182900  0.216000 0.112000 0.968000
+-0.700000 -0.100400 0.138900  0.488000 0.288000 0.816000
+-0.743500 -0.150600 0.182900  0.192000 0.096000 0.968000
+-0.700000 -0.150600 0.164200  0.408000 0.248000 0.872000
+-0.703900 -0.200800 0.182900  0.128000 0.064000 0.984000
+-0.700000 -0.200800 0.182200  0.152000 0.072000 0.984000
+-0.700000 -0.208700 0.182900  0.176000 0.120000 0.968000
+-0.650000 -0.200800 0.153500  0.376000 0.280000 0.872000
+-0.650000 -0.249200 0.182900  0.176000 0.464000 0.864000
+-0.600000 -0.200800 0.130000  0.152000 0.560000 0.808000
+-0.638500 -0.251000 0.182900  0.072000 0.424000 0.896000
+-0.600000 -0.251000 0.177800  0.080000 0.520000 0.840000
+-0.600000 -0.260000 0.182900  0.056000 0.320000 0.944000
+-0.550000 -0.251000 0.173600  -0.016000 0.472000 0.872000
+-0.550000 -0.264400 0.182900  -0.072000 0.456000 0.880000
+-0.512000 -0.251000 0.182900  -0.112000 0.632000 0.760000
+-0.550000 -0.251000 0.173600  -0.016000 0.472000 0.872000
+-0.500000 -0.249000 0.182900  -0.112000 0.656000 0.744000
+-0.550000 -0.202900 0.121900  0.032000 0.728000 0.680000
+-0.500000 -0.200800 0.127000  -0.088000 0.600000 0.784000
+-0.536800 -0.200800 0.121900  -0.104000 0.736000 0.664000
+-0.500000 -0.196200 0.121900  -0.112000 0.784000 0.600000
+-0.550000 -0.200800 0.118700  0.032000 0.784000 0.608000
+-0.500000 -0.166600 0.060900  -0.304000 0.832000 0.448000
+-0.550000 -0.166800 0.060900  0.264000 0.816000 0.504000
+-0.500000 -0.150600 0.019400  -0.216000 0.856000 0.464000
+-0.550000 -0.150600 0.029600  0.504000 0.688000 0.512000
+-0.500000 -0.141000 0.000000  -0.040000 0.880000 0.456000
+-0.550000 -0.125000 0.000000  0.608000 0.616000 0.488000
+-0.500000 -0.119500 -0.060900  -0.160000 0.976000 0.112000
+-0.550000 -0.100400 -0.036900  0.792000 0.376000 0.464000
+-0.533200 -0.100400 -0.060900  0.712000 0.696000 -0.024000
+-0.533200 -0.100400 -0.060900  0.712000 0.696000 -0.024000
+-0.750000 -0.267900 0.182900  -0.232000 -0.192000 0.944000
+-0.750000 -0.267900 0.182900  -0.232000 -0.192000 0.944000
+-0.750000 -0.301200 0.168400  -0.360000 -0.432000 0.816000
+-0.700000 -0.272200 0.182900  -0.072000 -0.128000 0.984000
+-0.700000 -0.301200 0.175400  -0.248000 -0.280000 0.920000
+-0.671000 -0.301200 0.182900  -0.120000 -0.104000 0.984000
+-0.700000 -0.351500 0.155000  -0.664000 -0.344000 0.656000
+-0.663400 -0.351500 0.182900  -0.304000 -0.080000 0.944000
+-0.700000 -0.401700 0.124500  -0.664000 -0.408000 0.616000
+-0.650000 -0.385200 0.182900  -0.496000 -0.152000 0.848000
+-0.650000 -0.401700 0.178700  -0.552000 -0.344000 0.752000
+-0.644900 -0.401700 0.182900  -0.528000 -0.240000 0.808000
+-0.650000 -0.451900 0.140100  -0.528000 -0.568000 0.624000
+-0.600000 -0.446800 0.182900  -0.240000 -0.464000 0.848000
+-0.600000 -0.451900 0.179400  -0.216000 -0.496000 0.832000
+-0.583500 -0.451900 0.182900  -0.128000 -0.544000 0.824000
+-0.600000 -0.495400 0.121900  -0.392000 -0.720000 0.560000
+-0.550000 -0.456500 0.182900  0.056000 -0.736000 0.672000
+-0.550000 -0.494000 0.121900  0.024000 -0.832000 0.536000
+-0.600000 -0.495400 0.121900  -0.392000 -0.720000 0.560000
+-0.550000 -0.502100 0.104800  0.104000 -0.840000 0.520000
+-0.600000 -0.502100 0.110700  -0.280000 -0.792000 0.528000
+-0.550000 -0.532000 0.060900  0.080000 -0.776000 0.624000
+-0.600000 -0.531600 0.060900  -0.448000 -0.736000 0.496000
+-0.600000 -0.502100 0.110700  -0.280000 -0.792000 0.528000
+-0.640700 -0.502100 0.060900  -0.496000 -0.728000 0.456000
+-0.600000 -0.495400 0.121900  -0.392000 -0.720000 0.560000
+-0.650000 -0.495900 0.060900  -0.528000 -0.720000 0.432000
+-0.650000 -0.463300 0.121900  -0.512000 -0.696000 0.496000
+-0.700000 -0.453200 0.060900  -0.560000 -0.720000 0.392000
+-0.664200 -0.451900 0.121900  -0.552000 -0.696000 0.448000
+-0.700000 -0.451900 0.063700  -0.672000 -0.600000 0.424000
+-0.700000 -0.404000 0.121900  -0.624000 -0.536000 0.560000
+-0.701000 -0.451900 0.060900  -0.792000 -0.480000 0.344000
+-0.701700 -0.401700 0.121900  -0.704000 -0.408000 0.568000
+-0.731300 -0.401700 0.060900  -0.784000 -0.496000 0.344000
+-0.739400 -0.351500 0.121900  -0.528000 -0.576000 0.616000
+-0.750000 -0.377100 0.060900  -0.760000 -0.552000 0.320000
+-0.750000 -0.351500 0.110100  -0.600000 -0.584000 0.536000
+-0.767900 -0.351500 0.060900  -0.760000 -0.568000 0.296000
+-0.767900 -0.351500 0.060900  -0.760000 -0.568000 0.296000
+-0.750000 -0.301200 0.168400  -0.360000 -0.432000 0.816000
+-0.750000 -0.301200 0.168400  -0.360000 -0.432000 0.816000
+-0.700000 -0.301200 0.175400  -0.248000 -0.280000 0.920000
+-0.750000 -0.342500 0.121900  -0.536000 -0.592000 0.592000
+-0.700000 -0.351500 0.155000  -0.664000 -0.344000 0.656000
+-0.739400 -0.351500 0.121900  -0.528000 -0.576000 0.616000
+-0.700000 -0.401700 0.124500  -0.664000 -0.408000 0.616000
+-0.701700 -0.401700 0.121900  -0.704000 -0.408000 0.568000
+-0.700000 -0.404000 0.121900  -0.624000 -0.536000 0.560000
+-0.700000 -0.401700 0.124500  -0.664000 -0.408000 0.616000
+-0.664200 -0.451900 0.121900  -0.552000 -0.696000 0.448000
+-0.650000 -0.401700 0.178700  -0.552000 -0.344000 0.752000
+-0.650000 -0.451900 0.140100  -0.528000 -0.568000 0.624000
+-0.664200 -0.451900 0.121900  -0.552000 -0.696000 0.448000
+-0.650000 -0.463300 0.121900  -0.512000 -0.696000 0.496000
+-0.650000 -0.451900 0.140100  -0.528000 -0.568000 0.624000
+-0.600000 -0.495400 0.121900  -0.392000 -0.720000 0.560000
+-0.600000 -0.451900 0.179400  -0.216000 -0.496000 0.832000
+-0.600000 -0.451900 0.179400  -0.216000 -0.496000 0.832000
+-0.700000 -0.062200 0.121900  0.504000 0.344000 0.784000
+-0.700000 -0.062200 0.121900  0.504000 0.344000 0.784000
+-0.677900 -0.100400 0.121900  0.528000 0.328000 0.776000
+-0.700000 -0.100400 0.138900  0.488000 0.288000 0.816000
+-0.650000 -0.141800 0.121900  0.432000 0.328000 0.832000
+-0.700000 -0.150600 0.164200  0.408000 0.248000 0.872000
+-0.650000 -0.150600 0.126000  0.408000 0.336000 0.840000
+-0.700000 -0.200800 0.182200  0.152000 0.072000 0.984000
+-0.650000 -0.200800 0.153500  0.376000 0.280000 0.872000
+-0.650000 -0.150600 0.126000  0.408000 0.336000 0.840000
+-0.600000 -0.200800 0.130000  0.152000 0.560000 0.808000
+-0.642900 -0.150600 0.121900  0.408000 0.352000 0.832000
+-0.600000 -0.190600 0.121900  0.296000 0.496000 0.808000
+-0.600000 -0.150600 0.080700  0.576000 0.424000 0.688000
+-0.559300 -0.200800 0.121900  0.160000 0.720000 0.672000
+-0.575700 -0.150600 0.060900  0.384000 0.664000 0.632000
+-0.550000 -0.200800 0.118700  0.032000 0.784000 0.608000
+-0.550000 -0.166800 0.060900  0.264000 0.816000 0.504000
+-0.575700 -0.150600 0.060900  0.384000 0.664000 0.632000
+-0.550000 -0.150600 0.029600  0.504000 0.688000 0.512000
+-0.600000 -0.122400 0.060900  0.616000 0.400000 0.664000
+-0.550000 -0.125000 0.000000  0.608000 0.616000 0.488000
+-0.600000 -0.100400 0.044600  0.672000 0.336000 0.656000
+-0.565600 -0.100400 0.000000  0.744000 0.440000 0.496000
+-0.550000 -0.125000 0.000000  0.608000 0.616000 0.488000
+-0.550000 -0.100400 -0.036900  0.792000 0.376000 0.464000
+-0.550000 -0.100400 -0.036900  0.792000 0.376000 0.464000
+-0.650000 -0.150600 0.126000  0.408000 0.336000 0.840000
+-0.650000 -0.150600 0.126000  0.408000 0.336000 0.840000
+-0.650000 -0.141800 0.121900  0.432000 0.328000 0.832000
+-0.642900 -0.150600 0.121900  0.408000 0.352000 0.832000
+-0.650000 -0.100400 0.096100  0.592000 0.288000 0.744000
+-0.600000 -0.150600 0.080700  0.576000 0.424000 0.688000
+-0.612900 -0.100400 0.060900  0.624000 0.376000 0.672000
+-0.600000 -0.122400 0.060900  0.616000 0.400000 0.664000
+-0.600000 -0.100400 0.044600  0.672000 0.336000 0.656000
+-0.600000 -0.100400 0.044600  0.672000 0.336000 0.656000
+-0.600000 -0.190600 0.121900  0.296000 0.496000 0.808000
+-0.600000 -0.190600 0.121900  0.296000 0.496000 0.808000
+-0.559300 -0.200800 0.121900  0.160000 0.720000 0.672000
+-0.600000 -0.200800 0.130000  0.152000 0.560000 0.808000
+-0.550000 -0.202900 0.121900  0.032000 0.728000 0.680000
+-0.600000 -0.251000 0.177800  0.080000 0.520000 0.840000
+-0.550000 -0.251000 0.173600  -0.016000 0.472000 0.872000
+-0.550000 -0.251000 0.173600  -0.016000 0.472000 0.872000
+-0.500000 -0.200800 0.127000  -0.088000 0.600000 0.784000
+-0.500000 -0.200800 0.127000  -0.088000 0.600000 0.784000
+-0.450000 -0.200800 0.150000  -0.304000 0.608000 0.720000
+-0.500000 -0.196200 0.121900  -0.112000 0.784000 0.600000
+-0.450000 -0.173700 0.121900  -0.368000 0.648000 0.656000
+-0.500000 -0.166600 0.060900  -0.304000 0.832000 0.448000
+-0.450000 -0.150600 0.089400  -0.440000 0.744000 0.496000
+-0.472400 -0.150600 0.060900  -0.464000 0.768000 0.416000
+-0.450000 -0.136300 0.060900  -0.512000 0.720000 0.448000
+-0.500000 -0.150600 0.019400  -0.216000 0.856000 0.464000
+-0.450000 -0.112700 0.000000  -0.520000 0.784000 0.320000
+-0.500000 -0.141000 0.000000  -0.040000 0.880000 0.456000
+-0.500000 -0.141000 0.000000  -0.040000 0.880000 0.456000
+-0.500000 -0.200800 0.127000  -0.088000 0.600000 0.784000
+-0.500000 -0.200800 0.127000  -0.088000 0.600000 0.784000
+-0.500000 -0.249000 0.182900  -0.112000 0.656000 0.744000
+-0.450000 -0.200800 0.150000  -0.304000 0.608000 0.720000
+-0.450000 -0.233700 0.182900  -0.216000 0.472000 0.848000
+-0.400000 -0.200800 0.179200  -0.200000 0.464000 0.856000
+-0.400000 -0.206800 0.182900  -0.168000 0.424000 0.880000
+-0.383500 -0.200800 0.182900  -0.152000 0.448000 0.872000
+-0.400000 -0.200800 0.179200  -0.200000 0.464000 0.856000
+-0.350000 -0.189600 0.182900  -0.288000 0.472000 0.824000
+-0.400000 -0.150600 0.133500  -0.392000 0.600000 0.688000
+-0.350000 -0.150600 0.151300  -0.584000 0.352000 0.720000
+-0.350000 -0.189600 0.182900  -0.288000 0.472000 0.824000
+-0.311100 -0.150600 0.182900  -0.424000 0.464000 0.768000
+-0.311100 -0.150600 0.182900  -0.424000 0.464000 0.768000
+-0.400000 -0.200800 0.179200  -0.200000 0.464000 0.856000
+-0.400000 -0.200800 0.179200  -0.200000 0.464000 0.856000
+-0.450000 -0.200800 0.150000  -0.304000 0.608000 0.720000
+-0.400000 -0.150600 0.133500  -0.392000 0.600000 0.688000
+-0.450000 -0.173700 0.121900  -0.368000 0.648000 0.656000
+-0.414900 -0.150600 0.121900  -0.424000 0.616000 0.648000
+-0.450000 -0.150600 0.089400  -0.440000 0.744000 0.496000
+-0.450000 -0.150600 0.089400  -0.440000 0.744000 0.496000
+-0.351400 -0.100400 0.121900  -0.608000 0.368000 0.696000
+-0.351400 -0.100400 0.121900  -0.608000 0.368000 0.696000
+-0.350000 -0.097900 0.121900  -0.560000 0.424000 0.704000
+-0.350000 -0.100400 0.123500  -0.608000 0.328000 0.712000
+-0.300000 -0.066800 0.121900  -0.280000 0.584000 0.752000
+-0.300000 -0.100400 0.149000  -0.304000 0.432000 0.840000
+-0.255700 -0.050200 0.121900  -0.192000 0.512000 0.832000
+-0.250000 -0.100400 0.155000  0.480000 0.160000 0.856000
+-0.250000 -0.050200 0.123600  0.200000 0.440000 0.864000
+-0.250000 -0.050200 0.123600  0.200000 0.440000 0.864000
+-0.369700 -0.301200 0.182900  0.552000 -0.328000 0.752000
+-0.369700 -0.301200 0.182900  0.552000 -0.328000 0.752000
+-0.350000 -0.276800 0.182900  0.600000 -0.432000 0.664000
+-0.350000 -0.301200 0.167500  0.592000 -0.368000 0.712000
+-0.350000 -0.301200 0.167500  0.592000 -0.368000 0.712000
+-0.334800 -0.251000 0.182900  0.672000 -0.480000 0.552000
+-0.334800 -0.251000 0.182900  0.672000 -0.480000 0.552000
+-0.300000 -0.205800 0.182900  0.768000 -0.472000 0.416000
+-0.300000 -0.251000 0.131000  0.632000 -0.616000 0.464000
+-0.300000 -0.251000 0.131000  0.632000 -0.616000 0.464000
+-0.300000 -0.251000 0.131000  0.632000 -0.616000 0.464000
+-0.300000 -0.251000 0.131000  0.632000 -0.616000 0.464000
+-0.294600 -0.251000 0.121900  0.616000 -0.600000 0.488000
+-0.300000 -0.256400 0.121900  0.624000 -0.624000 0.456000
+-0.300000 -0.256400 0.121900  0.624000 -0.624000 0.456000
+0.550000 0.331800 0.121900  -0.696000 0.536000 0.456000
+0.550000 0.331800 0.121900  -0.696000 0.536000 0.456000
+0.550000 0.301200 0.149100  -0.896000 -0.096000 0.416000
+0.538800 0.301200 0.121900  -0.912000 0.128000 0.376000
+0.538800 0.301200 0.121900  -0.912000 0.128000 0.376000
+0.548800 0.251000 0.121900  -0.912000 -0.176000 0.360000
+0.548800 0.251000 0.121900  -0.912000 -0.176000 0.360000
+0.550000 0.251000 0.125100  -0.872000 -0.184000 0.440000
+0.550000 0.246100 0.121900  -0.904000 -0.224000 0.352000
+0.586200 0.251000 0.182900  -0.672000 -0.144000 0.720000
+0.567500 0.200800 0.121900  -0.784000 -0.344000 0.504000
+0.600000 0.211800 0.182900  -0.672000 -0.280000 0.672000
+0.600000 0.200800 0.176700  -0.712000 -0.296000 0.624000
+0.604600 0.200800 0.182900  -0.672000 -0.288000 0.664000
+0.600000 0.150600 0.141200  -0.712000 -0.440000 0.536000
+0.641000 0.150600 0.182900  -0.528000 -0.464000 0.696000
+0.600000 0.134700 0.121900  -0.776000 -0.456000 0.424000
+0.650000 0.141000 0.182900  -0.512000 -0.488000 0.704000
+0.627900 0.100400 0.121900  -0.608000 -0.608000 0.504000
+0.650000 0.100400 0.150000  -0.536000 -0.592000 0.592000
+0.650000 0.080100 0.121900  -0.576000 -0.640000 0.496000
+0.685300 0.100400 0.182900  -0.504000 -0.560000 0.648000
+0.692100 0.050200 0.121900  -0.432000 -0.784000 0.424000
+0.700000 0.088000 0.182900  -0.464000 -0.608000 0.640000
+0.700000 0.050200 0.131500  -0.112000 -0.824000 0.544000
+0.750000 0.062100 0.182900  -0.416000 -0.632000 0.648000
+0.744700 0.050200 0.121900  0.096000 -0.864000 0.480000
+0.750000 0.050900 0.121900  0.096000 -0.792000 0.600000
+0.750000 0.050200 0.120200  -0.160000 -0.904000 0.376000
+0.751700 0.050200 0.121900  -0.392000 -0.816000 0.416000
+0.750000 0.031700 0.060900  -0.136000 -0.928000 0.336000
+0.800000 0.028400 0.121900  -0.376000 -0.808000 0.432000
+0.798100 0.000000 0.060900  -0.504000 -0.792000 0.312000
+0.800000 0.000000 0.064400  -0.576000 -0.736000 0.344000
+0.800000 -0.001000 0.060900  -0.584000 -0.776000 0.216000
+0.829700 0.000000 0.121900  -0.704000 -0.616000 0.344000
+0.843600 -0.050200 0.060900  -0.704000 -0.672000 0.184000
+0.850000 -0.029600 0.121900  -0.840000 -0.432000 0.312000
+0.850000 -0.050200 0.089500  -0.768000 -0.592000 0.216000
+0.857500 -0.050200 0.121900  -0.848000 -0.448000 0.272000
+0.850000 -0.056700 0.060900  -0.720000 -0.664000 0.176000
+0.892500 -0.100400 0.121900  -0.688000 -0.680000 0.240000
+0.881900 -0.100400 0.060900  -0.752000 -0.632000 0.152000
+0.850000 -0.056700 0.060900  -0.720000 -0.664000 0.176000
+0.873300 -0.100400 0.000000  -0.752000 -0.632000 0.120000
+0.850000 -0.068700 0.000000  -0.752000 -0.640000 0.136000
+0.865600 -0.100400 -0.060900  -0.776000 -0.616000 0.120000
+0.850000 -0.079400 -0.060900  -0.768000 -0.616000 0.120000
+0.858300 -0.100400 -0.121900  -0.792000 -0.600000 0.056000
+0.850000 -0.088400 -0.121900  -0.808000 -0.584000 0.016000
+0.858100 -0.100400 -0.182900  -0.824000 -0.552000 0.000000
+0.850000 -0.086900 -0.182900  -0.848000 -0.512000 -0.048000
+0.860900 -0.100400 -0.243900  -0.856000 -0.496000 -0.072000
+0.850000 -0.077200 -0.243900  -0.824000 -0.432000 -0.344000
+0.869700 -0.100400 -0.304800  -0.880000 -0.248000 -0.400000
+0.850000 -0.050200 -0.276700  -0.784000 -0.280000 -0.544000
+0.867300 -0.050200 -0.304800  -0.784000 -0.136000 -0.600000
+0.850000 0.000000 -0.279000  -0.536000 0.488000 -0.680000
+0.877300 0.000000 -0.304800  -0.592000 0.480000 -0.632000
+0.877300 0.000000 -0.304800  -0.592000 0.480000 -0.632000
+0.600000 0.150600 0.141200  -0.712000 -0.440000 0.536000
+0.600000 0.150600 0.141200  -0.712000 -0.440000 0.536000
+0.600000 0.200800 0.176700  -0.712000 -0.296000 0.624000
+0.591100 0.150600 0.121900  -0.792000 -0.400000 0.440000
+0.567500 0.200800 0.121900  -0.784000 -0.344000 0.504000
+0.560700 0.150600 0.060900  -0.704000 -0.368000 0.592000
+0.550000 0.200800 0.086900  -0.880000 -0.256000 0.392000
+0.550000 0.174700 0.060900  -0.744000 -0.320000 0.576000
+0.538800 0.200800 0.060900  -0.824000 -0.216000 0.520000
+0.550000 0.150600 0.048400  -0.632000 -0.416000 0.640000
+0.500000 0.200800 0.008600  -0.576000 -0.176000 0.792000
+0.510200 0.150600 0.000000  -0.752000 -0.384000 0.520000
+0.500000 0.181600 0.000000  -0.600000 -0.304000 0.728000
+0.500000 0.150600 -0.020200  -0.704000 -0.472000 0.520000
+0.488800 0.200800 0.000000  -0.512000 0.024000 0.856000
+0.460500 0.150600 -0.060900  -0.624000 -0.512000 0.584000
+0.450000 0.200800 -0.035500  -0.536000 -0.264000 0.792000
+0.450000 0.163500 -0.060900  -0.600000 -0.504000 0.608000
+0.416500 0.200800 -0.060900  -0.560000 -0.352000 0.744000
+0.450000 0.150600 -0.075000  -0.616000 -0.488000 0.608000
+0.400000 0.200800 -0.077800  -0.600000 -0.432000 0.664000
+0.401900 0.150600 -0.121900  -0.864000 -0.496000 -0.024000
+0.400000 0.152400 -0.121900  -0.688000 -0.712000 -0.048000
+0.407800 0.150600 -0.182900  -0.544000 -0.240000 -0.800000
+0.400000 0.155900 -0.182900  -0.216000 -0.144000 -0.960000
+0.450000 0.150600 -0.187200  -0.088000 0.168000 -0.976000
+0.400000 0.200800 -0.189400  -0.152000 -0.072000 -0.984000
+0.450000 0.200800 -0.192400  -0.128000 -0.040000 -0.984000
+0.400000 0.251000 -0.186400  -0.152000 0.040000 -0.984000
+0.450000 0.251000 -0.188200  -0.104000 0.040000 -0.992000
+0.400000 0.301200 -0.184200  -0.016000 -0.016000 -0.992000
+0.450000 0.301200 -0.186200  0.000000 -0.016000 -0.992000
+0.400000 0.351500 -0.194500  0.000000 0.072000 -0.992000
+0.450000 0.351500 -0.196000  0.120000 0.128000 -0.976000
+0.400000 0.377300 -0.182900  0.016000 0.320000 -0.944000
+0.450000 0.373800 -0.182900  0.104000 0.432000 -0.888000
+0.400000 0.401700 -0.171200  0.088000 0.472000 -0.872000
+0.450000 0.401700 -0.160800  0.376000 0.656000 -0.640000
+0.400000 0.432800 -0.121900  0.160000 0.904000 -0.384000
+0.450000 0.422200 -0.121900  0.368000 0.832000 -0.392000
+0.400000 0.419800 -0.060900  0.080000 0.848000 0.520000
+0.450000 0.414500 -0.060900  0.192000 0.928000 0.304000
+0.400000 0.401700 -0.034800  -0.040000 0.584000 0.808000
+0.450000 0.401700 -0.038900  -0.120000 0.592000 0.784000
+0.400000 0.351500 -0.018700  -0.136000 -0.208000 0.960000
+0.450000 0.351500 -0.003200  -0.296000 0.344000 0.888000
+0.450000 0.401700 -0.038900  -0.120000 0.592000 0.784000
+0.458200 0.351500 0.000000  -0.280000 0.520000 0.800000
+0.500000 0.401700 -0.057700  0.096000 0.864000 0.480000
+0.500000 0.369100 0.000000  -0.184000 0.800000 0.552000
+0.517100 0.401700 -0.060900  0.080000 0.968000 0.224000
+0.550000 0.388900 0.000000  -0.392000 0.856000 0.320000
+0.550000 0.398000 -0.060900  0.000000 0.968000 -0.216000
+0.517100 0.401700 -0.060900  0.080000 0.968000 0.224000
+0.550000 0.362300 -0.121900  0.400000 0.656000 -0.632000
+0.500000 0.401700 -0.069300  0.168000 0.952000 -0.216000
+0.500000 0.393600 -0.121900  0.504000 0.744000 -0.432000
+0.488600 0.401700 -0.121900  0.504000 0.776000 -0.368000
+0.500000 0.355500 -0.182900  0.400000 0.616000 -0.664000
+0.450000 0.401700 -0.160800  0.376000 0.656000 -0.640000
+0.450000 0.373800 -0.182900  0.104000 0.432000 -0.888000
+0.500000 0.355500 -0.182900  0.400000 0.616000 -0.664000
+0.450000 0.351500 -0.196000  0.120000 0.128000 -0.976000
+0.500000 0.351500 -0.187300  0.416000 0.568000 -0.696000
+0.450000 0.301200 -0.186200  0.000000 -0.016000 -0.992000
+0.500000 0.301200 -0.193500  0.168000 0.072000 -0.976000
+0.450000 0.251000 -0.188200  -0.104000 0.040000 -0.992000
+0.500000 0.251000 -0.199400  0.072000 0.096000 -0.984000
+0.450000 0.200800 -0.192400  -0.128000 -0.040000 -0.984000
+0.500000 0.200800 -0.200200  -0.104000 -0.048000 -0.992000
+0.450000 0.150600 -0.187200  -0.088000 0.168000 -0.976000
+0.500000 0.150600 -0.194400  -0.208000 0.240000 -0.944000
+0.450000 0.100400 -0.233000  -0.008000 0.816000 -0.568000
+0.500000 0.100400 -0.210700  0.048000 0.704000 -0.704000
+0.450000 0.095300 -0.243900  -0.008000 0.856000 -0.512000
+0.500000 0.082500 -0.243900  0.216000 0.832000 -0.504000
+0.450000 0.055500 -0.304800  0.064000 0.864000 -0.496000
+0.500000 0.050200 -0.303800  0.264000 0.816000 -0.504000
+0.496000 0.050200 -0.304800  0.104000 0.800000 -0.576000
+0.500000 0.049600 -0.304800  0.264000 0.736000 -0.616000
+0.450000 0.050200 -0.314200  0.064000 0.744000 -0.656000
+0.500000 0.014000 -0.365800  0.216000 0.784000 -0.568000
+0.450000 0.007700 -0.365800  -0.264000 0.744000 -0.600000
+0.500000 0.000000 -0.393700  0.528000 0.072000 -0.840000
+0.450000 0.000000 -0.377000  -0.360000 0.400000 -0.840000
+0.500000 -0.027200 -0.365800  0.264000 -0.576000 -0.768000
+0.450000 -0.014200 -0.365800  -0.336000 -0.568000 -0.744000
+0.500000 -0.050200 -0.339600  -0.136000 -0.672000 -0.720000
+0.450000 -0.050200 -0.325200  -0.120000 -0.568000 -0.808000
+0.450000 -0.014200 -0.365800  -0.336000 -0.568000 -0.744000
+0.400000 -0.050200 -0.360800  0.184000 -0.432000 -0.872000
+0.431500 0.000000 -0.365800  -0.424000 0.312000 -0.840000
+0.400000 0.000000 -0.343200  -0.216000 0.592000 -0.768000
+0.450000 0.007700 -0.365800  -0.264000 0.744000 -0.600000
+0.400000 0.041200 -0.304800  -0.352000 0.672000 -0.648000
+0.450000 0.050200 -0.314200  0.064000 0.744000 -0.656000
+0.419200 0.050200 -0.304800  -0.224000 0.736000 -0.632000
+0.450000 0.055500 -0.304800  0.064000 0.864000 -0.496000
+0.400000 0.050200 -0.294000  -0.352000 0.672000 -0.640000
+0.450000 0.095300 -0.243900  -0.008000 0.856000 -0.512000
+0.400000 0.083700 -0.243900  -0.328000 0.768000 -0.536000
+0.450000 0.100400 -0.233000  -0.008000 0.816000 -0.568000
+0.400000 0.100400 -0.207800  -0.424000 0.688000 -0.576000
+0.450000 0.150600 -0.187200  -0.088000 0.168000 -0.976000
+0.400000 0.146600 -0.182900  -0.440000 0.464000 -0.760000
+0.407800 0.150600 -0.182900  -0.544000 -0.240000 -0.800000
+0.400000 0.100400 -0.150800  -0.768000 0.376000 0.512000
+0.401900 0.150600 -0.121900  -0.864000 -0.496000 -0.024000
+0.415000 0.100400 -0.121900  -0.640000 0.192000 0.736000
+0.450000 0.150600 -0.075000  -0.616000 -0.488000 0.608000
+0.450000 0.100400 -0.090700  -0.384000 -0.320000 0.856000
+0.460500 0.150600 -0.060900  -0.624000 -0.512000 0.584000
+0.500000 0.100400 -0.067100  -0.632000 -0.296000 0.704000
+0.500000 0.107000 -0.060900  -0.608000 -0.480000 0.616000
+0.504600 0.100400 -0.060900  -0.704000 -0.248000 0.656000
+0.500000 0.150600 -0.020200  -0.704000 -0.472000 0.520000
+0.550000 0.100400 -0.005700  -0.672000 -0.576000 0.448000
+0.510200 0.150600 0.000000  -0.752000 -0.384000 0.520000
+0.550000 0.104000 0.000000  -0.664000 -0.568000 0.464000
+0.550000 0.150600 0.048400  -0.632000 -0.416000 0.640000
+0.553100 0.100400 0.000000  -0.664000 -0.576000 0.464000
+0.560700 0.150600 0.060900  -0.704000 -0.368000 0.592000
+0.593200 0.100400 0.060900  -0.640000 -0.584000 0.496000
+0.591100 0.150600 0.121900  -0.792000 -0.400000 0.440000
+0.600000 0.100400 0.071800  -0.648000 -0.592000 0.472000
+0.600000 0.134700 0.121900  -0.776000 -0.456000 0.424000
+0.627900 0.100400 0.121900  -0.608000 -0.608000 0.504000
+0.600000 0.100400 0.071800  -0.648000 -0.592000 0.472000
+0.650000 0.080100 0.121900  -0.576000 -0.640000 0.496000
+0.600000 0.093600 0.060900  -0.624000 -0.616000 0.464000
+0.650000 0.050200 0.073400  -0.576000 -0.624000 0.512000
+0.641200 0.050200 0.060900  -0.600000 -0.608000 0.512000
+0.650000 0.041800 0.060900  -0.568000 -0.648000 0.504000
+0.602900 0.050200 0.000000  -0.576000 -0.704000 0.400000
+0.650000 0.013100 0.000000  -0.448000 -0.792000 0.392000
+0.600000 0.050200 -0.005300  -0.440000 -0.752000 0.480000
+0.650000 0.000000 -0.040500  0.104000 -0.944000 0.296000
+0.600000 0.000000 -0.044900  -0.016000 -0.720000 0.688000
+0.650000 -0.010200 -0.060900  0.168000 -0.784000 0.592000
+0.600000 -0.012300 -0.060900  0.104000 -0.576000 0.800000
+0.650000 -0.033500 -0.121900  0.512000 -0.672000 0.520000
+0.600000 -0.050200 -0.088500  0.448000 -0.400000 0.792000
+0.638000 -0.050200 -0.121900  0.800000 -0.536000 0.256000
+0.600000 -0.100400 -0.077400  0.584000 0.048000 0.800000
+0.626600 -0.100400 -0.121900  0.848000 0.208000 0.472000
+0.638000 -0.050200 -0.121900  0.800000 -0.536000 0.256000
+0.638900 -0.100400 -0.182900  0.920000 0.368000 0.072000
+0.649100 -0.050200 -0.182900  0.816000 -0.544000 0.144000
+0.637300 -0.100400 -0.243900  0.848000 0.016000 -0.520000
+0.637200 -0.050200 -0.243900  0.840000 -0.080000 -0.528000
+0.604900 -0.100400 -0.304800  0.744000 -0.360000 -0.552000
+0.600000 -0.050200 -0.286000  0.712000 0.144000 -0.680000
+0.600000 -0.086300 -0.304800  0.440000 0.312000 -0.832000
+0.587300 -0.050200 -0.304800  0.688000 0.056000 -0.712000
+0.589400 -0.100400 -0.304800  -0.440000 -0.424000 -0.784000
+0.550000 -0.083700 -0.304800  0.088000 -0.736000 -0.664000
+0.550000 -0.100400 -0.280800  -0.008000 -0.528000 -0.840000
+0.500000 -0.082600 -0.304800  0.216000 -0.680000 -0.688000
+0.500000 -0.100400 -0.277800  0.560000 -0.104000 -0.816000
+0.475800 -0.100400 -0.304800  0.512000 -0.104000 -0.848000
+0.500000 -0.127100 -0.304800  0.480000 0.456000 -0.744000
+0.500000 -0.100400 -0.277800  0.560000 -0.104000 -0.816000
+0.523400 -0.150600 -0.304800  0.376000 0.592000 -0.704000
+0.550000 -0.100400 -0.280800  -0.008000 -0.528000 -0.840000
+0.550000 -0.150600 -0.287800  0.352000 0.528000 -0.768000
+0.589400 -0.100400 -0.304800  -0.440000 -0.424000 -0.784000
+0.600000 -0.150600 -0.265200  0.248000 0.032000 -0.960000
+0.600000 -0.105700 -0.304800  0.312000 -0.728000 -0.600000
+0.650000 -0.150600 -0.274900  0.544000 0.464000 -0.688000
+0.604900 -0.100400 -0.304800  0.744000 -0.360000 -0.552000
+0.650000 -0.120200 -0.243900  0.704000 0.520000 -0.472000
+0.637300 -0.100400 -0.243900  0.848000 0.016000 -0.520000
+0.650000 -0.117900 -0.182900  0.792000 0.600000 0.024000
+0.638900 -0.100400 -0.182900  0.920000 0.368000 0.072000
+0.650000 -0.146100 -0.121900  0.720000 0.504000 0.464000
+0.626600 -0.100400 -0.121900  0.848000 0.208000 0.472000
+0.626600 -0.100400 -0.121900  0.848000 0.208000 0.472000
+0.591100 0.150600 0.121900  -0.792000 -0.400000 0.440000
+0.591100 0.150600 0.121900  -0.792000 -0.400000 0.440000
+0.600000 0.150600 0.141200  -0.712000 -0.440000 0.536000
+0.600000 0.134700 0.121900  -0.776000 -0.456000 0.424000
+0.600000 0.134700 0.121900  -0.776000 -0.456000 0.424000
+0.650000 0.141000 0.182900  -0.512000 -0.488000 0.704000
+0.650000 0.141000 0.182900  -0.512000 -0.488000 0.704000
+0.685300 0.100400 0.182900  -0.504000 -0.560000 0.648000
+0.650000 0.100400 0.150000  -0.536000 -0.592000 0.592000
+0.650000 0.100400 0.150000  -0.536000 -0.592000 0.592000
+0.692100 0.050200 0.121900  -0.432000 -0.784000 0.424000
+0.692100 0.050200 0.121900  -0.432000 -0.784000 0.424000
+0.700000 0.050200 0.131500  -0.112000 -0.824000 0.544000
+0.700000 0.046100 0.121900  -0.152000 -0.904000 0.376000
+0.744700 0.050200 0.121900  0.096000 -0.864000 0.480000
+0.700000 0.026800 0.060900  -0.288000 -0.896000 0.328000
+0.750000 0.050200 0.120200  -0.160000 -0.904000 0.376000
+0.750000 0.031700 0.060900  -0.136000 -0.928000 0.336000
+0.700000 0.026800 0.060900  -0.288000 -0.896000 0.328000
+0.750000 0.013300 0.000000  -0.240000 -0.936000 0.240000
+0.700000 0.012000 0.000000  -0.032000 -0.960000 0.272000
+0.750000 0.001600 -0.060900  -0.416000 -0.904000 -0.016000
+0.700000 0.001400 -0.060900  0.088000 -0.968000 0.192000
+0.750000 0.004300 -0.121900  -0.408000 -0.880000 -0.216000
+0.700000 0.000400 -0.121900  0.224000 -0.968000 0.032000
+0.750000 0.019900 -0.182900  -0.176000 -0.792000 -0.576000
+0.700000 0.009000 -0.182900  0.456000 -0.744000 -0.472000
+0.750000 0.050200 -0.223600  -0.168000 -0.552000 -0.808000
+0.700000 0.050200 -0.225700  0.368000 -0.368000 -0.848000
+0.750000 0.100400 -0.218500  0.200000 0.232000 -0.944000
+0.700000 0.100400 -0.234000  0.272000 0.000000 -0.960000
+0.750000 0.150600 -0.191500  0.256000 0.656000 -0.704000
+0.700000 0.150600 -0.210500  0.296000 0.424000 -0.848000
+0.750000 0.157000 -0.182900  0.280000 0.720000 -0.624000
+0.700000 0.190400 -0.182900  0.432000 0.560000 -0.696000
+0.750000 0.186400 -0.121900  0.504000 0.648000 -0.560000
+0.700000 0.200800 -0.171600  0.480000 0.608000 -0.616000
+0.734900 0.200800 -0.121900  0.552000 0.608000 -0.552000
+0.700000 0.229200 -0.121900  0.528000 0.656000 -0.528000
+0.750000 0.200800 -0.104400  0.480000 0.680000 -0.544000
+0.700000 0.251000 -0.093200  0.552000 0.600000 -0.568000
+0.750000 0.228900 -0.060900  0.576000 0.696000 -0.416000
+0.725300 0.251000 -0.060900  0.696000 0.648000 -0.288000
+0.750000 0.219200 0.000000  0.672000 0.728000 0.080000
+0.721000 0.251000 0.000000  0.784000 0.608000 -0.040000
+0.750000 0.222200 0.060900  0.704000 0.696000 -0.080000
+0.727500 0.251000 0.060900  0.792000 0.584000 -0.112000
+0.750000 0.233400 0.121900  0.720000 0.680000 -0.080000
+0.736800 0.251000 0.121900  0.752000 0.632000 0.144000
+0.727500 0.251000 0.060900  0.792000 0.584000 -0.112000
+0.700000 0.297800 0.121900  0.728000 0.680000 -0.032000
+0.700000 0.290800 0.060900  0.800000 0.576000 -0.104000
+0.696500 0.301200 0.121900  0.712000 0.672000 0.168000
+0.692400 0.301200 0.060900  0.752000 0.648000 -0.056000
+0.653800 0.351500 0.121900  0.656000 0.616000 0.424000
+0.663900 0.351500 0.060900  0.768000 0.624000 0.096000
+0.650000 0.355500 0.121900  0.632000 0.632000 0.432000
+0.650000 0.370100 0.060900  0.776000 0.624000 0.048000
+0.600000 0.382600 0.121900  0.272000 0.776000 0.560000
+0.612200 0.401700 0.060900  0.488000 0.832000 0.224000
+0.600000 0.401700 0.085900  0.096000 0.928000 0.336000
+0.600000 0.407100 0.060900  0.120000 0.968000 0.184000
+0.584600 0.401700 0.060900  -0.416000 0.872000 0.248000
+0.600000 0.410900 0.000000  0.104000 0.992000 -0.032000
+0.568400 0.401700 0.000000  -0.472000 0.832000 -0.264000
+0.600000 0.401700 -0.057700  0.168000 0.920000 -0.344000
+0.600000 0.410900 0.000000  0.104000 0.992000 -0.032000
+0.616700 0.401700 0.000000  0.496000 0.864000 -0.032000
+0.600000 0.407100 0.060900  0.120000 0.968000 0.184000
+0.612200 0.401700 0.060900  0.488000 0.832000 0.224000
+0.616700 0.401700 0.000000  0.496000 0.864000 -0.032000
+0.650000 0.370100 0.060900  0.776000 0.624000 0.048000
+0.650000 0.368200 0.000000  0.792000 0.584000 -0.144000
+0.663900 0.351500 0.060900  0.768000 0.624000 0.096000
+0.660900 0.351500 0.000000  0.832000 0.512000 -0.176000
+0.692400 0.301200 0.060900  0.752000 0.648000 -0.056000
+0.685300 0.301200 0.000000  0.832000 0.536000 -0.104000
+0.700000 0.290800 0.060900  0.800000 0.576000 -0.104000
+0.700000 0.279600 0.000000  0.792000 0.600000 -0.048000
+0.727500 0.251000 0.060900  0.792000 0.584000 -0.112000
+0.721000 0.251000 0.000000  0.784000 0.608000 -0.040000
+0.700000 0.279600 0.000000  0.792000 0.600000 -0.048000
+0.725300 0.251000 -0.060900  0.696000 0.648000 -0.288000
+0.700000 0.278700 -0.060900  0.648000 0.584000 -0.472000
+0.700000 0.251000 -0.093200  0.552000 0.600000 -0.568000
+0.680100 0.301200 -0.060900  0.752000 0.544000 -0.368000
+0.673000 0.251000 -0.121900  0.568000 0.576000 -0.584000
+0.650000 0.301200 -0.100800  0.528000 0.504000 -0.672000
+0.650000 0.278000 -0.121900  0.448000 0.624000 -0.624000
+0.608400 0.301200 -0.121900  0.448000 0.488000 -0.744000
+0.650000 0.251000 -0.154700  0.488000 0.640000 -0.584000
+0.600000 0.301200 -0.128700  0.472000 0.520000 -0.704000
+0.608400 0.251000 -0.182900  0.328000 0.488000 -0.800000
+0.600000 0.256700 -0.182900  0.328000 0.496000 -0.792000
+0.600000 0.251000 -0.187000  0.320000 0.456000 -0.816000
+0.608400 0.251000 -0.182900  0.328000 0.488000 -0.800000
+0.600000 0.200800 -0.209200  0.248000 0.288000 -0.920000
+0.650000 0.227800 -0.182900  0.368000 0.576000 -0.720000
+0.650000 0.200800 -0.204000  0.272000 0.408000 -0.864000
+0.687200 0.200800 -0.182900  0.432000 0.544000 -0.712000
+0.650000 0.150600 -0.219600  0.200000 0.280000 -0.928000
+0.700000 0.190400 -0.182900  0.432000 0.560000 -0.696000
+0.700000 0.150600 -0.210500  0.296000 0.424000 -0.848000
+0.650000 0.150600 -0.219600  0.200000 0.280000 -0.928000
+0.700000 0.100400 -0.234000  0.272000 0.000000 -0.960000
+0.650000 0.100400 -0.241400  0.232000 0.064000 -0.968000
+0.700000 0.050200 -0.225700  0.368000 -0.368000 -0.848000
+0.650000 0.067400 -0.243900  0.208000 0.056000 -0.968000
+0.653800 0.050200 -0.243900  0.232000 0.032000 -0.968000
+0.650000 0.050200 -0.244900  0.216000 0.040000 -0.968000
+0.653800 0.000000 -0.243900  0.576000 -0.112000 -0.808000
+0.650000 0.000000 -0.248500  0.680000 -0.160000 -0.712000
+0.650000 -0.016900 -0.243900  0.704000 -0.184000 -0.672000
+0.600000 0.000000 -0.284600  0.512000 0.112000 -0.840000
+0.637200 -0.050200 -0.243900  0.840000 -0.080000 -0.528000
+0.600000 -0.050200 -0.286000  0.712000 0.144000 -0.680000
+0.600000 0.000000 -0.284600  0.512000 0.112000 -0.840000
+0.587300 -0.050200 -0.304800  0.688000 0.056000 -0.712000
+0.578400 0.000000 -0.304800  0.536000 0.480000 -0.688000
+0.578400 0.000000 -0.304800  0.536000 0.480000 -0.688000
+0.750000 0.062100 0.182900  -0.416000 -0.632000 0.648000
+0.750000 0.062100 0.182900  -0.416000 -0.632000 0.648000
+0.750000 0.050900 0.121900  0.096000 -0.792000 0.600000
+0.762700 0.050200 0.182900  -0.512000 -0.672000 0.520000
+0.751700 0.050200 0.121900  -0.392000 -0.816000 0.416000
+0.800000 0.035400 0.182900  -0.432000 -0.808000 0.384000
+0.800000 0.028400 0.121900  -0.376000 -0.808000 0.432000
+0.846600 0.000000 0.182900  -0.736000 -0.616000 0.264000
+0.829700 0.000000 0.121900  -0.704000 -0.616000 0.344000
+0.850000 -0.004200 0.182900  -0.720000 -0.616000 0.288000
+0.850000 -0.029600 0.121900  -0.840000 -0.432000 0.312000
+0.880500 -0.050200 0.182900  -0.744000 -0.528000 0.384000
+0.857500 -0.050200 0.121900  -0.848000 -0.448000 0.272000
+0.900000 -0.076800 0.182900  -0.504000 -0.624000 0.592000
+0.892500 -0.100400 0.121900  -0.688000 -0.680000 0.240000
+0.900000 -0.100400 0.145900  -0.608000 -0.728000 0.304000
+0.900000 -0.076800 0.182900  -0.504000 -0.624000 0.592000
+0.934300 -0.100400 0.182900  -0.392000 -0.752000 0.520000
+0.934300 -0.100400 0.182900  -0.392000 -0.752000 0.520000
+0.800000 0.150600 0.181400  0.520000 0.336000 0.776000
+0.800000 0.150600 0.181400  0.520000 0.336000 0.776000
+0.850000 0.150600 0.126500  0.640000 0.560000 0.512000
+0.800000 0.190400 0.121900  0.624000 0.752000 0.168000
+0.850000 0.151600 0.121900  0.680000 0.720000 0.080000
+0.800000 0.182100 0.060900  0.560000 0.824000 -0.024000
+0.850000 0.154700 0.060900  0.576000 0.800000 0.096000
+0.800000 0.184600 0.000000  0.464000 0.872000 0.120000
+0.850000 0.161100 0.000000  0.480000 0.856000 0.160000
+0.800000 0.194300 -0.060900  0.416000 0.824000 -0.360000
+0.850000 0.171300 -0.060900  0.448000 0.864000 -0.216000
+0.800000 0.164900 -0.121900  0.312000 0.800000 -0.504000
+0.850000 0.155600 -0.121900  0.432000 0.856000 -0.272000
+0.800000 0.150600 -0.164100  0.256000 0.800000 -0.528000
+0.850000 0.150600 -0.140900  0.432000 0.840000 -0.304000
+0.800000 0.138600 -0.182900  0.232000 0.712000 -0.656000
+0.850000 0.127100 -0.182900  0.192000 0.744000 -0.632000
+0.800000 0.100400 -0.216300  0.104000 0.416000 -0.896000
+0.850000 0.100400 -0.218500  0.128000 0.592000 -0.784000
+0.800000 0.050200 -0.233400  -0.176000 0.416000 -0.880000
+0.850000 0.050200 -0.237100  -0.376000 0.576000 -0.720000
+0.800000 0.000000 -0.217200  -0.656000 -0.464000 -0.584000
+0.850000 0.042400 -0.243900  -0.408000 0.528000 -0.736000
+0.819700 0.000000 -0.243900  -0.752000 -0.192000 -0.616000
+0.850000 0.000000 -0.279000  -0.536000 0.488000 -0.680000
+0.835300 -0.050200 -0.243900  -0.840000 -0.416000 -0.336000
+0.850000 -0.050200 -0.276700  -0.784000 -0.280000 -0.544000
+0.850000 -0.077200 -0.243900  -0.824000 -0.432000 -0.344000
+0.835300 -0.050200 -0.243900  -0.840000 -0.416000 -0.336000
+0.850000 -0.086900 -0.182900  -0.848000 -0.512000 -0.048000
+0.822900 -0.050200 -0.182900  -0.792000 -0.592000 -0.088000
+0.850000 -0.088400 -0.121900  -0.808000 -0.584000 0.016000
+0.818400 -0.050200 -0.121900  -0.760000 -0.640000 0.016000
+0.850000 -0.079400 -0.060900  -0.768000 -0.616000 0.120000
+0.823600 -0.050200 -0.060900  -0.736000 -0.664000 0.112000
+0.850000 -0.068700 0.000000  -0.752000 -0.640000 0.136000
+0.832800 -0.050200 0.000000  -0.728000 -0.656000 0.144000
+0.850000 -0.056700 0.060900  -0.720000 -0.664000 0.176000
+0.843600 -0.050200 0.060900  -0.704000 -0.672000 0.184000
+0.850000 -0.050200 0.089500  -0.768000 -0.592000 0.216000
+0.850000 -0.050200 0.089500  -0.768000 -0.592000 0.216000
+0.850000 0.150600 0.126500  0.640000 0.560000 0.512000
+0.850000 0.150600 0.126500  0.640000 0.560000 0.512000
+0.850000 0.151600 0.121900  0.680000 0.720000 0.080000
+0.850900 0.150600 0.121900  0.704000 0.704000 0.080000
+0.850000 0.154700 0.060900  0.576000 0.800000 0.096000
+0.855400 0.150600 0.060900  0.680000 0.720000 0.072000
+0.850000 0.161100 0.000000  0.480000 0.856000 0.160000
+0.867700 0.150600 0.000000  0.552000 0.816000 0.152000
+0.850000 0.171300 -0.060900  0.448000 0.864000 -0.216000
+0.888500 0.150600 -0.060900  0.504000 0.856000 -0.040000
+0.850000 0.155600 -0.121900  0.432000 0.856000 -0.272000
+0.859300 0.150600 -0.121900  0.456000 0.840000 -0.272000
+0.850000 0.150600 -0.140900  0.432000 0.840000 -0.304000
+0.850000 0.150600 -0.140900  0.432000 0.840000 -0.304000
+0.891700 0.100400 0.182900  0.576000 0.688000 0.424000
+0.891700 0.100400 0.182900  0.576000 0.688000 0.424000
+0.900000 0.100400 0.165200  0.584000 0.744000 0.296000
+0.900000 0.093100 0.182900  0.568000 0.672000 0.464000
+0.911800 0.100400 0.121900  0.528000 0.800000 0.264000
+0.940200 0.050200 0.182900  0.624000 0.528000 0.568000
+0.950000 0.069700 0.121900  0.360000 0.840000 0.384000
+0.950000 0.050200 0.169400  0.600000 0.560000 0.560000
+1.000000 0.053600 0.121900  0.280000 0.872000 0.392000
+1.000000 0.050200 0.131000  0.336000 0.784000 0.512000
+0.950000 0.050200 0.169400  0.600000 0.560000 0.560000
+1.000000 0.004900 0.182900  0.336000 0.520000 0.776000
+0.950000 0.037400 0.182900  0.520000 0.504000 0.680000
+0.950000 0.050200 0.169400  0.600000 0.560000 0.560000
+0.940200 0.050200 0.182900  0.624000 0.528000 0.568000
+0.940200 0.050200 0.182900  0.624000 0.528000 0.568000
+0.900000 0.100400 0.165200  0.584000 0.744000 0.296000
+0.900000 0.100400 0.165200  0.584000 0.744000 0.296000
+0.900000 0.107300 0.121900  0.512000 0.832000 0.184000
+0.911800 0.100400 0.121900  0.528000 0.800000 0.264000
+0.900000 0.118900 0.060900  0.472000 0.856000 0.184000
+0.936800 0.100400 0.060900  0.456000 0.872000 0.168000
+0.900000 0.131100 0.000000  0.480000 0.848000 0.192000
+0.950000 0.100400 0.012800  0.496000 0.848000 0.136000
+0.950000 0.102000 0.000000  0.472000 0.864000 0.120000
+0.952900 0.100400 0.000000  0.504000 0.848000 0.120000
+0.950000 0.106300 -0.060900  0.576000 0.776000 -0.240000
+0.957800 0.100400 -0.060900  0.544000 0.824000 -0.120000
+0.950000 0.100400 -0.078300  0.560000 0.768000 -0.304000
+1.000000 0.074600 -0.060900  0.496000 0.816000 -0.280000
+0.950000 0.086300 -0.121900  0.544000 0.784000 -0.280000
+1.000000 0.056100 -0.121900  0.488000 0.808000 -0.304000
+0.950000 0.069900 -0.182900  0.544000 0.736000 -0.392000
+1.000000 0.050200 -0.141200  0.512000 0.792000 -0.320000
+0.978000 0.050200 -0.182900  0.512000 0.768000 -0.376000
+1.000000 0.035800 -0.182900  0.504000 0.768000 -0.376000
+0.950000 0.050200 -0.224500  0.472000 0.712000 -0.504000
+1.000000 0.004200 -0.243900  0.464000 0.680000 -0.552000
+0.950000 0.037500 -0.243900  0.432000 0.688000 -0.576000
+1.000000 0.000000 -0.249700  0.512000 0.464000 -0.720000
+0.950000 0.000000 -0.291100  0.424000 0.536000 -0.720000
+1.000000 -0.050200 -0.288900  0.520000 0.432000 -0.728000
+0.950000 -0.016600 -0.304800  0.448000 0.520000 -0.720000
+0.981700 -0.050200 -0.304800  0.528000 0.432000 -0.720000
+0.950000 -0.050200 -0.338500  0.440000 0.400000 -0.800000
+1.000000 -0.073100 -0.304800  0.536000 0.424000 -0.720000
+0.950000 -0.100400 -0.351000  0.336000 0.064000 -0.936000
+1.000000 -0.100400 -0.325200  0.488000 0.344000 -0.792000
+0.950000 -0.150600 -0.345500  -0.032000 0.064000 -0.992000
+1.000000 -0.150600 -0.335800  0.136000 0.136000 -0.976000
+0.950000 -0.200800 -0.357000  -0.272000 -0.104000 -0.952000
+1.000000 -0.200800 -0.338800  0.136000 -0.384000 -0.904000
+0.950000 -0.251000 -0.328200  -0.712000 -0.568000 -0.392000
+1.000000 -0.251000 -0.355700  -0.816000 -0.248000 -0.504000
+1.000000 -0.251000 -0.355700  -0.816000 -0.248000 -0.504000
+1.000000 -0.012000 0.182900  0.384000 -0.248000 0.880000
+1.000000 -0.012000 0.182900  0.384000 -0.248000 0.880000
+1.000000 -0.050200 0.168100  0.416000 -0.344000 0.832000
+0.975800 -0.050200 0.182900  0.464000 -0.232000 0.848000
+1.000000 -0.100400 0.134700  0.432000 -0.528000 0.720000
+0.959000 -0.100400 0.182900  0.616000 -0.584000 0.520000
+0.959000 -0.100400 0.182900  0.616000 -0.584000 0.520000
+-0.900000 0.200800 0.074800  0.296000 0.712000 0.624000
+-0.900000 0.200800 0.074800  0.296000 0.712000 0.624000
+-0.900000 0.210300 0.060900  0.312000 0.744000 0.576000
+-0.879600 0.200800 0.060900  0.352000 0.712000 0.600000
+-0.900000 0.240500 0.000000  0.368000 0.840000 0.376000
+-0.850000 0.200800 0.035600  0.384000 0.744000 0.536000
+-0.850000 0.219100 0.000000  0.368000 0.824000 0.424000
+-0.811000 0.200800 0.000000  0.408000 0.816000 0.392000
+-0.811000 0.200800 0.000000  0.408000 0.816000 0.392000
+-0.900000 -0.127600 0.121900  -0.608000 -0.704000 0.344000
+-0.900000 -0.127600 0.121900  -0.608000 -0.704000 0.344000
+-0.900000 -0.149700 0.060900  -0.696000 -0.664000 0.232000
+-0.878400 -0.150600 0.121900  -0.736000 -0.560000 0.368000
+-0.899200 -0.150600 0.060900  -0.816000 -0.504000 0.256000
+-0.851500 -0.200800 0.121900  -0.832000 -0.360000 0.408000
+-0.869300 -0.200800 0.060900  -0.824000 -0.496000 0.248000
+-0.899200 -0.150600 0.060900  -0.816000 -0.504000 0.256000
+-0.882700 -0.200800 0.000000  -0.840000 -0.496000 0.192000
+-0.900000 -0.150600 0.057700  -0.744000 -0.616000 0.232000
+-0.900000 -0.169600 0.000000  -0.800000 -0.552000 0.224000
+-0.882700 -0.200800 0.000000  -0.840000 -0.496000 0.192000
+-0.900000 -0.192500 -0.060900  -0.856000 -0.488000 0.144000
+-0.895700 -0.200800 -0.060900  -0.864000 -0.480000 0.136000
+-0.900000 -0.200800 -0.096200  -0.752000 -0.632000 0.128000
+-0.860100 -0.251000 -0.060900  -0.808000 -0.568000 0.112000
+-0.900000 -0.204500 -0.121900  -0.688000 -0.712000 0.104000
+-0.866600 -0.251000 -0.121900  -0.808000 -0.576000 0.072000
+-0.900000 -0.206900 -0.182900  -0.648000 -0.752000 0.056000
+-0.864200 -0.251000 -0.182900  -0.800000 -0.592000 0.000000
+-0.900000 -0.212400 -0.243900  -0.672000 -0.712000 0.176000
+-0.869200 -0.251000 -0.243900  -0.768000 -0.600000 0.200000
+-0.900000 -0.236500 -0.304800  -0.680000 -0.456000 -0.560000
+-0.891700 -0.251000 -0.304800  -0.808000 -0.512000 -0.264000
+-0.891700 -0.251000 -0.304800  -0.808000 -0.512000 -0.264000
+-0.850000 0.184100 0.060900  0.376000 0.632000 0.664000
+-0.850000 0.184100 0.060900  0.376000 0.632000 0.664000
+-0.850000 0.150600 0.098600  0.360000 0.600000 0.704000
+-0.800000 0.153700 0.060900  0.432000 0.632000 0.632000
+-0.800000 0.150600 0.064100  0.424000 0.560000 0.704000
+-0.796300 0.150600 0.060900  0.512000 0.584000 0.616000
+-0.800000 0.153700 0.060900  0.432000 0.632000 0.632000
+-0.750000 0.150600 0.014500  0.472000 0.624000 0.608000
+-0.800000 0.195100 0.000000  0.456000 0.768000 0.432000
+-0.750000 0.162200 0.000000  0.464000 0.672000 0.560000
+-0.750000 0.150600 0.014500  0.472000 0.624000 0.608000
+-0.734000 0.150600 0.000000  0.496000 0.640000 0.576000
+-0.750000 0.162200 0.000000  0.464000 0.672000 0.560000
+-0.700000 0.150600 -0.043600  0.552000 0.712000 0.424000
+-0.750000 0.191300 -0.060900  0.496000 0.856000 0.072000
+-0.700000 0.159000 -0.060900  0.600000 0.776000 0.184000
+-0.750000 0.174400 -0.121900  0.448000 0.824000 -0.336000
+-0.700000 0.150600 -0.089800  0.592000 0.744000 -0.280000
+-0.715000 0.150600 -0.121900  0.512000 0.744000 -0.408000
+-0.700000 0.140000 -0.121900  0.536000 0.728000 -0.408000
+-0.750000 0.150600 -0.159200  0.432000 0.664000 -0.600000
+-0.700000 0.100400 -0.182100  0.536000 0.592000 -0.592000
+-0.750000 0.132600 -0.182900  0.408000 0.656000 -0.624000
+-0.700900 0.100400 -0.182900  0.440000 0.608000 -0.648000
+-0.750000 0.100400 -0.222000  0.432000 0.576000 -0.680000
+-0.700000 0.099700 -0.182900  0.504000 0.560000 -0.640000
+-0.750000 0.077000 -0.243900  0.368000 0.552000 -0.744000
+-0.700000 0.050200 -0.235800  0.504000 0.432000 -0.744000
+-0.711800 0.050200 -0.243900  0.416000 0.432000 -0.792000
+-0.700000 0.037400 -0.243900  0.440000 0.392000 -0.800000
+-0.750000 0.050200 -0.267100  0.368000 0.432000 -0.816000
+-0.700000 0.000000 -0.262900  0.392000 0.288000 -0.864000
+-0.750000 0.000000 -0.285200  0.328000 0.160000 -0.920000
+-0.750000 0.000000 -0.285200  0.328000 0.160000 -0.920000
+-0.750000 0.012900 0.121900  0.496000 0.384000 0.768000
+-0.750000 0.012900 0.121900  0.496000 0.384000 0.768000
+-0.781300 0.050200 0.121900  0.536000 0.400000 0.736000
+-0.750000 0.050200 0.097600  0.464000 0.408000 0.776000
+-0.750000 0.050200 0.097600  0.464000 0.408000 0.776000
+-0.800000 -0.280700 0.121900  -0.736000 -0.528000 0.408000
+-0.800000 -0.280700 0.121900  -0.736000 -0.528000 0.408000
+-0.783300 -0.301200 0.121900  -0.688000 -0.568000 0.440000
+-0.800000 -0.301200 0.085900  -0.768000 -0.544000 0.304000
+-0.800000 -0.301200 0.085900  -0.768000 -0.544000 0.304000
+-0.750000 -0.342500 0.121900  -0.536000 -0.592000 0.592000
+-0.750000 -0.342500 0.121900  -0.536000 -0.592000 0.592000
+-0.739400 -0.351500 0.121900  -0.528000 -0.576000 0.616000
+-0.750000 -0.351500 0.110100  -0.600000 -0.584000 0.536000
+-0.750000 -0.351500 0.110100  -0.600000 -0.584000 0.536000
+-0.701000 -0.451900 0.060900  -0.792000 -0.480000 0.344000
+-0.701000 -0.451900 0.060900  -0.792000 -0.480000 0.344000
+-0.700000 -0.451900 0.063700  -0.672000 -0.600000 0.424000
+-0.700000 -0.453200 0.060900  -0.560000 -0.720000 0.392000
+-0.700000 -0.453200 0.060900  -0.560000 -0.720000 0.392000
+-0.650000 -0.141800 0.121900  0.432000 0.328000 0.832000
+-0.650000 -0.141800 0.121900  0.432000 0.328000 0.832000
+-0.677900 -0.100400 0.121900  0.528000 0.328000 0.776000
+-0.650000 -0.100400 0.096100  0.592000 0.288000 0.744000
+-0.650000 -0.100400 0.096100  0.592000 0.288000 0.744000
+-0.600000 -0.122400 0.060900  0.616000 0.400000 0.664000
+-0.600000 -0.122400 0.060900  0.616000 0.400000 0.664000
+-0.575700 -0.150600 0.060900  0.384000 0.664000 0.632000
+-0.600000 -0.150600 0.080700  0.576000 0.424000 0.688000
+-0.600000 -0.150600 0.080700  0.576000 0.424000 0.688000
+-0.559300 -0.200800 0.121900  0.160000 0.720000 0.672000
+-0.559300 -0.200800 0.121900  0.160000 0.720000 0.672000
+-0.550000 -0.200800 0.118700  0.032000 0.784000 0.608000
+-0.550000 -0.202900 0.121900  0.032000 0.728000 0.680000
+-0.536800 -0.200800 0.121900  -0.104000 0.736000 0.664000
+-0.536800 -0.200800 0.121900  -0.104000 0.736000 0.664000
+-0.550000 -0.494000 0.121900  0.024000 -0.832000 0.536000
+-0.550000 -0.494000 0.121900  0.024000 -0.832000 0.536000
+-0.550000 -0.502100 0.104800  0.104000 -0.840000 0.520000
+-0.500000 -0.486900 0.121900  0.296000 -0.800000 0.504000
+-0.500000 -0.502100 0.088800  0.616000 -0.688000 0.376000
+-0.450000 -0.453600 0.121900  0.584000 -0.744000 0.288000
+-0.489100 -0.502100 0.060900  0.704000 -0.616000 0.328000
+-0.450000 -0.471900 0.060900  0.592000 -0.752000 0.272000
+-0.450000 -0.471900 0.060900  0.592000 -0.752000 0.272000
+-0.550000 -0.502100 0.104800  0.104000 -0.840000 0.520000
+-0.550000 -0.502100 0.104800  0.104000 -0.840000 0.520000
+-0.550000 -0.532000 0.060900  0.080000 -0.776000 0.624000
+-0.500000 -0.502100 0.088800  0.616000 -0.688000 0.376000
+-0.500000 -0.517700 0.060900  0.632000 -0.632000 0.440000
+-0.489100 -0.502100 0.060900  0.704000 -0.616000 0.328000
+-0.489100 -0.502100 0.060900  0.704000 -0.616000 0.328000
+-0.405500 -0.100400 0.060900  -0.712000 0.456000 0.520000
+-0.405500 -0.100400 0.060900  -0.712000 0.456000 0.520000
+-0.400000 -0.090100 0.060900  -0.696000 0.400000 0.584000
+-0.400000 -0.100400 0.069600  -0.688000 0.456000 0.552000
+-0.367400 -0.050200 0.060900  -0.696000 0.408000 0.584000
+-0.351400 -0.100400 0.121900  -0.608000 0.368000 0.696000
+-0.350000 -0.050200 0.083200  -0.416000 0.344000 0.832000
+-0.350000 -0.097900 0.121900  -0.560000 0.424000 0.704000
+-0.300000 -0.050200 0.104800  -0.312000 0.512000 0.792000
+-0.300000 -0.066800 0.121900  -0.280000 0.584000 0.752000
+-0.255700 -0.050200 0.121900  -0.192000 0.512000 0.832000
+-0.255700 -0.050200 0.121900  -0.192000 0.512000 0.832000
+-0.350000 -0.001900 0.060900  -0.656000 0.280000 0.688000
+-0.350000 -0.001900 0.060900  -0.656000 0.280000 0.688000
+-0.350000 -0.050200 0.083200  -0.416000 0.344000 0.832000
+-0.367400 -0.050200 0.060900  -0.696000 0.408000 0.584000
+-0.367400 -0.050200 0.060900  -0.696000 0.408000 0.584000
+-0.351400 -0.100400 0.121900  -0.608000 0.368000 0.696000
+-0.351400 -0.100400 0.121900  -0.608000 0.368000 0.696000
+-0.400000 -0.140400 0.121900  -0.448000 0.624000 0.632000
+-0.400000 -0.100400 0.069600  -0.688000 0.456000 0.552000
+-0.400000 -0.100400 0.069600  -0.688000 0.456000 0.552000
+-0.400000 -0.401700 0.111300  0.640000 -0.680000 0.336000
+-0.400000 -0.401700 0.111300  0.640000 -0.680000 0.336000
+-0.400000 -0.423000 0.060900  0.616000 -0.696000 0.360000
+-0.350000 -0.401700 0.073400  0.632000 -0.688000 0.344000
+-0.350000 -0.406300 0.060900  0.592000 -0.728000 0.320000
+-0.344500 -0.401700 0.060900  0.632000 -0.688000 0.328000
+-0.344500 -0.401700 0.060900  0.632000 -0.688000 0.328000
+-0.348200 0.000000 0.060900  -0.376000 0.448000 0.800000
+-0.348200 0.000000 0.060900  -0.376000 0.448000 0.800000
+-0.300000 0.027200 0.060900  -0.160000 0.552000 0.808000
+-0.300000 0.000000 0.088800  -0.240000 0.432000 0.864000
+-0.250000 0.033500 0.060900  0.056000 0.528000 0.840000
+-0.250000 0.000000 0.079500  -0.144000 0.552000 0.816000
+-0.200000 0.020500 0.060900  0.664000 0.440000 0.600000
+-0.200000 0.000000 0.081400  0.696000 0.336000 0.624000
+-0.190300 0.000000 0.060900  0.816000 0.200000 0.536000
+-0.200000 -0.050200 0.072600  0.688000 0.360000 0.624000
+-0.193200 -0.050200 0.060900  0.808000 0.008000 0.584000
+-0.200000 -0.100400 0.076800  0.784000 -0.136000 0.600000
+-0.190200 -0.100400 0.060900  0.752000 -0.248000 0.600000
+-0.200000 -0.121800 0.060900  0.728000 -0.328000 0.592000
+-0.200000 -0.121800 0.060900  0.728000 -0.328000 0.592000
+-0.250000 0.000000 0.079500  -0.144000 0.552000 0.816000
+-0.250000 0.000000 0.079500  -0.144000 0.552000 0.816000
+-0.200000 0.000000 0.081400  0.696000 0.336000 0.624000
+-0.250000 -0.048000 0.121900  0.272000 0.640000 0.704000
+-0.200000 -0.050200 0.072600  0.688000 0.360000 0.624000
+-0.247100 -0.050200 0.121900  0.488000 0.512000 0.696000
+-0.200000 -0.100400 0.076800  0.784000 -0.136000 0.600000
+-0.230200 -0.100400 0.121900  0.776000 -0.176000 0.600000
+-0.230200 -0.100400 0.121900  0.776000 -0.176000 0.600000
+0.550000 0.351500 0.078000  -0.616000 0.672000 0.392000
+0.550000 0.351500 0.078000  -0.616000 0.672000 0.392000
+0.540600 0.351500 0.060900  -0.584000 0.632000 0.496000
+0.550000 0.359900 0.060900  -0.592000 0.640000 0.480000
+0.500000 0.351500 0.029100  -0.680000 0.048000 0.728000
+0.550000 0.388900 0.000000  -0.392000 0.856000 0.320000
+0.500000 0.369100 0.000000  -0.184000 0.800000 0.552000
+0.500000 0.351500 0.029100  -0.680000 0.048000 0.728000
+0.458200 0.351500 0.000000  -0.280000 0.520000 0.800000
+0.458200 0.351500 0.000000  -0.280000 0.520000 0.800000
+0.550000 0.246100 0.121900  -0.904000 -0.224000 0.352000
+0.550000 0.246100 0.121900  -0.904000 -0.224000 0.352000
+0.550000 0.200800 0.086900  -0.880000 -0.256000 0.392000
+0.548800 0.251000 0.121900  -0.912000 -0.176000 0.360000
+0.538800 0.200800 0.060900  -0.824000 -0.216000 0.520000
+0.533200 0.251000 0.060900  -0.856000 0.032000 0.512000
+0.500000 0.200800 0.008600  -0.576000 -0.176000 0.792000
+0.500800 0.251000 0.000000  -0.792000 -0.016000 0.608000
+0.500000 0.245700 0.000000  -0.568000 0.120000 0.808000
+0.500000 0.251000 -0.000900  -0.496000 0.112000 0.856000
+0.488800 0.200800 0.000000  -0.512000 0.024000 0.856000
+0.450000 0.251000 -0.039600  -0.400000 -0.080000 0.904000
+0.450000 0.200800 -0.035500  -0.536000 -0.264000 0.792000
+0.400000 0.251000 -0.058700  -0.328000 -0.176000 0.920000
+0.416500 0.200800 -0.060900  -0.560000 -0.352000 0.744000
+0.400000 0.242400 -0.060900  -0.352000 -0.192000 0.904000
+0.400000 0.200800 -0.077800  -0.600000 -0.432000 0.664000
+0.395100 0.251000 -0.060900  -0.344000 -0.184000 0.912000
+0.366500 0.200800 -0.121900  -0.760000 -0.624000 0.168000
+0.350000 0.251000 -0.088400  -0.448000 -0.320000 0.824000
+0.350000 0.218900 -0.121900  -0.504000 -0.816000 0.264000
+0.300000 0.251000 -0.114600  -0.168000 -0.536000 0.824000
+0.300000 0.236900 -0.121900  -0.304000 -0.688000 0.640000
+0.271900 0.251000 -0.121900  -0.240000 -0.760000 0.592000
+0.300000 0.251000 -0.156100  -0.368000 -0.808000 -0.448000
+0.300000 0.236900 -0.121900  -0.304000 -0.688000 0.640000
+0.321900 0.251000 -0.182900  -0.240000 -0.296000 -0.920000
+0.350000 0.218900 -0.121900  -0.504000 -0.816000 0.264000
+0.350000 0.236900 -0.182900  -0.272000 -0.424000 -0.856000
+0.366500 0.200800 -0.121900  -0.760000 -0.624000 0.168000
+0.380800 0.200800 -0.182900  -0.440000 -0.264000 -0.856000
+0.400000 0.152400 -0.121900  -0.688000 -0.712000 -0.048000
+0.400000 0.155900 -0.182900  -0.216000 -0.144000 -0.960000
+0.380800 0.200800 -0.182900  -0.440000 -0.264000 -0.856000
+0.400000 0.200800 -0.189400  -0.152000 -0.072000 -0.984000
+0.350000 0.236900 -0.182900  -0.272000 -0.424000 -0.856000
+0.400000 0.251000 -0.186400  -0.152000 0.040000 -0.984000
+0.350000 0.251000 -0.187300  -0.168000 -0.184000 -0.960000
+0.400000 0.301200 -0.184200  -0.016000 -0.016000 -0.992000
+0.350000 0.301200 -0.184400  -0.056000 0.000000 -0.992000
+0.400000 0.351500 -0.194500  0.000000 0.072000 -0.992000
+0.350000 0.351500 -0.192800  0.000000 0.056000 -0.992000
+0.400000 0.377300 -0.182900  0.016000 0.320000 -0.944000
+0.350000 0.377400 -0.182900  0.000000 0.280000 -0.952000
+0.400000 0.401700 -0.171200  0.088000 0.472000 -0.872000
+0.350000 0.401700 -0.174600  0.056000 0.440000 -0.888000
+0.400000 0.432800 -0.121900  0.160000 0.904000 -0.384000
+0.350000 0.445000 -0.121900  0.208000 0.960000 -0.152000
+0.400000 0.419800 -0.060900  0.080000 0.848000 0.520000
+0.350000 0.424300 -0.060900  0.120000 0.824000 0.544000
+0.400000 0.401700 -0.034800  -0.040000 0.584000 0.808000
+0.350000 0.401700 -0.031000  0.032000 0.488000 0.864000
+0.400000 0.351500 -0.018700  -0.136000 -0.208000 0.960000
+0.350000 0.351500 -0.021800  0.032000 -0.048000 0.992000
+0.350000 0.401700 -0.031000  0.032000 0.488000 0.864000
+0.300000 0.351500 -0.009100  -0.016000 -0.144000 0.984000
+0.300000 0.401700 -0.022200  0.096000 0.472000 0.864000
+0.350000 0.401700 -0.031000  0.032000 0.488000 0.864000
+0.300000 0.430700 -0.060900  0.128000 0.808000 0.568000
+0.350000 0.424300 -0.060900  0.120000 0.824000 0.544000
+0.300000 0.451900 -0.106900  0.184000 0.864000 0.456000
+0.350000 0.445000 -0.121900  0.208000 0.960000 -0.152000
+0.323400 0.451900 -0.121900  0.248000 0.944000 -0.200000
+0.350000 0.401700 -0.174600  0.056000 0.440000 -0.888000
+0.300000 0.451900 -0.131100  0.200000 0.712000 -0.664000
+0.300000 0.401700 -0.174800  0.040000 0.368000 -0.920000
+0.350000 0.401700 -0.174600  0.056000 0.440000 -0.888000
+0.300000 0.379400 -0.182900  -0.016000 0.272000 -0.960000
+0.350000 0.377400 -0.182900  0.000000 0.280000 -0.952000
+0.300000 0.351500 -0.193900  -0.008000 0.064000 -0.992000
+0.350000 0.351500 -0.192800  0.000000 0.056000 -0.992000
+0.300000 0.301200 -0.184400  -0.064000 -0.072000 -0.992000
+0.350000 0.301200 -0.184400  -0.056000 0.000000 -0.992000
+0.300000 0.284000 -0.182900  -0.168000 -0.184000 -0.960000
+0.350000 0.251000 -0.187300  -0.168000 -0.184000 -0.960000
+0.321900 0.251000 -0.182900  -0.240000 -0.296000 -0.920000
+0.350000 0.236900 -0.182900  -0.272000 -0.424000 -0.856000
+0.350000 0.236900 -0.182900  -0.272000 -0.424000 -0.856000
+0.550000 0.246100 0.121900  -0.904000 -0.224000 0.352000
+0.550000 0.246100 0.121900  -0.904000 -0.224000 0.352000
+0.567500 0.200800 0.121900  -0.784000 -0.344000 0.504000
+0.550000 0.200800 0.086900  -0.880000 -0.256000 0.392000
+0.550000 0.200800 0.086900  -0.880000 -0.256000 0.392000
+0.600000 0.100400 0.071800  -0.648000 -0.592000 0.472000
+0.600000 0.100400 0.071800  -0.648000 -0.592000 0.472000
+0.600000 0.093600 0.060900  -0.624000 -0.616000 0.464000
+0.593200 0.100400 0.060900  -0.640000 -0.584000 0.496000
+0.600000 0.053300 0.000000  -0.472000 -0.712000 0.512000
+0.553100 0.100400 0.000000  -0.664000 -0.576000 0.464000
+0.600000 0.050200 -0.005300  -0.440000 -0.752000 0.480000
+0.550000 0.100400 -0.005700  -0.672000 -0.576000 0.448000
+0.550000 0.050200 -0.037800  -0.320000 -0.688000 0.640000
+0.504600 0.100400 -0.060900  -0.704000 -0.248000 0.656000
+0.500000 0.050200 -0.057700  -0.560000 0.128000 0.816000
+0.500000 0.067400 -0.060900  -0.592000 0.120000 0.792000
+0.495100 0.050200 -0.060900  -0.456000 0.136000 0.872000
+0.500000 0.100400 -0.067100  -0.632000 -0.296000 0.704000
+0.450000 0.050200 -0.077000  -0.360000 0.120000 0.920000
+0.450000 0.100400 -0.090700  -0.384000 -0.320000 0.856000
+0.400000 0.050200 -0.114800  -0.552000 0.256000 0.784000
+0.415000 0.100400 -0.121900  -0.640000 0.192000 0.736000
+0.400000 0.072600 -0.121900  -0.632000 0.256000 0.720000
+0.400000 0.100400 -0.150800  -0.768000 0.376000 0.512000
+0.393200 0.050200 -0.121900  -0.648000 0.352000 0.664000
+0.381500 0.100400 -0.182900  -0.896000 0.440000 -0.008000
+0.357200 0.050200 -0.182900  -0.736000 0.640000 0.184000
+0.400000 0.100400 -0.207800  -0.424000 0.688000 -0.576000
+0.351400 0.050200 -0.243900  -0.480000 0.768000 -0.416000
+0.400000 0.083700 -0.243900  -0.328000 0.768000 -0.536000
+0.400000 0.050200 -0.294000  -0.352000 0.672000 -0.640000
+0.351400 0.050200 -0.243900  -0.480000 0.768000 -0.416000
+0.400000 0.041200 -0.304800  -0.352000 0.672000 -0.648000
+0.350000 0.049300 -0.243900  -0.512000 0.784000 -0.320000
+0.350000 0.024300 -0.304800  -0.456000 0.784000 -0.408000
+0.300000 0.032100 -0.243900  -0.576000 0.680000 -0.432000
+0.301400 0.000000 -0.304800  -0.584000 0.656000 -0.464000
+0.300000 0.000000 -0.302400  -0.544000 0.608000 -0.568000
+0.300000 -0.003100 -0.304800  -0.376000 0.424000 -0.816000
+0.301400 0.000000 -0.304800  -0.584000 0.656000 -0.464000
+0.300000 -0.050200 -0.319900  -0.536000 0.224000 -0.808000
+0.350000 0.000000 -0.339100  -0.264000 0.552000 -0.784000
+0.342100 -0.050200 -0.365800  -0.640000 -0.104000 -0.752000
+0.350000 -0.037900 -0.365800  -0.440000 0.432000 -0.776000
+0.350000 -0.050200 -0.374000  -0.496000 -0.096000 -0.856000
+0.383500 -0.050200 -0.365800  0.200000 -0.288000 -0.928000
+0.350000 -0.059800 -0.365800  -0.280000 -0.560000 -0.768000
+0.400000 -0.050200 -0.360800  0.184000 -0.432000 -0.872000
+0.350000 -0.100400 -0.331300  -0.432000 -0.520000 -0.728000
+0.400000 -0.100400 -0.340000  -0.040000 -0.360000 -0.928000
+0.350000 -0.127600 -0.304800  0.032000 -0.600000 -0.792000
+0.400000 -0.150600 -0.318400  -0.432000 -0.416000 -0.792000
+0.380400 -0.150600 -0.304800  -0.424000 -0.456000 -0.776000
+0.400000 -0.168700 -0.304800  -0.504000 -0.464000 -0.720000
+0.350000 -0.150600 -0.283600  -0.064000 -0.424000 -0.896000
+0.400000 -0.200800 -0.276700  0.448000 -0.472000 -0.752000
+0.350000 -0.200800 -0.271400  0.216000 0.224000 -0.944000
+0.400000 -0.249400 -0.243900  0.760000 -0.472000 -0.424000
+0.350000 -0.228300 -0.304800  0.616000 0.528000 -0.576000
+0.399000 -0.251000 -0.243900  0.912000 -0.008000 -0.392000
+0.366700 -0.251000 -0.304800  0.704000 0.488000 -0.496000
+0.350000 -0.228300 -0.304800  0.616000 0.528000 -0.576000
+0.350000 -0.251000 -0.329500  0.536000 0.472000 -0.688000
+0.320800 -0.200800 -0.304800  0.496000 0.328000 -0.800000
+0.300000 -0.251000 -0.347800  0.304000 0.384000 -0.864000
+0.300000 -0.200800 -0.324200  0.480000 0.248000 -0.832000
+0.320800 -0.200800 -0.304800  0.496000 0.328000 -0.800000
+0.300000 -0.150600 -0.312600  0.312000 -0.200000 -0.920000
+0.313400 -0.150600 -0.304800  0.400000 -0.360000 -0.840000
+0.300000 -0.100400 -0.310000  -0.248000 0.072000 -0.960000
+0.350000 -0.127600 -0.304800  0.032000 -0.600000 -0.792000
+0.350000 -0.100400 -0.331300  -0.432000 -0.520000 -0.728000
+0.300000 -0.100400 -0.310000  -0.248000 0.072000 -0.960000
+0.350000 -0.059800 -0.365800  -0.280000 -0.560000 -0.768000
+0.300000 -0.050200 -0.319900  -0.536000 0.224000 -0.808000
+0.342100 -0.050200 -0.365800  -0.640000 -0.104000 -0.752000
+0.350000 -0.059800 -0.365800  -0.280000 -0.560000 -0.768000
+0.350000 -0.050200 -0.374000  -0.496000 -0.096000 -0.856000
+0.350000 -0.050200 -0.374000  -0.496000 -0.096000 -0.856000
+0.650000 0.080100 0.121900  -0.576000 -0.640000 0.496000
+0.650000 0.080100 0.121900  -0.576000 -0.640000 0.496000
+0.692100 0.050200 0.121900  -0.432000 -0.784000 0.424000
+0.650000 0.050200 0.073400  -0.576000 -0.624000 0.512000
+0.700000 0.046100 0.121900  -0.152000 -0.904000 0.376000
+0.650000 0.041800 0.060900  -0.568000 -0.648000 0.504000
+0.700000 0.026800 0.060900  -0.288000 -0.896000 0.328000
+0.650000 0.013100 0.000000  -0.448000 -0.792000 0.392000
+0.700000 0.012000 0.000000  -0.032000 -0.960000 0.272000
+0.650000 0.000000 -0.040500  0.104000 -0.944000 0.296000
+0.700000 0.001400 -0.060900  0.088000 -0.968000 0.192000
+0.686800 0.000000 -0.060900  0.208000 -0.960000 0.144000
+0.700000 0.000400 -0.121900  0.224000 -0.968000 0.032000
+0.698200 0.000000 -0.121900  0.296000 -0.952000 0.032000
+0.700000 0.009000 -0.182900  0.456000 -0.744000 -0.472000
+0.687300 0.000000 -0.182900  0.648000 -0.600000 -0.456000
+0.700000 0.050200 -0.225700  0.368000 -0.368000 -0.848000
+0.653800 0.000000 -0.243900  0.576000 -0.112000 -0.808000
+0.653800 0.050200 -0.243900  0.232000 0.032000 -0.968000
+0.653800 0.050200 -0.243900  0.232000 0.032000 -0.968000
+0.750000 0.233400 0.121900  0.720000 0.680000 -0.080000
+0.750000 0.233400 0.121900  0.720000 0.680000 -0.080000
+0.788900 0.200800 0.121900  0.632000 0.744000 0.184000
+0.750000 0.222200 0.060900  0.704000 0.696000 -0.080000
+0.772600 0.200800 0.060900  0.648000 0.736000 -0.136000
+0.750000 0.219200 0.000000  0.672000 0.728000 0.080000
+0.770200 0.200800 0.000000  0.616000 0.776000 0.056000
+0.750000 0.228900 -0.060900  0.576000 0.696000 -0.416000
+0.787300 0.200800 -0.060900  0.520000 0.824000 -0.184000
+0.750000 0.200800 -0.104400  0.480000 0.680000 -0.544000
+0.800000 0.194300 -0.060900  0.416000 0.824000 -0.360000
+0.750000 0.186400 -0.121900  0.504000 0.648000 -0.560000
+0.800000 0.164900 -0.121900  0.312000 0.800000 -0.504000
+0.750000 0.157000 -0.182900  0.280000 0.720000 -0.624000
+0.800000 0.150600 -0.164100  0.256000 0.800000 -0.528000
+0.769100 0.150600 -0.182900  0.248000 0.704000 -0.648000
+0.800000 0.138600 -0.182900  0.232000 0.712000 -0.656000
+0.750000 0.150600 -0.191500  0.256000 0.656000 -0.704000
+0.800000 0.100400 -0.216300  0.104000 0.416000 -0.896000
+0.750000 0.100400 -0.218500  0.200000 0.232000 -0.944000
+0.800000 0.050200 -0.233400  -0.176000 0.416000 -0.880000
+0.750000 0.050200 -0.223600  -0.168000 -0.552000 -0.808000
+0.800000 0.000000 -0.217200  -0.656000 -0.464000 -0.584000
+0.750000 0.019900 -0.182900  -0.176000 -0.792000 -0.576000
+0.776700 0.000000 -0.182900  -0.576000 -0.728000 -0.360000
+0.750000 0.004300 -0.121900  -0.408000 -0.880000 -0.216000
+0.756600 0.000000 -0.121900  -0.496000 -0.856000 -0.080000
+0.750000 0.001600 -0.060900  -0.416000 -0.904000 -0.016000
+0.753100 0.000000 -0.060900  -0.472000 -0.872000 0.000000
+0.750000 0.013300 0.000000  -0.240000 -0.936000 0.240000
+0.772100 0.000000 0.000000  -0.504000 -0.832000 0.224000
+0.750000 0.031700 0.060900  -0.136000 -0.928000 0.336000
+0.798100 0.000000 0.060900  -0.504000 -0.792000 0.312000
+0.772100 0.000000 0.000000  -0.504000 -0.832000 0.224000
+0.800000 -0.001000 0.060900  -0.584000 -0.776000 0.216000
+0.800000 -0.015400 0.000000  -0.560000 -0.800000 0.184000
+0.843600 -0.050200 0.060900  -0.704000 -0.672000 0.184000
+0.832800 -0.050200 0.000000  -0.728000 -0.656000 0.144000
+0.800000 -0.015400 0.000000  -0.560000 -0.800000 0.184000
+0.823600 -0.050200 -0.060900  -0.736000 -0.664000 0.112000
+0.800000 -0.024700 -0.060900  -0.616000 -0.776000 0.088000
+0.818400 -0.050200 -0.121900  -0.760000 -0.640000 0.016000
+0.800000 -0.027900 -0.121900  -0.664000 -0.736000 -0.072000
+0.822900 -0.050200 -0.182900  -0.792000 -0.592000 -0.088000
+0.800000 -0.017800 -0.182900  -0.616000 -0.680000 -0.376000
+0.835300 -0.050200 -0.243900  -0.840000 -0.416000 -0.336000
+0.800000 0.000000 -0.217200  -0.656000 -0.464000 -0.584000
+0.819700 0.000000 -0.243900  -0.752000 -0.192000 -0.616000
+0.819700 0.000000 -0.243900  -0.752000 -0.192000 -0.616000
+0.788900 0.200800 0.121900  0.632000 0.744000 0.184000
+0.788900 0.200800 0.121900  0.632000 0.744000 0.184000
+0.800000 0.190400 0.121900  0.624000 0.752000 0.168000
+0.772600 0.200800 0.060900  0.648000 0.736000 -0.136000
+0.800000 0.182100 0.060900  0.560000 0.824000 -0.024000
+0.770200 0.200800 0.000000  0.616000 0.776000 0.056000
+0.800000 0.184600 0.000000  0.464000 0.872000 0.120000
+0.787300 0.200800 -0.060900  0.520000 0.824000 -0.184000
+0.800000 0.194300 -0.060900  0.416000 0.824000 -0.360000
+0.800000 0.194300 -0.060900  0.416000 0.824000 -0.360000
+0.800000 0.028400 0.121900  -0.376000 -0.808000 0.432000
+0.800000 0.028400 0.121900  -0.376000 -0.808000 0.432000
+0.829700 0.000000 0.121900  -0.704000 -0.616000 0.344000
+0.800000 0.000000 0.064400  -0.576000 -0.736000 0.344000
+0.800000 0.000000 0.064400  -0.576000 -0.736000 0.344000
+0.911800 0.100400 0.121900  0.528000 0.800000 0.264000
+0.911800 0.100400 0.121900  0.528000 0.800000 0.264000
+0.950000 0.069700 0.121900  0.360000 0.840000 0.384000
+0.936800 0.100400 0.060900  0.456000 0.872000 0.168000
+0.950000 0.091300 0.060900  0.600000 0.776000 0.176000
+0.950000 0.100400 0.012800  0.496000 0.848000 0.136000
+1.000000 0.068400 0.060900  0.464000 0.872000 0.104000
+0.952900 0.100400 0.000000  0.504000 0.848000 0.120000
+1.000000 0.075000 0.000000  0.472000 0.872000 0.072000
+0.957800 0.100400 -0.060900  0.544000 0.824000 -0.120000
+1.000000 0.074600 -0.060900  0.496000 0.816000 -0.280000
+1.000000 0.074600 -0.060900  0.496000 0.816000 -0.280000
+0.950000 -0.142500 0.121900  -0.608000 -0.672000 0.392000
+0.950000 -0.142500 0.121900  -0.608000 -0.672000 0.392000
+0.950000 -0.150600 0.094900  -0.648000 -0.696000 0.272000
+0.900000 -0.107100 0.121900  -0.584000 -0.768000 0.240000
+0.942000 -0.150600 0.060900  -0.704000 -0.672000 0.200000
+0.900000 -0.117100 0.060900  -0.656000 -0.736000 0.136000
+0.931300 -0.150600 0.000000  -0.640000 -0.744000 0.144000
+0.900000 -0.125700 0.000000  -0.664000 -0.728000 0.136000
+0.917800 -0.150600 -0.060900  -0.640000 -0.736000 0.184000
+0.900000 -0.135500 -0.060900  -0.672000 -0.712000 0.168000
+0.902600 -0.150600 -0.121900  -0.664000 -0.736000 0.096000
+0.900000 -0.148200 -0.121900  -0.664000 -0.728000 0.088000
+0.900000 -0.150600 -0.145400  -0.696000 -0.704000 0.104000
+0.902600 -0.150600 -0.121900  -0.664000 -0.736000 0.096000
+0.900000 -0.155900 -0.182900  -0.744000 -0.648000 0.112000
+0.950000 -0.200400 -0.121900  -0.720000 -0.672000 0.136000
+0.939100 -0.200800 -0.182900  -0.712000 -0.672000 0.160000
+0.950000 -0.200800 -0.124000  -0.680000 -0.712000 0.160000
+0.950000 -0.211700 -0.182900  -0.704000 -0.680000 0.176000
+0.939100 -0.200800 -0.182900  -0.712000 -0.672000 0.160000
+0.950000 -0.224400 -0.243900  -0.688000 -0.640000 0.328000
+0.928800 -0.200800 -0.243900  -0.736000 -0.616000 0.240000
+0.939100 -0.200800 -0.182900  -0.712000 -0.672000 0.160000
+0.900000 -0.163000 -0.243900  -0.816000 -0.552000 0.128000
+0.900000 -0.155900 -0.182900  -0.744000 -0.648000 0.112000
+0.890800 -0.150600 -0.243900  -0.848000 -0.512000 0.064000
+0.895100 -0.150600 -0.182900  -0.744000 -0.648000 0.104000
+0.900000 -0.155900 -0.182900  -0.744000 -0.648000 0.112000
+0.900000 -0.150600 -0.145400  -0.696000 -0.704000 0.104000
+0.900000 -0.150600 -0.145400  -0.696000 -0.704000 0.104000
+0.950000 -0.150600 0.094900  -0.648000 -0.696000 0.272000
+0.950000 -0.150600 0.094900  -0.648000 -0.696000 0.272000
+0.950000 -0.158100 0.060900  -0.608000 -0.760000 0.200000
+0.942000 -0.150600 0.060900  -0.704000 -0.672000 0.200000
+0.950000 -0.168100 0.000000  -0.640000 -0.744000 0.184000
+0.931300 -0.150600 0.000000  -0.640000 -0.744000 0.144000
+0.950000 -0.183700 -0.060900  -0.632000 -0.728000 0.232000
+0.917800 -0.150600 -0.060900  -0.640000 -0.736000 0.184000
+0.950000 -0.200400 -0.121900  -0.720000 -0.672000 0.136000
+0.902600 -0.150600 -0.121900  -0.664000 -0.736000 0.096000
+0.902600 -0.150600 -0.121900  -0.664000 -0.736000 0.096000
+1.000000 0.053600 0.121900  0.280000 0.872000 0.392000
+1.000000 0.053600 0.121900  0.280000 0.872000 0.392000
+0.950000 0.069700 0.121900  0.360000 0.840000 0.384000
+1.000000 0.068400 0.060900  0.464000 0.872000 0.104000
+0.950000 0.091300 0.060900  0.600000 0.776000 0.176000
+0.950000 0.091300 0.060900  0.600000 0.776000 0.176000
+-1.000000 -0.090800 0.060900  -0.320000 -0.912000 0.248000
+-1.000000 -0.090800 0.060900  -0.320000 -0.912000 0.248000
+-0.973400 -0.100400 0.060900  -0.344000 -0.904000 0.240000
+-1.000000 -0.100400 0.014600  -0.304000 -0.920000 0.208000
+-1.000000 -0.100400 0.014600  -0.304000 -0.920000 0.208000
+-0.950000 0.258900 0.000000  0.296000 0.848000 0.432000
+-0.950000 0.258900 0.000000  0.296000 0.848000 0.432000
+-0.928700 0.251000 0.000000  0.312000 0.848000 0.408000
+-0.950000 0.251000 0.016800  0.288000 0.808000 0.504000
+-0.950000 0.251000 0.016800  0.288000 0.808000 0.504000
+-0.900000 -0.149700 0.060900  -0.696000 -0.664000 0.232000
+-0.900000 -0.149700 0.060900  -0.696000 -0.664000 0.232000
+-0.899200 -0.150600 0.060900  -0.816000 -0.504000 0.256000
+-0.900000 -0.150600 0.057700  -0.744000 -0.616000 0.232000
+-0.900000 -0.150600 0.057700  -0.744000 -0.616000 0.232000
+-0.750000 0.106000 0.060900  0.496000 0.464000 0.728000
+-0.750000 0.106000 0.060900  0.496000 0.464000 0.728000
+-0.796300 0.150600 0.060900  0.512000 0.584000 0.616000
+-0.750000 0.150600 0.014500  0.472000 0.624000 0.608000
+-0.750000 0.150600 0.014500  0.472000 0.624000 0.608000
+-0.750800 -0.401700 0.000000  -0.816000 -0.520000 0.208000
+-0.750800 -0.401700 0.000000  -0.816000 -0.520000 0.208000
+-0.750000 -0.401700 0.004100  -0.816000 -0.520000 0.232000
+-0.750000 -0.403200 0.000000  -0.832000 -0.504000 0.216000
+-0.750000 -0.403200 0.000000  -0.832000 -0.504000 0.216000
+-0.700000 0.051600 0.060900  0.528000 0.416000 0.728000
+-0.700000 0.051600 0.060900  0.528000 0.416000 0.728000
+-0.744800 0.100400 0.060900  0.496000 0.456000 0.728000
+-0.700000 0.100400 0.019100  0.504000 0.504000 0.688000
+-0.700000 0.100400 0.019100  0.504000 0.504000 0.688000
+-0.700000 0.121800 0.000000  0.536000 0.544000 0.632000
+-0.700000 0.121800 0.000000  0.536000 0.544000 0.632000
+-0.680200 0.100400 0.000000  0.600000 0.440000 0.656000
+-0.700000 0.100400 0.019100  0.504000 0.504000 0.688000
+-0.700000 0.100400 0.019100  0.504000 0.504000 0.688000
+-0.650000 -0.023500 0.060900  0.576000 0.360000 0.720000
+-0.650000 -0.023500 0.060900  0.576000 0.360000 0.720000
+-0.666100 0.000000 0.060900  0.560000 0.376000 0.728000
+-0.650000 0.000000 0.045200  0.576000 0.400000 0.704000
+-0.650000 0.000000 0.045200  0.576000 0.400000 0.704000
+-0.650000 0.063100 0.000000  0.592000 0.392000 0.696000
+-0.650000 0.063100 0.000000  0.592000 0.392000 0.696000
+-0.641800 0.050200 0.000000  0.616000 0.400000 0.664000
+-0.650000 0.050200 0.008200  0.568000 0.384000 0.720000
+-0.650000 0.050200 0.008200  0.568000 0.384000 0.720000
+-0.650000 -0.495900 0.060900  -0.528000 -0.720000 0.432000
+-0.650000 -0.495900 0.060900  -0.528000 -0.720000 0.432000
+-0.640700 -0.502100 0.060900  -0.496000 -0.728000 0.456000
+-0.650000 -0.502100 0.048300  -0.536000 -0.712000 0.440000
+-0.650000 -0.502100 0.048300  -0.536000 -0.712000 0.440000
+-0.633400 -0.552300 0.000000  -0.384000 -0.672000 0.624000
+-0.633400 -0.552300 0.000000  -0.384000 -0.672000 0.624000
+-0.600000 -0.552300 0.023900  -0.224000 -0.776000 0.584000
+-0.600000 -0.566300 0.000000  -0.184000 -0.816000 0.544000
+-0.550000 -0.552300 0.031000  0.256000 -0.800000 0.528000
+-0.550000 -0.565800 0.000000  0.224000 -0.872000 0.424000
+-0.509600 -0.552300 0.000000  0.320000 -0.840000 0.424000
+-0.509600 -0.552300 0.000000  0.320000 -0.840000 0.424000
+-0.600000 -0.018300 0.000000  0.712000 0.368000 0.584000
+-0.600000 -0.018300 0.000000  0.712000 0.368000 0.584000
+-0.584800 -0.050200 0.000000  0.744000 0.336000 0.568000
+-0.600000 -0.050200 0.018400  0.648000 0.320000 0.688000
+-0.600000 -0.050200 0.018400  0.648000 0.320000 0.688000
+-0.472400 -0.150600 0.060900  -0.464000 0.768000 0.416000
+-0.472400 -0.150600 0.060900  -0.464000 0.768000 0.416000
+-0.500000 -0.166600 0.060900  -0.304000 0.832000 0.448000
+-0.500000 -0.150600 0.019400  -0.216000 0.856000 0.464000
+-0.500000 -0.150600 0.019400  -0.216000 0.856000 0.464000
+-0.434300 -0.100400 0.000000  -0.648000 0.720000 0.208000
+-0.434300 -0.100400 0.000000  -0.648000 0.720000 0.208000
+-0.405500 -0.100400 0.060900  -0.712000 0.456000 0.520000
+-0.400000 -0.050900 0.000000  -0.776000 0.576000 0.224000
+-0.400000 -0.090100 0.060900  -0.696000 0.400000 0.584000
+-0.399300 -0.050200 0.000000  -0.696000 0.680000 0.184000
+-0.367400 -0.050200 0.060900  -0.696000 0.408000 0.584000
+-0.367400 -0.050200 0.060900  -0.696000 0.408000 0.584000
+-0.355100 0.050200 0.000000  -0.872000 0.216000 0.416000
+-0.355100 0.050200 0.000000  -0.872000 0.216000 0.416000
+-0.350000 0.077100 0.000000  -0.776000 0.256000 0.568000
+-0.350000 0.050200 0.010900  -0.568000 0.448000 0.680000
+-0.321000 0.100400 0.000000  -0.264000 0.416000 0.864000
+-0.300000 0.050200 0.038600  -0.224000 0.544000 0.800000
+-0.300000 0.100400 0.006400  -0.200000 0.408000 0.880000
+-0.250000 0.050200 0.048300  0.000000 0.552000 0.832000
+-0.250000 0.100400 0.002600  0.144000 0.496000 0.848000
+-0.250000 0.100400 0.002600  0.144000 0.496000 0.848000
+-0.350000 0.000000 0.059800  -0.688000 0.400000 0.592000
+-0.350000 0.000000 0.059800  -0.688000 0.400000 0.592000
+-0.350000 0.050200 0.010900  -0.568000 0.448000 0.680000
+-0.373100 0.000000 0.000000  -0.880000 0.240000 0.392000
+-0.355100 0.050200 0.000000  -0.872000 0.216000 0.416000
+-0.377800 0.000000 -0.060900  -0.864000 0.424000 -0.248000
+-0.358600 0.050200 -0.060900  -0.920000 0.168000 -0.328000
+-0.372200 0.000000 -0.121900  -0.848000 0.480000 -0.200000
+-0.350000 0.050200 -0.078800  -0.832000 0.272000 -0.472000
+-0.350000 0.031200 -0.121900  -0.744000 0.552000 -0.352000
+-0.335400 0.050200 -0.121900  -0.752000 0.472000 -0.456000
+-0.350000 0.000000 -0.171400  -0.688000 0.416000 -0.584000
+-0.301000 0.050200 -0.182900  -0.704000 0.472000 -0.512000
+-0.340600 0.000000 -0.182900  -0.696000 0.480000 -0.520000
+-0.350000 0.000000 -0.171400  -0.688000 0.416000 -0.584000
+-0.350000 -0.016600 -0.182900  -0.688000 0.360000 -0.616000
+-0.372200 0.000000 -0.121900  -0.848000 0.480000 -0.200000
+-0.365500 -0.050200 -0.182900  -0.728000 0.384000 -0.560000
+-0.399400 -0.050200 -0.121900  -0.760000 0.504000 -0.392000
+-0.400000 -0.096400 -0.182900  -0.664000 0.552000 -0.496000
+-0.400000 -0.050900 -0.121900  -0.736000 0.536000 -0.408000
+-0.403600 -0.100400 -0.182900  -0.616000 0.592000 -0.512000
+-0.434900 -0.100400 -0.121900  -0.608000 0.744000 -0.256000
+-0.434900 -0.100400 -0.121900  -0.608000 0.744000 -0.256000
+-0.350000 0.000000 0.059800  -0.688000 0.400000 0.592000
+-0.350000 0.000000 0.059800  -0.688000 0.400000 0.592000
+-0.350000 0.050200 0.010900  -0.568000 0.448000 0.680000
+-0.348200 0.000000 0.060900  -0.376000 0.448000 0.800000
+-0.300000 0.050200 0.038600  -0.224000 0.544000 0.800000
+-0.300000 0.027200 0.060900  -0.160000 0.552000 0.808000
+-0.250000 0.050200 0.048300  0.000000 0.552000 0.832000
+-0.250000 0.033500 0.060900  0.056000 0.528000 0.840000
+-0.200000 0.050200 0.037800  0.512000 0.448000 0.720000
+-0.200000 0.020500 0.060900  0.664000 0.440000 0.600000
+-0.200000 0.020500 0.060900  0.664000 0.440000 0.600000
+-0.208400 0.401700 0.000000  -0.424000 0.248000 0.864000
+-0.208400 0.401700 0.000000  -0.424000 0.248000 0.864000
+-0.200000 0.408700 0.000000  -0.112000 0.496000 0.856000
+-0.200000 0.401700 0.005100  -0.168000 0.288000 0.936000
+-0.185900 0.401700 0.000000  0.264000 0.248000 0.928000
+-0.200000 0.384800 0.000000  -0.112000 -0.232000 0.960000
+-0.150000 0.401700 -0.011900  0.240000 0.256000 0.928000
+-0.200000 0.351500 -0.009600  0.208000 -0.208000 0.952000
+-0.150000 0.351500 -0.029900  0.096000 -0.168000 0.976000
+-0.200000 0.301200 -0.022600  0.056000 -0.176000 0.976000
+-0.150000 0.301200 -0.033800  0.040000 -0.024000 0.992000
+-0.200000 0.251000 -0.048300  -0.120000 -0.296000 0.944000
+-0.150000 0.251000 -0.027500  -0.136000 -0.104000 0.984000
+-0.200000 0.206100 -0.060900  -0.448000 -0.184000 0.872000
+-0.150000 0.200800 -0.027500  -0.320000 -0.168000 0.928000
+-0.198000 0.200800 -0.060900  -0.464000 0.288000 0.832000
+-0.150000 0.150600 -0.037800  0.256000 -0.016000 0.960000
+-0.200000 0.199100 -0.060900  -0.320000 0.504000 0.792000
+-0.200000 0.150600 -0.023100  -0.360000 0.472000 0.792000
+-0.250000 0.177000 -0.060900  -0.096000 0.568000 0.808000
+-0.250000 0.150600 -0.042200  0.008000 0.568000 0.816000
+-0.277600 0.200800 -0.060900  0.584000 -0.072000 0.800000
+-0.300000 0.150600 -0.036000  -0.360000 0.064000 0.920000
+-0.300000 0.200800 -0.040500  0.440000 0.208000 0.864000
+-0.346000 0.150600 -0.060900  -0.768000 -0.144000 0.616000
+-0.350000 0.200800 -0.003200  -0.528000 -0.104000 0.832000
+-0.350000 0.153200 -0.060900  -0.608000 -0.784000 0.016000
+-0.368900 0.200800 -0.060900  -0.952000 0.040000 -0.280000
+-0.350000 0.200800 -0.076700  -0.368000 -0.104000 -0.920000
+-0.356100 0.251000 -0.060900  -0.936000 0.104000 -0.312000
+-0.350000 0.251000 -0.067500  -0.624000 0.048000 -0.768000
+-0.353500 0.301200 -0.060900  -0.872000 0.080000 -0.464000
+-0.350000 0.301200 -0.064600  -0.624000 0.064000 -0.768000
+-0.350000 0.329400 -0.060900  -0.960000 0.152000 -0.224000
+-0.300000 0.301200 -0.089300  -0.344000 0.056000 -0.936000
+-0.344500 0.351500 -0.060900  -0.776000 0.288000 0.552000
+-0.300000 0.351500 -0.083400  -0.432000 0.176000 -0.880000
+-0.307400 0.401700 -0.060900  -0.696000 0.688000 -0.152000
+-0.300000 0.401700 -0.066400  -0.448000 0.440000 -0.768000
+-0.300000 0.408800 -0.060900  -0.664000 0.712000 -0.184000
+-0.250000 0.401700 -0.091800  -0.416000 0.456000 -0.776000
+-0.250000 0.447500 -0.060900  -0.512000 0.744000 0.408000
+-0.208300 0.401700 -0.121900  -0.432000 0.432000 -0.784000
+-0.242600 0.451900 -0.060900  -0.440000 0.728000 0.512000
+-0.200000 0.409200 -0.121900  -0.400000 0.464000 -0.776000
+-0.200000 0.451900 -0.081300  -0.400000 0.504000 -0.752000
+-0.152100 0.451900 -0.121900  -0.424000 0.536000 -0.720000
+-0.200000 0.477600 -0.060900  -0.544000 0.808000 -0.208000
+-0.150000 0.453400 -0.121900  -0.320000 0.624000 -0.704000
+-0.150000 0.501300 -0.060900  -0.376000 0.880000 -0.280000
+-0.100000 0.479800 -0.121900  -0.288000 0.584000 -0.752000
+-0.146800 0.502100 -0.060900  -0.272000 0.960000 0.016000
+-0.100000 0.502100 -0.081300  -0.184000 0.840000 -0.488000
+-0.100000 0.517800 -0.060900  -0.120000 0.976000 0.136000
+-0.050000 0.502100 -0.117100  -0.040000 0.912000 -0.392000
+-0.050000 0.515300 -0.060900  0.432000 0.792000 0.408000
+-0.033200 0.502100 -0.060900  0.616000 0.496000 0.600000
+-0.050000 0.502100 -0.046900  0.400000 0.496000 0.760000
+-0.023600 0.451900 -0.060900  0.376000 0.152000 0.904000
+-0.050000 0.451900 -0.049700  0.432000 0.024000 0.896000
+-0.005200 0.401700 -0.060900  0.264000 0.168000 0.944000
+-0.050000 0.401700 -0.052300  0.176000 0.040000 0.976000
+0.000000 0.393800 -0.060900  0.224000 0.176000 0.952000
+-0.050000 0.351500 -0.043600  0.248000 0.032000 0.960000
+0.000000 0.351500 -0.051600  0.280000 -0.248000 0.920000
+-0.050000 0.301200 -0.044600  0.440000 -0.008000 0.896000
+0.000000 0.334500 -0.060900  0.312000 -0.368000 0.864000
+-0.027600 0.301200 -0.060900  0.456000 -0.208000 0.856000
+0.000000 0.301200 -0.076500  0.296000 -0.272000 0.904000
+-0.035000 0.251000 -0.060900  0.512000 -0.448000 0.728000
+0.000000 0.251000 -0.086600  0.344000 -0.360000 0.864000
+-0.050000 0.236000 -0.060900  0.536000 -0.496000 0.672000
+0.000000 0.211400 -0.121900  0.496000 -0.712000 0.480000
+-0.050000 0.200800 -0.090500  0.520000 -0.520000 0.672000
+-0.012800 0.200800 -0.121900  0.688000 -0.616000 0.376000
+-0.050000 0.170300 -0.121900  0.584000 -0.576000 0.560000
+0.000000 0.200800 -0.169000  0.576000 -0.744000 0.320000
+-0.050000 0.150600 -0.159500  0.712000 -0.480000 0.504000
+0.000000 0.195100 -0.182900  0.504000 -0.656000 -0.544000
+-0.033200 0.150600 -0.182900  0.832000 -0.552000 -0.016000
+0.000000 0.200800 -0.186400  0.272000 -0.456000 -0.840000
+-0.050000 0.150600 -0.210200  0.840000 -0.208000 -0.496000
+-0.050000 0.200800 -0.204500  0.304000 -0.328000 -0.888000
+-0.077600 0.150600 -0.243900  0.320000 0.328000 -0.880000
+-0.100000 0.200800 -0.221500  0.056000 0.392000 -0.912000
+-0.100000 0.164100 -0.243900  -0.032000 0.432000 -0.896000
+-0.150000 0.200800 -0.199200  -0.328000 0.272000 -0.896000
+-0.126800 0.150600 -0.243900  -0.208000 0.496000 -0.832000
+-0.150000 0.150600 -0.235500  -0.296000 0.536000 -0.784000
+-0.150000 0.141700 -0.243900  -0.352000 0.528000 -0.768000
+-0.200000 0.150600 -0.197300  -0.488000 0.464000 -0.728000
+-0.198500 0.100400 -0.243900  -0.376000 0.480000 -0.784000
+-0.200000 0.100400 -0.242800  -0.520000 0.512000 -0.672000
+-0.200000 0.099300 -0.243900  -0.456000 0.488000 -0.736000
+-0.249100 0.100400 -0.182900  -0.576000 0.496000 -0.640000
+-0.250000 0.055800 -0.243900  -0.560000 0.648000 -0.504000
+-0.250000 0.099600 -0.182900  -0.488000 0.616000 -0.608000
+-0.256300 0.050200 -0.243900  -0.592000 0.624000 -0.488000
+-0.300000 0.052000 -0.182900  -0.664000 0.464000 -0.568000
+-0.300000 0.050200 -0.185100  -0.648000 0.560000 -0.504000
+-0.256300 0.050200 -0.243900  -0.592000 0.624000 -0.488000
+-0.300000 0.001800 -0.243900  -0.496000 0.680000 -0.520000
+-0.250000 0.050200 -0.254100  -0.584000 0.656000 -0.464000
+-0.300000 0.000000 -0.248500  -0.656000 0.560000 -0.488000
+-0.250000 0.000000 -0.286200  -0.320000 0.712000 -0.616000
+-0.300000 -0.050200 -0.270300  -0.824000 0.232000 -0.512000
+-0.250000 -0.028200 -0.304800  -0.400000 0.416000 -0.808000
+-0.266700 -0.050200 -0.304800  -0.504000 0.288000 -0.808000
+-0.250000 -0.050200 -0.318700  -0.440000 0.320000 -0.832000
+-0.288100 -0.100400 -0.304800  -0.408000 0.240000 -0.872000
+-0.250000 -0.100400 -0.327300  -0.384000 0.152000 -0.904000
+-0.300000 -0.118900 -0.304800  -0.376000 0.264000 -0.880000
+-0.250000 -0.150600 -0.327500  -0.120000 0.152000 -0.976000
+-0.300000 -0.150600 -0.319300  -0.256000 0.480000 -0.832000
+-0.250000 -0.200800 -0.333200  0.168000 0.080000 -0.976000
+-0.300000 -0.200800 -0.340600  0.016000 0.280000 -0.952000
+-0.250000 -0.251000 -0.337900  0.384000 0.112000 -0.912000
+-0.300000 -0.251000 -0.348000  0.192000 0.248000 -0.944000
+-0.250000 -0.301200 -0.349000  0.296000 0.272000 -0.912000
+-0.300000 -0.296900 -0.365800  0.296000 0.528000 -0.784000
+-0.291400 -0.301200 -0.365800  0.272000 0.504000 -0.808000
+-0.300000 -0.301200 -0.369600  0.320000 0.544000 -0.768000
+-0.250000 -0.342900 -0.365800  0.504000 0.512000 -0.680000
+-0.300000 -0.341100 -0.426800  -0.128000 0.536000 -0.832000
+-0.250000 -0.351500 -0.379700  0.552000 0.712000 -0.416000
+-0.273100 -0.351500 -0.426800  0.480000 0.752000 -0.440000
+-0.250000 -0.368100 -0.426800  0.504000 0.792000 -0.336000
+-0.250000 -0.351500 -0.379700  0.552000 0.712000 -0.416000
+-0.200000 -0.393200 -0.426800  0.696000 0.632000 -0.328000
+-0.241400 -0.351500 -0.365800  0.488000 0.640000 -0.576000
+-0.200000 -0.365300 -0.365800  0.504000 0.768000 -0.376000
+-0.200000 -0.351500 -0.343300  0.312000 0.640000 -0.696000
+-0.241400 -0.351500 -0.365800  0.488000 0.640000 -0.576000
+-0.200000 -0.301200 -0.313400  0.328000 0.152000 -0.928000
+-0.250000 -0.342900 -0.365800  0.504000 0.512000 -0.680000
+-0.250000 -0.301200 -0.349000  0.296000 0.272000 -0.912000
+-0.291400 -0.301200 -0.365800  0.272000 0.504000 -0.808000
+-0.291400 -0.301200 -0.365800  0.272000 0.504000 -0.808000
+-0.200000 0.401700 0.005100  -0.168000 0.288000 0.936000
+-0.200000 0.401700 0.005100  -0.168000 0.288000 0.936000
+-0.200000 0.384800 0.000000  -0.112000 -0.232000 0.960000
+-0.208400 0.401700 0.000000  -0.424000 0.248000 0.864000
+-0.200000 0.351500 -0.009600  0.208000 -0.208000 0.952000
+-0.250000 0.401700 -0.023000  -0.400000 -0.016000 0.912000
+-0.250000 0.351500 -0.004200  0.040000 0.000000 0.992000
+-0.300000 0.401700 -0.053800  -0.512000 0.520000 0.672000
+-0.300000 0.351500 -0.024700  -0.384000 0.216000 0.896000
+-0.307400 0.401700 -0.060900  -0.696000 0.688000 -0.152000
+-0.344500 0.351500 -0.060900  -0.776000 0.288000 0.552000
+-0.300000 0.351500 -0.024700  -0.384000 0.216000 0.896000
+-0.350000 0.329400 -0.060900  -0.960000 0.152000 -0.224000
+-0.300000 0.301200 -0.020200  -0.184000 0.032000 0.976000
+-0.350000 0.301200 -0.051600  -0.832000 0.120000 0.528000
+-0.300000 0.251000 -0.020200  0.208000 -0.160000 0.960000
+-0.350000 0.251000 -0.040500  -0.808000 0.200000 0.544000
+-0.300000 0.200800 -0.040500  0.440000 0.208000 0.864000
+-0.350000 0.200800 -0.003200  -0.528000 -0.104000 0.832000
+-0.350000 0.251000 -0.040500  -0.808000 0.200000 0.544000
+-0.368900 0.200800 -0.060900  -0.952000 0.040000 -0.280000
+-0.356100 0.251000 -0.060900  -0.936000 0.104000 -0.312000
+-0.350000 0.251000 -0.040500  -0.808000 0.200000 0.544000
+-0.353500 0.301200 -0.060900  -0.872000 0.080000 -0.464000
+-0.350000 0.301200 -0.051600  -0.832000 0.120000 0.528000
+-0.350000 0.329400 -0.060900  -0.960000 0.152000 -0.224000
+-0.350000 0.329400 -0.060900  -0.960000 0.152000 -0.224000
+-0.250000 -0.301200 0.006000  0.344000 -0.608000 0.704000
+-0.250000 -0.301200 0.006000  0.344000 -0.608000 0.704000
+-0.235900 -0.301200 0.000000  0.272000 -0.568000 0.768000
+-0.250000 -0.307700 0.000000  0.288000 -0.576000 0.760000
+-0.250000 -0.307700 0.000000  0.288000 -0.576000 0.760000
+-0.169100 -0.301200 0.000000  -0.376000 -0.392000 0.832000
+-0.169100 -0.301200 0.000000  -0.376000 -0.392000 0.832000
+-0.150000 -0.301200 0.010200  -0.304000 -0.280000 0.904000
+-0.150000 -0.346200 0.000000  -0.392000 -0.160000 0.904000
+-0.100000 -0.301200 0.037800  -0.016000 -0.152000 0.984000
+-0.100000 -0.344900 0.000000  0.072000 -0.528000 0.840000
+-0.050000 -0.301200 0.029100  0.312000 -0.280000 0.904000
+-0.050000 -0.329200 0.000000  0.264000 -0.624000 0.720000
+-0.002200 -0.301200 0.000000  0.384000 -0.648000 0.648000
+-0.050000 -0.351500 -0.027000  0.488000 -0.688000 0.528000
+0.000000 -0.301200 -0.001900  0.408000 -0.704000 0.568000
+-0.029100 -0.351500 -0.060900  0.584000 -0.680000 0.424000
+0.000000 -0.326800 -0.060900  0.344000 -0.824000 0.432000
+0.000000 -0.351500 -0.112600  0.544000 -0.704000 0.448000
+0.032200 -0.301200 -0.060900  0.552000 -0.696000 0.448000
+0.006400 -0.351500 -0.121900  0.552000 -0.776000 0.288000
+0.050000 -0.301200 -0.085900  0.528000 -0.704000 0.464000
+0.050000 -0.321600 -0.121900  0.584000 -0.712000 0.376000
+0.074000 -0.301200 -0.121900  0.536000 -0.792000 0.264000
+0.050000 -0.327900 -0.182900  0.552000 -0.824000 0.048000
+0.088900 -0.301200 -0.182900  0.488000 -0.864000 0.072000
+0.050000 -0.327900 -0.243900  0.480000 -0.872000 0.000000
+0.091700 -0.301200 -0.243900  0.488000 -0.864000 -0.008000
+0.050000 -0.326800 -0.304800  0.424000 -0.880000 -0.184000
+0.085600 -0.301200 -0.304800  0.544000 -0.768000 -0.320000
+0.050000 -0.303000 -0.365800  0.400000 -0.792000 -0.448000
+0.052200 -0.301200 -0.365800  0.552000 -0.720000 -0.416000
+0.050000 -0.301200 -0.369000  0.376000 -0.768000 -0.512000
+0.100000 -0.263400 -0.365800  0.480000 -0.672000 -0.544000
+0.050000 -0.251000 -0.406500  0.232000 -0.312000 -0.912000
+0.100000 -0.251000 -0.380100  0.472000 -0.384000 -0.784000
+0.050000 -0.206300 -0.365800  -0.112000 0.608000 -0.776000
+0.100000 -0.224900 -0.365800  0.352000 0.456000 -0.808000
+0.050000 -0.200800 -0.360800  -0.016000 0.576000 -0.808000
+0.100000 -0.200800 -0.352600  0.240000 0.528000 -0.800000
+0.100000 -0.224900 -0.365800  0.352000 0.456000 -0.808000
+0.150000 -0.200800 -0.325200  0.160000 0.176000 -0.968000
+0.118000 -0.251000 -0.365800  0.536000 -0.224000 -0.808000
+0.150000 -0.251000 -0.336000  0.080000 -0.336000 -0.928000
+0.100000 -0.263400 -0.365800  0.480000 -0.672000 -0.544000
+0.150000 -0.287400 -0.304800  0.000000 -0.712000 -0.688000
+0.100000 -0.292600 -0.304800  0.432000 -0.840000 -0.304000
+0.150000 -0.287700 -0.243900  -0.208000 -0.968000 0.064000
+0.100000 -0.296900 -0.243900  0.408000 -0.912000 0.000000
+0.150000 -0.278000 -0.182900  -0.064000 -0.936000 0.328000
+0.100000 -0.295100 -0.182900  0.440000 -0.880000 0.144000
+0.150000 -0.253200 -0.121900  0.192000 -0.808000 0.552000
+0.100000 -0.284500 -0.121900  0.464000 -0.744000 0.472000
+0.150000 -0.251000 -0.118100  0.224000 -0.792000 0.560000
+0.100000 -0.256900 -0.060900  0.456000 -0.800000 0.368000
+0.110300 -0.251000 -0.060900  0.504000 -0.760000 0.392000
+0.100000 -0.251000 -0.044600  0.544000 -0.608000 0.568000
+0.130700 -0.200800 -0.060900  0.504000 0.008000 0.856000
+0.100000 -0.200800 -0.044900  0.416000 0.232000 0.872000
+0.100000 -0.170000 -0.060900  0.256000 0.296000 0.912000
+0.050000 -0.200800 -0.016400  0.232000 0.648000 0.720000
+0.076800 -0.150600 -0.060900  0.208000 0.432000 0.872000
+0.050000 -0.150600 -0.053500  0.160000 0.448000 0.872000
+0.050000 -0.140200 -0.060900  0.152000 0.504000 0.848000
+0.000000 -0.150600 -0.047300  0.168000 0.600000 0.768000
+0.000000 -0.136800 -0.060900  0.088000 0.520000 0.840000
+-0.050000 -0.150600 -0.033100  0.152000 0.512000 0.840000
+-0.050000 -0.119400 -0.060900  0.168000 0.528000 0.824000
+-0.100000 -0.150600 -0.019000  0.512000 0.456000 0.720000
+-0.100000 -0.105500 -0.060900  0.480000 0.464000 0.736000
+-0.129500 -0.150600 0.000000  0.416000 0.264000 0.864000
+-0.104300 -0.100400 -0.060900  0.528000 0.416000 0.728000
+-0.150000 -0.104300 0.000000  0.496000 0.120000 0.848000
+-0.150000 -0.100400 -0.001300  0.848000 0.032000 0.520000
+-0.150600 -0.100400 0.000000  0.800000 0.040000 0.592000
+-0.150000 -0.050200 -0.005700  0.768000 -0.024000 0.632000
+-0.152800 -0.050200 0.000000  0.848000 0.032000 0.520000
+-0.150000 0.000000 -0.001200  0.744000 0.064000 0.656000
+-0.150800 0.000000 0.000000  0.744000 0.072000 0.656000
+-0.150000 0.050200 -0.012600  0.624000 0.240000 0.728000
+-0.163800 0.050200 0.000000  0.704000 0.216000 0.664000
+-0.150000 0.100400 -0.027500  0.432000 0.296000 0.848000
+-0.200000 0.089800 0.000000  0.216000 0.544000 0.800000
+-0.200000 0.100400 -0.008800  0.176000 0.488000 0.848000
+-0.238500 0.100400 0.000000  0.152000 0.496000 0.848000
+-0.200000 0.150600 -0.023100  -0.360000 0.472000 0.792000
+-0.250000 0.104200 0.000000  0.144000 0.480000 0.856000
+-0.250000 0.150600 -0.042200  0.008000 0.568000 0.816000
+-0.300000 0.112500 0.000000  -0.064000 0.472000 0.872000
+-0.300000 0.150600 -0.036000  -0.360000 0.064000 0.920000
+-0.300000 0.150600 -0.036000  -0.360000 0.064000 0.920000
+-0.150000 -0.104300 0.000000  0.496000 0.120000 0.848000
+-0.150000 -0.104300 0.000000  0.496000 0.120000 0.848000
+-0.129500 -0.150600 0.000000  0.416000 0.264000 0.864000
+-0.150000 -0.150600 0.010200  0.376000 0.208000 0.896000
+-0.100000 -0.188700 0.000000  0.176000 0.408000 0.888000
+-0.150000 -0.200800 0.013600  0.104000 0.200000 0.968000
+-0.100000 -0.200800 0.005100  0.056000 0.344000 0.936000
+-0.150000 -0.251000 0.002400  -0.056000 -0.176000 0.976000
+-0.100000 -0.251000 0.029400  -0.128000 0.120000 0.976000
+-0.150000 -0.301200 0.010200  -0.304000 -0.280000 0.904000
+-0.100000 -0.301200 0.037800  -0.016000 -0.152000 0.984000
+-0.100000 -0.251000 0.029400  -0.128000 0.120000 0.976000
+-0.050000 -0.301200 0.029100  0.312000 -0.280000 0.904000
+-0.050000 -0.251000 0.040700  0.136000 0.064000 0.984000
+-0.002200 -0.301200 0.000000  0.384000 -0.648000 0.648000
+0.000000 -0.251000 0.031300  0.424000 -0.232000 0.872000
+0.000000 -0.299000 0.000000  0.440000 -0.464000 0.760000
+0.050000 -0.251000 0.003400  0.512000 0.320000 0.792000
+0.050000 -0.253500 0.000000  0.448000 -0.608000 0.648000
+0.054200 -0.251000 0.000000  0.552000 0.192000 0.800000
+0.050000 -0.286400 -0.060900  0.528000 -0.720000 0.440000
+0.100000 -0.251000 -0.044600  0.544000 -0.608000 0.568000
+0.100000 -0.256900 -0.060900  0.456000 -0.800000 0.368000
+0.050000 -0.286400 -0.060900  0.528000 -0.720000 0.440000
+0.100000 -0.284500 -0.121900  0.464000 -0.744000 0.472000
+0.050000 -0.301200 -0.085900  0.528000 -0.704000 0.464000
+0.074000 -0.301200 -0.121900  0.536000 -0.792000 0.264000
+0.100000 -0.284500 -0.121900  0.464000 -0.744000 0.472000
+0.088900 -0.301200 -0.182900  0.488000 -0.864000 0.072000
+0.100000 -0.295100 -0.182900  0.440000 -0.880000 0.144000
+0.091700 -0.301200 -0.243900  0.488000 -0.864000 -0.008000
+0.100000 -0.296900 -0.243900  0.408000 -0.912000 0.000000
+0.085600 -0.301200 -0.304800  0.544000 -0.768000 -0.320000
+0.100000 -0.292600 -0.304800  0.432000 -0.840000 -0.304000
+0.052200 -0.301200 -0.365800  0.552000 -0.720000 -0.416000
+0.100000 -0.263400 -0.365800  0.480000 -0.672000 -0.544000
+0.100000 -0.263400 -0.365800  0.480000 -0.672000 -0.544000
+-0.100000 -0.200800 0.005100  0.056000 0.344000 0.936000
+-0.100000 -0.200800 0.005100  0.056000 0.344000 0.936000
+-0.050000 -0.200800 0.008600  0.032000 0.536000 0.840000
+-0.100000 -0.188700 0.000000  0.176000 0.408000 0.888000
+-0.050000 -0.190400 0.000000  0.096000 0.648000 0.744000
+-0.100000 -0.150600 -0.019000  0.512000 0.456000 0.720000
+-0.050000 -0.150600 -0.033100  0.152000 0.512000 0.840000
+-0.050000 -0.190400 0.000000  0.096000 0.648000 0.744000
+0.000000 -0.150600 -0.047300  0.168000 0.600000 0.768000
+0.000000 -0.198800 0.000000  0.160000 0.688000 0.704000
+0.050000 -0.150600 -0.053500  0.160000 0.448000 0.872000
+0.006800 -0.200800 0.000000  0.232000 0.576000 0.776000
+0.050000 -0.200800 -0.016400  0.232000 0.648000 0.720000
+0.050000 -0.244100 0.000000  0.488000 0.320000 0.800000
+0.100000 -0.200800 -0.044900  0.416000 0.232000 0.872000
+0.054200 -0.251000 0.000000  0.552000 0.192000 0.800000
+0.100000 -0.251000 -0.044600  0.544000 -0.608000 0.568000
+0.100000 -0.251000 -0.044600  0.544000 -0.608000 0.568000
+-0.100000 -0.200800 0.005100  0.056000 0.344000 0.936000
+-0.100000 -0.200800 0.005100  0.056000 0.344000 0.936000
+-0.100000 -0.251000 0.029400  -0.128000 0.120000 0.976000
+-0.050000 -0.200800 0.008600  0.032000 0.536000 0.840000
+-0.050000 -0.251000 0.040700  0.136000 0.064000 0.984000
+0.000000 -0.200800 0.002300  0.160000 0.560000 0.808000
+0.000000 -0.251000 0.031300  0.424000 -0.232000 0.872000
+0.006800 -0.200800 0.000000  0.232000 0.576000 0.776000
+0.050000 -0.251000 0.003400  0.512000 0.320000 0.792000
+0.050000 -0.244100 0.000000  0.488000 0.320000 0.800000
+0.054200 -0.251000 0.000000  0.552000 0.192000 0.800000
+0.054200 -0.251000 0.000000  0.552000 0.192000 0.800000
+-0.050000 -0.190400 0.000000  0.096000 0.648000 0.744000
+-0.050000 -0.190400 0.000000  0.096000 0.648000 0.744000
+-0.050000 -0.200800 0.008600  0.032000 0.536000 0.840000
+0.000000 -0.198800 0.000000  0.160000 0.688000 0.704000
+0.000000 -0.200800 0.002300  0.160000 0.560000 0.808000
+0.006800 -0.200800 0.000000  0.232000 0.576000 0.776000
+0.006800 -0.200800 0.000000  0.232000 0.576000 0.776000
+0.500000 0.245700 0.000000  -0.568000 0.120000 0.808000
+0.500000 0.245700 0.000000  -0.568000 0.120000 0.808000
+0.500000 0.200800 0.008600  -0.576000 -0.176000 0.792000
+0.488800 0.200800 0.000000  -0.512000 0.024000 0.856000
+0.500000 0.181600 0.000000  -0.600000 -0.304000 0.728000
+0.500000 0.181600 0.000000  -0.600000 -0.304000 0.728000
+0.550000 0.174700 0.060900  -0.744000 -0.320000 0.576000
+0.550000 0.174700 0.060900  -0.744000 -0.320000 0.576000
+0.560700 0.150600 0.060900  -0.704000 -0.368000 0.592000
+0.550000 0.150600 0.048400  -0.632000 -0.416000 0.640000
+0.550000 0.150600 0.048400  -0.632000 -0.416000 0.640000
+0.641200 0.050200 0.060900  -0.600000 -0.608000 0.512000
+0.641200 0.050200 0.060900  -0.600000 -0.608000 0.512000
+0.600000 0.093600 0.060900  -0.624000 -0.616000 0.464000
+0.602900 0.050200 0.000000  -0.576000 -0.704000 0.400000
+0.600000 0.053300 0.000000  -0.472000 -0.712000 0.512000
+0.600000 0.050200 -0.005300  -0.440000 -0.752000 0.480000
+0.600000 0.050200 -0.005300  -0.440000 -0.752000 0.480000
+-0.915700 -0.150600 0.000000  -0.696000 -0.672000 0.232000
+-0.915700 -0.150600 0.000000  -0.696000 -0.672000 0.232000
+-0.950000 -0.123700 0.000000  -0.488000 -0.840000 0.216000
+-0.932400 -0.150600 -0.060900  -0.688000 -0.696000 0.176000
+-0.950000 -0.136200 -0.060900  -0.528000 -0.832000 0.152000
+-0.943100 -0.150600 -0.121900  -0.672000 -0.720000 0.120000
+-0.950000 -0.144800 -0.121900  -0.536000 -0.832000 0.120000
+-0.950000 -0.150600 -0.169000  -0.584000 -0.792000 0.136000
+-0.943100 -0.150600 -0.121900  -0.672000 -0.720000 0.120000
+-0.950000 -0.152700 -0.182900  -0.600000 -0.784000 0.144000
+-0.903800 -0.200800 -0.121900  -0.696000 -0.704000 0.120000
+-0.907400 -0.200800 -0.182900  -0.688000 -0.712000 0.072000
+-0.950000 -0.152700 -0.182900  -0.600000 -0.784000 0.144000
+-0.914100 -0.200800 -0.243900  -0.664000 -0.728000 0.128000
+-0.950000 -0.161800 -0.243900  -0.584000 -0.784000 0.176000
+-0.931500 -0.200800 -0.304800  -0.648000 -0.520000 -0.544000
+-0.950000 -0.180000 -0.304800  -0.552000 -0.600000 -0.568000
+-0.900000 -0.200800 -0.331500  -0.576000 -0.328000 -0.736000
+-0.950000 -0.150600 -0.330800  -0.416000 -0.432000 -0.792000
+-0.900000 -0.150600 -0.338300  -0.216000 -0.104000 -0.968000
+-0.900000 -0.200800 -0.331500  -0.576000 -0.328000 -0.736000
+-0.850000 -0.150600 -0.349400  0.072000 0.056000 -0.992000
+-0.850000 -0.200800 -0.351200  -0.168000 0.112000 -0.976000
+-0.800000 -0.150600 -0.340500  0.312000 0.288000 -0.896000
+-0.800000 -0.200800 -0.355700  0.080000 0.256000 -0.960000
+-0.750000 -0.150600 -0.317800  0.416000 0.384000 -0.816000
+-0.750000 -0.200800 -0.348300  0.272000 0.384000 -0.872000
+-0.731900 -0.150600 -0.304800  0.424000 0.400000 -0.808000
+-0.700000 -0.200800 -0.326900  0.208000 0.528000 -0.816000
+-0.700000 -0.175200 -0.304800  0.352000 0.528000 -0.768000
+-0.651700 -0.200800 -0.304800  0.320000 0.544000 -0.768000
+-0.700000 -0.150600 -0.284500  0.376000 0.392000 -0.832000
+-0.650000 -0.200800 -0.303800  0.136000 0.680000 -0.712000
+-0.650000 -0.150600 -0.267500  0.376000 0.464000 -0.792000
+-0.650000 -0.150600 -0.267500  0.376000 0.464000 -0.792000
+-0.895700 -0.200800 -0.060900  -0.864000 -0.480000 0.136000
+-0.895700 -0.200800 -0.060900  -0.864000 -0.480000 0.136000
+-0.882700 -0.200800 0.000000  -0.840000 -0.496000 0.192000
+-0.860100 -0.251000 -0.060900  -0.808000 -0.568000 0.112000
+-0.852600 -0.251000 0.000000  -0.800000 -0.568000 0.168000
+-0.852600 -0.251000 0.000000  -0.800000 -0.568000 0.168000
+-0.700000 -0.502100 -0.057900  -0.752000 -0.512000 0.400000
+-0.700000 -0.502100 -0.057900  -0.752000 -0.512000 0.400000
+-0.700000 -0.507800 -0.060900  -0.864000 -0.200000 0.448000
+-0.701200 -0.502100 -0.060900  -0.816000 -0.416000 0.392000
+-0.700000 -0.552300 -0.082500  -0.736000 -0.280000 0.608000
+-0.723300 -0.502100 -0.121900  -0.896000 -0.224000 0.368000
+-0.750000 -0.552300 -0.119400  0.072000 0.512000 0.848000
+-0.750000 -0.549900 -0.121900  0.080000 0.648000 0.752000
+-0.800000 -0.552300 -0.095900  0.424000 0.264000 0.864000
+-0.800000 -0.539500 -0.121900  0.176000 0.680000 0.704000
+-0.850000 -0.552300 -0.082300  -0.704000 -0.480000 0.504000
+-0.850000 -0.519700 -0.121900  0.200000 0.624000 0.752000
+-0.868200 -0.552300 -0.121900  -0.520000 -0.224000 0.816000
+-0.850000 -0.502100 -0.144600  0.400000 0.776000 0.480000
+-0.900000 -0.511500 -0.121900  -0.520000 -0.664000 0.528000
+-0.878700 -0.502100 -0.121900  0.408000 0.368000 0.832000
+-0.900000 -0.502100 -0.104000  -0.752000 0.000000 0.656000
+-0.900000 -0.492700 -0.121900  -0.520000 0.712000 0.448000
+-0.906100 -0.502100 -0.121900  -0.920000 0.072000 0.376000
+-0.900000 -0.462200 -0.182900  0.320000 0.888000 0.304000
+-0.925200 -0.502100 -0.182900  -0.976000 -0.008000 0.208000
+-0.900000 -0.451900 -0.229200  0.512000 0.832000 0.168000
+-0.929300 -0.502100 -0.243900  -0.992000 0.064000 -0.008000
+-0.921000 -0.451900 -0.243900  -0.184000 0.968000 0.160000
+-0.920600 -0.502100 -0.304800  -0.888000 -0.288000 -0.344000
+-0.912200 -0.451900 -0.304800  -0.496000 0.720000 -0.464000
+-0.900000 -0.502100 -0.352600  -0.672000 0.128000 -0.720000
+-0.900000 -0.451900 -0.318500  0.104000 0.872000 -0.464000
+-0.864000 -0.502100 -0.365800  -0.304000 0.480000 -0.816000
+-0.891000 -0.451900 -0.304800  0.528000 0.824000 -0.192000
+-0.850000 -0.496800 -0.365800  -0.176000 0.616000 -0.760000
+-0.850000 -0.473200 -0.304800  0.272000 0.896000 -0.336000
+-0.800000 -0.496400 -0.365800  -0.664000 0.416000 -0.608000
+-0.800000 -0.473000 -0.304800  -0.736000 0.648000 -0.168000
+-0.786000 -0.451900 -0.365800  -0.872000 0.080000 -0.472000
+-0.787800 -0.451900 -0.304800  -0.984000 0.136000 -0.040000
+-0.796500 -0.401700 -0.365800  -0.952000 -0.168000 -0.232000
+-0.797400 -0.401700 -0.304800  -0.928000 -0.344000 0.056000
+-0.800000 -0.388500 -0.365800  -0.864000 -0.288000 -0.400000
+-0.800000 -0.395700 -0.304800  -0.920000 -0.376000 0.000000
+-0.797400 -0.401700 -0.304800  -0.928000 -0.344000 0.056000
+-0.800000 -0.365300 -0.243900  -0.880000 -0.440000 0.160000
+-0.781800 -0.401700 -0.243900  -0.912000 -0.336000 0.208000
+-0.800000 -0.355500 -0.182900  -0.872000 -0.472000 0.032000
+-0.775200 -0.401700 -0.182900  -0.904000 -0.400000 0.120000
+-0.800000 -0.354700 -0.121900  -0.848000 -0.512000 0.080000
+-0.771000 -0.401700 -0.121900  -0.872000 -0.456000 0.128000
+-0.800000 -0.351500 -0.101400  -0.840000 -0.528000 0.104000
+-0.762700 -0.401700 -0.060900  -0.840000 -0.496000 0.168000
+-0.794800 -0.351500 -0.060900  -0.816000 -0.552000 0.144000
+-0.800000 -0.351500 -0.101400  -0.840000 -0.528000 0.104000
+-0.800000 -0.343900 -0.060900  -0.816000 -0.552000 0.128000
+-0.800000 -0.343900 -0.060900  -0.816000 -0.552000 0.128000
+-0.700000 0.150600 -0.043600  0.552000 0.712000 0.424000
+-0.700000 0.150600 -0.043600  0.552000 0.712000 0.424000
+-0.700000 0.159000 -0.060900  0.600000 0.776000 0.184000
+-0.689800 0.150600 -0.060900  0.640000 0.736000 0.192000
+-0.700000 0.150600 -0.089800  0.592000 0.744000 -0.280000
+-0.650000 0.112000 -0.060900  0.672000 0.704000 0.200000
+-0.700000 0.140000 -0.121900  0.536000 0.728000 -0.408000
+-0.650000 0.100400 -0.098000  0.720000 0.624000 -0.288000
+-0.657700 0.100400 -0.121900  0.728000 0.576000 -0.360000
+-0.650000 0.089500 -0.121900  0.728000 0.552000 -0.384000
+-0.700000 0.100400 -0.182100  0.536000 0.592000 -0.592000
+-0.650000 0.050200 -0.178200  0.664000 0.544000 -0.504000
+-0.700000 0.099700 -0.182900  0.504000 0.560000 -0.640000
+-0.652800 0.050200 -0.182900  0.592000 0.536000 -0.592000
+-0.700000 0.050200 -0.235800  0.504000 0.432000 -0.744000
+-0.650000 0.045800 -0.182900  0.672000 0.432000 -0.592000
+-0.700000 0.037400 -0.243900  0.440000 0.392000 -0.800000
+-0.650000 0.000000 -0.224600  0.632000 0.368000 -0.672000
+-0.669700 0.000000 -0.243900  0.480000 0.312000 -0.808000
+-0.700000 0.037400 -0.243900  0.440000 0.392000 -0.800000
+-0.700000 0.000000 -0.262900  0.392000 0.288000 -0.864000
+-0.700000 0.000000 -0.262900  0.392000 0.288000 -0.864000
+-0.650000 -0.541900 0.000000  -0.528000 -0.600000 0.592000
+-0.650000 -0.541900 0.000000  -0.528000 -0.600000 0.592000
+-0.633400 -0.552300 0.000000  -0.384000 -0.672000 0.624000
+-0.650000 -0.552300 -0.012600  -0.496000 -0.592000 0.624000
+-0.650000 -0.552300 -0.012600  -0.496000 -0.592000 0.624000
+-0.452400 -0.100400 -0.060900  -0.344000 0.936000 -0.016000
+-0.452400 -0.100400 -0.060900  -0.344000 0.936000 -0.016000
+-0.450000 -0.099400 -0.060900  -0.760000 0.616000 0.160000
+-0.450000 -0.100400 -0.057100  -0.400000 0.872000 0.264000
+-0.406900 -0.050200 -0.060900  -0.848000 0.520000 0.000000
+-0.434300 -0.100400 0.000000  -0.648000 0.720000 0.208000
+-0.400000 -0.050200 -0.003200  -0.712000 0.672000 0.168000
+-0.400000 -0.050900 0.000000  -0.776000 0.576000 0.224000
+-0.399300 -0.050200 0.000000  -0.696000 0.680000 0.184000
+-0.399300 -0.050200 0.000000  -0.696000 0.680000 0.184000
+-0.466200 -0.502100 0.000000  0.712000 -0.616000 0.320000
+-0.466200 -0.502100 0.000000  0.712000 -0.616000 0.320000
+-0.450000 -0.489500 0.000000  0.584000 -0.760000 0.264000
+-0.450000 -0.502100 -0.045100  0.560000 -0.696000 0.432000
+-0.403800 -0.451900 0.000000  0.744000 -0.560000 0.352000
+-0.400000 -0.502100 -0.024700  0.848000 -0.224000 0.464000
+-0.400000 -0.451900 -0.009600  0.744000 -0.536000 0.376000
+-0.403800 -0.451900 0.000000  0.744000 -0.560000 0.352000
+-0.400000 -0.447100 0.000000  0.720000 -0.584000 0.344000
+-0.400000 -0.451900 -0.009600  0.744000 -0.536000 0.376000
+-0.350000 -0.427600 0.000000  0.560000 -0.752000 0.336000
+-0.350000 -0.451900 -0.058800  0.248000 -0.624000 0.728000
+-0.350000 -0.451900 -0.058800  0.248000 -0.624000 0.728000
+-0.500000 -0.552300 -0.009400  0.352000 -0.840000 0.400000
+-0.500000 -0.552300 -0.009400  0.352000 -0.840000 0.400000
+-0.478800 -0.552300 -0.060900  0.704000 -0.592000 0.376000
+-0.500000 -0.570000 -0.060900  0.480000 -0.800000 0.328000
+-0.452200 -0.552300 -0.121900  0.864000 0.184000 0.464000
+-0.500000 -0.589900 -0.121900  0.408000 -0.832000 0.352000
+-0.450000 -0.552300 -0.127200  0.616000 -0.144000 0.768000
+-0.500000 -0.602500 -0.155300  0.000000 -0.920000 0.376000
+-0.450000 -0.558900 -0.121900  0.808000 0.320000 0.488000
+-0.474100 -0.602500 -0.121900  -0.520000 -0.712000 0.456000
+-0.450000 -0.602500 -0.084100  -0.232000 -0.736000 0.624000
+-0.450000 -0.612400 -0.121900  0.032000 -0.944000 0.312000
+-0.410500 -0.602500 -0.121900  0.456000 -0.632000 0.616000
+-0.450000 -0.629600 -0.182900  -0.344000 -0.872000 0.320000
+-0.400000 -0.602500 -0.131300  0.560000 -0.576000 0.584000
+-0.400000 -0.651500 -0.182900  -0.552000 -0.472000 0.672000
+-0.386500 -0.602500 -0.182900  0.376000 -0.032000 0.920000
+-0.400000 -0.652700 -0.184800  -0.640000 -0.536000 0.536000
+-0.350000 -0.647900 -0.182900  0.008000 0.768000 0.624000
+-0.396000 -0.652700 -0.182900  -0.176000 0.000000 0.984000
+-0.350000 -0.652700 -0.168800  -0.864000 0.056000 0.488000
+-0.350700 -0.703000 -0.182900  -0.792000 -0.176000 0.576000
+-0.350000 -0.703000 -0.180700  -0.616000 -0.504000 0.592000
+-0.350000 -0.704300 -0.182900  -0.112000 -0.808000 0.576000
+-0.300000 -0.703000 -0.173800  0.616000 -0.544000 0.552000
+-0.300000 -0.708000 -0.182900  0.360000 -0.768000 0.520000
+-0.293800 -0.703000 -0.182900  0.608000 -0.624000 0.488000
+-0.300000 -0.736500 -0.243900  0.320000 -0.832000 0.440000
+-0.256000 -0.703000 -0.243900  0.696000 -0.392000 0.584000
+-0.300000 -0.753200 -0.286100  0.088000 -0.928000 0.352000
+-0.250000 -0.703000 -0.252700  0.704000 -0.368000 0.600000
+-0.281500 -0.753200 -0.304800  0.312000 -0.920000 -0.216000
+-0.250000 -0.737300 -0.304800  0.568000 -0.808000 -0.112000
+-0.300000 -0.753200 -0.317300  0.136000 -0.840000 -0.512000
+-0.250000 -0.703000 -0.346500  0.432000 -0.280000 -0.848000
+-0.300000 -0.703000 -0.365100  0.056000 -0.232000 -0.968000
+-0.250000 -0.652700 -0.361600  0.240000 -0.216000 -0.944000
+-0.300000 -0.687100 -0.365800  0.104000 -0.048000 -0.992000
+-0.282800 -0.652700 -0.365800  0.080000 -0.160000 -0.976000
+-0.300000 -0.652700 -0.367500  0.064000 -0.112000 -0.984000
+-0.300000 -0.687100 -0.365800  0.104000 -0.048000 -0.992000
+-0.350000 -0.652700 -0.376000  0.560000 0.160000 -0.808000
+-0.350000 -0.679200 -0.365800  -0.072000 -0.176000 -0.976000
+-0.400000 -0.652700 -0.368100  -0.128000 -0.872000 -0.456000
+-0.400000 -0.653700 -0.365800  -0.176000 -0.888000 -0.416000
+-0.405700 -0.652700 -0.365800  -0.144000 -0.920000 -0.344000
+-0.400000 -0.672200 -0.304800  -0.400000 -0.904000 -0.128000
+-0.450000 -0.652700 -0.319500  -0.256000 -0.952000 -0.136000
+-0.450000 -0.654300 -0.304800  -0.272000 -0.952000 0.040000
+-0.455200 -0.652700 -0.304800  -0.280000 -0.952000 0.040000
+-0.450000 -0.652700 -0.293400  -0.288000 -0.936000 0.160000
+-0.500000 -0.637800 -0.304800  -0.208000 -0.976000 -0.032000
+-0.450000 -0.644000 -0.243900  -0.352000 -0.912000 0.200000
+-0.500000 -0.625200 -0.243900  -0.096000 -0.960000 0.240000
+-0.450000 -0.629600 -0.182900  -0.344000 -0.872000 0.320000
+-0.500000 -0.610400 -0.182900  -0.136000 -0.936000 0.304000
+-0.450000 -0.612400 -0.121900  0.032000 -0.944000 0.312000
+-0.500000 -0.602500 -0.155300  0.000000 -0.920000 0.376000
+-0.474100 -0.602500 -0.121900  -0.520000 -0.712000 0.456000
+-0.474100 -0.602500 -0.121900  -0.520000 -0.712000 0.456000
+-0.350000 0.148000 -0.060900  -0.504000 0.552000 0.656000
+-0.350000 0.148000 -0.060900  -0.504000 0.552000 0.656000
+-0.350000 0.100400 -0.017600  -0.744000 0.352000 0.552000
+-0.361800 0.100400 -0.060900  -0.920000 0.112000 -0.352000
+-0.350000 0.077100 0.000000  -0.776000 0.256000 0.568000
+-0.358600 0.050200 -0.060900  -0.920000 0.168000 -0.328000
+-0.355100 0.050200 0.000000  -0.872000 0.216000 0.416000
+-0.355100 0.050200 0.000000  -0.872000 0.216000 0.416000
+-0.307400 0.401700 -0.060900  -0.696000 0.688000 -0.152000
+-0.307400 0.401700 -0.060900  -0.696000 0.688000 -0.152000
+-0.300000 0.408800 -0.060900  -0.664000 0.712000 -0.184000
+-0.300000 0.401700 -0.053800  -0.512000 0.520000 0.672000
+-0.250000 0.447500 -0.060900  -0.512000 0.744000 0.408000
+-0.250000 0.401700 -0.023000  -0.400000 -0.016000 0.912000
+-0.242600 0.451900 -0.060900  -0.440000 0.728000 0.512000
+-0.208400 0.401700 0.000000  -0.424000 0.248000 0.864000
+-0.200000 0.451900 -0.034900  -0.360000 0.584000 0.720000
+-0.200000 0.408700 0.000000  -0.112000 0.496000 0.856000
+-0.150000 0.451900 -0.004000  -0.136000 0.584000 0.792000
+-0.185900 0.401700 0.000000  0.264000 0.248000 0.928000
+-0.150000 0.401700 -0.011900  0.240000 0.256000 0.928000
+-0.150000 0.451900 -0.004000  -0.136000 0.584000 0.792000
+-0.100000 0.401700 -0.042400  0.232000 -0.088000 0.960000
+-0.100000 0.451900 -0.019200  0.136000 0.056000 0.984000
+-0.050000 0.401700 -0.052300  0.176000 0.040000 0.976000
+-0.050000 0.451900 -0.049700  0.432000 0.024000 0.896000
+-0.100000 0.451900 -0.019200  0.136000 0.056000 0.984000
+-0.050000 0.502100 -0.046900  0.400000 0.496000 0.760000
+-0.100000 0.502100 -0.041900  -0.080000 0.528000 0.840000
+-0.050000 0.515300 -0.060900  0.432000 0.792000 0.408000
+-0.100000 0.517800 -0.060900  -0.120000 0.976000 0.136000
+-0.100000 0.502100 -0.041900  -0.080000 0.528000 0.840000
+-0.146800 0.502100 -0.060900  -0.272000 0.960000 0.016000
+-0.100000 0.451900 -0.019200  0.136000 0.056000 0.984000
+-0.150000 0.501300 -0.060900  -0.376000 0.880000 -0.280000
+-0.150000 0.451900 -0.004000  -0.136000 0.584000 0.792000
+-0.200000 0.477600 -0.060900  -0.544000 0.808000 -0.208000
+-0.200000 0.451900 -0.034900  -0.360000 0.584000 0.720000
+-0.242600 0.451900 -0.060900  -0.440000 0.728000 0.512000
+-0.200000 0.477600 -0.060900  -0.544000 0.808000 -0.208000
+-0.200000 0.451900 -0.081300  -0.400000 0.504000 -0.752000
+-0.200000 0.451900 -0.081300  -0.400000 0.504000 -0.752000
+-0.321000 0.100400 0.000000  -0.264000 0.416000 0.864000
+-0.321000 0.100400 0.000000  -0.264000 0.416000 0.864000
+-0.350000 0.077100 0.000000  -0.776000 0.256000 0.568000
+-0.350000 0.100400 -0.017600  -0.744000 0.352000 0.552000
+-0.350000 0.100400 -0.017600  -0.744000 0.352000 0.552000
+-0.250000 0.351500 -0.004200  0.040000 0.000000 0.992000
+-0.250000 0.351500 -0.004200  0.040000 0.000000 0.992000
+-0.300000 0.351500 -0.024700  -0.384000 0.216000 0.896000
+-0.250000 0.301200 -0.005700  0.112000 -0.104000 0.984000
+-0.300000 0.301200 -0.020200  -0.184000 0.032000 0.976000
+-0.250000 0.251000 -0.029400  0.176000 -0.456000 0.864000
+-0.300000 0.251000 -0.020200  0.208000 -0.160000 0.960000
+-0.250000 0.219300 -0.060900  0.304000 -0.640000 0.696000
+-0.300000 0.200800 -0.040500  0.440000 0.208000 0.864000
+-0.277600 0.200800 -0.060900  0.584000 -0.072000 0.800000
+-0.250000 0.219300 -0.060900  0.304000 -0.640000 0.696000
+-0.250000 0.200800 -0.094600  -0.184000 -0.064000 0.976000
+-0.200000 0.206100 -0.060900  -0.448000 -0.184000 0.872000
+-0.200000 0.200800 -0.062300  -0.304000 0.376000 0.864000
+-0.198000 0.200800 -0.060900  -0.464000 0.288000 0.832000
+-0.200000 0.199100 -0.060900  -0.320000 0.504000 0.792000
+-0.200000 0.200800 -0.062300  -0.304000 0.376000 0.864000
+-0.250000 0.177000 -0.060900  -0.096000 0.568000 0.808000
+-0.250000 0.200800 -0.094600  -0.184000 -0.064000 0.976000
+-0.277600 0.200800 -0.060900  0.584000 -0.072000 0.800000
+-0.277600 0.200800 -0.060900  0.584000 -0.072000 0.800000
+-0.250000 -0.351500 -0.038300  0.104000 -0.504000 0.848000
+-0.250000 -0.351500 -0.038300  0.104000 -0.504000 0.848000
+-0.300000 -0.351500 -0.012600  0.872000 -0.352000 0.320000
+-0.250000 -0.401700 -0.058800  -0.096000 -0.136000 0.984000
+-0.300000 -0.401700 -0.045100  0.792000 -0.248000 0.544000
+-0.250000 -0.451900 -0.040500  -0.352000 -0.008000 0.928000
+-0.300000 -0.435300 -0.060900  -0.192000 -0.360000 0.912000
+-0.287100 -0.451900 -0.060900  -0.448000 -0.328000 0.824000
+-0.300000 -0.451900 -0.070300  -0.328000 -0.392000 0.856000
+-0.279200 -0.502100 -0.060900  -0.688000 -0.328000 0.640000
+-0.300000 -0.502100 -0.097100  -0.592000 -0.576000 0.560000
+-0.250000 -0.533000 -0.060900  -0.336000 -0.760000 0.544000
+-0.300000 -0.516400 -0.121900  -0.256000 -0.872000 0.400000
+-0.250000 -0.552300 -0.101500  -0.080000 -0.904000 0.400000
+-0.260200 -0.552300 -0.121900  -0.560000 -0.752000 0.336000
+-0.250000 -0.559400 -0.121900  -0.088000 -0.912000 0.384000
+-0.285200 -0.552300 -0.182900  -0.616000 -0.680000 0.384000
+-0.250000 -0.581300 -0.182900  -0.104000 -0.888000 0.440000
+-0.300000 -0.552300 -0.209900  -0.624000 -0.616000 0.456000
+-0.250000 -0.602500 -0.226600  0.288000 -0.512000 0.800000
+-0.300000 -0.594300 -0.243900  -0.424000 -0.464000 0.768000
+-0.286800 -0.602500 -0.243900  -0.320000 0.232000 0.912000
+-0.300000 -0.602500 -0.250000  -0.408000 0.368000 0.824000
+-0.300000 -0.607200 -0.243900  -0.248000 0.672000 0.688000
+-0.344900 -0.602500 -0.304800  -0.744000 0.664000 -0.032000
+-0.350000 -0.630200 -0.243900  -0.144000 0.776000 0.600000
+-0.350000 -0.605300 -0.304800  0.248000 0.960000 -0.032000
+-0.371400 -0.602500 -0.243900  0.928000 0.016000 0.352000
+-0.351600 -0.602500 -0.304800  0.944000 0.304000 0.024000
+-0.363900 -0.552300 -0.243900  0.816000 -0.480000 0.304000
+-0.350000 -0.594300 -0.304800  0.520000 -0.800000 0.280000
+-0.350000 -0.552300 -0.283400  -0.096000 -0.680000 0.720000
+-0.344900 -0.602500 -0.304800  -0.744000 0.664000 -0.032000
+-0.317500 -0.552300 -0.243900  -0.600000 -0.648000 0.448000
+-0.300000 -0.602500 -0.250000  -0.408000 0.368000 0.824000
+-0.300000 -0.594300 -0.243900  -0.424000 -0.464000 0.768000
+-0.317500 -0.552300 -0.243900  -0.600000 -0.648000 0.448000
+-0.300000 -0.552300 -0.209900  -0.624000 -0.616000 0.456000
+-0.350000 -0.535600 -0.243900  0.360000 -0.840000 0.384000
+-0.300000 -0.538300 -0.182900  -0.584000 -0.696000 0.408000
+-0.350000 -0.518400 -0.182900  -0.088000 -0.928000 0.360000
+-0.300000 -0.516400 -0.121900  -0.256000 -0.872000 0.400000
+-0.350000 -0.503000 -0.121900  0.232000 -0.880000 0.400000
+-0.300000 -0.502100 -0.097100  -0.592000 -0.576000 0.560000
+-0.350000 -0.502100 -0.119400  0.240000 -0.864000 0.424000
+-0.300000 -0.451900 -0.070300  -0.328000 -0.392000 0.856000
+-0.350000 -0.453900 -0.060900  0.248000 -0.624000 0.728000
+-0.338500 -0.451900 -0.060900  0.112000 -0.632000 0.760000
+-0.300000 -0.451900 -0.070300  -0.328000 -0.392000 0.856000
+-0.300000 -0.435300 -0.060900  -0.192000 -0.360000 0.912000
+-0.300000 -0.435300 -0.060900  -0.192000 -0.360000 0.912000
+-0.287100 -0.451900 -0.060900  -0.448000 -0.328000 0.824000
+-0.287100 -0.451900 -0.060900  -0.448000 -0.328000 0.824000
+-0.279200 -0.502100 -0.060900  -0.688000 -0.328000 0.640000
+-0.250000 -0.451900 -0.040500  -0.352000 -0.008000 0.928000
+-0.250000 -0.502100 -0.016400  -0.320000 -0.344000 0.872000
+-0.200000 -0.451900 -0.018000  0.376000 -0.112000 0.912000
+-0.200000 -0.502100 -0.039000  0.512000 -0.608000 0.592000
+-0.250000 -0.502100 -0.016400  -0.320000 -0.344000 0.872000
+-0.200000 -0.511900 -0.060900  0.416000 -0.800000 0.424000
+-0.250000 -0.533000 -0.060900  -0.336000 -0.760000 0.544000
+-0.200000 -0.534300 -0.121900  0.456000 -0.832000 0.296000
+-0.250000 -0.552300 -0.101500  -0.080000 -0.904000 0.400000
+-0.235800 -0.552300 -0.121900  0.448000 -0.816000 0.336000
+-0.250000 -0.559400 -0.121900  -0.088000 -0.912000 0.384000
+-0.204600 -0.552300 -0.182900  0.504000 -0.776000 0.360000
+-0.250000 -0.581300 -0.182900  -0.104000 -0.888000 0.440000
+-0.200000 -0.552300 -0.190900  0.520000 -0.768000 0.360000
+-0.250000 -0.602500 -0.226600  0.288000 -0.512000 0.800000
+-0.200000 -0.579600 -0.243900  0.568000 -0.648000 0.496000
+-0.233200 -0.602500 -0.243900  0.608000 -0.320000 0.720000
+-0.200000 -0.602500 -0.268600  0.488000 -0.432000 0.752000
+-0.241600 -0.652700 -0.243900  0.680000 -0.216000 0.688000
+-0.200000 -0.652700 -0.286600  0.488000 -0.272000 0.824000
+-0.250000 -0.679700 -0.243900  0.728000 -0.208000 0.640000
+-0.200000 -0.693500 -0.304800  0.872000 -0.464000 -0.120000
+-0.250000 -0.703000 -0.252700  0.704000 -0.368000 0.600000
+-0.204300 -0.703000 -0.304800  0.856000 -0.496000 -0.088000
+-0.250000 -0.737300 -0.304800  0.568000 -0.808000 -0.112000
+-0.250000 -0.703000 -0.346500  0.432000 -0.280000 -0.848000
+-0.204300 -0.703000 -0.304800  0.856000 -0.496000 -0.088000
+-0.250000 -0.652700 -0.361600  0.240000 -0.216000 -0.944000
+-0.200000 -0.693500 -0.304800  0.872000 -0.464000 -0.120000
+-0.200000 -0.652700 -0.326500  0.488000 -0.272000 -0.824000
+-0.171500 -0.652700 -0.304800  0.576000 -0.304000 0.752000
+-0.200000 -0.693500 -0.304800  0.872000 -0.464000 -0.120000
+-0.200000 -0.652700 -0.286600  0.488000 -0.272000 0.824000
+-0.200000 -0.652700 -0.286600  0.488000 -0.272000 0.824000
+-0.279200 -0.502100 -0.060900  -0.688000 -0.328000 0.640000
+-0.279200 -0.502100 -0.060900  -0.688000 -0.328000 0.640000
+-0.250000 -0.502100 -0.016400  -0.320000 -0.344000 0.872000
+-0.250000 -0.533000 -0.060900  -0.336000 -0.760000 0.544000
+-0.250000 -0.533000 -0.060900  -0.336000 -0.760000 0.544000
+-0.200000 0.351500 -0.009600  0.208000 -0.208000 0.952000
+-0.200000 0.351500 -0.009600  0.208000 -0.208000 0.952000
+-0.250000 0.351500 -0.004200  0.040000 0.000000 0.992000
+-0.200000 0.301200 -0.022600  0.056000 -0.176000 0.976000
+-0.250000 0.301200 -0.005700  0.112000 -0.104000 0.984000
+-0.200000 0.251000 -0.048300  -0.120000 -0.296000 0.944000
+-0.250000 0.251000 -0.029400  0.176000 -0.456000 0.864000
+-0.200000 0.206100 -0.060900  -0.448000 -0.184000 0.872000
+-0.250000 0.219300 -0.060900  0.304000 -0.640000 0.696000
+-0.250000 0.219300 -0.060900  0.304000 -0.640000 0.696000
+-0.200000 -0.351500 -0.031500  -0.320000 -0.128000 0.936000
+-0.200000 -0.351500 -0.031500  -0.320000 -0.128000 0.936000
+-0.250000 -0.351500 -0.038300  0.104000 -0.504000 0.848000
+-0.200000 -0.401700 -0.023400  -0.056000 -0.008000 0.992000
+-0.250000 -0.401700 -0.058800  -0.096000 -0.136000 0.984000
+-0.200000 -0.451900 -0.018000  0.376000 -0.112000 0.912000
+-0.250000 -0.451900 -0.040500  -0.352000 -0.008000 0.928000
+-0.250000 -0.451900 -0.040500  -0.352000 -0.008000 0.928000
+-0.200000 0.150600 -0.023100  -0.360000 0.472000 0.792000
+-0.200000 0.150600 -0.023100  -0.360000 0.472000 0.792000
+-0.200000 0.100400 -0.008800  0.176000 0.488000 0.848000
+-0.150000 0.150600 -0.037800  0.256000 -0.016000 0.960000
+-0.150000 0.100400 -0.027500  0.432000 0.296000 0.848000
+-0.114400 0.150600 -0.060900  0.520000 -0.344000 0.776000
+-0.122500 0.100400 -0.060900  0.768000 -0.048000 0.624000
+-0.100000 0.150600 -0.075000  0.592000 -0.416000 0.688000
+-0.100000 0.100400 -0.099400  0.760000 -0.264000 0.584000
+-0.067900 0.150600 -0.121900  0.736000 -0.432000 0.504000
+-0.089100 0.100400 -0.121900  0.816000 -0.232000 0.520000
+-0.050000 0.150600 -0.159500  0.712000 -0.480000 0.504000
+-0.053800 0.100400 -0.182900  0.984000 -0.072000 0.112000
+-0.050000 0.116900 -0.182900  0.944000 -0.304000 0.048000
+-0.051400 0.100400 -0.243900  0.776000 0.216000 -0.576000
+-0.050000 0.150600 -0.210200  0.840000 -0.208000 -0.496000
+-0.077600 0.150600 -0.243900  0.320000 0.328000 -0.880000
+-0.051400 0.100400 -0.243900  0.776000 0.216000 -0.576000
+-0.100000 0.150600 -0.251000  -0.024000 0.408000 -0.904000
+-0.100000 0.100400 -0.276400  0.032000 0.376000 -0.920000
+-0.126800 0.150600 -0.243900  -0.208000 0.496000 -0.832000
+-0.150000 0.100400 -0.267100  -0.312000 0.440000 -0.832000
+-0.150000 0.141700 -0.243900  -0.352000 0.528000 -0.768000
+-0.198500 0.100400 -0.243900  -0.376000 0.480000 -0.784000
+-0.150000 0.100400 -0.267100  -0.312000 0.440000 -0.832000
+-0.200000 0.099300 -0.243900  -0.456000 0.488000 -0.736000
+-0.150000 0.050200 -0.299600  -0.080000 0.408000 -0.904000
+-0.200000 0.050200 -0.277000  -0.312000 0.416000 -0.848000
+-0.150000 0.040500 -0.304800  -0.136000 0.416000 -0.896000
+-0.200000 0.008900 -0.304800  -0.304000 0.456000 -0.832000
+-0.150000 0.000000 -0.322200  0.064000 0.240000 -0.968000
+-0.200000 0.000000 -0.310700  -0.288000 0.424000 -0.848000
+-0.150000 -0.050200 -0.328000  0.128000 0.064000 -0.984000
+-0.200000 -0.050200 -0.330400  -0.144000 0.264000 -0.944000
+-0.150000 -0.100400 -0.338700  0.056000 -0.088000 -0.992000
+-0.200000 -0.100400 -0.330100  -0.024000 -0.008000 -0.992000
+-0.150000 -0.150600 -0.309500  -0.032000 -0.400000 -0.912000
+-0.200000 -0.150600 -0.333300  0.216000 -0.272000 -0.936000
+-0.200000 -0.100400 -0.330100  -0.024000 -0.008000 -0.992000
+-0.250000 -0.150600 -0.327500  -0.120000 0.152000 -0.976000
+-0.250000 -0.100400 -0.327300  -0.384000 0.152000 -0.904000
+-0.200000 -0.100400 -0.330100  -0.024000 -0.008000 -0.992000
+-0.250000 -0.050200 -0.318700  -0.440000 0.320000 -0.832000
+-0.200000 -0.050200 -0.330400  -0.144000 0.264000 -0.944000
+-0.250000 -0.028200 -0.304800  -0.400000 0.416000 -0.808000
+-0.200000 0.000000 -0.310700  -0.288000 0.424000 -0.848000
+-0.213400 0.000000 -0.304800  -0.304000 0.448000 -0.832000
+-0.200000 0.008900 -0.304800  -0.304000 0.456000 -0.832000
+-0.250000 0.000000 -0.286200  -0.320000 0.712000 -0.616000
+-0.200000 0.050200 -0.277000  -0.312000 0.416000 -0.848000
+-0.250000 0.050200 -0.254100  -0.584000 0.656000 -0.464000
+-0.200000 0.099300 -0.243900  -0.456000 0.488000 -0.736000
+-0.250000 0.055800 -0.243900  -0.560000 0.648000 -0.504000
+-0.250000 0.050200 -0.254100  -0.584000 0.656000 -0.464000
+-0.256300 0.050200 -0.243900  -0.592000 0.624000 -0.488000
+-0.256300 0.050200 -0.243900  -0.592000 0.624000 -0.488000
+-0.200000 -0.502100 -0.039000  0.512000 -0.608000 0.592000
+-0.200000 -0.502100 -0.039000  0.512000 -0.608000 0.592000
+-0.181900 -0.502100 -0.060900  0.504000 -0.680000 0.520000
+-0.200000 -0.511900 -0.060900  0.416000 -0.800000 0.424000
+-0.200000 -0.511900 -0.060900  0.416000 -0.800000 0.424000
+-0.100000 0.401700 -0.042400  0.232000 -0.088000 0.960000
+-0.100000 0.401700 -0.042400  0.232000 -0.088000 0.960000
+-0.150000 0.401700 -0.011900  0.240000 0.256000 0.928000
+-0.100000 0.351500 -0.035500  0.120000 0.000000 0.992000
+-0.150000 0.351500 -0.029900  0.096000 -0.168000 0.976000
+-0.100000 0.301200 -0.032000  0.168000 0.008000 0.984000
+-0.150000 0.301200 -0.033800  0.040000 -0.024000 0.992000
+-0.100000 0.251000 -0.029400  0.344000 -0.104000 0.928000
+-0.150000 0.251000 -0.027500  -0.136000 -0.104000 0.984000
+-0.100000 0.200800 -0.041900  0.456000 -0.304000 0.832000
+-0.150000 0.200800 -0.027500  -0.320000 -0.168000 0.928000
+-0.100000 0.167200 -0.060900  0.520000 -0.424000 0.736000
+-0.150000 0.150600 -0.037800  0.256000 -0.016000 0.960000
+-0.114400 0.150600 -0.060900  0.520000 -0.344000 0.776000
+-0.100000 0.167200 -0.060900  0.520000 -0.424000 0.736000
+-0.100000 0.150600 -0.075000  0.592000 -0.416000 0.688000
+-0.078700 0.200800 -0.060900  0.568000 -0.416000 0.704000
+-0.067900 0.150600 -0.121900  0.736000 -0.432000 0.504000
+-0.050000 0.200800 -0.090500  0.520000 -0.520000 0.672000
+-0.050000 0.170300 -0.121900  0.584000 -0.576000 0.560000
+-0.067900 0.150600 -0.121900  0.736000 -0.432000 0.504000
+-0.050000 0.150600 -0.159500  0.712000 -0.480000 0.504000
+-0.050000 0.150600 -0.159500  0.712000 -0.480000 0.504000
+-0.150000 0.100400 -0.027500  0.432000 0.296000 0.848000
+-0.150000 0.100400 -0.027500  0.432000 0.296000 0.848000
+-0.150000 0.050200 -0.012600  0.624000 0.240000 0.728000
+-0.122500 0.100400 -0.060900  0.768000 -0.048000 0.624000
+-0.123500 0.050200 -0.060900  0.888000 -0.104000 0.440000
+-0.100000 0.100400 -0.099400  0.760000 -0.264000 0.584000
+-0.100700 0.050200 -0.121900  0.856000 0.048000 0.504000
+-0.100000 0.054100 -0.121900  0.816000 -0.176000 0.544000
+-0.100000 0.050200 -0.123300  0.696000 -0.176000 0.688000
+-0.089100 0.100400 -0.121900  0.816000 -0.232000 0.520000
+-0.051100 0.050200 -0.182900  0.712000 0.184000 0.664000
+-0.053800 0.100400 -0.182900  0.984000 -0.072000 0.112000
+-0.050000 0.050200 -0.189300  0.800000 0.488000 0.336000
+-0.051400 0.100400 -0.243900  0.776000 0.216000 -0.576000
+-0.050000 0.095100 -0.243900  0.808000 0.256000 -0.520000
+-0.100000 0.100400 -0.276400  0.032000 0.376000 -0.920000
+-0.050000 0.050200 -0.257500  0.608000 0.208000 -0.760000
+-0.100000 0.050200 -0.292200  0.304000 0.312000 -0.896000
+-0.050000 0.000000 -0.288000  0.256000 0.560000 -0.776000
+-0.100000 0.022400 -0.304800  0.184000 0.304000 -0.928000
+-0.077600 0.000000 -0.304800  0.248000 0.344000 -0.896000
+-0.100000 0.000000 -0.309600  0.168000 0.152000 -0.968000
+-0.050000 -0.015100 -0.304800  0.280000 0.536000 -0.784000
+-0.100000 -0.050200 -0.318600  0.080000 0.144000 -0.984000
+-0.050000 -0.050200 -0.321000  0.120000 0.280000 -0.944000
+-0.100000 -0.100400 -0.323700  -0.040000 -0.152000 -0.984000
+-0.050000 -0.100400 -0.342800  0.056000 -0.032000 -0.992000
+-0.100000 -0.150600 -0.315000  -0.456000 -0.064000 -0.880000
+-0.050000 -0.150600 -0.332400  0.016000 -0.080000 -0.992000
+-0.050000 -0.100400 -0.342800  0.056000 -0.032000 -0.992000
+0.000000 -0.150600 -0.318000  0.160000 0.016000 -0.984000
+0.000000 -0.100400 -0.336000  0.328000 -0.184000 -0.920000
+0.050000 -0.150600 -0.318000  0.352000 0.312000 -0.872000
+0.039400 -0.100400 -0.304800  0.408000 0.224000 -0.880000
+0.050000 -0.119800 -0.304800  0.416000 0.264000 -0.864000
+0.050000 -0.100400 -0.298100  0.360000 0.248000 -0.896000
+0.096000 -0.150600 -0.304800  0.176000 0.336000 -0.920000
+0.100000 -0.100400 -0.298900  0.040000 0.136000 -0.984000
+0.100000 -0.150600 -0.303900  -0.176000 0.088000 -0.976000
+0.114400 -0.100400 -0.304800  -0.344000 0.128000 -0.928000
+0.101900 -0.150600 -0.304800  -0.296000 0.368000 -0.872000
+0.100000 -0.150600 -0.303900  -0.176000 0.088000 -0.976000
+0.100000 -0.151600 -0.304800  -0.176000 0.536000 -0.816000
+0.096000 -0.150600 -0.304800  0.176000 0.336000 -0.920000
+0.096000 -0.150600 -0.304800  0.176000 0.336000 -0.920000
+-0.150000 0.050200 -0.012600  0.624000 0.240000 0.728000
+-0.150000 0.050200 -0.012600  0.624000 0.240000 0.728000
+-0.150000 0.000000 -0.001200  0.744000 0.064000 0.656000
+-0.123500 0.050200 -0.060900  0.888000 -0.104000 0.440000
+-0.120900 0.000000 -0.060900  0.800000 0.080000 0.592000
+-0.100700 0.050200 -0.121900  0.856000 0.048000 0.504000
+-0.100000 0.000000 -0.110200  0.808000 0.176000 0.552000
+-0.100000 0.044900 -0.121900  0.816000 0.112000 0.552000
+-0.089600 0.000000 -0.121900  0.568000 0.512000 0.632000
+-0.100000 0.050200 -0.123300  0.696000 -0.176000 0.688000
+-0.050000 0.000000 -0.158900  0.584000 0.336000 0.728000
+-0.051100 0.050200 -0.182900  0.712000 0.184000 0.664000
+-0.050000 0.047900 -0.182900  0.488000 0.480000 0.720000
+-0.050000 0.050200 -0.189300  0.800000 0.488000 0.336000
+0.000000 0.039200 -0.182900  0.256000 0.544000 0.792000
+0.000000 0.050200 -0.198900  0.168000 0.840000 0.504000
+0.050000 0.005700 -0.182900  0.312000 0.584000 0.744000
+0.046000 0.050200 -0.243900  0.728000 0.480000 -0.472000
+0.050000 0.042300 -0.243900  0.688000 0.376000 -0.616000
+0.000000 0.050200 -0.275900  0.288000 0.416000 -0.856000
+0.050000 0.000000 -0.258500  0.448000 0.256000 -0.848000
+0.000000 0.000000 -0.289100  0.520000 0.272000 -0.800000
+0.050000 -0.050200 -0.279200  0.280000 0.320000 -0.896000
+0.000000 -0.038700 -0.304800  0.368000 0.192000 -0.904000
+0.004800 -0.050200 -0.304800  0.368000 0.176000 -0.904000
+0.000000 -0.050200 -0.306900  0.320000 0.152000 -0.928000
+0.039400 -0.100400 -0.304800  0.408000 0.224000 -0.880000
+0.000000 -0.100400 -0.336000  0.328000 -0.184000 -0.920000
+0.000000 -0.050200 -0.306900  0.320000 0.152000 -0.928000
+-0.050000 -0.100400 -0.342800  0.056000 -0.032000 -0.992000
+-0.050000 -0.050200 -0.321000  0.120000 0.280000 -0.944000
+0.000000 -0.050200 -0.306900  0.320000 0.152000 -0.928000
+-0.050000 -0.015100 -0.304800  0.280000 0.536000 -0.784000
+0.000000 -0.038700 -0.304800  0.368000 0.192000 -0.904000
+-0.050000 0.000000 -0.288000  0.256000 0.560000 -0.776000
+0.000000 0.000000 -0.289100  0.520000 0.272000 -0.800000
+-0.050000 0.050200 -0.257500  0.608000 0.208000 -0.760000
+0.000000 0.050200 -0.275900  0.288000 0.416000 -0.856000
+-0.050000 0.095100 -0.243900  0.808000 0.256000 -0.520000
+0.000000 0.087200 -0.243900  0.456000 0.816000 -0.344000
+-0.050000 0.050200 -0.189300  0.800000 0.488000 0.336000
+0.000000 0.050200 -0.198900  0.168000 0.840000 0.504000
+0.000000 0.087200 -0.243900  0.456000 0.816000 -0.344000
+0.046000 0.050200 -0.243900  0.728000 0.480000 -0.472000
+0.000000 0.050200 -0.275900  0.288000 0.416000 -0.856000
+0.000000 0.050200 -0.275900  0.288000 0.416000 -0.856000
+-0.150000 0.000000 -0.001200  0.744000 0.064000 0.656000
+-0.150000 0.000000 -0.001200  0.744000 0.064000 0.656000
+-0.150000 -0.050200 -0.005700  0.768000 -0.024000 0.632000
+-0.120900 0.000000 -0.060900  0.800000 0.080000 0.592000
+-0.114700 -0.050200 -0.060900  0.632000 0.112000 0.760000
+-0.100000 0.000000 -0.110200  0.808000 0.176000 0.552000
+-0.100000 -0.050200 -0.077100  0.584000 0.232000 0.768000
+-0.089600 0.000000 -0.121900  0.568000 0.512000 0.632000
+-0.050000 -0.050200 -0.098600  0.240000 0.488000 0.832000
+-0.050000 -0.024600 -0.121900  0.296000 0.656000 0.688000
+0.000000 -0.050200 -0.114000  0.064000 0.408000 0.904000
+0.000000 -0.035500 -0.121900  0.072000 0.496000 0.856000
+0.050000 -0.050200 -0.115700  0.016000 0.416000 0.904000
+0.050000 -0.038600 -0.121900  0.000000 0.528000 0.840000
+0.100000 -0.050200 -0.113200  -0.016000 0.464000 0.880000
+0.100000 -0.037100 -0.121900  -0.016000 0.544000 0.832000
+0.150000 -0.050200 -0.113700  0.032000 0.448000 0.888000
+0.150000 -0.036300 -0.121900  0.008000 0.488000 0.864000
+0.100000 -0.037100 -0.121900  -0.016000 0.544000 0.832000
+0.150000 0.000000 -0.166100  -0.096000 0.688000 0.712000
+0.100000 0.000000 -0.179900  0.000000 0.528000 0.840000
+0.150000 0.016800 -0.182900  -0.152000 0.840000 0.520000
+0.100000 0.004900 -0.182900  -0.288000 0.864000 0.400000
+0.150000 0.015400 -0.243900  -0.208000 0.728000 -0.640000
+0.100000 0.000000 -0.203800  -0.256000 0.936000 -0.224000
+0.113100 0.000000 -0.243900  -0.392000 0.768000 -0.496000
+0.100000 -0.005500 -0.243900  -0.184000 0.760000 -0.616000
+0.150000 0.000000 -0.257100  -0.208000 0.552000 -0.800000
+0.100000 -0.050200 -0.272200  -0.136000 0.384000 -0.904000
+0.150000 -0.050200 -0.298400  -0.176000 0.328000 -0.920000
+0.100000 -0.100400 -0.298900  0.040000 0.136000 -0.984000
+0.150000 -0.064700 -0.304800  -0.200000 0.328000 -0.912000
+0.114400 -0.100400 -0.304800  -0.344000 0.128000 -0.928000
+0.114400 -0.100400 -0.304800  -0.344000 0.128000 -0.928000
+-0.150000 -0.050200 -0.005700  0.768000 -0.024000 0.632000
+-0.150000 -0.050200 -0.005700  0.768000 -0.024000 0.632000
+-0.150000 -0.100400 -0.001300  0.848000 0.032000 0.520000
+-0.114700 -0.050200 -0.060900  0.632000 0.112000 0.760000
+-0.104300 -0.100400 -0.060900  0.528000 0.416000 0.728000
+-0.100000 -0.050200 -0.077100  0.584000 0.232000 0.768000
+-0.100000 -0.100400 -0.064700  0.496000 0.416000 0.752000
+-0.050000 -0.050200 -0.098600  0.240000 0.488000 0.832000
+-0.050000 -0.100400 -0.073900  0.136000 0.480000 0.864000
+0.000000 -0.050200 -0.114000  0.064000 0.408000 0.904000
+0.000000 -0.100400 -0.085100  0.096000 0.456000 0.880000
+0.050000 -0.050200 -0.115700  0.016000 0.416000 0.904000
+0.050000 -0.100400 -0.083400  0.000000 0.440000 0.888000
+0.100000 -0.050200 -0.113200  -0.016000 0.464000 0.880000
+0.100000 -0.100400 -0.084200  0.032000 0.360000 0.928000
+0.150000 -0.050200 -0.113700  0.032000 0.448000 0.888000
+0.150000 -0.100400 -0.080500  0.184000 0.336000 0.920000
+0.100000 -0.100400 -0.084200  0.032000 0.360000 0.928000
+0.150000 -0.150600 -0.071000  0.136000 0.176000 0.968000
+0.100000 -0.150600 -0.068400  0.184000 0.416000 0.888000
+0.150000 -0.200800 -0.071800  0.312000 -0.208000 0.920000
+0.100000 -0.170000 -0.060900  0.256000 0.296000 0.912000
+0.130700 -0.200800 -0.060900  0.504000 0.008000 0.856000
+0.150000 -0.200800 -0.071800  0.312000 -0.208000 0.920000
+0.110300 -0.251000 -0.060900  0.504000 -0.760000 0.392000
+0.150000 -0.251000 -0.118100  0.224000 -0.792000 0.560000
+0.150000 -0.251000 -0.118100  0.224000 -0.792000 0.560000
+-0.100000 -0.188700 0.000000  0.176000 0.408000 0.888000
+-0.100000 -0.188700 0.000000  0.176000 0.408000 0.888000
+-0.129500 -0.150600 0.000000  0.416000 0.264000 0.864000
+-0.100000 -0.150600 -0.019000  0.512000 0.456000 0.720000
+-0.100000 -0.150600 -0.019000  0.512000 0.456000 0.720000
+-0.150000 -0.346200 0.000000  -0.392000 -0.160000 0.904000
+-0.150000 -0.346200 0.000000  -0.392000 -0.160000 0.904000
+-0.150000 -0.351500 -0.001100  -0.192000 -0.352000 0.912000
+-0.100000 -0.344900 0.000000  0.072000 -0.528000 0.840000
+-0.100000 -0.351500 -0.005700  0.248000 -0.576000 0.776000
+-0.050000 -0.329200 0.000000  0.264000 -0.624000 0.720000
+-0.050000 -0.351500 -0.027000  0.488000 -0.688000 0.528000
+-0.100000 -0.351500 -0.005700  0.248000 -0.576000 0.776000
+-0.050000 -0.370100 -0.060900  0.592000 -0.672000 0.424000
+-0.100000 -0.401700 -0.044900  0.592000 -0.496000 0.624000
+-0.087700 -0.401700 -0.060900  0.608000 -0.600000 0.504000
+-0.100000 -0.415900 -0.060900  0.680000 -0.544000 0.480000
+-0.054100 -0.401700 -0.121900  0.656000 -0.688000 0.280000
+-0.100000 -0.451900 -0.117700  0.624000 -0.664000 0.392000
+-0.098000 -0.451900 -0.121900  0.712000 -0.680000 0.120000
+-0.100000 -0.453500 -0.121900  0.600000 -0.776000 0.168000
+-0.098100 -0.451900 -0.182900  0.736000 -0.672000 0.032000
+-0.100000 -0.453800 -0.182900  0.696000 -0.712000 0.024000
+-0.094700 -0.451900 -0.243900  0.784000 -0.568000 0.216000
+-0.100000 -0.458900 -0.243900  0.744000 -0.632000 0.192000
+-0.061500 -0.451900 -0.304800  0.928000 -0.352000 0.088000
+-0.100000 -0.502100 -0.283200  0.616000 -0.376000 0.680000
+-0.074100 -0.502100 -0.304800  0.864000 -0.480000 0.112000
+-0.100000 -0.549700 -0.304800  0.696000 -0.392000 0.592000
+-0.100000 -0.502100 -0.325200  0.520000 -0.368000 -0.760000
+-0.101500 -0.552300 -0.304800  0.552000 -0.392000 0.720000
+-0.147100 -0.502100 -0.365800  0.472000 -0.192000 -0.848000
+-0.150000 -0.552300 -0.337600  0.424000 -0.304000 -0.840000
+-0.150000 -0.505900 -0.365800  0.272000 -0.320000 -0.904000
+-0.196100 -0.552300 -0.365800  0.320000 -0.272000 -0.904000
+-0.150000 -0.502100 -0.367300  0.088000 -0.320000 -0.936000
+-0.200000 -0.552300 -0.367100  0.360000 -0.232000 -0.896000
+-0.200000 -0.502100 -0.370700  0.184000 -0.352000 -0.912000
+-0.200000 -0.502100 -0.370700  0.184000 -0.352000 -0.912000
+-0.100000 -0.351500 -0.005700  0.248000 -0.576000 0.776000
+-0.100000 -0.351500 -0.005700  0.248000 -0.576000 0.776000
+-0.150000 -0.351500 -0.001100  -0.192000 -0.352000 0.912000
+-0.100000 -0.401700 -0.044900  0.592000 -0.496000 0.624000
+-0.150000 -0.401700 -0.019000  0.408000 -0.232000 0.880000
+-0.100000 -0.415900 -0.060900  0.680000 -0.544000 0.480000
+-0.150000 -0.451900 -0.041900  0.560000 -0.440000 0.696000
+-0.133200 -0.451900 -0.060900  0.584000 -0.656000 0.464000
+-0.150000 -0.470000 -0.060900  0.568000 -0.552000 0.600000
+-0.100000 -0.451900 -0.117700  0.624000 -0.664000 0.392000
+-0.150000 -0.502100 -0.111600  0.592000 -0.752000 0.280000
+-0.100000 -0.453500 -0.121900  0.600000 -0.776000 0.168000
+-0.146100 -0.502100 -0.121900  0.616000 -0.744000 0.232000
+-0.100000 -0.453800 -0.182900  0.696000 -0.712000 0.024000
+-0.141200 -0.502100 -0.182900  0.696000 -0.688000 0.184000
+-0.100000 -0.458900 -0.243900  0.744000 -0.632000 0.192000
+-0.125700 -0.502100 -0.243900  0.664000 -0.408000 0.624000
+-0.100000 -0.502100 -0.283200  0.616000 -0.376000 0.680000
+-0.150000 -0.530700 -0.243900  0.632000 -0.664000 0.392000
+-0.100000 -0.549700 -0.304800  0.696000 -0.392000 0.592000
+-0.150000 -0.552300 -0.270100  0.544000 -0.504000 0.656000
+-0.101500 -0.552300 -0.304800  0.552000 -0.392000 0.720000
+-0.150000 -0.602500 -0.302600  0.392000 -0.240000 0.880000
+-0.145700 -0.602500 -0.304800  0.824000 -0.528000 0.192000
+-0.150000 -0.609400 -0.304800  0.840000 -0.512000 0.152000
+-0.150000 -0.602500 -0.307600  0.456000 -0.280000 -0.840000
+-0.145700 -0.602500 -0.304800  0.824000 -0.528000 0.192000
+-0.150000 -0.552300 -0.337600  0.424000 -0.304000 -0.840000
+-0.101500 -0.552300 -0.304800  0.552000 -0.392000 0.720000
+-0.101500 -0.552300 -0.304800  0.552000 -0.392000 0.720000
+-0.050000 0.401700 -0.052300  0.176000 0.040000 0.976000
+-0.050000 0.401700 -0.052300  0.176000 0.040000 0.976000
+-0.100000 0.401700 -0.042400  0.232000 -0.088000 0.960000
+-0.050000 0.351500 -0.043600  0.248000 0.032000 0.960000
+-0.100000 0.351500 -0.035500  0.120000 0.000000 0.992000
+-0.050000 0.301200 -0.044600  0.440000 -0.008000 0.896000
+-0.100000 0.301200 -0.032000  0.168000 0.008000 0.984000
+-0.050000 0.251000 -0.047300  0.528000 -0.360000 0.760000
+-0.100000 0.251000 -0.029400  0.344000 -0.104000 0.928000
+-0.050000 0.236000 -0.060900  0.536000 -0.496000 0.672000
+-0.100000 0.200800 -0.041900  0.456000 -0.304000 0.832000
+-0.078700 0.200800 -0.060900  0.568000 -0.416000 0.704000
+-0.100000 0.167200 -0.060900  0.520000 -0.424000 0.736000
+-0.100000 0.167200 -0.060900  0.520000 -0.424000 0.736000
+-0.027600 0.301200 -0.060900  0.456000 -0.208000 0.856000
+-0.027600 0.301200 -0.060900  0.456000 -0.208000 0.856000
+-0.050000 0.301200 -0.044600  0.440000 -0.008000 0.896000
+-0.035000 0.251000 -0.060900  0.512000 -0.448000 0.728000
+-0.050000 0.251000 -0.047300  0.528000 -0.360000 0.760000
+-0.050000 0.236000 -0.060900  0.536000 -0.496000 0.672000
+-0.050000 0.236000 -0.060900  0.536000 -0.496000 0.672000
+-0.002200 -0.301200 0.000000  0.384000 -0.648000 0.648000
+-0.002200 -0.301200 0.000000  0.384000 -0.648000 0.648000
+0.000000 -0.299000 0.000000  0.440000 -0.464000 0.760000
+0.000000 -0.301200 -0.001900  0.408000 -0.704000 0.568000
+0.050000 -0.253500 0.000000  0.448000 -0.608000 0.648000
+0.032200 -0.301200 -0.060900  0.552000 -0.696000 0.448000
+0.050000 -0.286400 -0.060900  0.528000 -0.720000 0.440000
+0.050000 -0.301200 -0.085900  0.528000 -0.704000 0.464000
+0.050000 -0.301200 -0.085900  0.528000 -0.704000 0.464000
+-0.050000 -0.351500 -0.027000  0.488000 -0.688000 0.528000
+-0.050000 -0.351500 -0.027000  0.488000 -0.688000 0.528000
+-0.029100 -0.351500 -0.060900  0.584000 -0.680000 0.424000
+-0.050000 -0.370100 -0.060900  0.592000 -0.672000 0.424000
+0.000000 -0.351500 -0.112600  0.544000 -0.704000 0.448000
+-0.050000 -0.398200 -0.121900  0.592000 -0.704000 0.368000
+0.000000 -0.356400 -0.121900  0.560000 -0.728000 0.384000
+-0.050000 -0.389600 -0.182900  0.656000 -0.736000 -0.128000
+0.000000 -0.353400 -0.182900  0.520000 -0.832000 -0.160000
+-0.050000 -0.380500 -0.243900  0.664000 -0.736000 -0.104000
+0.000000 -0.351500 -0.193300  0.504000 -0.832000 -0.176000
+-0.013800 -0.351500 -0.243900  0.552000 -0.808000 -0.168000
+0.000000 -0.343100 -0.243900  0.464000 -0.864000 -0.160000
+-0.026900 -0.351500 -0.304800  0.608000 -0.688000 -0.384000
+0.000000 -0.336000 -0.304800  0.392000 -0.872000 -0.264000
+-0.050000 -0.351500 -0.336900  0.024000 -0.576000 -0.808000
+0.000000 -0.316900 -0.365800  0.224000 -0.832000 -0.496000
+-0.050000 -0.309800 -0.365800  -0.336000 -0.416000 -0.840000
+0.000000 -0.301200 -0.413400  -0.392000 -0.192000 -0.896000
+-0.050000 -0.301200 -0.370400  -0.392000 -0.264000 -0.872000
+0.000000 -0.251000 -0.386300  -0.352000 0.496000 -0.792000
+-0.050000 -0.266900 -0.365800  -0.288000 0.088000 -0.944000
+-0.044700 -0.251000 -0.365800  -0.216000 0.376000 -0.896000
+-0.050000 -0.251000 -0.364300  -0.216000 0.352000 -0.904000
+0.000000 -0.238800 -0.365800  -0.192000 0.648000 -0.728000
+-0.050000 -0.200800 -0.320900  -0.056000 0.280000 -0.952000
+0.000000 -0.200800 -0.332000  -0.296000 0.528000 -0.784000
+0.000000 -0.238800 -0.365800  -0.192000 0.648000 -0.728000
+0.050000 -0.200800 -0.360800  -0.016000 0.576000 -0.808000
+0.050000 -0.206300 -0.365800  -0.112000 0.608000 -0.776000
+0.000000 -0.238800 -0.365800  -0.192000 0.648000 -0.728000
+0.050000 -0.251000 -0.406500  0.232000 -0.312000 -0.912000
+0.000000 -0.251000 -0.386300  -0.352000 0.496000 -0.792000
+0.050000 -0.301200 -0.369000  0.376000 -0.768000 -0.512000
+0.000000 -0.301200 -0.413400  -0.392000 -0.192000 -0.896000
+0.050000 -0.303000 -0.365800  0.400000 -0.792000 -0.448000
+0.000000 -0.316900 -0.365800  0.224000 -0.832000 -0.496000
+0.050000 -0.326800 -0.304800  0.424000 -0.880000 -0.184000
+0.000000 -0.336000 -0.304800  0.392000 -0.872000 -0.264000
+0.050000 -0.327900 -0.243900  0.480000 -0.872000 0.000000
+0.000000 -0.343100 -0.243900  0.464000 -0.864000 -0.160000
+0.050000 -0.327900 -0.182900  0.552000 -0.824000 0.048000
+0.000000 -0.351500 -0.193300  0.504000 -0.832000 -0.176000
+0.003100 -0.351500 -0.182900  0.504000 -0.840000 -0.160000
+0.000000 -0.353400 -0.182900  0.520000 -0.832000 -0.160000
+0.006400 -0.351500 -0.121900  0.552000 -0.776000 0.288000
+0.000000 -0.356400 -0.121900  0.560000 -0.728000 0.384000
+0.000000 -0.351500 -0.112600  0.544000 -0.704000 0.448000
+0.000000 -0.351500 -0.112600  0.544000 -0.704000 0.448000
+0.000000 0.351500 -0.051600  0.280000 -0.248000 0.920000
+0.000000 0.351500 -0.051600  0.280000 -0.248000 0.920000
+0.000000 0.393800 -0.060900  0.224000 0.176000 0.952000
+0.042100 0.351500 -0.060900  0.160000 -0.080000 0.976000
+0.000000 0.401700 -0.062800  0.256000 0.176000 0.944000
+0.050000 0.351500 -0.062500  0.000000 -0.264000 0.960000
+0.050000 0.401700 -0.062500  -0.008000 0.136000 0.984000
+0.065700 0.351500 -0.060900  -0.064000 -0.312000 0.944000
+0.100000 0.401700 -0.066700  -0.048000 0.000000 0.992000
+0.100000 0.368600 -0.060900  0.104000 0.120000 0.984000
+0.150000 0.401700 -0.062100  -0.392000 -0.400000 0.816000
+0.111400 0.351500 -0.060900  0.184000 -0.224000 0.952000
+0.150000 0.351500 -0.070300  -0.056000 -0.480000 0.872000
+0.100000 0.345700 -0.060900  0.056000 -0.392000 0.912000
+0.150000 0.301200 -0.094700  0.096000 -0.408000 0.904000
+0.100000 0.301200 -0.081200  0.144000 -0.392000 0.904000
+0.150000 0.253300 -0.121900  0.144000 -0.672000 0.712000
+0.100000 0.251000 -0.119300  0.048000 -0.664000 0.736000
+0.134200 0.251000 -0.121900  0.072000 -0.752000 0.648000
+0.100000 0.248700 -0.121900  0.064000 -0.824000 0.552000
+0.150000 0.251000 -0.128300  0.144000 -0.904000 0.392000
+0.100000 0.246100 -0.182900  0.136000 -0.488000 -0.856000
+0.150000 0.224100 -0.182900  0.056000 -0.672000 -0.728000
+0.100000 0.251000 -0.185300  0.160000 -0.296000 -0.936000
+0.150000 0.251000 -0.192500  0.112000 0.024000 -0.992000
+0.100000 0.301200 -0.188500  0.112000 0.128000 -0.984000
+0.150000 0.284700 -0.182900  0.352000 0.368000 -0.856000
+0.133500 0.301200 -0.182900  0.272000 0.264000 -0.920000
+0.150000 0.251000 -0.128300  0.144000 -0.904000 0.392000
+0.150000 0.301200 -0.172900  0.456000 0.432000 -0.768000
+0.134200 0.251000 -0.121900  0.072000 -0.752000 0.648000
+0.150000 0.253300 -0.121900  0.144000 -0.672000 0.712000
+0.150000 0.301200 -0.172900  0.456000 0.432000 -0.768000
+0.200000 0.269500 -0.121900  -0.008000 -0.896000 0.432000
+0.200000 0.301200 -0.179700  -0.152000 -0.352000 -0.920000
+0.250000 0.256500 -0.121900  -0.200000 -0.800000 0.552000
+0.215700 0.301200 -0.182900  -0.120000 -0.160000 -0.976000
+0.250000 0.284000 -0.182900  -0.096000 -0.256000 -0.952000
+0.250000 0.301200 -0.184400  -0.080000 -0.056000 -0.992000
+0.215700 0.301200 -0.182900  -0.120000 -0.160000 -0.976000
+0.250000 0.351500 -0.189100  -0.160000 0.168000 -0.968000
+0.226900 0.351500 -0.182900  -0.224000 0.192000 -0.952000
+0.250000 0.370000 -0.182900  -0.184000 0.304000 -0.928000
+0.200000 0.351500 -0.169700  -0.320000 0.304000 -0.888000
+0.250000 0.401700 -0.172700  -0.016000 0.288000 -0.952000
+0.200000 0.401700 -0.169400  -0.056000 0.168000 -0.976000
+0.250000 0.451900 -0.137900  0.128000 0.536000 -0.824000
+0.200000 0.451900 -0.151000  0.136000 0.400000 -0.896000
+0.250000 0.466900 -0.121900  0.232000 0.968000 0.016000
+0.200000 0.484800 -0.121900  0.312000 0.872000 0.360000
+0.250000 0.451900 -0.094000  0.248000 0.784000 0.552000
+0.200000 0.453000 -0.060900  0.112000 0.728000 0.672000
+0.203100 0.451900 -0.060900  0.264000 0.672000 0.680000
+0.200000 0.451900 -0.059700  0.136000 0.632000 0.760000
+0.250000 0.432000 -0.060900  0.224000 0.624000 0.736000
+0.200000 0.401700 -0.033800  -0.352000 0.000000 0.928000
+0.250000 0.401700 -0.026800  -0.216000 0.176000 0.952000
+0.200000 0.352900 -0.060900  -0.368000 -0.496000 0.776000
+0.250000 0.351500 -0.020200  -0.488000 -0.416000 0.760000
+0.201200 0.351500 -0.060900  -0.488000 -0.576000 0.648000
+0.250000 0.317900 -0.060900  -0.432000 -0.680000 0.584000
+0.200000 0.351500 -0.062100  -0.312000 -0.640000 0.696000
+0.250000 0.301200 -0.083600  -0.096000 -0.744000 0.648000
+0.200000 0.301200 -0.098800  -0.120000 -0.584000 0.800000
+0.250000 0.256500 -0.121900  -0.200000 -0.800000 0.552000
+0.200000 0.269500 -0.121900  -0.008000 -0.896000 0.432000
+0.200000 0.301200 -0.098800  -0.120000 -0.584000 0.800000
+0.150000 0.253300 -0.121900  0.144000 -0.672000 0.712000
+0.150000 0.301200 -0.094700  0.096000 -0.408000 0.904000
+0.200000 0.301200 -0.098800  -0.120000 -0.584000 0.800000
+0.150000 0.351500 -0.070300  -0.056000 -0.480000 0.872000
+0.200000 0.351500 -0.062100  -0.312000 -0.640000 0.696000
+0.150000 0.401700 -0.062100  -0.392000 -0.400000 0.816000
+0.200000 0.352900 -0.060900  -0.368000 -0.496000 0.776000
+0.151400 0.401700 -0.060900  -0.480000 -0.416000 0.760000
+0.200000 0.401700 -0.033800  -0.352000 0.000000 0.928000
+0.150000 0.409600 -0.060900  -0.208000 -0.072000 0.968000
+0.200000 0.451900 -0.059700  0.136000 0.632000 0.760000
+0.150000 0.451900 -0.057100  -0.080000 0.496000 0.856000
+0.200000 0.453000 -0.060900  0.112000 0.728000 0.672000
+0.150000 0.456100 -0.060900  0.048000 0.664000 0.736000
+0.200000 0.484800 -0.121900  0.312000 0.872000 0.360000
+0.150000 0.502100 -0.119700  0.016000 0.656000 0.752000
+0.153400 0.502100 -0.121900  0.448000 0.824000 -0.336000
+0.150000 0.503100 -0.121900  0.272000 0.456000 -0.840000
+0.150000 0.502100 -0.123200  0.032000 0.424000 -0.896000
+0.138500 0.502100 -0.121900  -0.184000 0.952000 -0.216000
+0.150000 0.451900 -0.151900  0.184000 0.376000 -0.904000
+0.100000 0.494400 -0.121900  -0.184000 0.952000 -0.216000
+0.100000 0.451900 -0.146900  -0.088000 0.224000 -0.968000
+0.050000 0.485400 -0.121900  -0.032000 0.904000 -0.408000
+0.050000 0.451900 -0.139600  -0.080000 0.232000 -0.960000
+0.000000 0.493800 -0.121900  0.128000 0.960000 -0.232000
+0.000000 0.451900 -0.135500  0.000000 0.160000 -0.984000
+-0.050000 0.500300 -0.121900  -0.104000 0.896000 -0.424000
+-0.050000 0.451900 -0.137500  0.040000 0.112000 -0.992000
+-0.100000 0.479800 -0.121900  -0.288000 0.584000 -0.752000
+-0.100000 0.451900 -0.142300  -0.128000 0.312000 -0.936000
+-0.150000 0.453400 -0.121900  -0.320000 0.624000 -0.704000
+-0.150000 0.451900 -0.123200  -0.344000 0.512000 -0.784000
+-0.152100 0.451900 -0.121900  -0.424000 0.536000 -0.720000
+-0.150000 0.401700 -0.148200  -0.240000 0.400000 -0.872000
+-0.200000 0.409200 -0.121900  -0.400000 0.464000 -0.776000
+-0.200000 0.401700 -0.127400  -0.400000 0.440000 -0.800000
+-0.208300 0.401700 -0.121900  -0.432000 0.432000 -0.784000
+-0.200000 0.351500 -0.146000  -0.416000 0.224000 -0.872000
+-0.233300 0.351500 -0.121900  -0.616000 0.184000 -0.752000
+-0.200000 0.301200 -0.154100  -0.392000 0.112000 -0.904000
+-0.245300 0.301200 -0.121900  -0.680000 0.120000 -0.720000
+-0.200000 0.251000 -0.156200  -0.432000 0.168000 -0.880000
+-0.250000 0.268200 -0.121900  -0.464000 0.088000 -0.872000
+-0.250000 0.251000 -0.124000  -0.376000 0.088000 -0.920000
+-0.254200 0.251000 -0.121900  -0.384000 0.088000 -0.912000
+-0.250000 0.200800 -0.129700  -0.392000 0.152000 -0.904000
+-0.263400 0.200800 -0.121900  -0.480000 0.216000 -0.840000
+-0.250000 0.150600 -0.154100  -0.464000 0.344000 -0.808000
+-0.295300 0.150600 -0.121900  -0.728000 0.520000 -0.432000
+-0.250000 0.100400 -0.182000  -0.504000 0.488000 -0.704000
+-0.300000 0.144000 -0.121900  -0.728000 0.496000 -0.456000
+-0.300000 0.100400 -0.141500  -0.560000 0.512000 -0.640000
+-0.250000 0.100400 -0.182000  -0.504000 0.488000 -0.704000
+-0.300000 0.052000 -0.182900  -0.664000 0.464000 -0.568000
+-0.250000 0.099600 -0.182900  -0.488000 0.616000 -0.608000
+-0.250000 0.100400 -0.182000  -0.504000 0.488000 -0.704000
+-0.249100 0.100400 -0.182900  -0.576000 0.496000 -0.640000
+-0.250000 0.150600 -0.154100  -0.464000 0.344000 -0.808000
+-0.216700 0.150600 -0.182900  -0.560000 0.376000 -0.728000
+-0.250000 0.200800 -0.129700  -0.392000 0.152000 -0.904000
+-0.200000 0.172600 -0.182900  -0.488000 0.416000 -0.760000
+-0.200000 0.200800 -0.161600  -0.480000 0.384000 -0.776000
+-0.173800 0.200800 -0.182900  -0.480000 0.344000 -0.800000
+-0.200000 0.251000 -0.156200  -0.432000 0.168000 -0.880000
+-0.153800 0.251000 -0.182900  -0.312000 0.176000 -0.928000
+-0.200000 0.301200 -0.154100  -0.392000 0.112000 -0.904000
+-0.150000 0.257900 -0.182900  -0.288000 0.168000 -0.936000
+-0.150000 0.301200 -0.169700  -0.080000 0.248000 -0.960000
+-0.100000 0.273500 -0.182900  -0.112000 0.208000 -0.968000
+-0.100000 0.301200 -0.172200  -0.168000 0.416000 -0.888000
+-0.058500 0.301200 -0.182900  -0.128000 0.320000 -0.936000
+-0.100000 0.351500 -0.158200  0.008000 0.264000 -0.960000
+-0.050000 0.304700 -0.182900  -0.120000 0.336000 -0.928000
+-0.050000 0.351500 -0.155800  -0.048000 0.328000 -0.936000
+0.000000 0.313300 -0.182900  -0.064000 0.304000 -0.944000
+0.000000 0.351500 -0.164900  -0.080000 0.368000 -0.920000
+0.050000 0.327400 -0.182900  -0.016000 0.344000 -0.936000
+0.050000 0.351500 -0.166400  0.000000 0.392000 -0.912000
+0.100000 0.320500 -0.182900  0.096000 0.312000 -0.936000
+0.100000 0.351500 -0.169000  0.056000 0.272000 -0.952000
+0.133500 0.301200 -0.182900  0.272000 0.264000 -0.920000
+0.150000 0.351500 -0.160600  0.144000 0.128000 -0.976000
+0.150000 0.301200 -0.172900  0.456000 0.432000 -0.768000
+0.200000 0.351500 -0.169700  -0.320000 0.304000 -0.888000
+0.200000 0.301200 -0.179700  -0.152000 -0.352000 -0.920000
+0.226900 0.351500 -0.182900  -0.224000 0.192000 -0.952000
+0.215700 0.301200 -0.182900  -0.120000 -0.160000 -0.976000
+0.215700 0.301200 -0.182900  -0.120000 -0.160000 -0.976000
+0.000000 0.351500 -0.051600  0.280000 -0.248000 0.920000
+0.000000 0.351500 -0.051600  0.280000 -0.248000 0.920000
+0.042100 0.351500 -0.060900  0.160000 -0.080000 0.976000
+0.000000 0.334500 -0.060900  0.312000 -0.368000 0.864000
+0.050000 0.351500 -0.062500  0.000000 -0.264000 0.960000
+0.000000 0.301200 -0.076500  0.296000 -0.272000 0.904000
+0.050000 0.301200 -0.074400  0.160000 -0.248000 0.952000
+0.000000 0.251000 -0.086600  0.344000 -0.360000 0.864000
+0.050000 0.251000 -0.100200  0.224000 -0.464000 0.848000
+0.000000 0.211400 -0.121900  0.496000 -0.712000 0.480000
+0.050000 0.230600 -0.121900  0.312000 -0.824000 0.464000
+0.000000 0.200800 -0.169000  0.576000 -0.744000 0.320000
+0.050000 0.219300 -0.182900  0.280000 -0.632000 -0.712000
+0.008500 0.200800 -0.182900  0.416000 -0.688000 -0.584000
+0.050000 0.251000 -0.200200  0.040000 -0.232000 -0.968000
+0.000000 0.200800 -0.186400  0.272000 -0.456000 -0.840000
+0.000000 0.251000 -0.201400  0.024000 -0.152000 -0.984000
+-0.050000 0.200800 -0.204500  0.304000 -0.328000 -0.888000
+-0.050000 0.251000 -0.205600  -0.136000 0.216000 -0.960000
+-0.100000 0.200800 -0.221500  0.056000 0.392000 -0.912000
+-0.100000 0.251000 -0.188700  -0.192000 0.256000 -0.944000
+-0.150000 0.200800 -0.199200  -0.328000 0.272000 -0.896000
+-0.150000 0.251000 -0.184400  -0.280000 0.168000 -0.936000
+-0.173800 0.200800 -0.182900  -0.480000 0.344000 -0.800000
+-0.153800 0.251000 -0.182900  -0.312000 0.176000 -0.928000
+-0.150000 0.251000 -0.184400  -0.280000 0.168000 -0.936000
+-0.150000 0.257900 -0.182900  -0.288000 0.168000 -0.936000
+-0.100000 0.251000 -0.188700  -0.192000 0.256000 -0.944000
+-0.100000 0.273500 -0.182900  -0.112000 0.208000 -0.968000
+-0.050000 0.251000 -0.205600  -0.136000 0.216000 -0.960000
+-0.058500 0.301200 -0.182900  -0.128000 0.320000 -0.936000
+-0.050000 0.301200 -0.184300  -0.112000 0.296000 -0.944000
+-0.050000 0.304700 -0.182900  -0.120000 0.336000 -0.928000
+0.000000 0.301200 -0.186500  -0.056000 0.232000 -0.968000
+0.000000 0.313300 -0.182900  -0.064000 0.304000 -0.944000
+0.050000 0.301200 -0.192400  0.024000 0.192000 -0.976000
+0.050000 0.327400 -0.182900  -0.016000 0.344000 -0.936000
+0.100000 0.301200 -0.188500  0.112000 0.128000 -0.984000
+0.100000 0.320500 -0.182900  0.096000 0.312000 -0.936000
+0.133500 0.301200 -0.182900  0.272000 0.264000 -0.920000
+0.133500 0.301200 -0.182900  0.272000 0.264000 -0.920000
+0.000000 -0.301200 -0.001900  0.408000 -0.704000 0.568000
+0.000000 -0.301200 -0.001900  0.408000 -0.704000 0.568000
+0.032200 -0.301200 -0.060900  0.552000 -0.696000 0.448000
+0.000000 -0.326800 -0.060900  0.344000 -0.824000 0.432000
+0.000000 -0.326800 -0.060900  0.344000 -0.824000 0.432000
+0.065700 0.351500 -0.060900  -0.064000 -0.312000 0.944000
+0.065700 0.351500 -0.060900  -0.064000 -0.312000 0.944000
+0.100000 0.368600 -0.060900  0.104000 0.120000 0.984000
+0.100000 0.351500 -0.058100  0.120000 -0.240000 0.960000
+0.111400 0.351500 -0.060900  0.184000 -0.224000 0.952000
+0.100000 0.345700 -0.060900  0.056000 -0.392000 0.912000
+0.100000 0.351500 -0.058100  0.120000 -0.240000 0.960000
+0.065700 0.351500 -0.060900  -0.064000 -0.312000 0.944000
+0.100000 0.345700 -0.060900  0.056000 -0.392000 0.912000
+0.050000 0.351500 -0.062500  0.000000 -0.264000 0.960000
+0.100000 0.301200 -0.081200  0.144000 -0.392000 0.904000
+0.050000 0.301200 -0.074400  0.160000 -0.248000 0.952000
+0.100000 0.251000 -0.119300  0.048000 -0.664000 0.736000
+0.050000 0.251000 -0.100200  0.224000 -0.464000 0.848000
+0.100000 0.248700 -0.121900  0.064000 -0.824000 0.552000
+0.050000 0.230600 -0.121900  0.312000 -0.824000 0.464000
+0.100000 0.246100 -0.182900  0.136000 -0.488000 -0.856000
+0.050000 0.219300 -0.182900  0.280000 -0.632000 -0.712000
+0.100000 0.251000 -0.185300  0.160000 -0.296000 -0.936000
+0.050000 0.251000 -0.200200  0.040000 -0.232000 -0.968000
+0.100000 0.301200 -0.188500  0.112000 0.128000 -0.984000
+0.050000 0.301200 -0.192400  0.024000 0.192000 -0.976000
+0.050000 0.251000 -0.200200  0.040000 -0.232000 -0.968000
+0.000000 0.301200 -0.186500  -0.056000 0.232000 -0.968000
+0.000000 0.251000 -0.201400  0.024000 -0.152000 -0.984000
+-0.050000 0.301200 -0.184300  -0.112000 0.296000 -0.944000
+-0.050000 0.251000 -0.205600  -0.136000 0.216000 -0.960000
+-0.050000 0.251000 -0.205600  -0.136000 0.216000 -0.960000
+0.150000 0.456100 -0.060900  0.048000 0.664000 0.736000
+0.150000 0.456100 -0.060900  0.048000 0.664000 0.736000
+0.150000 0.451900 -0.057100  -0.080000 0.496000 0.856000
+0.121900 0.451900 -0.060900  -0.112000 0.472000 0.872000
+0.150000 0.409600 -0.060900  -0.208000 -0.072000 0.968000
+0.100000 0.451900 -0.066700  -0.192000 0.072000 0.976000
+0.150000 0.401700 -0.062100  -0.392000 -0.400000 0.816000
+0.100000 0.401700 -0.066700  -0.048000 0.000000 0.992000
+0.100000 0.451900 -0.066700  -0.192000 0.072000 0.976000
+0.050000 0.401700 -0.062500  -0.008000 0.136000 0.984000
+0.050000 0.451900 -0.077800  0.016000 0.408000 0.912000
+0.000000 0.401700 -0.062800  0.256000 0.176000 0.944000
+0.000000 0.451900 -0.081100  0.280000 0.456000 0.832000
+-0.005200 0.401700 -0.060900  0.264000 0.168000 0.944000
+-0.023600 0.451900 -0.060900  0.376000 0.152000 0.904000
+0.000000 0.451900 -0.081100  0.280000 0.456000 0.832000
+-0.033200 0.502100 -0.060900  0.616000 0.496000 0.600000
+0.000000 0.493800 -0.121900  0.128000 0.960000 -0.232000
+-0.050000 0.502100 -0.117100  -0.040000 0.912000 -0.392000
+-0.050000 0.500300 -0.121900  -0.104000 0.896000 -0.424000
+-0.100000 0.502100 -0.081300  -0.184000 0.840000 -0.488000
+-0.100000 0.479800 -0.121900  -0.288000 0.584000 -0.752000
+-0.100000 0.479800 -0.121900  -0.288000 0.584000 -0.752000
+0.350000 0.302200 -0.060900  -0.144000 -0.624000 0.760000
+0.350000 0.302200 -0.060900  -0.144000 -0.624000 0.760000
+0.300000 0.310700 -0.060900  -0.072000 -0.760000 0.640000
+0.350000 0.351500 -0.021800  0.032000 -0.048000 0.992000
+0.300000 0.351500 -0.009100  -0.016000 -0.144000 0.984000
+0.300000 0.351500 -0.009100  -0.016000 -0.144000 0.984000
+0.395100 0.251000 -0.060900  -0.344000 -0.184000 0.912000
+0.395100 0.251000 -0.060900  -0.344000 -0.184000 0.912000
+0.400000 0.251000 -0.058700  -0.328000 -0.176000 0.920000
+0.400000 0.242400 -0.060900  -0.352000 -0.192000 0.904000
+0.400000 0.242400 -0.060900  -0.352000 -0.192000 0.904000
+0.450000 0.401700 -0.038900  -0.120000 0.592000 0.784000
+0.450000 0.401700 -0.038900  -0.120000 0.592000 0.784000
+0.500000 0.401700 -0.057700  0.096000 0.864000 0.480000
+0.450000 0.414500 -0.060900  0.192000 0.928000 0.304000
+0.500000 0.403100 -0.060900  0.112000 0.944000 0.280000
+0.450000 0.422200 -0.121900  0.368000 0.832000 -0.392000
+0.500000 0.401700 -0.069300  0.168000 0.952000 -0.216000
+0.488600 0.401700 -0.121900  0.504000 0.776000 -0.368000
+0.450000 0.422200 -0.121900  0.368000 0.832000 -0.392000
+0.450000 0.401700 -0.160800  0.376000 0.656000 -0.640000
+0.450000 0.401700 -0.160800  0.376000 0.656000 -0.640000
+0.460500 0.150600 -0.060900  -0.624000 -0.512000 0.584000
+0.460500 0.150600 -0.060900  -0.624000 -0.512000 0.584000
+0.500000 0.150600 -0.020200  -0.704000 -0.472000 0.520000
+0.500000 0.107000 -0.060900  -0.608000 -0.480000 0.616000
+0.500000 0.107000 -0.060900  -0.608000 -0.480000 0.616000
+0.500000 0.000000 -0.045100  -0.376000 -0.208000 0.896000
+0.500000 0.000000 -0.045100  -0.376000 -0.208000 0.896000
+0.500000 0.050200 -0.057700  -0.560000 0.128000 0.816000
+0.478700 0.000000 -0.060900  -0.440000 -0.008000 0.888000
+0.495100 0.050200 -0.060900  -0.456000 0.136000 0.872000
+0.450000 0.000000 -0.073300  -0.344000 -0.088000 0.928000
+0.450000 0.050200 -0.077000  -0.360000 0.120000 0.920000
+0.400000 0.000000 -0.102200  -0.272000 0.176000 0.936000
+0.400000 0.050200 -0.114800  -0.552000 0.256000 0.784000
+0.351500 0.000000 -0.121900  -0.376000 0.528000 0.752000
+0.393200 0.050200 -0.121900  -0.648000 0.352000 0.664000
+0.350000 0.000000 -0.123200  -0.512000 0.592000 0.608000
+0.357200 0.050200 -0.182900  -0.736000 0.640000 0.184000
+0.350000 0.043300 -0.182900  -0.488000 0.704000 0.504000
+0.351400 0.050200 -0.243900  -0.480000 0.768000 -0.416000
+0.350000 0.049300 -0.243900  -0.512000 0.784000 -0.320000
+0.350000 0.043300 -0.182900  -0.488000 0.704000 0.504000
+0.300000 0.032100 -0.243900  -0.576000 0.680000 -0.432000
+0.300000 0.018000 -0.182900  -0.296000 0.768000 0.552000
+0.350000 0.043300 -0.182900  -0.488000 0.704000 0.504000
+0.300000 0.000000 -0.166100  -0.488000 0.464000 0.728000
+0.350000 0.000000 -0.123200  -0.512000 0.592000 0.608000
+0.300000 -0.050200 -0.130700  -0.504000 0.472000 0.720000
+0.350000 -0.001200 -0.121900  -0.472000 0.472000 0.736000
+0.307700 -0.050200 -0.121900  -0.592000 0.464000 0.648000
+0.350000 -0.050200 -0.093300  -0.312000 0.392000 0.856000
+0.300000 -0.060700 -0.121900  -0.512000 0.456000 0.720000
+0.350000 -0.100400 -0.081200  -0.280000 0.032000 0.952000
+0.300000 -0.100400 -0.098900  -0.360000 0.344000 0.856000
+0.350000 -0.150600 -0.101500  0.088000 -0.352000 0.928000
+0.300000 -0.150600 -0.090800  0.240000 -0.024000 0.968000
+0.350000 -0.182300 -0.121900  -0.032000 -0.520000 0.848000
+0.300000 -0.200800 -0.101500  0.424000 -0.216000 0.872000
+0.329200 -0.200800 -0.121900  0.376000 -0.264000 0.880000
+0.300000 -0.234400 -0.121900  0.104000 -0.472000 0.872000
+0.350000 -0.200800 -0.137500  0.248000 -0.232000 0.936000
+0.300000 -0.251000 -0.132800  -0.224000 -0.464000 0.856000
+0.350000 -0.234100 -0.121900  0.384000 0.224000 0.888000
+0.328900 -0.251000 -0.121900  -0.264000 -0.304000 0.912000
+0.350000 -0.251000 -0.114600  0.576000 -0.200000 0.784000
+0.350000 -0.260400 -0.121900  0.448000 -0.472000 0.752000
+0.354900 -0.251000 -0.121900  0.704000 -0.304000 0.632000
+0.350000 -0.251000 -0.114600  0.576000 -0.200000 0.784000
+0.350000 -0.234100 -0.121900  0.384000 0.224000 0.888000
+0.354900 -0.251000 -0.121900  0.704000 -0.304000 0.632000
+0.350000 -0.200800 -0.137500  0.248000 -0.232000 0.936000
+0.400000 -0.203000 -0.121900  -0.184000 -0.672000 0.712000
+0.391400 -0.200800 -0.121900  -0.176000 -0.648000 0.736000
+0.400000 -0.200800 -0.119100  -0.200000 -0.688000 0.688000
+0.350000 -0.182300 -0.121900  -0.032000 -0.520000 0.848000
+0.400000 -0.150600 -0.068400  -0.344000 -0.312000 0.880000
+0.350000 -0.150600 -0.101500  0.088000 -0.352000 0.928000
+0.400000 -0.100400 -0.080400  -0.024000 0.176000 0.976000
+0.350000 -0.100400 -0.081200  -0.280000 0.032000 0.952000
+0.400000 -0.050200 -0.089900  -0.128000 0.176000 0.968000
+0.350000 -0.050200 -0.093300  -0.312000 0.392000 0.856000
+0.400000 0.000000 -0.102200  -0.272000 0.176000 0.936000
+0.350000 -0.001200 -0.121900  -0.472000 0.472000 0.736000
+0.351500 0.000000 -0.121900  -0.376000 0.528000 0.752000
+0.350000 0.000000 -0.123200  -0.512000 0.592000 0.608000
+0.350000 0.000000 -0.123200  -0.512000 0.592000 0.608000
+0.478700 0.000000 -0.060900  -0.440000 -0.008000 0.888000
+0.478700 0.000000 -0.060900  -0.440000 -0.008000 0.888000
+0.500000 0.000000 -0.045100  -0.376000 -0.208000 0.896000
+0.500000 -0.026100 -0.060900  -0.336000 -0.328000 0.872000
+0.550000 0.000000 -0.046900  0.008000 -0.120000 0.992000
+0.550000 -0.046200 -0.060900  -0.104000 -0.168000 0.976000
+0.600000 0.000000 -0.044900  -0.016000 -0.720000 0.688000
+0.600000 -0.012300 -0.060900  0.104000 -0.576000 0.800000
+0.550000 -0.046200 -0.060900  -0.104000 -0.168000 0.976000
+0.600000 -0.050200 -0.088500  0.448000 -0.400000 0.792000
+0.550000 -0.050200 -0.061500  -0.064000 -0.152000 0.984000
+0.600000 -0.100400 -0.077400  0.584000 0.048000 0.800000
+0.550000 -0.100400 -0.076900  0.056000 0.056000 0.992000
+0.550000 -0.050200 -0.061500  -0.064000 -0.152000 0.984000
+0.500000 -0.100400 -0.086800  -0.048000 0.256000 0.960000
+0.500000 -0.050200 -0.068900  -0.136000 -0.144000 0.976000
+0.450000 -0.100400 -0.078400  -0.088000 0.200000 0.968000
+0.450000 -0.050200 -0.086300  -0.128000 -0.040000 0.984000
+0.400000 -0.100400 -0.080400  -0.024000 0.176000 0.976000
+0.400000 -0.050200 -0.089900  -0.128000 0.176000 0.968000
+0.450000 -0.050200 -0.086300  -0.128000 -0.040000 0.984000
+0.400000 0.000000 -0.102200  -0.272000 0.176000 0.936000
+0.450000 0.000000 -0.073300  -0.344000 -0.088000 0.928000
+0.450000 -0.050200 -0.086300  -0.128000 -0.040000 0.984000
+0.478700 0.000000 -0.060900  -0.440000 -0.008000 0.888000
+0.500000 -0.050200 -0.068900  -0.136000 -0.144000 0.976000
+0.500000 -0.026100 -0.060900  -0.336000 -0.328000 0.872000
+0.550000 -0.050200 -0.061500  -0.064000 -0.152000 0.984000
+0.550000 -0.046200 -0.060900  -0.104000 -0.168000 0.976000
+0.550000 -0.046200 -0.060900  -0.104000 -0.168000 0.976000
+0.500000 0.401700 -0.057700  0.096000 0.864000 0.480000
+0.500000 0.401700 -0.057700  0.096000 0.864000 0.480000
+0.500000 0.403100 -0.060900  0.112000 0.944000 0.280000
+0.517100 0.401700 -0.060900  0.080000 0.968000 0.224000
+0.500000 0.401700 -0.069300  0.168000 0.952000 -0.216000
+0.500000 0.401700 -0.069300  0.168000 0.952000 -0.216000
+0.500000 0.266900 0.000000  -0.760000 -0.040000 0.640000
+0.500000 0.266900 0.000000  -0.760000 -0.040000 0.640000
+0.500800 0.251000 0.000000  -0.792000 -0.016000 0.608000
+0.500000 0.251000 -0.000900  -0.496000 0.112000 0.856000
+0.500000 0.251000 -0.000900  -0.496000 0.112000 0.856000
+0.500000 0.050200 -0.057700  -0.560000 0.128000 0.816000
+0.500000 0.050200 -0.057700  -0.560000 0.128000 0.816000
+0.500000 0.000000 -0.045100  -0.376000 -0.208000 0.896000
+0.550000 0.050200 -0.037800  -0.320000 -0.688000 0.640000
+0.550000 0.000000 -0.046900  0.008000 -0.120000 0.992000
+0.600000 0.050200 -0.005300  -0.440000 -0.752000 0.480000
+0.600000 0.000000 -0.044900  -0.016000 -0.720000 0.688000
+0.600000 0.000000 -0.044900  -0.016000 -0.720000 0.688000
+0.550000 0.104000 0.000000  -0.664000 -0.568000 0.464000
+0.550000 0.104000 0.000000  -0.664000 -0.568000 0.464000
+0.553100 0.100400 0.000000  -0.664000 -0.576000 0.464000
+0.550000 0.100400 -0.005700  -0.672000 -0.576000 0.448000
+0.550000 0.100400 -0.005700  -0.672000 -0.576000 0.448000
+0.550000 -0.200800 -0.034900  0.016000 -0.040000 0.992000
+0.550000 -0.200800 -0.034900  0.016000 -0.040000 0.992000
+0.600000 -0.200800 -0.056500  0.336000 0.448000 0.816000
+0.550000 -0.159500 -0.060900  0.248000 0.472000 0.840000
+0.600000 -0.194800 -0.060900  0.352000 0.496000 0.784000
+0.550000 -0.150600 -0.067100  0.240000 0.480000 0.840000
+0.600000 -0.150600 -0.093600  0.304000 0.568000 0.752000
+0.600000 -0.194800 -0.060900  0.352000 0.496000 0.784000
+0.650000 -0.150600 -0.116200  0.720000 0.480000 0.488000
+0.608400 -0.200800 -0.060900  0.360000 0.488000 0.792000
+0.650000 -0.200800 -0.092600  0.656000 0.384000 0.640000
+0.650000 -0.242600 -0.060900  0.392000 0.384000 0.824000
+0.677400 -0.200800 -0.121900  0.528000 0.512000 0.672000
+0.657600 -0.251000 -0.060900  0.456000 -0.072000 0.880000
+0.700000 -0.217500 -0.121900  0.616000 0.552000 0.544000
+0.700000 -0.251000 -0.086700  0.608000 0.464000 0.632000
+0.719200 -0.251000 -0.121900  0.760000 0.456000 0.440000
+0.700000 -0.301200 -0.068800  0.336000 0.392000 0.848000
+0.750000 -0.297400 -0.121900  0.656000 0.584000 0.464000
+0.750000 -0.301200 -0.116500  0.704000 0.400000 0.568000
+0.752700 -0.301200 -0.121900  0.792000 0.344000 0.488000
+0.750000 -0.351500 -0.097900  0.640000 0.048000 0.760000
+0.775700 -0.351500 -0.121900  0.600000 0.328000 0.720000
+0.750000 -0.401700 -0.115900  -0.264000 -0.344000 0.896000
+0.800000 -0.391100 -0.121900  0.384000 0.416000 0.816000
+0.800000 -0.401700 -0.115500  0.392000 0.184000 0.896000
+0.810500 -0.401700 -0.121900  0.456000 0.104000 0.872000
+0.800000 -0.418600 -0.121900  0.304000 -0.320000 0.888000
+0.850000 -0.401700 -0.151500  0.608000 0.552000 0.560000
+0.800000 -0.451900 -0.135400  0.168000 -0.384000 0.904000
+0.850000 -0.451900 -0.123600  0.328000 0.296000 0.888000
+0.800000 -0.502100 -0.171200  -0.360000 -0.648000 0.664000
+0.850000 -0.502100 -0.142100  -0.224000 -0.520000 0.816000
+0.800000 -0.511100 -0.182900  -0.376000 -0.744000 0.544000
+0.850000 -0.533300 -0.182900  -0.416000 -0.736000 0.528000
+0.800000 -0.519900 -0.243900  -0.400000 -0.904000 -0.112000
+0.850000 -0.540400 -0.243900  -0.360000 -0.768000 -0.512000
+0.800000 -0.502100 -0.293400  -0.120000 -0.840000 -0.520000
+0.850000 -0.504700 -0.304800  -0.096000 -0.664000 -0.736000
+0.832800 -0.502100 -0.304800  -0.104000 -0.544000 -0.824000
+0.850000 -0.502100 -0.307100  0.032000 -0.240000 -0.968000
+0.850000 -0.490600 -0.304800  0.216000 0.112000 -0.968000
+0.856800 -0.502100 -0.304800  0.288000 0.144000 -0.944000
+0.850000 -0.451900 -0.293100  0.448000 0.248000 -0.848000
+0.900000 -0.502100 -0.284600  -0.008000 -0.096000 -0.992000
+0.900000 -0.451900 -0.272400  0.368000 0.408000 -0.824000
+0.950000 -0.502100 -0.277800  0.272000 0.288000 -0.912000
+0.950000 -0.451900 -0.300000  0.488000 0.464000 -0.728000
+1.000000 -0.502100 -0.271100  0.392000 0.584000 -0.696000
+0.980700 -0.451900 -0.243900  0.752000 0.648000 0.032000
+1.000000 -0.475100 -0.243900  0.736000 0.608000 -0.280000
+0.950000 -0.451900 -0.206400  0.504000 0.736000 0.440000
+1.000000 -0.502100 -0.189300  0.760000 0.568000 0.296000
+0.950000 -0.463500 -0.182900  0.464000 0.672000 0.568000
+0.998000 -0.502100 -0.182900  0.528000 0.664000 0.520000
+0.950000 -0.502100 -0.136000  -0.296000 0.400000 0.864000
+1.000000 -0.503200 -0.182900  0.400000 0.704000 0.576000
+0.950000 -0.531200 -0.121900  -0.376000 0.368000 0.840000
+1.000000 -0.544400 -0.121900  0.360000 0.712000 0.592000
+0.950000 -0.552300 -0.115100  -0.432000 -0.368000 0.816000
+1.000000 -0.552300 -0.111000  0.040000 -0.024000 0.992000
+0.950000 -0.560000 -0.121900  -0.400000 -0.536000 0.728000
+1.000000 -0.602500 -0.115100  -0.504000 -0.464000 0.712000
+0.992300 -0.602500 -0.121900  -0.520000 -0.480000 0.696000
+1.000000 -0.611000 -0.121900  -0.528000 -0.480000 0.696000
+0.950000 -0.602500 -0.169200  -0.536000 -0.520000 0.656000
+1.000000 -0.652700 -0.168000  -0.488000 -0.568000 0.656000
+0.950000 -0.619400 -0.182900  -0.632000 -0.592000 0.480000
+0.983200 -0.652700 -0.182900  -0.528000 -0.608000 0.584000
+0.950000 -0.619400 -0.243900  -0.600000 -0.584000 -0.536000
+0.979500 -0.652700 -0.243900  -0.672000 -0.664000 -0.304000
+0.950000 -0.602500 -0.260200  -0.544000 -0.504000 -0.664000
+1.000000 -0.652700 -0.268800  -0.592000 -0.512000 -0.608000
+0.990600 -0.602500 -0.304800  -0.488000 -0.376000 -0.784000
+1.000000 -0.614600 -0.304800  -0.488000 -0.376000 -0.776000
+1.000000 -0.602500 -0.311200  -0.448000 -0.336000 -0.816000
+0.990600 -0.602500 -0.304800  -0.488000 -0.376000 -0.784000
+1.000000 -0.552300 -0.319800  -0.248000 0.216000 -0.936000
+0.953900 -0.552300 -0.304800  -0.328000 0.312000 -0.888000
+1.000000 -0.525900 -0.304800  -0.248000 0.496000 -0.824000
+0.950000 -0.552300 -0.303200  -0.304000 0.392000 -0.864000
+1.000000 -0.502100 -0.271100  0.392000 0.584000 -0.696000
+0.950000 -0.502100 -0.277800  0.272000 0.288000 -0.912000
+0.950000 -0.552300 -0.303200  -0.304000 0.392000 -0.864000
+0.900000 -0.502100 -0.284600  -0.008000 -0.096000 -0.992000
+0.900000 -0.552300 -0.278500  -0.424000 -0.592000 -0.672000
+0.856800 -0.502100 -0.304800  0.288000 0.144000 -0.944000
+0.868400 -0.552300 -0.243900  -0.552000 -0.760000 -0.328000
+0.850000 -0.504700 -0.304800  -0.096000 -0.664000 -0.736000
+0.850000 -0.540400 -0.243900  -0.360000 -0.768000 -0.512000
+0.868400 -0.552300 -0.243900  -0.552000 -0.760000 -0.328000
+0.850000 -0.533300 -0.182900  -0.416000 -0.736000 0.528000
+0.876500 -0.552300 -0.182900  -0.528000 -0.672000 0.504000
+0.850000 -0.502100 -0.142100  -0.224000 -0.520000 0.816000
+0.900000 -0.552300 -0.159100  -0.496000 -0.592000 0.632000
+0.900000 -0.502100 -0.123800  -0.168000 -0.208000 0.960000
+0.940600 -0.552300 -0.121900  -0.512000 -0.272000 0.808000
+0.950000 -0.502100 -0.136000  -0.296000 0.400000 0.864000
+0.950000 -0.531200 -0.121900  -0.376000 0.368000 0.840000
+0.940600 -0.552300 -0.121900  -0.512000 -0.272000 0.808000
+0.950000 -0.552300 -0.115100  -0.432000 -0.368000 0.816000
+0.950000 -0.560000 -0.121900  -0.400000 -0.536000 0.728000
+0.940600 -0.552300 -0.121900  -0.512000 -0.272000 0.808000
+0.950000 -0.602500 -0.169200  -0.536000 -0.520000 0.656000
+0.900000 -0.552300 -0.159100  -0.496000 -0.592000 0.632000
+0.935000 -0.602500 -0.182900  -0.552000 -0.552000 0.608000
+0.900000 -0.573700 -0.182900  -0.608000 -0.704000 0.344000
+0.933200 -0.602500 -0.243900  -0.584000 -0.624000 -0.512000
+0.900000 -0.578300 -0.243900  -0.552000 -0.704000 -0.440000
+0.950000 -0.602500 -0.260200  -0.544000 -0.504000 -0.664000
+0.900000 -0.552300 -0.278500  -0.424000 -0.592000 -0.672000
+0.950000 -0.552300 -0.303200  -0.304000 0.392000 -0.864000
+0.950000 -0.602500 -0.260200  -0.544000 -0.504000 -0.664000
+0.953900 -0.552300 -0.304800  -0.328000 0.312000 -0.888000
+0.990600 -0.602500 -0.304800  -0.488000 -0.376000 -0.784000
+0.990600 -0.602500 -0.304800  -0.488000 -0.376000 -0.784000
+0.550000 -0.242100 -0.060900  -0.400000 -0.536000 0.736000
+0.550000 -0.242100 -0.060900  -0.400000 -0.536000 0.736000
+0.550000 -0.200800 -0.034900  0.016000 -0.040000 0.992000
+0.562800 -0.251000 -0.060900  -0.368000 -0.568000 0.720000
+0.600000 -0.200800 -0.056500  0.336000 0.448000 0.816000
+0.600000 -0.251000 -0.042400  -0.104000 -0.208000 0.968000
+0.608400 -0.200800 -0.060900  0.360000 0.488000 0.792000
+0.650000 -0.251000 -0.056300  0.424000 -0.024000 0.896000
+0.650000 -0.242600 -0.060900  0.392000 0.384000 0.824000
+0.657600 -0.251000 -0.060900  0.456000 -0.072000 0.880000
+0.650000 -0.251000 -0.056300  0.424000 -0.024000 0.896000
+0.650000 -0.258100 -0.060900  0.392000 -0.456000 0.792000
+0.600000 -0.251000 -0.042400  -0.104000 -0.208000 0.968000
+0.600000 -0.272000 -0.060900  -0.264000 -0.632000 0.720000
+0.562800 -0.251000 -0.060900  -0.368000 -0.568000 0.720000
+0.600000 -0.301200 -0.098800  -0.176000 -0.576000 0.792000
+0.550000 -0.251000 -0.069700  -0.416000 -0.584000 0.688000
+0.552600 -0.301200 -0.121900  -0.368000 -0.384000 0.840000
+0.550000 -0.300100 -0.121900  -0.624000 -0.616000 0.472000
+0.550000 -0.301200 -0.123600  -0.624000 -0.440000 0.632000
+0.552600 -0.301200 -0.121900  -0.368000 -0.384000 0.840000
+0.550000 -0.317100 -0.121900  -0.368000 0.064000 0.920000
+0.600000 -0.333000 -0.121900  0.024000 -0.312000 0.944000
+0.558500 -0.351500 -0.121900  0.208000 -0.648000 0.728000
+0.600000 -0.351500 -0.136300  0.144000 -0.792000 0.584000
+0.550000 -0.353000 -0.121900  -0.032000 -0.832000 0.536000
+0.600000 -0.392700 -0.182900  -0.184000 -0.752000 0.624000
+0.550000 -0.389500 -0.182900  -0.304000 -0.784000 0.528000
+0.600000 -0.401700 -0.203000  -0.208000 -0.872000 0.432000
+0.550000 -0.401700 -0.218900  -0.128000 -0.904000 0.392000
+0.600000 -0.414700 -0.243900  -0.184000 -0.936000 0.272000
+0.550000 -0.409700 -0.243900  -0.144000 -0.944000 0.272000
+0.600000 -0.422100 -0.304800  -0.120000 -0.768000 -0.616000
+0.550000 -0.415900 -0.304800  -0.192000 -0.848000 -0.480000
+0.600000 -0.401700 -0.327900  -0.024000 -0.544000 -0.832000
+0.550000 -0.401700 -0.333700  -0.144000 -0.688000 -0.704000
+0.600000 -0.351500 -0.337900  0.040000 -0.080000 -0.992000
+0.550000 -0.351500 -0.364500  0.120000 -0.104000 -0.984000
+0.600000 -0.301200 -0.352300  -0.528000 -0.312000 -0.776000
+0.550000 -0.316300 -0.304800  -0.472000 0.688000 -0.536000
+0.567500 -0.301200 -0.304800  -0.696000 0.400000 -0.584000
+0.550000 -0.301200 -0.279200  -0.712000 0.120000 -0.680000
+0.550000 -0.272400 -0.304800  -0.680000 -0.440000 -0.576000
+0.550000 -0.272400 -0.304800  -0.680000 -0.440000 -0.576000
+0.616700 0.401700 0.000000  0.496000 0.864000 -0.032000
+0.616700 0.401700 0.000000  0.496000 0.864000 -0.032000
+0.650000 0.368200 0.000000  0.792000 0.584000 -0.144000
+0.600000 0.401700 -0.057700  0.168000 0.920000 -0.344000
+0.650000 0.351500 -0.057700  0.800000 0.552000 -0.208000
+0.600000 0.400600 -0.060900  -0.072000 0.912000 -0.384000
+0.648900 0.351500 -0.060900  0.576000 0.600000 -0.544000
+0.600000 0.351500 -0.101600  0.448000 0.496000 -0.736000
+0.650000 0.350500 -0.060900  0.712000 0.536000 -0.440000
+0.600000 0.310600 -0.121900  0.480000 0.424000 -0.760000
+0.650000 0.301200 -0.100800  0.528000 0.504000 -0.672000
+0.608400 0.301200 -0.121900  0.448000 0.488000 -0.744000
+0.600000 0.310600 -0.121900  0.480000 0.424000 -0.760000
+0.600000 0.301200 -0.128700  0.472000 0.520000 -0.704000
+0.600000 0.301200 -0.128700  0.472000 0.520000 -0.704000
+0.648900 0.351500 -0.060900  0.576000 0.600000 -0.544000
+0.648900 0.351500 -0.060900  0.576000 0.600000 -0.544000
+0.650000 0.350500 -0.060900  0.712000 0.536000 -0.440000
+0.650000 0.351500 -0.057700  0.800000 0.552000 -0.208000
+0.680100 0.301200 -0.060900  0.752000 0.544000 -0.368000
+0.660900 0.351500 0.000000  0.832000 0.512000 -0.176000
+0.685300 0.301200 0.000000  0.832000 0.536000 -0.104000
+0.680100 0.301200 -0.060900  0.752000 0.544000 -0.368000
+0.700000 0.279600 0.000000  0.792000 0.600000 -0.048000
+0.700000 0.278700 -0.060900  0.648000 0.584000 -0.472000
+0.700000 0.278700 -0.060900  0.648000 0.584000 -0.472000
+0.600000 -0.194800 -0.060900  0.352000 0.496000 0.784000
+0.600000 -0.194800 -0.060900  0.352000 0.496000 0.784000
+0.608400 -0.200800 -0.060900  0.360000 0.488000 0.792000
+0.600000 -0.200800 -0.056500  0.336000 0.448000 0.816000
+0.600000 -0.200800 -0.056500  0.336000 0.448000 0.816000
+0.650000 0.368200 0.000000  0.792000 0.584000 -0.144000
+0.650000 0.368200 0.000000  0.792000 0.584000 -0.144000
+0.650000 0.351500 -0.057700  0.800000 0.552000 -0.208000
+0.660900 0.351500 0.000000  0.832000 0.512000 -0.176000
+0.660900 0.351500 0.000000  0.832000 0.512000 -0.176000
+0.650000 0.000000 -0.040500  0.104000 -0.944000 0.296000
+0.650000 0.000000 -0.040500  0.104000 -0.944000 0.296000
+0.686800 0.000000 -0.060900  0.208000 -0.960000 0.144000
+0.650000 -0.010200 -0.060900  0.168000 -0.784000 0.592000
+0.698200 0.000000 -0.121900  0.296000 -0.952000 0.032000
+0.650000 -0.033500 -0.121900  0.512000 -0.672000 0.520000
+0.687300 0.000000 -0.182900  0.648000 -0.600000 -0.456000
+0.650000 -0.048900 -0.182900  0.792000 -0.584000 0.152000
+0.653800 0.000000 -0.243900  0.576000 -0.112000 -0.808000
+0.650000 -0.016900 -0.243900  0.704000 -0.184000 -0.672000
+0.650000 -0.048900 -0.182900  0.792000 -0.584000 0.152000
+0.637200 -0.050200 -0.243900  0.840000 -0.080000 -0.528000
+0.649100 -0.050200 -0.182900  0.816000 -0.544000 0.144000
+0.650000 -0.048900 -0.182900  0.792000 -0.584000 0.152000
+0.638000 -0.050200 -0.121900  0.800000 -0.536000 0.256000
+0.650000 -0.033500 -0.121900  0.512000 -0.672000 0.520000
+0.650000 -0.033500 -0.121900  0.512000 -0.672000 0.520000
+0.800000 -0.015400 0.000000  -0.560000 -0.800000 0.184000
+0.800000 -0.015400 0.000000  -0.560000 -0.800000 0.184000
+0.772100 0.000000 0.000000  -0.504000 -0.832000 0.224000
+0.800000 -0.024700 -0.060900  -0.616000 -0.776000 0.088000
+0.753100 0.000000 -0.060900  -0.472000 -0.872000 0.000000
+0.800000 -0.027900 -0.121900  -0.664000 -0.736000 -0.072000
+0.756600 0.000000 -0.121900  -0.496000 -0.856000 -0.080000
+0.800000 -0.017800 -0.182900  -0.616000 -0.680000 -0.376000
+0.776700 0.000000 -0.182900  -0.576000 -0.728000 -0.360000
+0.800000 0.000000 -0.217200  -0.656000 -0.464000 -0.584000
+0.800000 0.000000 -0.217200  -0.656000 -0.464000 -0.584000
+0.900000 0.131100 0.000000  0.480000 0.848000 0.192000
+0.900000 0.131100 0.000000  0.480000 0.848000 0.192000
+0.950000 0.102000 0.000000  0.472000 0.864000 0.120000
+0.900000 0.143500 -0.060900  0.528000 0.808000 -0.240000
+0.950000 0.106300 -0.060900  0.576000 0.776000 -0.240000
+0.900000 0.127900 -0.121900  0.560000 0.776000 -0.264000
+0.950000 0.100400 -0.078300  0.560000 0.768000 -0.304000
+0.931600 0.100400 -0.121900  0.600000 0.744000 -0.272000
+0.950000 0.086300 -0.121900  0.544000 0.784000 -0.280000
+0.912000 0.100400 -0.182900  0.600000 0.704000 -0.360000
+0.950000 0.069900 -0.182900  0.544000 0.736000 -0.392000
+0.900000 0.100400 -0.203200  0.536000 0.688000 -0.472000
+0.950000 0.050200 -0.224500  0.472000 0.712000 -0.504000
+0.900000 0.070800 -0.243900  -0.096000 0.744000 -0.656000
+0.929600 0.050200 -0.243900  0.432000 0.672000 -0.584000
+0.900000 0.050200 -0.268900  0.208000 0.672000 -0.696000
+0.950000 0.037500 -0.243900  0.432000 0.688000 -0.576000
+0.900000 0.016700 -0.304800  -0.152000 0.720000 -0.664000
+0.950000 0.000000 -0.291100  0.424000 0.536000 -0.720000
+0.927400 0.000000 -0.304800  0.400000 0.560000 -0.720000
+0.950000 -0.016600 -0.304800  0.448000 0.520000 -0.720000
+0.900000 0.000000 -0.329500  -0.080000 0.648000 -0.744000
+0.950000 -0.050200 -0.338500  0.440000 0.400000 -0.800000
+0.900000 -0.050200 -0.348300  -0.256000 0.192000 -0.944000
+0.950000 -0.100400 -0.351000  0.336000 0.064000 -0.936000
+0.900000 -0.100400 -0.341700  -0.464000 -0.104000 -0.872000
+0.950000 -0.150600 -0.345500  -0.032000 0.064000 -0.992000
+0.900000 -0.150600 -0.332000  -0.672000 -0.328000 -0.656000
+0.900000 -0.150600 -0.332000  -0.672000 -0.328000 -0.656000
+0.995800 -0.200800 0.000000  -0.648000 -0.704000 0.264000
+0.995800 -0.200800 0.000000  -0.648000 -0.704000 0.264000
+0.950000 -0.168100 0.000000  -0.640000 -0.744000 0.184000
+0.973000 -0.200800 -0.060900  -0.584000 -0.760000 0.264000
+0.950000 -0.183700 -0.060900  -0.632000 -0.728000 0.232000
+0.950500 -0.200800 -0.121900  -0.632000 -0.744000 0.192000
+0.950000 -0.200400 -0.121900  -0.720000 -0.672000 0.136000
+0.950000 -0.200800 -0.124000  -0.680000 -0.712000 0.160000
+0.950000 -0.200800 -0.124000  -0.680000 -0.712000 0.160000
+-0.910500 0.251000 -0.121900  0.344000 0.880000 -0.304000
+-0.910500 0.251000 -0.121900  0.344000 0.880000 -0.304000
+-0.900000 0.246900 -0.121900  0.360000 0.872000 -0.304000
+-0.900000 0.251000 -0.101700  0.376000 0.896000 -0.216000
+-0.900000 0.251000 -0.101700  0.376000 0.896000 -0.216000
+-0.900000 -0.502100 -0.104000  -0.752000 0.000000 0.656000
+-0.900000 -0.502100 -0.104000  -0.752000 0.000000 0.656000
+-0.900000 -0.511500 -0.121900  -0.520000 -0.664000 0.528000
+-0.906100 -0.502100 -0.121900  -0.920000 0.072000 0.376000
+-0.900000 -0.542100 -0.182900  -0.808000 -0.560000 0.136000
+-0.925200 -0.502100 -0.182900  -0.976000 -0.008000 0.208000
+-0.900000 -0.551700 -0.243900  -0.808000 -0.568000 -0.120000
+-0.929300 -0.502100 -0.243900  -0.992000 0.064000 -0.008000
+-0.900000 -0.539600 -0.304800  -0.720000 -0.488000 -0.480000
+-0.920600 -0.502100 -0.304800  -0.888000 -0.288000 -0.344000
+-0.900000 -0.502100 -0.352600  -0.672000 0.128000 -0.720000
+-0.900000 -0.539600 -0.304800  -0.720000 -0.488000 -0.480000
+-0.864000 -0.502100 -0.365800  -0.304000 0.480000 -0.816000
+-0.891900 -0.552300 -0.304800  -0.800000 -0.568000 -0.136000
+-0.860100 -0.552300 -0.365800  -0.680000 -0.432000 -0.584000
+-0.850000 -0.602000 -0.304800  -0.640000 -0.736000 -0.184000
+-0.850000 -0.564700 -0.365800  -0.608000 -0.528000 -0.584000
+-0.849200 -0.602500 -0.304800  -0.536000 -0.720000 -0.432000
+-0.806700 -0.602500 -0.365800  -0.520000 -0.656000 -0.536000
+-0.800000 -0.636000 -0.304800  -0.536000 -0.792000 -0.272000
+-0.800000 -0.607700 -0.365800  -0.488000 -0.640000 -0.584000
+-0.750000 -0.652200 -0.304800  -0.040000 -0.952000 -0.288000
+-0.750000 -0.628000 -0.365800  -0.232000 -0.808000 -0.528000
+-0.734200 -0.652700 -0.304800  -0.024000 -0.976000 -0.192000
+-0.700000 -0.639000 -0.365800  -0.040000 -0.920000 -0.376000
+-0.700000 -0.652700 -0.309000  0.024000 -0.952000 -0.296000
+-0.650000 -0.641900 -0.365800  -0.024000 -0.952000 -0.280000
+-0.688500 -0.652700 -0.304800  0.080000 -0.992000 -0.064000
+-0.650000 -0.650400 -0.304800  0.048000 -0.992000 0.096000
+-0.700000 -0.652700 -0.298900  0.056000 -0.976000 0.184000
+-0.650000 -0.641500 -0.243900  0.040000 -0.976000 0.168000
+-0.700000 -0.645500 -0.243900  -0.008000 -0.984000 0.160000
+-0.650000 -0.630900 -0.182900  0.008000 -0.968000 0.232000
+-0.700000 -0.633400 -0.182900  -0.064000 -0.960000 0.248000
+-0.650000 -0.615500 -0.121900  -0.008000 -0.952000 0.304000
+-0.700000 -0.614700 -0.121900  -0.136000 -0.888000 0.424000
+-0.650000 -0.602500 -0.069700  -0.072000 -0.800000 0.584000
+-0.700000 -0.602500 -0.083600  -0.192000 -0.680000 0.704000
+-0.650000 -0.594800 -0.060900  -0.368000 -0.640000 0.664000
+-0.700000 -0.552300 -0.082500  -0.736000 -0.280000 0.608000
+-0.685200 -0.552300 -0.060900  -0.696000 -0.384000 0.592000
+-0.700000 -0.507800 -0.060900  -0.864000 -0.200000 0.448000
+-0.700000 -0.507800 -0.060900  -0.864000 -0.200000 0.448000
+-0.868200 -0.552300 -0.121900  -0.520000 -0.224000 0.816000
+-0.868200 -0.552300 -0.121900  -0.520000 -0.224000 0.816000
+-0.850000 -0.552300 -0.082300  -0.704000 -0.480000 0.504000
+-0.850000 -0.569100 -0.121900  -0.488000 -0.776000 0.384000
+-0.800000 -0.552300 -0.095900  0.424000 0.264000 0.864000
+-0.800000 -0.584500 -0.121900  -0.288000 -0.544000 0.776000
+-0.750000 -0.552300 -0.119400  0.072000 0.512000 0.848000
+-0.764000 -0.602500 -0.121900  -0.176000 -0.816000 0.544000
+-0.750000 -0.602500 -0.116200  -0.176000 -0.808000 0.544000
+-0.750000 -0.605000 -0.121900  -0.152000 -0.872000 0.456000
+-0.700000 -0.602500 -0.083600  -0.192000 -0.680000 0.704000
+-0.700000 -0.614700 -0.121900  -0.136000 -0.888000 0.424000
+-0.750000 -0.605000 -0.121900  -0.152000 -0.872000 0.456000
+-0.700000 -0.633400 -0.182900  -0.064000 -0.960000 0.248000
+-0.750000 -0.630100 -0.182900  -0.144000 -0.912000 0.360000
+-0.700000 -0.645500 -0.243900  -0.008000 -0.984000 0.160000
+-0.750000 -0.646000 -0.243900  -0.088000 -0.984000 0.144000
+-0.700000 -0.652700 -0.298900  0.056000 -0.976000 0.184000
+-0.750000 -0.652200 -0.304800  -0.040000 -0.952000 -0.288000
+-0.734200 -0.652700 -0.304800  -0.024000 -0.976000 -0.192000
+-0.700000 -0.652700 -0.298900  0.056000 -0.976000 0.184000
+-0.700000 -0.653800 -0.304800  0.056000 -0.992000 -0.080000
+-0.688500 -0.652700 -0.304800  0.080000 -0.992000 -0.064000
+-0.700000 -0.652700 -0.309000  0.024000 -0.952000 -0.296000
+-0.700000 -0.653800 -0.304800  0.056000 -0.992000 -0.080000
+-0.734200 -0.652700 -0.304800  -0.024000 -0.976000 -0.192000
+-0.734200 -0.652700 -0.304800  -0.024000 -0.976000 -0.192000
+-0.804300 0.200800 -0.121900  0.384000 0.872000 -0.288000
+-0.804300 0.200800 -0.121900  0.384000 0.872000 -0.288000
+-0.800000 0.198900 -0.121900  0.384000 0.872000 -0.288000
+-0.800000 0.200800 -0.113900  0.392000 0.880000 -0.256000
+-0.800000 0.200800 -0.113900  0.392000 0.880000 -0.256000
+-0.762700 -0.401700 -0.060900  -0.840000 -0.496000 0.168000
+-0.762700 -0.401700 -0.060900  -0.840000 -0.496000 0.168000
+-0.771000 -0.401700 -0.121900  -0.872000 -0.456000 0.128000
+-0.750000 -0.426100 -0.060900  -0.864000 -0.448000 0.200000
+-0.750000 -0.448400 -0.121900  -0.880000 -0.432000 0.160000
+-0.735400 -0.451900 -0.060900  -0.768000 -0.512000 0.360000
+-0.748200 -0.451900 -0.121900  -0.880000 -0.440000 0.160000
+-0.701200 -0.502100 -0.060900  -0.816000 -0.416000 0.392000
+-0.723300 -0.502100 -0.121900  -0.896000 -0.224000 0.368000
+-0.748200 -0.451900 -0.121900  -0.880000 -0.440000 0.160000
+-0.749300 -0.502100 -0.182900  -0.920000 -0.232000 0.288000
+-0.750000 -0.451900 -0.133400  -0.896000 -0.392000 0.184000
+-0.750000 -0.499500 -0.182900  -0.936000 -0.200000 0.264000
+-0.757600 -0.451900 -0.182900  -0.952000 -0.232000 0.184000
+-0.750000 -0.502100 -0.184800  -0.496000 0.696000 0.496000
+-0.769800 -0.451900 -0.243900  -0.952000 -0.080000 0.272000
+-0.800000 -0.502100 -0.227500  0.432000 0.824000 0.352000
+-0.800000 -0.496000 -0.243900  0.424000 0.840000 0.320000
+-0.820300 -0.502100 -0.182900  0.496000 0.792000 0.344000
+-0.850000 -0.480800 -0.243900  0.376000 0.912000 0.152000
+-0.850000 -0.490700 -0.182900  0.328000 0.896000 0.288000
+-0.896800 -0.451900 -0.243900  0.600000 0.776000 0.136000
+-0.900000 -0.462200 -0.182900  0.320000 0.888000 0.304000
+-0.900000 -0.451900 -0.229200  0.512000 0.832000 0.168000
+-0.896800 -0.451900 -0.243900  0.600000 0.776000 0.136000
+-0.900000 -0.449600 -0.243900  0.496000 0.856000 0.136000
+-0.891000 -0.451900 -0.304800  0.528000 0.824000 -0.192000
+-0.900000 -0.446300 -0.304800  0.160000 0.912000 -0.360000
+-0.900000 -0.451900 -0.318500  0.104000 0.872000 -0.464000
+-0.912200 -0.451900 -0.304800  -0.496000 0.720000 -0.464000
+-0.900000 -0.446300 -0.304800  0.160000 0.912000 -0.360000
+-0.921000 -0.451900 -0.243900  -0.184000 0.968000 0.160000
+-0.900000 -0.449600 -0.243900  0.496000 0.856000 0.136000
+-0.900000 -0.451900 -0.229200  0.512000 0.832000 0.168000
+-0.900000 -0.451900 -0.229200  0.512000 0.832000 0.168000
+-0.700000 -0.602500 -0.083600  -0.192000 -0.680000 0.704000
+-0.700000 -0.602500 -0.083600  -0.192000 -0.680000 0.704000
+-0.750000 -0.602500 -0.116200  -0.176000 -0.808000 0.544000
+-0.700000 -0.552300 -0.082500  -0.736000 -0.280000 0.608000
+-0.750000 -0.552300 -0.119400  0.072000 0.512000 0.848000
+-0.750000 -0.552300 -0.119400  0.072000 0.512000 0.848000
+-0.650000 -0.594800 -0.060900  -0.368000 -0.640000 0.664000
+-0.650000 -0.594800 -0.060900  -0.368000 -0.640000 0.664000
+-0.650000 -0.602500 -0.069700  -0.072000 -0.800000 0.584000
+-0.600000 -0.601900 -0.060900  -0.072000 -0.808000 0.568000
+-0.600000 -0.602500 -0.062100  -0.056000 -0.816000 0.560000
+-0.550000 -0.588500 -0.060900  0.224000 -0.888000 0.384000
+-0.550000 -0.602500 -0.100200  0.256000 -0.912000 0.288000
+-0.500000 -0.570000 -0.060900  0.480000 -0.800000 0.328000
+-0.531000 -0.602500 -0.121900  0.248000 -0.920000 0.272000
+-0.500000 -0.589900 -0.121900  0.408000 -0.832000 0.352000
+-0.500000 -0.602500 -0.155300  0.000000 -0.920000 0.376000
+-0.531000 -0.602500 -0.121900  0.248000 -0.920000 0.272000
+-0.500000 -0.610400 -0.182900  -0.136000 -0.936000 0.304000
+-0.550000 -0.606400 -0.121900  0.192000 -0.952000 0.216000
+-0.550000 -0.618800 -0.182900  0.168000 -0.944000 0.272000
+-0.600000 -0.616000 -0.121900  0.080000 -0.960000 0.256000
+-0.600000 -0.629300 -0.182900  0.072000 -0.968000 0.224000
+-0.650000 -0.615500 -0.121900  -0.008000 -0.952000 0.304000
+-0.650000 -0.630900 -0.182900  0.008000 -0.968000 0.232000
+-0.600000 -0.629300 -0.182900  0.072000 -0.968000 0.224000
+-0.650000 -0.641500 -0.243900  0.040000 -0.976000 0.168000
+-0.600000 -0.640700 -0.243900  0.080000 -0.976000 0.192000
+-0.650000 -0.650400 -0.304800  0.048000 -0.992000 0.096000
+-0.600000 -0.650800 -0.304800  0.064000 -0.992000 0.000000
+-0.650000 -0.641900 -0.365800  -0.024000 -0.952000 -0.280000
+-0.600000 -0.645500 -0.365800  0.016000 -0.968000 -0.216000
+-0.650000 -0.621300 -0.426800  -0.080000 -0.904000 -0.400000
+-0.600000 -0.630300 -0.426800  -0.072000 -0.944000 -0.312000
+-0.600000 -0.645500 -0.365800  0.016000 -0.968000 -0.216000
+-0.550000 -0.626200 -0.426800  0.144000 -0.960000 -0.232000
+-0.550000 -0.637200 -0.365800  0.152000 -0.968000 -0.168000
+-0.500000 -0.621400 -0.426800  0.072000 -0.968000 -0.232000
+-0.500000 -0.633000 -0.365800  -0.088000 -0.968000 -0.200000
+-0.450000 -0.629300 -0.426800  -0.048000 -0.904000 -0.416000
+-0.450000 -0.645700 -0.365800  -0.144000 -0.904000 -0.392000
+-0.400000 -0.621700 -0.426800  0.392000 -0.856000 -0.304000
+-0.405700 -0.652700 -0.365800  -0.144000 -0.920000 -0.344000
+-0.400000 -0.652700 -0.368100  -0.128000 -0.872000 -0.456000
+-0.400000 -0.652700 -0.368100  -0.128000 -0.872000 -0.456000
+-0.650000 -0.602500 -0.069700  -0.072000 -0.800000 0.584000
+-0.650000 -0.602500 -0.069700  -0.072000 -0.800000 0.584000
+-0.650000 -0.615500 -0.121900  -0.008000 -0.952000 0.304000
+-0.600000 -0.602500 -0.062100  -0.056000 -0.816000 0.560000
+-0.600000 -0.616000 -0.121900  0.080000 -0.960000 0.256000
+-0.550000 -0.602500 -0.100200  0.256000 -0.912000 0.288000
+-0.550000 -0.606400 -0.121900  0.192000 -0.952000 0.216000
+-0.531000 -0.602500 -0.121900  0.248000 -0.920000 0.272000
+-0.531000 -0.602500 -0.121900  0.248000 -0.920000 0.272000
+-0.554400 -0.050200 -0.060900  0.944000 0.280000 0.128000
+-0.554400 -0.050200 -0.060900  0.944000 0.280000 0.128000
+-0.586600 -0.050200 -0.121900  0.872000 0.224000 -0.424000
+-0.550000 -0.066800 -0.060900  0.944000 0.320000 -0.008000
+-0.578300 -0.100400 -0.121900  0.848000 0.312000 -0.424000
+-0.550000 -0.100400 -0.079500  0.552000 0.552000 -0.616000
+-0.550000 -0.145600 -0.121900  0.512000 0.792000 -0.312000
+-0.578300 -0.100400 -0.121900  0.848000 0.312000 -0.424000
+-0.550000 -0.150600 -0.142400  0.376000 0.896000 -0.200000
+-0.594100 -0.100400 -0.182900  0.816000 0.296000 -0.480000
+-0.561800 -0.150600 -0.182900  0.544000 0.784000 -0.280000
+-0.550000 -0.150600 -0.142400  0.376000 0.896000 -0.200000
+-0.550000 -0.155500 -0.182900  0.296000 0.920000 -0.232000
+-0.550000 -0.155500 -0.182900  0.296000 0.920000 -0.232000
+-0.452400 -0.100400 -0.060900  -0.344000 0.936000 -0.016000
+-0.452400 -0.100400 -0.060900  -0.344000 0.936000 -0.016000
+-0.450000 -0.100400 -0.065100  -0.512000 0.824000 -0.200000
+-0.450000 -0.099400 -0.060900  -0.760000 0.616000 0.160000
+-0.450000 -0.099400 -0.060900  -0.760000 0.616000 0.160000
+-0.450000 -0.512800 -0.060900  0.208000 -0.760000 0.608000
+-0.450000 -0.512800 -0.060900  0.208000 -0.760000 0.608000
+-0.478800 -0.552300 -0.060900  0.704000 -0.592000 0.376000
+-0.450000 -0.549200 -0.121900  -0.080000 -0.800000 0.584000
+-0.452200 -0.552300 -0.121900  0.864000 0.184000 0.464000
+-0.450000 -0.552300 -0.127200  0.616000 -0.144000 0.768000
+-0.450000 -0.549200 -0.121900  -0.080000 -0.800000 0.584000
+-0.440600 -0.552300 -0.121900  -0.264000 -0.768000 0.568000
+-0.450000 -0.512800 -0.060900  0.208000 -0.760000 0.608000
+-0.400000 -0.552300 -0.100200  0.624000 -0.512000 0.584000
+-0.400000 -0.527700 -0.060900  0.080000 -0.768000 0.624000
+-0.393200 -0.552300 -0.121900  0.872000 -0.352000 0.320000
+-0.380200 -0.502100 -0.060900  0.648000 -0.616000 0.432000
+-0.350000 -0.503000 -0.121900  0.232000 -0.880000 0.400000
+-0.350000 -0.502100 -0.119400  0.240000 -0.864000 0.424000
+-0.380200 -0.502100 -0.060900  0.648000 -0.616000 0.432000
+-0.350000 -0.453900 -0.060900  0.248000 -0.624000 0.728000
+-0.350000 -0.453900 -0.060900  0.248000 -0.624000 0.728000
+-0.450000 -0.602500 -0.084100  -0.232000 -0.736000 0.624000
+-0.450000 -0.602500 -0.084100  -0.232000 -0.736000 0.624000
+-0.450000 -0.558900 -0.121900  0.808000 0.320000 0.488000
+-0.410500 -0.602500 -0.121900  0.456000 -0.632000 0.616000
+-0.450000 -0.552300 -0.127200  0.616000 -0.144000 0.768000
+-0.400000 -0.602500 -0.131300  0.560000 -0.576000 0.584000
+-0.440600 -0.552300 -0.121900  -0.264000 -0.768000 0.568000
+-0.400000 -0.588000 -0.121900  0.672000 -0.144000 0.720000
+-0.400000 -0.552300 -0.100200  0.624000 -0.512000 0.584000
+-0.393200 -0.552300 -0.121900  0.872000 -0.352000 0.320000
+-0.400000 -0.588000 -0.121900  0.672000 -0.144000 0.720000
+-0.379200 -0.552300 -0.182900  0.864000 -0.416000 0.264000
+-0.400000 -0.602500 -0.131300  0.560000 -0.576000 0.584000
+-0.386500 -0.602500 -0.182900  0.376000 -0.032000 0.920000
+-0.379200 -0.552300 -0.182900  0.864000 -0.416000 0.264000
+-0.371400 -0.602500 -0.243900  0.928000 0.016000 0.352000
+-0.363900 -0.552300 -0.243900  0.816000 -0.480000 0.304000
+-0.379200 -0.552300 -0.182900  0.864000 -0.416000 0.264000
+-0.350000 -0.535600 -0.243900  0.360000 -0.840000 0.384000
+-0.350000 -0.518400 -0.182900  -0.088000 -0.928000 0.360000
+-0.379200 -0.552300 -0.182900  0.864000 -0.416000 0.264000
+-0.350000 -0.503000 -0.121900  0.232000 -0.880000 0.400000
+-0.393200 -0.552300 -0.121900  0.872000 -0.352000 0.320000
+-0.393200 -0.552300 -0.121900  0.872000 -0.352000 0.320000
+-0.350000 0.148000 -0.060900  -0.504000 0.552000 0.656000
+-0.350000 0.148000 -0.060900  -0.504000 0.552000 0.656000
+-0.361800 0.100400 -0.060900  -0.920000 0.112000 -0.352000
+-0.350000 0.100400 -0.076700  -0.736000 0.256000 -0.616000
+-0.358600 0.050200 -0.060900  -0.920000 0.168000 -0.328000
+-0.350000 0.050200 -0.078800  -0.832000 0.272000 -0.472000
+-0.350000 0.100400 -0.076700  -0.736000 0.256000 -0.616000
+-0.335400 0.050200 -0.121900  -0.752000 0.472000 -0.456000
+-0.317300 0.100400 -0.121900  -0.712000 0.264000 -0.640000
+-0.317300 0.100400 -0.121900  -0.712000 0.264000 -0.640000
+-0.377800 0.000000 -0.060900  -0.864000 0.424000 -0.248000
+-0.377800 0.000000 -0.060900  -0.864000 0.424000 -0.248000
+-0.400000 -0.037800 -0.060900  -0.728000 0.664000 0.152000
+-0.372200 0.000000 -0.121900  -0.848000 0.480000 -0.200000
+-0.400000 -0.050200 -0.118700  -0.832000 0.528000 -0.160000
+-0.399400 -0.050200 -0.121900  -0.760000 0.504000 -0.392000
+-0.400000 -0.050900 -0.121900  -0.736000 0.536000 -0.408000
+-0.400000 -0.050900 -0.121900  -0.736000 0.536000 -0.408000
+-0.350000 0.301200 -0.064600  -0.624000 0.064000 -0.768000
+-0.350000 0.301200 -0.064600  -0.624000 0.064000 -0.768000
+-0.300000 0.301200 -0.089300  -0.344000 0.056000 -0.936000
+-0.350000 0.251000 -0.067500  -0.624000 0.048000 -0.768000
+-0.300000 0.251000 -0.090000  -0.368000 0.088000 -0.920000
+-0.350000 0.200800 -0.076700  -0.368000 -0.104000 -0.920000
+-0.300000 0.200800 -0.077300  -0.504000 0.240000 -0.824000
+-0.350000 0.153200 -0.060900  -0.608000 -0.784000 0.016000
+-0.300000 0.150600 -0.105900  -0.768000 0.536000 -0.320000
+-0.346000 0.150600 -0.060900  -0.768000 -0.144000 0.616000
+-0.346000 0.150600 -0.060900  -0.768000 -0.144000 0.616000
+-0.300000 0.401700 -0.066400  -0.448000 0.440000 -0.768000
+-0.300000 0.401700 -0.066400  -0.448000 0.440000 -0.768000
+-0.250000 0.401700 -0.091800  -0.416000 0.456000 -0.776000
+-0.300000 0.351500 -0.083400  -0.432000 0.176000 -0.880000
+-0.250000 0.351500 -0.107800  -0.464000 0.176000 -0.864000
+-0.300000 0.301200 -0.089300  -0.344000 0.056000 -0.936000
+-0.250000 0.301200 -0.116200  -0.672000 0.120000 -0.720000
+-0.300000 0.251000 -0.090000  -0.368000 0.088000 -0.920000
+-0.250000 0.268200 -0.121900  -0.464000 0.088000 -0.872000
+-0.254200 0.251000 -0.121900  -0.384000 0.088000 -0.912000
+-0.300000 0.251000 -0.090000  -0.368000 0.088000 -0.920000
+-0.263400 0.200800 -0.121900  -0.480000 0.216000 -0.840000
+-0.300000 0.200800 -0.077300  -0.504000 0.240000 -0.824000
+-0.295300 0.150600 -0.121900  -0.728000 0.520000 -0.432000
+-0.300000 0.150600 -0.105900  -0.768000 0.536000 -0.320000
+-0.300000 0.144000 -0.121900  -0.728000 0.496000 -0.456000
+-0.300000 0.144000 -0.121900  -0.728000 0.496000 -0.456000
+-0.250000 0.401700 -0.091800  -0.416000 0.456000 -0.776000
+-0.250000 0.401700 -0.091800  -0.416000 0.456000 -0.776000
+-0.208300 0.401700 -0.121900  -0.432000 0.432000 -0.784000
+-0.250000 0.351500 -0.107800  -0.464000 0.176000 -0.864000
+-0.233300 0.351500 -0.121900  -0.616000 0.184000 -0.752000
+-0.250000 0.301200 -0.116200  -0.672000 0.120000 -0.720000
+-0.245300 0.301200 -0.121900  -0.680000 0.120000 -0.720000
+-0.250000 0.268200 -0.121900  -0.464000 0.088000 -0.872000
+-0.250000 0.268200 -0.121900  -0.464000 0.088000 -0.872000
+-0.104300 -0.100400 -0.060900  0.528000 0.416000 0.728000
+-0.104300 -0.100400 -0.060900  0.528000 0.416000 0.728000
+-0.100000 -0.100400 -0.064700  0.496000 0.416000 0.752000
+-0.100000 -0.105500 -0.060900  0.480000 0.464000 0.736000
+-0.050000 -0.100400 -0.073900  0.136000 0.480000 0.864000
+-0.050000 -0.119400 -0.060900  0.168000 0.528000 0.824000
+0.000000 -0.100400 -0.085100  0.096000 0.456000 0.880000
+0.000000 -0.136800 -0.060900  0.088000 0.520000 0.840000
+0.050000 -0.100400 -0.083400  0.000000 0.440000 0.888000
+0.050000 -0.140200 -0.060900  0.152000 0.504000 0.848000
+0.100000 -0.100400 -0.084200  0.032000 0.360000 0.928000
+0.076800 -0.150600 -0.060900  0.208000 0.432000 0.872000
+0.100000 -0.150600 -0.068400  0.184000 0.416000 0.888000
+0.100000 -0.170000 -0.060900  0.256000 0.296000 0.912000
+0.100000 -0.170000 -0.060900  0.256000 0.296000 0.912000
+-0.133200 -0.451900 -0.060900  0.584000 -0.656000 0.464000
+-0.133200 -0.451900 -0.060900  0.584000 -0.656000 0.464000
+-0.100000 -0.415900 -0.060900  0.680000 -0.544000 0.480000
+-0.100000 -0.451900 -0.117700  0.624000 -0.664000 0.392000
+-0.100000 -0.451900 -0.117700  0.624000 -0.664000 0.392000
+-0.150000 -0.502100 -0.111600  0.592000 -0.752000 0.280000
+-0.150000 -0.502100 -0.111600  0.592000 -0.752000 0.280000
+-0.146100 -0.502100 -0.121900  0.616000 -0.744000 0.232000
+-0.150000 -0.505100 -0.121900  0.584000 -0.768000 0.240000
+-0.141200 -0.502100 -0.182900  0.696000 -0.688000 0.184000
+-0.150000 -0.510100 -0.182900  0.616000 -0.760000 0.168000
+-0.125700 -0.502100 -0.243900  0.664000 -0.408000 0.624000
+-0.150000 -0.530700 -0.243900  0.632000 -0.664000 0.392000
+-0.150000 -0.530700 -0.243900  0.632000 -0.664000 0.392000
+-0.078700 0.200800 -0.060900  0.568000 -0.416000 0.704000
+-0.078700 0.200800 -0.060900  0.568000 -0.416000 0.704000
+-0.050000 0.236000 -0.060900  0.536000 -0.496000 0.672000
+-0.050000 0.200800 -0.090500  0.520000 -0.520000 0.672000
+-0.050000 0.200800 -0.090500  0.520000 -0.520000 0.672000
+-0.100000 0.100400 -0.099400  0.760000 -0.264000 0.584000
+-0.100000 0.100400 -0.099400  0.760000 -0.264000 0.584000
+-0.089100 0.100400 -0.121900  0.816000 -0.232000 0.520000
+-0.100000 0.054100 -0.121900  0.816000 -0.176000 0.544000
+-0.100000 0.054100 -0.121900  0.816000 -0.176000 0.544000
+-0.050000 -0.370100 -0.060900  0.592000 -0.672000 0.424000
+-0.050000 -0.370100 -0.060900  0.592000 -0.672000 0.424000
+-0.087700 -0.401700 -0.060900  0.608000 -0.600000 0.504000
+-0.050000 -0.398200 -0.121900  0.592000 -0.704000 0.368000
+-0.054100 -0.401700 -0.121900  0.656000 -0.688000 0.280000
+-0.050000 -0.389600 -0.182900  0.656000 -0.736000 -0.128000
+-0.061900 -0.401700 -0.182900  0.744000 -0.648000 -0.120000
+-0.050000 -0.380500 -0.243900  0.664000 -0.736000 -0.104000
+-0.071000 -0.401700 -0.243900  0.856000 -0.496000 -0.072000
+-0.050000 -0.374600 -0.304800  0.584000 -0.672000 -0.448000
+-0.073900 -0.401700 -0.304800  0.784000 -0.304000 -0.528000
+-0.050000 -0.351500 -0.336900  0.024000 -0.576000 -0.808000
+-0.100000 -0.401700 -0.330800  0.576000 -0.152000 -0.792000
+-0.100000 -0.351500 -0.338800  0.024000 -0.312000 -0.944000
+-0.150000 -0.401700 -0.364300  0.552000 0.080000 -0.824000
+-0.150000 -0.351500 -0.350300  0.512000 0.192000 -0.832000
+-0.100000 -0.351500 -0.338800  0.024000 -0.312000 -0.944000
+-0.150000 -0.301200 -0.318500  -0.024000 0.504000 -0.856000
+-0.100000 -0.301200 -0.349000  -0.368000 0.264000 -0.888000
+-0.150000 -0.286300 -0.304800  -0.184000 0.480000 -0.848000
+-0.100000 -0.251000 -0.333700  -0.512000 0.248000 -0.816000
+-0.123600 -0.251000 -0.304800  -0.536000 0.288000 -0.784000
+-0.100000 -0.200800 -0.311700  -0.496000 0.128000 -0.856000
+-0.108400 -0.200800 -0.304800  -0.496000 -0.048000 -0.856000
+-0.123600 -0.251000 -0.304800  -0.536000 0.288000 -0.784000
+-0.150000 -0.200800 -0.284500  0.024000 -0.216000 -0.968000
+-0.150000 -0.251000 -0.289400  -0.264000 0.272000 -0.920000
+-0.196100 -0.200800 -0.304800  0.360000 -0.200000 -0.904000
+-0.195100 -0.251000 -0.304800  0.376000 0.112000 -0.912000
+-0.150000 -0.251000 -0.289400  -0.264000 0.272000 -0.920000
+-0.150000 -0.286300 -0.304800  -0.184000 0.480000 -0.848000
+-0.123600 -0.251000 -0.304800  -0.536000 0.288000 -0.784000
+-0.123600 -0.251000 -0.304800  -0.536000 0.288000 -0.784000
+0.000000 0.393800 -0.060900  0.224000 0.176000 0.952000
+0.000000 0.393800 -0.060900  0.224000 0.176000 0.952000
+-0.005200 0.401700 -0.060900  0.264000 0.168000 0.944000
+0.000000 0.401700 -0.062800  0.256000 0.176000 0.944000
+0.000000 0.401700 -0.062800  0.256000 0.176000 0.944000
+0.000000 0.493800 -0.121900  0.128000 0.960000 -0.232000
+0.000000 0.493800 -0.121900  0.128000 0.960000 -0.232000
+0.000000 0.451900 -0.081100  0.280000 0.456000 0.832000
+0.050000 0.485400 -0.121900  -0.032000 0.904000 -0.408000
+0.050000 0.451900 -0.077800  0.016000 0.408000 0.912000
+0.100000 0.494400 -0.121900  -0.184000 0.952000 -0.216000
+0.100000 0.451900 -0.066700  -0.192000 0.072000 0.976000
+0.138500 0.502100 -0.121900  -0.184000 0.952000 -0.216000
+0.121900 0.451900 -0.060900  -0.112000 0.472000 0.872000
+0.150000 0.502100 -0.119700  0.016000 0.656000 0.752000
+0.150000 0.456100 -0.060900  0.048000 0.664000 0.736000
+0.150000 0.456100 -0.060900  0.048000 0.664000 0.736000
+0.150000 0.503100 -0.121900  0.272000 0.456000 -0.840000
+0.150000 0.503100 -0.121900  0.272000 0.456000 -0.840000
+0.150000 0.502100 -0.119700  0.016000 0.656000 0.752000
+0.138500 0.502100 -0.121900  -0.184000 0.952000 -0.216000
+0.138500 0.502100 -0.121900  -0.184000 0.952000 -0.216000
+0.150000 0.409600 -0.060900  -0.208000 -0.072000 0.968000
+0.150000 0.409600 -0.060900  -0.208000 -0.072000 0.968000
+0.151400 0.401700 -0.060900  -0.480000 -0.416000 0.760000
+0.150000 0.401700 -0.062100  -0.392000 -0.400000 0.816000
+0.150000 0.401700 -0.062100  -0.392000 -0.400000 0.816000
+0.150000 -0.251000 -0.118100  0.224000 -0.792000 0.560000
+0.150000 -0.251000 -0.118100  0.224000 -0.792000 0.560000
+0.161400 -0.251000 -0.121900  0.152000 -0.792000 0.576000
+0.150000 -0.253200 -0.121900  0.192000 -0.808000 0.552000
+0.150000 -0.253200 -0.121900  0.192000 -0.808000 0.552000
+0.250000 0.432000 -0.060900  0.224000 0.624000 0.736000
+0.250000 0.432000 -0.060900  0.224000 0.624000 0.736000
+0.203100 0.451900 -0.060900  0.264000 0.672000 0.680000
+0.250000 0.451900 -0.094000  0.248000 0.784000 0.552000
+0.250000 0.451900 -0.094000  0.248000 0.784000 0.552000
+0.200000 0.352900 -0.060900  -0.368000 -0.496000 0.776000
+0.200000 0.352900 -0.060900  -0.368000 -0.496000 0.776000
+0.201200 0.351500 -0.060900  -0.488000 -0.576000 0.648000
+0.200000 0.351500 -0.062100  -0.312000 -0.640000 0.696000
+0.200000 0.351500 -0.062100  -0.312000 -0.640000 0.696000
+0.200000 -0.041200 -0.121900  0.160000 0.488000 0.856000
+0.200000 -0.041200 -0.121900  0.160000 0.488000 0.856000
+0.222300 -0.050200 -0.121900  0.200000 0.432000 0.872000
+0.200000 -0.050200 -0.116900  0.136000 0.368000 0.912000
+0.200000 -0.050200 -0.116900  0.136000 0.368000 0.912000
+0.300000 0.451900 -0.106900  0.184000 0.864000 0.456000
+0.300000 0.451900 -0.106900  0.184000 0.864000 0.456000
+0.300000 0.458100 -0.121900  0.224000 0.952000 -0.176000
+0.323400 0.451900 -0.121900  0.248000 0.944000 -0.200000
+0.300000 0.451900 -0.131100  0.200000 0.712000 -0.664000
+0.300000 0.451900 -0.131100  0.200000 0.712000 -0.664000
+0.366500 0.200800 -0.121900  -0.760000 -0.624000 0.168000
+0.366500 0.200800 -0.121900  -0.760000 -0.624000 0.168000
+0.400000 0.200800 -0.077800  -0.600000 -0.432000 0.664000
+0.400000 0.152400 -0.121900  -0.688000 -0.712000 -0.048000
+0.400000 0.152400 -0.121900  -0.688000 -0.712000 -0.048000
+0.400000 0.072600 -0.121900  -0.632000 0.256000 0.720000
+0.400000 0.072600 -0.121900  -0.632000 0.256000 0.720000
+0.400000 0.050200 -0.114800  -0.552000 0.256000 0.784000
+0.393200 0.050200 -0.121900  -0.648000 0.352000 0.664000
+0.393200 0.050200 -0.121900  -0.648000 0.352000 0.664000
+0.450000 -0.100400 -0.078400  -0.088000 0.200000 0.968000
+0.450000 -0.100400 -0.078400  -0.088000 0.200000 0.968000
+0.400000 -0.100400 -0.080400  -0.024000 0.176000 0.976000
+0.450000 -0.150600 -0.064700  -0.192000 0.128000 0.968000
+0.400000 -0.150600 -0.068400  -0.344000 -0.312000 0.880000
+0.450000 -0.200800 -0.072200  -0.256000 -0.536000 0.800000
+0.400000 -0.200800 -0.119100  -0.200000 -0.688000 0.688000
+0.450000 -0.227100 -0.121900  -0.296000 -0.712000 0.624000
+0.400000 -0.203000 -0.121900  -0.184000 -0.672000 0.712000
+0.450000 -0.251000 -0.179900  -0.288000 -0.680000 0.664000
+0.400000 -0.249800 -0.182900  0.472000 -0.752000 0.448000
+0.415700 -0.251000 -0.182900  -0.088000 -0.872000 0.480000
+0.400000 -0.249400 -0.243900  0.760000 -0.472000 -0.424000
+0.450000 -0.251000 -0.203800  -0.216000 -0.960000 -0.144000
+0.450000 -0.248400 -0.243900  -0.224000 -0.888000 -0.384000
+0.459300 -0.251000 -0.243900  -0.280000 -0.864000 -0.400000
+0.459300 -0.251000 -0.243900  -0.280000 -0.864000 -0.400000
+0.450000 0.163500 -0.060900  -0.600000 -0.504000 0.608000
+0.450000 0.163500 -0.060900  -0.600000 -0.504000 0.608000
+0.460500 0.150600 -0.060900  -0.624000 -0.512000 0.584000
+0.450000 0.150600 -0.075000  -0.616000 -0.488000 0.608000
+0.450000 0.150600 -0.075000  -0.616000 -0.488000 0.608000
+0.504600 0.100400 -0.060900  -0.704000 -0.248000 0.656000
+0.504600 0.100400 -0.060900  -0.704000 -0.248000 0.656000
+0.500000 0.067400 -0.060900  -0.592000 0.120000 0.792000
+0.500000 0.100400 -0.067100  -0.632000 -0.296000 0.704000
+0.500000 0.100400 -0.067100  -0.632000 -0.296000 0.704000
+0.550000 -0.159500 -0.060900  0.248000 0.472000 0.840000
+0.550000 -0.159500 -0.060900  0.248000 0.472000 0.840000
+0.530700 -0.150600 -0.060900  0.208000 0.504000 0.832000
+0.550000 -0.150600 -0.067100  0.240000 0.480000 0.840000
+0.550000 -0.150600 -0.067100  0.240000 0.480000 0.840000
+0.546800 -0.351500 -0.121900  -0.560000 -0.304000 0.760000
+0.546800 -0.351500 -0.121900  -0.560000 -0.304000 0.760000
+0.550000 -0.317100 -0.121900  -0.368000 0.064000 0.920000
+0.550000 -0.351500 -0.118900  -0.368000 0.056000 0.920000
+0.558500 -0.351500 -0.121900  0.208000 -0.648000 0.728000
+0.550000 -0.353000 -0.121900  -0.032000 -0.832000 0.536000
+0.550000 -0.351500 -0.118900  -0.368000 0.056000 0.920000
+0.546800 -0.351500 -0.121900  -0.560000 -0.304000 0.760000
+0.550000 -0.353000 -0.121900  -0.032000 -0.832000 0.536000
+0.500000 -0.351500 -0.156800  -0.392000 -0.248000 0.880000
+0.550000 -0.389500 -0.182900  -0.304000 -0.784000 0.528000
+0.500000 -0.372900 -0.182900  -0.184000 -0.776000 0.592000
+0.550000 -0.401700 -0.218900  -0.128000 -0.904000 0.392000
+0.500000 -0.400600 -0.243900  0.024000 -0.920000 0.384000
+0.503900 -0.401700 -0.243900  -0.232000 -0.936000 0.256000
+0.500000 -0.400200 -0.304800  -0.176000 -0.672000 -0.712000
+0.502600 -0.401700 -0.304800  -0.320000 -0.840000 -0.416000
+0.500000 -0.351500 -0.354900  -0.384000 -0.472000 -0.784000
+0.550000 -0.401700 -0.333700  -0.144000 -0.688000 -0.704000
+0.550000 -0.351500 -0.364500  0.120000 -0.104000 -0.984000
+0.500000 -0.351500 -0.354900  -0.384000 -0.472000 -0.784000
+0.550000 -0.316300 -0.304800  -0.472000 0.688000 -0.536000
+0.500000 -0.333600 -0.304800  -0.408000 0.824000 -0.376000
+0.550000 -0.301200 -0.279200  -0.712000 0.120000 -0.680000
+0.500000 -0.310500 -0.243900  -0.600000 0.776000 -0.152000
+0.513800 -0.301200 -0.243900  -0.728000 0.592000 -0.328000
+0.500000 -0.316400 -0.182900  -0.704000 0.472000 0.520000
+0.511800 -0.301200 -0.182900  -0.912000 0.352000 0.176000
+0.500000 -0.351500 -0.156800  -0.392000 -0.248000 0.880000
+0.550000 -0.301200 -0.123600  -0.624000 -0.440000 0.632000
+0.546800 -0.351500 -0.121900  -0.560000 -0.304000 0.760000
+0.550000 -0.317100 -0.121900  -0.368000 0.064000 0.920000
+0.550000 -0.317100 -0.121900  -0.368000 0.064000 0.920000
+0.550000 -0.242100 -0.060900  -0.400000 -0.536000 0.736000
+0.550000 -0.242100 -0.060900  -0.400000 -0.536000 0.736000
+0.562800 -0.251000 -0.060900  -0.368000 -0.568000 0.720000
+0.550000 -0.251000 -0.069700  -0.416000 -0.584000 0.688000
+0.550000 -0.251000 -0.069700  -0.416000 -0.584000 0.688000
+0.552600 -0.301200 -0.121900  -0.368000 -0.384000 0.840000
+0.552600 -0.301200 -0.121900  -0.368000 -0.384000 0.840000
+0.600000 -0.301200 -0.098800  -0.176000 -0.576000 0.792000
+0.600000 -0.333000 -0.121900  0.024000 -0.312000 0.944000
+0.650000 -0.301200 -0.100200  0.264000 -0.568000 0.768000
+0.650000 -0.327200 -0.121900  -0.280000 -0.536000 0.792000
+0.700000 -0.301200 -0.068800  0.336000 0.392000 0.848000
+0.679500 -0.351500 -0.121900  -0.424000 -0.464000 0.768000
+0.700000 -0.351500 -0.108700  -0.352000 -0.464000 0.808000
+0.700000 -0.372000 -0.121900  -0.360000 -0.440000 0.816000
+0.750000 -0.351500 -0.097900  0.640000 0.048000 0.760000
+0.737900 -0.401700 -0.121900  -0.352000 -0.448000 0.816000
+0.750000 -0.401700 -0.115900  -0.264000 -0.344000 0.896000
+0.750000 -0.411100 -0.121900  -0.304000 -0.456000 0.824000
+0.800000 -0.401700 -0.115500  0.392000 0.184000 0.896000
+0.800000 -0.418600 -0.121900  0.304000 -0.320000 0.888000
+0.750000 -0.411100 -0.121900  -0.304000 -0.456000 0.824000
+0.800000 -0.451900 -0.135400  0.168000 -0.384000 0.904000
+0.750000 -0.451900 -0.153800  -0.384000 -0.528000 0.752000
+0.800000 -0.502100 -0.171200  -0.360000 -0.648000 0.664000
+0.750000 -0.479900 -0.182900  -0.456000 -0.632000 0.616000
+0.783200 -0.502100 -0.182900  -0.448000 -0.720000 0.512000
+0.750000 -0.502100 -0.236900  -0.448000 -0.776000 0.432000
+0.800000 -0.511100 -0.182900  -0.376000 -0.744000 0.544000
+0.750000 -0.505200 -0.243900  -0.480000 -0.856000 0.152000
+0.800000 -0.519900 -0.243900  -0.400000 -0.904000 -0.112000
+0.750000 -0.502100 -0.254300  -0.448000 -0.832000 -0.312000
+0.800000 -0.502100 -0.293400  -0.120000 -0.840000 -0.520000
+0.750000 -0.487000 -0.304800  -0.104000 -0.744000 -0.656000
+0.800000 -0.493800 -0.304800  0.032000 -0.688000 -0.720000
+0.750000 -0.451900 -0.330900  0.152000 -0.080000 -0.984000
+0.800000 -0.451900 -0.330300  0.328000 0.200000 -0.920000
+0.750000 -0.401700 -0.321600  0.336000 0.000000 -0.936000
+0.800000 -0.418300 -0.304800  0.408000 0.496000 -0.760000
+0.779200 -0.401700 -0.304800  0.400000 0.336000 -0.848000
+0.800000 -0.401700 -0.291400  0.440000 0.456000 -0.760000
+0.754800 -0.351500 -0.304800  0.424000 0.136000 -0.888000
+0.800000 -0.351500 -0.277300  0.568000 0.408000 -0.704000
+0.750000 -0.334300 -0.304800  0.512000 0.112000 -0.840000
+0.800000 -0.328800 -0.243900  0.640000 0.656000 -0.384000
+0.750000 -0.301200 -0.299800  0.512000 0.144000 -0.840000
+0.780500 -0.301200 -0.243900  0.848000 0.504000 -0.128000
+0.750000 -0.251000 -0.256700  0.824000 0.520000 -0.208000
+0.752500 -0.251000 -0.243900  0.840000 0.528000 -0.096000
+0.750000 -0.247000 -0.243900  0.832000 0.536000 -0.096000
+0.750000 -0.251000 -0.218200  0.840000 0.520000 0.096000
+0.717800 -0.200800 -0.243900  0.824000 0.560000 -0.064000
+0.746300 -0.251000 -0.182900  0.848000 0.496000 0.152000
+0.713600 -0.200800 -0.182900  0.824000 0.512000 0.224000
+0.719200 -0.251000 -0.121900  0.760000 0.456000 0.440000
+0.700000 -0.200800 -0.144600  0.696000 0.528000 0.480000
+0.700000 -0.217500 -0.121900  0.616000 0.552000 0.544000
+0.677400 -0.200800 -0.121900  0.528000 0.512000 0.672000
+0.700000 -0.200800 -0.144600  0.696000 0.528000 0.480000
+0.652900 -0.150600 -0.121900  0.752000 0.456000 0.464000
+0.700000 -0.178500 -0.182900  0.792000 0.568000 0.200000
+0.675300 -0.150600 -0.182900  0.768000 0.552000 0.296000
+0.700000 -0.175300 -0.243900  0.752000 0.600000 -0.240000
+0.674200 -0.150600 -0.243900  0.696000 0.600000 -0.384000
+0.674200 -0.150600 -0.243900  0.696000 0.600000 -0.384000
+0.600000 -0.272000 -0.060900  -0.264000 -0.632000 0.720000
+0.600000 -0.272000 -0.060900  -0.264000 -0.632000 0.720000
+0.600000 -0.301200 -0.098800  -0.176000 -0.576000 0.792000
+0.650000 -0.258100 -0.060900  0.392000 -0.456000 0.792000
+0.650000 -0.301200 -0.100200  0.264000 -0.568000 0.768000
+0.657600 -0.251000 -0.060900  0.456000 -0.072000 0.880000
+0.700000 -0.301200 -0.068800  0.336000 0.392000 0.848000
+0.700000 -0.251000 -0.086700  0.608000 0.464000 0.632000
+0.700000 -0.251000 -0.086700  0.608000 0.464000 0.632000
+0.650000 0.350500 -0.060900  0.712000 0.536000 -0.440000
+0.650000 0.350500 -0.060900  0.712000 0.536000 -0.440000
+0.650000 0.301200 -0.100800  0.528000 0.504000 -0.672000
+0.680100 0.301200 -0.060900  0.752000 0.544000 -0.368000
+0.680100 0.301200 -0.060900  0.752000 0.544000 -0.368000
+0.700000 0.251000 -0.093200  0.552000 0.600000 -0.568000
+0.700000 0.251000 -0.093200  0.552000 0.600000 -0.568000
+0.673000 0.251000 -0.121900  0.568000 0.576000 -0.584000
+0.700000 0.229200 -0.121900  0.528000 0.656000 -0.528000
+0.650000 0.251000 -0.154700  0.488000 0.640000 -0.584000
+0.700000 0.200800 -0.171600  0.480000 0.608000 -0.616000
+0.650000 0.227800 -0.182900  0.368000 0.576000 -0.720000
+0.687200 0.200800 -0.182900  0.432000 0.544000 -0.712000
+0.700000 0.200800 -0.171600  0.480000 0.608000 -0.616000
+0.700000 0.190400 -0.182900  0.432000 0.560000 -0.696000
+0.700000 0.190400 -0.182900  0.432000 0.560000 -0.696000
+0.650000 -0.200800 -0.092600  0.656000 0.384000 0.640000
+0.650000 -0.200800 -0.092600  0.656000 0.384000 0.640000
+0.650000 -0.150600 -0.116200  0.720000 0.480000 0.488000
+0.677400 -0.200800 -0.121900  0.528000 0.512000 0.672000
+0.652900 -0.150600 -0.121900  0.752000 0.456000 0.464000
+0.652900 -0.150600 -0.121900  0.752000 0.456000 0.464000
+0.734900 0.200800 -0.121900  0.552000 0.608000 -0.552000
+0.734900 0.200800 -0.121900  0.552000 0.608000 -0.552000
+0.750000 0.186400 -0.121900  0.504000 0.648000 -0.560000
+0.750000 0.200800 -0.104400  0.480000 0.680000 -0.544000
+0.750000 0.200800 -0.104400  0.480000 0.680000 -0.544000
+0.750000 -0.351500 -0.097900  0.640000 0.048000 0.760000
+0.750000 -0.351500 -0.097900  0.640000 0.048000 0.760000
+0.700000 -0.351500 -0.108700  -0.352000 -0.464000 0.808000
+0.750000 -0.301200 -0.116500  0.704000 0.400000 0.568000
+0.700000 -0.301200 -0.068800  0.336000 0.392000 0.848000
+0.700000 -0.301200 -0.068800  0.336000 0.392000 0.848000
+-0.950000 -0.150600 -0.169000  -0.584000 -0.792000 0.136000
+-0.950000 -0.150600 -0.169000  -0.584000 -0.792000 0.136000
+-0.950000 -0.152700 -0.182900  -0.600000 -0.784000 0.144000
+-0.952800 -0.150600 -0.182900  -0.568000 -0.808000 0.136000
+-0.950000 -0.161800 -0.243900  -0.584000 -0.784000 0.176000
+-0.966700 -0.150600 -0.243900  -0.472000 -0.864000 0.152000
+-0.950000 -0.180000 -0.304800  -0.552000 -0.600000 -0.568000
+-0.989000 -0.150600 -0.304800  -0.440000 -0.624000 -0.640000
+-0.950000 -0.150600 -0.330800  -0.416000 -0.432000 -0.792000
+-0.950000 -0.150600 -0.330800  -0.416000 -0.432000 -0.792000
+-0.900000 -0.492700 -0.121900  -0.520000 0.712000 0.448000
+-0.900000 -0.492700 -0.121900  -0.520000 0.712000 0.448000
+-0.900000 -0.462200 -0.182900  0.320000 0.888000 0.304000
+-0.878700 -0.502100 -0.121900  0.408000 0.368000 0.832000
+-0.850000 -0.490700 -0.182900  0.328000 0.896000 0.288000
+-0.850000 -0.502100 -0.144600  0.400000 0.776000 0.480000
+-0.820300 -0.502100 -0.182900  0.496000 0.792000 0.344000
+-0.850000 -0.519700 -0.121900  0.200000 0.624000 0.752000
+-0.800000 -0.513200 -0.182900  -0.080000 0.880000 0.456000
+-0.800000 -0.539500 -0.121900  0.176000 0.680000 0.704000
+-0.750000 -0.503000 -0.182900  -0.200000 0.848000 0.472000
+-0.750000 -0.549900 -0.121900  0.080000 0.648000 0.752000
+-0.749300 -0.502100 -0.182900  -0.920000 -0.232000 0.288000
+-0.723300 -0.502100 -0.121900  -0.896000 -0.224000 0.368000
+-0.723300 -0.502100 -0.121900  -0.896000 -0.224000 0.368000
+-0.900000 -0.511500 -0.121900  -0.520000 -0.664000 0.528000
+-0.900000 -0.511500 -0.121900  -0.520000 -0.664000 0.528000
+-0.900000 -0.542100 -0.182900  -0.808000 -0.560000 0.136000
+-0.868200 -0.552300 -0.121900  -0.520000 -0.224000 0.816000
+-0.892400 -0.552300 -0.182900  -0.760000 -0.624000 0.176000
+-0.850000 -0.569100 -0.121900  -0.488000 -0.776000 0.384000
+-0.850000 -0.592600 -0.182900  -0.520000 -0.800000 0.264000
+-0.800000 -0.584500 -0.121900  -0.288000 -0.544000 0.776000
+-0.832500 -0.602500 -0.182900  -0.576000 -0.768000 0.272000
+-0.800000 -0.602500 -0.136500  -0.416000 -0.648000 0.632000
+-0.800000 -0.620600 -0.182900  -0.312000 -0.880000 0.336000
+-0.764000 -0.602500 -0.121900  -0.176000 -0.816000 0.544000
+-0.750000 -0.630100 -0.182900  -0.144000 -0.912000 0.360000
+-0.750000 -0.605000 -0.121900  -0.152000 -0.872000 0.456000
+-0.750000 -0.605000 -0.121900  -0.152000 -0.872000 0.456000
+-0.802000 -0.351500 -0.121900  -0.840000 -0.520000 0.096000
+-0.802000 -0.351500 -0.121900  -0.840000 -0.520000 0.096000
+-0.832400 -0.301200 -0.121900  -0.840000 -0.528000 0.048000
+-0.802200 -0.351500 -0.182900  -0.872000 -0.480000 0.016000
+-0.831100 -0.301200 -0.182900  -0.848000 -0.520000 0.016000
+-0.807300 -0.351500 -0.243900  -0.864000 -0.472000 0.152000
+-0.834700 -0.301200 -0.243900  -0.840000 -0.504000 0.184000
+-0.834700 -0.301200 -0.243900  -0.840000 -0.504000 0.184000
+-0.779100 0.150600 -0.182900  0.400000 0.664000 -0.616000
+-0.779100 0.150600 -0.182900  0.400000 0.664000 -0.616000
+-0.750000 0.132600 -0.182900  0.408000 0.656000 -0.624000
+-0.750000 0.150600 -0.159200  0.432000 0.664000 -0.600000
+-0.750000 0.150600 -0.159200  0.432000 0.664000 -0.600000
+-0.750000 -0.448400 -0.121900  -0.880000 -0.432000 0.160000
+-0.750000 -0.448400 -0.121900  -0.880000 -0.432000 0.160000
+-0.750000 -0.451900 -0.133400  -0.896000 -0.392000 0.184000
+-0.771000 -0.401700 -0.121900  -0.872000 -0.456000 0.128000
+-0.757600 -0.451900 -0.182900  -0.952000 -0.232000 0.184000
+-0.775200 -0.401700 -0.182900  -0.904000 -0.400000 0.120000
+-0.769800 -0.451900 -0.243900  -0.952000 -0.080000 0.272000
+-0.781800 -0.401700 -0.243900  -0.912000 -0.336000 0.208000
+-0.787800 -0.451900 -0.304800  -0.984000 0.136000 -0.040000
+-0.797400 -0.401700 -0.304800  -0.928000 -0.344000 0.056000
+-0.797400 -0.401700 -0.304800  -0.928000 -0.344000 0.056000
+-0.800000 -0.584500 -0.121900  -0.288000 -0.544000 0.776000
+-0.800000 -0.584500 -0.121900  -0.288000 -0.544000 0.776000
+-0.764000 -0.602500 -0.121900  -0.176000 -0.816000 0.544000
+-0.800000 -0.602500 -0.136500  -0.416000 -0.648000 0.632000
+-0.800000 -0.602500 -0.136500  -0.416000 -0.648000 0.632000
+-0.750000 0.174400 -0.121900  0.448000 0.824000 -0.336000
+-0.750000 0.174400 -0.121900  0.448000 0.824000 -0.336000
+-0.750000 0.150600 -0.159200  0.432000 0.664000 -0.600000
+-0.715000 0.150600 -0.121900  0.512000 0.744000 -0.408000
+-0.715000 0.150600 -0.121900  0.512000 0.744000 -0.408000
+-0.700900 0.100400 -0.182900  0.440000 0.608000 -0.648000
+-0.700900 0.100400 -0.182900  0.440000 0.608000 -0.648000
+-0.700000 0.099700 -0.182900  0.504000 0.560000 -0.640000
+-0.700000 0.100400 -0.182100  0.536000 0.592000 -0.592000
+-0.700000 0.100400 -0.182100  0.536000 0.592000 -0.592000
+-0.750000 -0.448400 -0.121900  -0.880000 -0.432000 0.160000
+-0.750000 -0.448400 -0.121900  -0.880000 -0.432000 0.160000
+-0.748200 -0.451900 -0.121900  -0.880000 -0.440000 0.160000
+-0.750000 -0.451900 -0.133400  -0.896000 -0.392000 0.184000
+-0.750000 -0.451900 -0.133400  -0.896000 -0.392000 0.184000
+-0.700000 0.140000 -0.121900  0.536000 0.728000 -0.408000
+-0.700000 0.140000 -0.121900  0.536000 0.728000 -0.408000
+-0.700000 0.100400 -0.182100  0.536000 0.592000 -0.592000
+-0.657700 0.100400 -0.121900  0.728000 0.576000 -0.360000
+-0.657700 0.100400 -0.121900  0.728000 0.576000 -0.360000
+-0.652800 0.050200 -0.182900  0.592000 0.536000 -0.592000
+-0.652800 0.050200 -0.182900  0.592000 0.536000 -0.592000
+-0.650000 0.045800 -0.182900  0.672000 0.432000 -0.592000
+-0.650000 0.050200 -0.178200  0.664000 0.544000 -0.504000
+-0.621400 0.000000 -0.182900  0.848000 0.280000 -0.440000
+-0.614300 0.050200 -0.121900  0.720000 0.480000 -0.480000
+-0.601900 0.000000 -0.121900  0.848000 0.208000 -0.472000
+-0.601900 0.000000 -0.121900  0.848000 0.208000 -0.472000
+-0.650000 0.089500 -0.121900  0.728000 0.552000 -0.384000
+-0.650000 0.089500 -0.121900  0.728000 0.552000 -0.384000
+-0.650000 0.050200 -0.178200  0.664000 0.544000 -0.504000
+-0.614300 0.050200 -0.121900  0.720000 0.480000 -0.480000
+-0.614300 0.050200 -0.121900  0.720000 0.480000 -0.480000
+-0.491700 -0.150600 -0.182900  -0.448000 0.848000 -0.264000
+-0.491700 -0.150600 -0.182900  -0.448000 0.848000 -0.264000
+-0.500000 -0.150600 -0.154000  -0.424000 0.880000 -0.160000
+-0.500000 -0.154300 -0.182900  -0.320000 0.920000 -0.176000
+-0.500000 -0.154300 -0.182900  -0.320000 0.920000 -0.176000
+-0.372200 0.000000 -0.121900  -0.848000 0.480000 -0.200000
+-0.372200 0.000000 -0.121900  -0.848000 0.480000 -0.200000
+-0.350000 0.000000 -0.171400  -0.688000 0.416000 -0.584000
+-0.350000 0.031200 -0.121900  -0.744000 0.552000 -0.352000
+-0.350000 0.031200 -0.121900  -0.744000 0.552000 -0.352000
+-0.350000 -0.652700 -0.168800  -0.864000 0.056000 0.488000
+-0.350000 -0.652700 -0.168800  -0.864000 0.056000 0.488000
+-0.300000 -0.652700 -0.176500  0.496000 0.568000 0.648000
+-0.350000 -0.647900 -0.182900  0.008000 0.768000 0.624000
+-0.300000 -0.647500 -0.182900  0.464000 0.632000 0.616000
+-0.350000 -0.630200 -0.243900  -0.144000 0.776000 0.600000
+-0.300000 -0.607200 -0.243900  -0.248000 0.672000 0.688000
+-0.300000 -0.647500 -0.182900  0.464000 0.632000 0.616000
+-0.286800 -0.602500 -0.243900  -0.320000 0.232000 0.912000
+-0.293900 -0.652700 -0.182900  0.576000 0.496000 0.640000
+-0.250000 -0.602500 -0.226600  0.288000 -0.512000 0.800000
+-0.250000 -0.652700 -0.232900  0.624000 0.072000 0.768000
+-0.233200 -0.602500 -0.243900  0.608000 -0.320000 0.720000
+-0.241600 -0.652700 -0.243900  0.680000 -0.216000 0.688000
+-0.250000 -0.652700 -0.232900  0.624000 0.072000 0.768000
+-0.250000 -0.679700 -0.243900  0.728000 -0.208000 0.640000
+-0.293900 -0.652700 -0.182900  0.576000 0.496000 0.640000
+-0.256000 -0.703000 -0.243900  0.696000 -0.392000 0.584000
+-0.293800 -0.703000 -0.182900  0.608000 -0.624000 0.488000
+-0.293900 -0.652700 -0.182900  0.576000 0.496000 0.640000
+-0.300000 -0.703000 -0.173800  0.616000 -0.544000 0.552000
+-0.300000 -0.652700 -0.176500  0.496000 0.568000 0.648000
+-0.350000 -0.703000 -0.180700  -0.616000 -0.504000 0.592000
+-0.350000 -0.652700 -0.168800  -0.864000 0.056000 0.488000
+-0.350000 -0.652700 -0.168800  -0.864000 0.056000 0.488000
+-0.260200 -0.552300 -0.121900  -0.560000 -0.752000 0.336000
+-0.260200 -0.552300 -0.121900  -0.560000 -0.752000 0.336000
+-0.300000 -0.516400 -0.121900  -0.256000 -0.872000 0.400000
+-0.285200 -0.552300 -0.182900  -0.616000 -0.680000 0.384000
+-0.300000 -0.538300 -0.182900  -0.584000 -0.696000 0.408000
+-0.300000 -0.552300 -0.209900  -0.624000 -0.616000 0.456000
+-0.300000 -0.552300 -0.209900  -0.624000 -0.616000 0.456000
+-0.300000 -0.647500 -0.182900  0.464000 0.632000 0.616000
+-0.300000 -0.647500 -0.182900  0.464000 0.632000 0.616000
+-0.293900 -0.652700 -0.182900  0.576000 0.496000 0.640000
+-0.300000 -0.652700 -0.176500  0.496000 0.568000 0.648000
+-0.300000 -0.652700 -0.176500  0.496000 0.568000 0.648000
+-0.200000 0.251000 -0.156200  -0.432000 0.168000 -0.880000
+-0.200000 0.251000 -0.156200  -0.432000 0.168000 -0.880000
+-0.250000 0.251000 -0.124000  -0.376000 0.088000 -0.920000
+-0.200000 0.200800 -0.161600  -0.480000 0.384000 -0.776000
+-0.250000 0.200800 -0.129700  -0.392000 0.152000 -0.904000
+-0.250000 0.200800 -0.129700  -0.392000 0.152000 -0.904000
+-0.200000 -0.534300 -0.121900  0.456000 -0.832000 0.296000
+-0.200000 -0.534300 -0.121900  0.456000 -0.832000 0.296000
+-0.235800 -0.552300 -0.121900  0.448000 -0.816000 0.336000
+-0.200000 -0.549300 -0.182900  0.504000 -0.784000 0.344000
+-0.204600 -0.552300 -0.182900  0.504000 -0.776000 0.360000
+-0.200000 -0.552300 -0.190900  0.520000 -0.768000 0.360000
+-0.200000 -0.552300 -0.190900  0.520000 -0.768000 0.360000
+-0.200000 0.401700 -0.127400  -0.400000 0.440000 -0.800000
+-0.200000 0.401700 -0.127400  -0.400000 0.440000 -0.800000
+-0.150000 0.401700 -0.148200  -0.240000 0.400000 -0.872000
+-0.200000 0.351500 -0.146000  -0.416000 0.224000 -0.872000
+-0.150000 0.351500 -0.156300  -0.024000 0.152000 -0.984000
+-0.200000 0.301200 -0.154100  -0.392000 0.112000 -0.904000
+-0.150000 0.301200 -0.169700  -0.080000 0.248000 -0.960000
+-0.150000 0.351500 -0.156300  -0.024000 0.152000 -0.984000
+-0.100000 0.301200 -0.172200  -0.168000 0.416000 -0.888000
+-0.100000 0.351500 -0.158200  0.008000 0.264000 -0.960000
+-0.150000 0.351500 -0.156300  -0.024000 0.152000 -0.984000
+-0.100000 0.401700 -0.143600  0.056000 0.120000 -0.984000
+-0.150000 0.401700 -0.148200  -0.240000 0.400000 -0.872000
+-0.100000 0.451900 -0.142300  -0.128000 0.312000 -0.936000
+-0.150000 0.451900 -0.123200  -0.344000 0.512000 -0.784000
+-0.150000 0.451900 -0.123200  -0.344000 0.512000 -0.784000
+-0.100000 0.044900 -0.121900  0.816000 0.112000 0.552000
+-0.100000 0.044900 -0.121900  0.816000 0.112000 0.552000
+-0.100700 0.050200 -0.121900  0.856000 0.048000 0.504000
+-0.100000 0.050200 -0.123300  0.696000 -0.176000 0.688000
+-0.100000 0.050200 -0.123300  0.696000 -0.176000 0.688000
+-0.100000 0.451900 -0.142300  -0.128000 0.312000 -0.936000
+-0.100000 0.451900 -0.142300  -0.128000 0.312000 -0.936000
+-0.050000 0.451900 -0.137500  0.040000 0.112000 -0.992000
+-0.100000 0.401700 -0.143600  0.056000 0.120000 -0.984000
+-0.050000 0.401700 -0.142300  0.000000 0.168000 -0.984000
+-0.100000 0.351500 -0.158200  0.008000 0.264000 -0.960000
+-0.050000 0.351500 -0.155800  -0.048000 0.328000 -0.936000
+-0.050000 0.401700 -0.142300  0.000000 0.168000 -0.984000
+0.000000 0.351500 -0.164900  -0.080000 0.368000 -0.920000
+0.000000 0.401700 -0.144600  -0.056000 0.192000 -0.976000
+0.050000 0.351500 -0.166400  0.000000 0.392000 -0.912000
+0.050000 0.401700 -0.150400  -0.088000 0.216000 -0.968000
+0.100000 0.351500 -0.169000  0.056000 0.272000 -0.952000
+0.100000 0.401700 -0.152800  -0.048000 0.168000 -0.984000
+0.150000 0.351500 -0.160600  0.144000 0.128000 -0.976000
+0.150000 0.401700 -0.154900  -0.096000 0.088000 -0.984000
+0.200000 0.351500 -0.169700  -0.320000 0.304000 -0.888000
+0.200000 0.401700 -0.169400  -0.056000 0.168000 -0.976000
+0.150000 0.401700 -0.154900  -0.096000 0.088000 -0.984000
+0.200000 0.451900 -0.151000  0.136000 0.400000 -0.896000
+0.150000 0.451900 -0.151900  0.184000 0.376000 -0.904000
+0.200000 0.484800 -0.121900  0.312000 0.872000 0.360000
+0.150000 0.502100 -0.123200  0.032000 0.424000 -0.896000
+0.153400 0.502100 -0.121900  0.448000 0.824000 -0.336000
+0.153400 0.502100 -0.121900  0.448000 0.824000 -0.336000
+-0.089600 0.000000 -0.121900  0.568000 0.512000 0.632000
+-0.089600 0.000000 -0.121900  0.568000 0.512000 0.632000
+-0.050000 0.000000 -0.158900  0.584000 0.336000 0.728000
+-0.050000 -0.024600 -0.121900  0.296000 0.656000 0.688000
+0.000000 0.000000 -0.165000  0.096000 0.640000 0.752000
+0.000000 -0.035500 -0.121900  0.072000 0.496000 0.856000
+0.050000 0.000000 -0.179700  0.216000 0.504000 0.832000
+0.050000 -0.038600 -0.121900  0.000000 0.528000 0.840000
+0.100000 0.000000 -0.179900  0.000000 0.528000 0.840000
+0.100000 -0.037100 -0.121900  -0.016000 0.544000 0.832000
+0.100000 -0.037100 -0.121900  -0.016000 0.544000 0.832000
+-0.054100 -0.401700 -0.121900  0.656000 -0.688000 0.280000
+-0.054100 -0.401700 -0.121900  0.656000 -0.688000 0.280000
+-0.098000 -0.451900 -0.121900  0.712000 -0.680000 0.120000
+-0.061900 -0.401700 -0.182900  0.744000 -0.648000 -0.120000
+-0.098100 -0.451900 -0.182900  0.736000 -0.672000 0.032000
+-0.071000 -0.401700 -0.243900  0.856000 -0.496000 -0.072000
+-0.094700 -0.451900 -0.243900  0.784000 -0.568000 0.216000
+-0.073900 -0.401700 -0.304800  0.784000 -0.304000 -0.528000
+-0.061500 -0.451900 -0.304800  0.928000 -0.352000 0.088000
+-0.100000 -0.401700 -0.330800  0.576000 -0.152000 -0.792000
+-0.100000 -0.451900 -0.336100  0.496000 -0.048000 -0.856000
+-0.150000 -0.401700 -0.364300  0.552000 0.080000 -0.824000
+-0.145700 -0.451900 -0.365800  0.464000 0.040000 -0.880000
+-0.150000 -0.417500 -0.365800  0.544000 0.056000 -0.832000
+-0.150000 -0.451900 -0.368100  0.456000 -0.056000 -0.880000
+-0.145700 -0.451900 -0.365800  0.464000 0.040000 -0.880000
+-0.150000 -0.502100 -0.367300  0.088000 -0.320000 -0.936000
+-0.147100 -0.502100 -0.365800  0.472000 -0.192000 -0.848000
+-0.150000 -0.505900 -0.365800  0.272000 -0.320000 -0.904000
+-0.150000 -0.505900 -0.365800  0.272000 -0.320000 -0.904000
+-0.050000 0.401700 -0.142300  0.000000 0.168000 -0.984000
+-0.050000 0.401700 -0.142300  0.000000 0.168000 -0.984000
+-0.050000 0.451900 -0.137500  0.040000 0.112000 -0.992000
+0.000000 0.401700 -0.144600  -0.056000 0.192000 -0.976000
+0.000000 0.451900 -0.135500  0.000000 0.160000 -0.984000
+0.050000 0.401700 -0.150400  -0.088000 0.216000 -0.968000
+0.050000 0.451900 -0.139600  -0.080000 0.232000 -0.960000
+0.100000 0.401700 -0.152800  -0.048000 0.168000 -0.984000
+0.100000 0.451900 -0.146900  -0.088000 0.224000 -0.968000
+0.150000 0.401700 -0.154900  -0.096000 0.088000 -0.984000
+0.150000 0.451900 -0.151900  0.184000 0.376000 -0.904000
+0.150000 0.451900 -0.151900  0.184000 0.376000 -0.904000
+-0.012800 0.200800 -0.121900  0.688000 -0.616000 0.376000
+-0.012800 0.200800 -0.121900  0.688000 -0.616000 0.376000
+0.000000 0.211400 -0.121900  0.496000 -0.712000 0.480000
+0.000000 0.200800 -0.169000  0.576000 -0.744000 0.320000
+0.000000 0.200800 -0.169000  0.576000 -0.744000 0.320000
+-0.050000 0.150600 -0.159500  0.712000 -0.480000 0.504000
+-0.050000 0.150600 -0.159500  0.712000 -0.480000 0.504000
+-0.033200 0.150600 -0.182900  0.832000 -0.552000 -0.016000
+-0.050000 0.116900 -0.182900  0.944000 -0.304000 0.048000
+-0.050000 0.150600 -0.210200  0.840000 -0.208000 -0.496000
+-0.050000 0.150600 -0.210200  0.840000 -0.208000 -0.496000
+-0.050000 0.047900 -0.182900  0.488000 0.480000 0.720000
+-0.050000 0.047900 -0.182900  0.488000 0.480000 0.720000
+-0.050000 0.000000 -0.158900  0.584000 0.336000 0.728000
+0.000000 0.039200 -0.182900  0.256000 0.544000 0.792000
+0.000000 0.000000 -0.165000  0.096000 0.640000 0.752000
+0.050000 0.005700 -0.182900  0.312000 0.584000 0.744000
+0.050000 0.000000 -0.179700  0.216000 0.504000 0.832000
+0.100000 0.004900 -0.182900  -0.288000 0.864000 0.400000
+0.100000 0.000000 -0.179900  0.000000 0.528000 0.840000
+0.100000 0.000000 -0.179900  0.000000 0.528000 0.840000
+0.000000 0.200800 -0.169000  0.576000 -0.744000 0.320000
+0.000000 0.200800 -0.169000  0.576000 -0.744000 0.320000
+0.008500 0.200800 -0.182900  0.416000 -0.688000 -0.584000
+0.000000 0.195100 -0.182900  0.504000 -0.656000 -0.544000
+0.000000 0.200800 -0.186400  0.272000 -0.456000 -0.840000
+0.000000 0.200800 -0.186400  0.272000 -0.456000 -0.840000
+0.050000 -0.327900 -0.182900  0.552000 -0.824000 0.048000
+0.050000 -0.327900 -0.182900  0.552000 -0.824000 0.048000
+0.003100 -0.351500 -0.182900  0.504000 -0.840000 -0.160000
+0.050000 -0.321600 -0.121900  0.584000 -0.712000 0.376000
+0.006400 -0.351500 -0.121900  0.552000 -0.776000 0.288000
+0.006400 -0.351500 -0.121900  0.552000 -0.776000 0.288000
+0.150000 0.251000 -0.128300  0.144000 -0.904000 0.392000
+0.150000 0.251000 -0.128300  0.144000 -0.904000 0.392000
+0.150000 0.284700 -0.182900  0.352000 0.368000 -0.856000
+0.194700 0.251000 -0.182900  0.496000 -0.104000 -0.856000
+0.150000 0.251000 -0.192500  0.112000 0.024000 -0.992000
+0.150000 0.224100 -0.182900  0.056000 -0.672000 -0.728000
+0.194700 0.251000 -0.182900  0.496000 -0.104000 -0.856000
+0.150000 0.251000 -0.128300  0.144000 -0.904000 0.392000
+0.150000 0.251000 -0.128300  0.144000 -0.904000 0.392000
+0.211500 -0.301200 -0.182900  -0.568000 -0.672000 0.464000
+0.211500 -0.301200 -0.182900  -0.568000 -0.672000 0.464000
+0.250000 -0.301200 -0.149400  -0.376000 -0.584000 0.712000
+0.250000 -0.319600 -0.182900  -0.280000 -0.832000 0.472000
+0.300000 -0.301200 -0.149800  -0.024000 -0.480000 0.872000
+0.300000 -0.330300 -0.182900  -0.312000 -0.696000 0.632000
+0.350000 -0.301200 -0.148100  0.392000 -0.048000 0.912000
+0.331500 -0.351500 -0.182900  -0.432000 -0.576000 0.688000
+0.350000 -0.351500 -0.171100  -0.312000 -0.512000 0.792000
+0.350000 -0.366900 -0.182900  -0.368000 -0.552000 0.736000
+0.400000 -0.351500 -0.165500  0.064000 -0.056000 0.992000
+0.400000 -0.370500 -0.182900  -0.008000 -0.616000 0.776000
+0.450000 -0.351500 -0.174300  0.040000 0.080000 0.992000
+0.450000 -0.370700 -0.182900  -0.080000 -0.520000 0.848000
+0.500000 -0.351500 -0.156800  -0.392000 -0.248000 0.880000
+0.500000 -0.372900 -0.182900  -0.184000 -0.776000 0.592000
+0.450000 -0.370700 -0.182900  -0.080000 -0.520000 0.848000
+0.500000 -0.400600 -0.243900  0.024000 -0.920000 0.384000
+0.450000 -0.401700 -0.212100  0.240000 -0.816000 0.520000
+0.496800 -0.401700 -0.243900  0.256000 -0.880000 0.376000
+0.450000 -0.418500 -0.243900  -0.152000 -0.896000 0.400000
+0.492100 -0.401700 -0.304800  0.152000 -0.576000 -0.792000
+0.450000 -0.411100 -0.304800  -0.144000 -0.808000 -0.560000
+0.450000 -0.401700 -0.316200  -0.184000 -0.360000 -0.904000
+0.428900 -0.401700 -0.304800  -0.392000 -0.464000 -0.784000
+0.450000 -0.380500 -0.304800  -0.144000 0.256000 -0.952000
+0.400000 -0.401700 -0.257800  0.112000 -0.952000 -0.280000
+0.450000 -0.351500 -0.290700  -0.176000 0.632000 -0.744000
+0.400000 -0.388800 -0.304800  0.392000 -0.800000 -0.448000
+0.437100 -0.351500 -0.304800  0.688000 0.472000 -0.536000
+0.400000 -0.351500 -0.338800  0.360000 -0.568000 -0.728000
+0.401200 -0.301200 -0.304800  0.744000 0.488000 -0.440000
+0.400000 -0.301200 -0.307300  0.704000 0.496000 -0.496000
+0.400000 -0.299100 -0.304800  0.736000 0.472000 -0.472000
+0.401200 -0.301200 -0.304800  0.744000 0.488000 -0.440000
+0.400000 -0.252300 -0.243900  0.744000 0.488000 -0.440000
+0.429200 -0.301200 -0.243900  0.816000 0.544000 -0.176000
+0.400000 -0.252800 -0.182900  0.760000 0.464000 0.440000
+0.427100 -0.301200 -0.182900  0.776000 0.464000 0.416000
+0.400000 -0.301200 -0.149800  0.528000 0.376000 0.752000
+0.450000 -0.338000 -0.182900  0.248000 0.592000 0.752000
+0.400000 -0.351500 -0.165500  0.064000 -0.056000 0.992000
+0.450000 -0.351500 -0.174300  0.040000 0.080000 0.992000
+0.450000 -0.338000 -0.182900  0.248000 0.592000 0.752000
+0.500000 -0.351500 -0.156800  -0.392000 -0.248000 0.880000
+0.500000 -0.316400 -0.182900  -0.704000 0.472000 0.520000
+0.450000 -0.338000 -0.182900  0.248000 0.592000 0.752000
+0.500000 -0.310500 -0.243900  -0.600000 0.776000 -0.152000
+0.450000 -0.327300 -0.243900  -0.064000 0.864000 -0.488000
+0.500000 -0.333600 -0.304800  -0.408000 0.824000 -0.376000
+0.450000 -0.351500 -0.290700  -0.176000 0.632000 -0.744000
+0.458900 -0.351500 -0.304800  -0.472000 0.360000 -0.792000
+0.450000 -0.380500 -0.304800  -0.144000 0.256000 -0.952000
+0.500000 -0.400200 -0.304800  -0.176000 -0.672000 -0.712000
+0.492100 -0.401700 -0.304800  0.152000 -0.576000 -0.792000
+0.500000 -0.400600 -0.243900  0.024000 -0.920000 0.384000
+0.496800 -0.401700 -0.243900  0.256000 -0.880000 0.376000
+0.496800 -0.401700 -0.243900  0.256000 -0.880000 0.376000
+0.265700 0.200800 -0.182900  -0.312000 -0.760000 -0.552000
+0.265700 0.200800 -0.182900  -0.312000 -0.760000 -0.552000
+0.300000 0.218000 -0.182900  0.768000 0.424000 -0.464000
+0.300000 0.200800 -0.174500  0.536000 -0.360000 0.752000
+0.306800 0.200800 -0.182900  0.752000 -0.400000 -0.512000
+0.300000 0.193900 -0.182900  0.520000 -0.696000 -0.480000
+0.300000 0.200800 -0.185900  0.256000 -0.192000 -0.944000
+0.265700 0.200800 -0.182900  -0.312000 -0.760000 -0.552000
+0.300000 0.218000 -0.182900  0.768000 0.424000 -0.464000
+0.300000 0.200800 -0.185900  0.256000 -0.192000 -0.944000
+0.306800 0.200800 -0.182900  0.752000 -0.400000 -0.512000
+0.306800 0.200800 -0.182900  0.752000 -0.400000 -0.512000
+0.265700 0.200800 -0.182900  -0.312000 -0.760000 -0.552000
+0.265700 0.200800 -0.182900  -0.312000 -0.760000 -0.552000
+0.300000 0.200800 -0.174500  0.536000 -0.360000 0.752000
+0.300000 0.193900 -0.182900  0.520000 -0.696000 -0.480000
+0.300000 0.193900 -0.182900  0.520000 -0.696000 -0.480000
+0.300000 0.284000 -0.182900  -0.168000 -0.184000 -0.960000
+0.300000 0.284000 -0.182900  -0.168000 -0.184000 -0.960000
+0.300000 0.251000 -0.156100  -0.368000 -0.808000 -0.448000
+0.321900 0.251000 -0.182900  -0.240000 -0.296000 -0.920000
+0.321900 0.251000 -0.182900  -0.240000 -0.296000 -0.920000
+0.307700 -0.050200 -0.121900  -0.592000 0.464000 0.648000
+0.307700 -0.050200 -0.121900  -0.592000 0.464000 0.648000
+0.300000 -0.060700 -0.121900  -0.512000 0.456000 0.720000
+0.300000 -0.050200 -0.130700  -0.504000 0.472000 0.720000
+0.300000 -0.050200 -0.130700  -0.504000 0.472000 0.720000
+0.329200 -0.200800 -0.121900  0.376000 -0.264000 0.880000
+0.329200 -0.200800 -0.121900  0.376000 -0.264000 0.880000
+0.350000 -0.182300 -0.121900  -0.032000 -0.520000 0.848000
+0.350000 -0.200800 -0.137500  0.248000 -0.232000 0.936000
+0.391400 -0.200800 -0.121900  -0.176000 -0.648000 0.736000
+0.391400 -0.200800 -0.121900  -0.176000 -0.648000 0.736000
+0.400000 0.100400 -0.150800  -0.768000 0.376000 0.512000
+0.400000 0.100400 -0.150800  -0.768000 0.376000 0.512000
+0.381500 0.100400 -0.182900  -0.896000 0.440000 -0.008000
+0.400000 0.146600 -0.182900  -0.440000 0.464000 -0.760000
+0.400000 0.100400 -0.207800  -0.424000 0.688000 -0.576000
+0.400000 0.100400 -0.207800  -0.424000 0.688000 -0.576000
+0.400000 -0.203000 -0.121900  -0.184000 -0.672000 0.712000
+0.400000 -0.203000 -0.121900  -0.184000 -0.672000 0.712000
+0.354900 -0.251000 -0.121900  0.704000 -0.304000 0.632000
+0.400000 -0.249800 -0.182900  0.472000 -0.752000 0.448000
+0.398900 -0.251000 -0.182900  0.896000 -0.160000 0.400000
+0.400000 -0.249400 -0.243900  0.760000 -0.472000 -0.424000
+0.399000 -0.251000 -0.243900  0.912000 -0.008000 -0.392000
+0.399000 -0.251000 -0.243900  0.912000 -0.008000 -0.392000
+0.400000 -0.351500 -0.165500  0.064000 -0.056000 0.992000
+0.400000 -0.351500 -0.165500  0.064000 -0.056000 0.992000
+0.350000 -0.351500 -0.171100  -0.312000 -0.512000 0.792000
+0.400000 -0.301200 -0.149800  0.528000 0.376000 0.752000
+0.350000 -0.301200 -0.148100  0.392000 -0.048000 0.912000
+0.350000 -0.301200 -0.148100  0.392000 -0.048000 0.912000
+0.450000 -0.251000 -0.179900  -0.288000 -0.680000 0.664000
+0.450000 -0.251000 -0.179900  -0.288000 -0.680000 0.664000
+0.450000 -0.255300 -0.182900  -0.208000 -0.656000 0.712000
+0.415700 -0.251000 -0.182900  -0.088000 -0.872000 0.480000
+0.450000 -0.251000 -0.203800  -0.216000 -0.960000 -0.144000
+0.450000 -0.251000 -0.203800  -0.216000 -0.960000 -0.144000
+0.500000 0.355500 -0.182900  0.400000 0.616000 -0.664000
+0.500000 0.355500 -0.182900  0.400000 0.616000 -0.664000
+0.506000 0.351500 -0.182900  0.424000 0.584000 -0.680000
+0.500000 0.393600 -0.121900  0.504000 0.744000 -0.432000
+0.550000 0.351500 -0.135900  0.456000 0.632000 -0.616000
+0.550000 0.362300 -0.121900  0.400000 0.656000 -0.632000
+0.566700 0.351500 -0.121900  0.448000 0.536000 -0.704000
+0.566700 0.351500 -0.121900  0.448000 0.536000 -0.704000
+0.550000 0.351500 -0.135900  0.456000 0.632000 -0.616000
+0.550000 0.351500 -0.135900  0.456000 0.632000 -0.616000
+0.550000 0.301200 -0.167400  0.408000 0.504000 -0.752000
+0.506000 0.351500 -0.182900  0.424000 0.584000 -0.680000
+0.526000 0.301200 -0.182900  0.408000 0.312000 -0.848000
+0.500000 0.351500 -0.187300  0.416000 0.568000 -0.696000
+0.500000 0.301200 -0.193500  0.168000 0.072000 -0.976000
+0.526000 0.301200 -0.182900  0.408000 0.312000 -0.848000
+0.500000 0.251000 -0.199400  0.072000 0.096000 -0.984000
+0.550000 0.283200 -0.182900  0.320000 0.472000 -0.816000
+0.550000 0.251000 -0.199600  0.176000 0.288000 -0.936000
+0.500000 0.251000 -0.199400  0.072000 0.096000 -0.984000
+0.550000 0.200800 -0.211100  0.016000 0.048000 -0.992000
+0.500000 0.200800 -0.200200  -0.104000 -0.048000 -0.992000
+0.550000 0.150600 -0.215400  -0.144000 0.080000 -0.984000
+0.500000 0.150600 -0.194400  -0.208000 0.240000 -0.944000
+0.550000 0.100400 -0.212600  -0.200000 0.352000 -0.904000
+0.500000 0.100400 -0.210700  0.048000 0.704000 -0.704000
+0.550000 0.067800 -0.243900  0.024000 0.672000 -0.728000
+0.500000 0.082500 -0.243900  0.216000 0.832000 -0.504000
+0.550000 0.050200 -0.258400  0.160000 0.632000 -0.752000
+0.500000 0.050200 -0.303800  0.264000 0.816000 -0.504000
+0.550000 0.015600 -0.304800  0.472000 0.712000 -0.512000
+0.500000 0.049600 -0.304800  0.264000 0.736000 -0.616000
+0.550000 0.000000 -0.335900  0.576000 0.464000 -0.664000
+0.500000 0.014000 -0.365800  0.216000 0.784000 -0.568000
+0.524100 0.000000 -0.365800  0.648000 0.312000 -0.688000
+0.500000 0.000000 -0.393700  0.528000 0.072000 -0.840000
+0.500000 -0.027200 -0.365800  0.264000 -0.576000 -0.768000
+0.524100 0.000000 -0.365800  0.648000 0.312000 -0.688000
+0.500000 -0.050200 -0.339600  -0.136000 -0.672000 -0.720000
+0.550000 0.000000 -0.335900  0.576000 0.464000 -0.664000
+0.550000 -0.050200 -0.345500  0.192000 -0.560000 -0.792000
+0.550000 -0.050200 -0.345500  0.192000 -0.560000 -0.792000
+0.526000 0.301200 -0.182900  0.408000 0.312000 -0.848000
+0.526000 0.301200 -0.182900  0.408000 0.312000 -0.848000
+0.550000 0.283200 -0.182900  0.320000 0.472000 -0.816000
+0.550000 0.301200 -0.167400  0.408000 0.504000 -0.752000
+0.550000 0.301200 -0.167400  0.408000 0.504000 -0.752000
+0.500000 -0.250100 -0.121900  -0.432000 -0.712000 0.536000
+0.500000 -0.250100 -0.121900  -0.432000 -0.712000 0.536000
+0.501100 -0.251000 -0.121900  -0.552000 -0.624000 0.544000
+0.500000 -0.251000 -0.123800  -0.544000 -0.688000 0.456000
+0.500000 -0.251000 -0.123800  -0.544000 -0.688000 0.456000
+0.608400 0.251000 -0.182900  0.328000 0.488000 -0.800000
+0.608400 0.251000 -0.182900  0.328000 0.488000 -0.800000
+0.650000 0.227800 -0.182900  0.368000 0.576000 -0.720000
+0.650000 0.251000 -0.154700  0.488000 0.640000 -0.584000
+0.650000 0.251000 -0.154700  0.488000 0.640000 -0.584000
+0.600000 -0.333000 -0.121900  0.024000 -0.312000 0.944000
+0.600000 -0.333000 -0.121900  0.024000 -0.312000 0.944000
+0.600000 -0.351500 -0.136300  0.144000 -0.792000 0.584000
+0.650000 -0.327200 -0.121900  -0.280000 -0.536000 0.792000
+0.650000 -0.351500 -0.143500  -0.280000 -0.536000 0.784000
+0.679500 -0.351500 -0.121900  -0.424000 -0.464000 0.768000
+0.650000 -0.401700 -0.175000  -0.240000 -0.688000 0.680000
+0.700000 -0.372000 -0.121900  -0.360000 -0.440000 0.816000
+0.700000 -0.401700 -0.145100  -0.400000 -0.504000 0.752000
+0.737900 -0.401700 -0.121900  -0.352000 -0.448000 0.816000
+0.700000 -0.435200 -0.182900  -0.448000 -0.712000 0.536000
+0.750000 -0.411100 -0.121900  -0.304000 -0.456000 0.824000
+0.719600 -0.451900 -0.182900  -0.568000 -0.640000 0.512000
+0.750000 -0.451900 -0.153800  -0.384000 -0.528000 0.752000
+0.750000 -0.479900 -0.182900  -0.456000 -0.632000 0.616000
+0.719600 -0.451900 -0.182900  -0.568000 -0.640000 0.512000
+0.750000 -0.502100 -0.236900  -0.448000 -0.776000 0.432000
+0.700000 -0.451900 -0.215800  -0.528000 -0.696000 0.472000
+0.744200 -0.502100 -0.243900  -0.480000 -0.864000 0.128000
+0.700000 -0.472400 -0.243900  -0.560000 -0.816000 -0.016000
+0.750000 -0.502100 -0.254300  -0.448000 -0.832000 -0.312000
+0.700000 -0.481300 -0.304800  -0.240000 -0.712000 -0.656000
+0.750000 -0.487000 -0.304800  -0.104000 -0.744000 -0.656000
+0.700000 -0.451900 -0.321600  -0.136000 -0.312000 -0.936000
+0.750000 -0.451900 -0.330900  0.152000 -0.080000 -0.984000
+0.700000 -0.401700 -0.334100  0.120000 -0.128000 -0.976000
+0.750000 -0.401700 -0.321600  0.336000 0.000000 -0.936000
+0.700000 -0.351500 -0.333900  0.344000 -0.040000 -0.936000
+0.750000 -0.351500 -0.307800  0.512000 0.128000 -0.840000
+0.700000 -0.301200 -0.354900  0.160000 -0.240000 -0.952000
+0.750000 -0.334300 -0.304800  0.512000 0.112000 -0.840000
+0.744500 -0.301200 -0.304800  0.640000 0.104000 -0.760000
+0.750000 -0.301200 -0.299800  0.512000 0.144000 -0.840000
+0.728900 -0.251000 -0.304800  0.720000 0.440000 -0.528000
+0.750000 -0.251000 -0.256700  0.824000 0.520000 -0.208000
+0.700000 -0.211400 -0.304800  0.288000 0.624000 -0.720000
+0.750000 -0.247000 -0.243900  0.832000 0.536000 -0.096000
+0.700000 -0.200800 -0.294000  0.576000 0.608000 -0.536000
+0.717800 -0.200800 -0.243900  0.824000 0.560000 -0.064000
+0.700000 -0.175300 -0.243900  0.752000 0.600000 -0.240000
+0.713600 -0.200800 -0.182900  0.824000 0.512000 0.224000
+0.700000 -0.178500 -0.182900  0.792000 0.568000 0.200000
+0.700000 -0.200800 -0.144600  0.696000 0.528000 0.480000
+0.700000 -0.200800 -0.144600  0.696000 0.528000 0.480000
+0.600000 -0.351500 -0.136300  0.144000 -0.792000 0.584000
+0.600000 -0.351500 -0.136300  0.144000 -0.792000 0.584000
+0.650000 -0.351500 -0.143500  -0.280000 -0.536000 0.784000
+0.600000 -0.392700 -0.182900  -0.184000 -0.752000 0.624000
+0.650000 -0.401700 -0.175000  -0.240000 -0.688000 0.680000
+0.628900 -0.401700 -0.182900  -0.216000 -0.760000 0.608000
+0.650000 -0.407700 -0.182900  -0.272000 -0.728000 0.624000
+0.600000 -0.401700 -0.203000  -0.208000 -0.872000 0.432000
+0.650000 -0.436800 -0.243900  -0.416000 -0.848000 0.320000
+0.600000 -0.414700 -0.243900  -0.184000 -0.936000 0.272000
+0.650000 -0.449600 -0.304800  -0.280000 -0.432000 -0.848000
+0.600000 -0.422100 -0.304800  -0.120000 -0.768000 -0.616000
+0.650000 -0.401700 -0.330300  -0.240000 -0.360000 -0.896000
+0.600000 -0.401700 -0.327900  -0.024000 -0.544000 -0.832000
+0.650000 -0.351500 -0.332000  0.016000 -0.144000 -0.984000
+0.600000 -0.351500 -0.337900  0.040000 -0.080000 -0.992000
+0.650000 -0.301200 -0.350300  0.016000 -0.440000 -0.888000
+0.600000 -0.301200 -0.352300  -0.528000 -0.312000 -0.776000
+0.600000 -0.301200 -0.352300  -0.528000 -0.312000 -0.776000
+0.650000 0.278000 -0.121900  0.448000 0.624000 -0.624000
+0.650000 0.278000 -0.121900  0.448000 0.624000 -0.624000
+0.650000 0.251000 -0.154700  0.488000 0.640000 -0.584000
+0.673000 0.251000 -0.121900  0.568000 0.576000 -0.584000
+0.673000 0.251000 -0.121900  0.568000 0.576000 -0.584000
+0.700000 -0.401700 -0.145100  -0.400000 -0.504000 0.752000
+0.700000 -0.401700 -0.145100  -0.400000 -0.504000 0.752000
+0.650000 -0.401700 -0.175000  -0.240000 -0.688000 0.680000
+0.700000 -0.435200 -0.182900  -0.448000 -0.712000 0.536000
+0.650000 -0.407700 -0.182900  -0.272000 -0.728000 0.624000
+0.700000 -0.451900 -0.215800  -0.528000 -0.696000 0.472000
+0.650000 -0.436800 -0.243900  -0.416000 -0.848000 0.320000
+0.673600 -0.451900 -0.243900  -0.480000 -0.752000 0.448000
+0.650000 -0.449600 -0.304800  -0.280000 -0.432000 -0.848000
+0.653100 -0.451900 -0.304800  -0.336000 -0.480000 -0.800000
+0.650000 -0.401700 -0.330300  -0.240000 -0.360000 -0.896000
+0.700000 -0.451900 -0.321600  -0.136000 -0.312000 -0.936000
+0.700000 -0.401700 -0.334100  0.120000 -0.128000 -0.976000
+0.650000 -0.401700 -0.330300  -0.240000 -0.360000 -0.896000
+0.700000 -0.351500 -0.333900  0.344000 -0.040000 -0.936000
+0.650000 -0.351500 -0.332000  0.016000 -0.144000 -0.984000
+0.700000 -0.301200 -0.354900  0.160000 -0.240000 -0.952000
+0.650000 -0.301200 -0.350300  0.016000 -0.440000 -0.888000
+0.650000 -0.301200 -0.350300  0.016000 -0.440000 -0.888000
+0.719200 -0.251000 -0.121900  0.760000 0.456000 0.440000
+0.719200 -0.251000 -0.121900  0.760000 0.456000 0.440000
+0.750000 -0.297400 -0.121900  0.656000 0.584000 0.464000
+0.746300 -0.251000 -0.182900  0.848000 0.496000 0.152000
+0.750000 -0.257500 -0.182900  0.856000 0.488000 0.120000
+0.750000 -0.251000 -0.218200  0.840000 0.520000 0.096000
+0.777000 -0.301200 -0.182900  0.784000 0.536000 0.304000
+0.752500 -0.251000 -0.243900  0.840000 0.528000 -0.096000
+0.780500 -0.301200 -0.243900  0.848000 0.504000 -0.128000
+0.777000 -0.301200 -0.182900  0.784000 0.536000 0.304000
+0.800000 -0.328800 -0.243900  0.640000 0.656000 -0.384000
+0.800000 -0.333100 -0.182900  0.680000 0.680000 0.256000
+0.829500 -0.351500 -0.243900  0.648000 0.640000 -0.400000
+0.821300 -0.351500 -0.182900  0.624000 0.648000 0.416000
+0.850000 -0.375700 -0.243900  0.544000 0.616000 -0.552000
+0.850000 -0.381900 -0.182900  0.632000 0.696000 0.328000
+0.890600 -0.401700 -0.243900  0.576000 0.616000 -0.528000
+0.872200 -0.401700 -0.182900  0.632000 0.640000 0.416000
+0.900000 -0.412700 -0.243900  0.520000 0.640000 -0.552000
+0.900000 -0.433800 -0.182900  0.512000 0.688000 0.504000
+0.950000 -0.433400 -0.243900  0.528000 0.832000 0.152000
+0.933400 -0.451900 -0.182900  0.464000 0.712000 0.512000
+0.950000 -0.451900 -0.206400  0.504000 0.736000 0.440000
+0.950000 -0.463500 -0.182900  0.464000 0.672000 0.568000
+0.933400 -0.451900 -0.182900  0.464000 0.712000 0.512000
+0.950000 -0.502100 -0.136000  -0.296000 0.400000 0.864000
+0.900000 -0.451900 -0.156900  0.400000 0.632000 0.656000
+0.900000 -0.502100 -0.123800  -0.168000 -0.208000 0.960000
+0.850000 -0.451900 -0.123600  0.328000 0.296000 0.888000
+0.850000 -0.502100 -0.142100  -0.224000 -0.520000 0.816000
+0.850000 -0.502100 -0.142100  -0.224000 -0.520000 0.816000
+0.750000 -0.257500 -0.182900  0.856000 0.488000 0.120000
+0.750000 -0.257500 -0.182900  0.856000 0.488000 0.120000
+0.750000 -0.297400 -0.121900  0.656000 0.584000 0.464000
+0.777000 -0.301200 -0.182900  0.784000 0.536000 0.304000
+0.752700 -0.301200 -0.121900  0.792000 0.344000 0.488000
+0.800000 -0.333100 -0.182900  0.680000 0.680000 0.256000
+0.775700 -0.351500 -0.121900  0.600000 0.328000 0.720000
+0.800000 -0.351500 -0.149400  0.664000 0.512000 0.528000
+0.800000 -0.391100 -0.121900  0.384000 0.416000 0.816000
+0.821300 -0.351500 -0.182900  0.624000 0.648000 0.416000
+0.810500 -0.401700 -0.121900  0.456000 0.104000 0.872000
+0.850000 -0.381900 -0.182900  0.632000 0.696000 0.328000
+0.850000 -0.401700 -0.151500  0.608000 0.552000 0.560000
+0.872200 -0.401700 -0.182900  0.632000 0.640000 0.416000
+0.850000 -0.451900 -0.123600  0.328000 0.296000 0.888000
+0.900000 -0.433800 -0.182900  0.512000 0.688000 0.504000
+0.900000 -0.451900 -0.156900  0.400000 0.632000 0.656000
+0.933400 -0.451900 -0.182900  0.464000 0.712000 0.512000
+0.933400 -0.451900 -0.182900  0.464000 0.712000 0.512000
+0.783200 -0.502100 -0.182900  -0.448000 -0.720000 0.512000
+0.783200 -0.502100 -0.182900  -0.448000 -0.720000 0.512000
+0.800000 -0.502100 -0.171200  -0.360000 -0.648000 0.664000
+0.800000 -0.511100 -0.182900  -0.376000 -0.744000 0.544000
+0.800000 -0.511100 -0.182900  -0.376000 -0.744000 0.544000
+0.800000 -0.333100 -0.182900  0.680000 0.680000 0.256000
+0.800000 -0.333100 -0.182900  0.680000 0.680000 0.256000
+0.821300 -0.351500 -0.182900  0.624000 0.648000 0.416000
+0.800000 -0.351500 -0.149400  0.664000 0.512000 0.528000
+0.800000 -0.351500 -0.149400  0.664000 0.512000 0.528000
+0.900000 -0.552300 -0.159100  -0.496000 -0.592000 0.632000
+0.900000 -0.552300 -0.159100  -0.496000 -0.592000 0.632000
+0.900000 -0.573700 -0.182900  -0.608000 -0.704000 0.344000
+0.876500 -0.552300 -0.182900  -0.528000 -0.672000 0.504000
+0.900000 -0.578300 -0.243900  -0.552000 -0.704000 -0.440000
+0.868400 -0.552300 -0.243900  -0.552000 -0.760000 -0.328000
+0.900000 -0.552300 -0.278500  -0.424000 -0.592000 -0.672000
+0.900000 -0.552300 -0.278500  -0.424000 -0.592000 -0.672000
+0.900000 0.127900 -0.121900  0.560000 0.776000 -0.264000
+0.900000 0.127900 -0.121900  0.560000 0.776000 -0.264000
+0.931600 0.100400 -0.121900  0.600000 0.744000 -0.272000
+0.900000 0.111100 -0.182900  0.552000 0.712000 -0.416000
+0.912000 0.100400 -0.182900  0.600000 0.704000 -0.360000
+0.900000 0.100400 -0.203200  0.536000 0.688000 -0.472000
+0.900000 0.100400 -0.203200  0.536000 0.688000 -0.472000
+0.950000 -0.602500 -0.169200  -0.536000 -0.520000 0.656000
+0.950000 -0.602500 -0.169200  -0.536000 -0.520000 0.656000
+0.950000 -0.619400 -0.182900  -0.632000 -0.592000 0.480000
+0.935000 -0.602500 -0.182900  -0.552000 -0.552000 0.608000
+0.950000 -0.619400 -0.243900  -0.600000 -0.584000 -0.536000
+0.933200 -0.602500 -0.243900  -0.584000 -0.624000 -0.512000
+0.950000 -0.602500 -0.260200  -0.544000 -0.504000 -0.664000
+0.950000 -0.602500 -0.260200  -0.544000 -0.504000 -0.664000
+1.000000 -0.251000 -0.154300  -0.728000 -0.648000 0.200000
+1.000000 -0.251000 -0.154300  -0.728000 -0.648000 0.200000
+1.000000 -0.258900 -0.182900  -0.752000 -0.616000 0.208000
+0.993400 -0.251000 -0.182900  -0.736000 -0.640000 0.200000
+1.000000 -0.277900 -0.243900  -0.712000 -0.592000 0.360000
+0.978600 -0.251000 -0.243900  -0.696000 -0.616000 0.352000
+0.978600 -0.251000 -0.243900  -0.696000 -0.616000 0.352000
+0.950000 -0.560000 -0.121900  -0.400000 -0.536000 0.728000
+0.950000 -0.560000 -0.121900  -0.400000 -0.536000 0.728000
+0.992300 -0.602500 -0.121900  -0.520000 -0.480000 0.696000
+0.950000 -0.602500 -0.169200  -0.536000 -0.520000 0.656000
+0.950000 -0.602500 -0.169200  -0.536000 -0.520000 0.656000
+1.000000 -0.652700 -0.168000  -0.488000 -0.568000 0.656000
+1.000000 -0.652700 -0.168000  -0.488000 -0.568000 0.656000
+1.000000 -0.666200 -0.182900  -0.536000 -0.632000 0.544000
+0.983200 -0.652700 -0.182900  -0.528000 -0.608000 0.584000
+1.000000 -0.673300 -0.243900  -0.656000 -0.656000 -0.368000
+0.979500 -0.652700 -0.243900  -0.672000 -0.664000 -0.304000
+1.000000 -0.652700 -0.268800  -0.592000 -0.512000 -0.608000
+1.000000 -0.652700 -0.268800  -0.592000 -0.512000 -0.608000
+-1.000000 0.256900 -0.182900  0.288000 0.752000 -0.584000
+-1.000000 0.256900 -0.182900  0.288000 0.752000 -0.584000
+-1.000000 0.251000 -0.191500  0.280000 0.728000 -0.616000
+-0.985000 0.251000 -0.182900  0.288000 0.752000 -0.576000
+-0.985000 0.251000 -0.182900  0.288000 0.752000 -0.576000
+-0.980800 0.200800 -0.243900  0.232000 0.632000 -0.736000
+-0.980800 0.200800 -0.243900  0.232000 0.632000 -0.736000
+-0.950000 0.189400 -0.243900  0.264000 0.616000 -0.728000
+-0.950000 0.200800 -0.231900  0.272000 0.640000 -0.704000
+-0.950000 0.200800 -0.231900  0.272000 0.640000 -0.704000
+-0.900000 0.214200 -0.182900  0.360000 0.720000 -0.576000
+-0.900000 0.214200 -0.182900  0.360000 0.720000 -0.576000
+-0.900000 0.200800 -0.201400  0.352000 0.680000 -0.640000
+-0.874200 0.200800 -0.182900  0.360000 0.712000 -0.584000
+-0.874200 0.200800 -0.182900  0.360000 0.712000 -0.584000
+-0.878700 0.150600 -0.243900  0.328000 0.616000 -0.704000
+-0.878700 0.150600 -0.243900  0.328000 0.616000 -0.704000
+-0.850000 0.135500 -0.243900  0.320000 0.608000 -0.712000
+-0.850000 0.150600 -0.229000  0.320000 0.608000 -0.720000
+-0.850000 0.150600 -0.229000  0.320000 0.608000 -0.720000
+-0.900000 -0.542100 -0.182900  -0.808000 -0.560000 0.136000
+-0.900000 -0.542100 -0.182900  -0.808000 -0.560000 0.136000
+-0.900000 -0.551700 -0.243900  -0.808000 -0.568000 -0.120000
+-0.892400 -0.552300 -0.182900  -0.760000 -0.624000 0.176000
+-0.899500 -0.552300 -0.243900  -0.800000 -0.592000 -0.072000
+-0.850000 -0.592600 -0.182900  -0.520000 -0.800000 0.264000
+-0.851300 -0.602500 -0.243900  -0.680000 -0.720000 -0.008000
+-0.850000 -0.602500 -0.238600  -0.616000 -0.752000 0.216000
+-0.850000 -0.603800 -0.243900  -0.656000 -0.744000 0.064000
+-0.832500 -0.602500 -0.182900  -0.576000 -0.768000 0.272000
+-0.800000 -0.632800 -0.243900  -0.432000 -0.896000 0.072000
+-0.800000 -0.620600 -0.182900  -0.312000 -0.880000 0.336000
+-0.750000 -0.646000 -0.243900  -0.088000 -0.984000 0.144000
+-0.750000 -0.630100 -0.182900  -0.144000 -0.912000 0.360000
+-0.750000 -0.630100 -0.182900  -0.144000 -0.912000 0.360000
+-0.820300 -0.502100 -0.182900  0.496000 0.792000 0.344000
+-0.820300 -0.502100 -0.182900  0.496000 0.792000 0.344000
+-0.800000 -0.502100 -0.227500  0.432000 0.824000 0.352000
+-0.800000 -0.513200 -0.182900  -0.080000 0.880000 0.456000
+-0.750000 -0.502100 -0.184800  -0.496000 0.696000 0.496000
+-0.750000 -0.503000 -0.182900  -0.200000 0.848000 0.472000
+-0.749300 -0.502100 -0.182900  -0.920000 -0.232000 0.288000
+-0.750000 -0.502100 -0.184800  -0.496000 0.696000 0.496000
+-0.750000 -0.499500 -0.182900  -0.936000 -0.200000 0.264000
+-0.750000 -0.499500 -0.182900  -0.936000 -0.200000 0.264000
+-0.850000 -0.592600 -0.182900  -0.520000 -0.800000 0.264000
+-0.850000 -0.592600 -0.182900  -0.520000 -0.800000 0.264000
+-0.832500 -0.602500 -0.182900  -0.576000 -0.768000 0.272000
+-0.850000 -0.602500 -0.238600  -0.616000 -0.752000 0.216000
+-0.850000 -0.602500 -0.238600  -0.616000 -0.752000 0.216000
+-0.650000 0.045800 -0.182900  0.672000 0.432000 -0.592000
+-0.650000 0.045800 -0.182900  0.672000 0.432000 -0.592000
+-0.650000 0.000000 -0.224600  0.632000 0.368000 -0.672000
+-0.621400 0.000000 -0.182900  0.848000 0.280000 -0.440000
+-0.621400 0.000000 -0.182900  0.848000 0.280000 -0.440000
+-0.600000 -0.629300 -0.182900  0.072000 -0.968000 0.224000
+-0.600000 -0.629300 -0.182900  0.072000 -0.968000 0.224000
+-0.600000 -0.640700 -0.243900  0.080000 -0.976000 0.192000
+-0.550000 -0.618800 -0.182900  0.168000 -0.944000 0.272000
+-0.550000 -0.629900 -0.243900  0.160000 -0.960000 0.200000
+-0.500000 -0.610400 -0.182900  -0.136000 -0.936000 0.304000
+-0.500000 -0.625200 -0.243900  -0.096000 -0.960000 0.240000
+-0.550000 -0.629900 -0.243900  0.160000 -0.960000 0.200000
+-0.500000 -0.637800 -0.304800  -0.208000 -0.976000 -0.032000
+-0.550000 -0.639800 -0.304800  0.152000 -0.984000 0.000000
+-0.500000 -0.633000 -0.365800  -0.088000 -0.968000 -0.200000
+-0.550000 -0.637200 -0.365800  0.152000 -0.968000 -0.168000
+-0.550000 -0.639800 -0.304800  0.152000 -0.984000 0.000000
+-0.600000 -0.645500 -0.365800  0.016000 -0.968000 -0.216000
+-0.600000 -0.650800 -0.304800  0.064000 -0.992000 0.000000
+-0.550000 -0.639800 -0.304800  0.152000 -0.984000 0.000000
+-0.600000 -0.640700 -0.243900  0.080000 -0.976000 0.192000
+-0.550000 -0.629900 -0.243900  0.160000 -0.960000 0.200000
+-0.550000 -0.629900 -0.243900  0.160000 -0.960000 0.200000
+-0.403600 -0.100400 -0.182900  -0.616000 0.592000 -0.512000
+-0.403600 -0.100400 -0.182900  -0.616000 0.592000 -0.512000
+-0.400000 -0.100400 -0.188300  -0.616000 0.576000 -0.520000
+-0.400000 -0.096400 -0.182900  -0.664000 0.552000 -0.496000
+-0.354400 -0.100400 -0.243900  -0.584000 0.448000 -0.664000
+-0.365500 -0.050200 -0.182900  -0.728000 0.384000 -0.560000
+-0.350000 -0.093900 -0.243900  -0.600000 0.408000 -0.680000
+-0.350000 -0.050200 -0.209400  -0.696000 0.392000 -0.584000
+-0.321700 -0.050200 -0.243900  -0.656000 0.344000 -0.656000
+-0.350000 -0.016600 -0.182900  -0.688000 0.360000 -0.616000
+-0.301700 0.000000 -0.243900  -0.744000 0.392000 -0.536000
+-0.340600 0.000000 -0.182900  -0.696000 0.480000 -0.520000
+-0.340600 0.000000 -0.182900  -0.696000 0.480000 -0.520000
+-0.444500 -0.150600 -0.243900  -0.312000 0.784000 -0.528000
+-0.444500 -0.150600 -0.243900  -0.312000 0.784000 -0.528000
+-0.450000 -0.150600 -0.239400  -0.408000 0.792000 -0.448000
+-0.450000 -0.152500 -0.243900  -0.384000 0.800000 -0.448000
+-0.450000 -0.152500 -0.243900  -0.384000 0.800000 -0.448000
+-0.400000 -0.651500 -0.182900  -0.552000 -0.472000 0.672000
+-0.400000 -0.651500 -0.182900  -0.552000 -0.472000 0.672000
+-0.400000 -0.652700 -0.184800  -0.640000 -0.536000 0.536000
+-0.450000 -0.629600 -0.182900  -0.344000 -0.872000 0.320000
+-0.428400 -0.652700 -0.243900  -0.584000 -0.736000 0.336000
+-0.450000 -0.644000 -0.243900  -0.352000 -0.912000 0.200000
+-0.450000 -0.652700 -0.293400  -0.288000 -0.936000 0.160000
+-0.428400 -0.652700 -0.243900  -0.584000 -0.736000 0.336000
+-0.450000 -0.654300 -0.304800  -0.272000 -0.952000 0.040000
+-0.400000 -0.663600 -0.243900  -0.504000 -0.840000 0.160000
+-0.400000 -0.672200 -0.304800  -0.400000 -0.904000 -0.128000
+-0.363900 -0.703000 -0.243900  -0.784000 -0.584000 0.176000
+-0.371300 -0.703000 -0.304800  -0.816000 -0.552000 -0.144000
+-0.350000 -0.730400 -0.243900  -0.544000 -0.776000 0.296000
+-0.350000 -0.747900 -0.304800  -0.512000 -0.832000 -0.184000
+-0.300000 -0.736500 -0.243900  0.320000 -0.832000 0.440000
+-0.330700 -0.753200 -0.304800  -0.192000 -0.968000 -0.112000
+-0.300000 -0.753200 -0.286100  0.088000 -0.928000 0.352000
+-0.300000 -0.758500 -0.304800  0.104000 -0.976000 -0.144000
+-0.281500 -0.753200 -0.304800  0.312000 -0.920000 -0.216000
+-0.300000 -0.753200 -0.317300  0.136000 -0.840000 -0.512000
+-0.300000 -0.758500 -0.304800  0.104000 -0.976000 -0.144000
+-0.330700 -0.753200 -0.304800  -0.192000 -0.968000 -0.112000
+-0.300000 -0.753200 -0.317300  0.136000 -0.840000 -0.512000
+-0.350000 -0.747900 -0.304800  -0.512000 -0.832000 -0.184000
+-0.300000 -0.703000 -0.365100  0.056000 -0.232000 -0.968000
+-0.350000 -0.703000 -0.357000  -0.336000 -0.496000 -0.792000
+-0.300000 -0.687100 -0.365800  0.104000 -0.048000 -0.992000
+-0.350000 -0.679200 -0.365800  -0.072000 -0.176000 -0.976000
+-0.350000 -0.703000 -0.357000  -0.336000 -0.496000 -0.792000
+-0.400000 -0.653700 -0.365800  -0.176000 -0.888000 -0.416000
+-0.371300 -0.703000 -0.304800  -0.816000 -0.552000 -0.144000
+-0.400000 -0.672200 -0.304800  -0.400000 -0.904000 -0.128000
+-0.400000 -0.672200 -0.304800  -0.400000 -0.904000 -0.128000
+-0.428400 -0.652700 -0.243900  -0.584000 -0.736000 0.336000
+-0.428400 -0.652700 -0.243900  -0.584000 -0.736000 0.336000
+-0.400000 -0.652700 -0.184800  -0.640000 -0.536000 0.536000
+-0.400000 -0.663600 -0.243900  -0.504000 -0.840000 0.160000
+-0.396000 -0.652700 -0.182900  -0.176000 0.000000 0.984000
+-0.363900 -0.703000 -0.243900  -0.784000 -0.584000 0.176000
+-0.350700 -0.703000 -0.182900  -0.792000 -0.176000 0.576000
+-0.350000 -0.730400 -0.243900  -0.544000 -0.776000 0.296000
+-0.350000 -0.704300 -0.182900  -0.112000 -0.808000 0.576000
+-0.300000 -0.736500 -0.243900  0.320000 -0.832000 0.440000
+-0.300000 -0.708000 -0.182900  0.360000 -0.768000 0.520000
+-0.300000 -0.708000 -0.182900  0.360000 -0.768000 0.520000
+-0.365500 -0.050200 -0.182900  -0.728000 0.384000 -0.560000
+-0.365500 -0.050200 -0.182900  -0.728000 0.384000 -0.560000
+-0.350000 -0.050200 -0.209400  -0.696000 0.392000 -0.584000
+-0.350000 -0.016600 -0.182900  -0.688000 0.360000 -0.616000
+-0.350000 -0.016600 -0.182900  -0.688000 0.360000 -0.616000
+-0.400000 -0.100400 -0.188300  -0.616000 0.576000 -0.520000
+-0.400000 -0.100400 -0.188300  -0.616000 0.576000 -0.520000
+-0.400000 -0.131400 -0.243900  -0.384000 0.744000 -0.536000
+-0.354400 -0.100400 -0.243900  -0.584000 0.448000 -0.664000
+-0.400000 -0.150600 -0.272200  -0.312000 0.624000 -0.704000
+-0.350000 -0.100400 -0.248500  -0.576000 0.440000 -0.680000
+-0.350000 -0.150600 -0.298700  -0.264000 0.464000 -0.840000
+-0.400000 -0.150600 -0.272200  -0.312000 0.624000 -0.704000
+-0.350000 -0.159400 -0.304800  -0.248000 0.528000 -0.808000
+-0.400000 -0.174400 -0.304800  -0.224000 0.736000 -0.632000
+-0.350000 -0.200800 -0.339000  0.200000 0.416000 -0.880000
+-0.400000 -0.200800 -0.333600  -0.064000 0.568000 -0.816000
+-0.350000 -0.248400 -0.365800  0.184000 0.424000 -0.880000
+-0.400000 -0.239300 -0.365800  0.048000 0.512000 -0.848000
+-0.350000 -0.251000 -0.367200  0.240000 0.168000 -0.952000
+-0.400000 -0.251000 -0.373300  0.080000 0.400000 -0.904000
+-0.350000 -0.301200 -0.377400  0.232000 0.208000 -0.944000
+-0.400000 -0.301200 -0.390900  0.144000 0.296000 -0.936000
+-0.350000 -0.351500 -0.416300  -0.176000 0.600000 -0.768000
+-0.400000 -0.351500 -0.411400  0.000000 0.616000 -0.784000
+-0.400000 -0.351500 -0.411400  0.000000 0.616000 -0.784000
+-0.350000 -0.647900 -0.182900  0.008000 0.768000 0.624000
+-0.350000 -0.647900 -0.182900  0.008000 0.768000 0.624000
+-0.386500 -0.602500 -0.182900  0.376000 -0.032000 0.920000
+-0.350000 -0.630200 -0.243900  -0.144000 0.776000 0.600000
+-0.371400 -0.602500 -0.243900  0.928000 0.016000 0.352000
+-0.371400 -0.602500 -0.243900  0.928000 0.016000 0.352000
+-0.200000 0.172600 -0.182900  -0.488000 0.416000 -0.760000
+-0.200000 0.172600 -0.182900  -0.488000 0.416000 -0.760000
+-0.216700 0.150600 -0.182900  -0.560000 0.376000 -0.728000
+-0.200000 0.150600 -0.197300  -0.488000 0.464000 -0.728000
+-0.249100 0.100400 -0.182900  -0.576000 0.496000 -0.640000
+-0.200000 0.100400 -0.242800  -0.520000 0.512000 -0.672000
+-0.200000 0.100400 -0.242800  -0.520000 0.512000 -0.672000
+-0.200000 0.172600 -0.182900  -0.488000 0.416000 -0.760000
+-0.200000 0.172600 -0.182900  -0.488000 0.416000 -0.760000
+-0.200000 0.150600 -0.197300  -0.488000 0.464000 -0.728000
+-0.173800 0.200800 -0.182900  -0.480000 0.344000 -0.800000
+-0.150000 0.150600 -0.235500  -0.296000 0.536000 -0.784000
+-0.150000 0.200800 -0.199200  -0.328000 0.272000 -0.896000
+-0.150000 0.200800 -0.199200  -0.328000 0.272000 -0.896000
+0.100000 0.004900 -0.182900  -0.288000 0.864000 0.400000
+0.100000 0.004900 -0.182900  -0.288000 0.864000 0.400000
+0.050000 0.005700 -0.182900  0.312000 0.584000 0.744000
+0.100000 0.000000 -0.203800  -0.256000 0.936000 -0.224000
+0.050000 0.042300 -0.243900  0.688000 0.376000 -0.616000
+0.078000 0.000000 -0.243900  0.336000 0.616000 -0.696000
+0.050000 0.000000 -0.258500  0.448000 0.256000 -0.848000
+0.100000 -0.005500 -0.243900  -0.184000 0.760000 -0.616000
+0.050000 -0.050200 -0.279200  0.280000 0.320000 -0.896000
+0.100000 -0.050200 -0.272200  -0.136000 0.384000 -0.904000
+0.050000 -0.100400 -0.298100  0.360000 0.248000 -0.896000
+0.100000 -0.100400 -0.298900  0.040000 0.136000 -0.984000
+0.100000 -0.100400 -0.298900  0.040000 0.136000 -0.984000
+0.078000 0.000000 -0.243900  0.336000 0.616000 -0.696000
+0.078000 0.000000 -0.243900  0.336000 0.616000 -0.696000
+0.100000 -0.005500 -0.243900  -0.184000 0.760000 -0.616000
+0.100000 0.000000 -0.203800  -0.256000 0.936000 -0.224000
+0.100000 0.000000 -0.203800  -0.256000 0.936000 -0.224000
+0.200000 -0.301200 -0.206400  -0.600000 -0.688000 0.384000
+0.200000 -0.301200 -0.206400  -0.600000 -0.688000 0.384000
+0.200000 -0.319700 -0.243900  -0.624000 -0.696000 0.328000
+0.176900 -0.301200 -0.243900  -0.504000 -0.800000 0.304000
+0.200000 -0.340400 -0.304800  -0.480000 -0.448000 -0.744000
+0.170700 -0.301200 -0.304800  -0.520000 -0.608000 -0.592000
+0.200000 -0.301200 -0.321600  -0.488000 -0.368000 -0.784000
+0.200000 -0.301200 -0.321600  -0.488000 -0.368000 -0.784000
+0.300000 -0.330300 -0.182900  -0.312000 -0.696000 0.632000
+0.300000 -0.330300 -0.182900  -0.312000 -0.696000 0.632000
+0.300000 -0.351500 -0.225700  -0.416000 -0.800000 0.416000
+0.250000 -0.319600 -0.182900  -0.280000 -0.832000 0.472000
+0.277600 -0.351500 -0.243900  -0.264000 -0.888000 0.352000
+0.250000 -0.343100 -0.243900  -0.320000 -0.920000 0.208000
+0.271900 -0.351500 -0.304800  -0.112000 -0.784000 -0.608000
+0.250000 -0.348300 -0.304800  -0.128000 -0.736000 -0.656000
+0.300000 -0.351500 -0.310200  -0.192000 -0.728000 -0.648000
+0.250000 -0.313600 -0.365800  -0.336000 -0.640000 -0.680000
+0.300000 -0.308000 -0.365800  0.080000 -0.656000 -0.744000
+0.250000 -0.301200 -0.379400  -0.536000 -0.264000 -0.792000
+0.300000 -0.301200 -0.372900  0.128000 -0.472000 -0.864000
+0.300000 -0.308000 -0.365800  0.080000 -0.656000 -0.744000
+0.333500 -0.301200 -0.365800  0.208000 -0.080000 -0.968000
+0.300000 -0.351500 -0.310200  -0.192000 -0.728000 -0.648000
+0.350000 -0.301200 -0.360500  0.376000 0.184000 -0.904000
+0.348000 -0.351500 -0.365800  -0.720000 -0.032000 -0.680000
+0.350000 -0.334300 -0.365800  -0.304000 0.096000 -0.944000
+0.350000 -0.351500 -0.368100  -0.440000 0.096000 -0.888000
+0.355700 -0.351500 -0.365800  0.360000 -0.072000 -0.928000
+0.350000 -0.354600 -0.365800  -0.264000 -0.632000 -0.720000
+0.400000 -0.351500 -0.338800  0.360000 -0.568000 -0.728000
+0.350000 -0.401700 -0.317400  -0.608000 -0.560000 -0.544000
+0.400000 -0.388800 -0.304800  0.392000 -0.800000 -0.448000
+0.376800 -0.401700 -0.304800  0.336000 -0.848000 -0.392000
+0.400000 -0.401700 -0.257800  0.112000 -0.952000 -0.280000
+0.350000 -0.410700 -0.304800  -0.592000 -0.664000 -0.440000
+0.400000 -0.404800 -0.243900  0.016000 -0.968000 0.240000
+0.350000 -0.409600 -0.243900  -0.632000 -0.696000 0.320000
+0.400000 -0.401700 -0.239700  -0.184000 -0.720000 0.656000
+0.350000 -0.401700 -0.229000  -0.616000 -0.656000 0.416000
+0.400000 -0.370500 -0.182900  -0.008000 -0.616000 0.776000
+0.350000 -0.366900 -0.182900  -0.368000 -0.552000 0.736000
+0.350000 -0.401700 -0.229000  -0.616000 -0.656000 0.416000
+0.331500 -0.351500 -0.182900  -0.432000 -0.576000 0.688000
+0.343800 -0.401700 -0.243900  -0.728000 -0.584000 0.344000
+0.300000 -0.351500 -0.225700  -0.416000 -0.800000 0.416000
+0.300000 -0.357600 -0.243900  -0.288000 -0.920000 0.248000
+0.277600 -0.351500 -0.243900  -0.264000 -0.888000 0.352000
+0.300000 -0.355300 -0.304800  -0.272000 -0.752000 -0.592000
+0.271900 -0.351500 -0.304800  -0.112000 -0.784000 -0.608000
+0.300000 -0.351500 -0.310200  -0.192000 -0.728000 -0.648000
+0.300000 -0.355300 -0.304800  -0.272000 -0.752000 -0.592000
+0.348000 -0.351500 -0.365800  -0.720000 -0.032000 -0.680000
+0.344100 -0.401700 -0.304800  -0.784000 -0.512000 -0.336000
+0.350000 -0.354600 -0.365800  -0.264000 -0.632000 -0.720000
+0.350000 -0.401700 -0.317400  -0.608000 -0.560000 -0.544000
+0.344100 -0.401700 -0.304800  -0.784000 -0.512000 -0.336000
+0.350000 -0.410700 -0.304800  -0.592000 -0.664000 -0.440000
+0.343800 -0.401700 -0.243900  -0.728000 -0.584000 0.344000
+0.350000 -0.409600 -0.243900  -0.632000 -0.696000 0.320000
+0.350000 -0.401700 -0.229000  -0.616000 -0.656000 0.416000
+0.350000 -0.401700 -0.229000  -0.616000 -0.656000 0.416000
+0.300000 -0.330300 -0.182900  -0.312000 -0.696000 0.632000
+0.300000 -0.330300 -0.182900  -0.312000 -0.696000 0.632000
+0.331500 -0.351500 -0.182900  -0.432000 -0.576000 0.688000
+0.300000 -0.351500 -0.225700  -0.416000 -0.800000 0.416000
+0.300000 -0.351500 -0.225700  -0.416000 -0.800000 0.416000
+0.427100 -0.301200 -0.182900  0.776000 0.464000 0.416000
+0.427100 -0.301200 -0.182900  0.776000 0.464000 0.416000
+0.450000 -0.338000 -0.182900  0.248000 0.592000 0.752000
+0.429200 -0.301200 -0.243900  0.816000 0.544000 -0.176000
+0.450000 -0.327300 -0.243900  -0.064000 0.864000 -0.488000
+0.401200 -0.301200 -0.304800  0.744000 0.488000 -0.440000
+0.450000 -0.351500 -0.290700  -0.176000 0.632000 -0.744000
+0.437100 -0.351500 -0.304800  0.688000 0.472000 -0.536000
+0.437100 -0.351500 -0.304800  0.688000 0.472000 -0.536000
+0.450000 -0.370700 -0.182900  -0.080000 -0.520000 0.848000
+0.450000 -0.370700 -0.182900  -0.080000 -0.520000 0.848000
+0.400000 -0.370500 -0.182900  -0.008000 -0.616000 0.776000
+0.450000 -0.401700 -0.212100  0.240000 -0.816000 0.520000
+0.400000 -0.401700 -0.239700  -0.184000 -0.720000 0.656000
+0.450000 -0.418500 -0.243900  -0.152000 -0.896000 0.400000
+0.400000 -0.404800 -0.243900  0.016000 -0.968000 0.240000
+0.450000 -0.411100 -0.304800  -0.144000 -0.808000 -0.560000
+0.400000 -0.401700 -0.257800  0.112000 -0.952000 -0.280000
+0.428900 -0.401700 -0.304800  -0.392000 -0.464000 -0.784000
+0.428900 -0.401700 -0.304800  -0.392000 -0.464000 -0.784000
+0.500000 0.355500 -0.182900  0.400000 0.616000 -0.664000
+0.500000 0.355500 -0.182900  0.400000 0.616000 -0.664000
+0.500000 0.351500 -0.187300  0.416000 0.568000 -0.696000
+0.506000 0.351500 -0.182900  0.424000 0.584000 -0.680000
+0.506000 0.351500 -0.182900  0.424000 0.584000 -0.680000
+0.550000 -0.401700 -0.218900  -0.128000 -0.904000 0.392000
+0.550000 -0.401700 -0.218900  -0.128000 -0.904000 0.392000
+0.550000 -0.409700 -0.243900  -0.144000 -0.944000 0.272000
+0.503900 -0.401700 -0.243900  -0.232000 -0.936000 0.256000
+0.550000 -0.415900 -0.304800  -0.192000 -0.848000 -0.480000
+0.502600 -0.401700 -0.304800  -0.320000 -0.840000 -0.416000
+0.550000 -0.401700 -0.333700  -0.144000 -0.688000 -0.704000
+0.550000 -0.401700 -0.333700  -0.144000 -0.688000 -0.704000
+0.600000 0.200800 -0.209200  0.248000 0.288000 -0.920000
+0.600000 0.200800 -0.209200  0.248000 0.288000 -0.920000
+0.650000 0.200800 -0.204000  0.272000 0.408000 -0.864000
+0.600000 0.150600 -0.225200  0.008000 0.128000 -0.984000
+0.650000 0.150600 -0.219600  0.200000 0.280000 -0.928000
+0.600000 0.100400 -0.237100  -0.096000 0.168000 -0.976000
+0.650000 0.100400 -0.241400  0.232000 0.064000 -0.968000
+0.600000 0.076600 -0.243900  -0.096000 0.360000 -0.920000
+0.650000 0.067400 -0.243900  0.208000 0.056000 -0.968000
+0.600000 0.050200 -0.251100  0.248000 0.344000 -0.896000
+0.650000 0.050200 -0.244900  0.216000 0.040000 -0.968000
+0.600000 0.000000 -0.284600  0.512000 0.112000 -0.840000
+0.650000 0.000000 -0.248500  0.680000 -0.160000 -0.712000
+0.650000 0.000000 -0.248500  0.680000 -0.160000 -0.712000
+0.600000 -0.392700 -0.182900  -0.184000 -0.752000 0.624000
+0.600000 -0.392700 -0.182900  -0.184000 -0.752000 0.624000
+0.628900 -0.401700 -0.182900  -0.216000 -0.760000 0.608000
+0.600000 -0.401700 -0.203000  -0.208000 -0.872000 0.432000
+0.600000 -0.401700 -0.203000  -0.208000 -0.872000 0.432000
+0.700000 -0.451900 -0.215800  -0.528000 -0.696000 0.472000
+0.700000 -0.451900 -0.215800  -0.528000 -0.696000 0.472000
+0.700000 -0.472400 -0.243900  -0.560000 -0.816000 -0.016000
+0.673600 -0.451900 -0.243900  -0.480000 -0.752000 0.448000
+0.700000 -0.481300 -0.304800  -0.240000 -0.712000 -0.656000
+0.653100 -0.451900 -0.304800  -0.336000 -0.480000 -0.800000
+0.700000 -0.451900 -0.321600  -0.136000 -0.312000 -0.936000
+0.700000 -0.451900 -0.321600  -0.136000 -0.312000 -0.936000
+0.700000 -0.435200 -0.182900  -0.448000 -0.712000 0.536000
+0.700000 -0.435200 -0.182900  -0.448000 -0.712000 0.536000
+0.719600 -0.451900 -0.182900  -0.568000 -0.640000 0.512000
+0.700000 -0.451900 -0.215800  -0.528000 -0.696000 0.472000
+0.700000 -0.451900 -0.215800  -0.528000 -0.696000 0.472000
+0.750000 -0.502100 -0.236900  -0.448000 -0.776000 0.432000
+0.750000 -0.502100 -0.236900  -0.448000 -0.776000 0.432000
+0.750000 -0.505200 -0.243900  -0.480000 -0.856000 0.152000
+0.744200 -0.502100 -0.243900  -0.480000 -0.864000 0.128000
+0.750000 -0.502100 -0.254300  -0.448000 -0.832000 -0.312000
+0.750000 -0.502100 -0.254300  -0.448000 -0.832000 -0.312000
+0.750000 0.157000 -0.182900  0.280000 0.720000 -0.624000
+0.750000 0.157000 -0.182900  0.280000 0.720000 -0.624000
+0.750000 0.150600 -0.191500  0.256000 0.656000 -0.704000
+0.769100 0.150600 -0.182900  0.248000 0.704000 -0.648000
+0.769100 0.150600 -0.182900  0.248000 0.704000 -0.648000
+0.929600 0.050200 -0.243900  0.432000 0.672000 -0.584000
+0.929600 0.050200 -0.243900  0.432000 0.672000 -0.584000
+0.950000 0.037500 -0.243900  0.432000 0.688000 -0.576000
+0.950000 0.050200 -0.224500  0.472000 0.712000 -0.504000
+0.950000 0.050200 -0.224500  0.472000 0.712000 -0.504000
+0.950000 0.069900 -0.182900  0.544000 0.736000 -0.392000
+0.950000 0.069900 -0.182900  0.544000 0.736000 -0.392000
+0.950000 0.050200 -0.224500  0.472000 0.712000 -0.504000
+0.978000 0.050200 -0.182900  0.512000 0.768000 -0.376000
+0.978000 0.050200 -0.182900  0.512000 0.768000 -0.376000
+0.950000 -0.451900 -0.206400  0.504000 0.736000 0.440000
+0.950000 -0.451900 -0.206400  0.504000 0.736000 0.440000
+0.950000 -0.433400 -0.243900  0.528000 0.832000 0.152000
+0.980700 -0.451900 -0.243900  0.752000 0.648000 0.032000
+0.950000 -0.451900 -0.300000  0.488000 0.464000 -0.728000
+0.950000 -0.433400 -0.243900  0.528000 0.832000 0.152000
+0.900000 -0.451900 -0.272400  0.368000 0.408000 -0.824000
+0.900000 -0.412700 -0.243900  0.520000 0.640000 -0.552000
+0.850000 -0.451900 -0.293100  0.448000 0.248000 -0.848000
+0.890600 -0.401700 -0.243900  0.576000 0.616000 -0.528000
+0.850000 -0.401700 -0.268600  0.504000 0.432000 -0.744000
+0.850000 -0.375700 -0.243900  0.544000 0.616000 -0.552000
+0.800000 -0.401700 -0.291400  0.440000 0.456000 -0.760000
+0.829500 -0.351500 -0.243900  0.648000 0.640000 -0.400000
+0.800000 -0.351500 -0.277300  0.568000 0.408000 -0.704000
+0.800000 -0.328800 -0.243900  0.640000 0.656000 -0.384000
+0.800000 -0.328800 -0.243900  0.640000 0.656000 -0.384000
+1.000000 -0.503200 -0.182900  0.400000 0.704000 0.576000
+1.000000 -0.503200 -0.182900  0.400000 0.704000 0.576000
+0.998000 -0.502100 -0.182900  0.528000 0.664000 0.520000
+1.000000 -0.502100 -0.189300  0.760000 0.568000 0.296000
+1.000000 -0.502100 -0.189300  0.760000 0.568000 0.296000
+-0.891000 -0.451900 -0.304800  0.528000 0.824000 -0.192000
+-0.891000 -0.451900 -0.304800  0.528000 0.824000 -0.192000
+-0.896800 -0.451900 -0.243900  0.600000 0.776000 0.136000
+-0.850000 -0.473200 -0.304800  0.272000 0.896000 -0.336000
+-0.850000 -0.480800 -0.243900  0.376000 0.912000 0.152000
+-0.800000 -0.473000 -0.304800  -0.736000 0.648000 -0.168000
+-0.800000 -0.496000 -0.243900  0.424000 0.840000 0.320000
+-0.787800 -0.451900 -0.304800  -0.984000 0.136000 -0.040000
+-0.769800 -0.451900 -0.243900  -0.952000 -0.080000 0.272000
+-0.769800 -0.451900 -0.243900  -0.952000 -0.080000 0.272000
+-0.900000 -0.551700 -0.243900  -0.808000 -0.568000 -0.120000
+-0.900000 -0.551700 -0.243900  -0.808000 -0.568000 -0.120000
+-0.900000 -0.539600 -0.304800  -0.720000 -0.488000 -0.480000
+-0.899500 -0.552300 -0.243900  -0.800000 -0.592000 -0.072000
+-0.891900 -0.552300 -0.304800  -0.800000 -0.568000 -0.136000
+-0.851300 -0.602500 -0.243900  -0.680000 -0.720000 -0.008000
+-0.850000 -0.602000 -0.304800  -0.640000 -0.736000 -0.184000
+-0.850000 -0.602500 -0.285600  -0.672000 -0.728000 -0.024000
+-0.849200 -0.602500 -0.304800  -0.536000 -0.720000 -0.432000
+-0.850000 -0.603800 -0.243900  -0.656000 -0.744000 0.064000
+-0.800000 -0.636000 -0.304800  -0.536000 -0.792000 -0.272000
+-0.800000 -0.632800 -0.243900  -0.432000 -0.896000 0.072000
+-0.750000 -0.652200 -0.304800  -0.040000 -0.952000 -0.288000
+-0.750000 -0.646000 -0.243900  -0.088000 -0.984000 0.144000
+-0.750000 -0.646000 -0.243900  -0.088000 -0.984000 0.144000
+-0.850000 -0.603800 -0.243900  -0.656000 -0.744000 0.064000
+-0.850000 -0.603800 -0.243900  -0.656000 -0.744000 0.064000
+-0.850000 -0.602500 -0.285600  -0.672000 -0.728000 -0.024000
+-0.851300 -0.602500 -0.243900  -0.680000 -0.720000 -0.008000
+-0.851300 -0.602500 -0.243900  -0.680000 -0.720000 -0.008000
+-0.800000 0.108800 -0.243900  0.352000 0.608000 -0.704000
+-0.800000 0.108800 -0.243900  0.352000 0.608000 -0.704000
+-0.800000 0.100400 -0.252800  0.360000 0.584000 -0.720000
+-0.785800 0.100400 -0.243900  0.360000 0.584000 -0.720000
+-0.785800 0.100400 -0.243900  0.360000 0.584000 -0.720000
+-0.750000 0.077000 -0.243900  0.368000 0.552000 -0.744000
+-0.750000 0.077000 -0.243900  0.368000 0.552000 -0.744000
+-0.750000 0.050200 -0.267100  0.368000 0.432000 -0.816000
+-0.711800 0.050200 -0.243900  0.416000 0.432000 -0.792000
+-0.711800 0.050200 -0.243900  0.416000 0.432000 -0.792000
+-0.731900 -0.150600 -0.304800  0.424000 0.400000 -0.808000
+-0.731900 -0.150600 -0.304800  0.424000 0.400000 -0.808000
+-0.700000 -0.175200 -0.304800  0.352000 0.528000 -0.768000
+-0.700000 -0.150600 -0.284500  0.376000 0.392000 -0.832000
+-0.700000 -0.150600 -0.284500  0.376000 0.392000 -0.832000
+-0.650000 -0.200800 -0.303800  0.136000 0.680000 -0.712000
+-0.650000 -0.200800 -0.303800  0.136000 0.680000 -0.712000
+-0.651700 -0.200800 -0.304800  0.320000 0.544000 -0.768000
+-0.650000 -0.201600 -0.304800  0.104000 0.688000 -0.704000
+-0.700000 -0.200800 -0.326900  0.208000 0.528000 -0.816000
+-0.650000 -0.251000 -0.354800  0.152000 0.632000 -0.752000
+-0.700000 -0.251000 -0.364900  0.104000 0.560000 -0.816000
+-0.650000 -0.261300 -0.365800  0.088000 0.568000 -0.808000
+-0.700000 -0.252100 -0.365800  0.096000 0.552000 -0.824000
+-0.700000 -0.251000 -0.364900  0.104000 0.560000 -0.816000
+-0.707800 -0.251000 -0.365800  0.064000 0.432000 -0.896000
+-0.700000 -0.200800 -0.326900  0.208000 0.528000 -0.816000
+-0.750000 -0.240500 -0.365800  0.056000 0.272000 -0.952000
+-0.750000 -0.200800 -0.348300  0.272000 0.384000 -0.872000
+-0.800000 -0.234100 -0.365800  -0.112000 0.264000 -0.952000
+-0.800000 -0.200800 -0.355700  0.080000 0.256000 -0.960000
+-0.800000 -0.200800 -0.355700  0.080000 0.256000 -0.960000
+-0.650000 -0.035200 -0.243900  0.544000 0.264000 -0.792000
+-0.650000 -0.035200 -0.243900  0.544000 0.264000 -0.792000
+-0.650000 -0.050200 -0.249300  0.496000 0.208000 -0.840000
+-0.642900 -0.050200 -0.243900  0.560000 0.208000 -0.792000
+-0.642900 -0.050200 -0.243900  0.560000 0.208000 -0.792000
+-0.544700 -0.200800 -0.304800  -0.080000 0.824000 -0.552000
+-0.544700 -0.200800 -0.304800  -0.080000 0.824000 -0.552000
+-0.550000 -0.200800 -0.303600  -0.040000 0.880000 -0.464000
+-0.550000 -0.201300 -0.304800  -0.032000 0.864000 -0.488000
+-0.550000 -0.201300 -0.304800  -0.032000 0.864000 -0.488000
+-0.354400 -0.100400 -0.243900  -0.584000 0.448000 -0.664000
+-0.354400 -0.100400 -0.243900  -0.584000 0.448000 -0.664000
+-0.350000 -0.100400 -0.248500  -0.576000 0.440000 -0.680000
+-0.350000 -0.093900 -0.243900  -0.600000 0.408000 -0.680000
+-0.350000 -0.093900 -0.243900  -0.600000 0.408000 -0.680000
+-0.363900 -0.552300 -0.243900  0.816000 -0.480000 0.304000
+-0.363900 -0.552300 -0.243900  0.816000 -0.480000 0.304000
+-0.350000 -0.535600 -0.243900  0.360000 -0.840000 0.384000
+-0.350000 -0.552300 -0.283400  -0.096000 -0.680000 0.720000
+-0.317500 -0.552300 -0.243900  -0.600000 -0.648000 0.448000
+-0.317500 -0.552300 -0.243900  -0.600000 -0.648000 0.448000
+-0.300000 -0.050200 -0.270300  -0.824000 0.232000 -0.512000
+-0.300000 -0.050200 -0.270300  -0.824000 0.232000 -0.512000
+-0.266700 -0.050200 -0.304800  -0.504000 0.288000 -0.808000
+-0.300000 -0.100400 -0.298100  -0.480000 0.288000 -0.824000
+-0.288100 -0.100400 -0.304800  -0.408000 0.240000 -0.872000
+-0.300000 -0.118900 -0.304800  -0.376000 0.264000 -0.880000
+-0.300000 -0.118900 -0.304800  -0.376000 0.264000 -0.880000
+-0.256000 -0.703000 -0.243900  0.696000 -0.392000 0.584000
+-0.256000 -0.703000 -0.243900  0.696000 -0.392000 0.584000
+-0.250000 -0.679700 -0.243900  0.728000 -0.208000 0.640000
+-0.250000 -0.703000 -0.252700  0.704000 -0.368000 0.600000
+-0.250000 -0.703000 -0.252700  0.704000 -0.368000 0.600000
+-0.213400 0.000000 -0.304800  -0.304000 0.448000 -0.832000
+-0.213400 0.000000 -0.304800  -0.304000 0.448000 -0.832000
+-0.250000 0.000000 -0.286200  -0.320000 0.712000 -0.616000
+-0.250000 -0.028200 -0.304800  -0.400000 0.416000 -0.808000
+-0.250000 -0.028200 -0.304800  -0.400000 0.416000 -0.808000
+-0.196100 -0.200800 -0.304800  0.360000 -0.200000 -0.904000
+-0.196100 -0.200800 -0.304800  0.360000 -0.200000 -0.904000
+-0.150000 -0.200800 -0.284500  0.024000 -0.216000 -0.968000
+-0.150000 -0.159100 -0.304800  0.152000 -0.400000 -0.896000
+-0.108400 -0.200800 -0.304800  -0.496000 -0.048000 -0.856000
+-0.108400 -0.200800 -0.304800  -0.496000 -0.048000 -0.856000
+-0.172800 -0.552300 -0.243900  0.592000 -0.568000 0.560000
+-0.172800 -0.552300 -0.243900  0.592000 -0.568000 0.560000
+-0.150000 -0.530700 -0.243900  0.632000 -0.664000 0.392000
+-0.150000 -0.552300 -0.270100  0.544000 -0.504000 0.656000
+-0.150000 -0.552300 -0.270100  0.544000 -0.504000 0.656000
+-0.126800 0.150600 -0.243900  -0.208000 0.496000 -0.832000
+-0.126800 0.150600 -0.243900  -0.208000 0.496000 -0.832000
+-0.100000 0.150600 -0.251000  -0.024000 0.408000 -0.904000
+-0.100000 0.164100 -0.243900  -0.032000 0.432000 -0.896000
+-0.077600 0.150600 -0.243900  0.320000 0.328000 -0.880000
+-0.077600 0.150600 -0.243900  0.320000 0.328000 -0.880000
+-0.150000 0.100400 -0.267100  -0.312000 0.440000 -0.832000
+-0.150000 0.100400 -0.267100  -0.312000 0.440000 -0.832000
+-0.100000 0.100400 -0.276400  0.032000 0.376000 -0.920000
+-0.150000 0.050200 -0.299600  -0.080000 0.408000 -0.904000
+-0.100000 0.050200 -0.292200  0.304000 0.312000 -0.896000
+-0.150000 0.040500 -0.304800  -0.136000 0.416000 -0.896000
+-0.100000 0.022400 -0.304800  0.184000 0.304000 -0.928000
+-0.150000 0.000000 -0.322200  0.064000 0.240000 -0.968000
+-0.100000 0.000000 -0.309600  0.168000 0.152000 -0.968000
+-0.150000 -0.050200 -0.328000  0.128000 0.064000 -0.984000
+-0.100000 -0.050200 -0.318600  0.080000 0.144000 -0.984000
+-0.150000 -0.100400 -0.338700  0.056000 -0.088000 -0.992000
+-0.100000 -0.100400 -0.323700  -0.040000 -0.152000 -0.984000
+-0.150000 -0.150600 -0.309500  -0.032000 -0.400000 -0.912000
+-0.100000 -0.150600 -0.315000  -0.456000 -0.064000 -0.880000
+-0.100000 -0.150600 -0.315000  -0.456000 -0.064000 -0.880000
+-0.077600 0.000000 -0.304800  0.248000 0.344000 -0.896000
+-0.077600 0.000000 -0.304800  0.248000 0.344000 -0.896000
+-0.050000 -0.015100 -0.304800  0.280000 0.536000 -0.784000
+-0.050000 0.000000 -0.288000  0.256000 0.560000 -0.776000
+-0.050000 0.000000 -0.288000  0.256000 0.560000 -0.776000
+-0.013800 -0.351500 -0.243900  0.552000 -0.808000 -0.168000
+-0.013800 -0.351500 -0.243900  0.552000 -0.808000 -0.168000
+-0.050000 -0.380500 -0.243900  0.664000 -0.736000 -0.104000
+-0.026900 -0.351500 -0.304800  0.608000 -0.688000 -0.384000
+-0.050000 -0.374600 -0.304800  0.584000 -0.672000 -0.448000
+-0.050000 -0.351500 -0.336900  0.024000 -0.576000 -0.808000
+-0.050000 -0.351500 -0.336900  0.024000 -0.576000 -0.808000
+0.050000 -0.050200 -0.279200  0.280000 0.320000 -0.896000
+0.050000 -0.050200 -0.279200  0.280000 0.320000 -0.896000
+0.004800 -0.050200 -0.304800  0.368000 0.176000 -0.904000
+0.050000 -0.100400 -0.298100  0.360000 0.248000 -0.896000
+0.039400 -0.100400 -0.304800  0.408000 0.224000 -0.880000
+0.039400 -0.100400 -0.304800  0.408000 0.224000 -0.880000
+0.113100 0.000000 -0.243900  -0.392000 0.768000 -0.496000
+0.113100 0.000000 -0.243900  -0.392000 0.768000 -0.496000
+0.150000 0.000000 -0.257100  -0.208000 0.552000 -0.800000
+0.150000 0.015400 -0.243900  -0.208000 0.728000 -0.640000
+0.150000 0.015400 -0.243900  -0.208000 0.728000 -0.640000
+0.200000 -0.100400 -0.298900  0.088000 0.040000 -0.992000
+0.200000 -0.100400 -0.298900  0.088000 0.040000 -0.992000
+0.185500 -0.100400 -0.304800  0.296000 0.104000 -0.944000
+0.200000 -0.139100 -0.304800  0.208000 0.104000 -0.968000
+0.150000 -0.100400 -0.322200  0.000000 0.224000 -0.968000
+0.200000 -0.150600 -0.306400  0.192000 0.112000 -0.968000
+0.150000 -0.150600 -0.323600  -0.232000 0.464000 -0.848000
+0.200000 -0.200800 -0.335700  -0.120000 0.200000 -0.968000
+0.150000 -0.200800 -0.325200  0.160000 0.176000 -0.968000
+0.200000 -0.251000 -0.346500  -0.184000 0.088000 -0.976000
+0.150000 -0.251000 -0.336000  0.080000 -0.336000 -0.928000
+0.150000 -0.251000 -0.336000  0.080000 -0.336000 -0.928000
+0.211400 -0.050200 -0.304800  0.152000 0.184000 -0.968000
+0.211400 -0.050200 -0.304800  0.152000 0.184000 -0.968000
+0.200000 -0.061600 -0.304800  0.000000 -0.144000 -0.984000
+0.250000 -0.050200 -0.297000  0.000000 0.040000 -0.992000
+0.200000 -0.100400 -0.298900  0.088000 0.040000 -0.992000
+0.250000 -0.100400 -0.298400  -0.088000 0.216000 -0.968000
+0.200000 -0.139100 -0.304800  0.208000 0.104000 -0.968000
+0.250000 -0.114900 -0.304800  -0.104000 0.280000 -0.952000
+0.200000 -0.150600 -0.306400  0.192000 0.112000 -0.968000
+0.250000 -0.150600 -0.317700  0.024000 0.336000 -0.936000
+0.200000 -0.200800 -0.335700  -0.120000 0.200000 -0.968000
+0.250000 -0.200800 -0.343100  0.104000 0.232000 -0.960000
+0.200000 -0.251000 -0.346500  -0.184000 0.088000 -0.976000
+0.250000 -0.251000 -0.353900  0.064000 0.384000 -0.920000
+0.250000 -0.251000 -0.353900  0.064000 0.384000 -0.920000
+0.250000 -0.050200 -0.297000  0.000000 0.040000 -0.992000
+0.250000 -0.050200 -0.297000  0.000000 0.040000 -0.992000
+0.266500 -0.050200 -0.304800  -0.280000 0.064000 -0.952000
+0.250000 -0.100400 -0.298400  -0.088000 0.216000 -0.968000
+0.278900 -0.100400 -0.304800  -0.176000 0.256000 -0.944000
+0.250000 -0.114900 -0.304800  -0.104000 0.280000 -0.952000
+0.250000 -0.114900 -0.304800  -0.104000 0.280000 -0.952000
+0.350000 -0.127600 -0.304800  0.032000 -0.600000 -0.792000
+0.350000 -0.127600 -0.304800  0.032000 -0.600000 -0.792000
+0.313400 -0.150600 -0.304800  0.400000 -0.360000 -0.840000
+0.350000 -0.150600 -0.283600  -0.064000 -0.424000 -0.896000
+0.320800 -0.200800 -0.304800  0.496000 0.328000 -0.800000
+0.350000 -0.200800 -0.271400  0.216000 0.224000 -0.944000
+0.350000 -0.228300 -0.304800  0.616000 0.528000 -0.576000
+0.350000 -0.228300 -0.304800  0.616000 0.528000 -0.576000
+0.300000 -0.357600 -0.243900  -0.288000 -0.920000 0.248000
+0.300000 -0.357600 -0.243900  -0.288000 -0.920000 0.248000
+0.343800 -0.401700 -0.243900  -0.728000 -0.584000 0.344000
+0.300000 -0.355300 -0.304800  -0.272000 -0.752000 -0.592000
+0.344100 -0.401700 -0.304800  -0.784000 -0.512000 -0.336000
+0.344100 -0.401700 -0.304800  -0.784000 -0.512000 -0.336000
+0.350000 -0.127600 -0.304800  0.032000 -0.600000 -0.792000
+0.350000 -0.127600 -0.304800  0.032000 -0.600000 -0.792000
+0.350000 -0.150600 -0.283600  -0.064000 -0.424000 -0.896000
+0.380400 -0.150600 -0.304800  -0.424000 -0.456000 -0.776000
+0.380400 -0.150600 -0.304800  -0.424000 -0.456000 -0.776000
+0.419200 0.050200 -0.304800  -0.224000 0.736000 -0.632000
+0.419200 0.050200 -0.304800  -0.224000 0.736000 -0.632000
+0.400000 0.050200 -0.294000  -0.352000 0.672000 -0.640000
+0.400000 0.041200 -0.304800  -0.352000 0.672000 -0.648000
+0.400000 0.041200 -0.304800  -0.352000 0.672000 -0.648000
+0.400000 -0.168700 -0.304800  -0.504000 -0.464000 -0.720000
+0.400000 -0.168700 -0.304800  -0.504000 -0.464000 -0.720000
+0.400000 -0.200800 -0.276700  0.448000 -0.472000 -0.752000
+0.424400 -0.200800 -0.304800  -0.552000 -0.520000 -0.648000
+0.400000 -0.249400 -0.243900  0.760000 -0.472000 -0.424000
+0.450000 -0.217600 -0.304800  -0.352000 -0.736000 -0.560000
+0.450000 -0.248400 -0.243900  -0.224000 -0.888000 -0.384000
+0.450000 -0.248400 -0.243900  -0.224000 -0.888000 -0.384000
+0.550000 -0.150600 -0.287800  0.352000 0.528000 -0.768000
+0.550000 -0.150600 -0.287800  0.352000 0.528000 -0.768000
+0.523400 -0.150600 -0.304800  0.376000 0.592000 -0.704000
+0.550000 -0.162200 -0.304800  0.376000 0.720000 -0.576000
+0.500000 -0.150600 -0.319100  0.336000 0.504000 -0.792000
+0.550000 -0.194000 -0.365800  0.224000 0.896000 -0.368000
+0.500000 -0.200800 -0.334200  -0.376000 -0.448000 -0.800000
+0.535800 -0.200800 -0.365800  -0.736000 0.208000 -0.632000
+0.500000 -0.222600 -0.304800  -0.320000 -0.704000 -0.624000
+0.550000 -0.216200 -0.365800  -0.080000 -0.576000 -0.808000
+0.535300 -0.251000 -0.304800  -0.648000 -0.480000 -0.576000
+0.550000 -0.251000 -0.326800  -0.648000 -0.504000 -0.560000
+0.550000 -0.216200 -0.365800  -0.080000 -0.576000 -0.808000
+0.573000 -0.251000 -0.365800  -0.696000 0.544000 -0.464000
+0.559600 -0.200800 -0.365800  0.680000 0.504000 -0.520000
+0.600000 -0.231600 -0.365800  0.072000 0.640000 -0.760000
+0.594200 -0.200800 -0.304800  0.544000 0.576000 -0.600000
+0.600000 -0.206100 -0.304800  0.488000 0.616000 -0.608000
+0.600000 -0.200800 -0.298700  0.448000 0.592000 -0.656000
+0.650000 -0.208600 -0.304800  0.024000 0.680000 -0.728000
+0.650000 -0.200800 -0.297000  0.088000 0.616000 -0.776000
+0.600000 -0.200800 -0.298700  0.448000 0.592000 -0.656000
+0.650000 -0.150600 -0.274900  0.544000 0.464000 -0.688000
+0.600000 -0.150600 -0.265200  0.248000 0.032000 -0.960000
+0.600000 -0.200800 -0.298700  0.448000 0.592000 -0.656000
+0.550000 -0.150600 -0.287800  0.352000 0.528000 -0.768000
+0.594200 -0.200800 -0.304800  0.544000 0.576000 -0.600000
+0.550000 -0.162200 -0.304800  0.376000 0.720000 -0.576000
+0.559600 -0.200800 -0.365800  0.680000 0.504000 -0.520000
+0.550000 -0.194000 -0.365800  0.224000 0.896000 -0.368000
+0.550000 -0.200800 -0.388300  0.280000 0.584000 -0.752000
+0.535800 -0.200800 -0.365800  -0.736000 0.208000 -0.632000
+0.550000 -0.216200 -0.365800  -0.080000 -0.576000 -0.808000
+0.550000 -0.200800 -0.388300  0.280000 0.584000 -0.752000
+0.559600 -0.200800 -0.365800  0.680000 0.504000 -0.520000
+0.559600 -0.200800 -0.365800  0.680000 0.504000 -0.520000
+0.500000 -0.222600 -0.304800  -0.320000 -0.704000 -0.624000
+0.500000 -0.222600 -0.304800  -0.320000 -0.704000 -0.624000
+0.500000 -0.251000 -0.264200  -0.272000 -0.744000 -0.600000
+0.535300 -0.251000 -0.304800  -0.648000 -0.480000 -0.576000
+0.535300 -0.251000 -0.304800  -0.648000 -0.480000 -0.576000
+0.800000 -0.401700 -0.291400  0.440000 0.456000 -0.760000
+0.800000 -0.401700 -0.291400  0.440000 0.456000 -0.760000
+0.800000 -0.418300 -0.304800  0.408000 0.496000 -0.760000
+0.850000 -0.401700 -0.268600  0.504000 0.432000 -0.744000
+0.837100 -0.451900 -0.304800  0.528000 0.264000 -0.800000
+0.850000 -0.451900 -0.293100  0.448000 0.248000 -0.848000
+0.800000 -0.493800 -0.304800  0.032000 -0.688000 -0.720000
+0.850000 -0.490600 -0.304800  0.216000 0.112000 -0.968000
+0.800000 -0.502100 -0.293400  -0.120000 -0.840000 -0.520000
+0.832800 -0.502100 -0.304800  -0.104000 -0.544000 -0.824000
+0.832800 -0.502100 -0.304800  -0.104000 -0.544000 -0.824000
+0.858900 0.050200 -0.243900  -0.424000 0.568000 -0.696000
+0.858900 0.050200 -0.243900  -0.424000 0.568000 -0.696000
+0.900000 0.050200 -0.268900  0.208000 0.672000 -0.696000
+0.900000 0.070800 -0.243900  -0.096000 0.744000 -0.656000
+0.900000 0.070800 -0.243900  -0.096000 0.744000 -0.656000
+0.981700 -0.050200 -0.304800  0.528000 0.432000 -0.720000
+0.981700 -0.050200 -0.304800  0.528000 0.432000 -0.720000
+1.000000 -0.073100 -0.304800  0.536000 0.424000 -0.720000
+1.000000 -0.050200 -0.288900  0.520000 0.432000 -0.728000
+1.000000 -0.050200 -0.288900  0.520000 0.432000 -0.728000
+-0.900000 0.104600 -0.304800  0.304000 0.568000 -0.760000
+-0.900000 0.104600 -0.304800  0.304000 0.568000 -0.760000
+-0.900000 0.100400 -0.308600  0.312000 0.536000 -0.776000
+-0.892300 0.100400 -0.304800  0.320000 0.536000 -0.776000
+-0.892300 0.100400 -0.304800  0.320000 0.536000 -0.776000
+-0.850000 -0.301200 -0.321900  -0.728000 -0.616000 -0.280000
+-0.850000 -0.301200 -0.321900  -0.728000 -0.616000 -0.280000
+-0.850000 -0.251000 -0.359600  -0.320000 0.248000 -0.912000
+-0.826000 -0.301200 -0.365800  -0.648000 -0.448000 -0.600000
+-0.828000 -0.251000 -0.365800  -0.248000 0.216000 -0.936000
+-0.800000 -0.301200 -0.380800  -0.264000 0.104000 -0.952000
+-0.800000 -0.251000 -0.370300  -0.064000 0.200000 -0.976000
+-0.750000 -0.301200 -0.392900  -0.104000 0.352000 -0.928000
+-0.750000 -0.251000 -0.369800  0.056000 0.280000 -0.952000
+-0.750000 -0.251000 -0.369800  0.056000 0.280000 -0.952000
+-0.800000 -0.066700 -0.304800  0.296000 0.144000 -0.936000
+-0.800000 -0.066700 -0.304800  0.296000 0.144000 -0.936000
+-0.800000 -0.100400 -0.313000  0.368000 0.216000 -0.896000
+-0.785000 -0.100400 -0.304800  0.328000 0.224000 -0.912000
+-0.785000 -0.100400 -0.304800  0.328000 0.224000 -0.912000
+-0.750000 -0.129200 -0.304800  0.392000 0.376000 -0.832000
+-0.750000 -0.129200 -0.304800  0.392000 0.376000 -0.832000
+-0.750000 -0.150600 -0.317800  0.416000 0.384000 -0.816000
+-0.731900 -0.150600 -0.304800  0.424000 0.400000 -0.808000
+-0.731900 -0.150600 -0.304800  0.424000 0.400000 -0.808000
+-0.576800 -0.251000 -0.365800  -0.136000 0.624000 -0.760000
+-0.576800 -0.251000 -0.365800  -0.136000 0.624000 -0.760000
+-0.600000 -0.251000 -0.360600  -0.120000 0.624000 -0.760000
+-0.600000 -0.256300 -0.365800  -0.112000 0.608000 -0.776000
+-0.600000 -0.256300 -0.365800  -0.112000 0.608000 -0.776000
+-0.500000 -0.637800 -0.304800  -0.208000 -0.976000 -0.032000
+-0.500000 -0.637800 -0.304800  -0.208000 -0.976000 -0.032000
+-0.455200 -0.652700 -0.304800  -0.280000 -0.952000 0.040000
+-0.500000 -0.633000 -0.365800  -0.088000 -0.968000 -0.200000
+-0.450000 -0.652700 -0.319500  -0.256000 -0.952000 -0.136000
+-0.450000 -0.645700 -0.365800  -0.144000 -0.904000 -0.392000
+-0.405700 -0.652700 -0.365800  -0.144000 -0.920000 -0.344000
+-0.405700 -0.652700 -0.365800  -0.144000 -0.920000 -0.344000
+-0.350000 -0.585900 -0.365800  0.168000 -0.792000 -0.576000
+-0.350000 -0.585900 -0.365800  0.168000 -0.792000 -0.576000
+-0.350000 -0.594300 -0.304800  0.520000 -0.800000 0.280000
+-0.357100 -0.602500 -0.365800  0.904000 0.256000 -0.312000
+-0.351600 -0.602500 -0.304800  0.944000 0.304000 0.024000
+-0.350000 -0.629600 -0.365800  0.056000 0.640000 -0.760000
+-0.350000 -0.605300 -0.304800  0.248000 0.960000 -0.032000
+-0.328400 -0.602500 -0.365800  -0.832000 -0.248000 -0.488000
+-0.344900 -0.602500 -0.304800  -0.744000 0.664000 -0.032000
+-0.350000 -0.585900 -0.365800  0.168000 -0.792000 -0.576000
+-0.350000 -0.594300 -0.304800  0.520000 -0.800000 0.280000
+-0.350000 -0.594300 -0.304800  0.520000 -0.800000 0.280000
+-0.350000 -0.747900 -0.304800  -0.512000 -0.832000 -0.184000
+-0.350000 -0.747900 -0.304800  -0.512000 -0.832000 -0.184000
+-0.350000 -0.703000 -0.357000  -0.336000 -0.496000 -0.792000
+-0.371300 -0.703000 -0.304800  -0.816000 -0.552000 -0.144000
+-0.371300 -0.703000 -0.304800  -0.816000 -0.552000 -0.144000
+-0.331500 -0.150600 -0.304800  -0.256000 0.464000 -0.840000
+-0.331500 -0.150600 -0.304800  -0.256000 0.464000 -0.840000
+-0.300000 -0.150600 -0.319300  -0.256000 0.480000 -0.832000
+-0.300000 -0.118900 -0.304800  -0.376000 0.264000 -0.880000
+-0.300000 -0.118900 -0.304800  -0.376000 0.264000 -0.880000
+-0.250000 -0.639500 -0.365800  0.216000 -0.224000 -0.944000
+-0.250000 -0.639500 -0.365800  0.216000 -0.224000 -0.944000
+-0.282800 -0.652700 -0.365800  0.080000 -0.160000 -0.976000
+-0.250000 -0.652700 -0.361600  0.240000 -0.216000 -0.944000
+-0.250000 -0.652700 -0.361600  0.240000 -0.216000 -0.944000
+-0.250000 -0.150600 -0.327500  -0.120000 0.152000 -0.976000
+-0.250000 -0.150600 -0.327500  -0.120000 0.152000 -0.976000
+-0.200000 -0.150600 -0.333300  0.216000 -0.272000 -0.936000
+-0.250000 -0.200800 -0.333200  0.168000 0.080000 -0.976000
+-0.200000 -0.200800 -0.306700  0.368000 -0.184000 -0.904000
+-0.250000 -0.251000 -0.337900  0.384000 0.112000 -0.912000
+-0.200000 -0.251000 -0.307600  0.408000 0.096000 -0.904000
+-0.250000 -0.301200 -0.349000  0.296000 0.272000 -0.912000
+-0.200000 -0.301200 -0.313400  0.328000 0.152000 -0.928000
+-0.200000 -0.301200 -0.313400  0.328000 0.152000 -0.928000
+-0.200000 -0.602500 -0.345500  0.488000 -0.272000 -0.824000
+-0.200000 -0.602500 -0.345500  0.488000 -0.272000 -0.824000
+-0.200000 -0.558000 -0.365800  0.448000 -0.240000 -0.856000
+-0.229500 -0.602500 -0.365800  0.408000 -0.240000 -0.872000
+-0.200000 -0.552300 -0.367100  0.360000 -0.232000 -0.896000
+-0.250000 -0.602500 -0.376000  0.360000 -0.328000 -0.872000
+-0.250000 -0.552300 -0.402600  0.504000 -0.312000 -0.792000
+-0.250000 -0.552300 -0.402600  0.504000 -0.312000 -0.792000
+-0.150000 -0.602500 -0.307600  0.456000 -0.280000 -0.840000
+-0.150000 -0.602500 -0.307600  0.456000 -0.280000 -0.840000
+-0.150000 -0.552300 -0.337600  0.424000 -0.304000 -0.840000
+-0.200000 -0.602500 -0.345500  0.488000 -0.272000 -0.824000
+-0.196100 -0.552300 -0.365800  0.320000 -0.272000 -0.904000
+-0.200000 -0.558000 -0.365800  0.448000 -0.240000 -0.856000
+-0.200000 -0.552300 -0.367100  0.360000 -0.232000 -0.896000
+-0.200000 -0.552300 -0.367100  0.360000 -0.232000 -0.896000
+-0.147100 -0.502100 -0.365800  0.472000 -0.192000 -0.848000
+-0.147100 -0.502100 -0.365800  0.472000 -0.192000 -0.848000
+-0.145700 -0.451900 -0.365800  0.464000 0.040000 -0.880000
+-0.100000 -0.502100 -0.325200  0.520000 -0.368000 -0.760000
+-0.100000 -0.451900 -0.336100  0.496000 -0.048000 -0.856000
+-0.074100 -0.502100 -0.304800  0.864000 -0.480000 0.112000
+-0.061500 -0.451900 -0.304800  0.928000 -0.352000 0.088000
+-0.061500 -0.451900 -0.304800  0.928000 -0.352000 0.088000
+-0.100000 -0.200800 -0.311700  -0.496000 0.128000 -0.856000
+-0.100000 -0.200800 -0.311700  -0.496000 0.128000 -0.856000
+-0.050000 -0.200800 -0.320900  -0.056000 0.280000 -0.952000
+-0.100000 -0.251000 -0.333700  -0.512000 0.248000 -0.816000
+-0.050000 -0.251000 -0.364300  -0.216000 0.352000 -0.904000
+-0.100000 -0.301200 -0.349000  -0.368000 0.264000 -0.888000
+-0.050000 -0.266900 -0.365800  -0.288000 0.088000 -0.944000
+-0.058500 -0.301200 -0.365800  -0.384000 -0.288000 -0.872000
+-0.050000 -0.301200 -0.370400  -0.392000 -0.264000 -0.872000
+-0.050000 -0.309800 -0.365800  -0.336000 -0.416000 -0.840000
+-0.058500 -0.301200 -0.365800  -0.384000 -0.288000 -0.872000
+-0.050000 -0.351500 -0.336900  0.024000 -0.576000 -0.808000
+-0.100000 -0.301200 -0.349000  -0.368000 0.264000 -0.888000
+-0.100000 -0.351500 -0.338800  0.024000 -0.312000 -0.944000
+-0.100000 -0.351500 -0.338800  0.024000 -0.312000 -0.944000
+0.050000 -0.119800 -0.304800  0.416000 0.264000 -0.864000
+0.050000 -0.119800 -0.304800  0.416000 0.264000 -0.864000
+0.050000 -0.150600 -0.318000  0.352000 0.312000 -0.872000
+0.096000 -0.150600 -0.304800  0.176000 0.336000 -0.920000
+0.096000 -0.150600 -0.304800  0.176000 0.336000 -0.920000
+0.301400 0.000000 -0.304800  -0.584000 0.656000 -0.464000
+0.301400 0.000000 -0.304800  -0.584000 0.656000 -0.464000
+0.350000 0.000000 -0.339100  -0.264000 0.552000 -0.784000
+0.350000 0.024300 -0.304800  -0.456000 0.784000 -0.408000
+0.400000 0.000000 -0.343200  -0.216000 0.592000 -0.768000
+0.400000 0.041200 -0.304800  -0.352000 0.672000 -0.648000
+0.400000 0.041200 -0.304800  -0.352000 0.672000 -0.648000
+0.383500 -0.050200 -0.365800  0.200000 -0.288000 -0.928000
+0.383500 -0.050200 -0.365800  0.200000 -0.288000 -0.928000
+0.400000 -0.050200 -0.360800  0.184000 -0.432000 -0.872000
+0.350000 -0.037900 -0.365800  -0.440000 0.432000 -0.776000
+0.400000 0.000000 -0.343200  -0.216000 0.592000 -0.768000
+0.350000 0.000000 -0.339100  -0.264000 0.552000 -0.784000
+0.350000 0.000000 -0.339100  -0.264000 0.552000 -0.784000
+0.355700 -0.351500 -0.365800  0.360000 -0.072000 -0.928000
+0.355700 -0.351500 -0.365800  0.360000 -0.072000 -0.928000
+0.400000 -0.351500 -0.338800  0.360000 -0.568000 -0.728000
+0.350000 -0.334300 -0.365800  -0.304000 0.096000 -0.944000
+0.400000 -0.301200 -0.307300  0.704000 0.496000 -0.496000
+0.350000 -0.301200 -0.360500  0.376000 0.184000 -0.904000
+0.350000 -0.301200 -0.360500  0.376000 0.184000 -0.904000
+0.376800 -0.401700 -0.304800  0.336000 -0.848000 -0.392000
+0.376800 -0.401700 -0.304800  0.336000 -0.848000 -0.392000
+0.350000 -0.401700 -0.317400  -0.608000 -0.560000 -0.544000
+0.350000 -0.410700 -0.304800  -0.592000 -0.664000 -0.440000
+0.350000 -0.410700 -0.304800  -0.592000 -0.664000 -0.440000
+0.400000 -0.050200 -0.360800  0.184000 -0.432000 -0.872000
+0.400000 -0.050200 -0.360800  0.184000 -0.432000 -0.872000
+0.450000 -0.050200 -0.325200  -0.120000 -0.568000 -0.808000
+0.400000 -0.100400 -0.340000  -0.040000 -0.360000 -0.928000
+0.450000 -0.100400 -0.322200  0.392000 -0.360000 -0.840000
+0.400000 -0.150600 -0.318400  -0.432000 -0.416000 -0.792000
+0.450000 -0.150600 -0.321300  -0.008000 0.120000 -0.992000
+0.400000 -0.168700 -0.304800  -0.504000 -0.464000 -0.720000
+0.450000 -0.200800 -0.331300  -0.472000 -0.400000 -0.776000
+0.424400 -0.200800 -0.304800  -0.552000 -0.520000 -0.648000
+0.450000 -0.217600 -0.304800  -0.352000 -0.736000 -0.560000
+0.450000 -0.217600 -0.304800  -0.352000 -0.736000 -0.560000
+0.450000 0.055500 -0.304800  0.064000 0.864000 -0.496000
+0.450000 0.055500 -0.304800  0.064000 0.864000 -0.496000
+0.450000 0.050200 -0.314200  0.064000 0.744000 -0.656000
+0.496000 0.050200 -0.304800  0.104000 0.800000 -0.576000
+0.496000 0.050200 -0.304800  0.104000 0.800000 -0.576000
+0.500000 -0.333600 -0.304800  -0.408000 0.824000 -0.376000
+0.500000 -0.333600 -0.304800  -0.408000 0.824000 -0.376000
+0.458900 -0.351500 -0.304800  -0.472000 0.360000 -0.792000
+0.500000 -0.351500 -0.354900  -0.384000 -0.472000 -0.784000
+0.500000 -0.400200 -0.304800  -0.176000 -0.672000 -0.712000
+0.500000 -0.400200 -0.304800  -0.176000 -0.672000 -0.712000
+0.450000 -0.380500 -0.304800  -0.144000 0.256000 -0.952000
+0.450000 -0.380500 -0.304800  -0.144000 0.256000 -0.952000
+0.450000 -0.401700 -0.316200  -0.184000 -0.360000 -0.904000
+0.492100 -0.401700 -0.304800  0.152000 -0.576000 -0.792000
+0.492100 -0.401700 -0.304800  0.152000 -0.576000 -0.792000
+0.500000 -0.127100 -0.304800  0.480000 0.456000 -0.744000
+0.500000 -0.127100 -0.304800  0.480000 0.456000 -0.744000
+0.500000 -0.150600 -0.319100  0.336000 0.504000 -0.792000
+0.523400 -0.150600 -0.304800  0.376000 0.592000 -0.704000
+0.523400 -0.150600 -0.304800  0.376000 0.592000 -0.704000
+0.600000 -0.086300 -0.304800  0.440000 0.312000 -0.832000
+0.600000 -0.086300 -0.304800  0.440000 0.312000 -0.832000
+0.589400 -0.100400 -0.304800  -0.440000 -0.424000 -0.784000
+0.600000 -0.100400 -0.312700  0.376000 -0.472000 -0.792000
+0.600000 -0.105700 -0.304800  0.312000 -0.728000 -0.600000
+0.604900 -0.100400 -0.304800  0.744000 -0.360000 -0.552000
+0.600000 -0.100400 -0.312700  0.376000 -0.472000 -0.792000
+0.600000 -0.086300 -0.304800  0.440000 0.312000 -0.832000
+0.600000 -0.086300 -0.304800  0.440000 0.312000 -0.832000
+0.600000 -0.206100 -0.304800  0.488000 0.616000 -0.608000
+0.600000 -0.206100 -0.304800  0.488000 0.616000 -0.608000
+0.650000 -0.208600 -0.304800  0.024000 0.680000 -0.728000
+0.600000 -0.231600 -0.365800  0.072000 0.640000 -0.760000
+0.650000 -0.245700 -0.365800  0.168000 0.856000 -0.480000
+0.600000 -0.249700 -0.426800  -0.344000 0.872000 -0.328000
+0.650000 -0.251000 -0.378600  0.328000 0.752000 -0.560000
+0.604800 -0.251000 -0.426800  0.544000 0.248000 -0.792000
+0.650000 -0.267900 -0.365800  0.280000 -0.440000 -0.848000
+0.600000 -0.252700 -0.426800  -0.416000 -0.736000 -0.520000
+0.600000 -0.288400 -0.365800  -0.376000 -0.712000 -0.584000
+0.598300 -0.251000 -0.426800  -0.848000 0.144000 -0.496000
+0.573000 -0.251000 -0.365800  -0.696000 0.544000 -0.464000
+0.600000 -0.249700 -0.426800  -0.344000 0.872000 -0.328000
+0.600000 -0.231600 -0.365800  0.072000 0.640000 -0.760000
+0.600000 -0.231600 -0.365800  0.072000 0.640000 -0.760000
+0.700000 -0.211400 -0.304800  0.288000 0.624000 -0.720000
+0.700000 -0.211400 -0.304800  0.288000 0.624000 -0.720000
+0.700000 -0.251000 -0.357800  0.296000 0.496000 -0.808000
+0.728900 -0.251000 -0.304800  0.720000 0.440000 -0.528000
+0.700000 -0.301200 -0.354900  0.160000 -0.240000 -0.952000
+0.744500 -0.301200 -0.304800  0.640000 0.104000 -0.760000
+0.744500 -0.301200 -0.304800  0.640000 0.104000 -0.760000
+0.750000 -0.334300 -0.304800  0.512000 0.112000 -0.840000
+0.750000 -0.334300 -0.304800  0.512000 0.112000 -0.840000
+0.750000 -0.351500 -0.307800  0.512000 0.128000 -0.840000
+0.754800 -0.351500 -0.304800  0.424000 0.136000 -0.888000
+0.750000 -0.401700 -0.321600  0.336000 0.000000 -0.936000
+0.779200 -0.401700 -0.304800  0.400000 0.336000 -0.848000
+0.779200 -0.401700 -0.304800  0.400000 0.336000 -0.848000
+0.800000 -0.418300 -0.304800  0.408000 0.496000 -0.760000
+0.800000 -0.418300 -0.304800  0.408000 0.496000 -0.760000
+0.800000 -0.451900 -0.330300  0.328000 0.200000 -0.920000
+0.837100 -0.451900 -0.304800  0.528000 0.264000 -0.800000
+0.800000 -0.493800 -0.304800  0.032000 -0.688000 -0.720000
+0.800000 -0.493800 -0.304800  0.032000 -0.688000 -0.720000
+0.856800 -0.502100 -0.304800  0.288000 0.144000 -0.944000
+0.856800 -0.502100 -0.304800  0.288000 0.144000 -0.944000
+0.850000 -0.502100 -0.307100  0.032000 -0.240000 -0.968000
+0.850000 -0.504700 -0.304800  -0.096000 -0.664000 -0.736000
+0.850000 -0.504700 -0.304800  -0.096000 -0.664000 -0.736000
+0.900000 0.016700 -0.304800  -0.152000 0.720000 -0.664000
+0.900000 0.016700 -0.304800  -0.152000 0.720000 -0.664000
+0.900000 0.000000 -0.329500  -0.080000 0.648000 -0.744000
+0.927400 0.000000 -0.304800  0.400000 0.560000 -0.720000
+0.927400 0.000000 -0.304800  0.400000 0.560000 -0.720000
+-0.850000 -0.496800 -0.365800  -0.176000 0.616000 -0.760000
+-0.850000 -0.496800 -0.365800  -0.176000 0.616000 -0.760000
+-0.864000 -0.502100 -0.365800  -0.304000 0.480000 -0.816000
+-0.850000 -0.502100 -0.370900  -0.184000 0.560000 -0.800000
+-0.860100 -0.552300 -0.365800  -0.680000 -0.432000 -0.584000
+-0.850000 -0.552300 -0.378600  -0.568000 -0.344000 -0.736000
+-0.850000 -0.564700 -0.365800  -0.608000 -0.528000 -0.584000
+-0.800000 -0.552300 -0.401000  -0.552000 -0.288000 -0.776000
+-0.806700 -0.602500 -0.365800  -0.520000 -0.656000 -0.536000
+-0.800000 -0.602500 -0.372400  -0.488000 -0.592000 -0.624000
+-0.800000 -0.607700 -0.365800  -0.488000 -0.640000 -0.584000
+-0.750000 -0.602500 -0.401000  -0.336000 -0.696000 -0.624000
+-0.750000 -0.628000 -0.365800  -0.232000 -0.808000 -0.528000
+-0.714100 -0.602500 -0.426800  -0.368000 -0.680000 -0.624000
+-0.700000 -0.639000 -0.365800  -0.040000 -0.920000 -0.376000
+-0.700000 -0.609100 -0.426800  -0.336000 -0.744000 -0.568000
+-0.650000 -0.641900 -0.365800  -0.024000 -0.952000 -0.280000
+-0.650000 -0.621300 -0.426800  -0.080000 -0.904000 -0.400000
+-0.650000 -0.621300 -0.426800  -0.080000 -0.904000 -0.400000
+-0.850000 -0.496800 -0.365800  -0.176000 0.616000 -0.760000
+-0.850000 -0.496800 -0.365800  -0.176000 0.616000 -0.760000
+-0.800000 -0.496400 -0.365800  -0.664000 0.416000 -0.608000
+-0.850000 -0.502100 -0.370900  -0.184000 0.560000 -0.800000
+-0.800000 -0.502100 -0.369300  -0.768000 0.256000 -0.576000
+-0.850000 -0.552300 -0.378600  -0.568000 -0.344000 -0.736000
+-0.800000 -0.552300 -0.401000  -0.552000 -0.288000 -0.776000
+-0.800000 -0.502100 -0.369300  -0.768000 0.256000 -0.576000
+-0.750000 -0.552300 -0.422100  -0.552000 -0.096000 -0.824000
+-0.750000 -0.502100 -0.424900  -0.848000 -0.112000 -0.512000
+-0.744500 -0.552300 -0.426800  -0.560000 -0.080000 -0.816000
+-0.748800 -0.502100 -0.426800  -0.584000 -0.048000 -0.800000
+-0.750000 -0.502100 -0.424900  -0.848000 -0.112000 -0.512000
+-0.750000 -0.498100 -0.426800  -0.864000 -0.184000 -0.448000
+-0.800000 -0.502100 -0.369300  -0.768000 0.256000 -0.576000
+-0.764100 -0.451900 -0.426800  -0.880000 -0.256000 -0.384000
+-0.800000 -0.496400 -0.365800  -0.664000 0.416000 -0.608000
+-0.786000 -0.451900 -0.365800  -0.872000 0.080000 -0.472000
+-0.764100 -0.451900 -0.426800  -0.880000 -0.256000 -0.384000
+-0.796500 -0.401700 -0.365800  -0.952000 -0.168000 -0.232000
+-0.777800 -0.401700 -0.426800  -0.928000 0.040000 -0.360000
+-0.777800 -0.401700 -0.426800  -0.928000 0.040000 -0.360000
+-0.800000 -0.602500 -0.372400  -0.488000 -0.592000 -0.624000
+-0.800000 -0.602500 -0.372400  -0.488000 -0.592000 -0.624000
+-0.800000 -0.552300 -0.401000  -0.552000 -0.288000 -0.776000
+-0.750000 -0.602500 -0.401000  -0.336000 -0.696000 -0.624000
+-0.750000 -0.552300 -0.422100  -0.552000 -0.096000 -0.824000
+-0.714100 -0.602500 -0.426800  -0.368000 -0.680000 -0.624000
+-0.744500 -0.552300 -0.426800  -0.560000 -0.080000 -0.816000
+-0.744500 -0.552300 -0.426800  -0.560000 -0.080000 -0.816000
+-0.350000 -0.248400 -0.365800  0.184000 0.424000 -0.880000
+-0.350000 -0.248400 -0.365800  0.184000 0.424000 -0.880000
+-0.350000 -0.251000 -0.367200  0.240000 0.168000 -0.952000
+-0.345700 -0.251000 -0.365800  0.320000 0.336000 -0.880000
+-0.345700 -0.251000 -0.365800  0.320000 0.336000 -0.880000
+-0.250000 -0.342900 -0.365800  0.504000 0.512000 -0.680000
+-0.250000 -0.342900 -0.365800  0.504000 0.512000 -0.680000
+-0.250000 -0.351500 -0.379700  0.552000 0.712000 -0.416000
+-0.241400 -0.351500 -0.365800  0.488000 0.640000 -0.576000
+-0.241400 -0.351500 -0.365800  0.488000 0.640000 -0.576000
+-0.200000 -0.365300 -0.365800  0.504000 0.768000 -0.376000
+-0.200000 -0.365300 -0.365800  0.504000 0.768000 -0.376000
+-0.200000 -0.393200 -0.426800  0.696000 0.632000 -0.328000
+-0.151700 -0.401700 -0.365800  0.568000 0.104000 -0.808000
+-0.194300 -0.401700 -0.426800  0.792000 0.416000 -0.432000
+-0.194300 -0.401700 -0.426800  0.792000 0.416000 -0.432000
+-0.044700 -0.251000 -0.365800  -0.216000 0.376000 -0.896000
+-0.044700 -0.251000 -0.365800  -0.216000 0.376000 -0.896000
+0.000000 -0.251000 -0.386300  -0.352000 0.496000 -0.792000
+0.000000 -0.238800 -0.365800  -0.192000 0.648000 -0.728000
+0.000000 -0.238800 -0.365800  -0.192000 0.648000 -0.728000
+0.100000 -0.224900 -0.365800  0.352000 0.456000 -0.808000
+0.100000 -0.224900 -0.365800  0.352000 0.456000 -0.808000
+0.100000 -0.251000 -0.380100  0.472000 -0.384000 -0.784000
+0.118000 -0.251000 -0.365800  0.536000 -0.224000 -0.808000
+0.100000 -0.263400 -0.365800  0.480000 -0.672000 -0.544000
+0.100000 -0.263400 -0.365800  0.480000 -0.672000 -0.544000
+0.350000 -0.354600 -0.365800  -0.264000 -0.632000 -0.720000
+0.350000 -0.354600 -0.365800  -0.264000 -0.632000 -0.720000
+0.350000 -0.351500 -0.368100  -0.440000 0.096000 -0.888000
+0.348000 -0.351500 -0.365800  -0.720000 -0.032000 -0.680000
+0.348000 -0.351500 -0.365800  -0.720000 -0.032000 -0.680000
+0.450000 0.007700 -0.365800  -0.264000 0.744000 -0.600000
+0.450000 0.007700 -0.365800  -0.264000 0.744000 -0.600000
+0.431500 0.000000 -0.365800  -0.424000 0.312000 -0.840000
+0.450000 0.000000 -0.377000  -0.360000 0.400000 -0.840000
+0.450000 -0.014200 -0.365800  -0.336000 -0.568000 -0.744000
+0.450000 -0.014200 -0.365800  -0.336000 -0.568000 -0.744000
+0.650000 -0.245700 -0.365800  0.168000 0.856000 -0.480000
+0.650000 -0.245700 -0.365800  0.168000 0.856000 -0.480000
+0.650000 -0.251000 -0.378600  0.328000 0.752000 -0.560000
+0.678000 -0.251000 -0.365800  0.264000 0.520000 -0.808000
+0.650000 -0.267900 -0.365800  0.280000 -0.440000 -0.848000
diff --git a/progs/demos/morph3d.c b/progs/demos/morph3d.c
new file mode 100644 (file)
index 0000000..30ca922
--- /dev/null
@@ -0,0 +1,892 @@
+/* $Id: morph3d.c,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
+
+/*
+ * $Log: morph3d.c,v $
+ * Revision 1.1  1999/08/19 00:55:40  jtg
+ * Initial revision
+ *
+ * Revision 3.1  1998/06/29 02:37:30  brianp
+ * minor changes for Windows (Ted Jump)
+ *
+ * Revision 3.0  1998/02/14 18:42:29  brianp
+ * initial rev
+ *
+ */
+
+
+/*-
+ * morph3d.c - Shows 3D morphing objects
+ *
+ * Converted to GLUT by brianp on 1/1/98
+ *
+ * This program was inspired on a WindowsNT(R)'s screen saver. It was written 
+ * from scratch and it was not based on any other source code. 
+ * 
+ * Porting it to xlock (the final objective of this code since the moment I
+ * decided to create it) was possible by comparing the original Mesa's gear
+ * demo with it's ported version, so thanks for Danny Sung for his indirect
+ * help (look at gear.c in xlock source tree). NOTE: At the moment this code
+ * was sent to Brian Paul for package inclusion, the XLock Version was not
+ * available. In fact, I'll wait it to appear on the next Mesa release (If you
+ * are reading this, it means THIS release) to send it for xlock package 
+ * inclusion). It will probably there be a GLUT version too.
+ *
+ * Thanks goes also to Brian Paul for making it possible and inexpensive
+ * to use OpenGL at home.
+ *
+ * Since I'm not a native english speaker, my apologies for any gramatical
+ * mistake.
+ *
+ * My e-mail addresses are
+ *
+ * vianna@cat.cbpf.br 
+ *         and
+ * marcelo@venus.rdc.puc-rio.br
+ *
+ * Marcelo F. Vianna (Feb-13-1997)
+ */
+
+/*
+This document is VERY incomplete, but tries to describe the mathematics used
+in the program. At this moment it just describes how the polyhedra are 
+generated. On futhurer versions, this document will be probabbly improved.
+
+Since I'm not a native english speaker, my apologies for any gramatical
+mistake.
+
+Marcelo Fernandes Vianna 
+- Undergraduate in Computer Engeneering at Catholic Pontifical University
+- of Rio de Janeiro (PUC-Rio) Brasil.
+- e-mail: vianna@cat.cbpf.br or marcelo@venus.rdc.puc-rio.br
+- Feb-13-1997
+
+POLYHEDRA GENERATION
+
+For the purpose of this program it's not sufficient to know the polyhedra
+vertexes coordinates. Since the morphing algorithm applies a nonlinear 
+transformation over the surfaces (faces) of the polyhedron, each face has
+to be divided into smaller ones. The morphing algorithm needs to transform 
+each vertex of these smaller faces individually. It's a very time consoming
+task.
+
+In order to reduce calculation overload, and since all the macro faces of
+the polyhedron are transformed by the same way, the generation is made by 
+creating only one face of the polyhedron, morphing it and then rotating it
+around the polyhedron center. 
+
+What we need to know is the face radius of the polyhedron (the radius of 
+the inscribed sphere) and the angle between the center of two adjacent 
+faces using the center of the sphere as the angle's vertex.
+
+The face radius of the regular polyhedra are known values which I decided
+to not waste my time calculating. Following is a table of face radius for
+the regular polyhedra with edge length = 1:
+
+    TETRAHEDRON  : 1/(2*sqrt(2))/sqrt(3)
+    CUBE        : 1/2
+    OCTAHEDRON   : 1/sqrt(6)
+    DODECAHEDRON : T^2 * sqrt((T+2)/5) / 2     -> where T=(sqrt(5)+1)/2
+    ICOSAHEDRON  : (3*sqrt(3)+sqrt(15))/12
+
+I've not found any reference about the mentioned angles, so I needed to
+calculate them, not a trivial task until I figured out how :)
+Curiously these angles are the same for the tetrahedron and octahedron.
+A way to obtain this value is inscribing the tetrahedron inside the cube
+by matching their vertexes. So you'll notice that the remaining unmatched
+vertexes are in the same straight line starting in the cube/tetrahedron
+center and crossing the center of each tetrahedron's face. At this point
+it's easy to obtain the bigger angle of the isosceles triangle formed by
+the center of the cube and two opposite vertexes on the same cube face.
+The edges of this triangle have the following lenghts: sqrt(2) for the base
+and sqrt(3)/2 for the other two other edges. So the angle we want is:
+     +-----------------------------------------------------------+
+     | 2*ARCSIN(sqrt(2)/sqrt(3)) = 109.47122063449069174 degrees |
+     +-----------------------------------------------------------+
+For the cube this angle is obvious, but just for formality it can be
+easily obtained because we also know it's isosceles edge lenghts:
+sqrt(2)/2 for the base and 1/2 for the other two edges. So the angle we 
+want is:
+     +-----------------------------------------------------------+
+     | 2*ARCSIN((sqrt(2)/2)/1)   = 90.000000000000000000 degrees |
+     +-----------------------------------------------------------+
+For the octahedron we use the same idea used for the tetrahedron, but now
+we inscribe the cube inside the octahedron so that all cubes's vertexes
+matches excatly the center of each octahedron's face. It's now clear that
+this angle is the same of the thetrahedron one:
+     +-----------------------------------------------------------+
+     | 2*ARCSIN(sqrt(2)/sqrt(3)) = 109.47122063449069174 degrees |
+     +-----------------------------------------------------------+
+For the dodecahedron it's a little bit harder because it's only relationship
+with the cube is useless to us. So we need to solve the problem by another
+way. The concept of Face radius also exists on 2D polygons with the name
+Edge radius:
+  Edge Radius For Pentagon (ERp)
+  ERp = (1/2)/TAN(36 degrees) * VRp = 0.6881909602355867905
+  (VRp is the pentagon's vertex radio).
+  Face Radius For Dodecahedron
+  FRd = T^2 * sqrt((T+2)/5) / 2 = 1.1135163644116068404
+Why we need ERp? Well, ERp and FRd segments forms a 90 degrees angle, 
+completing this triangle, the lesser angle is a half of the angle we are 
+looking for, so this angle is:
+     +-----------------------------------------------------------+
+     | 2*ARCTAN(ERp/FRd)        = 63.434948822922009981 degrees |
+     +-----------------------------------------------------------+
+For the icosahedron we can use the same method used for dodecahedron (well
+the method used for dodecahedron may be used for all regular polyhedra)
+  Edge Radius For Triangle (this one is well known: 1/3 of the triangle height)
+  ERt = sin(60)/3 = sqrt(3)/6 = 0.2886751345948128655
+  Face Radius For Icosahedron
+  FRi= (3*sqrt(3)+sqrt(15))/12 = 0.7557613140761707538
+So the angle is:
+     +-----------------------------------------------------------+
+     | 2*ARCTAN(ERt/FRi)        = 41.810314895778596167 degrees |
+     +-----------------------------------------------------------+
+
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+#include <GL/glut.h>
+#include <math.h>
+#include <string.h>
+
+#define Scale                      0.3
+
+#define VectMul(X1,Y1,Z1,X2,Y2,Z2) (Y1)*(Z2)-(Z1)*(Y2),(Z1)*(X2)-(X1)*(Z2),(X1)*(Y2)-(Y1)*(X2)
+#define sqr(A)                     ((A)*(A))
+
+/* Increasing this values produces better image quality, the price is speed. */
+/* Very low values produces erroneous/incorrect plotting */
+#define tetradivisions             23
+#define cubedivisions              20
+#define octadivisions              21
+#define dodecadivisions            10
+#define icodivisions               15
+
+#define tetraangle                 109.47122063449069174
+#define cubeangle                  90.000000000000000000
+#define octaangle                  109.47122063449069174
+#define dodecaangle                63.434948822922009981
+#define icoangle                   41.810314895778596167
+
+#ifndef Pi
+#define Pi                         3.1415926535897932385
+#endif
+#define SQRT2                      1.4142135623730951455
+#define SQRT3                      1.7320508075688771932
+#define SQRT5                      2.2360679774997898051
+#define SQRT6                      2.4494897427831778813
+#define SQRT15                     3.8729833462074170214
+#define cossec36_2                 0.8506508083520399322
+#define cos72                      0.3090169943749474241
+#define sin72                      0.9510565162951535721
+#define cos36                      0.8090169943749474241
+#define sin36                      0.5877852522924731292
+
+/*************************************************************************/
+
+static int       mono=0;
+static int       smooth=1;
+static GLint     WindH, WindW;
+static GLfloat   step=0;
+static GLfloat   seno;
+static int       object;
+static int       edgedivisions;
+static void      (*draw_object)( void );
+static float     Magnitude;
+static float     *MaterialColor[20];
+
+static float front_shininess[] =   {60.0};
+static float front_specular[]  =   { 0.7, 0.7, 0.7, 1.0 };
+static float ambient[]         =   { 0.0, 0.0, 0.0, 1.0 };
+static float diffuse[]         =   { 1.0, 1.0, 1.0, 1.0 };
+static float position0[]       =   { 1.0, 1.0, 1.0, 0.0 };
+static float position1[]       =   {-1.0,-1.0, 1.0, 0.0 };
+static float lmodel_ambient[]  =   { 0.5, 0.5, 0.5, 1.0 };
+static float lmodel_twoside[]  =   {GL_TRUE};
+
+static float MaterialRed[]     =   { 0.7, 0.0, 0.0, 1.0 };
+static float MaterialGreen[]   =   { 0.1, 0.5, 0.2, 1.0 };
+static float MaterialBlue[]    =   { 0.0, 0.0, 0.7, 1.0 };
+static float MaterialCyan[]    =   { 0.2, 0.5, 0.7, 1.0 };
+static float MaterialYellow[]  =   { 0.7, 0.7, 0.0, 1.0 };
+static float MaterialMagenta[] =   { 0.6, 0.2, 0.5, 1.0 };
+static float MaterialWhite[]   =   { 0.7, 0.7, 0.7, 1.0 };
+static float MaterialGray[]    =   { 0.2, 0.2, 0.2, 1.0 };
+
+#define TRIANGLE(Edge, Amp, Divisions, Z)                                                                        \
+{                                                                                                                \
+  GLfloat   Xf,Yf,Xa,Yb,Xf2,Yf2;                                                                                 \
+  GLfloat   Factor,Factor1,Factor2;                                                                              \
+  GLfloat   VertX,VertY,VertZ,NeiAX,NeiAY,NeiAZ,NeiBX,NeiBY,NeiBZ;                                               \
+  GLfloat   Ax,Ay,Bx;                                                                                            \
+  int       Ri,Ti;                                                                                               \
+  GLfloat   Vr=(Edge)*SQRT3/3;                                                                                   \
+  GLfloat   AmpVr2=(Amp)/sqr(Vr);                                                                                \
+  GLfloat   Zf=(Edge)*(Z);                                                                                       \
+                                                                                                                 \
+  Ax=(Edge)*(+0.5/(Divisions)), Ay=(Edge)*(-SQRT3/(2*Divisions));                                                \
+  Bx=(Edge)*(-0.5/(Divisions));                                                                                  \
+                                                                                                                 \
+  for (Ri=1; Ri<=(Divisions); Ri++) {                                                                            \
+    glBegin(GL_TRIANGLE_STRIP);                                                                                  \
+    for (Ti=0; Ti<Ri; Ti++) {                                                                                    \
+      Xf=(float)(Ri-Ti)*Ax + (float)Ti*Bx;                                                                       \
+      Yf=Vr+(float)(Ri-Ti)*Ay + (float)Ti*Ay;                                                                    \
+      Xa=Xf+0.001; Yb=Yf+0.001;                                                                                  \
+      Factor=1-(((Xf2=sqr(Xf))+(Yf2=sqr(Yf)))*AmpVr2);                                                           \
+      Factor1=1-((sqr(Xa)+Yf2)*AmpVr2);                                                                          \
+      Factor2=1-((Xf2+sqr(Yb))*AmpVr2);                                                                          \
+      VertX=Factor*Xf;        VertY=Factor*Yf;        VertZ=Factor*Zf;                                           \
+      NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ;                                    \
+      NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ;                                    \
+      glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ));                                             \
+      glVertex3f(VertX, VertY, VertZ);                                                                           \
+                                                                                                                 \
+      Xf=(float)(Ri-Ti-1)*Ax + (float)Ti*Bx;                                                                     \
+      Yf=Vr+(float)(Ri-Ti-1)*Ay + (float)Ti*Ay;                                                                  \
+      Xa=Xf+0.001; Yb=Yf+0.001;                                                                                  \
+      Factor=1-(((Xf2=sqr(Xf))+(Yf2=sqr(Yf)))*AmpVr2);                                                           \
+      Factor1=1-((sqr(Xa)+Yf2)*AmpVr2);                                                                          \
+      Factor2=1-((Xf2+sqr(Yb))*AmpVr2);                                                                          \
+      VertX=Factor*Xf;        VertY=Factor*Yf;        VertZ=Factor*Zf;                                           \
+      NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ;                                    \
+      NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ;                                    \
+      glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ));                                             \
+      glVertex3f(VertX, VertY, VertZ);                                                                           \
+                                                                                                                 \
+    }                                                                                                            \
+    Xf=(float)Ri*Bx;                                                                                             \
+    Yf=Vr+(float)Ri*Ay;                                                                                          \
+    Xa=Xf+0.001; Yb=Yf+0.001;                                                                                    \
+    Factor=1-(((Xf2=sqr(Xf))+(Yf2=sqr(Yf)))*AmpVr2);                                                             \
+    Factor1=1-((sqr(Xa)+Yf2)*AmpVr2);                                                                            \
+    Factor2=1-((Xf2+sqr(Yb))*AmpVr2);                                                                            \
+    VertX=Factor*Xf;        VertY=Factor*Yf;        VertZ=Factor*Zf;                                             \
+    NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ;                                      \
+    NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ;                                      \
+    glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ));                                               \
+    glVertex3f(VertX, VertY, VertZ);                                                                             \
+    glEnd();                                                                                                     \
+  }                                                                                                              \
+}
+
+#define SQUARE(Edge, Amp, Divisions, Z)                                                                          \
+{                                                                                                                \
+  int       Xi,Yi;                                                                                               \
+  GLfloat   Xf,Yf,Y,Xf2,Yf2,Y2,Xa,Yb;                                                                            \
+  GLfloat   Factor,Factor1,Factor2;                                                                              \
+  GLfloat   VertX,VertY,VertZ,NeiAX,NeiAY,NeiAZ,NeiBX,NeiBY,NeiBZ;                                               \
+  GLfloat   Zf=(Edge)*(Z);                                                                                       \
+  GLfloat   AmpVr2=(Amp)/sqr((Edge)*SQRT2/2);                                                                    \
+                                                                                                                 \
+  for (Yi=0; Yi<(Divisions); Yi++) {                                                                             \
+    Yf=-((Edge)/2.0) + ((float)Yi)/(Divisions)*(Edge);                                                           \
+    Yf2=sqr(Yf);                                                                                                 \
+    Y=Yf+1.0/(Divisions)*(Edge);                                                                                 \
+    Y2=sqr(Y);                                                                                                   \
+    glBegin(GL_QUAD_STRIP);                                                                                      \
+    for (Xi=0; Xi<=(Divisions); Xi++) {                                                                          \
+      Xf=-((Edge)/2.0) + ((float)Xi)/(Divisions)*(Edge);                                                         \
+      Xf2=sqr(Xf);                                                                                               \
+                                                                                                                 \
+      Xa=Xf+0.001; Yb=Y+0.001;                                                                                   \
+      Factor=1-((Xf2+Y2)*AmpVr2);                                                                                \
+      Factor1=1-((sqr(Xa)+Y2)*AmpVr2);                                                                           \
+      Factor2=1-((Xf2+sqr(Yb))*AmpVr2);                                                                          \
+      VertX=Factor*Xf;        VertY=Factor*Y;         VertZ=Factor*Zf;                                           \
+      NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Y-VertY;  NeiAZ=Factor1*Zf-VertZ;                                    \
+      NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ;                                    \
+      glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ));                                             \
+      glVertex3f(VertX, VertY, VertZ);                                                                           \
+                                                                                                                 \
+      Xa=Xf+0.001; Yb=Yf+0.001;                                                                                  \
+      Factor=1-((Xf2+Yf2)*AmpVr2);                                                                               \
+      Factor1=1-((sqr(Xa)+Yf2)*AmpVr2);                                                                          \
+      Factor2=1-((Xf2+sqr(Yb))*AmpVr2);                                                                          \
+      VertX=Factor*Xf;        VertY=Factor*Yf;        VertZ=Factor*Zf;                                           \
+      NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ;                                    \
+      NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ;                                    \
+      glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ));                                             \
+      glVertex3f(VertX, VertY, VertZ);                                                                           \
+    }                                                                                                            \
+    glEnd();                                                                                                     \
+  }                                                                                                              \
+}
+
+#define PENTAGON(Edge, Amp, Divisions, Z)                                                                        \
+{                                                                                                                \
+  int       Ri,Ti,Fi;                                                                                            \
+  GLfloat   Xf,Yf,Xa,Yb,Xf2,Yf2;                                                                                 \
+  GLfloat   x[6],y[6];                                                                                           \
+  GLfloat   Factor,Factor1,Factor2;                                                                              \
+  GLfloat   VertX,VertY,VertZ,NeiAX,NeiAY,NeiAZ,NeiBX,NeiBY,NeiBZ;                                               \
+  GLfloat   Zf=(Edge)*(Z);                                                                                       \
+  GLfloat   AmpVr2=(Amp)/sqr((Edge)*cossec36_2);                                                                 \
+                                                                                                                 \
+  for(Fi=0;Fi<6;Fi++) {                                                                                          \
+    x[Fi]=-cos( Fi*2*Pi/5 + Pi/10 )/(Divisions)*cossec36_2*(Edge);                                                \
+    y[Fi]=sin( Fi*2*Pi/5 + Pi/10 )/(Divisions)*cossec36_2*(Edge);                                                \
+  }                                                                                                              \
+                                                                                                                 \
+  for (Ri=1; Ri<=(Divisions); Ri++) {                                                                            \
+    for (Fi=0; Fi<5; Fi++) {                                                                                     \
+      glBegin(GL_TRIANGLE_STRIP);                                                                                \
+      for (Ti=0; Ti<Ri; Ti++) {                                                                                  \
+        Xf=(float)(Ri-Ti)*x[Fi] + (float)Ti*x[Fi+1];                                                             \
+        Yf=(float)(Ri-Ti)*y[Fi] + (float)Ti*y[Fi+1];                                                             \
+        Xa=Xf+0.001; Yb=Yf+0.001;                                                                                \
+       Factor=1-(((Xf2=sqr(Xf))+(Yf2=sqr(Yf)))*AmpVr2);                                                         \
+       Factor1=1-((sqr(Xa)+Yf2)*AmpVr2);                                                                        \
+       Factor2=1-((Xf2+sqr(Yb))*AmpVr2);                                                                        \
+        VertX=Factor*Xf;        VertY=Factor*Yf;        VertZ=Factor*Zf;                                         \
+        NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ;                                  \
+        NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ;                                  \
+        glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ));                                           \
+       glVertex3f(VertX, VertY, VertZ);                                                                         \
+                                                                                                                 \
+        Xf=(float)(Ri-Ti-1)*x[Fi] + (float)Ti*x[Fi+1];                                                           \
+        Yf=(float)(Ri-Ti-1)*y[Fi] + (float)Ti*y[Fi+1];                                                           \
+        Xa=Xf+0.001; Yb=Yf+0.001;                                                                                \
+       Factor=1-(((Xf2=sqr(Xf))+(Yf2=sqr(Yf)))*AmpVr2);                                                         \
+       Factor1=1-((sqr(Xa)+Yf2)*AmpVr2);                                                                        \
+       Factor2=1-((Xf2+sqr(Yb))*AmpVr2);                                                                        \
+        VertX=Factor*Xf;        VertY=Factor*Yf;        VertZ=Factor*Zf;                                         \
+        NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ;                                  \
+        NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ;                                  \
+        glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ));                                           \
+       glVertex3f(VertX, VertY, VertZ);                                                                         \
+                                                                                                                 \
+      }                                                                                                          \
+      Xf=(float)Ri*x[Fi+1];                                                                                      \
+      Yf=(float)Ri*y[Fi+1];                                                                                      \
+      Xa=Xf+0.001; Yb=Yf+0.001;                                                                                  \
+      Factor=1-(((Xf2=sqr(Xf))+(Yf2=sqr(Yf)))*AmpVr2);                                                           \
+      Factor1=1-((sqr(Xa)+Yf2)*AmpVr2);                                                                          \
+      Factor2=1-((Xf2+sqr(Yb))*AmpVr2);                                                                          \
+      VertX=Factor*Xf;        VertY=Factor*Yf;        VertZ=Factor*Zf;                                           \
+      NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ;                                    \
+      NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ;                                    \
+      glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ));                                             \
+      glVertex3f(VertX, VertY, VertZ);                                                                           \
+      glEnd();                                                                                                   \
+    }                                                                                                            \
+  }                                                                                                              \
+}
+
+static void draw_tetra( void )
+{
+  GLuint list;
+
+  list = glGenLists( 1 );
+  glNewList( list, GL_COMPILE );
+  TRIANGLE(2,seno,edgedivisions,0.5/SQRT6);
+  glEndList();
+
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[0]);
+  glCallList(list);
+  glPushMatrix();
+  glRotatef(180,0,0,1);
+  glRotatef(-tetraangle,1,0,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[1]);
+  glCallList(list);
+  glPopMatrix();
+  glPushMatrix();
+  glRotatef(180,0,1,0);
+  glRotatef(-180+tetraangle,0.5,SQRT3/2,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[2]);
+  glCallList(list);
+  glPopMatrix();
+  glRotatef(180,0,1,0);
+  glRotatef(-180+tetraangle,0.5,-SQRT3/2,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[3]);
+  glCallList(list);
+
+  glDeleteLists(list,1);
+}
+
+static void draw_cube( void )
+{
+  GLuint list;
+
+  list = glGenLists( 1 );
+  glNewList( list, GL_COMPILE );
+  SQUARE(2, seno, edgedivisions, 0.5)
+  glEndList();
+
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[0]);
+  glCallList(list);
+  glRotatef(cubeangle,1,0,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[1]);
+  glCallList(list);
+  glRotatef(cubeangle,1,0,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[2]);
+  glCallList(list);
+  glRotatef(cubeangle,1,0,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[3]);
+  glCallList(list);
+  glRotatef(cubeangle,0,1,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[4]);
+  glCallList(list);
+  glRotatef(2*cubeangle,0,1,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[5]);
+  glCallList(list);
+
+  glDeleteLists(list,1);
+}
+
+static void draw_octa( void )
+{
+  GLuint list;
+
+  list = glGenLists( 1 );
+  glNewList( list, GL_COMPILE );
+  TRIANGLE(2,seno,edgedivisions,1/SQRT6);
+  glEndList();
+
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[0]);
+  glCallList(list);
+  glPushMatrix();
+  glRotatef(180,0,0,1);
+  glRotatef(-180+octaangle,1,0,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[1]);
+  glCallList(list);
+  glPopMatrix();
+  glPushMatrix();
+  glRotatef(180,0,1,0);
+  glRotatef(-octaangle,0.5,SQRT3/2,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[2]);
+  glCallList(list);
+  glPopMatrix();
+  glPushMatrix();
+  glRotatef(180,0,1,0);
+  glRotatef(-octaangle,0.5,-SQRT3/2,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[3]);
+  glCallList(list);
+  glPopMatrix();
+  glRotatef(180,1,0,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[4]);
+  glCallList(list);
+  glPushMatrix();
+  glRotatef(180,0,0,1);
+  glRotatef(-180+octaangle,1,0,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[5]);
+  glCallList(list);
+  glPopMatrix();
+  glPushMatrix();
+  glRotatef(180,0,1,0);
+  glRotatef(-octaangle,0.5,SQRT3/2,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[6]);
+  glCallList(list);
+  glPopMatrix();
+  glRotatef(180,0,1,0);
+  glRotatef(-octaangle,0.5,-SQRT3/2,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[7]);
+  glCallList(list);
+
+  glDeleteLists(list,1);
+}
+
+static void draw_dodeca( void )
+{
+  GLuint list;
+
+  #define TAU ((SQRT5+1)/2)
+
+  list = glGenLists( 1 );
+  glNewList( list, GL_COMPILE );
+  PENTAGON(1,seno,edgedivisions,sqr(TAU) * sqrt((TAU+2)/5) / 2);
+  glEndList();
+
+  glPushMatrix();
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[0]);
+  glCallList(list);
+  glRotatef(180,0,0,1);
+  glPushMatrix();
+  glRotatef(-dodecaangle,1,0,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[1]);
+  glCallList(list);
+  glPopMatrix();
+  glPushMatrix();
+  glRotatef(-dodecaangle,cos72,sin72,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[2]);
+  glCallList(list);
+  glPopMatrix();
+  glPushMatrix();
+  glRotatef(-dodecaangle,cos72,-sin72,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[3]);
+  glCallList(list);
+  glPopMatrix();
+  glPushMatrix();
+  glRotatef(dodecaangle,cos36,-sin36,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[4]);
+  glCallList(list);
+  glPopMatrix();
+  glRotatef(dodecaangle,cos36,sin36,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[5]);
+  glCallList(list);
+  glPopMatrix();
+  glRotatef(180,1,0,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[6]);
+  glCallList(list);
+  glRotatef(180,0,0,1);
+  glPushMatrix();
+  glRotatef(-dodecaangle,1,0,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[7]);
+  glCallList(list);
+  glPopMatrix();
+  glPushMatrix();
+  glRotatef(-dodecaangle,cos72,sin72,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[8]);
+  glCallList(list);
+  glPopMatrix();
+  glPushMatrix();
+  glRotatef(-dodecaangle,cos72,-sin72,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[9]);
+  glCallList(list);
+  glPopMatrix();
+  glPushMatrix();
+  glRotatef(dodecaangle,cos36,-sin36,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[10]);
+  glCallList(list);
+  glPopMatrix();
+  glRotatef(dodecaangle,cos36,sin36,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[11]);
+  glCallList(list);
+
+  glDeleteLists(list,1);
+}
+
+static void draw_ico( void )
+{
+  GLuint list;
+
+  list = glGenLists( 1 );
+  glNewList( list, GL_COMPILE );
+  TRIANGLE(1.5,seno,edgedivisions,(3*SQRT3+SQRT15)/12);
+  glEndList();
+
+  glPushMatrix();
+
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[0]);
+  glCallList(list);
+  glPushMatrix();
+  glRotatef(180,0,0,1);
+  glRotatef(-icoangle,1,0,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[1]);
+  glCallList(list);
+  glPushMatrix();
+  glRotatef(180,0,1,0);
+  glRotatef(-180+icoangle,0.5,SQRT3/2,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[2]);
+  glCallList(list);
+  glPopMatrix();
+  glRotatef(180,0,1,0);
+  glRotatef(-180+icoangle,0.5,-SQRT3/2,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[3]);
+  glCallList(list);
+  glPopMatrix();
+  glPushMatrix();
+  glRotatef(180,0,1,0);
+  glRotatef(-180+icoangle,0.5,SQRT3/2,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[4]);
+  glCallList(list);
+  glPushMatrix();
+  glRotatef(180,0,1,0);
+  glRotatef(-180+icoangle,0.5,SQRT3/2,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[5]);
+  glCallList(list);
+  glPopMatrix();
+  glRotatef(180,0,0,1);
+  glRotatef(-icoangle,1,0,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[6]);
+  glCallList(list);
+  glPopMatrix();
+  glRotatef(180,0,1,0);
+  glRotatef(-180+icoangle,0.5,-SQRT3/2,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[7]);
+  glCallList(list);
+  glPushMatrix();
+  glRotatef(180,0,1,0);
+  glRotatef(-180+icoangle,0.5,-SQRT3/2,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[8]);
+  glCallList(list);
+  glPopMatrix();
+  glRotatef(180,0,0,1);
+  glRotatef(-icoangle,1,0,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[9]);
+  glCallList(list);
+  glPopMatrix();
+  glRotatef(180,1,0,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[10]);
+  glCallList(list);
+  glPushMatrix();
+  glRotatef(180,0,0,1);
+  glRotatef(-icoangle,1,0,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[11]);
+  glCallList(list);
+  glPushMatrix();
+  glRotatef(180,0,1,0);
+  glRotatef(-180+icoangle,0.5,SQRT3/2,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[12]);
+  glCallList(list);
+  glPopMatrix();
+  glRotatef(180,0,1,0);
+  glRotatef(-180+icoangle,0.5,-SQRT3/2,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[13]);
+  glCallList(list);
+  glPopMatrix();
+  glPushMatrix();
+  glRotatef(180,0,1,0);
+  glRotatef(-180+icoangle,0.5,SQRT3/2,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[14]);
+  glCallList(list);
+  glPushMatrix();
+  glRotatef(180,0,1,0);
+  glRotatef(-180+icoangle,0.5,SQRT3/2,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[15]);
+  glCallList(list);
+  glPopMatrix();
+  glRotatef(180,0,0,1);
+  glRotatef(-icoangle,1,0,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[16]);
+  glCallList(list);
+  glPopMatrix();
+  glRotatef(180,0,1,0);
+  glRotatef(-180+icoangle,0.5,-SQRT3/2,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[17]);
+  glCallList(list);
+  glPushMatrix();
+  glRotatef(180,0,1,0);
+  glRotatef(-180+icoangle,0.5,-SQRT3/2,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[18]);
+  glCallList(list);
+  glPopMatrix();
+  glRotatef(180,0,0,1);
+  glRotatef(-icoangle,1,0,0);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[19]);
+  glCallList(list);
+
+  glDeleteLists(list,1);
+}
+
+static void draw ( void ) {
+  glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+
+  glPushMatrix();
+
+    glTranslatef( 0.0, 0.0, -10.0 );
+    glScalef( Scale*WindH/WindW, Scale, Scale );
+    glTranslatef(2.5*WindW/WindH*sin(step*1.11),2.5*cos(step*1.25*1.11),0);
+    glRotatef(step*100,1,0,0);
+    glRotatef(step*95,0,1,0);
+    glRotatef(step*90,0,0,1);
+
+  seno=(sin(step)+1.0/3.0)*(4.0/5.0)*Magnitude;
+
+  draw_object();
+
+  glPopMatrix();
+
+  glFlush();
+
+  glutSwapBuffers();
+
+  step+=0.05;
+}
+
+static void idle_( void )
+{
+   glutPostRedisplay();
+}
+
+static void reshape( int width, int height )
+{
+  glViewport(0, 0, WindW=(GLint)width, WindH=(GLint)height);
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+  glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 15.0 );
+  glMatrixMode(GL_MODELVIEW);
+}
+
+static void pinit(void);
+
+static void key( unsigned char k, int x, int y )
+{
+  switch (k) {
+    case '1': object=1; break;
+    case '2': object=2; break;
+    case '3': object=3; break;
+    case '4': object=4; break;
+    case '5': object=5; break;
+    case ' ': mono^=1; break;
+    case 13: smooth^=1; break;
+    case 27:
+       exit(0);
+  }
+  pinit();
+}
+
+static void pinit(void)
+{
+  switch(object) {
+    case 1:
+      draw_object=draw_tetra;
+      MaterialColor[0]=MaterialRed;
+      MaterialColor[1]=MaterialGreen;
+      MaterialColor[2]=MaterialBlue;
+      MaterialColor[3]=MaterialWhite;
+      edgedivisions=tetradivisions;
+      Magnitude=2.5;
+      break;
+    case 2:
+      draw_object=draw_cube;
+      MaterialColor[0]=MaterialRed;
+      MaterialColor[1]=MaterialGreen;
+      MaterialColor[2]=MaterialCyan;
+      MaterialColor[3]=MaterialMagenta;
+      MaterialColor[4]=MaterialYellow;
+      MaterialColor[5]=MaterialBlue;
+      edgedivisions=cubedivisions;
+      Magnitude=2.0;
+      break;
+    case 3:
+      draw_object=draw_octa;
+      MaterialColor[0]=MaterialRed;
+      MaterialColor[1]=MaterialGreen;
+      MaterialColor[2]=MaterialBlue;
+      MaterialColor[3]=MaterialWhite;
+      MaterialColor[4]=MaterialCyan;
+      MaterialColor[5]=MaterialMagenta;
+      MaterialColor[6]=MaterialGray;
+      MaterialColor[7]=MaterialYellow;
+      edgedivisions=octadivisions;
+      Magnitude=2.5;
+      break;
+    case 4:
+      draw_object=draw_dodeca;
+      MaterialColor[ 0]=MaterialRed;
+      MaterialColor[ 1]=MaterialGreen;
+      MaterialColor[ 2]=MaterialCyan;
+      MaterialColor[ 3]=MaterialBlue;
+      MaterialColor[ 4]=MaterialMagenta;
+      MaterialColor[ 5]=MaterialYellow;
+      MaterialColor[ 6]=MaterialGreen;
+      MaterialColor[ 7]=MaterialCyan;
+      MaterialColor[ 8]=MaterialRed;
+      MaterialColor[ 9]=MaterialMagenta;
+      MaterialColor[10]=MaterialBlue;
+      MaterialColor[11]=MaterialYellow;
+      edgedivisions=dodecadivisions;
+      Magnitude=2.0;
+      break;
+    case 5:
+      draw_object=draw_ico;
+      MaterialColor[ 0]=MaterialRed;
+      MaterialColor[ 1]=MaterialGreen;
+      MaterialColor[ 2]=MaterialBlue;
+      MaterialColor[ 3]=MaterialCyan;
+      MaterialColor[ 4]=MaterialYellow;
+      MaterialColor[ 5]=MaterialMagenta;
+      MaterialColor[ 6]=MaterialRed;
+      MaterialColor[ 7]=MaterialGreen;
+      MaterialColor[ 8]=MaterialBlue;
+      MaterialColor[ 9]=MaterialWhite;
+      MaterialColor[10]=MaterialCyan;
+      MaterialColor[11]=MaterialYellow;
+      MaterialColor[12]=MaterialMagenta;
+      MaterialColor[13]=MaterialRed;
+      MaterialColor[14]=MaterialGreen;
+      MaterialColor[15]=MaterialBlue;
+      MaterialColor[16]=MaterialCyan;
+      MaterialColor[17]=MaterialYellow;
+      MaterialColor[18]=MaterialMagenta;
+      MaterialColor[19]=MaterialGray;
+      edgedivisions=icodivisions;
+      Magnitude=2.5;
+      break;
+  }
+  if (mono) {
+    int loop;
+    for (loop=0; loop<20; loop++) MaterialColor[loop]=MaterialGray;
+  }
+  if (smooth) {
+    glShadeModel( GL_SMOOTH );
+  } else {
+    glShadeModel( GL_FLAT );
+  }
+
+}
+
+void INIT(void)
+{
+  printf("Morph 3D - Shows morphing platonic polyhedra\n");
+  printf("Author: Marcelo Fernandes Vianna (vianna@cat.cbpf.br)\n\n");
+  printf("  [1]    - Tetrahedron\n");
+  printf("  [2]    - Hexahedron (Cube)\n");
+  printf("  [3]    - Octahedron\n");
+  printf("  [4]    - Dodecahedron\n");
+  printf("  [5]    - Icosahedron\n");
+  printf("[SPACE]  - Toggle colored faces\n");
+  printf("[RETURN] - Toggle smooth/flat shading\n");
+  printf(" [ESC]   - Quit\n");
+
+  object=1;
+
+  glutInitWindowPosition(0,0);
+  glutInitWindowSize(640,480);
+
+  glutInitDisplayMode( GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB );
+
+  if (glutCreateWindow("Morph 3D - Shows morphing platonic polyhedra") <= 0) {
+     exit(0);
+  }
+
+  glClearDepth(1.0);
+  glClearColor( 0.0, 0.0, 0.0, 1.0 );
+  glColor3f( 1.0, 1.0, 1.0 );
+
+  glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+  glFlush();
+  glutSwapBuffers();
+
+  glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
+  glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
+  glLightfv(GL_LIGHT0, GL_POSITION, position0);
+  glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
+  glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
+  glLightfv(GL_LIGHT1, GL_POSITION, position1);
+  glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
+  glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
+  glEnable(GL_LIGHTING);
+  glEnable(GL_LIGHT0);
+  glEnable(GL_LIGHT1);
+  glEnable(GL_DEPTH_TEST);
+  glEnable(GL_NORMALIZE);
+
+  glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, front_shininess);
+  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, front_specular);
+
+  glHint(GL_FOG_HINT, GL_FASTEST);
+  glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
+  glHint(GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
+
+  pinit();
+
+  glutReshapeFunc( reshape );
+  glutKeyboardFunc( key );
+  glutIdleFunc( idle_ );
+  glutDisplayFunc( draw );
+  glutMainLoop();
+  
+}
+
+int main(int argc, char **argv)
+{
+  INIT();
+  return(0);
+}
diff --git a/progs/demos/multiarb.c b/progs/demos/multiarb.c
new file mode 100644 (file)
index 0000000..68419cd
--- /dev/null
@@ -0,0 +1,307 @@
+/* $Id: multiarb.c,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
+
+/*
+ * GL_ARB_multitexture demo
+ * Brian Paul  November 1998  This program is in the public domain.
+ */
+
+/*
+ * $Log: multiarb.c,v $
+ * Revision 1.1  1999/08/19 00:55:40  jtg
+ * Initial revision
+ *
+ * Revision 1.3  1999/03/28 18:20:49  brianp
+ * minor clean-up
+ *
+ * Revision 1.2  1998/11/05 04:34:04  brianp
+ * moved image files to ../images/ directory
+ *
+ * Revision 1.1  1998/11/03 01:36:33  brianp
+ * Initial revision
+ *
+ */
+
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <GL/glut.h>
+
+#include "../util/readtex.c"   /* I know, this is a hack. */
+
+#define TEXTURE_1_FILE "../images/girl.rgb"
+#define TEXTURE_2_FILE "../images/reflect.rgb"
+
+#define TEX0 1
+#define TEX1 2
+#define TEXBOTH 3
+#define ANIMATE 10
+#define QUIT 100
+
+static GLboolean Animate = GL_TRUE;
+
+static GLfloat Drift = 0.0;
+static GLfloat Xrot = 20.0, Yrot = 30.0, Zrot = 0.0;
+
+
+
+static void Idle( void )
+{
+   if (Animate) {
+      Drift += 0.05;
+
+#ifdef GL_ARB_multitexture
+      glActiveTextureARB(GL_TEXTURE0_ARB);
+#endif
+      glMatrixMode(GL_TEXTURE);
+      glLoadIdentity();
+      glTranslatef(Drift, 0.0, 0.0);
+      glMatrixMode(GL_MODELVIEW);
+
+#ifdef GL_ARB_multitexture
+      glActiveTextureARB(GL_TEXTURE1_ARB);
+#endif
+      glMatrixMode(GL_TEXTURE);
+      glLoadIdentity();
+      glTranslatef(0.0, Drift, 0.0);
+      glMatrixMode(GL_MODELVIEW);
+
+      glutPostRedisplay();
+   }
+}
+
+
+static void DrawObject(void)
+{
+   glBegin(GL_QUADS);
+
+#ifdef GL_ARB_multitexture
+   glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0, 0.0);
+   glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0, 0.0);
+   glVertex2f(-1.0, -1.0);
+
+   glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 2.0, 0.0);
+   glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0, 0.0);
+   glVertex2f(1.0, -1.0);
+
+   glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 2.0, 2.0);
+   glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0, 1.0);
+   glVertex2f(1.0, 1.0);
+
+   glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0, 2.0);
+   glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0, 1.0);
+   glVertex2f(-1.0, 1.0);
+#else
+   glTexCoord2f(0.0, 0.0);
+   glVertex2f(-1.0, -1.0);
+
+   glTexCoord2f(1.0, 0.0);
+   glVertex2f(1.0, -1.0);
+
+   glTexCoord2f(1.0, 1.0);
+   glVertex2f(1.0, 1.0);
+
+   glTexCoord2f(0.0, 1.0);
+   glVertex2f(-1.0, 1.0);
+#endif
+
+   glEnd();
+}
+
+
+
+static void Display( void )
+{
+   glClear( GL_COLOR_BUFFER_BIT );
+
+   glPushMatrix();
+      glRotatef(Xrot, 1.0, 0.0, 0.0);
+      glRotatef(Yrot, 0.0, 1.0, 0.0);
+      glRotatef(Zrot, 0.0, 0.0, 1.0);
+      glScalef(5.0, 5.0, 5.0);
+      DrawObject();
+   glPopMatrix();
+
+   glutSwapBuffers();
+}
+
+
+static void Reshape( int width, int height )
+{
+   glViewport( 0, 0, width, height );
+   glMatrixMode( GL_PROJECTION );
+   glLoadIdentity();
+   glFrustum( -1.0, 1.0, -1.0, 1.0, 10.0, 100.0 );
+   /*glOrtho( -6.0, 6.0, -6.0, 6.0, 10.0, 100.0 );*/
+   glMatrixMode( GL_MODELVIEW );
+   glLoadIdentity();
+   glTranslatef( 0.0, 0.0, -70.0 );
+}
+
+
+static void ModeMenu(int entry)
+{
+   GLboolean enable0 = GL_FALSE, enable1 = GL_FALSE;
+   if (entry==TEX0) {
+      enable0 = GL_TRUE;
+   }
+   else if (entry==TEX1) {
+      enable1 = GL_TRUE;
+   }
+   else if (entry==TEXBOTH) {
+      enable0 = GL_TRUE;
+      enable1 = GL_TRUE;
+   }
+   else if (entry==ANIMATE) {
+      Animate = !Animate;
+   }
+   else if (entry==QUIT) {
+      exit(0);
+   }
+
+   if (entry != ANIMATE) {
+#ifdef GL_ARB_multitexture
+      glActiveTextureARB(GL_TEXTURE0_ARB);
+#endif
+      if (enable0) {
+         glEnable(GL_TEXTURE_2D);
+      }
+      else
+         glDisable(GL_TEXTURE_2D);
+
+#ifdef GL_ARB_multitexture
+      glActiveTextureARB(GL_TEXTURE1_ARB);
+#endif
+      if (enable1) {
+         glEnable(GL_TEXTURE_2D);
+      }
+      else
+         glDisable(GL_TEXTURE_2D);
+   }
+
+   glutPostRedisplay();
+}
+
+
+static void Key( unsigned char key, int x, int y )
+{
+   (void) x;
+   (void) y;
+   switch (key) {
+      case 27:
+         exit(0);
+         break;
+   }
+   glutPostRedisplay();
+}
+
+
+static void SpecialKey( int key, int x, int y )
+{
+   float step = 3.0;
+   (void) x;
+   (void) y;
+
+   switch (key) {
+      case GLUT_KEY_UP:
+         Xrot += step;
+         break;
+      case GLUT_KEY_DOWN:
+         Xrot -= step;
+         break;
+      case GLUT_KEY_LEFT:
+         Yrot += step;
+         break;
+      case GLUT_KEY_RIGHT:
+         Yrot -= step;
+         break;
+   }
+   glutPostRedisplay();
+}
+
+
+static void Init( void )
+{
+   const char *exten = (const char *) glGetString(GL_EXTENSIONS);
+   if (!strstr(exten, "GL_ARB_multitexture")) {
+      printf("Sorry, GL_ARB_multitexture not supported by this renderer.\n");
+      exit(1);
+   }
+
+   /* setup texture env 0 */
+#ifdef GL_ARB_multitexture
+   glActiveTextureARB(GL_TEXTURE0_ARB);
+#endif
+#ifdef LINEAR_FILTER
+   /* linear filtering looks much nicer but is much slower for Mesa */
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+#else
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+#endif
+
+   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+   if (!LoadRGBMipmaps(TEXTURE_1_FILE, GL_RGB)) {
+      printf("Error: couldn't load texture image\n");
+      exit(1);
+   }
+
+
+   /* setup texture env 1 */
+#ifdef GL_ARB_multitexture
+   glActiveTextureARB(GL_TEXTURE1_ARB);
+#endif
+#ifdef LINEAR_FILTER
+   /* linear filtering looks much nicer but is much slower for Mesa */
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+#else
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+#endif
+
+   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+   if (!LoadRGBMipmaps(TEXTURE_2_FILE, GL_RGB)) {
+      printf("Error: couldn't load texture image\n");
+      exit(1);
+   }
+
+   glShadeModel(GL_FLAT);
+   glClearColor(0.3, 0.3, 0.4, 1.0);
+
+   ModeMenu(TEXBOTH);
+}
+
+
+int main( int argc, char *argv[] )
+{
+   glutInit( &argc, argv );
+   glutInitWindowSize( 300, 300 );
+   glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
+   glutCreateWindow(argv[0] );
+
+   Init();
+
+   glutReshapeFunc( Reshape );
+   glutKeyboardFunc( Key );
+   glutSpecialFunc( SpecialKey );
+   glutDisplayFunc( Display );
+   glutIdleFunc( Idle );
+
+   glutCreateMenu(ModeMenu);
+   glutAddMenuEntry("Texture 0", TEX0);
+   glutAddMenuEntry("Texture 1", TEX1);
+   glutAddMenuEntry("Multi-texture", TEXBOTH);
+   glutAddMenuEntry("Toggle Animation", ANIMATE);
+   glutAddMenuEntry("Quit", QUIT);
+   glutAttachMenu(GLUT_RIGHT_BUTTON);
+
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/demos/osdemo.c b/progs/demos/osdemo.c
new file mode 100644 (file)
index 0000000..f69cd22
--- /dev/null
@@ -0,0 +1,169 @@
+/* $Id: osdemo.c,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
+
+/*
+ * Demo of off-screen Mesa rendering
+ *
+ * See Mesa/include/GL/osmesa.h for documentation of the OSMesa functions.
+ *
+ * If you want to render BIG images you'll probably have to increase
+ * MAX_WIDTH and MAX_HEIGHT in src/config.h.
+ *
+ * This program is in the public domain.
+ *
+ * Brian Paul
+ *
+ * PPM output provided by Joerg Schmalzl.
+ * ASCII PPM output added by Brian Paul.
+ */
+
+
+/*
+ * $Log: osdemo.c,v $
+ * Revision 1.1  1999/08/19 00:55:40  jtg
+ * Initial revision
+ *
+ * Revision 3.0  1998/02/14 18:42:29  brianp
+ * initial rev
+ *
+ */
+
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "GL/osmesa.h"
+#include "GL/glut.h"
+
+
+
+#define WIDTH 400
+#define HEIGHT 400
+
+
+
+static void render_image( void )
+{
+   GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 };
+   GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
+   GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
+   GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
+   GLfloat red_mat[]   = { 1.0, 0.2, 0.2, 1.0 };
+   GLfloat green_mat[] = { 0.2, 1.0, 0.2, 1.0 };
+   GLfloat blue_mat[]  = { 0.2, 0.2, 1.0, 1.0 };
+
+
+   glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
+   glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
+   glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
+   glLightfv(GL_LIGHT0, GL_POSITION, light_position);
+    
+   glEnable(GL_LIGHTING);
+   glEnable(GL_LIGHT0);
+   glEnable(GL_DEPTH_TEST);
+
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   glOrtho(-2.5, 2.5, -2.5, 2.5, -10.0, 10.0);
+   glMatrixMode(GL_MODELVIEW);
+
+   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+
+   glPushMatrix();
+   glRotatef(20.0, 1.0, 0.0, 0.0);
+
+   glPushMatrix();
+   glTranslatef(-0.75, 0.5, 0.0); 
+   glRotatef(90.0, 1.0, 0.0, 0.0);
+   glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, red_mat );
+   glutSolidTorus(0.275, 0.85, 20, 20);
+   glPopMatrix();
+
+   glPushMatrix();
+   glTranslatef(-0.75, -0.5, 0.0); 
+   glRotatef(270.0, 1.0, 0.0, 0.0);
+   glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, green_mat );
+   glutSolidCone(1.0, 2.0, 16, 1);
+   glPopMatrix();
+
+   glPushMatrix();
+   glTranslatef(0.75, 0.0, -1.0); 
+   glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blue_mat );
+   glutSolidSphere(1.0, 20, 20);
+   glPopMatrix();
+
+   glPopMatrix();
+}
+
+
+
+int main( int argc, char *argv[] )
+{
+   OSMesaContext ctx;
+   void *buffer;
+
+   /* Create an RGBA-mode context */
+   ctx = OSMesaCreateContext( GL_RGBA, NULL );
+
+   /* Allocate the image buffer */
+   buffer = malloc( WIDTH * HEIGHT * 4 );
+
+   /* Bind the buffer to the context and make it current */
+   OSMesaMakeCurrent( ctx, buffer, GL_UNSIGNED_BYTE, WIDTH, HEIGHT );
+
+   render_image();
+
+   if (argc>1) {
+      /* write PPM file */
+      FILE *f = fopen( argv[1], "w" );
+      if (f) {
+         int i, x, y;
+         GLubyte *ptr = (GLubyte *) buffer;
+#define BINARY 0
+#if BINARY
+         fprintf(f,"P6\n");
+         fprintf(f,"# ppm-file created by %s\n",  argv[0]);
+         fprintf(f,"%i %i\n", WIDTH,HEIGHT);
+         fprintf(f,"255\n");
+         fclose(f);
+         f = fopen( argv[1], "ab" );  /* reopen in binary append mode */
+         for (y=HEIGHT-1; y>=0; y--) {
+            for (x=0; x<WIDTH; x++) {
+               i = (y*WIDTH + x) * 4;
+               fputc(ptr[i], f);   /* write red */
+               fputc(ptr[i+1], f); /* write green */
+               fputc(ptr[i+2], f); /* write blue */
+            }
+         }
+#else /*ASCII*/
+         int counter = 0;
+         fprintf(f,"P3\n");
+         fprintf(f,"# ascii ppm file created by %s\n", argv[0]);
+         fprintf(f,"%i %i\n", WIDTH, HEIGHT);
+         fprintf(f,"255\n");
+         for (y=HEIGHT-1; y>=0; y--) {
+            for (x=0; x<WIDTH; x++) {
+               i = (y*WIDTH + x) * 4;
+               fprintf(f, " %3d %3d %3d", ptr[i], ptr[i+1], ptr[i+2]);
+               counter++;
+               if (counter % 5 == 0)
+                  fprintf(f, "\n");
+            }
+         }
+#endif
+         fclose(f);
+      }
+   }
+   else {
+      printf("Specify a filename if you want to make a ppm file\n");
+   }
+
+   printf("all done\n");
+
+   /* free the image buffer */
+   free( buffer );
+
+   /* destroy the context */
+   OSMesaDestroyContext( ctx );
+
+   return 0;
+}
diff --git a/progs/demos/paltex.c b/progs/demos/paltex.c
new file mode 100644 (file)
index 0000000..e33a8ee
--- /dev/null
@@ -0,0 +1,186 @@
+/* $Id: paltex.c,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
+
+/*
+ * Paletted texture demo.  Written by Brian Paul.  This file in public domain.
+ */
+
+/*
+ * $Log: paltex.c,v $
+ * Revision 1.1  1999/08/19 00:55:40  jtg
+ * Initial revision
+ *
+ * Revision 3.1  1999/03/28 18:20:49  brianp
+ * minor clean-up
+ *
+ * Revision 3.0  1998/02/14 18:42:29  brianp
+ * initial rev
+ *
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <GL/glut.h>
+
+
+static float Rot = 0.0;
+
+
+static void Idle( void )
+{
+   Rot += 5.0;
+   glutPostRedisplay();
+}
+
+
+static void Display( void )
+{
+   glClear( GL_COLOR_BUFFER_BIT );
+
+   glPushMatrix();
+   glRotatef(Rot, 0, 0, 1);
+
+   glBegin(GL_POLYGON);
+   glTexCoord2f(0, 1);  glVertex2f(-1, -1);
+   glTexCoord2f(1, 1);  glVertex2f( 1, -1);
+   glTexCoord2f(1, 0);  glVertex2f( 1,  1);
+   glTexCoord2f(0, 0);  glVertex2f(-1,  1);
+   glEnd();
+
+   glPopMatrix();
+
+   glutSwapBuffers();
+}
+
+
+static void Reshape( int width, int height )
+{
+   glViewport( 0, 0, width, height );
+   glMatrixMode( GL_PROJECTION );
+   glLoadIdentity();
+   glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 25.0 );
+   glMatrixMode( GL_MODELVIEW );
+   glLoadIdentity();
+   glTranslatef( 0.0, 0.0, -15.0 );
+}
+
+
+static void Key( unsigned char key, int x, int y )
+{
+   (void) x;
+   (void) y;
+   switch (key) {
+      case 27:
+         exit(0);
+         break;
+   }
+   glutPostRedisplay();
+}
+
+
+static void SpecialKey( int key, int x, int y )
+{
+   (void) x;
+   (void) y;
+   switch (key) {
+      case GLUT_KEY_UP:
+         break;
+      case GLUT_KEY_DOWN:
+         break;
+      case GLUT_KEY_LEFT:
+         break;
+      case GLUT_KEY_RIGHT:
+         break;
+   }
+   glutPostRedisplay();
+}
+
+
+static void Init( void )
+{
+   GLubyte texture[8][8] = {  /* PT = Paletted Texture! */
+      {  0,   0,   0,   0,   0,   0,   0,   0},
+      {  0, 100, 100, 100,   0, 180, 180, 180},
+      {  0, 100,   0, 100,   0,   0, 180,   0},
+      {  0, 100,   0, 100,   0,   0, 180,   0},
+      {  0, 100, 100, 100,   0,   0, 180,   0},
+      {  0, 100,   0,   0,   0,   0, 180,   0},
+      {  0, 100,   0,   0,   0,   0, 180,   0},
+      {  0, 100, 255,   0,   0,   0, 180, 250},
+   };
+
+   GLubyte table[256][4];
+   int i;
+
+   if (!glutExtensionSupported("GL_EXT_paletted_texture")) {
+      printf("Sorry, GL_EXT_paletted_texture not supported\n");
+      exit(0);
+   }
+
+   /* put some wacky colors into the texture palette */
+   for (i=0;i<256;i++) {
+      table[i][0] = i;
+      table[i][1] = 0;
+      table[i][2] = 127 + i / 2;
+      table[i][3] = 255;
+   }
+
+#ifdef GL_EXT_paletted_texture
+
+#if defined(GL_EXT_shared_texture_palette) && defined(SHARED_PALETTE)
+   printf("Using shared palette\n");
+   glColorTableEXT(GL_SHARED_TEXTURE_PALETTE_EXT,    /* target */
+                   GL_RGBA,          /* internal format */
+                   256,              /* table size */
+                   GL_RGBA,          /* table format */
+                   GL_UNSIGNED_BYTE, /* table type */
+                   table);           /* the color table */
+   glEnable(GL_SHARED_TEXTURE_PALETTE_EXT);
+#else
+   glColorTableEXT(GL_TEXTURE_2D,    /* target */
+                   GL_RGBA,          /* internal format */
+                   256,              /* table size */
+                   GL_RGBA,          /* table format */
+                   GL_UNSIGNED_BYTE, /* table type */
+                   table);           /* the color table */
+#endif
+
+   glTexImage2D(GL_TEXTURE_2D,       /* target */
+                0,                   /* level */
+                GL_COLOR_INDEX8_EXT, /* internal format */
+                8, 8,                /* width, height */
+                0,                   /* border */
+                GL_COLOR_INDEX,      /* texture format */
+                GL_UNSIGNED_BYTE,    /* texture type */
+                texture);            /* teh texture */
+#endif
+
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+   glEnable(GL_TEXTURE_2D);
+}
+
+
+int main( int argc, char *argv[] )
+{
+   glutInit( &argc, argv );
+   glutInitWindowPosition( 0, 0 );
+   glutInitWindowSize( 400, 400 );
+
+   glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
+
+   glutCreateWindow(argv[0]);
+
+   Init();
+
+   glutReshapeFunc( Reshape );
+   glutKeyboardFunc( Key );
+   glutSpecialFunc( SpecialKey );
+   glutDisplayFunc( Display );
+   glutIdleFunc( Idle );
+
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/demos/pointblast.c b/progs/demos/pointblast.c
new file mode 100644 (file)
index 0000000..a36046f
--- /dev/null
@@ -0,0 +1,506 @@
+
+/* Copyright (c) Mark J. Kilgard, 1997.  */
+
+/* This program is freely distributable without licensing fees 
+   and is provided without guarantee or warrantee expressed or 
+   implied. This program is -not- in the public domain. */
+
+/* This example demonstrates how to render particle effects
+   with OpenGL.  A cloud of pinkish/orange particles explodes with the
+   particles bouncing off the ground.  When the EXT_point_parameters
+   is present , the particle size is attenuated based on eye distance. */
+
+
+/*
+ * $Log: pointblast.c,v $
+ * Revision 1.1  1999/08/19 00:55:40  jtg
+ * Initial revision
+ *
+ * Revision 3.3  1998/07/26 01:24:27  brianp
+ * removed include of gl.h
+ *
+ * Revision 3.2  1998/02/14 18:51:46  brianp
+ * fixed a small compiler warning
+ *
+ * Revision 3.1  1998/02/14 18:45:25  brianp
+ * optimized to use flat shading, don't blend ground polygon
+ *
+ * Revision 3.0  1998/02/14 18:42:29  brianp
+ * initial rev
+ *
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>       /* for cos(), sin(), and sqrt() */
+#include <GL/glut.h>
+
+/* Some <math.h> files do not define M_PI... */
+#ifndef M_PI
+#define M_PI 3.14159265
+#endif
+
+#if 0  /* For debugging. */
+#undef GL_EXT_point_parameters
+#endif
+
+static GLfloat angle = -150;   /* in degrees */
+static int spin = 0;
+static int moving, begin;
+static int newModel = 1;
+static float theTime;
+static int repeat = 1;
+static int blend = 1;
+int useMipmaps = 1;
+int linearFiltering = 1;
+
+static GLfloat constant[3] = { 1/5.0, 0.0, 0.0 };
+static GLfloat linear[3] = { 0.0, 1/5.0, 0.0 };
+static GLfloat theQuad[3] = { 0.25, 0.0, 1/60.0 };
+
+#define MAX_POINTS 2000
+
+static int numPoints = 200;
+
+static GLfloat pointList[MAX_POINTS][3];
+static GLfloat pointTime[MAX_POINTS];
+static GLfloat pointVelocity[MAX_POINTS][2];
+static GLfloat pointDirection[MAX_POINTS][2];
+static int colorList[MAX_POINTS];
+static int animate = 1, motion = 0;
+
+static GLfloat colorSet[][4] = {
+  /* Shades of red. */
+  { 0.7, 0.2, 0.4, 0.5 },
+  { 0.8, 0.0, 0.7, 0.5 },
+  { 1.0, 0.0, 0.0, 0.5 },
+  { 0.9, 0.3, 0.6, 0.5 },
+  { 1.0, 0.4, 0.0, 0.5 },
+  { 1.0, 0.0, 0.5, 0.5 },
+};
+
+#define NUM_COLORS (sizeof(colorSet)/sizeof(colorSet[0]))
+
+#define DEAD (NUM_COLORS+1)
+
+
+#if 0  /* drand48 might be better on Unix machines */
+#define RANDOM_RANGE(lo, hi) ((lo) + (hi - lo) * drand48())
+#else
+static float float_rand(void) { return rand() / (float) RAND_MAX; }
+#define RANDOM_RANGE(lo, hi) ((lo) + (hi - lo) * float_rand())
+#endif
+
+#define MEAN_VELOCITY 3.0
+#define GRAVITY 2.0
+#define TIME_DELTA 0.025  /* The speed of time. */
+
+/* Modeling units of ground extent in each X and Z direction. */
+#define EDGE 12
+
+void
+makePointList(void)
+{
+  float angle, velocity, direction;
+  int i;
+
+  motion = 1;
+  for (i=0; i<numPoints; i++) {
+    pointList[i][0] = 0.0;
+    pointList[i][1] = 0.0;
+    pointList[i][2] = 0.0;
+    pointTime[i] = 0.0;
+    angle = (RANDOM_RANGE(60.0, 70.0)) * M_PI/180.0;
+    direction = RANDOM_RANGE(0.0, 360.0) * M_PI/180.0;
+    pointDirection[i][0] = cos(direction);
+    pointDirection[i][1] = sin(direction);
+    velocity = MEAN_VELOCITY + RANDOM_RANGE(-0.8, 1.0);
+    pointVelocity[i][0] = velocity * cos(angle);
+    pointVelocity[i][1] = velocity * sin(angle);
+    colorList[i] = rand() % NUM_COLORS;
+  }
+  theTime = 0.0;
+}
+
+void
+updatePointList(void)
+{
+  float distance;
+  int i;
+
+  motion = 0;
+  for (i=0; i<numPoints; i++) {
+    distance = pointVelocity[i][0] * theTime;
+
+    /* X and Z */
+    pointList[i][0] = pointDirection[i][0] * distance;
+    pointList[i][2] = pointDirection[i][1] * distance;
+
+    /* Z */
+    pointList[i][1] =
+      (pointVelocity[i][1] - 0.5 * GRAVITY * pointTime[i])*pointTime[i];
+
+    /* If we hit the ground, bounce the point upward again. */
+    if (pointList[i][1] <= 0.0) {
+      if (distance > EDGE) {
+        /* Particle has hit ground past the distance duration of
+          the particles.  Mark particle as dead. */
+       colorList[i] = NUM_COLORS;  /* Not moving. */
+       continue;
+      }
+
+      pointVelocity[i][1] *= 0.8;  /* 80% of previous up velocity. */
+      pointTime[i] = 0.0;  /* Reset the particles sense of up time. */
+    }
+    motion = 1;
+    pointTime[i] += TIME_DELTA;
+  }
+  theTime += TIME_DELTA;
+  if (!motion && !spin) {
+    if (repeat) {
+      makePointList();
+    } else {
+      glutIdleFunc(NULL);
+    }
+  }
+}
+
+void
+idle(void)
+{
+  updatePointList();
+  if (spin) {
+    angle += 0.3;
+    newModel = 1;
+  }
+  glutPostRedisplay();
+}
+
+void
+visible(int vis)
+{
+  if (vis == GLUT_VISIBLE) {
+    if (animate && (motion || spin)) {
+      glutIdleFunc(idle);
+    }
+  } else {
+    glutIdleFunc(NULL);
+  }
+}
+
+void
+recalcModelView(void)
+{
+  glPopMatrix();
+  glPushMatrix();
+  glRotatef(angle, 0.0, 1.0, 0.0);
+  newModel = 0;
+}
+
+void
+redraw(void)
+{
+  int i;
+
+  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+  if (newModel)
+    recalcModelView();
+
+  glDepthMask(GL_FALSE);
+
+  /* Draw the floor. */
+/*  glEnable(GL_TEXTURE_2D);*/
+  glColor3f(0.5, 1.0, 0.5);
+  glBegin(GL_QUADS);
+    glTexCoord2f(0.0, 0.0);
+    glVertex3f(-EDGE, -0.05, -EDGE);
+    glTexCoord2f(20.0, 0.0);
+    glVertex3f(EDGE, -0.05, -EDGE);
+    glTexCoord2f(20.0, 20.0);
+    glVertex3f(EDGE, -0.05, EDGE);
+    glTexCoord2f(0.0, 20.0);
+    glVertex3f(-EDGE, -0.05, EDGE);
+  glEnd();
+
+  /* Allow particles to blend with each other. */
+  glDepthMask(GL_TRUE);
+
+  if (blend)
+     glEnable(GL_BLEND);
+
+  glDisable(GL_TEXTURE_2D);
+  glBegin(GL_POINTS);
+    for (i=0; i<numPoints; i++) {
+      /* Draw alive particles. */
+      if (colorList[i] != DEAD) {
+        glColor4fv(colorSet[colorList[i]]);
+        glVertex3fv(pointList[i]);
+      }
+    }
+  glEnd();
+
+  glDisable(GL_BLEND);
+
+  glutSwapBuffers();
+}
+
+/* ARGSUSED2 */
+void
+mouse(int button, int state, int x, int y)
+{
+  /* Scene can be spun around Y axis using left
+     mouse button movement. */
+  if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
+    moving = 1;
+    begin = x;
+  }
+  if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) {
+    moving = 0;
+  }
+}
+
+/* ARGSUSED1 */
+void
+mouseMotion(int x, int y)
+{
+  if (moving) {
+    angle = angle + (x - begin);
+    begin = x;
+    newModel = 1;
+    glutPostRedisplay();
+  }
+}
+
+void
+menu(int option)
+{
+  switch (option) {
+  case 0:
+    makePointList();
+    break;
+#if GL_EXT_point_parameters
+  case 1:
+    glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, constant);
+    break;
+  case 2:
+    glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, linear);
+    break;
+  case 3:
+    glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, theQuad);
+    break;
+#endif
+  case 4:
+    blend = 1;
+    break;
+  case 5:
+    blend = 0;
+    break;
+#if GL_EXT_point_parameters
+  case 6:
+    glPointParameterfEXT(GL_POINT_FADE_THRESHOLD_SIZE_EXT, 1.0);
+    break;
+  case 7:
+    glPointParameterfEXT(GL_POINT_FADE_THRESHOLD_SIZE_EXT, 10.0);
+    break;
+#endif
+  case 8:
+    glEnable(GL_POINT_SMOOTH);
+    break;
+  case 9:
+    glDisable(GL_POINT_SMOOTH);
+    break;
+  case 10:
+    glPointSize(2.0);
+    break;
+  case 11:
+    glPointSize(4.0);
+    break;
+  case 12:
+    glPointSize(8.0);
+    break;
+  case 13:
+    spin = 1 - spin;
+    if (animate && (spin || motion)) {
+      glutIdleFunc(idle);
+    } else {
+      glutIdleFunc(NULL);
+    }
+    break;
+  case 14:
+    numPoints = 200;
+    break;
+  case 15:
+    numPoints = 500;
+    break;
+  case 16:
+    numPoints = 1000;
+    break;
+  case 17:
+    numPoints = 2000;
+    break;
+  case 666:
+    exit(0);
+  }
+  glutPostRedisplay();
+}
+
+/* ARGSUSED1 */
+void
+key(unsigned char c, int x, int y)
+{
+  switch (c) {
+  case 13:
+    animate = 1 - animate;  /* toggle. */
+    if (animate && (motion || spin)) {
+      glutIdleFunc(idle);
+    } else {
+      glutIdleFunc(NULL);
+    }
+    break;
+  case ' ':
+    animate = 1;
+    makePointList();
+    glutIdleFunc(idle);
+    break;
+  case 27:
+    exit(0);
+  }
+}
+
+/* Nice floor texture tiling pattern. */
+static char *circles[] = {
+  "....xxxx........",
+  "..xxxxxxxx......",
+  ".xxxxxxxxxx.....",
+  ".xxx....xxx.....",
+  "xxx......xxx....",
+  "xxx......xxx....",
+  "xxx......xxx....",
+  "xxx......xxx....",
+  ".xxx....xxx.....",
+  ".xxxxxxxxxx.....",
+  "..xxxxxxxx......",
+  "....xxxx........",
+  "................",
+  "................",
+  "................",
+  "................",
+};
+
+static void
+makeFloorTexture(void)
+{
+  GLubyte floorTexture[16][16][3];
+  GLubyte *loc;
+  int s, t;
+
+  /* Setup RGB image for the texture. */
+  loc = (GLubyte*) floorTexture;
+  for (t = 0; t < 16; t++) {
+    for (s = 0; s < 16; s++) {
+      if (circles[t][s] == 'x') {
+        /* Nice blue. */
+        loc[0] = 0x1f;
+        loc[1] = 0x1f;
+        loc[2] = 0x8f;
+      } else {
+        /* Light gray. */
+        loc[0] = 0xca;
+        loc[1] = 0xca;
+        loc[2] = 0xca;
+      }
+      loc += 3;
+    }
+  }
+
+  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+  if (useMipmaps) {
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+      GL_LINEAR_MIPMAP_LINEAR);
+    gluBuild2DMipmaps(GL_TEXTURE_2D, 3, 16, 16,
+      GL_RGB, GL_UNSIGNED_BYTE, floorTexture);
+  } else {
+    if (linearFiltering) {
+      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    } else {
+      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    }
+    glTexImage2D(GL_TEXTURE_2D, 0, 3, 16, 16, 0,
+      GL_RGB, GL_UNSIGNED_BYTE, floorTexture);
+  }
+}
+
+int
+main(int argc, char **argv)
+{
+  int i;
+  glutInit(&argc, argv);
+  glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE);
+
+  for (i=1; i<argc; i++) {
+    if(!strcmp("-noms", argv[i])) {
+      glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
+      printf("forcing no multisampling\n");
+    } else if(!strcmp("-nomipmaps", argv[i])) {
+      useMipmaps = 0;
+    } else if(!strcmp("-nearest", argv[i])) {
+      linearFiltering = 0;
+    }
+  }
+
+  glutCreateWindow("point burst");
+  glutDisplayFunc(redraw);
+  glutMouseFunc(mouse);
+  glutMotionFunc(mouseMotion);
+  glutVisibilityFunc(visible);
+  glutKeyboardFunc(key);
+  glutCreateMenu(menu);
+  glutAddMenuEntry("Reset time", 0);
+  glutAddMenuEntry("Constant", 1);
+  glutAddMenuEntry("Linear", 2);
+  glutAddMenuEntry("Quadratic", 3);
+  glutAddMenuEntry("Blend on", 4);
+  glutAddMenuEntry("Blend off", 5);
+  glutAddMenuEntry("Threshold 1", 6);
+  glutAddMenuEntry("Threshold 10", 7);
+  glutAddMenuEntry("Point smooth on", 8);
+  glutAddMenuEntry("Point smooth off", 9);
+  glutAddMenuEntry("Point size 2", 10);
+  glutAddMenuEntry("Point size 4", 11);
+  glutAddMenuEntry("Point size 8", 12);
+  glutAddMenuEntry("Toggle spin", 13);
+  glutAddMenuEntry("200 points ", 14);
+  glutAddMenuEntry("500 points ", 15);
+  glutAddMenuEntry("1000 points ", 16);
+  glutAddMenuEntry("2000 points ", 17);
+  glutAddMenuEntry("Quit", 666);
+  glutAttachMenu(GLUT_RIGHT_BUTTON);
+
+  glShadeModel(GL_FLAT);
+  glEnable(GL_DEPTH_TEST);
+  glEnable(GL_POINT_SMOOTH);
+  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+  glPointSize(8.0);
+#if GL_EXT_point_parameters
+  glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, theQuad);
+#endif
+  glMatrixMode(GL_PROJECTION);
+  gluPerspective( /* field of view in degree */ 40.0,
+  /* aspect ratio */ 1.0,
+    /* Z near */ 0.5, /* Z far */ 40.0);
+  glMatrixMode(GL_MODELVIEW);
+  gluLookAt(0.0, 1.0, 8.0, /* eye location */
+    0.0, 1.0, 0.0,      /* center is at (0,0,0) */
+    0.0, 1.0, 0.);      /* up is in postivie Y direction */
+  glPushMatrix();       /* dummy push so we can pop on model
+                           recalc */
+
+  makePointList();
+  makeFloorTexture();
+
+  glutMainLoop();
+  return 0;             /* ANSI C requires main to return int. */
+}
diff --git a/progs/demos/reflect.c b/progs/demos/reflect.c
new file mode 100644 (file)
index 0000000..d941a73
--- /dev/null
@@ -0,0 +1,435 @@
+/* $Id: reflect.c,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
+
+/*
+ * Demo of a reflective, texture-mapped surface with OpenGL.
+ * Brian Paul   August 14, 1995   This file is in the public domain.
+ *
+ * Hardware texture mapping is highly recommended!
+ *
+ * The basic steps are:
+ *    1. Render the reflective object (a polygon) from the normal viewpoint,
+ *       setting the stencil planes = 1.
+ *    2. Render the scene from a special viewpoint:  the viewpoint which
+ *       is on the opposite side of the reflective plane.  Only draw where
+ *       stencil = 1.  This draws the objects in the reflective surface.
+ *    3. Render the scene from the original viewpoint.  This draws the
+ *       objects in the normal fashion.  Use blending when drawing
+ *       the reflective, textured surface.
+ *
+ * This is a very crude demo.  It could be much better.
+ */
+/*
+ * Dirk Reiners (reiners@igd.fhg.de) made some modifications to this code.
+ *
+ * August 1996 - A few optimizations by Brian
+ */
+
+/*
+ * April, 1997 - Added Mark Kilgard's changes.
+ */
+
+/*
+ * $Log: reflect.c,v $
+ * Revision 1.1  1999/08/19 00:55:40  jtg
+ * Initial revision
+ *
+ * Revision 3.4  1999/03/28 18:22:05  brianp
+ * minor clean-up
+ *
+ * Revision 3.3  1998/11/22 02:54:29  brianp
+ * only draw one stack for gluCylinders
+ *
+ * Revision 3.2  1998/11/19 02:53:48  brianp
+ * changed texture image and background color
+ *
+ * Revision 3.1  1998/11/05 04:34:04  brianp
+ * moved image files to ../images/ directory
+ *
+ * Revision 3.0  1998/02/14 18:42:29  brianp
+ * initial rev
+ *
+ */
+
+
+#define USE_ZBUFFER
+
+
+/* OK, without hardware support this is overkill. */
+#define USE_TEXTURE
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "GL/glut.h"
+
+#include "../util/readtex.c"  /* a hack, I know */
+
+
+#define DEG2RAD (3.14159/180.0)
+
+
+#define TABLE_TEXTURE "../images/tile.rgb"
+
+static int ImgWidth, ImgHeight;
+static GLenum ImgFormat;
+static GLubyte *Image = NULL;
+
+#define MAX_OBJECTS 2
+
+static GLint table_list;
+static GLint objects_list[MAX_OBJECTS];
+
+
+static GLfloat xrot, yrot;
+static GLfloat spin;
+
+
+
+static void make_table( void )
+{
+   static GLfloat table_mat[] = { 1.0, 1.0, 1.0, 0.6 };
+   static GLfloat gray[] = { 0.4, 0.4, 0.4, 1.0 };
+
+   table_list = glGenLists(1);
+   glNewList( table_list, GL_COMPILE );
+
+   /* load table's texture */
+   glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, table_mat );
+/*   glMaterialfv( GL_FRONT, GL_EMISSION, gray );*/
+   glMaterialfv( GL_FRONT, GL_DIFFUSE, table_mat );
+   glMaterialfv( GL_FRONT, GL_AMBIENT, gray );
+   
+   /* draw textured square for the table */
+   glPushMatrix();
+   glScalef( 4.0, 4.0, 4.0 );
+   glBegin( GL_POLYGON );
+   glNormal3f( 0.0, 1.0, 0.0 );
+   glTexCoord2f( 0.0, 0.0 );   glVertex3f( -1.0, 0.0,  1.0 );
+   glTexCoord2f( 1.0, 0.0 );   glVertex3f(  1.0, 0.0,  1.0 );
+   glTexCoord2f( 1.0, 1.0 );   glVertex3f(  1.0, 0.0, -1.0 );
+   glTexCoord2f( 0.0, 1.0 );   glVertex3f( -1.0, 0.0, -1.0 );
+   glEnd();
+   glPopMatrix();
+
+   glDisable( GL_TEXTURE_2D );
+
+   glEndList();
+}
+
+
+static void make_objects( void )
+{
+   GLUquadricObj *q;
+
+   static GLfloat cyan[] = { 0.0, 1.0, 1.0, 1.0 };
+   static GLfloat green[] = { 0.2, 1.0, 0.2, 1.0 };
+   static GLfloat black[] = { 0.0, 0.0, 0.0, 0.0 };
+
+   q = gluNewQuadric();
+   gluQuadricDrawStyle( q, GLU_FILL );
+   gluQuadricNormals( q, GLU_SMOOTH );
+
+   objects_list[0] = glGenLists(1);
+   glNewList( objects_list[0], GL_COMPILE );
+   glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cyan );
+   glMaterialfv( GL_FRONT, GL_EMISSION, black );
+   gluCylinder( q, 0.5, 0.5,  1.0, 15, 1 );
+   glEndList();
+
+   objects_list[1] = glGenLists(1);
+   glNewList( objects_list[1], GL_COMPILE );
+   glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green );
+   glMaterialfv( GL_FRONT, GL_EMISSION, black );
+   gluCylinder( q, 1.5, 0.0,  2.5, 15, 1 );
+   glEndList();
+}
+
+
+static GLfloat light_pos[] = { 0.0, 20.0, 0.0, 1.0 };
+
+static void init( void )
+{
+   make_table();
+   make_objects();
+
+   /* Setup texture */
+#ifdef USE_TEXTURE
+
+   Image = LoadRGBImage( TABLE_TEXTURE, &ImgWidth, &ImgHeight, &ImgFormat );
+   if (!Image) {
+      printf("Couldn't read %s\n", TABLE_TEXTURE);
+      exit(0);
+   }
+
+   gluBuild2DMipmaps(GL_TEXTURE_2D, 3, ImgWidth, ImgHeight,
+                     ImgFormat, GL_UNSIGNED_BYTE, Image);
+
+   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
+   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
+   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
+   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
+#endif
+
+
+   xrot = 30.0;
+   yrot = 50.0;
+   spin = 0.0;
+
+#ifndef USE_ZBUFFER
+   glEnable( GL_CULL_FACE );
+#endif
+
+   glShadeModel( GL_FLAT );
+   
+   glEnable( GL_LIGHT0 );
+   glEnable( GL_LIGHTING );
+
+   glClearColor( 0.5, 0.5, 0.9, 1.0 );
+
+   glEnable( GL_NORMALIZE );
+}
+
+
+
+static void reshape(int w, int h)
+{
+   GLfloat aspect = (float) w / (float) h;
+
+   glViewport(0, 0, w, h);
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   glFrustum( -aspect, aspect, -1.0, 1.0, 4.0, 300.0 );
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+}
+
+
+
+static void draw_objects( GLfloat eyex, GLfloat eyey, GLfloat eyez )
+{
+   (void) eyex;
+   (void) eyey;
+   (void) eyez;
+#ifndef USE_ZBUFFER
+       if (eyex<0.5)
+       {
+#endif
+          glPushMatrix();
+          glTranslatef( 1.0, 1.5, 0.0 );
+          glRotatef( spin, 1.0, 0.5, 0.0 );
+          glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
+          glCallList( objects_list[0] );
+          glPopMatrix();
+       
+          glPushMatrix();
+          glTranslatef( -1.0, 0.85+3.0*fabs( cos(0.01*spin) ), 0.0 );
+          glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
+          glRotatef( spin, 1.0, 0.5, 0.0 );
+          glScalef( 0.5, 0.5, 0.5 );
+          glCallList( objects_list[1] );
+          glPopMatrix();
+#ifndef USE_ZBUFFER
+       }
+       else
+       {       
+          glPushMatrix();
+          glTranslatef( -1.0, 0.85+3.0*fabs( cos(0.01*spin) ), 0.0 );
+          glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
+          glRotatef( spin, 1.0, 0.5, 0.0 );
+          glScalef( 0.5, 0.5, 0.5 );
+          glCallList( objects_list[1] );
+          glPopMatrix();
+
+          glPushMatrix();
+          glTranslatef( 1.0, 1.5, 0.0 );
+          glRotatef( spin, 1.0, 0.5, 0.0 );
+          glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
+          glCallList( objects_list[0] );
+          glPopMatrix();
+       }
+#endif
+}
+
+
+
+static void draw_table( void )
+{
+   glCallList( table_list );
+}
+
+
+
+static void draw_scene( void )
+{
+   GLfloat dist = 20.0;
+   GLfloat eyex, eyey, eyez;
+
+   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+
+
+   eyex = dist * cos(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
+   eyez = dist * sin(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
+   eyey = dist * sin(xrot*DEG2RAD);
+
+   /* view from top */
+   glPushMatrix();
+   gluLookAt( eyex, eyey, eyez, 0.0, 0.0, 0.0,  0.0, 1.0, 0.0 );
+
+   glLightfv( GL_LIGHT0, GL_POSITION, light_pos );
+   /* draw table into stencil planes */
+   glEnable( GL_STENCIL_TEST );
+#ifdef USE_ZBUFFER
+   glDisable( GL_DEPTH_TEST );
+#endif
+   glStencilFunc( GL_ALWAYS, 1, 0xffffffff );
+   glStencilOp( GL_REPLACE, GL_REPLACE, GL_REPLACE );
+   glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
+   draw_table();
+   glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
+
+#ifdef USE_ZBUFFER
+   glEnable( GL_DEPTH_TEST );
+#endif
+
+
+   /* render view from below (reflected viewport) */
+   /* only draw where stencil==1 */
+   if (eyey>0.0) {
+      glPushMatrix();
+      glStencilFunc( GL_EQUAL, 1, 0xffffffff );  /* draw if ==1 */
+      glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
+      glScalef( 1.0, -1.0, 1.0 );
+
+      /* Reposition light in reflected space. */
+      glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
+
+      draw_objects(eyex, eyey, eyez);
+      glPopMatrix();
+
+      /* Restore light's original unreflected position. */
+      glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
+   }
+
+   glDisable( GL_STENCIL_TEST );
+
+   glEnable( GL_BLEND );
+   glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
+
+#ifdef USE_TEXTURE
+   glEnable( GL_TEXTURE_2D );
+#endif
+   draw_table();
+   glDisable( GL_TEXTURE_2D );
+   glDisable( GL_BLEND );
+
+   /* view from top */
+   glPushMatrix();
+
+   draw_objects(eyex, eyey, eyez);
+
+   glPopMatrix();
+
+   glPopMatrix();
+
+   glutSwapBuffers();
+}
+
+
+
+#if 0
+void draw_scene(void)
+{
+   GLfloat dist = 20.0;
+   GLfloat eyex, eyey, eyez;
+
+   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+
+
+   eyex = dist * cos(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
+   eyez = dist * sin(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
+   eyey = dist * sin(xrot*DEG2RAD);
+
+   /* view from top */
+   glPushMatrix();
+   gluLookAt( eyex, eyey, eyez, 0.0, 0.0, 0.0,  0.0, 1.0, 0.0 );
+
+   draw_table();
+
+   glPopMatrix();
+
+   glutSwapBuffers();
+}
+#endif
+
+
+static void Key( unsigned char key, int x, int y )
+{
+   (void) x;
+   (void) y;
+   if (key==27)
+      exit(0);
+}
+
+
+static void SpecialKey( int key, int x, int y )
+{
+   (void) x;
+   (void) y;
+   switch (key) {
+      case GLUT_KEY_UP:
+         xrot += 3.0;
+#ifndef USE_ZBUFFER
+                if ( xrot > 180 )      xrot = 180;
+#endif
+         break;
+      case GLUT_KEY_DOWN:
+         xrot -= 3.0;
+#ifndef USE_ZBUFFER
+                if ( xrot < 0 )        xrot = 0;
+#endif
+         break;
+      case GLUT_KEY_LEFT:
+         yrot += 3.0;
+         break;
+      case GLUT_KEY_RIGHT:
+         yrot -= 3.0;
+         break;
+   }
+   glutPostRedisplay();
+}
+
+
+
+static void idle( void )
+{
+   spin += 2.0;
+   yrot += 3.0;
+   glutPostRedisplay();
+}
+
+
+
+int main( int argc, char *argv[] )
+{
+   glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB 
+#ifdef USE_ZBUFFER
+               | GLUT_DEPTH 
+#endif
+               | GLUT_STENCIL);
+   glutInitWindowPosition( 0, 0 );
+   glutInitWindowSize(400, 300 );
+   glutCreateWindow(argv[0]);
+   glutReshapeFunc(reshape);
+   glutDisplayFunc(draw_scene);
+   glutKeyboardFunc(Key);
+   glutSpecialFunc(SpecialKey);
+   glutIdleFunc(idle);
+
+   init();
+
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/demos/renormal.c b/progs/demos/renormal.c
new file mode 100644 (file)
index 0000000..bd099dc
--- /dev/null
@@ -0,0 +1,123 @@
+/* $Id: renormal.c,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
+
+/*
+ * Test GL_EXT_rescale_normal extension
+ * Brian Paul  January 1998   This program is in the public domain.
+ */
+
+/*
+ * $Id: renormal.c,v 1.1 1999/08/19 00:55:40 jtg Exp $
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <GL/glut.h>
+
+
+static GLfloat Phi = 0.0;
+
+
+static void Idle(void)
+{
+   Phi += 0.1;
+   glutPostRedisplay();
+}
+
+
+static void Display( void )
+{
+   GLfloat scale = 0.6 + 0.5 * sin(Phi);
+   glClear( GL_COLOR_BUFFER_BIT );
+   glPushMatrix();
+   glScalef(scale, scale, scale);
+   glutSolidSphere(2.0, 20, 20);
+   glPopMatrix();
+   glutSwapBuffers();
+}
+
+
+static void Reshape( int width, int height )
+{
+   glViewport( 0, 0, width, height );
+   glMatrixMode( GL_PROJECTION );
+   glLoadIdentity();
+   glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 25.0 );
+   glMatrixMode( GL_MODELVIEW );
+   glLoadIdentity();
+   glTranslatef( 0.0, 0.0, -15.0 );
+}
+
+
+
+static void Init( void )
+{
+   static GLfloat mat[4] = { 0.8, 0.8, 0.0, 1.0 };
+   static GLfloat pos[4] = { -1.0, 1.0, 1.0, 0.0 };
+
+   /* setup lighting, etc */
+   glEnable(GL_LIGHTING);
+   glEnable(GL_LIGHT0);
+   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat);
+   glLightfv(GL_LIGHT0, GL_POSITION, pos);
+
+   glEnable(GL_CULL_FACE);
+
+   glDisable(GL_RESCALE_NORMAL_EXT);
+   glDisable(GL_NORMALIZE);
+}
+
+
+#define UNSCALED  1
+#define NORMALIZE 2
+#define RESCALE   3
+#define QUIT      4
+
+
+static void ModeMenu(int entry)
+{
+   if (entry==UNSCALED) {
+      glDisable(GL_RESCALE_NORMAL_EXT);
+      glDisable(GL_NORMALIZE);
+   }
+   else if (entry==NORMALIZE) {
+      glEnable(GL_NORMALIZE);
+      glDisable(GL_RESCALE_NORMAL_EXT);
+   }
+   else if (entry==RESCALE) {
+      glDisable(GL_NORMALIZE);
+      glEnable(GL_RESCALE_NORMAL_EXT);
+   }
+   else if (entry==QUIT) {
+      exit(0);
+   }
+   glutPostRedisplay();
+}
+
+
+int main( int argc, char *argv[] )
+{
+   glutInit( &argc, argv );
+   glutInitWindowSize( 400, 400 );
+
+   glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
+
+   glutCreateWindow(argv[0]);
+
+   Init();
+
+   glutIdleFunc( Idle );
+   glutReshapeFunc( Reshape );
+   glutDisplayFunc( Display );
+
+   glutCreateMenu(ModeMenu);
+   glutAddMenuEntry("Unscaled", UNSCALED);
+   glutAddMenuEntry("Normalize", NORMALIZE);
+   glutAddMenuEntry("Rescale EXT", RESCALE);
+   glutAddMenuEntry("Quit", QUIT);
+   glutAttachMenu(GLUT_RIGHT_BUTTON);
+
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/demos/spectex.c b/progs/demos/spectex.c
new file mode 100644 (file)
index 0000000..412f442
--- /dev/null
@@ -0,0 +1,277 @@
+/* $Id: spectex.c,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
+
+/*
+ * GLUT demonstration of texturing with specular highlights.
+ *
+ * When drawing a lit, textured surface one usually wants the specular
+ * highlight to override the texture colors.  However, OpenGL applies
+ * texturing after lighting so the specular highlight is modulated by
+ * the texture.
+ *
+ * The solution here shown here is a two-pass algorithm:
+ *  1. Draw the textured surface without specular lighting.
+ *  2. Enable blending to add the next pass:
+ *  3. Redraw the surface with a matte white material and only the
+ *     specular components of light sources enabled.
+ *
+ * Brian Paul  February 1997
+ */
+
+
+/*
+ * $Log: spectex.c,v $
+ * Revision 1.1  1999/08/19 00:55:40  jtg
+ * Initial revision
+ *
+ * Revision 3.2  1999/03/28 18:22:05  brianp
+ * minor clean-up
+ *
+ * Revision 3.1  1998/02/14 18:47:48  brianp
+ * added OpenGL 1.2 separate specular interpolation support
+ *
+ * Revision 3.0  1998/02/14 18:42:29  brianp
+ * initial rev
+ *
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <GL/glut.h>
+
+
+static GLUquadricObj *Quadric;
+static GLuint Sphere;
+static GLfloat LightPos[4] = {10.0, 10.0, 10.0, 1.0};
+static GLfloat Delta = 1.0;
+static GLint Mode = 0;
+
+/*static GLfloat Blue[4] = {0.0, 0.0, 1.0, 1.0};*/
+/*static GLfloat Gray[4] = {0.5, 0.5, 0.5, 1.0};*/
+static GLfloat Black[4] = {0.0, 0.0, 0.0, 1.0};
+static GLfloat White[4] = {1.0, 1.0, 1.0, 1.0};
+
+
+
+static void Idle( void )
+{
+   LightPos[0] += Delta;
+   if (LightPos[0]>15.0)
+      Delta = -1.0;
+   else if (LightPos[0]<-15.0)
+      Delta = 1.0;
+
+   glutPostRedisplay();
+}
+
+
+static void Display( void )
+{
+   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+
+   glLightfv(GL_LIGHT0, GL_POSITION, LightPos);
+
+   glPushMatrix();
+   glRotatef(90.0, 1.0, 0.0, 0.0);
+
+   if (Mode==0) {
+      /* Typical method: diffuse + specular + texture */
+      glEnable(GL_TEXTURE_2D);
+      glLightfv(GL_LIGHT0, GL_DIFFUSE, White);  /* enable diffuse */
+      glLightfv(GL_LIGHT0, GL_SPECULAR, White);  /* enable specular */
+#ifdef GL_VERSION_1_2
+      glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
+#endif
+      glCallList(Sphere);
+   }
+   else if (Mode==1) {
+      /* just specular highlight */
+      glDisable(GL_TEXTURE_2D);
+      glLightfv(GL_LIGHT0, GL_DIFFUSE, Black);  /* disable diffuse */
+      glLightfv(GL_LIGHT0, GL_SPECULAR, White);  /* enable specular */
+#ifdef GL_VERSION_1_2
+      glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
+#endif
+      glCallList(Sphere);
+   }
+   else if (Mode==2) {
+      /* diffuse textured */
+      glEnable(GL_TEXTURE_2D);
+      glLightfv(GL_LIGHT0, GL_DIFFUSE, White);  /* enable diffuse */
+      glLightfv(GL_LIGHT0, GL_SPECULAR, Black);  /* disable specular */
+#ifdef GL_VERSION_1_2
+      glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
+#endif
+      glCallList(Sphere);
+   }
+   else if (Mode==3) {
+      /* 2-pass: diffuse textured then add specular highlight*/
+      glEnable(GL_TEXTURE_2D);
+      glLightfv(GL_LIGHT0, GL_DIFFUSE, White);  /* enable diffuse */
+      glLightfv(GL_LIGHT0, GL_SPECULAR, Black);  /* disable specular */
+#ifdef GL_VERSION_1_2
+      glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
+#endif
+      glCallList(Sphere);
+      /* specular highlight */
+      glDepthFunc(GL_EQUAL);  /* redraw same pixels */
+      glDisable(GL_TEXTURE_2D);
+      glEnable(GL_BLEND);  /* add */
+      glLightfv(GL_LIGHT0, GL_DIFFUSE, Black);  /* disable diffuse */
+      glLightfv(GL_LIGHT0, GL_SPECULAR, White);  /* enable specular */
+      glCallList(Sphere);
+      glDepthFunc(GL_LESS);
+      glDisable(GL_BLEND);
+   }
+   else if (Mode==4) {
+      /* OpenGL 1.2's separate diffuse and specular color */
+      glEnable(GL_TEXTURE_2D);
+      glLightfv(GL_LIGHT0, GL_DIFFUSE, White);  /* enable diffuse */
+      glLightfv(GL_LIGHT0, GL_SPECULAR, White);  /* enable specular */
+#ifdef GL_VERSION_1_2
+      glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
+#endif
+      glCallList(Sphere);
+   }
+
+   glPopMatrix();
+
+   glutSwapBuffers();
+}
+
+
+static void Reshape( int width, int height )
+{
+   glViewport( 0, 0, width, height );
+   glMatrixMode( GL_PROJECTION );
+   glLoadIdentity();
+   glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 25.0 );
+   glMatrixMode( GL_MODELVIEW );
+   glLoadIdentity();
+   glTranslatef( 0.0, 0.0, -12.0 );
+}
+
+
+static void Key( unsigned char key, int x, int y )
+{
+   (void) x;
+   (void) y;
+   switch (key) {
+      case 27:
+         exit(0);
+         break;
+   }
+   glutPostRedisplay();
+}
+
+
+static void SpecialKey( int key, int x, int y )
+{
+   (void) x;
+   (void) y;
+   switch (key) {
+      case GLUT_KEY_UP:
+         break;
+      case GLUT_KEY_DOWN:
+         break;
+   }
+   glutPostRedisplay();
+}
+
+
+static void Init( void )
+{
+   int i, j;
+   GLubyte texImage[64][64][3];
+
+   glEnable(GL_LIGHTING);
+   glEnable(GL_LIGHT0);
+   glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
+   glLightModelfv(GL_LIGHT_MODEL_AMBIENT, Black);
+
+   glMaterialfv(GL_FRONT, GL_DIFFUSE, White);
+   glMaterialfv(GL_FRONT, GL_SPECULAR, White);
+   glMaterialf(GL_FRONT, GL_SHININESS, 20.0);
+
+   /* Actually, these are set again later */
+   glLightfv(GL_LIGHT0, GL_DIFFUSE, White);
+   glLightfv(GL_LIGHT0, GL_SPECULAR, White);
+
+   Quadric = gluNewQuadric();
+   gluQuadricTexture( Quadric, GL_TRUE );
+
+   Sphere= glGenLists(1);
+   glNewList( Sphere, GL_COMPILE );
+   gluSphere( Quadric, 1.0, 24, 24 );
+   glEndList();
+
+   glEnable(GL_DEPTH_TEST);
+   glEnable(GL_CULL_FACE);
+
+   for (i=0;i<64;i++) {
+      for (j=0;j<64;j++) {
+         int k = ((i>>3)&1) ^ ((j>>3)&1);
+         texImage[i][j][0] = 255*k;
+         texImage[i][j][1] = 255*(1-k);
+         texImage[i][j][2] = 0;
+      }
+   }
+
+   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+   glTexImage2D( GL_TEXTURE_2D,
+                 0,
+                 3,
+                 64, 64,
+                 0,
+                 GL_RGB, GL_UNSIGNED_BYTE,
+                 texImage );
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+   glEnable(GL_TEXTURE_2D);
+
+   glBlendFunc(GL_ONE, GL_ONE);
+}
+
+
+static void ModeMenu(int entry)
+{
+   if (entry==99)
+      exit(0);
+   Mode = entry;
+}
+
+
+int main( int argc, char *argv[] )
+{
+
+   glutInit( &argc, argv );
+   glutInitWindowPosition( 0, 0 );
+   glutInitWindowSize( 300, 300 );
+
+   glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
+
+   glutCreateWindow( "spectex" );
+
+   Init();
+
+   glutReshapeFunc( Reshape );
+   glutKeyboardFunc( Key );
+   glutSpecialFunc( SpecialKey );
+   glutDisplayFunc( Display );
+   glutIdleFunc( Idle );
+
+   glutCreateMenu( ModeMenu );
+   glutAddMenuEntry("1-pass lighting + texturing", 0);
+   glutAddMenuEntry("specular lighting", 1);
+   glutAddMenuEntry("diffuse lighting + texturing", 2);
+   glutAddMenuEntry("2-pass lighting + texturing", 3);
+#ifdef GL_VERSION_1_2
+   glutAddMenuEntry("OpenGL 1.2 separate specular", 4);
+#endif
+   glutAddMenuEntry("Quit", 99);
+   glutAttachMenu(GLUT_RIGHT_BUTTON);
+
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/demos/stex3d.c b/progs/demos/stex3d.c
new file mode 100644 (file)
index 0000000..7c478c7
--- /dev/null
@@ -0,0 +1,578 @@
+/* $Id: stex3d.c,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
+
+/*----------------------------- 
+ * stex3d.c GL example of the mesa 3d-texture extention to simulate procedural
+ *            texturing, it uses a perlin noise and turbulence functions.
+ * 
+ * Author:   Daniel Barrero
+ *           barrero@irit.fr
+ *           dbarrero@pegasus.uniandes.edu.co
+ *
+ * Converted to GLUT by brianp on 1/1/98
+ *
+ *      
+ * cc stex3d.c -o stex3d -lglut -lMesaGLU -lMesaGL -lX11 -lXext -lm 
+ *
+ *---------------------------- */
+
+/*
+ * $Log: stex3d.c,v $
+ * Revision 1.1  1999/08/19 00:55:40  jtg
+ * Initial revision
+ *
+ * Revision 3.1  1998/06/09 01:53:49  brianp
+ * main() should return an int
+ *
+ * Revision 3.0  1998/02/14 18:42:29  brianp
+ * initial rev
+ *
+ */
+
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <GL/gl.h>
+#include <GL/glut.h>
+/* function declarations */
+#ifndef M_PI
+#define M_PI            3.14159265358979323846
+#endif
+void init(void),
+     printHelp(void),
+     create3Dtexture(void),
+     setDefaults(void),
+     drawScene(void),
+     resize(int w, int h),
+     buildFigure(void),
+     initNoise(void);
+float turbulence(float point[3], float lofreq, float hifreq);
+
+int isExtSupported(char *ext);
+void KeyHandler( unsigned char key, int x, int y );
+GLenum parseCmdLine(int argc, char **argv);
+float noise3(float vec[3]);
+      
+/* global variables */
+GLenum rgb, doubleBuffer, directRender, windType; /* visualization state*/
+float tex_width,tex_height,tex_depth;        /* texture volume dimensions  */
+unsigned char *voxels;                       /* texture data ptr */
+int angx,angy,angz;
+GLuint figure;
+
+/*function definitions */
+int main(int argc, char **argv)
+{
+
+ if (parseCmdLine(argc, argv) == GL_FALSE) {
+    exit(0);
+ }
+
+ glutInitWindowPosition(0, 0);
+ glutInitWindowSize(400, 400);
+ windType = (rgb) ? GLUT_RGB : GLUT_INDEX;
+ windType |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
+ windType |= GLUT_DEPTH;
+ glutInitDisplayMode(windType);
+
+ if (glutCreateWindow("stex3d") <= 0) {
+    exit(0);
+ }
+ /* init all */
+ init();
+
+ glutReshapeFunc(resize);
+ glutKeyboardFunc(KeyHandler);
+ glutDisplayFunc(drawScene);
+ glutMainLoop();
+ return 0;
+}
+
+void init()
+{ 
+ /* init light */
+ GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
+ GLfloat mat_shininess[] = { 25.0 };
+ GLfloat gray[] = { 0.6, 0.6, 0.6, 0.0 };
+ GLfloat white[] = { 1.0, 1.0, 1.0, 0.0 };
+ GLfloat light_position[] = { 0.0, 1.0, 1.0, 0.0 };
+
+ glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
+ glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
+ glLightfv(GL_LIGHT1, GL_POSITION, light_position);
+ glLightfv(GL_LIGHT1, GL_AMBIENT, gray);
+ glLightfv(GL_LIGHT1, GL_DIFFUSE, white);
+ glLightfv(GL_LIGHT1, GL_SPECULAR, white);
+ glColorMaterial(GL_FRONT, GL_DIFFUSE);
+ glEnable(GL_COLOR_MATERIAL);
+ glEnable(GL_LIGHTING);
+ glEnable(GL_LIGHT1);
+
+ /* create torus for texturing */
+ figure=glGenLists(1); 
+ buildFigure();
+/* tkSolidTorus(figure,0.3,1.2);*/
+
+ /* start the noise function variables */
+ initNoise();
+ /* see if the texture 3d extention is supported */
+ if (!isExtSupported("GL_EXT_texture3D")) {
+   printf("Sorry this GL implementation (%s) does not support 3d texture extentions\n",
+        (char *)(glGetString(GL_RENDERER)));
+/*   tkQuit();*/
+ }
+ /* if texture is supported then generate the texture */
+ create3Dtexture(); 
+
+ glEnable(GL_TEXTURE_3D_EXT); 
+ /*
+ glBlendFunc(GL_SRC_COLOR, GL_SRC_ALPHA);
+ glEnable(GL_BLEND); 
+ */
+ glEnable(GL_DEPTH_TEST);
+
+ glShadeModel(GL_FLAT);
+ glColor3f(0.6,0.7,0.8);
+}
+
+void buildFigure(void)
+{   GLint i, j;
+    float theta1, phi1, theta2, phi2, rings, sides;
+    float v0[03], v1[3], v2[3], v3[3];
+    float t0[03], t1[3], t2[3], t3[3];
+    float n0[3], n1[3], n2[3], n3[3];
+    float innerRadius=0.4;
+    float outerRadius=0.8;
+    float scalFac;
+
+    rings = 8;
+    sides = 10;
+    scalFac=1/(outerRadius*2);
+
+    glNewList(figure, GL_COMPILE);
+    for (i = 0; i < rings; i++) {
+        theta1 = (float)i * 2.0 * M_PI / rings;
+        theta2 = (float)(i + 1) * 2.0 * M_PI / rings;
+        for (j = 0; j < sides; j++) {
+            phi1 = (float)j * 2.0 * M_PI / sides;
+            phi2 = (float)(j + 1) * 2.0 * M_PI / sides;
+
+            v0[0] = cos(theta1) * (outerRadius + innerRadius * cos(phi1));
+            v0[1] = -sin(theta1) * (outerRadius + innerRadius * cos(phi1));
+            v0[2] = innerRadius * sin(phi1);
+
+            v1[0] = cos(theta2) * (outerRadius + innerRadius * cos(phi1));
+            v1[1] = -sin(theta2) * (outerRadius + innerRadius * cos(phi1));
+            v1[2] = innerRadius * sin(phi1);
+            v2[0] = cos(theta2) * (outerRadius + innerRadius * cos(phi2));
+            v2[1] = -sin(theta2) * (outerRadius + innerRadius * cos(phi2));
+            v2[2] = innerRadius * sin(phi2);
+
+            v3[0] = cos(theta1) * (outerRadius + innerRadius * cos(phi2));
+            v3[1] = -sin(theta1) * (outerRadius + innerRadius * cos(phi2));
+            v3[2] = innerRadius * sin(phi2);
+
+            n0[0] = cos(theta1) * (cos(phi1));
+            n0[1] = -sin(theta1) * (cos(phi1));
+            n0[2] = sin(phi1);
+
+            n1[0] = cos(theta2) * (cos(phi1));
+            n1[1] = -sin(theta2) * (cos(phi1));
+            n1[2] = sin(phi1);
+
+            n2[0] = cos(theta2) * (cos(phi2));
+            n2[1] = -sin(theta2) * (cos(phi2));
+            n2[2] = sin(phi2);
+
+            n3[0] = cos(theta1) * (cos(phi2));
+            n3[1] = -sin(theta1) * (cos(phi2));
+            n3[2] = sin(phi2);
+
+            t0[0] = v0[0]*scalFac + 0.5;
+            t0[1] = v0[1]*scalFac + 0.5;
+            t0[2] = v0[2]*scalFac + 0.5;
+
+            t1[0] = v1[0]*scalFac + 0.5;
+            t1[1] = v1[1]*scalFac + 0.5;
+            t1[2] = v1[2]*scalFac + 0.5;
+
+            t2[0] = v2[0]*scalFac + 0.5;
+            t2[1] = v2[1]*scalFac + 0.5;
+            t2[2] = v2[2]*scalFac + 0.5;
+
+            t3[0] = v3[0]*scalFac + 0.5;
+            t3[1] = v3[1]*scalFac + 0.5;
+            t3[2] = v3[2]*scalFac + 0.5;
+
+            glBegin(GL_POLYGON);
+                glNormal3fv(n3); glTexCoord3fv(t3); glVertex3fv(v3);
+                glNormal3fv(n2); glTexCoord3fv(t2); glVertex3fv(v2);
+                glNormal3fv(n1); glTexCoord3fv(t1); glVertex3fv(v1);
+                glNormal3fv(n0); glTexCoord3fv(t0); glVertex3fv(v0);
+            glEnd();
+        }
+    }
+    glEndList();
+}
+
+void create3Dtexture()
+{
+ int i,j,k;
+ unsigned char *vp;
+ float vec[3];
+ int tmp;
+
+ printf("creating 3d textures...\n");
+ voxels = (unsigned char  *) malloc((4*tex_width*tex_height*tex_depth));
+ vp=voxels;
+ for (i=0;i<tex_width;i++){
+    vec[0]=i;
+    for (j=0;j<tex_height;j++) {
+      vec[1]=j;
+       for (k=0;k<tex_depth;k++) {
+           vec[2]=k;
+           tmp=(sin(k*i*j+turbulence(vec,0.01,1))+1)*127.5; 
+           *vp++=0;
+           *vp++=0;
+           *vp++=tmp; 
+           *vp++=tmp+128; 
+       }
+     }
+ }
+
+ printf("setting up 3d texture...\n");
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ glTexParameteri(GL_TEXTURE_3D_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_3D_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_3D_EXT, GL_TEXTURE_WRAP_S,     GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_3D_EXT, GL_TEXTURE_WRAP_T,     GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_3D_EXT, GL_TEXTURE_WRAP_R_EXT, GL_REPEAT);
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
+
+ glTexImage3DEXT(GL_TEXTURE_3D_EXT, 0, GL_RGBA,
+                    tex_width, tex_height, tex_depth,
+                    0, GL_RGBA, GL_UNSIGNED_BYTE, voxels);
+ printf("finished setting up 3d texture image...\n");
+}
+
+int isExtSupported(char *ext)
+{
+    /* routine to find whether a specified OpenGL extension is supported */
+
+    char *c;
+    int len;
+    char *allext = (char *)(glGetString(GL_EXTENSIONS));
+
+    len = strlen(ext);
+    if (len <= 0) return 0;
+
+    c = allext;
+    while (c) {
+        if (!strncmp(c,ext,len)) return 1;
+        c = strchr(c+1,'G');
+    }
+    return 0;
+}
+
+void printHelp()
+{
+  printf("\nUsage: stex3d  <cmd line options>\n"); 
+  printf(" cmd line options:\n");
+  printf("      -help   print this help!\n");
+  printf("      -rgb     RGBA mode. (Default)\n");
+  printf("      -ci     Color index mode.\n");
+  printf("      -sb     Single buffer mode. (Default)\n");
+  printf("      -db     Double buffer mode. \n");
+  printf("      -dr     Direct render mode.\n");
+  printf("      -ir     Indirect render mode. (Default)\n");
+  printf("      -wxxx   Width of the texture (Default=64)\n");
+  printf("      -hxxx   Height of the texture (Default=64)\n");
+  printf("      -dxxx   Depth of the texture (Default=64)\n");
+  printf(" Keyboard Options:\n");
+  printf("       1      Object Texture coordinates (Default)\n");
+  printf("       2      Eye Texture coordinates \n");
+  printf("       x      rotate around x clockwise\n");
+  printf("       X      rotate around x counter clockwise\n");
+  printf("       y      rotate around y clockwise\n");
+  printf("       Y      rotate around y counter clockwise\n");
+  printf("       z      rotate around z clockwise\n");
+  printf("       Z      rotate around z counter clockwise\n");
+  printf("       t      enable 3-D texuring (Default)\n");
+  printf("       T      disable 3-D texuring\n");
+  printf("       s      smooth shading \n");
+  printf("       S      flat shading (Default)\n");
+}
+
+void setDefaults()
+{
+ /* visualization defaults */
+  rgb = GL_TRUE;
+  doubleBuffer = GL_FALSE;
+  directRender = GL_TRUE;
+  angx=130;
+  angy=30;
+  angz=0; 
+ /* texture values */
+ tex_width=64;
+ tex_height=64;
+ tex_depth=64;
+}
+
+GLenum parseCmdLine(int argc, char **argv)
+{
+  GLint i;
+  setDefaults();
+
+  for (i = 1; i < argc; i++) {
+      if (strcmp(argv[i], "-ci") == 0) {
+          rgb = GL_FALSE;
+      } else if (strcmp(argv[i], "-rgb") == 0) {
+          rgb = GL_TRUE;
+      } else if (strcmp(argv[i], "-sb") == 0) {
+          doubleBuffer = GL_FALSE;
+      } else if (strcmp(argv[i], "-db") == 0) {
+          doubleBuffer = GL_TRUE;
+      } else if (strcmp(argv[i], "-dr") == 0) {
+          directRender = GL_TRUE;
+      } else if (strcmp(argv[i], "-ir") == 0) {
+          directRender = GL_FALSE;
+      } else if (strstr(argv[i], "-w") == 0) {
+          tex_width=atoi((argv[i])+2);
+      } else if (strstr(argv[i], "-h") == 0) {
+          tex_height=atoi((argv[i])+2);
+      } else if (strstr(argv[i], "-d") == 0) {
+          tex_depth=atoi((argv[i])+2);
+      } else if (strcmp(argv[i], "-help") == 0) {
+          printHelp();
+          return GL_FALSE;
+      } else {
+          printf("%s (Bad option).\n", argv[i]);
+          printHelp();
+          return GL_FALSE;
+      }
+  }
+ if(tex_width==0 || tex_height==0 || tex_depth==0) {
+   printf("%s (Bad option).\n", "size parameters can't be 0");
+   printHelp();
+   return GL_FALSE;
+ }
+  return GL_TRUE;
+}
+
+void drawScene()
+{
+ /* clear background, z buffer etc */
+ glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+ glPushMatrix();
+ glRotatef(angx,1.0,0.0,0.0);
+ glRotatef(angy,0.0,1.0,0.0);
+ glRotatef(angz,0.0,0.0,1.0);
+
+ glCallList(figure);     
+ glPopMatrix();
+ glFlush();
+ if(doubleBuffer)
+    glutSwapBuffers();
+ ;
+}
+
+void resize(int w, int h)
+{ 
+ glViewport(0, 0, (GLint)w, (GLint)h);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(-2,2,-2,2,-5,10);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0,0,-5);
+}
+
+void cleanEverything(void)
+{
+/*  free(voxels); */
+}
+
+
+void KeyHandler( unsigned char key, int x, int y )
+{
+   switch(key) {
+      case 27:
+      case 'q':
+      case 'Q': /* quit game. */
+         cleanEverything();
+         exit(0);
+         break;
+      case 'x':
+         angx+=10;
+         break;
+      case 'X': 
+         angx-=10; 
+         break;
+      case 'y':
+         angy+=10;
+         break;
+      case 'Y': 
+         angy-=10; 
+         break;
+      case 'z':
+         angz+=10;
+         break;
+      case 'Z': 
+         angz-=10; 
+         break;
+      case 't':
+         glEnable(GL_TEXTURE_3D_EXT); 
+         break;
+      case 'T':
+         glDisable(GL_TEXTURE_3D_EXT);
+         break;
+      case 's':
+         glShadeModel(GL_SMOOTH);
+         break;
+      case 'S':
+         glShadeModel(GL_FLAT);
+         break;
+      case '1':
+         glDisable(GL_TEXTURE_GEN_S);
+         glDisable(GL_TEXTURE_GEN_T);
+         glDisable(GL_TEXTURE_GEN_R);
+         break;
+      case '2':
+         glEnable(GL_TEXTURE_GEN_S);
+         glEnable(GL_TEXTURE_GEN_T);
+         glEnable(GL_TEXTURE_GEN_R);
+         break;
+      default:
+         break;
+   }
+   glutPostRedisplay();
+}
+
+/*--------------------------------------------------------------------
+ noise function over R3 - implemented by a pseudorandom tricubic spline 
+              EXCERPTED FROM SIGGRAPH 92, COURSE 23
+                        PROCEDURAL MODELING
+                             Ken Perlin
+                           New York University
+----------------------------------------------------------------------*/
+
+
+#define DOT(a,b) (a[0] * b[0] + a[1] * b[1] + a[2] * b[2])
+#define B 256
+static int p[B + B + 2];
+static float g[B + B + 2][3];
+#define setup(i,b0,b1,r0,r1) \
+        t = vec[i] + 10000.; \
+        b0 = ((int)t) & (B-1); \
+        b1 = (b0+1) & (B-1); \
+        r0 = t - (int)t; \
+        r1 = r0 - 1.;
+
+float noise3(float vec[3])
+{
+        int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
+        float rx0, rx1, ry0, ry1, rz0, rz1, *q, sx, sy, sz, a, b, c, d, t, u, v;
+        register int i, j;
+
+        setup(0, bx0,bx1, rx0,rx1);
+        setup(1, by0,by1, ry0,ry1);
+        setup(2, bz0,bz1, rz0,rz1);
+
+        i = p[ bx0 ];
+        j = p[ bx1 ];
+
+        b00 = p[ i + by0 ];
+        b10 = p[ j + by0 ];
+        b01 = p[ i + by1 ];
+        b11 = p[ j + by1 ];
+
+#define at(rx,ry,rz) ( rx * q[0] + ry * q[1] + rz * q[2] )
+#define surve(t) ( t * t * (3. - 2. * t) )
+#define lerp(t, a, b) ( a + t * (b - a) )
+
+        sx = surve(rx0);
+        sy = surve(ry0);
+        sz = surve(rz0);
+
+        q = g[ b00 + bz0 ] ; u = at(rx0,ry0,rz0);
+        q = g[ b10 + bz0 ] ; v = at(rx1,ry0,rz0);
+        a = lerp(sx, u, v);
+
+        q = g[ b01 + bz0 ] ; u = at(rx0,ry1,rz0);
+        q = g[ b11 + bz0 ] ; v = at(rx1,ry1,rz0);
+        b = lerp(sx, u, v);
+
+        c = lerp(sy, a, b);          /* interpolate in y at lo x */
+
+        q = g[ b00 + bz1 ] ; u = at(rx0,ry0,rz1);
+        q = g[ b10 + bz1 ] ; v = at(rx1,ry0,rz1);
+        a = lerp(sx, u, v);
+
+        q = g[ b01 + bz1 ] ; u = at(rx0,ry1,rz1);
+        q = g[ b11 + bz1 ] ; v = at(rx1,ry1,rz1);
+        b = lerp(sx, u, v);
+
+        d = lerp(sy, a, b);          /* interpolate in y at hi x */
+
+        return 1.5 * lerp(sz, c, d); /* interpolate in z */
+}
+
+void initNoise()
+{
+        /*long random();*/
+        int i, j, k;
+        float v[3], s;
+
+/* Create an array of random gradient vectors uniformly on the unit sphere */
+        /*srandom(1);*/
+        srand(1);
+        for (i = 0 ; i < B ; i++) {
+                do {                            /* Choose uniformly in a cube */                        for (j=0 ; j<3 ; j++)
+                                v[j] = (float)((rand() % (B + B)) - B) / B;
+                        s = DOT(v,v);
+                } while (s > 1.0);              /* If not in sphere try again */                s = sqrt(s);
+                for (j = 0 ; j < 3 ; j++)       /* Else normalize */
+                        g[i][j] = v[j] / s;
+        }
+
+/* Create a pseudorandom permutation of [1..B] */
+        for (i = 0 ; i < B ; i++)
+                p[i] = i;
+        for (i = B ; i > 0 ; i -= 2) {
+                k = p[i];
+                p[i] = p[j = rand() % B];
+                p[j] = k;
+        }
+
+/* Extend g and p arrays to allow for faster indexing */
+        for (i = 0 ; i < B + 2 ; i++) {
+                p[B + i] = p[i];
+                for (j = 0 ; j < 3 ; j++)
+                        g[B + i][j] = g[i][j];
+        }
+}
+
+float turbulence(float point[3], float lofreq, float hifreq)
+{
+        float freq, t, p[3];
+
+        p[0] = point[0] + 123.456;
+        p[1] = point[1];
+        p[2] = point[2];
+
+        t = 0;
+        for (freq = lofreq ; freq < hifreq ; freq *= 2.) {
+                t += fabs(noise3(p)) / freq;
+                p[0] *= 2.;
+                p[1] *= 2.;
+                p[2] *= 2.;
+        }
+        return t - 0.3; /* readjust to make mean value = 0.0 */
+}
+
diff --git a/progs/demos/tessdemo.c b/progs/demos/tessdemo.c
new file mode 100644 (file)
index 0000000..497b105
--- /dev/null
@@ -0,0 +1,439 @@
+/* $Id: tessdemo.c,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
+
+/*
+ * A demo of the GLU polygon tesselation functions written by Bogdan Sikorski.
+ * This demo isn't built by the Makefile because it needs GLUT.  After you've
+ * installed GLUT you can try this demo.
+ * Here's the command for IRIX, for example:
+   cc -g -ansi -prototypes -fullwarn -float -I../include -DSHM tess_demo.c -L../lib -lglut -lMesaGLU -lMesaGL -lm -lX11 -lXext -lXmu -lfpe -lXext -o tess_demo
+ */
+
+
+/*
+ * $Log: tessdemo.c,v $
+ * Revision 1.1  1999/08/19 00:55:40  jtg
+ * Initial revision
+ *
+ * Revision 3.5  1999/03/28 18:24:37  brianp
+ * minor clean-up
+ *
+ * Revision 3.4  1999/02/14 03:37:07  brianp
+ * fixed callback problem
+ *
+ * Revision 3.3  1998/07/26 01:25:26  brianp
+ * removed include of gl.h and glu.h
+ *
+ * Revision 3.2  1998/06/29 02:37:30  brianp
+ * minor changes for Windows (Ted Jump)
+ *
+ * Revision 3.1  1998/06/09 01:53:49  brianp
+ * main() should return an int
+ *
+ * Revision 3.0  1998/02/14 18:42:29  brianp
+ * initial rev
+ *
+ */
+
+
+#include <GL/glut.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define MAX_POINTS 200
+#define MAX_CONTOURS 50
+
+int menu;
+typedef enum{ QUIT, TESSELATE, CLEAR } menu_entries;
+typedef enum{ DEFINE, TESSELATED } mode_type;
+struct
+{
+       GLint p[MAX_POINTS][2];
+       GLuint point_cnt;
+} contours[MAX_CONTOURS];
+GLuint contour_cnt;
+GLsizei width,height;
+mode_type mode;
+
+struct
+{
+       GLsizei no;
+       GLfloat color[3];
+       GLint p[3][2];
+       GLclampf p_color[3][3];
+} triangle;
+
+
+#ifndef GLCALLBACK
+#ifdef CALLBACK
+#define GLCALLBACK CALLBACK
+#else
+#define GLCALLBACK
+#endif
+#endif
+
+
+void GLCALLBACK my_error(GLenum err)
+{
+       int len,i;
+       char const *str;
+
+       glColor3f(0.9,0.9,0.9);
+       glRasterPos2i(5,5);
+       str=(const char *)gluErrorString(err);
+       len=strlen(str);
+       for(i=0;i<len;i++)
+               glutBitmapCharacter(GLUT_BITMAP_9_BY_15,str[i]);
+}
+
+void GLCALLBACK begin_callback(GLenum mode)
+{
+       triangle.no=0;
+}
+
+void GLCALLBACK edge_callback(GLenum flag)
+{
+       if(flag==GL_TRUE)
+       {
+               triangle.color[0]=1.0;
+               triangle.color[1]=1.0;
+               triangle.color[2]=0.5;
+       }
+       else
+       {
+               triangle.color[0]=1.0;
+               triangle.color[1]=0.0;
+               triangle.color[2]=0.0;
+       }
+}
+
+void GLCALLBACK end_callback()
+{
+       glBegin(GL_LINES);
+       glColor3f(triangle.p_color[0][0],triangle.p_color[0][1],
+               triangle.p_color[0][2]);
+       glVertex2i(triangle.p[0][0],triangle.p[0][1]);
+       glVertex2i(triangle.p[1][0],triangle.p[1][1]);
+       glColor3f(triangle.p_color[1][0],triangle.p_color[1][1],
+               triangle.p_color[1][2]);
+       glVertex2i(triangle.p[1][0],triangle.p[1][1]);
+       glVertex2i(triangle.p[2][0],triangle.p[2][1]);
+       glColor3f(triangle.p_color[2][0],triangle.p_color[2][1],
+               triangle.p_color[2][2]);
+       glVertex2i(triangle.p[2][0],triangle.p[2][1]);
+       glVertex2i(triangle.p[0][0],triangle.p[0][1]);
+       glEnd();
+}
+
+void GLCALLBACK vertex_callback(void *data)
+{
+       GLsizei no;
+       GLint *p;
+
+       p=(GLint *)data;
+       no=triangle.no;
+       triangle.p[no][0]=p[0];
+       triangle.p[no][1]=p[1];
+       triangle.p_color[no][0]=triangle.color[0];
+       triangle.p_color[no][1]=triangle.color[1];
+       triangle.p_color[no][2]=triangle.color[2];
+       ++(triangle.no);
+}
+
+void set_screen_wh(GLsizei w, GLsizei h)
+{
+       width=w;
+       height=h;
+}
+
+void tesse(void)
+{
+       GLUtriangulatorObj *tobj;
+       GLdouble data[3];
+       GLuint i,j,point_cnt;
+
+       tobj=gluNewTess();
+       if(tobj!=NULL)
+       {
+               glClear(GL_COLOR_BUFFER_BIT);
+               glColor3f (0.7, 0.7, 0.0);
+               gluTessCallback(tobj,GLU_BEGIN,glBegin);
+               gluTessCallback(tobj,GLU_END,glEnd);
+               gluTessCallback(tobj,GLU_ERROR,my_error);
+               gluTessCallback(tobj,GLU_VERTEX,glVertex2iv);
+               gluBeginPolygon(tobj);
+               for(j=0;j<=contour_cnt;j++)
+               {
+                       point_cnt=contours[j].point_cnt;
+                       gluNextContour(tobj,GLU_UNKNOWN);
+                       for(i=0;i<point_cnt;i++)
+                       {
+                               data[0]=(GLdouble)(contours[j].p[i][0]);
+                               data[1]=(GLdouble)(contours[j].p[i][1]);
+                               data[2]=0.0;
+                               gluTessVertex(tobj,data,contours[j].p[i]);
+                       }
+               }
+               gluEndPolygon(tobj);
+               glLineWidth(2.0);
+               gluTessCallback(tobj,GLU_BEGIN,begin_callback);
+               gluTessCallback(tobj,GLU_END,end_callback);
+               gluTessCallback(tobj,GLU_VERTEX,vertex_callback);
+               gluTessCallback(tobj,GLU_EDGE_FLAG,edge_callback);
+               gluBeginPolygon(tobj);
+               for(j=0;j<=contour_cnt;j++)
+               {
+                       point_cnt=contours[j].point_cnt;
+                       gluNextContour(tobj,GLU_UNKNOWN);
+                       for(i=0;i<point_cnt;i++)
+                       {
+                               data[0]=(GLdouble)(contours[j].p[i][0]);
+                               data[1]=(GLdouble)(contours[j].p[i][1]);
+                               data[2]=0.0;
+                               gluTessVertex(tobj,data,contours[j].p[i]);
+                       }
+               }
+               gluEndPolygon(tobj);
+               gluDeleteTess(tobj);
+               glutMouseFunc(NULL);
+               glColor3f (1.0, 1.0, 0.0);
+               glLineWidth(1.0);
+               mode=TESSELATED;
+       }
+}
+
+void left_down(int x1,int y1)
+{
+       GLint P[2];
+       GLuint point_cnt;
+
+       /* translate GLUT into GL coordinates */
+       P[0]=x1;
+       P[1]=height-y1;
+       point_cnt=contours[contour_cnt].point_cnt;
+       contours[contour_cnt].p[point_cnt][0]=P[0];
+       contours[contour_cnt].p[point_cnt][1]=P[1];
+    glBegin(GL_LINES);
+    if(point_cnt)
+    {
+        glVertex2iv(contours[contour_cnt].p[point_cnt-1]);
+        glVertex2iv(P);
+    }
+    else
+    {
+        glVertex2iv(P);
+        glVertex2iv(P);
+    }
+    glEnd();
+    glFinish();
+       ++(contours[contour_cnt].point_cnt);
+}
+
+void middle_down(int x1, int y1)
+{
+       GLuint point_cnt;
+        (void) x1;
+        (void) y1;
+
+       point_cnt=contours[contour_cnt].point_cnt;
+       if(point_cnt>2)
+       {
+               glBegin(GL_LINES);
+               glVertex2iv(contours[contour_cnt].p[0]);
+               glVertex2iv(contours[contour_cnt].p[point_cnt-1]);
+               contours[contour_cnt].p[point_cnt][0]= -1;
+               glEnd();
+               glFinish();
+               contour_cnt++;
+               contours[contour_cnt].point_cnt=0;
+       }
+}
+
+void mouse_clicked(int button,int state,int x,int y)
+{
+       x-= x%10;
+       y-= y%10;
+       switch(button)
+       {
+               case GLUT_LEFT_BUTTON:
+                       if(state==GLUT_DOWN)
+                               left_down(x,y);
+                       break;
+               case GLUT_MIDDLE_BUTTON:
+                       if(state==GLUT_DOWN)
+                               middle_down(x,y);
+                       break;
+       }
+}
+
+void display(void)
+{
+       GLuint i,j;
+       GLuint point_cnt;
+
+    glClear(GL_COLOR_BUFFER_BIT);
+    switch(mode)
+    {
+       case DEFINE:
+                       /* draw grid */
+                       glColor3f (0.6,0.5,0.5);
+                       glBegin(GL_LINES);
+                       for(i=0;i<width;i+=10)
+                               for(j=0;j<height;j+=10)
+                               {
+                                       glVertex2i(0,j);
+                                       glVertex2i(width,j);
+                                       glVertex2i(i,height);
+                                       glVertex2i(i,0);
+                       }
+                       glColor3f (1.0, 1.0, 0.0);
+                       for(i=0;i<=contour_cnt;i++)
+                       {
+                               point_cnt=contours[i].point_cnt;
+                               glBegin(GL_LINES);
+                               switch(point_cnt)
+                               {
+                                       case 0:
+                                               break;
+                                       case 1:
+                                               glVertex2iv(contours[i].p[0]);
+                                               glVertex2iv(contours[i].p[0]);
+                                               break;
+                                       case 2:
+                                               glVertex2iv(contours[i].p[0]);
+                                               glVertex2iv(contours[i].p[1]);
+                                               break;
+                                       default:
+                                               --point_cnt;
+                                               for(j=0;j<point_cnt;j++)
+                                               {
+                                                       glVertex2iv(contours[i].p[j]);
+                                                       glVertex2iv(contours[i].p[j+1]);
+                                               }
+                                               if(contours[i].p[j+1][0]== -1)
+                                               {
+                                                       glVertex2iv(contours[i].p[0]);
+                                                       glVertex2iv(contours[i].p[j]);
+                                               }
+                                               break;
+                               }
+                               glEnd();
+                       }
+                       glFinish();
+                       break;
+               case TESSELATED:
+                       /* draw lines */
+                       tesse();
+                       break;
+       }
+
+    glColor3f (1.0, 1.0, 0.0);
+}
+
+void clear( void )
+{
+    contour_cnt=0;
+    contours[0].point_cnt=0;
+       glutMouseFunc(mouse_clicked);
+       mode=DEFINE;
+       display();
+}
+
+void quit( void )
+{
+       exit(0);
+}
+
+void menu_selected(int entry)
+{
+       switch(entry)
+       {
+               case CLEAR:
+                       clear();
+                       break;
+               case TESSELATE:
+                       tesse();
+                       break;
+               case QUIT:
+                       quit();
+                       break;
+       }
+}
+
+void key_pressed(unsigned char key,int x,int y)
+{
+       (void) x;
+       (void) y;
+       switch(key)
+       {
+               case 't':
+               case 'T':
+                       tesse();
+                       glFinish();
+                       break;
+               case 'q':
+               case 'Q':
+                       quit();
+                       break;
+               case 'c':
+               case 'C':
+                       clear();
+                       break;
+       }
+}
+
+void myinit (void) 
+{
+/*  clear background to gray   */
+    glClearColor (0.4, 0.4, 0.4, 0.0);
+    glShadeModel (GL_FLAT);    
+
+       menu=glutCreateMenu(menu_selected);
+       glutAddMenuEntry("clear",CLEAR);
+       glutAddMenuEntry("tesselate",TESSELATE);
+       glutAddMenuEntry("quit",QUIT);
+       glutAttachMenu(GLUT_RIGHT_BUTTON);
+       glutMouseFunc(mouse_clicked);
+       glutKeyboardFunc(key_pressed);
+    contour_cnt=0;
+    glPolygonMode(GL_FRONT,GL_FILL);
+    mode=DEFINE;
+}
+
+static void reshape(GLsizei w, GLsizei h)
+{
+    glViewport(0, 0, w, h);
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    glOrtho(0.0, (GLdouble)w, 0.0, (GLdouble)h, -1.0, 1.0);
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
+    set_screen_wh(w,h);
+}
+
+
+static void usage( void )
+{
+   printf("Use left mouse button to place vertices.\n");
+   printf("Press middle mouse button when done.\n");
+   printf("Select tesselate from the pop-up menu.\n");
+}
+
+
+/*  Main Loop
+ *  Open window with initial window size, title bar, 
+ *  RGBA display mode, and handle input events.
+ */
+int main(int argc, char** argv)
+{
+   usage();
+   glutInit(&argc, argv);
+   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
+   glutInitWindowSize (400, 400);
+   glutCreateWindow (argv[0]);
+   myinit ();
+   glutDisplayFunc(display);
+   glutReshapeFunc(reshape);
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/demos/texcyl.c b/progs/demos/texcyl.c
new file mode 100644 (file)
index 0000000..0358d29
--- /dev/null
@@ -0,0 +1,261 @@
+/* $Id: texcyl.c,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
+
+/*
+ * Textured cylinder demo: lighting, texturing, reflection mapping.
+ * Brian Paul  May 1997  This program is in the public domain.
+ */
+
+/*
+ * $Log: texcyl.c,v $
+ * Revision 1.1  1999/08/19 00:55:40  jtg
+ * Initial revision
+ *
+ * Revision 3.3  1999/03/28 18:24:37  brianp
+ * minor clean-up
+ *
+ * Revision 3.2  1998/11/05 04:34:04  brianp
+ * moved image files to ../images/ directory
+ *
+ * Revision 3.1  1998/06/23 03:16:51  brianp
+ * added Point/Linear sampling menu items
+ *
+ * Revision 3.0  1998/02/14 18:42:29  brianp
+ * initial rev
+ *
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <GL/glut.h>
+
+#include "../util/readtex.c"   /* I know, this is a hack. */
+
+#define TEXTURE_FILE "../images/reflect.rgb"
+
+#define LIT 1
+#define TEXTURED 2
+#define REFLECT 3
+#define ANIMATE 10
+#define POINT_FILTER 20
+#define LINEAR_FILTER 21
+#define QUIT 100
+
+static GLuint CylinderObj = 0;
+static GLboolean Animate = GL_TRUE;
+
+static GLfloat Xrot = 0.0, Yrot = 0.0, Zrot = 0.0;
+static GLfloat DXrot = 1.0, DYrot = 2.5;
+
+
+static void Idle( void )
+{
+   if (Animate) {
+      Xrot += DXrot;
+      Yrot += DYrot;
+      glutPostRedisplay();
+   }
+}
+
+
+static void Display( void )
+{
+   glClear( GL_COLOR_BUFFER_BIT );
+
+   glPushMatrix();
+   glRotatef(Xrot, 1.0, 0.0, 0.0);
+   glRotatef(Yrot, 0.0, 1.0, 0.0);
+   glRotatef(Zrot, 0.0, 0.0, 1.0);
+   glScalef(5.0, 5.0, 5.0);
+   glCallList(CylinderObj);
+
+   glPopMatrix();
+
+   glutSwapBuffers();
+}
+
+
+static void Reshape( int width, int height )
+{
+   glViewport( 0, 0, width, height );
+   glMatrixMode( GL_PROJECTION );
+   glLoadIdentity();
+   glFrustum( -1.0, 1.0, -1.0, 1.0, 10.0, 100.0 );
+   glMatrixMode( GL_MODELVIEW );
+   glLoadIdentity();
+   glTranslatef( 0.0, 0.0, -70.0 );
+}
+
+
+static void SetMode(GLuint m)
+{
+   /* disable everything */
+   glDisable(GL_LIGHTING);
+   glDisable(GL_TEXTURE_2D);
+   glDisable(GL_TEXTURE_GEN_S);
+   glDisable(GL_TEXTURE_GEN_T);
+
+   /* enable what's needed */
+   if (m==LIT) {
+      glEnable(GL_LIGHTING);
+   }
+   else if (m==TEXTURED) {
+      glEnable(GL_TEXTURE_2D);
+   }
+   else if (m==REFLECT) {
+      glEnable(GL_TEXTURE_2D);
+      glEnable(GL_TEXTURE_GEN_S);
+      glEnable(GL_TEXTURE_GEN_T);
+   }
+}
+
+
+static void ModeMenu(int entry)
+{
+   if (entry==ANIMATE) {
+      Animate = !Animate;
+   }
+   else if (entry==POINT_FILTER) {
+      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+   }
+   else if (entry==LINEAR_FILTER) {
+      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+   }
+   else if (entry==QUIT) {
+      exit(0);
+   }
+   else {
+      SetMode(entry);
+   }
+   glutPostRedisplay();
+}
+
+
+static void Key( unsigned char key, int x, int y )
+{
+   (void) x;
+   (void) y;
+   switch (key) {
+      case 27:
+         exit(0);
+         break;
+   }
+   glutPostRedisplay();
+}
+
+
+static void SpecialKey( int key, int x, int y )
+{
+   float step = 3.0;
+   (void) x;
+   (void) y;
+
+   switch (key) {
+      case GLUT_KEY_UP:
+         Xrot += step;
+         break;
+      case GLUT_KEY_DOWN:
+         Xrot -= step;
+         break;
+      case GLUT_KEY_LEFT:
+         Yrot += step;
+         break;
+      case GLUT_KEY_RIGHT:
+         Yrot -= step;
+         break;
+   }
+   glutPostRedisplay();
+}
+
+
+static void Init( void )
+{
+   GLUquadricObj *q = gluNewQuadric();
+   CylinderObj = glGenLists(1);
+   glNewList(CylinderObj, GL_COMPILE);
+
+   glTranslatef(0.0, 0.0, -1.0);
+
+   /* cylinder */
+   gluQuadricNormals(q, GL_SMOOTH);
+   gluQuadricTexture(q, GL_TRUE);
+   gluCylinder(q, 0.6, 0.6, 2.0, 24, 1);
+
+   /* end cap */
+   glTranslatef(0.0, 0.0, 2.0);
+   gluDisk(q, 0.0, 0.6, 24, 1);
+
+   /* other end cap */
+   glTranslatef(0.0, 0.0, -2.0);
+   gluQuadricOrientation(q, GLU_INSIDE);
+   gluDisk(q, 0.0, 0.6, 24, 1);
+
+   glEndList();
+   gluDeleteQuadric(q);
+
+   /* lighting */
+   glEnable(GL_LIGHTING);
+   {
+      GLfloat gray[4] = {0.2, 0.2, 0.2, 1.0};
+      GLfloat white[4] = {1.0, 1.0, 1.0, 1.0};
+      GLfloat teal[4] = { 0.0, 1.0, 0.8, 1.0 };
+      glMaterialfv(GL_FRONT, GL_DIFFUSE, teal);
+      glLightfv(GL_LIGHT0, GL_AMBIENT, gray);
+      glLightfv(GL_LIGHT0, GL_DIFFUSE, white);
+      glEnable(GL_LIGHT0);
+   }
+
+   /* fitering = nearest, initially */
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
+   glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
+
+   glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
+   glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
+
+   if (!LoadRGBMipmaps(TEXTURE_FILE, GL_RGB)) {
+      printf("Error: couldn't load texture image\n");
+      exit(1);
+   }
+
+   glEnable(GL_CULL_FACE);  /* don't need Z testing for convex objects */
+
+   SetMode(LIT);
+}
+
+
+int main( int argc, char *argv[] )
+{
+   glutInit( &argc, argv );
+   glutInitWindowSize( 400, 400 );
+
+   glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
+
+   glutCreateWindow(argv[0] );
+
+   Init();
+
+   glutReshapeFunc( Reshape );
+   glutKeyboardFunc( Key );
+   glutSpecialFunc( SpecialKey );
+   glutDisplayFunc( Display );
+   glutIdleFunc( Idle );
+
+   glutCreateMenu(ModeMenu);
+   glutAddMenuEntry("Lit", LIT);
+   glutAddMenuEntry("Textured", TEXTURED);
+   glutAddMenuEntry("Reflect", REFLECT);
+   glutAddMenuEntry("Point Filtered", POINT_FILTER);
+   glutAddMenuEntry("Linear Filtered", LINEAR_FILTER);
+   glutAddMenuEntry("Toggle Animation", ANIMATE);
+   glutAddMenuEntry("Quit", QUIT);
+   glutAttachMenu(GLUT_RIGHT_BUTTON);
+
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/demos/texobj.c b/progs/demos/texobj.c
new file mode 100644 (file)
index 0000000..673923c
--- /dev/null
@@ -0,0 +1,289 @@
+/* $Id: texobj.c,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
+
+/*
+ * Example of using the 1.1 texture object functions.
+ * Also, this demo utilizes Mesa's fast texture map path.
+ *
+ * Brian Paul   June 1996   This file is in the public domain.
+ */
+
+
+/*
+ * $Log: texobj.c,v $
+ * Revision 1.1  1999/08/19 00:55:40  jtg
+ * Initial revision
+ *
+ * Revision 3.1  1999/03/28 18:24:37  brianp
+ * minor clean-up
+ *
+ * Revision 3.0  1998/02/14 18:42:29  brianp
+ * initial rev
+ *
+ */
+
+
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include "GL/glut.h"
+
+static GLuint Window = 0;
+
+static GLuint TexObj[2];
+static GLfloat Angle = 0.0f;
+static GLboolean HaveTexObj = GL_FALSE;
+
+
+#if defined(GL_VERSION_1_1)
+#  define TEXTURE_OBJECT 1
+#elif defined(GL_EXT_texture_object)
+#  define TEXTURE_OBJECT 1
+#  define glBindTexture(A,B)     glBindTextureEXT(A,B)
+#  define glGenTextures(A,B)     glGenTexturesEXT(A,B)
+#  define glDeleteTextures(A,B)  glDeleteTexturesEXT(A,B)
+#endif
+
+
+
+
+static void draw( void )
+{
+   glDepthFunc(GL_EQUAL);
+   /*   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );*/
+   glClear( GL_COLOR_BUFFER_BIT );
+
+   glColor3f( 1.0, 1.0, 1.0 );
+
+   /* draw first polygon */
+   glPushMatrix();
+   glTranslatef( -1.0, 0.0, 0.0 );
+   glRotatef( Angle, 0.0, 0.0, 1.0 );
+   if (HaveTexObj) {
+#ifdef TEXTURE_OBJECT
+      glBindTexture( GL_TEXTURE_2D, TexObj[0] );
+#endif
+   }
+   else {
+      glCallList( TexObj[0] );
+   }
+   glBegin( GL_POLYGON );
+   glTexCoord2f( 0.0, 0.0 );   glVertex2f( -1.0, -1.0 );
+   glTexCoord2f( 1.0, 0.0 );   glVertex2f(  1.0, -1.0 );
+   glTexCoord2f( 1.0, 1.0 );   glVertex2f(  1.0,  1.0 );
+   glTexCoord2f( 0.0, 1.0 );   glVertex2f( -1.0,  1.0 );
+   glEnd();
+   glPopMatrix();
+
+   /* draw second polygon */
+   glPushMatrix();
+   glTranslatef( 1.0, 0.0, 0.0 );
+   glRotatef( Angle-90.0, 0.0, 1.0, 0.0 );
+   if (HaveTexObj) {
+#ifdef TEXTURE_OBJECT
+      glBindTexture( GL_TEXTURE_2D, TexObj[1] );
+#endif
+   }
+   else {
+      glCallList( TexObj[0] );
+   }
+   glBegin( GL_POLYGON );
+   glTexCoord2f( 0.0, 0.0 );   glVertex2f( -1.0, -1.0 );
+   glTexCoord2f( 1.0, 0.0 );   glVertex2f(  1.0, -1.0 );
+   glTexCoord2f( 1.0, 1.0 );   glVertex2f(  1.0,  1.0 );
+   glTexCoord2f( 0.0, 1.0 );   glVertex2f( -1.0,  1.0 );
+   glEnd();
+   glPopMatrix();
+
+   glutSwapBuffers();
+}
+
+
+
+static void idle( void )
+{
+   Angle += 2.0;
+   glutPostRedisplay();
+}
+
+
+
+/* change view Angle, exit upon ESC */
+static void key(unsigned char k, int x, int y)
+{
+   (void) x;
+   (void) y;
+   switch (k) {
+      case 27:
+#ifdef TEXTURE_OBJECT
+         glDeleteTextures( 2, TexObj );
+#endif
+         glutDestroyWindow(Window);
+         exit(0);
+   }
+}
+
+
+
+/* new window size or exposure */
+static void reshape( int width, int height )
+{
+   glViewport(0, 0, (GLint)width, (GLint)height);
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   /*   glOrtho( -3.0, 3.0, -3.0, 3.0, -10.0, 10.0 );*/
+   glFrustum( -2.0, 2.0, -2.0, 2.0, 6.0, 20.0 );
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+   glTranslatef( 0.0, 0.0, -8.0 );
+}
+
+
+static void init( void )
+{
+   static int width=8, height=8;
+   static GLubyte tex1[] = {
+     0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 1, 0, 0, 0,
+     0, 0, 0, 1, 1, 0, 0, 0,
+     0, 0, 0, 0, 1, 0, 0, 0,
+     0, 0, 0, 0, 1, 0, 0, 0,
+     0, 0, 0, 0, 1, 0, 0, 0,
+     0, 0, 0, 1, 1, 1, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0 };
+
+   static GLubyte tex2[] = {
+     0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 2, 2, 0, 0, 0,
+     0, 0, 2, 0, 0, 2, 0, 0,
+     0, 0, 0, 0, 0, 2, 0, 0,
+     0, 0, 0, 0, 2, 0, 0, 0,
+     0, 0, 0, 2, 0, 0, 0, 0,
+     0, 0, 2, 2, 2, 2, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0 };
+
+   GLubyte tex[64][3];
+   GLint i, j;
+
+
+   glDisable( GL_DITHER );
+
+   /* Setup texturing */
+   glEnable( GL_TEXTURE_2D );
+   glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL );
+   glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST );
+
+
+   /* generate texture object IDs */
+   if (HaveTexObj) {
+#ifdef TEXTURE_OBJECT
+      glGenTextures( 2, TexObj );
+#endif
+   }
+   else {
+      TexObj[0] = glGenLists(2);
+      TexObj[1] = TexObj[0]+1;
+   }
+
+   /* setup first texture object */
+   if (HaveTexObj) {
+#ifdef TEXTURE_OBJECT
+      glBindTexture( GL_TEXTURE_2D, TexObj[0] );
+#endif
+   }
+   else {
+      glNewList( TexObj[0], GL_COMPILE );
+   }
+   /* red on white */
+   for (i=0;i<height;i++) {
+      for (j=0;j<width;j++) {
+         int p = i*width+j;
+         if (tex1[(height-i-1)*width+j]) {
+            tex[p][0] = 255;   tex[p][1] = 0;     tex[p][2] = 0;
+         }
+         else {
+            tex[p][0] = 255;   tex[p][1] = 255;   tex[p][2] = 255;
+         }
+      }
+   }
+
+   glTexImage2D( GL_TEXTURE_2D, 0, 3, width, height, 0,
+                 GL_RGB, GL_UNSIGNED_BYTE, tex );
+   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
+   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
+   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
+   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
+   if (!HaveTexObj) {
+      glEndList();
+   }
+   /* end of texture object */
+
+   /* setup second texture object */
+   if (HaveTexObj) {
+#ifdef TEXTURE_OBJECT
+      glBindTexture( GL_TEXTURE_2D, TexObj[1] );
+#endif
+   }
+   else {
+      glNewList( TexObj[1], GL_COMPILE );
+   }
+   /* green on blue */
+   for (i=0;i<height;i++) {
+      for (j=0;j<width;j++) {
+         int p = i*width+j;
+         if (tex2[(height-i-1)*width+j]) {
+            tex[p][0] = 0;     tex[p][1] = 255;   tex[p][2] = 0;
+         }
+         else {
+            tex[p][0] = 0;     tex[p][1] = 0;     tex[p][2] = 255;
+         }
+      }
+   }
+   glTexImage2D( GL_TEXTURE_2D, 0, 3, width, height, 0,
+                 GL_RGB, GL_UNSIGNED_BYTE, tex );
+   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
+   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
+   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
+   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
+   if (!HaveTexObj) {
+      glEndList();
+   }
+   /* end texture object */
+
+}
+
+
+
+int main( int argc, char *argv[] )
+{
+   glutInitWindowPosition(0, 0);
+   glutInitWindowSize(300, 300);
+   glutInitDisplayMode( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE );
+
+   Window = glutCreateWindow("Texture Objects");
+   if (!Window) {
+      exit(1);
+   }
+
+   /* check that renderer has the GL_EXT_texture_object extension
+    * or supports OpenGL 1.1
+    */
+#ifdef TEXTURE_OBJECT
+   {
+      char *exten = (char *) glGetString( GL_EXTENSIONS );
+      char *version = (char *) glGetString( GL_VERSION );
+      if (   strstr( exten, "GL_EXT_texture_object" )
+          || strncmp( version, "1.1", 3 )==0 ) {
+         HaveTexObj = GL_TRUE;
+      }
+   }
+#endif
+
+   init();
+
+   glutReshapeFunc( reshape );
+   glutKeyboardFunc( key );
+   glutIdleFunc( idle );
+   glutDisplayFunc( draw );
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/demos/trispd.c b/progs/demos/trispd.c
new file mode 100644 (file)
index 0000000..a836c9d
--- /dev/null
@@ -0,0 +1,277 @@
+/* $Id: trispd.c,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
+
+/*
+ * Simple GLUT program to measure triangle strip rendering speed.
+ * Brian Paul  February 15, 1997  This file is in the public domain.
+ */
+
+/*
+ * $Log: trispd.c,v $
+ * Revision 1.1  1999/08/19 00:55:40  jtg
+ * Initial revision
+ *
+ * Revision 3.4  1999/03/28 18:24:37  brianp
+ * minor clean-up
+ *
+ * Revision 3.3  1999/03/18 08:16:52  joukj
+ *
+ *     cmpstr needs string.h to included to avoid warnings
+ *
+ * Revision 3.2  1998/07/08 03:02:00  brianp
+ * added Marten Stromberg's texture options
+ *
+ * Revision 3.1  1998/06/29 02:36:58  brianp
+ * removed unneeded includes
+ *
+ * Revision 3.0  1998/02/14 18:42:29  brianp
+ * initial rev
+ *
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+#include <GL/glut.h>
+
+
+static float MinPeriod = 2.0;   /* 2 seconds */
+static float Width = 400.0;
+static float Height = 400.0;
+static int Loops = 1;
+static int Size = 50;
+static int Texture = 0;
+
+
+
+static void Idle( void )
+{
+   glutPostRedisplay();
+}
+
+
+static void Display( void )
+{
+   float x, y;
+   float xStep;
+   float yStep;
+   double t0, t1;
+   double triRate;
+   double pixelRate;
+   int triCount;
+   int i;
+   float red[3] = { 1.0, 0.0, 0.0 };
+   float blue[3] = { 0.0, 0.0, 1.0 };
+
+   xStep = yStep = sqrt( 2.0 * Size );
+
+   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+
+   triCount = 0;
+   t0 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
+   if (Texture) {
+      float uStep = xStep / Width;
+      float vStep = yStep / Height;
+      float u, v;
+      for (i=0; i<Loops; i++) {
+        for (y=1.0, v=0.0f; y<Height-yStep; y+=yStep, v+=vStep) {
+           glBegin(GL_TRIANGLE_STRIP);
+           for (x=1.0, u=0.0f; x<Width; x+=xStep, u+=uStep) {
+              glColor3fv(red);
+              glTexCoord2f(u, v);          
+              glVertex2f(x, y);
+              glColor3fv(blue);
+              glTexCoord2f(u, v+vStep);
+              glVertex2f(x, y+yStep);
+              triCount += 2;
+           }
+           glEnd();
+           triCount -= 2;
+        }
+      }
+   }
+   else {
+      for (i=0; i<Loops; i++) {
+        for (y=1.0; y<Height-yStep; y+=yStep) {
+           glBegin(GL_TRIANGLE_STRIP);
+           for (x=1.0; x<Width; x+=xStep) {
+              glColor3fv(red);
+              glVertex2f(x, y);
+              glColor3fv(blue);
+              glVertex2f(x, y+yStep);
+              triCount += 2;
+           }
+           glEnd();
+           triCount -= 2;
+        }
+      }
+   }
+   t1 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
+   
+   if (t1-t0 < MinPeriod) {
+      /* Next time draw more triangles to get longer elapsed time */
+      Loops *= 2;
+      return;
+   }
+
+   triRate = triCount / (t1-t0);
+   pixelRate = triRate * Size;
+   printf("Rate: %d tri in %gs = %g tri/s  %d pixels/s\n",
+          triCount, t1-t0, triRate, (int)pixelRate);
+
+   glutSwapBuffers();
+}
+
+
+static void Reshape( int width, int height )
+{
+   Width = width;
+   Height = height;
+   glViewport( 0, 0, width, height );
+   glMatrixMode( GL_PROJECTION );
+   glLoadIdentity();
+   glOrtho(0.0, width, 0.0, height, -1.0, 1.0);
+   glMatrixMode( GL_MODELVIEW );
+   glLoadIdentity();
+}
+
+
+static void Key( unsigned char key, int x, int y )
+{
+   (void) x;
+   (void) y;
+   switch (key) {
+      case 27:
+         exit(0);
+         break;
+   }
+   glutPostRedisplay();
+}
+
+
+static void LoadTex(int comp, int filter)
+{
+   GLubyte *pixels;
+   int x, y;
+   pixels = malloc(4*256*256);
+   for (y = 0; y < 256; ++y)
+      for (x = 0; x < 256; ++x) {
+        pixels[(y*256+x)*4+0] = (int)(128.5 + 127.0 * cos(0.024544 * x));
+        pixels[(y*256+x)*4+1] = 255;
+        pixels[(y*256+x)*4+2] = (int)(128.5 + 127.0 * cos(0.024544 * y));
+        pixels[(y*256+x)*4+3] = 255;
+      }
+   glEnable(GL_TEXTURE_2D);
+   glTexImage2D(GL_TEXTURE_2D, 0, comp, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+   printf("Texture: GL_MODULATE, %d comps, %s\n", comp, filter == GL_NEAREST ? "GL_NEAREST" : "GL_LINEAR");
+}
+
+
+static void Init( int argc, char *argv[] )
+{
+   GLint shade;
+   GLint rBits, gBits, bBits;
+   int filter = GL_NEAREST, comp = 3;
+
+   int i;
+   for (i=1; i<argc; i++) {
+      if (strcmp(argv[i],"-dither")==0)
+         glDisable(GL_DITHER);
+      else if (strcmp(argv[i],"+dither")==0)
+         glEnable(GL_DITHER);
+      else if (strcmp(argv[i],"+smooth")==0)
+         glShadeModel(GL_SMOOTH);
+      else if (strcmp(argv[i],"+flat")==0)
+         glShadeModel(GL_FLAT);
+      else if (strcmp(argv[i],"+depth")==0)
+         glEnable(GL_DEPTH_TEST);
+      else if (strcmp(argv[i],"-depth")==0)
+         glDisable(GL_DEPTH_TEST);
+      else if (strcmp(argv[i],"-size")==0) {
+         Size = atoi(argv[i+1]);
+         i++;
+      }
+      else if (strcmp(argv[i],"-texture")==0)
+        Texture = 0;
+      else if (strcmp(argv[i],"+texture")==0)
+        Texture = 1;
+      else if (strcmp(argv[i],"-linear")==0)
+        filter = GL_NEAREST;
+      else if (strcmp(argv[i],"+linear")==0)
+        filter = GL_LINEAR;
+      else if (strcmp(argv[i],"-persp")==0)
+        glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
+      else if (strcmp(argv[i],"+persp")==0)
+        glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
+      else if (strcmp(argv[i],"-comp")==0) {
+        comp = atoi(argv[i+1]);
+        i++;
+      }
+      else
+         printf("Unknown option: %s\n", argv[i]);
+   }
+
+   glGetIntegerv(GL_SHADE_MODEL, &shade);
+
+   printf("Dither: %s\n", glIsEnabled(GL_DITHER) ? "on" : "off");
+   printf("ShadeModel: %s\n", (shade==GL_FLAT) ? "flat" : "smooth");
+   printf("DepthTest: %s\n", glIsEnabled(GL_DEPTH_TEST) ? "on" : "off");
+   printf("Size: %d pixels\n", Size);
+
+   if (Texture)
+      LoadTex(comp, filter);
+
+   glGetIntegerv(GL_RED_BITS, &rBits);
+   glGetIntegerv(GL_GREEN_BITS, &gBits);
+   glGetIntegerv(GL_BLUE_BITS, &bBits);
+   printf("RedBits: %d  GreenBits: %d  BlueBits: %d\n", rBits, gBits, bBits);
+}
+
+
+static void Help( const char *program )
+{
+   printf("%s options:\n", program);
+   printf("  +/-dither      enable/disable dithering\n");
+   printf("  +/-depth       enable/disable depth test\n");
+   printf("  +flat          flat shading\n");
+   printf("  +smooth        smooth shading\n");
+   printf("  -size pixels   specify pixels/triangle\n");
+   printf("  +/-texture     enable/disable texture\n");
+   printf("  -comp n        texture format\n");
+   printf("  +/-linear      bilinear texture filter\n");
+   printf("  +/-persp       perspective correction hint\n");
+}
+
+
+int main( int argc, char *argv[] )
+{
+   printf("For options:  %s -help\n", argv[0]);
+   glutInit( &argc, argv );
+   glutInitWindowSize( (int) Width, (int) Height );
+   glutInitWindowPosition( 0, 0 );
+
+   glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
+
+   glutCreateWindow( argv[0] );
+
+   if (argc==2 && strcmp(argv[1],"-help")==0) {
+      Help(argv[0]);
+      return 0;
+   }
+
+   Init( argc, argv );
+
+   glutReshapeFunc( Reshape );
+   glutKeyboardFunc( Key );
+   glutDisplayFunc( Display );
+   glutIdleFunc( Idle );
+
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/demos/winpos.c b/progs/demos/winpos.c
new file mode 100644 (file)
index 0000000..a3f931c
--- /dev/null
@@ -0,0 +1,128 @@
+/* $Id: winpos.c,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
+
+/*
+ * Example of how to use the GL_MESA_window_pos extension.
+ * Brian Paul   This file is in the public domain.
+ */
+
+
+/*
+ * $Log: winpos.c,v $
+ * Revision 1.1  1999/08/19 00:55:40  jtg
+ * Initial revision
+ *
+ * Revision 3.3  1999/03/28 18:24:37  brianp
+ * minor clean-up
+ *
+ * Revision 3.2  1998/11/05 04:34:04  brianp
+ * moved image files to ../images/ directory
+ *
+ * Revision 3.1  1998/02/22 16:36:10  brianp
+ * changed image file and set unpack alignment to 1
+ *
+ * Revision 3.0  1998/02/14 18:42:29  brianp
+ * initial rev
+ *
+ */
+
+
+#include <math.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "GL/glut.h"
+
+#include "../util/readtex.c"  /* a hack, I know */
+
+#define IMAGE_FILE "../images/girl.rgb"
+
+
+#ifndef M_PI
+#  define M_PI 3.14159265
+#endif
+
+
+
+static GLubyte *Image;
+static int ImgWidth, ImgHeight;
+static GLenum ImgFormat;
+
+
+
+static void draw( void )
+{
+   GLfloat angle;
+   char *extensions;
+
+   extensions = (char *) glGetString( GL_EXTENSIONS );
+   if (strstr( extensions, "GL_MESA_window_pos")==NULL) {
+      printf("Sorry, GL_MESA_window_pos extension not available.\n");
+      return;
+   }
+
+   glClear( GL_COLOR_BUFFER_BIT );
+
+   for (angle = -45.0; angle <= 135.0; angle += 10.0) {
+      GLfloat x = 50.0 + 200.0 * cos( angle * M_PI / 180.0 );
+      GLfloat y = 50.0 + 200.0 * sin( angle * M_PI / 180.0 );
+
+      /* Don't need to worry about the modelview or projection matrices!!! */
+#ifdef GL_MESA_window_pos
+      glWindowPos2fMESA( x, y );
+#endif
+      glDrawPixels( ImgWidth, ImgHeight, ImgFormat, GL_UNSIGNED_BYTE, Image );
+   }
+}
+
+
+
+
+static void key( unsigned char key, int x, int y )
+{
+   (void) x;
+   (void) y;
+   switch (key) {
+      case 27:
+         exit(0);
+   }
+}
+
+
+
+/* new window size or exposure */
+static void reshape( int width, int height )
+{
+   glViewport(0, 0, (GLint)width, (GLint)height);
+}
+
+
+static void init( void )
+{
+   Image = LoadRGBImage( IMAGE_FILE, &ImgWidth, &ImgHeight, &ImgFormat );
+   if (!Image) {
+      printf("Couldn't read %s\n", IMAGE_FILE);
+      exit(0);
+   }
+   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+}
+
+
+
+int main( int argc, char *argv[] )
+{
+   glutInitWindowPosition(0, 0);
+   glutInitWindowSize(500, 500);
+   glutInitDisplayMode( GLUT_RGB );
+
+   if (glutCreateWindow("winpos") <= 0) {
+      exit(0);
+   }
+
+   init();
+
+   glutReshapeFunc( reshape );
+   glutKeyboardFunc( key );
+   glutDisplayFunc( draw );
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/images/girl.rgb b/progs/images/girl.rgb
new file mode 100644 (file)
index 0000000..8901e45
Binary files /dev/null and b/progs/images/girl.rgb differ
diff --git a/progs/images/reflect.rgb b/progs/images/reflect.rgb
new file mode 100644 (file)
index 0000000..45319e9
Binary files /dev/null and b/progs/images/reflect.rgb differ
diff --git a/progs/images/tile.rgb b/progs/images/tile.rgb
new file mode 100644 (file)
index 0000000..5c1c73b
Binary files /dev/null and b/progs/images/tile.rgb differ
diff --git a/progs/redbook/Imakefile b/progs/redbook/Imakefile
new file mode 100644 (file)
index 0000000..23a6b16
--- /dev/null
@@ -0,0 +1,222 @@
+LOCAL_LIBRARIES = $(XLIB) $(TOP)\lib\Mesaaux.a $(TOP)\lib\Mesaglu.a $(TOP)\lib\MesaGL.a\r
+\r
+INCLUDES = -I$(TOP)\include\r
+\r
+SRCS = accanti.c \\r
+       accnot.c \\r
+       accpersp.c \\r
+       accum.c \\r
+       aim.c \\r
+       alpha.c \\r
+       alpha3D.c \\r
+       anti.c \\r
+       antiindex.c \\r
+       antipindex.c \\r
+       antipoint.c \\r
+       antipoly.c \\r
+       bezcurve.c \\r
+       bezmesh.c \\r
+       bezsurf.c \\r
+       checker.c \\r
+       checker2.c \\r
+       chess.c \\r
+       clip.c \\r
+       colormat.c \\r
+       cone.c \\r
+       cube.c \\r
+       curve.c \\r
+       depthcue.c \\r
+       disk.c \\r
+       dof.c \\r
+       dofnot.c \\r
+       double.c \\r
+       drawf.c \\r
+       feedback.c \\r
+       fog.c \\r
+       fogindex.c \\r
+       font.c \\r
+       light.c \\r
+       linelist.c \\r
+       lines.c \\r
+       list.c \\r
+       list2.c \\r
+       maplight.c \\r
+       material.c \\r
+       mipmap.c \\r
+       model.c \\r
+       movelight.c \\r
+       nurbs.c \\r
+       pickdepth.c \\r
+       pickline.c \\r
+       picksquare.c \\r
+       plane.c \\r
+       planet.c \\r
+       planetup.c \\r
+       polys.c \\r
+       robot.c \\r
+       sccolorlight.c \\r
+       scene.c \\r
+       scenebamb.c \\r
+       sceneflat.c \\r
+       select.c \\r
+       simple.c \\r
+       smooth.c \\r
+       sphere.c \\r
+       stencil.c \\r
+       stroke.c \\r
+       surface.c \\r
+       tea.c \\r
+       teaambient.c \\r
+       teapots.c \\r
+       texgen.c \\r
+       texturesurf.c \\r
+       trim.c \\r
+       xfont.c\r
+\r
+PROGRAMS = ProgramTargetName(accanti) \\r
+       ProgramTargetName(accnot) \\r
+       ProgramTargetName(accpersp) \\r
+       ProgramTargetName(accum) \\r
+       ProgramTargetName(aim) \\r
+       ProgramTargetName(alpha) \\r
+       ProgramTargetName(alpha3D) \\r
+       ProgramTargetName(anti) \\r
+       ProgramTargetName(antiindex) \\r
+       ProgramTargetName(antipindex) \\r
+       ProgramTargetName(antipoint) \\r
+       ProgramTargetName(antipoly) \\r
+       ProgramTargetName(bezcurve) \\r
+       ProgramTargetName(bezmesh) \\r
+       ProgramTargetName(bezsurf) \\r
+       ProgramTargetName(checker) \\r
+       ProgramTargetName(checker2) \\r
+       ProgramTargetName(chess) \\r
+       ProgramTargetName(clip) \\r
+       ProgramTargetName(colormat) \\r
+       ProgramTargetName(cone) \\r
+       ProgramTargetName(cube) \\r
+       ProgramTargetName(curve) \\r
+       ProgramTargetName(depthcue) \\r
+       ProgramTargetName(disk) \\r
+       ProgramTargetName(dof) \\r
+       ProgramTargetName(dofnot) \\r
+       ProgramTargetName(double) \\r
+       ProgramTargetName(drawf) \\r
+       ProgramTargetName(feedback) \\r
+       ProgramTargetName(fog) \\r
+       ProgramTargetName(fogindex) \\r
+       ProgramTargetName(font) \\r
+       ProgramTargetName(light) \\r
+       ProgramTargetName(linelist) \\r
+       ProgramTargetName(lines) \\r
+       ProgramTargetName(list) \\r
+       ProgramTargetName(list2) \\r
+       ProgramTargetName(maplight) \\r
+       ProgramTargetName(material) \\r
+       ProgramTargetName(mipmap) \\r
+       ProgramTargetName(model) \\r
+       ProgramTargetName(movelight) \\r
+       ProgramTargetName(nurbs) \\r
+       ProgramTargetName(pickdepth) \\r
+       ProgramTargetName(pickline) \\r
+       ProgramTargetName(picksquare) \\r
+       ProgramTargetName(plane) \\r
+       ProgramTargetName(planet) \\r
+       ProgramTargetName(planetup) \\r
+       ProgramTargetName(polys) \\r
+       ProgramTargetName(robot) \\r
+       ProgramTargetName(sccolorlight) \\r
+       ProgramTargetName(scene) \\r
+       ProgramTargetName(scenebamb) \\r
+       ProgramTargetName(sceneflat) \\r
+       ProgramTargetName(select) \\r
+       ProgramTargetName(simple) \\r
+       ProgramTargetName(smooth) \\r
+       ProgramTargetName(sphere) \\r
+       ProgramTargetName(stencil) \\r
+       ProgramTargetName(stroke) \\r
+       ProgramTargetName(surface) \\r
+       ProgramTargetName(tea) \\r
+       ProgramTargetName(teaambient) \\r
+       ProgramTargetName(teapots) \\r
+       ProgramTargetName(texgen) \\r
+       ProgramTargetName(texturesurf) \\r
+       ProgramTargetName(trim) \\r
+       ProgramTargetName(xfont)\r
+\r
+AllTarget($(PROGRAMS))\r
+\r
+NormalProgramTarget(accanti,accanti.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(accnot,accnot.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(accpersp,accpersp.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(accum,accum.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(aim,aim.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(alpha,alpha.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(alpha3D,alpha3D.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(anti,anti.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(antiindex,antiindex.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(antipindex,antipindex.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(antipoint,antipoint.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(antipoly,antipoly.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(bezcurve,bezcurve.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(bezmesh,bezmesh.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(bezsurf,bezsurf.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(checker,checker.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(checker2,checker2.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(chess,chess.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(clip,clip.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(colormat,colormat.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(cone,cone.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(cube,cube.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(curve,curve.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(depthcue,depthcue.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(disk,disk.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(dof,dof.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(dofnot,dofnot.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(double,double.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(drawf,drawf.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(feedback,feedback.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(fog,fog.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(fogindex,fogindex.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(font,font.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(light,light.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(linelist,linelist.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(lines,lines.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(list,list.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(list2,list2.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(maplight,maplight.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(material,material.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(mipmap,mipmap.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(model,model.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(movelight,movelight.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(nurbs,nurbs.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(pickdepth,pickdepth.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(pickline,pickline.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(picksquare,picksquare.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(plane,plane.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(planet,planet.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(planetup,planetup.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(polys,polys.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(robot,robot.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(sccolorlight,sccolorlight.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(scene,scene.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(scenebamb,scenebamb.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(sceneflat,sceneflat.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(select,select.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(simple,simple.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(smooth,smooth.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(sphere,sphere.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(stencil,stencil.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(stroke,stroke.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(surface,surface.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(tea,tea.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(teaambient,teaambient.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(teapots,teapots.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(texgen,texgen.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(texturesurf,texturesurf.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(trim,trim.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(xfont,xfont.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+\r
+DependTarget()\r
\r
+\1a
\ No newline at end of file
diff --git a/progs/redbook/Makefile.BeOS-R4 b/progs/redbook/Makefile.BeOS-R4
new file mode 100644 (file)
index 0000000..f99e8ed
--- /dev/null
@@ -0,0 +1,70 @@
+# $Id: Makefile.BeOS-R4,v 1.1 1999/08/19 00:55:40 jtg Exp $
+
+# Makefile for OpenGL Programming Guide programs for BeOS R4
+# This file is in the public domain.
+
+
+# $Log: Makefile.BeOS-R4,v $
+# Revision 1.1  1999/08/19 00:55:40  jtg
+# Initial revision
+#
+# Revision 1.1  1999/02/25 02:13:06  brianp
+# initial check-in
+#
+
+
+##### MACROS #####
+
+INCDIR = ../include
+LIBDIR = ../lib
+
+GL_LIBS = -L$(LIBDIR) -L/boot/home/config/lib -Xlinker -rpath $(LIBDIR) -lbe -lglut -lMesaGLU -lMesaGL $(XLIBS)
+
+LIB_DEP = $(LIBDIR)/$(GL_LIB) $(LIBDIR)/$(GLU_LIB) $(LIBDIR)/$(GLUT_LIB)
+
+PROGS =  aaindex aapoly aargb accanti accpersp alpha alpha3D anti \
+       bezcurve bezmesh checker clip colormat cube depthcue dof \
+       double drawf feedback fog fogindex font hello image light \
+       lines list material mipmap model movelight nurbs pickdepth \
+       picksquare plane planet polyoff polys  robot sccolorlight \
+       scene scenebamb sceneflat select smooth stencil stroke surface \
+       teaambient teapots tess tesswind texbind texgen texprox texsub \
+       texturesurf torus unproject varray wrap        
+
+
+##### RULES #####
+
+.SUFFIXES:
+.SUFFIXES: .c
+
+.c: $(LIB_DEP)
+       $(CC) -I$(INCDIR) $(CFLAGS) $< $(GL_LIBS) -o $@
+
+
+
+##### TARGETS #####
+
+default:
+       @echo "Specify a target configuration"
+
+clean:
+       -rm *.o *~
+
+realclean:
+       -rm $(PROGS)
+       -rm *.o *~
+
+targets: $(PROGS)
+
+# execute all programs
+exec: $(PROGS)
+       @for prog in $(PROGS) ;                 \
+       do                                      \
+               echo -n "Running $$prog ..." ;  \
+               $$prog ;                        \
+               echo ;                          \
+       done
+
+
+include ../Make-config
+
diff --git a/progs/redbook/Makefile.X11 b/progs/redbook/Makefile.X11
new file mode 100644 (file)
index 0000000..129918c
--- /dev/null
@@ -0,0 +1,64 @@
+# $Id: Makefile.X11,v 1.1 1999/08/19 00:55:40 jtg Exp $
+
+# Mesa 3-D graphics library
+# Version:  3.1
+# Copyright (C) 1995-1998  Brian Paul
+
+# Makefile for programs from the OpenGL Programming Guide
+
+
+##### MACROS #####
+
+INCDIR = ../include
+LIBDIR = ../lib
+
+GL_LIBS = -L$(LIBDIR) -lglut -lGLU -lGL -lm $(XLIBS)
+
+LIB_DEP = $(LIBDIR)/$(GL_LIB) $(LIBDIR)/$(GLU_LIB) $(LIBDIR)/$(GLUT_LIB)
+
+PROGS = aaindex aapoly aargb accanti accpersp alpha alpha3D anti \
+       bezcurve bezmesh checker clip colormat cube depthcue dof \
+       double drawf feedback fog fogindex font hello image light \
+       lines list material mipmap model movelight nurbs pickdepth \
+       picksquare plane planet polyoff polys quadric robot sccolorlight \
+       scene scenebamb sceneflat select smooth stencil stroke surface \
+       teaambient teapots tess tesswind texbind texgen texprox texsub \
+       texturesurf torus trim unproject varray wrap 
+
+
+
+##### RULES #####
+
+.SUFFIXES:
+.SUFFIXES: .c
+
+.c: $(LIB_DEP)
+       $(CC) -I$(INCDIR) $(CFLAGS) $< $(GL_LIBS) -o $@
+
+
+
+##### TARGETS ######
+
+default:
+       @echo "Specify a target configuration"
+
+clean:
+       -rm *.o *~
+
+realclean:
+       -rm $(PROGS)
+       -rm *.o *~
+
+targets: $(PROGS)
+
+# execute all programs
+exec: $(PROGS)
+       @for prog in $(PROGS) ;                 \
+       do                                      \
+               echo -n "Running $$prog ..." ;  \
+               $$prog ;                        \
+               echo ;                          \
+       done
+
+
+include ../Make-config
diff --git a/progs/redbook/Makefile.win b/progs/redbook/Makefile.win
new file mode 100644 (file)
index 0000000..79c4f67
--- /dev/null
@@ -0,0 +1,81 @@
+# Makefile for Win32
+
+TOP = ..
+
+!include "$(TOP)/names.win"
+
+!include <win32.mak>
+
+SRCS= \
+   accanti.c \
+   accnot.c   \
+   accum.c    \
+   aim.c      \
+   alpha.c    \
+   alpha3D.c  \
+   anti.c     \
+   antiindex.c  \
+   antipindex.c \
+   antipoint.c  \
+   antipoly.c  \
+   bezcurve.c  \
+   bezmesh.c   \
+   bezsurf.c   \
+   checker.c   \
+   checker2.c  \
+   chess.c     \
+   clip.c      \
+   colormat.c  \
+   cone.c      \
+   cube.c      \
+   curve.c     \
+   depthcue.c  \
+   disk.c      \
+   dof.c       \
+   dofnot.c    \
+   double.c    \
+   drawf.c     \
+   feedback.c  \
+   fog.c       \
+   fogindex.c  \
+   font.c      \
+   light.c     \
+   linelist.c  \
+   lines.c     \
+   list.c      \
+   list2.c     \
+   maplight.c  \
+   material.c  \
+   mipmap.c    \
+   model.c     \
+   movelight.c \
+   nurbs.c     \
+   pickdepth.c \
+   pickline.c  \
+   picksquare.c \
+   plane.c     \
+   planet.c    \
+   planetup.c  \
+   polys.c     \
+   robot.c     \
+   sccolorlight.c \
+   scene.c     \
+   scenebamb.c \
+   sceneflat.c \
+   select.c    \
+   smooth.c    \
+   sphere.c    \
+   stencil.c   \
+   stroke.c    \
+   surface.c   \
+   tea.c       \
+   teaambient.c \
+   teapots.c   \
+   texgen.c    \
+   texturesurf.c \
+   trim.c     
+
+EXTRALIBS = $(MESAGL).lib $(MESAGLU).lib $(MESATK).lib $(MESAAUX).lib
+
+!include "$(TOP)/mesawin32.mak"
+
diff --git a/progs/redbook/README b/progs/redbook/README
new file mode 100644 (file)
index 0000000..4c8d5a7
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ *     For the software in this directory
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+ */
+
+The source code examples in this directory accompany the examples
+printed in the _OpenGL Programming Guide_, published by Addison-Wesley;
+ISBN 0-201-63274-8.
diff --git a/progs/redbook/aaindex.c b/progs/redbook/aaindex.c
new file mode 100644 (file)
index 0000000..7dbc7b4
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 1993-1997, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*
+ *  aaindex.c
+ *  This program draws shows how to draw anti-aliased lines in color
+ *  index mode. It draws two diagonal lines to form an X; when 'r' 
+ *  is typed in the window, the lines are rotated in opposite 
+ *  directions.
+ */
+#include <GL/glut.h>
+#include "stdlib.h"
+
+#define RAMPSIZE 16
+#define RAMP1START 32
+#define RAMP2START 48
+
+static float rotAngle = 0.;
+
+/*  Initialize antialiasing for color index mode,
+ *  including loading a green color ramp starting
+ *  at RAMP1START, and a blue color ramp starting
+ *  at RAMP2START. The ramps must be a multiple of 16.
+ */
+void init(void)
+{
+   int i;
+
+   for (i = 0; i < RAMPSIZE; i++) {
+      GLfloat shade;
+      shade = (GLfloat) i/(GLfloat) RAMPSIZE;
+      glutSetColor(RAMP1START+(GLint)i, 0., shade, 0.);
+      glutSetColor(RAMP2START+(GLint)i, 0., 0., shade);
+   }
+
+   glEnable (GL_LINE_SMOOTH);
+   glHint (GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
+   glLineWidth (1.5);
+
+   glClearIndex ((GLfloat) RAMP1START);
+}
+
+/*  Draw 2 diagonal lines to form an X
+ */
+void display(void)
+{
+   glClear(GL_COLOR_BUFFER_BIT);
+
+   glIndexi(RAMP1START);
+   glPushMatrix();
+   glRotatef(-rotAngle, 0.0, 0.0, 0.1);
+   glBegin (GL_LINES);
+      glVertex2f (-0.5, 0.5);
+      glVertex2f (0.5, -0.5);
+   glEnd ();
+   glPopMatrix();
+
+   glIndexi(RAMP2START);
+   glPushMatrix();
+   glRotatef(rotAngle, 0.0, 0.0, 0.1);
+   glBegin (GL_LINES);
+      glVertex2f (0.5, 0.5);
+      glVertex2f (-0.5, -0.5);
+   glEnd ();
+   glPopMatrix();
+
+   glFlush();
+}
+
+void reshape(int w, int h)
+{
+   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   if (w <= h) 
+      gluOrtho2D (-1.0, 1.0, 
+         -1.0*(GLfloat)h/(GLfloat)w, 1.0*(GLfloat)h/(GLfloat)w);
+   else 
+      gluOrtho2D (-1.0*(GLfloat)w/(GLfloat)h, 
+         1.0*(GLfloat)w/(GLfloat)h, -1.0, 1.0);
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+}
+
+/* ARGSUSED1 */
+void keyboard(unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 'r':
+      case 'R':
+         rotAngle += 20.;
+         if (rotAngle >= 360.) rotAngle = 0.;
+         glutPostRedisplay();  
+         break;
+      case 27:  /*  Escape Key */
+         exit(0);
+         break;
+      default:
+         break;
+    }
+}
+
+/*  Main Loop
+ *  Open window with initial window size, title bar, 
+ *  color index display mode, and handle input events.
+ */
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode (GLUT_SINGLE | GLUT_INDEX);
+   glutInitWindowSize (200, 200);
+   glutCreateWindow (argv[0]);
+   init();
+   glutReshapeFunc (reshape);
+   glutKeyboardFunc (keyboard);
+   glutDisplayFunc (display);
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/redbook/aapoly.c b/progs/redbook/aapoly.c
new file mode 100644 (file)
index 0000000..757f0f4
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 1993-1997, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*
+ *  aapoly.c
+ *  This program draws filled polygons with antialiased
+ *  edges.  The special GL_SRC_ALPHA_SATURATE blending 
+ *  function is used.
+ *  Pressing the 't' key turns the antialiasing on and off.
+ */
+#include <GL/glut.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+GLboolean polySmooth = GL_TRUE;
+
+static void init(void)
+{
+   glCullFace (GL_BACK);
+   glEnable (GL_CULL_FACE);
+   glBlendFunc (GL_SRC_ALPHA_SATURATE, GL_ONE);
+   glClearColor (0.0, 0.0, 0.0, 0.0);
+}
+
+#define NFACE 6
+#define NVERT 8
+void drawCube(GLdouble x0, GLdouble x1, GLdouble y0, GLdouble y1,
+        GLdouble z0, GLdouble z1)
+{
+   static GLfloat v[8][3];
+   static GLfloat c[8][4] = {
+      {0.0, 0.0, 0.0, 1.0}, {1.0, 0.0, 0.0, 1.0},
+      {0.0, 1.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 1.0},
+      {0.0, 0.0, 1.0, 1.0}, {1.0, 0.0, 1.0, 1.0},
+      {0.0, 1.0, 1.0, 1.0}, {1.0, 1.0, 1.0, 1.0}
+   };
+
+/*  indices of front, top, left, bottom, right, back faces  */
+   static GLubyte indices[NFACE][4] = {
+      {4, 5, 6, 7}, {2, 3, 7, 6}, {0, 4, 7, 3},
+      {0, 1, 5, 4}, {1, 5, 6, 2}, {0, 3, 2, 1}
+   };
+
+   v[0][0] = v[3][0] = v[4][0] = v[7][0] = x0;
+   v[1][0] = v[2][0] = v[5][0] = v[6][0] = x1;
+   v[0][1] = v[1][1] = v[4][1] = v[5][1] = y0;
+   v[2][1] = v[3][1] = v[6][1] = v[7][1] = y1;
+   v[0][2] = v[1][2] = v[2][2] = v[3][2] = z0;
+   v[4][2] = v[5][2] = v[6][2] = v[7][2] = z1;
+
+#ifdef GL_VERSION_1_1
+   glEnableClientState (GL_VERTEX_ARRAY);
+   glEnableClientState (GL_COLOR_ARRAY);
+   glVertexPointer (3, GL_FLOAT, 0, v);
+   glColorPointer (4, GL_FLOAT, 0, c);
+   glDrawElements (GL_QUADS, NFACE*4, GL_UNSIGNED_BYTE, indices);
+   glDisableClientState (GL_VERTEX_ARRAY);
+   glDisableClientState (GL_COLOR_ARRAY);
+#else
+   printf ("If this is GL Version 1.0, ");
+   printf ("vertex arrays are not supported.\n");
+   exit(1);
+#endif
+}
+
+/*  Note:  polygons must be drawn from front to back
+ *  for proper blending.
+ */
+void display(void)
+{
+   if (polySmooth) {
+      glClear (GL_COLOR_BUFFER_BIT);
+      glEnable (GL_BLEND);
+      glEnable (GL_POLYGON_SMOOTH);
+      glDisable (GL_DEPTH_TEST);
+   }
+   else { 
+      glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+      glDisable (GL_BLEND);
+      glDisable (GL_POLYGON_SMOOTH);
+      glEnable (GL_DEPTH_TEST);
+   }
+
+   glPushMatrix ();
+      glTranslatef (0.0, 0.0, -8.0);    
+      glRotatef (30.0, 1.0, 0.0, 0.0);
+      glRotatef (60.0, 0.0, 1.0, 0.0); 
+      drawCube(-0.5, 0.5, -0.5, 0.5, -0.5, 0.5);
+   glPopMatrix ();
+
+   glFlush ();
+}
+
+void reshape(int w, int h)
+{
+   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   gluPerspective(30.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+}
+
+/* ARGSUSED1 */
+void keyboard(unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 't':
+      case 'T':
+         polySmooth = !polySmooth;
+         glutPostRedisplay();
+         break;
+      case 27:
+         exit(0);  /*  Escape key  */
+         break;
+      default:
+         break;
+   }
+}
+
+/*  Main Loop
+ */
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB 
+                        | GLUT_ALPHA | GLUT_DEPTH);
+   glutInitWindowSize(200, 200);
+   glutCreateWindow(argv[0]);
+   init ();
+   glutReshapeFunc (reshape);
+   glutKeyboardFunc (keyboard);
+   glutDisplayFunc (display);
+   glutMainLoop();
+   return 0;
+}
+
diff --git a/progs/redbook/aargb.c b/progs/redbook/aargb.c
new file mode 100644 (file)
index 0000000..f519841
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 1993-1997, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*
+ *  aargb.c
+ *  This program draws shows how to draw anti-aliased lines. It draws
+ *  two diagonal lines to form an X; when 'r' is typed in the window, 
+ *  the lines are rotated in opposite directions.
+ */
+#include <GL/glut.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+static float rotAngle = 0.;
+
+/*  Initialize antialiasing for RGBA mode, including alpha
+ *  blending, hint, and line width.  Print out implementation
+ *  specific info on line width granularity and width.
+ */
+void init(void)
+{
+   GLfloat values[2];
+   glGetFloatv (GL_LINE_WIDTH_GRANULARITY, values);
+   printf ("GL_LINE_WIDTH_GRANULARITY value is %3.1f\n", values[0]);
+
+   glGetFloatv (GL_LINE_WIDTH_RANGE, values);
+   printf ("GL_LINE_WIDTH_RANGE values are %3.1f %3.1f\n",
+      values[0], values[1]);
+
+   glEnable (GL_LINE_SMOOTH);
+   glEnable (GL_BLEND);
+   glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+   glHint (GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
+   glLineWidth (1.5);
+
+   glClearColor(0.0, 0.0, 0.0, 0.0);
+}
+
+/* Draw 2 diagonal lines to form an X
+ */
+void display(void)
+{
+   glClear(GL_COLOR_BUFFER_BIT);
+
+   glColor3f (0.0, 1.0, 0.0);
+   glPushMatrix();
+   glRotatef(-rotAngle, 0.0, 0.0, 0.1);
+   glBegin (GL_LINES);
+      glVertex2f (-0.5, 0.5);
+      glVertex2f (0.5, -0.5);
+   glEnd ();
+   glPopMatrix();
+
+   glColor3f (0.0, 0.0, 1.0);
+   glPushMatrix();
+   glRotatef(rotAngle, 0.0, 0.0, 0.1);
+   glBegin (GL_LINES);
+      glVertex2f (0.5, 0.5);
+      glVertex2f (-0.5, -0.5);
+   glEnd ();
+   glPopMatrix();
+
+   glFlush();
+}
+
+void reshape(int w, int h)
+{
+   glViewport(0, 0, w, h);
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   if (w <= h) 
+      gluOrtho2D (-1.0, 1.0, 
+         -1.0*(GLfloat)h/(GLfloat)w, 1.0*(GLfloat)h/(GLfloat)w);
+   else 
+      gluOrtho2D (-1.0*(GLfloat)w/(GLfloat)h, 
+         1.0*(GLfloat)w/(GLfloat)h, -1.0, 1.0);
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+}
+
+/* ARGSUSED1 */
+void keyboard(unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 'r':
+      case 'R':
+         rotAngle += 20.;
+         if (rotAngle >= 360.) rotAngle = 0.;
+         glutPostRedisplay();  
+         break;
+      case 27:  /*  Escape Key  */
+         exit(0);
+         break;
+      default:
+         break;
+    }
+}
+
+/*  Main Loop
+ *  Open window with initial window size, title bar, 
+ *  RGBA display mode, and handle input events.
+ */
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
+   glutInitWindowSize (200, 200);
+   glutCreateWindow (argv[0]);
+   init();
+   glutReshapeFunc (reshape);
+   glutKeyboardFunc (keyboard);
+   glutDisplayFunc (display);
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/redbook/accanti.c b/progs/redbook/accanti.c
new file mode 100644 (file)
index 0000000..d45cf9e
--- /dev/null
@@ -0,0 +1,168 @@
+
+/* Copyright (c) Mark J. Kilgard, 1994. */
+
+/*
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+ */
+/*  accanti.c
+ */
+#include <stdlib.h>
+#include <GL/glut.h>
+#include "jitter.h"
+
+/*  Initialize lighting and other values.
+ */
+void myinit(void)
+{
+    GLfloat mat_ambient[] = { 1.0, 1.0, 1.0, 1.0 };
+    GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
+    GLfloat light_position[] = { 0.0, 0.0, 10.0, 1.0 };
+    GLfloat lm_ambient[] = { 0.2, 0.2, 0.2, 1.0 };
+
+    glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
+    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
+    glMaterialf(GL_FRONT, GL_SHININESS, 50.0);
+    glLightfv(GL_LIGHT0, GL_POSITION, light_position);
+    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lm_ambient);
+    
+    glEnable(GL_LIGHTING);
+    glEnable(GL_LIGHT0);
+    glDepthFunc(GL_LESS);
+    glEnable(GL_DEPTH_TEST);
+    glShadeModel (GL_FLAT);
+
+    glClearColor(0.0, 0.0, 0.0, 0.0);
+    glClearAccum(0.0, 0.0, 0.0, 0.0);
+}
+
+void displayObjects(void) 
+{
+    GLfloat torus_diffuse[] = { 0.7, 0.7, 0.0, 1.0 };
+    GLfloat cube_diffuse[] = { 0.0, 0.7, 0.7, 1.0 };
+    GLfloat sphere_diffuse[] = { 0.7, 0.0, 0.7, 1.0 };
+    GLfloat octa_diffuse[] = { 0.7, 0.4, 0.4, 1.0 };
+    
+    glPushMatrix ();
+    glRotatef (30.0, 1.0, 0.0, 0.0);
+
+    glPushMatrix ();
+    glTranslatef (-0.80, 0.35, 0.0); 
+    glRotatef (100.0, 1.0, 0.0, 0.0);
+    glMaterialfv(GL_FRONT, GL_DIFFUSE, torus_diffuse);
+    glutSolidTorus (0.275, 0.85, 16, 16);
+    glPopMatrix ();
+
+    glPushMatrix ();
+    glTranslatef (-0.75, -0.50, 0.0); 
+    glRotatef (45.0, 0.0, 0.0, 1.0);
+    glRotatef (45.0, 1.0, 0.0, 0.0);
+    glMaterialfv(GL_FRONT, GL_DIFFUSE, cube_diffuse);
+    glutSolidCube (1.5);
+    glPopMatrix ();
+
+    glPushMatrix ();
+    glTranslatef (0.75, 0.60, 0.0); 
+    glRotatef (30.0, 1.0, 0.0, 0.0);
+    glMaterialfv(GL_FRONT, GL_DIFFUSE, sphere_diffuse);
+    glutSolidSphere (1.0, 16, 16);
+    glPopMatrix ();
+
+    glPushMatrix ();
+    glTranslatef (0.70, -0.90, 0.25); 
+    glMaterialfv(GL_FRONT, GL_DIFFUSE, octa_diffuse);
+    glutSolidOctahedron ();
+    glPopMatrix ();
+
+    glPopMatrix ();
+}
+
+#define ACSIZE 8
+
+void display(void)
+{
+    GLint viewport[4];
+    int jitter;
+
+    glGetIntegerv (GL_VIEWPORT, viewport);
+
+    glClear(GL_ACCUM_BUFFER_BIT);
+    for (jitter = 0; jitter < ACSIZE; jitter++) {
+       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+       glPushMatrix ();
+/*     Note that 4.5 is the distance in world space between
+ *     left and right and bottom and top.
+ *     This formula converts fractional pixel movement to 
+ *     world coordinates.
+ */
+       glTranslatef (j8[jitter].x*4.5/viewport[2],
+           j8[jitter].y*4.5/viewport[3], 0.0);
+       displayObjects ();
+       glPopMatrix ();
+       glAccum(GL_ACCUM, 1.0/ACSIZE);
+    }
+    glAccum (GL_RETURN, 1.0);
+    glFlush();
+}
+
+void myReshape(int w, int h)
+{
+    glViewport(0, 0, w, h);
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    if (w <= h) 
+       glOrtho (-2.25, 2.25, -2.25*h/w, 2.25*h/w, -10.0, 10.0);
+    else 
+       glOrtho (-2.25*w/h, 2.25*w/h, -2.25, 2.25, -10.0, 10.0);
+    glMatrixMode(GL_MODELVIEW);
+}
+
+/*  Main Loop
+ *  Open window with initial window size, title bar, 
+ *  RGBA display mode, and handle input events.
+ */
+int main(int argc, char** argv)
+{
+    glutInit(&argc, argv);
+    glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB
+                       | GLUT_ACCUM | GLUT_DEPTH);
+    glutInitWindowSize (250, 250);
+    glutCreateWindow (argv[0]);
+    myinit();
+    glutReshapeFunc (myReshape);
+    glutDisplayFunc(display);
+    glutMainLoop();
+    return 0;             /* ANSI C requires main to return int. */
+}
diff --git a/progs/redbook/accpersp.c b/progs/redbook/accpersp.c
new file mode 100644 (file)
index 0000000..46e369a
--- /dev/null
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 1993-1997, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*  accpersp.c
+ *  Use the accumulation buffer to do full-scene antialiasing
+ *  on a scene with perspective projection, using the special
+ *  routines accFrustum() and accPerspective().
+ */
+#include <stdlib.h>
+#include <math.h>
+#include <GL/glut.h>
+#include "jitter.h"
+
+#define PI_ 3.14159265358979323846
+
+/* accFrustum()
+ * The first 6 arguments are identical to the glFrustum() call.
+ *  
+ * pixdx and pixdy are anti-alias jitter in pixels. 
+ * Set both equal to 0.0 for no anti-alias jitter.
+ * eyedx and eyedy are depth-of field jitter in pixels. 
+ * Set both equal to 0.0 for no depth of field effects.
+ *
+ * focus is distance from eye to plane in focus. 
+ * focus must be greater than, but not equal to 0.0.
+ *
+ * Note that accFrustum() calls glTranslatef().  You will 
+ * probably want to insure that your ModelView matrix has been 
+ * initialized to identity before calling accFrustum().
+ */
+void accFrustum(GLdouble left, GLdouble right, GLdouble bottom, 
+   GLdouble top, GLdouble nnear, GLdouble ffar, GLdouble pixdx, 
+   GLdouble pixdy, GLdouble eyedx, GLdouble eyedy, GLdouble focus)
+{
+   GLdouble xwsize, ywsize; 
+   GLdouble dx, dy;
+   GLint viewport[4];
+
+   glGetIntegerv (GL_VIEWPORT, viewport);
+       
+   xwsize = right - left;
+   ywsize = top - bottom;
+       
+   dx = -(pixdx*xwsize/(GLdouble) viewport[2] + eyedx*nnear/focus);
+   dy = -(pixdy*ywsize/(GLdouble) viewport[3] + eyedy*nnear/focus);
+       
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   glFrustum (left + dx, right + dx, bottom + dy, top + dy, nnear, ffar);
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+   glTranslatef (-eyedx, -eyedy, 0.0);
+}
+
+/* accPerspective()
+ * 
+ * The first 4 arguments are identical to the gluPerspective() call.
+ * pixdx and pixdy are anti-alias jitter in pixels. 
+ * Set both equal to 0.0 for no anti-alias jitter.
+ * eyedx and eyedy are depth-of field jitter in pixels. 
+ * Set both equal to 0.0 for no depth of field effects.
+ *
+ * focus is distance from eye to plane in focus. 
+ * focus must be greater than, but not equal to 0.0.
+ *
+ * Note that accPerspective() calls accFrustum().
+ */
+void accPerspective(GLdouble fovy, GLdouble aspect, 
+   GLdouble nnear, GLdouble ffar, GLdouble pixdx, GLdouble pixdy, 
+   GLdouble eyedx, GLdouble eyedy, GLdouble focus)
+{
+   GLdouble fov2,left,right,bottom,top;
+
+   fov2 = ((fovy*PI_) / 180.0) / 2.0;
+
+   top = nnear / (cos(fov2) / sin(fov2));
+   bottom = -top;
+
+   right = top * aspect;
+   left = -right;
+
+   accFrustum (left, right, bottom, top, nnear, ffar,
+               pixdx, pixdy, eyedx, eyedy, focus);
+}
+
+/*  Initialize lighting and other values.
+ */
+void init(void)
+{
+   GLfloat mat_ambient[] = { 1.0, 1.0, 1.0, 1.0 };
+   GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
+   GLfloat light_position[] = { 0.0, 0.0, 10.0, 1.0 };
+   GLfloat lm_ambient[] = { 0.2, 0.2, 0.2, 1.0 };
+
+   glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
+   glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
+   glMaterialf(GL_FRONT, GL_SHININESS, 50.0);
+   glLightfv(GL_LIGHT0, GL_POSITION, light_position);
+   glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lm_ambient);
+    
+   glEnable(GL_LIGHTING);
+   glEnable(GL_LIGHT0);
+   glEnable(GL_DEPTH_TEST);
+   glShadeModel (GL_FLAT);
+
+   glClearColor(0.0, 0.0, 0.0, 0.0);
+   glClearAccum(0.0, 0.0, 0.0, 0.0);
+}
+
+void displayObjects(void) 
+{
+   GLfloat torus_diffuse[] = { 0.7, 0.7, 0.0, 1.0 };
+   GLfloat cube_diffuse[] = { 0.0, 0.7, 0.7, 1.0 };
+   GLfloat sphere_diffuse[] = { 0.7, 0.0, 0.7, 1.0 };
+   GLfloat octa_diffuse[] = { 0.7, 0.4, 0.4, 1.0 };
+    
+   glPushMatrix ();
+   glTranslatef (0.0, 0.0, -5.0); 
+   glRotatef (30.0, 1.0, 0.0, 0.0);
+
+   glPushMatrix ();
+   glTranslatef (-0.80, 0.35, 0.0); 
+   glRotatef (100.0, 1.0, 0.0, 0.0);
+   glMaterialfv(GL_FRONT, GL_DIFFUSE, torus_diffuse);
+   glutSolidTorus (0.275, 0.85, 16, 16);
+   glPopMatrix ();
+
+   glPushMatrix ();
+   glTranslatef (-0.75, -0.50, 0.0); 
+   glRotatef (45.0, 0.0, 0.0, 1.0);
+   glRotatef (45.0, 1.0, 0.0, 0.0);
+   glMaterialfv(GL_FRONT, GL_DIFFUSE, cube_diffuse);
+   glutSolidCube (1.5);
+   glPopMatrix ();
+
+   glPushMatrix ();
+   glTranslatef (0.75, 0.60, 0.0); 
+   glRotatef (30.0, 1.0, 0.0, 0.0);
+   glMaterialfv(GL_FRONT, GL_DIFFUSE, sphere_diffuse);
+   glutSolidSphere (1.0, 16, 16);
+   glPopMatrix ();
+
+   glPushMatrix ();
+   glTranslatef (0.70, -0.90, 0.25); 
+   glMaterialfv(GL_FRONT, GL_DIFFUSE, octa_diffuse);
+   glutSolidOctahedron ();
+   glPopMatrix ();
+
+   glPopMatrix ();
+}
+
+#define ACSIZE 8
+
+void display(void)
+{
+   GLint viewport[4];
+   int jitter;
+
+   glGetIntegerv (GL_VIEWPORT, viewport);
+
+   glClear(GL_ACCUM_BUFFER_BIT);
+   for (jitter = 0; jitter < ACSIZE; jitter++) {
+      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+      accPerspective (50.0, 
+         (GLdouble) viewport[2]/(GLdouble) viewport[3], 
+         1.0, 15.0, j8[jitter].x, j8[jitter].y, 0.0, 0.0, 1.0);
+      displayObjects ();
+      glAccum(GL_ACCUM, 1.0/ACSIZE);
+   }
+   glAccum (GL_RETURN, 1.0);
+   glFlush();
+}
+
+void reshape(int w, int h)
+{
+   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
+}
+
+/* ARGSUSED1 */
+void keyboard(unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 27:
+         exit(0);
+         break;
+   }
+}
+
+/*  Main Loop
+ *  Be certain you request an accumulation buffer.
+ */
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB
+                        | GLUT_ACCUM | GLUT_DEPTH);
+   glutInitWindowSize (250, 250);
+   glutInitWindowPosition (100, 100);
+   glutCreateWindow (argv[0]);
+   init();
+   glutReshapeFunc(reshape);
+   glutDisplayFunc(display);
+   glutKeyboardFunc(keyboard);
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/redbook/alpha.c b/progs/redbook/alpha.c
new file mode 100644 (file)
index 0000000..6eeb45b
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 1993-1997, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*
+ *  alpha.c
+ *  This program draws several overlapping filled polygons
+ *  to demonstrate the effect order has on alpha blending results.
+ *  Use the 't' key to toggle the order of drawing polygons.
+ */
+#include <GL/glut.h>
+#include <stdlib.h>
+
+static int leftFirst = GL_TRUE;
+
+/*  Initialize alpha blending function.
+ */
+static void init(void)
+{
+   glEnable (GL_BLEND);
+   glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+   glShadeModel (GL_FLAT);
+   glClearColor (0.0, 0.0, 0.0, 0.0);
+}
+
+static void drawLeftTriangle(void)
+{
+   /* draw yellow triangle on LHS of screen */
+
+   glBegin (GL_TRIANGLES);
+      glColor4f(1.0, 1.0, 0.0, 0.75);
+      glVertex3f(0.1, 0.9, 0.0); 
+      glVertex3f(0.1, 0.1, 0.0); 
+      glVertex3f(0.7, 0.5, 0.0); 
+   glEnd();
+}
+
+static void drawRightTriangle(void)
+{
+   /* draw cyan triangle on RHS of screen */
+
+   glBegin (GL_TRIANGLES);
+      glColor4f(0.0, 1.0, 1.0, 0.75);
+      glVertex3f(0.9, 0.9, 0.0); 
+      glVertex3f(0.3, 0.5, 0.0); 
+      glVertex3f(0.9, 0.1, 0.0); 
+   glEnd();
+}
+
+void display(void)
+{
+   glClear(GL_COLOR_BUFFER_BIT);
+
+   if (leftFirst) {
+      drawLeftTriangle();
+      drawRightTriangle();
+   }
+   else {
+      drawRightTriangle();
+      drawLeftTriangle();
+   }
+
+   glFlush();
+}
+
+void reshape(int w, int h)
+{
+   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   if (w <= h) 
+      gluOrtho2D (0.0, 1.0, 0.0, 1.0*(GLfloat)h/(GLfloat)w);
+   else 
+      gluOrtho2D (0.0, 1.0*(GLfloat)w/(GLfloat)h, 0.0, 1.0);
+}
+
+/* ARGSUSED1 */
+void keyboard(unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 't':
+      case 'T':
+         leftFirst = !leftFirst;
+         glutPostRedisplay();  
+         break;
+      case 27:  /*  Escape key  */
+         exit(0);
+         break;
+      default:
+         break;
+   }
+}
+
+/*  Main Loop
+ *  Open window with initial window size, title bar, 
+ *  RGBA display mode, and handle input events.
+ */
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
+   glutInitWindowSize (200, 200);
+   glutCreateWindow (argv[0]);
+   init();
+   glutReshapeFunc (reshape);
+   glutKeyboardFunc (keyboard);
+   glutDisplayFunc (display);
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/redbook/alpha3D.c b/progs/redbook/alpha3D.c
new file mode 100644 (file)
index 0000000..413836e
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 1993-1997, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*
+ *  alpha3D.c
+ *  This program demonstrates how to intermix opaque and
+ *  alpha blended polygons in the same scene, by using 
+ *  glDepthMask.  Press the 'a' key to animate moving the 
+ *  transparent object through the opaque object.  Press 
+ *  the 'r' key to reset the scene.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <GL/glut.h>
+
+#define MAXZ 8.0
+#define MINZ -8.0
+#define ZINC 0.4
+
+static float solidZ = MAXZ;
+static float transparentZ = MINZ;
+static GLuint sphereList, cubeList;
+
+static void init(void)
+{
+   GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 0.15 };
+   GLfloat mat_shininess[] = { 100.0 };
+   GLfloat position[] = { 0.5, 0.5, 1.0, 0.0 };
+
+   glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
+   glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
+   glLightfv(GL_LIGHT0, GL_POSITION, position);
+
+   glEnable(GL_LIGHTING);
+   glEnable(GL_LIGHT0);
+   glEnable(GL_DEPTH_TEST);
+
+   sphereList = glGenLists(1);
+   glNewList(sphereList, GL_COMPILE);
+      glutSolidSphere (0.4, 16, 16);
+   glEndList();
+
+   cubeList = glGenLists(1);
+   glNewList(cubeList, GL_COMPILE);
+      glutSolidCube (0.6);
+   glEndList();
+}
+
+void display(void)
+{
+   GLfloat mat_solid[] = { 0.75, 0.75, 0.0, 1.0 };
+   GLfloat mat_zero[] = { 0.0, 0.0, 0.0, 1.0 };
+   GLfloat mat_transparent[] = { 0.0, 0.8, 0.8, 0.6 };
+   GLfloat mat_emission[] = { 0.0, 0.3, 0.3, 0.6 };
+
+   glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+   glPushMatrix ();
+      glTranslatef (-0.15, -0.15, solidZ);
+      glMaterialfv(GL_FRONT, GL_EMISSION, mat_zero);
+      glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_solid);
+      glCallList (sphereList);
+   glPopMatrix ();
+
+   glPushMatrix ();
+      glTranslatef (0.15, 0.15, transparentZ);
+      glRotatef (15.0, 1.0, 1.0, 0.0);
+      glRotatef (30.0, 0.0, 1.0, 0.0);
+      glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);
+      glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_transparent);
+      glEnable (GL_BLEND);
+      glDepthMask (GL_FALSE);
+      glBlendFunc (GL_SRC_ALPHA, GL_ONE);
+      glCallList (cubeList);
+      glDepthMask (GL_TRUE);
+      glDisable (GL_BLEND);
+   glPopMatrix ();
+
+   glutSwapBuffers();
+}
+
+void reshape(int w, int h)
+{
+   glViewport(0, 0, (GLint) w, (GLint) h);
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   if (w <= h)
+      glOrtho (-1.5, 1.5, -1.5*(GLfloat)h/(GLfloat)w,
+               1.5*(GLfloat)h/(GLfloat)w, -10.0, 10.0);
+   else
+      glOrtho (-1.5*(GLfloat)w/(GLfloat)h,
+               1.5*(GLfloat)w/(GLfloat)h, -1.5, 1.5, -10.0, 10.0);
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+}
+
+void animate(void)
+{
+   if (solidZ <= MINZ || transparentZ >= MAXZ)
+      glutIdleFunc(NULL);
+   else {
+      solidZ -= ZINC;
+      transparentZ += ZINC;
+      glutPostRedisplay();
+   }
+}
+
+/* ARGSUSED1 */
+void keyboard(unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 'a':
+      case 'A':
+         solidZ = MAXZ;
+         transparentZ = MINZ;
+         glutIdleFunc(animate);
+         break;
+      case 'r':
+      case 'R':
+         solidZ = MAXZ;
+         transparentZ = MINZ;
+         glutPostRedisplay();
+         break;
+      case 27:
+        exit(0);
+    }
+}
+
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
+   glutInitWindowSize(500, 500);
+   glutCreateWindow(argv[0]);
+   init();
+   glutReshapeFunc(reshape);
+   glutKeyboardFunc(keyboard);
+   glutDisplayFunc(display);
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/redbook/anti.c b/progs/redbook/anti.c
new file mode 100644 (file)
index 0000000..12aa5f8
--- /dev/null
@@ -0,0 +1,111 @@
+
+/* Copyright (c) Mark J. Kilgard, 1994. */
+
+/*
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+ */
+/*
+ *  anti.c
+ *  This program draws antialiased lines in RGBA mode.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <GL/glut.h>
+
+/*  Initialize antialiasing for RGBA mode, including alpha 
+ *  blending, hint, and line width.  Print out implementation 
+ *  specific info on line width granularity and width.
+ */
+void myinit(void)
+{
+    GLfloat values[2];
+    glGetFloatv (GL_LINE_WIDTH_GRANULARITY, values);
+    printf ("GL_LINE_WIDTH_GRANULARITY value is %3.1f\n", values[0]);
+
+    glGetFloatv (GL_LINE_WIDTH_RANGE, values);
+    printf ("GL_LINE_WIDTH_RANGE values are %3.1f %3.1f\n", 
+       values[0], values[1]);
+
+    glEnable (GL_LINE_SMOOTH);
+    glEnable (GL_BLEND);
+    glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+    glHint (GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
+    glLineWidth (1.5);
+
+    glShadeModel(GL_FLAT);
+    glClearColor(0.0, 0.0, 0.0, 0.0);
+    glDepthFunc(GL_LESS);
+    glEnable(GL_DEPTH_TEST);
+}
+
+/*  display() draws an icosahedron with a large alpha value, 1.0.
+ */
+void display(void)
+{
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+    glColor4f (1.0, 1.0, 1.0, 1.0);
+    glutWireIcosahedron();
+    glFlush();
+}
+
+void myReshape(int w, int h)
+{
+    glViewport(0, 0, w, h);
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    gluPerspective (45.0, (GLfloat) w/(GLfloat) h, 3.0, 5.0);
+
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity ();
+    glTranslatef (0.0, 0.0, -4.0);  /*  move object into view   */
+}
+
+/*  Main Loop
+ *  Open window with initial window size, title bar, 
+ *  RGBA display mode, and handle input events.
+ */
+int main(int argc, char** argv)
+{
+    glutInit(&argc, argv);
+    glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
+    glutCreateWindow (argv[0]);
+    myinit();
+    glutReshapeFunc (myReshape);
+    glutDisplayFunc(display);
+    glutMainLoop();
+    return 0;             /* ANSI C requires main to return int. */
+}
+
diff --git a/progs/redbook/bezcurve.c b/progs/redbook/bezcurve.c
new file mode 100644 (file)
index 0000000..5dee440
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 1993-1997, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*  bezcurve.c                 
+ *  This program uses evaluators to draw a Bezier curve.
+ */
+#include <stdlib.h>
+#include <GL/glut.h>
+
+GLfloat ctrlpoints[4][3] = {
+       { -4.0, -4.0, 0.0}, { -2.0, 4.0, 0.0}, 
+       {2.0, -4.0, 0.0}, {4.0, 4.0, 0.0}};
+
+void init(void)
+{
+   glClearColor(0.0, 0.0, 0.0, 0.0);
+   glShadeModel(GL_FLAT);
+   glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &ctrlpoints[0][0]);
+   glEnable(GL_MAP1_VERTEX_3);
+}
+
+void display(void)
+{
+   int i;
+
+   glClear(GL_COLOR_BUFFER_BIT);
+   glColor3f(1.0, 1.0, 1.0);
+   glBegin(GL_LINE_STRIP);
+      for (i = 0; i <= 30; i++) 
+         glEvalCoord1f((GLfloat) i/30.0);
+   glEnd();
+   /* The following code displays the control points as dots. */
+   glPointSize(5.0);
+   glColor3f(1.0, 1.0, 0.0);
+   glBegin(GL_POINTS);
+      for (i = 0; i < 4; i++) 
+         glVertex3fv(&ctrlpoints[i][0]);
+   glEnd();
+   glFlush();
+}
+
+void reshape(int w, int h)
+{
+   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   if (w <= h)
+      glOrtho(-5.0, 5.0, -5.0*(GLfloat)h/(GLfloat)w, 
+               5.0*(GLfloat)h/(GLfloat)w, -5.0, 5.0);
+   else
+      glOrtho(-5.0*(GLfloat)w/(GLfloat)h, 
+               5.0*(GLfloat)w/(GLfloat)h, -5.0, 5.0, -5.0, 5.0);
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+}
+
+/* ARGSUSED1 */
+void keyboard(unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 27:
+         exit(0);
+         break;
+   }
+}
+
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
+   glutInitWindowSize (500, 500);
+   glutInitWindowPosition (100, 100);
+   glutCreateWindow (argv[0]);
+   init ();
+   glutDisplayFunc(display);
+   glutReshapeFunc(reshape);
+   glutKeyboardFunc (keyboard);
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/redbook/bezmesh.c b/progs/redbook/bezmesh.c
new file mode 100644 (file)
index 0000000..eb7f0f7
--- /dev/null
@@ -0,0 +1,148 @@
+
+/* Copyright (c) Mark J. Kilgard, 1994. */
+
+/**
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+ */
+/*  bezsurf.c
+ *  This program renders a lighted, filled Bezier surface,
+ *  using two-dimensional evaluators.
+ */
+#include <stdlib.h>
+#include <GL/glut.h>
+
+GLfloat ctrlpoints[4][4][3] =
+{
+    {
+        {-1.5, -1.5, 4.0},
+        {-0.5, -1.5, 2.0},
+        {0.5, -1.5, -1.0},
+        {1.5, -1.5, 2.0}},
+    {
+        {-1.5, -0.5, 1.0},
+        {-0.5, -0.5, 3.0},
+        {0.5, -0.5, 0.0},
+        {1.5, -0.5, -1.0}},
+    {
+        {-1.5, 0.5, 4.0},
+        {-0.5, 0.5, 0.0},
+        {0.5, 0.5, 3.0},
+        {1.5, 0.5, 4.0}},
+    {
+        {-1.5, 1.5, -2.0},
+        {-0.5, 1.5, -2.0},
+        {0.5, 1.5, 0.0},
+        {1.5, 1.5, -1.0}}
+};
+
+void 
+initlights(void)
+{
+    GLfloat ambient[] =
+    {0.2, 0.2, 0.2, 1.0};
+    GLfloat position[] =
+    {0.0, 0.0, 2.0, 1.0};
+    GLfloat mat_diffuse[] =
+    {0.6, 0.6, 0.6, 1.0};
+    GLfloat mat_specular[] =
+    {1.0, 1.0, 1.0, 1.0};
+    GLfloat mat_shininess[] =
+    {50.0};
+
+    glEnable(GL_LIGHTING);
+    glEnable(GL_LIGHT0);
+
+    glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
+    glLightfv(GL_LIGHT0, GL_POSITION, position);
+
+    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
+    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
+    glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
+}
+
+void 
+display(void)
+{
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+    glPushMatrix();
+    glRotatef(85.0, 1.0, 1.0, 1.0);
+    glEvalMesh2(GL_FILL, 0, 20, 0, 20);
+    glPopMatrix();
+    glFlush();
+}
+
+void 
+myinit(void)
+{
+    glClearColor(0.0, 0.0, 0.0, 1.0);
+    glEnable(GL_DEPTH_TEST);
+    glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4,
+        0, 1, 12, 4, &ctrlpoints[0][0][0]);
+    glEnable(GL_MAP2_VERTEX_3);
+    glEnable(GL_AUTO_NORMAL);
+    glEnable(GL_NORMALIZE);
+    glMapGrid2f(20, 0.0, 1.0, 20, 0.0, 1.0);
+    initlights();       /* for lighted version only */
+}
+
+void 
+myReshape(int w, int h)
+{
+    glViewport(0, 0, w, h);
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    if (w <= h)
+        glOrtho(-4.0, 4.0, -4.0 * (GLfloat) h / (GLfloat) w,
+            4.0 * (GLfloat) h / (GLfloat) w, -4.0, 4.0);
+    else
+        glOrtho(-4.0 * (GLfloat) w / (GLfloat) h,
+            4.0 * (GLfloat) w / (GLfloat) h, -4.0, 4.0, -4.0, 4.0);
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
+}
+
+int 
+main(int argc, char **argv)
+{
+    glutInit(&argc, argv);
+    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
+    glutCreateWindow(argv[0]);
+    myinit();
+    glutReshapeFunc(myReshape);
+    glutDisplayFunc(display);
+    glutMainLoop();
+    return 0;             /* ANSI C requires main to return int. */
+}
diff --git a/progs/redbook/checker.c b/progs/redbook/checker.c
new file mode 100644 (file)
index 0000000..34853b0
--- /dev/null
@@ -0,0 +1,125 @@
+
+/* Copyright (c) Mark J. Kilgard, 1994. */
+
+/*
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+ */
+/*  checker.c
+ *  This program texture maps a checkerboard image onto
+ *  two rectangles.  This program clamps the texture, if
+ *  the texture coordinates fall outside 0.0 and 1.0.
+ */
+#include <GL/glut.h>
+
+/*     Create checkerboard texture     */
+#define        checkImageWidth 64
+#define        checkImageHeight 64
+GLubyte checkImage[checkImageWidth][checkImageHeight][3];
+
+void makeCheckImage(void)
+{
+    int i, j, c;
+    
+    for (i = 0; i < checkImageWidth; i++) {
+       for (j = 0; j < checkImageHeight; j++) {
+           c = ((((i&0x8)==0)^((j&0x8))==0))*255;
+           checkImage[i][j][0] = (GLubyte) c;
+           checkImage[i][j][1] = (GLubyte) c;
+           checkImage[i][j][2] = (GLubyte) c;
+       }
+    }
+}
+
+void myinit(void)
+{    
+    glClearColor (0.0, 0.0, 0.0, 0.0);
+    glEnable(GL_DEPTH_TEST);
+    glDepthFunc(GL_LESS);
+
+    makeCheckImage();
+    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+    glTexImage2D(GL_TEXTURE_2D, 0, 3, checkImageWidth, 
+       checkImageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, 
+       &checkImage[0][0][0]);
+    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
+    glEnable(GL_TEXTURE_2D);
+    glShadeModel(GL_FLAT);
+}
+
+void display(void)
+{
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+    glBegin(GL_QUADS);
+    glTexCoord2f(0.0, 0.0); glVertex3f(-2.0, -1.0, 0.0);
+    glTexCoord2f(0.0, 1.0); glVertex3f(-2.0, 1.0, 0.0);
+    glTexCoord2f(1.0, 1.0); glVertex3f(0.0, 1.0, 0.0);
+    glTexCoord2f(1.0, 0.0); glVertex3f(0.0, -1.0, 0.0);
+
+    glTexCoord2f(0.0, 0.0); glVertex3f(1.0, -1.0, 0.0);
+    glTexCoord2f(0.0, 1.0); glVertex3f(1.0, 1.0, 0.0);
+    glTexCoord2f(1.0, 1.0); glVertex3f(2.41421, 1.0, -1.41421);
+    glTexCoord2f(1.0, 0.0); glVertex3f(2.41421, -1.0, -1.41421);
+    glEnd();
+    glutSwapBuffers();
+}
+
+void myReshape(int w, int h)
+{
+    glViewport(0, 0, w, h);
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    gluPerspective(60.0, 1.0*(GLfloat)w/(GLfloat)h, 1.0, 30.0);
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
+    glTranslatef(0.0, 0.0, -3.6);
+}
+
+int
+main(int argc, char** argv)
+{
+    glutInit(&argc, argv);
+    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
+    glutCreateWindow("checker");
+    myinit();
+    glutReshapeFunc (myReshape);
+    glutDisplayFunc(display);
+    glutMainLoop();
+    return 0;             /* ANSI C requires main to return int. */
+}
diff --git a/progs/redbook/clip.c b/progs/redbook/clip.c
new file mode 100644 (file)
index 0000000..90816f2
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 1993-1997, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*
+ *  clip.c
+ *  This program demonstrates arbitrary clipping planes.
+ */
+#include <GL/glut.h>
+#include <stdlib.h>
+
+void init(void) 
+{
+   glClearColor (0.0, 0.0, 0.0, 0.0);
+   glShadeModel (GL_FLAT);
+}
+
+void display(void)
+{
+   GLdouble eqn[4] = {0.0, 1.0, 0.0, 0.0};
+   GLdouble eqn2[4] = {1.0, 0.0, 0.0, 0.0};
+
+   glClear(GL_COLOR_BUFFER_BIT);
+
+   glColor3f (1.0, 1.0, 1.0);
+   glPushMatrix();
+   glTranslatef (0.0, 0.0, -5.0);
+
+/*    clip lower half -- y < 0          */
+   glClipPlane (GL_CLIP_PLANE0, eqn);
+   glEnable (GL_CLIP_PLANE0);
+/*    clip left half -- x < 0           */
+   glClipPlane (GL_CLIP_PLANE1, eqn2);
+   glEnable (GL_CLIP_PLANE1);
+
+   glRotatef (90.0, 1.0, 0.0, 0.0);
+   glutWireSphere(1.0, 20, 16);
+   glPopMatrix();
+
+   glFlush ();
+}
+
+void reshape (int w, int h)
+{
+   glViewport (0, 0, (GLsizei) w, (GLsizei) h); 
+   glMatrixMode (GL_PROJECTION);
+   glLoadIdentity ();
+   gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);
+   glMatrixMode (GL_MODELVIEW);
+}
+
+/* ARGSUSED1 */
+void keyboard(unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 27:
+         exit(0);
+         break;
+   }
+}
+
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
+   glutInitWindowSize (500, 500); 
+   glutInitWindowPosition (100, 100);
+   glutCreateWindow (argv[0]);
+   init ();
+   glutDisplayFunc(display); 
+   glutReshapeFunc(reshape);
+   glutKeyboardFunc(keyboard);
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/redbook/colormat.c b/progs/redbook/colormat.c
new file mode 100644 (file)
index 0000000..9db4491
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 1993-1997, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*
+ *  colormat.c
+ *  After initialization, the program will be in
+ *  ColorMaterial mode.  Interaction:  pressing the 
+ *  mouse buttons will change the diffuse reflection values.
+ */
+#include <GL/glut.h>
+#include <stdlib.h>
+
+GLfloat diffuseMaterial[4] = { 0.5, 0.5, 0.5, 1.0 };
+
+/*  Initialize material property, light source, lighting model,
+ *  and depth buffer.
+ */
+void init(void) 
+{
+   GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
+   GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
+
+   glClearColor (0.0, 0.0, 0.0, 0.0);
+   glShadeModel (GL_SMOOTH);
+   glEnable(GL_DEPTH_TEST);
+   glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuseMaterial);
+   glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
+   glMaterialf(GL_FRONT, GL_SHININESS, 25.0);
+   glLightfv(GL_LIGHT0, GL_POSITION, light_position);
+   glEnable(GL_LIGHTING);
+   glEnable(GL_LIGHT0);
+
+   glColorMaterial(GL_FRONT, GL_DIFFUSE);
+   glEnable(GL_COLOR_MATERIAL);
+}
+
+void display(void)
+{
+   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+   glutSolidSphere(1.0, 20, 16);
+   glFlush ();
+}
+
+void reshape (int w, int h)
+{
+   glViewport (0, 0, (GLsizei) w, (GLsizei) h);
+   glMatrixMode (GL_PROJECTION);
+   glLoadIdentity();
+   if (w <= h)
+      glOrtho (-1.5, 1.5, -1.5*(GLfloat)h/(GLfloat)w,
+         1.5*(GLfloat)h/(GLfloat)w, -10.0, 10.0);
+   else
+      glOrtho (-1.5*(GLfloat)w/(GLfloat)h,
+         1.5*(GLfloat)w/(GLfloat)h, -1.5, 1.5, -10.0, 10.0);
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+}
+
+/* ARGSUSED2 */
+void mouse(int button, int state, int x, int y)
+{
+   switch (button) {
+      case GLUT_LEFT_BUTTON:
+         if (state == GLUT_DOWN) {
+            diffuseMaterial[0] += 0.1;
+            if (diffuseMaterial[0] > 1.0)
+               diffuseMaterial[0] = 0.0;
+            glColor4fv(diffuseMaterial);
+            glutPostRedisplay();
+         }
+         break;
+      case GLUT_MIDDLE_BUTTON:
+         if (state == GLUT_DOWN) {
+            diffuseMaterial[1] += 0.1;
+            if (diffuseMaterial[1] > 1.0)
+               diffuseMaterial[1] = 0.0;
+            glColor4fv(diffuseMaterial);
+            glutPostRedisplay();
+         }
+         break;
+      case GLUT_RIGHT_BUTTON:
+         if (state == GLUT_DOWN) {
+            diffuseMaterial[2] += 0.1;
+            if (diffuseMaterial[2] > 1.0)
+               diffuseMaterial[2] = 0.0;
+            glColor4fv(diffuseMaterial);
+            glutPostRedisplay();
+         }
+         break;
+      default:
+         break;
+   }
+}
+
+/* ARGSUSED1 */
+void keyboard(unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 27:
+         exit(0);
+         break;
+   }
+}
+
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
+   glutInitWindowSize (500, 500); 
+   glutInitWindowPosition (100, 100);
+   glutCreateWindow (argv[0]);
+   init ();
+   glutDisplayFunc(display); 
+   glutReshapeFunc(reshape);
+   glutMouseFunc(mouse);
+   glutKeyboardFunc(keyboard);
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/redbook/cube.c b/progs/redbook/cube.c
new file mode 100644 (file)
index 0000000..5ecc628
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 1993-1997, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*
+ *  cube.c
+ *  This program demonstrates a single modeling transformation,
+ *  glScalef() and a single viewing transformation, gluLookAt().
+ *  A wireframe cube is rendered.
+ */
+#include <GL/glut.h>
+#include <stdlib.h>
+
+void init(void) 
+{
+   glClearColor (0.0, 0.0, 0.0, 0.0);
+   glShadeModel (GL_FLAT);
+}
+
+void display(void)
+{
+   glClear (GL_COLOR_BUFFER_BIT);
+   glColor3f (1.0, 1.0, 1.0);
+   glLoadIdentity ();             /* clear the matrix */
+           /* viewing transformation  */
+   gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
+   glScalef (1.0, 2.0, 1.0);      /* modeling transformation */ 
+   glutWireCube (1.0);
+   glFlush ();
+}
+
+void reshape (int w, int h)
+{
+   glViewport (0, 0, (GLsizei) w, (GLsizei) h); 
+   glMatrixMode (GL_PROJECTION);
+   glLoadIdentity ();
+   glFrustum (-1.0, 1.0, -1.0, 1.0, 1.5, 20.0);
+   glMatrixMode (GL_MODELVIEW);
+}
+
+/* ARGSUSED1 */
+void keyboard(unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 27:
+         exit(0);
+         break;
+   }
+}
+
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
+   glutInitWindowSize (500, 500); 
+   glutInitWindowPosition (100, 100);
+   glutCreateWindow (argv[0]);
+   init ();
+   glutDisplayFunc(display); 
+   glutReshapeFunc(reshape);
+   glutKeyboardFunc(keyboard);
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/redbook/depthcue.c b/progs/redbook/depthcue.c
new file mode 100644 (file)
index 0000000..41af19c
--- /dev/null
@@ -0,0 +1,102 @@
+
+/* Copyright (c) Mark J. Kilgard, 1994. */
+
+/*
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+ */
+/*
+ *  depthcue.c
+ *  This program draws a wireframe model, which uses 
+ *  intensity (brightness) to give clues to distance.
+ *  Fog is used to achieve this effect.
+ */
+#include <stdlib.h>
+#include <GL/glut.h>
+
+/*  Initialize linear fog for depth cueing.
+ */
+void myinit(void)
+{
+    GLfloat fogColor[4] = {0.0, 0.0, 0.0, 1.0};
+
+    glEnable(GL_FOG);
+    glFogi (GL_FOG_MODE, GL_LINEAR);
+    glHint (GL_FOG_HINT, GL_NICEST);  /*  per pixel   */
+    glFogf (GL_FOG_START, 3.0);
+    glFogf (GL_FOG_END, 5.0);
+    glFogfv (GL_FOG_COLOR, fogColor);
+    glClearColor(0.0, 0.0, 0.0, 1.0);
+
+    glDepthFunc(GL_LESS);
+    glEnable(GL_DEPTH_TEST);
+    glShadeModel(GL_FLAT);
+}
+
+/*  display() draws an icosahedron.
+ */
+void display(void)
+{
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+    glColor3f (1.0, 1.0, 1.0);
+    glutWireIcosahedron();
+    glFlush();
+}
+
+void myReshape(int w, int h)
+{
+    glViewport(0, 0, w, h);
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    gluPerspective (45.0, (GLfloat) w/(GLfloat) h, 3.0, 5.0);
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity ();
+    glTranslatef (0.0, 0.0, -4.0);  /*  move object into view   */
+}
+
+/*  Main Loop
+ */
+int main(int argc, char** argv)
+{
+    glutInit(&argc, argv);
+    glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
+    glutCreateWindow(argv[0]);
+    myinit();
+    glutReshapeFunc(myReshape);
+    glutDisplayFunc(display);
+    glutMainLoop();
+    return 0;             /* ANSI C requires main to return int. */
+}
+
diff --git a/progs/redbook/dof.c b/progs/redbook/dof.c
new file mode 100644 (file)
index 0000000..166ca9e
--- /dev/null
@@ -0,0 +1,238 @@
+
+/* Copyright (c) Mark J. Kilgard, 1994. */
+
+/*
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+ */
+/*
+ *  dof.c
+ *  This program demonstrates use of the accumulation buffer to
+ *  create an out-of-focus depth-of-field effect.  The teapots
+ *  are drawn several times into the accumulation buffer.  The
+ *  viewing volume is jittered, except at the focal point, where
+ *  the viewing volume is at the same position, each time.  In
+ *  this case, the gold teapot remains in focus.
+ */
+#include <stdlib.h>
+#include <math.h>
+#include <GL/glut.h>
+#include "jitter.h"
+
+#define PI_ 3.14159265358979323846
+
+/*     accFrustum()
+ *  The first 6 arguments are identical to the glFrustum() call.
+ *  
+ *  pixdx and pixdy are anti-alias jitter in pixels. 
+ *  Set both equal to 0.0 for no anti-alias jitter.
+ *  eyedx and eyedy are depth-of field jitter in pixels. 
+ *  Set both equal to 0.0 for no depth of field effects.
+ *
+ *  focus is distance from eye to plane in focus. 
+ *  focus must be greater than, but not equal to 0.0.
+ *
+ *  Note that accFrustum() calls glTranslatef().  You will 
+ *  probably want to insure that your ModelView matrix has been 
+ *  initialized to identity before calling accFrustum().
+ */
+void accFrustum(GLdouble left, GLdouble right, GLdouble bottom, 
+    GLdouble top, GLdouble nnear, GLdouble ffar, GLdouble pixdx, 
+    GLdouble pixdy, GLdouble eyedx, GLdouble eyedy, GLdouble focus)
+{
+    GLdouble xwsize, ywsize; 
+    GLdouble dx, dy;
+    GLint viewport[4];
+
+    glGetIntegerv (GL_VIEWPORT, viewport);
+       
+    xwsize = right - left;
+    ywsize = top - bottom;
+       
+    dx = -(pixdx*xwsize/(GLdouble) viewport[2] + eyedx*nnear/focus);
+    dy = -(pixdy*ywsize/(GLdouble) viewport[3] + eyedy*nnear/focus);
+       
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    glFrustum (left + dx, right + dx, bottom + dy, top + dy, nnear, ffar);
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
+    glTranslatef (-eyedx, -eyedy, 0.0);
+}
+
+/*  accPerspective()
+ * 
+ *  The first 4 arguments are identical to the gluPerspective() call.
+ *  pixdx and pixdy are anti-alias jitter in pixels. 
+ *  Set both equal to 0.0 for no anti-alias jitter.
+ *  eyedx and eyedy are depth-of field jitter in pixels. 
+ *  Set both equal to 0.0 for no depth of field effects.
+ *
+ *  focus is distance from eye to plane in focus. 
+ *  focus must be greater than, but not equal to 0.0.
+ *
+ *  Note that accPerspective() calls accFrustum().
+ */
+void accPerspective(GLdouble fovy, GLdouble aspect, 
+    GLdouble nnear, GLdouble ffar, GLdouble pixdx, GLdouble pixdy, 
+    GLdouble eyedx, GLdouble eyedy, GLdouble focus)
+{
+    GLdouble fov2,left,right,bottom,top;
+
+    fov2 = ((fovy*PI_) / 180.0) / 2.0;
+
+    top = nnear / (cos(fov2) / sin(fov2));
+    bottom = -top;
+
+    right = top * aspect;
+    left = -right;
+
+    accFrustum (left, right, bottom, top, nnear, ffar,
+       pixdx, pixdy, eyedx, eyedy, focus);
+}
+
+void myinit(void)
+{
+    GLfloat ambient[] = { 0.0, 0.0, 0.0, 1.0 };
+    GLfloat diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
+    GLfloat position[] = { 0.0, 3.0, 3.0, 0.0 };
+    
+    GLfloat lmodel_ambient[] = { 0.2, 0.2, 0.2, 1.0 };
+    GLfloat local_view[] = { 0.0 };
+
+    glEnable(GL_DEPTH_TEST);
+    glDepthFunc(GL_LESS);
+
+    glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
+    glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
+    glLightfv(GL_LIGHT0, GL_POSITION, position);
+    
+    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
+    glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, local_view);
+
+    glFrontFace (GL_CW);
+    glEnable(GL_LIGHTING);
+    glEnable(GL_LIGHT0);
+    glEnable(GL_AUTO_NORMAL);
+    glEnable(GL_NORMALIZE);
+
+    glMatrixMode (GL_MODELVIEW);
+    glLoadIdentity ();
+
+    glClearColor(0.0, 0.0, 0.0, 0.0);
+    glClearAccum(0.0, 0.0, 0.0, 0.0);
+}
+
+void renderTeapot (GLfloat x, GLfloat y, GLfloat z, 
+    GLfloat ambr, GLfloat ambg, GLfloat ambb, 
+    GLfloat difr, GLfloat difg, GLfloat difb, 
+    GLfloat specr, GLfloat specg, GLfloat specb, GLfloat shine)
+{
+    float mat[4];
+
+    glPushMatrix();
+    glTranslatef (x, y, z);
+    mat[0] = ambr; mat[1] = ambg; mat[2] = ambb; mat[3] = 1.0; 
+    glMaterialfv (GL_FRONT, GL_AMBIENT, mat);
+    mat[0] = difr; mat[1] = difg; mat[2] = difb;       
+    glMaterialfv (GL_FRONT, GL_DIFFUSE, mat);
+    mat[0] = specr; mat[1] = specg; mat[2] = specb;
+    glMaterialfv (GL_FRONT, GL_SPECULAR, mat);
+    glMaterialf (GL_FRONT, GL_SHININESS, shine*128.0);
+    glutSolidTeapot(0.5);
+    glPopMatrix();
+}
+
+/*  display() draws 5 teapots into the accumulation buffer 
+ *  several times; each time with a jittered perspective.
+ *  The focal point is at z = 5.0, so the gold teapot will 
+ *  stay in focus.  The amount of jitter is adjusted by the
+ *  magnitude of the accPerspective() jitter; in this example, 0.33.
+ *  In this example, the teapots are drawn 8 times.  See jitter.h
+ */
+void display(void)
+{
+    int jitter;
+    GLint viewport[4];
+
+    glGetIntegerv (GL_VIEWPORT, viewport);
+    glClear(GL_ACCUM_BUFFER_BIT);
+
+    for (jitter = 0; jitter < 8; jitter++) {
+       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+       accPerspective (45.0, 
+               (GLdouble) viewport[2]/(GLdouble) viewport[3], 
+               1.0, 15.0, 0.0, 0.0,
+               0.33*j8[jitter].x, 0.33*j8[jitter].y, 5.0);
+/*     ruby, gold, silver, emerald, and cyan teapots   */
+       renderTeapot (-1.1, -0.5, -4.5, 0.1745, 0.01175, 0.01175,
+           0.61424, 0.04136, 0.04136, 0.727811, 0.626959, 0.626959, 0.6);
+       renderTeapot (-0.5, -0.5, -5.0, 0.24725, 0.1995, 0.0745,
+           0.75164, 0.60648, 0.22648, 0.628281, 0.555802, 0.366065, 0.4);
+       renderTeapot (0.2, -0.5, -5.5, 0.19225, 0.19225, 0.19225,
+           0.50754, 0.50754, 0.50754, 0.508273, 0.508273, 0.508273, 0.4);
+       renderTeapot (1.0, -0.5, -6.0, 0.0215, 0.1745, 0.0215, 
+           0.07568, 0.61424, 0.07568, 0.633, 0.727811, 0.633, 0.6);
+       renderTeapot (1.8, -0.5, -6.5, 0.0, 0.1, 0.06, 0.0, 0.50980392, 
+           0.50980392, 0.50196078, 0.50196078, 0.50196078, .25);
+       glAccum (GL_ACCUM, 0.125);
+    }
+
+    glAccum (GL_RETURN, 1.0);
+    glFlush();
+}
+
+void myReshape(int w, int h)
+{
+    glViewport(0, 0, w, h);
+}
+
+/*  Main Loop
+ *  Open window with initial window size, title bar, 
+ *  RGBA display mode, depth buffer, and handle input events.
+ */
+int main(int argc, char** argv)
+{
+    glutInit(&argc, argv);
+    glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB
+                       | GLUT_ACCUM | GLUT_DEPTH);
+    glutCreateWindow (argv[0]);
+    myinit();
+    glutReshapeFunc(myReshape);
+    glutDisplayFunc(display);
+    glutMainLoop();
+    return 0;             /* ANSI C requires main to return int. */
+}
+
diff --git a/progs/redbook/double.c b/progs/redbook/double.c
new file mode 100644 (file)
index 0000000..65dfd4b
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 1993-1997, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*
+ *  double.c
+ *  This is a simple double buffered program.
+ *  Pressing the left mouse button rotates the rectangle.
+ *  Pressing the middle mouse button stops the rotation.
+ */
+#include <GL/glut.h>
+#include <stdlib.h>
+
+static GLfloat spin = 0.0;
+
+void display(void)
+{
+   glClear(GL_COLOR_BUFFER_BIT);
+   glPushMatrix();
+   glRotatef(spin, 0.0, 0.0, 1.0);
+   glColor3f(1.0, 1.0, 1.0);
+   glRectf(-25.0, -25.0, 25.0, 25.0);
+   glPopMatrix();
+
+   glutSwapBuffers();
+}
+
+void spinDisplay(void)
+{
+   spin = spin + 2.0;
+   if (spin > 360.0)
+      spin = spin - 360.0;
+   glutPostRedisplay();
+}
+
+void init(void) 
+{
+   glClearColor (0.0, 0.0, 0.0, 0.0);
+   glShadeModel (GL_FLAT);
+}
+
+void reshape(int w, int h)
+{
+   glViewport (0, 0, (GLsizei) w, (GLsizei) h);
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   glOrtho(-50.0, 50.0, -50.0, 50.0, -1.0, 1.0);
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+}
+
+/* ARGSUSED2 */
+void mouse(int button, int state, int x, int y) 
+{
+   switch (button) {
+      case GLUT_LEFT_BUTTON:
+         if (state == GLUT_DOWN)
+            glutIdleFunc(spinDisplay);
+         break;
+      case GLUT_MIDDLE_BUTTON:
+         if (state == GLUT_DOWN)
+            glutIdleFunc(NULL);
+         break;
+      default:
+         break;
+   }
+}
+   
+/* 
+ *  Request double buffer display mode.
+ *  Register mouse input callback functions
+ */
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
+   glutInitWindowSize (250, 250); 
+   glutInitWindowPosition (100, 100);
+   glutCreateWindow (argv[0]);
+   init ();
+   glutDisplayFunc(display); 
+   glutReshapeFunc(reshape); 
+   glutMouseFunc(mouse);
+   glutMainLoop();
+   return 0;   /* ANSI C requires main to return int. */
+}
diff --git a/progs/redbook/drawf.c b/progs/redbook/drawf.c
new file mode 100644 (file)
index 0000000..5bcccb6
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 1993-1997, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*
+ *  drawf.c
+ *  Draws the bitmapped letter F on the screen (several times).
+ *  This demonstrates use of the glBitmap() call.
+ */
+#include <GL/glut.h>
+#include <stdlib.h>
+
+GLubyte rasters[24] = {
+   0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00,
+   0xff, 0x00, 0xff, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00,
+   0xff, 0xc0, 0xff, 0xc0};
+
+void init(void)
+{
+   glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
+   glClearColor (0.0, 0.0, 0.0, 0.0);
+}
+
+void display(void)
+{
+   glClear(GL_COLOR_BUFFER_BIT);
+   glColor3f (1.0, 1.0, 1.0);
+   glRasterPos2i (20, 20);
+   glBitmap (10, 12, 0.0, 0.0, 11.0, 0.0, rasters);
+   glBitmap (10, 12, 0.0, 0.0, 11.0, 0.0, rasters);
+   glBitmap (10, 12, 0.0, 0.0, 11.0, 0.0, rasters);
+   glFlush();
+}
+
+void reshape(int w, int h)
+{
+   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   glOrtho (0, w, 0, h, -1.0, 1.0);
+   glMatrixMode(GL_MODELVIEW);
+}
+
+/* ARGSUSED1 */
+void keyboard(unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 27:
+         exit(0);
+   }
+}
+
+/*  Main Loop
+ *  Open window with initial window size, title bar, 
+ *  RGBA display mode, and handle input events.
+ */
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
+   glutInitWindowSize(100, 100);
+   glutInitWindowPosition(100, 100);
+   glutCreateWindow(argv[0]);
+   init();
+   glutReshapeFunc(reshape);
+   glutKeyboardFunc(keyboard);
+   glutDisplayFunc(display);
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/redbook/feedback.c b/progs/redbook/feedback.c
new file mode 100644 (file)
index 0000000..4981854
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 1993-1997, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*
+ * feedback.c
+ * This program demonstrates use of OpenGL feedback.  First,
+ * a lighting environment is set up and a few lines are drawn.
+ * Then feedback mode is entered, and the same lines are 
+ * drawn.  The results in the feedback buffer are printed.
+ */
+#include <GL/glut.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+/*  Initialize lighting.
+ */
+void init(void)
+{
+   glEnable(GL_LIGHTING);
+   glEnable(GL_LIGHT0);
+}
+
+/* Draw a few lines and two points, one of which will 
+ * be clipped.  If in feedback mode, a passthrough token 
+ * is issued between the each primitive.
+ */
+void drawGeometry (GLenum mode)
+{
+   glBegin (GL_LINE_STRIP);
+   glNormal3f (0.0, 0.0, 1.0);
+   glVertex3f (30.0, 30.0, 0.0);
+   glVertex3f (50.0, 60.0, 0.0);
+   glVertex3f (70.0, 40.0, 0.0);
+   glEnd ();
+   if (mode == GL_FEEDBACK)
+      glPassThrough (1.0);
+   glBegin (GL_POINTS);
+   glVertex3f (-100.0, -100.0, -100.0);  /*  will be clipped  */
+   glEnd ();
+   if (mode == GL_FEEDBACK)
+      glPassThrough (2.0);
+   glBegin (GL_POINTS);
+   glNormal3f (0.0, 0.0, 1.0);
+   glVertex3f (50.0, 50.0, 0.0);
+   glEnd ();
+}
+
+/* Write contents of one vertex to stdout.     */
+void print3DcolorVertex (GLint size, GLint *count, 
+                         GLfloat *buffer)
+{
+   int i;
+
+   printf ("  ");
+   for (i = 0; i < 7; i++) {
+      printf ("%4.2f ", buffer[size-(*count)]);
+      *count = *count - 1;
+   }
+   printf ("\n");
+}
+
+/*  Write contents of entire buffer.  (Parse tokens!)  */
+void printBuffer(GLint size, GLfloat *buffer)
+{
+   GLint count;
+   GLfloat token;
+
+   count = size;
+   while (count) {
+      token = buffer[size-count]; count--;
+      if (token == GL_PASS_THROUGH_TOKEN) {
+         printf ("GL_PASS_THROUGH_TOKEN\n");
+         printf ("  %4.2f\n", buffer[size-count]);
+         count--;
+      }
+      else if (token == GL_POINT_TOKEN) {
+         printf ("GL_POINT_TOKEN\n");
+         print3DcolorVertex (size, &count, buffer);
+      }
+      else if (token == GL_LINE_TOKEN) {
+         printf ("GL_LINE_TOKEN\n");
+         print3DcolorVertex (size, &count, buffer);
+         print3DcolorVertex (size, &count, buffer);
+      }
+      else if (token == GL_LINE_RESET_TOKEN) {
+         printf ("GL_LINE_RESET_TOKEN\n");
+         print3DcolorVertex (size, &count, buffer);
+         print3DcolorVertex (size, &count, buffer);
+      }
+   }
+}
+
+void display(void)
+{
+   GLfloat feedBuffer[1024];
+   GLint size;
+
+   glMatrixMode (GL_PROJECTION);
+   glLoadIdentity ();
+   glOrtho (0.0, 100.0, 0.0, 100.0, 0.0, 1.0);
+
+   glClearColor (0.0, 0.0, 0.0, 0.0);
+   glClear(GL_COLOR_BUFFER_BIT);
+   drawGeometry (GL_RENDER);
+
+   glFeedbackBuffer (1024, GL_3D_COLOR, feedBuffer);
+   (void) glRenderMode (GL_FEEDBACK);
+   drawGeometry (GL_FEEDBACK);
+
+   size = glRenderMode (GL_RENDER);
+   printBuffer (size, feedBuffer);
+}
+
+/* ARGSUSED1 */
+void keyboard(unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 27:
+         exit(0);
+         break;
+   }
+}
+
+/*  Main Loop  */
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
+   glutInitWindowSize (100, 100);
+   glutInitWindowPosition (100, 100);
+   glutCreateWindow(argv[0]);
+   init();
+   glutDisplayFunc(display);
+   glutKeyboardFunc (keyboard);
+   glutMainLoop();
+   return 0; 
+}
diff --git a/progs/redbook/fog.c b/progs/redbook/fog.c
new file mode 100644 (file)
index 0000000..5f8a4e4
--- /dev/null
@@ -0,0 +1,186 @@
+
+/* Copyright (c) Mark J. Kilgard, 1994. */
+
+/**
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+ */
+/*
+ *  fog.c
+ *  This program draws 5 red teapots, each at a different 
+ *  z distance from the eye, in different types of fog.  
+ *  Pressing the left mouse button chooses between 3 types of 
+ *  fog:  exponential, exponential squared, and linear.  
+ *  In this program, there is a fixed density value, as well 
+ *  as fixed start and end values for the linear fog.
+ */
+#include <stdlib.h>
+#include <math.h>
+#include <GL/glut.h>
+
+GLint fogMode;
+
+void 
+selectFog(int mode)
+{
+    switch(mode) {
+    case GL_LINEAR:
+        glFogf(GL_FOG_START, 1.0);
+        glFogf(GL_FOG_END, 5.0);
+       /* falls through */
+    case GL_EXP2:
+    case GL_EXP:
+        glFogi(GL_FOG_MODE, mode);
+       glutPostRedisplay();
+       break;
+    case 0:
+       exit(0);
+    }
+}
+
+/*  Initialize z-buffer, projection matrix, light source, 
+ *  and lighting model.  Do not specify a material property here.
+ */
+void 
+myinit(void)
+{
+    GLfloat position[] =
+    {0.0, 3.0, 3.0, 0.0};
+    GLfloat local_view[] =
+    {0.0};
+
+    glEnable(GL_DEPTH_TEST);
+    glDepthFunc(GL_LESS);
+
+    glLightfv(GL_LIGHT0, GL_POSITION, position);
+    glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, local_view);
+
+    glFrontFace(GL_CW);
+    glEnable(GL_LIGHTING);
+    glEnable(GL_LIGHT0);
+    glEnable(GL_AUTO_NORMAL);
+    glEnable(GL_NORMALIZE);
+    glEnable(GL_FOG);
+    {
+        GLfloat fogColor[4] =
+        {0.5, 0.5, 0.5, 1.0};
+
+        fogMode = GL_EXP;
+        glFogi(GL_FOG_MODE, fogMode);
+        glFogfv(GL_FOG_COLOR, fogColor);
+        glFogf(GL_FOG_DENSITY, 0.35);
+        glHint(GL_FOG_HINT, GL_DONT_CARE);
+        glClearColor(0.5, 0.5, 0.5, 1.0);
+    }
+}
+
+void 
+renderRedTeapot(GLfloat x, GLfloat y, GLfloat z)
+{
+    float mat[4];
+
+    glPushMatrix();
+    glTranslatef(x, y, z);
+    mat[0] = 0.1745;
+    mat[1] = 0.01175;
+    mat[2] = 0.01175;
+    mat[3] = 1.0;
+    glMaterialfv(GL_FRONT, GL_AMBIENT, mat);
+    mat[0] = 0.61424;
+    mat[1] = 0.04136;
+    mat[2] = 0.04136;
+    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat);
+    mat[0] = 0.727811;
+    mat[1] = 0.626959;
+    mat[2] = 0.626959;
+    glMaterialfv(GL_FRONT, GL_SPECULAR, mat);
+    glMaterialf(GL_FRONT, GL_SHININESS, 0.6 * 128.0);
+    glutSolidTeapot(1.0);
+    glPopMatrix();
+}
+
+/*  display() draws 5 teapots at different z positions.
+ */
+void 
+display(void)
+{
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+    renderRedTeapot(-4.0, -0.5, -1.0);
+    renderRedTeapot(-2.0, -0.5, -2.0);
+    renderRedTeapot(0.0, -0.5, -3.0);
+    renderRedTeapot(2.0, -0.5, -4.0);
+    renderRedTeapot(4.0, -0.5, -5.0);
+    glFlush();
+}
+
+void 
+myReshape(int w, int h)
+{
+    glViewport(0, 0, w, h);
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    if (w <= (h * 3))
+        glOrtho(-6.0, 6.0, -2.0 * ((GLfloat) h * 3) / (GLfloat) w,
+            2.0 * ((GLfloat) h * 3) / (GLfloat) w, 0.0, 10.0);
+    else
+        glOrtho(-6.0 * (GLfloat) w / ((GLfloat) h * 3),
+            6.0 * (GLfloat) w / ((GLfloat) h * 3), -2.0, 2.0, 0.0, 10.0);
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
+}
+
+/*  Main Loop
+ *  Open window with initial window size, title bar, 
+ *  RGBA display mode, depth buffer, and handle input events.
+ */
+int 
+main(int argc, char **argv)
+{
+    glutInit(&argc, argv);
+    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
+    glutInitWindowSize(450, 150);
+    glutCreateWindow(argv[0]);
+    myinit();
+    glutReshapeFunc(myReshape);
+    glutDisplayFunc(display);
+    glutCreateMenu(selectFog);
+    glutAddMenuEntry("Fog EXP", GL_EXP);
+    glutAddMenuEntry("Fog EXP2", GL_EXP2);
+    glutAddMenuEntry("Fog LINEAR", GL_LINEAR);
+    glutAddMenuEntry("Quit", 0);
+    glutAttachMenu(GLUT_RIGHT_BUTTON);
+    glutMainLoop();
+    return 0;             /* ANSI C requires main to return int. */
+}
diff --git a/progs/redbook/fogindex.c b/progs/redbook/fogindex.c
new file mode 100644 (file)
index 0000000..b409c95
--- /dev/null
@@ -0,0 +1,138 @@
+
+/* Copyright (c) Mark J. Kilgard, 1994. */
+
+/*
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+ */
+/*
+ *  fogindex.c
+ *  This program demonstrates fog in color index mode.  
+ *  Three cones are drawn at different z values in a linear 
+ *  fog.  32 contiguous colors (from 16 to 47) are loaded 
+ *  with a color ramp.
+ */
+#include <stdlib.h>
+#include <GL/glut.h>
+
+/*  Initialize color map and fog.  Set screen clear color 
+ *  to end of color ramp.
+ */
+#define NUM_COLORS 32
+#define RAMPSTART 16
+
+void 
+myinit(void)
+{
+  int i;
+
+  glEnable(GL_DEPTH_TEST);
+  glDepthFunc(GL_LESS);
+  for (i = 0; i < NUM_COLORS; i++) {
+    GLfloat shade;
+    shade = (GLfloat) (NUM_COLORS - i) / (GLfloat) NUM_COLORS;
+    glutSetColor(16 + i, shade, shade, shade);
+  }
+  glEnable(GL_FOG);
+
+  glFogi(GL_FOG_MODE, GL_LINEAR);
+  glFogi(GL_FOG_INDEX, NUM_COLORS);
+  glFogf(GL_FOG_START, 0.0);
+  glFogf(GL_FOG_END, 4.0);
+  glHint(GL_FOG_HINT, GL_NICEST);
+  glClearIndex((GLfloat) (NUM_COLORS + RAMPSTART - 1));
+}
+
+/*  display() renders 3 cones at different z positions.
+ */
+void 
+display(void)
+{
+  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+  glPushMatrix();
+  glTranslatef(-1.0, -1.0, -1.0);
+  glRotatef(-90.0, 1.0, 0.0, 0.0);
+  glIndexi(RAMPSTART);
+  glutSolidCone(1.0, 2.0, 10, 10);
+  glPopMatrix();
+
+  glPushMatrix();
+  glTranslatef(0.0, -1.0, -2.25);
+  glRotatef(-90.0, 1.0, 0.0, 0.0);
+  glIndexi(RAMPSTART);
+  glutSolidCone(1.0, 2.0, 10, 10);
+  glPopMatrix();
+
+  glPushMatrix();
+  glTranslatef(1.0, -1.0, -3.5);
+  glRotatef(-90.0, 1.0, 0.0, 0.0);
+  glIndexi(RAMPSTART);
+  glutSolidCone(1.0, 2.0, 10, 10);
+  glPopMatrix();
+  glFlush();
+}
+
+void 
+myReshape(int w, int h)
+{
+  glViewport(0, 0, w, h);
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+  if (w <= h)
+    glOrtho(-2.0, 2.0, -2.0 * (GLfloat) h / (GLfloat) w,
+      2.0 * (GLfloat) h / (GLfloat) w, 0.0, 10.0);
+  else
+    glOrtho(-2.0 * (GLfloat) w / (GLfloat) h,
+      2.0 * (GLfloat) w / (GLfloat) h, -2.0, 2.0, 0.0, 10.0);
+  glMatrixMode(GL_MODELVIEW);
+  glLoadIdentity();
+}
+
+/*  Main Loop
+ *  Open window with initial window size, title bar, 
+ *  RGBA display mode, depth buffer, and handle input events.
+ */
+int 
+main(int argc, char **argv)
+{
+  glutInit(&argc, argv);
+  glutInitDisplayMode(GLUT_SINGLE | GLUT_INDEX | GLUT_DEPTH);
+  glutCreateWindow(argv[0]);
+  myinit();
+  glutReshapeFunc(myReshape);
+  glutDisplayFunc(display);
+  glutMainLoop();
+  return 0;             /* ANSI C requires main to return int. */
+}
diff --git a/progs/redbook/font.c b/progs/redbook/font.c
new file mode 100644 (file)
index 0000000..2d92e9b
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 1993-1997, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*
+ *  font.c
+ *
+ *  Draws some text in a bitmapped font.  Uses glBitmap() 
+ *  and other pixel routines.  Also demonstrates use of 
+ *  display lists.
+ */
+#include <GL/glut.h>
+#include <stdlib.h>
+#include <string.h>
+
+GLubyte space[] = 
+{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+GLubyte letters[][13] = {
+{0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xff, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18}, 
+{0x00, 0x00, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe}, 
+{0x00, 0x00, 0x7e, 0xe7, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xe7, 0x7e}, 
+{0x00, 0x00, 0xfc, 0xce, 0xc7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc7, 0xce, 0xfc}, 
+{0x00, 0x00, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xff}, 
+{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xff}, 
+{0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xcf, 0xc0, 0xc0, 0xc0, 0xc0, 0xe7, 0x7e}, 
+{0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xff, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3}, 
+{0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e}, 
+{0x00, 0x00, 0x7c, 0xee, 0xc6, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06}, 
+{0x00, 0x00, 0xc3, 0xc6, 0xcc, 0xd8, 0xf0, 0xe0, 0xf0, 0xd8, 0xcc, 0xc6, 0xc3}, 
+{0x00, 0x00, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0}, 
+{0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xff, 0xff, 0xe7, 0xc3}, 
+{0x00, 0x00, 0xc7, 0xc7, 0xcf, 0xcf, 0xdf, 0xdb, 0xfb, 0xf3, 0xf3, 0xe3, 0xe3}, 
+{0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xe7, 0x7e}, 
+{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe}, 
+{0x00, 0x00, 0x3f, 0x6e, 0xdf, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c}, 
+{0x00, 0x00, 0xc3, 0xc6, 0xcc, 0xd8, 0xf0, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe}, 
+{0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x07, 0x7e, 0xe0, 0xc0, 0xc0, 0xe7, 0x7e}, 
+{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff}, 
+{0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3}, 
+{0x00, 0x00, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3}, 
+{0x00, 0x00, 0xc3, 0xe7, 0xff, 0xff, 0xdb, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3}, 
+{0x00, 0x00, 0xc3, 0x66, 0x66, 0x3c, 0x3c, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3}, 
+{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3}, 
+{0x00, 0x00, 0xff, 0xc0, 0xc0, 0x60, 0x30, 0x7e, 0x0c, 0x06, 0x03, 0x03, 0xff}
+};
+
+GLuint fontOffset;
+
+void makeRasterFont(void)
+{
+   GLuint i, j;
+   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+   fontOffset = glGenLists (128);
+   for (i = 0,j = 'A'; i < 26; i++,j++) {
+      glNewList(fontOffset + j, GL_COMPILE);
+      glBitmap(8, 13, 0.0, 2.0, 10.0, 0.0, letters[i]);
+      glEndList();
+   }
+   glNewList(fontOffset + ' ', GL_COMPILE);
+   glBitmap(8, 13, 0.0, 2.0, 10.0, 0.0, space);
+   glEndList();
+}
+
+void init(void)
+{
+   glShadeModel (GL_FLAT);
+   makeRasterFont();
+}
+
+void printString(char *s)
+{
+   glPushAttrib (GL_LIST_BIT);
+   glListBase(fontOffset);
+   glCallLists((GLsizei) strlen(s), GL_UNSIGNED_BYTE, (GLubyte *) s);
+   glPopAttrib ();
+}
+
+/* Everything above this line could be in a library 
+ * that defines a font.  To make it work, you've got 
+ * to call makeRasterFont() before you start making 
+ * calls to printString().
+ */
+void display(void)
+{
+   GLfloat white[3] = { 1.0, 1.0, 1.0 };
+
+   glClear(GL_COLOR_BUFFER_BIT);
+   glColor3fv(white);
+
+   glRasterPos2i(20, 60);
+   printString("THE QUICK BROWN FOX JUMPS");
+   glRasterPos2i(20, 40);
+   printString("OVER A LAZY DOG");
+   glFlush ();
+}
+
+void reshape(int w, int h)
+{
+   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   glOrtho (0.0, w, 0.0, h, -1.0, 1.0);
+   glMatrixMode(GL_MODELVIEW);
+}
+
+/* ARGSUSED1 */
+void keyboard(unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 27:
+         exit(0);
+   }
+}
+
+/*  Main Loop
+ *  Open window with initial window size, title bar, 
+ *  RGBA display mode, and handle input events.
+ */
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
+   glutInitWindowSize(300, 100);
+   glutInitWindowPosition (100, 100);
+   glutCreateWindow(argv[0]);
+   init();
+   glutReshapeFunc(reshape);
+   glutKeyboardFunc(keyboard);
+   glutDisplayFunc(display);
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/redbook/hello.c b/progs/redbook/hello.c
new file mode 100644 (file)
index 0000000..516c9ec
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 1993-1997, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*
+ * hello.c
+ * This is a simple, introductory OpenGL program.
+ */
+#include <GL/glut.h>
+
+void display(void)
+{
+/* clear all pixels  */
+   glClear (GL_COLOR_BUFFER_BIT);
+
+/* draw white polygon (rectangle) with corners at
+ * (0.25, 0.25, 0.0) and (0.75, 0.75, 0.0)  
+ */
+   glColor3f (1.0, 1.0, 1.0);
+   glBegin(GL_POLYGON);
+      glVertex3f (0.25, 0.25, 0.0);
+      glVertex3f (0.75, 0.25, 0.0);
+      glVertex3f (0.75, 0.75, 0.0);
+      glVertex3f (0.25, 0.75, 0.0);
+   glEnd();
+
+/* don't wait!  
+ * start processing buffered OpenGL routines 
+ */
+   glFlush ();
+}
+
+void init (void) 
+{
+/* select clearing color       */
+   glClearColor (0.0, 0.0, 0.0, 0.0);
+
+/* initialize viewing values  */
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
+}
+
+/* 
+ * Declare initial window size, position, and display mode
+ * (single buffer and RGBA).  Open window with "hello"
+ * in its title bar.  Call initialization routines.
+ * Register callback function to display graphics.
+ * Enter main loop and process events.
+ */
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
+   glutInitWindowSize (250, 250); 
+   glutInitWindowPosition (100, 100);
+   glutCreateWindow ("hello");
+   init ();
+   glutDisplayFunc(display); 
+   glutMainLoop();
+   return 0;   /* ANSI C requires main to return int. */
+}
diff --git a/progs/redbook/image.c b/progs/redbook/image.c
new file mode 100644 (file)
index 0000000..8e62f5a
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 1993-1997, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*  image.c
+ *  This program demonstrates drawing pixels and shows the effect
+ *  of glDrawPixels(), glCopyPixels(), and glPixelZoom().
+ *  Interaction: moving the mouse while pressing the mouse button
+ *  will copy the image in the lower-left corner of the window
+ *  to the mouse position, using the current pixel zoom factors.
+ *  There is no attempt to prevent you from drawing over the original
+ *  image.  If you press the 'r' key, the original image and zoom
+ *  factors are reset.  If you press the 'z' or 'Z' keys, you change
+ *  the zoom factors.
+ */
+#include <GL/glut.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+/*     Create checkerboard image       */
+#define        checkImageWidth 64
+#define        checkImageHeight 64
+GLubyte checkImage[checkImageHeight][checkImageWidth][3];
+
+static GLdouble zoomFactor = 1.0;
+static GLint height;
+
+void makeCheckImage(void)
+{
+   int i, j, c;
+    
+   for (i = 0; i < checkImageHeight; i++) {
+      for (j = 0; j < checkImageWidth; j++) {
+         c = ((((i&0x8)==0)^((j&0x8))==0))*255;
+         checkImage[i][j][0] = (GLubyte) c;
+         checkImage[i][j][1] = (GLubyte) c;
+         checkImage[i][j][2] = (GLubyte) c;
+      }
+   }
+}
+
+void init(void)
+{    
+   glClearColor (0.0, 0.0, 0.0, 0.0);
+   glShadeModel(GL_FLAT);
+   makeCheckImage();
+   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+}
+
+void display(void)
+{
+   glClear(GL_COLOR_BUFFER_BIT);
+   glRasterPos2i(0, 0);
+   glDrawPixels(checkImageWidth, checkImageHeight, GL_RGB, 
+                GL_UNSIGNED_BYTE, checkImage);
+   glFlush();
+}
+
+void reshape(int w, int h)
+{
+   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
+   height = (GLint) h;
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   gluOrtho2D(0.0, (GLdouble) w, 0.0, (GLdouble) h);
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+}
+
+void motion(int x, int y)
+{
+   static GLint screeny;
+   
+   screeny = height - (GLint) y;
+   glRasterPos2i (x, screeny);
+   glPixelZoom (zoomFactor, zoomFactor);
+   glCopyPixels (0, 0, checkImageWidth, checkImageHeight, GL_COLOR);
+   glPixelZoom (1.0, 1.0);
+   glFlush ();
+}
+
+/* ARGSUSED1 */
+void keyboard(unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 'r':
+      case 'R':
+         zoomFactor = 1.0;
+         glutPostRedisplay();
+         printf ("zoomFactor reset to 1.0\n");
+         break;
+      case 'z':
+         zoomFactor += 0.5;
+         if (zoomFactor >= 3.0) 
+            zoomFactor = 3.0;
+         printf ("zoomFactor is now %4.1f\n", zoomFactor);
+         break;
+      case 'Z':
+         zoomFactor -= 0.5;
+         if (zoomFactor <= 0.5) 
+            zoomFactor = 0.5;
+         printf ("zoomFactor is now %4.1f\n", zoomFactor);
+         break;
+      case 27:
+         exit(0);
+         break;
+      default:
+         break;
+   }
+}
+
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
+   glutInitWindowSize(250, 250);
+   glutInitWindowPosition(100, 100);
+   glutCreateWindow(argv[0]);
+   init();
+   glutDisplayFunc(display);
+   glutReshapeFunc(reshape);
+   glutKeyboardFunc(keyboard);
+   glutMotionFunc(motion);
+   glutMainLoop();
+   return 0; 
+}
diff --git a/progs/redbook/jitter.h b/progs/redbook/jitter.h
new file mode 100644 (file)
index 0000000..1ec08c8
--- /dev/null
@@ -0,0 +1,222 @@
+/*
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+ */
+/*
+jitter.h
+
+This file contains jitter point arrays for 2,3,4,8,15,24 and 66 jitters.
+
+The arrays are named j2, j3, etc. Each element in the array has the form,
+for example, j8[0].x and j8[0].y
+
+Values are floating point in the range -.5 < x < .5, -.5 < y < .5, and
+have a gaussian distribution around the origin.
+
+Use these to do model jittering for scene anti-aliasing and view volume
+jittering for depth of field effects. Use in conjunction with the 
+accwindow() routine.
+*/
+
+typedef struct 
+{
+       GLfloat x, y;
+} jitter_point;
+
+#define MAX_SAMPLES  66
+
+
+/* 2 jitter points */
+jitter_point j2[] =
+{
+       { 0.246490,  0.249999},
+       {-0.246490, -0.249999}
+};
+
+
+/* 3 jitter points */
+jitter_point j3[] =
+{
+       {-0.373411, -0.250550},
+       { 0.256263,  0.368119},
+       { 0.117148, -0.117570}
+};
+
+
+/* 4 jitter points */
+jitter_point j4[] =
+{
+       {-0.208147,  0.353730},
+       { 0.203849, -0.353780},
+       {-0.292626, -0.149945},
+       { 0.296924,  0.149994}
+};
+
+
+/* 8 jitter points */
+jitter_point j8[] =
+{
+       {-0.334818,  0.435331},
+       { 0.286438, -0.393495},
+       { 0.459462,  0.141540},
+       {-0.414498, -0.192829},
+       {-0.183790,  0.082102},
+       {-0.079263, -0.317383},
+       { 0.102254,  0.299133},
+       { 0.164216, -0.054399}
+};
+
+
+/* 15 jitter points */
+jitter_point j15[] =
+{
+       { 0.285561,  0.188437},
+       { 0.360176, -0.065688},
+       {-0.111751,  0.275019},
+       {-0.055918, -0.215197},
+       {-0.080231, -0.470965},
+       { 0.138721,  0.409168},
+       { 0.384120,  0.458500},
+       {-0.454968,  0.134088},
+       { 0.179271, -0.331196},
+       {-0.307049, -0.364927},
+       { 0.105354, -0.010099},
+       {-0.154180,  0.021794},
+       {-0.370135, -0.116425},
+       { 0.451636, -0.300013},
+       {-0.370610,  0.387504}
+};
+
+
+/* 24 jitter points */
+jitter_point j24[] =
+{
+       { 0.030245,  0.136384},
+       { 0.018865, -0.348867},
+       {-0.350114, -0.472309},
+       { 0.222181,  0.149524},
+       {-0.393670, -0.266873},
+       { 0.404568,  0.230436},
+       { 0.098381,  0.465337},
+       { 0.462671,  0.442116},
+       { 0.400373, -0.212720},
+       {-0.409988,  0.263345},
+       {-0.115878, -0.001981},
+       { 0.348425, -0.009237},
+       {-0.464016,  0.066467},
+       {-0.138674, -0.468006},
+       { 0.144932, -0.022780},
+       {-0.250195,  0.150161},
+       {-0.181400, -0.264219},
+       { 0.196097, -0.234139},
+       {-0.311082, -0.078815},
+       { 0.268379,  0.366778},
+       {-0.040601,  0.327109},
+       {-0.234392,  0.354659},
+       {-0.003102, -0.154402},
+       { 0.297997, -0.417965}
+};
+
+
+/* 66 jitter points */
+jitter_point j66[] =
+{
+       { 0.266377, -0.218171},
+       {-0.170919, -0.429368},
+       { 0.047356, -0.387135},
+       {-0.430063,  0.363413},
+       {-0.221638, -0.313768},
+       { 0.124758, -0.197109},
+       {-0.400021,  0.482195},
+       { 0.247882,  0.152010},
+       {-0.286709, -0.470214},
+       {-0.426790,  0.004977},
+       {-0.361249, -0.104549},
+       {-0.040643,  0.123453},
+       {-0.189296,  0.438963},
+       {-0.453521, -0.299889},
+       { 0.408216, -0.457699},
+       { 0.328973, -0.101914},
+       {-0.055540, -0.477952},
+       { 0.194421,  0.453510},
+       { 0.404051,  0.224974},
+       { 0.310136,  0.419700},
+       {-0.021743,  0.403898},
+       {-0.466210,  0.248839},
+       { 0.341369,  0.081490},
+       { 0.124156, -0.016859},
+       {-0.461321, -0.176661},
+       { 0.013210,  0.234401},
+       { 0.174258, -0.311854},
+       { 0.294061,  0.263364},
+       {-0.114836,  0.328189},
+       { 0.041206, -0.106205},
+       { 0.079227,  0.345021},
+       {-0.109319, -0.242380},
+       { 0.425005, -0.332397},
+       { 0.009146,  0.015098},
+       {-0.339084, -0.355707},
+       {-0.224596, -0.189548},
+       { 0.083475,  0.117028},
+       { 0.295962, -0.334699},
+       { 0.452998,  0.025397},
+       { 0.206511, -0.104668},
+       { 0.447544, -0.096004},
+       {-0.108006, -0.002471},
+       {-0.380810,  0.130036},
+       {-0.242440,  0.186934},
+       {-0.200363,  0.070863},
+       {-0.344844, -0.230814},
+       { 0.408660,  0.345826},
+       {-0.233016,  0.305203},
+       { 0.158475, -0.430762},
+       { 0.486972,  0.139163},
+       {-0.301610,  0.009319},
+       { 0.282245, -0.458671},
+       { 0.482046,  0.443890},
+       {-0.121527,  0.210223},
+       {-0.477606, -0.424878},
+       {-0.083941, -0.121440},
+       {-0.345773,  0.253779},
+       { 0.234646,  0.034549},
+       { 0.394102, -0.210901},
+       {-0.312571,  0.397656},
+       { 0.200906,  0.333293},
+       { 0.018703, -0.261792},
+       {-0.209349, -0.065383},
+       { 0.076248,  0.478538},
+       {-0.073036, -0.355064},
+       { 0.145087,  0.221726}
+};
diff --git a/progs/redbook/light.c b/progs/redbook/light.c
new file mode 100644 (file)
index 0000000..0eed85e
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 1993-1997, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*
+ *  light.c
+ *  This program demonstrates the use of the OpenGL lighting
+ *  model.  A sphere is drawn using a grey material characteristic.
+ *  A single light source illuminates the object.
+ */
+#include <GL/glut.h>
+#include <stdlib.h>
+
+/*  Initialize material property, light source, lighting model,
+ *  and depth buffer.
+ */
+void init(void) 
+{
+   GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
+   GLfloat mat_shininess[] = { 50.0 };
+   GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
+
+   glClearColor (0.0, 0.0, 0.0, 0.0);
+   glShadeModel (GL_SMOOTH);
+
+   glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
+   glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
+   glLightfv(GL_LIGHT0, GL_POSITION, light_position);
+
+   glEnable(GL_LIGHTING);
+   glEnable(GL_LIGHT0);
+   glEnable(GL_DEPTH_TEST);
+}
+
+void display(void)
+{
+   glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+   glutSolidSphere (1.0, 20, 16);
+   glFlush ();
+}
+
+void reshape (int w, int h)
+{
+   glViewport (0, 0, (GLsizei) w, (GLsizei) h);
+   glMatrixMode (GL_PROJECTION);
+   glLoadIdentity();
+   if (w <= h)
+      glOrtho (-1.5, 1.5, -1.5*(GLfloat)h/(GLfloat)w,
+         1.5*(GLfloat)h/(GLfloat)w, -10.0, 10.0);
+   else
+      glOrtho (-1.5*(GLfloat)w/(GLfloat)h,
+         1.5*(GLfloat)w/(GLfloat)h, -1.5, 1.5, -10.0, 10.0);
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+}
+
+/* ARGSUSED1 */
+void keyboard(unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 27:
+         exit(0);
+         break;
+   }
+}
+
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
+   glutInitWindowSize (500, 500); 
+   glutInitWindowPosition (100, 100);
+   glutCreateWindow (argv[0]);
+   init ();
+   glutDisplayFunc(display); 
+   glutReshapeFunc(reshape);
+   glutKeyboardFunc(keyboard);
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/redbook/lines.c b/progs/redbook/lines.c
new file mode 100644 (file)
index 0000000..b34d4c4
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 1993-1997, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*
+ *  lines.c
+ *  This program demonstrates geometric primitives and
+ *  their attributes.
+ */
+#include <GL/glut.h>
+#include <stdlib.h>
+
+#define drawOneLine(x1,y1,x2,y2)  glBegin(GL_LINES);  \
+   glVertex2f ((x1),(y1)); glVertex2f ((x2),(y2)); glEnd();
+
+void init(void) 
+{
+   glClearColor (0.0, 0.0, 0.0, 0.0);
+   glShadeModel (GL_FLAT);
+}
+
+void display(void)
+{
+   int i;
+
+   glClear (GL_COLOR_BUFFER_BIT);
+
+/* select white for all lines  */
+   glColor3f (1.0, 1.0, 1.0);
+
+/* in 1st row, 3 lines, each with a different stipple  */
+   glEnable (GL_LINE_STIPPLE);
+   
+   glLineStipple (1, 0x0101);  /*  dotted  */
+   drawOneLine (50.0, 125.0, 150.0, 125.0);
+   glLineStipple (1, 0x00FF);  /*  dashed  */
+   drawOneLine (150.0, 125.0, 250.0, 125.0);
+   glLineStipple (1, 0x1C47);  /*  dash/dot/dash  */
+   drawOneLine (250.0, 125.0, 350.0, 125.0);
+
+/* in 2nd row, 3 wide lines, each with different stipple */
+   glLineWidth (5.0);
+   glLineStipple (1, 0x0101);  /*  dotted  */
+   drawOneLine (50.0, 100.0, 150.0, 100.0);
+   glLineStipple (1, 0x00FF);  /*  dashed  */
+   drawOneLine (150.0, 100.0, 250.0, 100.0);
+   glLineStipple (1, 0x1C47);  /*  dash/dot/dash  */
+   drawOneLine (250.0, 100.0, 350.0, 100.0);
+   glLineWidth (1.0);
+
+/* in 3rd row, 6 lines, with dash/dot/dash stipple  */
+/* as part of a single connected line strip         */
+   glLineStipple (1, 0x1C47);  /*  dash/dot/dash  */
+   glBegin (GL_LINE_STRIP);
+   for (i = 0; i < 7; i++)
+      glVertex2f (50.0 + ((GLfloat) i * 50.0), 75.0);
+   glEnd ();
+
+/* in 4th row, 6 independent lines with same stipple  */
+   for (i = 0; i < 6; i++) {
+      drawOneLine (50.0 + ((GLfloat) i * 50.0), 50.0,
+         50.0 + ((GLfloat)(i+1) * 50.0), 50.0);
+   }
+
+/* in 5th row, 1 line, with dash/dot/dash stipple    */
+/* and a stipple repeat factor of 5                  */
+   glLineStipple (5, 0x1C47);  /*  dash/dot/dash  */
+   drawOneLine (50.0, 25.0, 350.0, 25.0);
+
+   glDisable (GL_LINE_STIPPLE);
+   glFlush ();
+}
+
+void reshape (int w, int h)
+{
+   glViewport (0, 0, (GLsizei) w, (GLsizei) h);
+   glMatrixMode (GL_PROJECTION);
+   glLoadIdentity ();
+   gluOrtho2D (0.0, (GLdouble) w, 0.0, (GLdouble) h);
+}
+
+/* ARGSUSED1 */
+void keyboard(unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 27:
+         exit(0);
+         break;
+   }
+}
+
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
+   glutInitWindowSize (400, 150); 
+   glutInitWindowPosition (100, 100);
+   glutCreateWindow (argv[0]);
+   init ();
+   glutDisplayFunc(display); 
+   glutReshapeFunc(reshape);
+   glutKeyboardFunc(keyboard);
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/redbook/list.c b/progs/redbook/list.c
new file mode 100644 (file)
index 0000000..3b4f44b
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 1993-1997, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*
+ *  list.c
+ *  This program demonstrates how to make and execute a 
+ *  display list.  Note that attributes, such as current 
+ *  color and matrix, are changed.
+ */
+#include <GL/glut.h>
+#include <stdlib.h>
+
+GLuint listName;
+
+static void init (void)
+{
+   listName = glGenLists (1);
+   glNewList (listName, GL_COMPILE);
+      glColor3f (1.0, 0.0, 0.0);  /*  current color red  */
+      glBegin (GL_TRIANGLES);
+      glVertex2f (0.0, 0.0);
+      glVertex2f (1.0, 0.0);
+      glVertex2f (0.0, 1.0);
+      glEnd ();
+      glTranslatef (1.5, 0.0, 0.0); /*  move position  */
+   glEndList ();
+   glShadeModel (GL_FLAT);
+}
+
+static void drawLine (void)
+{
+   glBegin (GL_LINES);
+   glVertex2f (0.0, 0.5);
+   glVertex2f (15.0, 0.5);
+   glEnd ();
+}
+
+void display(void)
+{
+   GLuint i;
+
+   glClear (GL_COLOR_BUFFER_BIT);
+   glColor3f (0.0, 1.0, 0.0);  /*  current color green  */
+   for (i = 0; i < 10; i++)    /*  draw 10 triangles    */
+      glCallList (listName);
+   drawLine ();  /*  is this line green?  NO!  */
+                 /*  where is the line drawn?  */
+   glFlush ();
+}
+
+void reshape(int w, int h)
+{
+   glViewport(0, 0, w, h);
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   if (w <= h) 
+      gluOrtho2D (0.0, 2.0, -0.5 * (GLfloat) h/(GLfloat) w, 
+         1.5 * (GLfloat) h/(GLfloat) w);
+   else 
+      gluOrtho2D (0.0, 2.0 * (GLfloat) w/(GLfloat) h, -0.5, 1.5); 
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+}
+
+/* ARGSUSED1 */
+void keyboard(unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 27:
+         exit(0);
+         break;
+   }
+}
+
+/*  Main Loop
+ *  Open window with initial window size, title bar, 
+ *  RGBA display mode, and handle input events.
+ */
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
+   glutInitWindowSize(650, 50);
+   glutCreateWindow(argv[0]);
+   init ();
+   glutReshapeFunc (reshape);
+   glutDisplayFunc (display);
+   glutKeyboardFunc (keyboard);
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/redbook/material.c b/progs/redbook/material.c
new file mode 100644 (file)
index 0000000..f8d6a91
--- /dev/null
@@ -0,0 +1,293 @@
+
+/* Copyright (c) Mark J. Kilgard, 1994. */
+
+/*
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+ */
+/*
+ * material.c
+ * This program demonstrates the use of the GL lighting model.
+ * Several objects are drawn using different material characteristics.
+ * A single light source illuminates the objects.
+ */
+#include <stdlib.h>
+#include <GL/glut.h>
+
+/*  Initialize z-buffer, projection matrix, light source, 
+ *  and lighting model.  Do not specify a material property here.
+ */
+void myinit(void)
+{
+    GLfloat ambient[] = { 0.0, 0.0, 0.0, 1.0 };
+    GLfloat diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
+    GLfloat position[] = { 0.0, 3.0, 2.0, 0.0 };
+    GLfloat lmodel_ambient[] = { 0.4, 0.4, 0.4, 1.0 };
+    GLfloat local_view[] = { 0.0 };
+
+    glEnable(GL_DEPTH_TEST);
+    glDepthFunc(GL_LESS);
+
+    glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
+    glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
+    glLightfv(GL_LIGHT0, GL_POSITION, position);
+    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
+    glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, local_view);
+
+    glEnable(GL_LIGHTING);
+    glEnable(GL_LIGHT0);
+
+    glClearColor(0.0, 0.1, 0.1, 0.0);
+}
+
+/*  Draw twelve spheres in 3 rows with 4 columns.  
+ *  The spheres in the first row have materials with no ambient reflection.
+ *  The second row has materials with significant ambient reflection.
+ *  The third row has materials with colored ambient reflection.
+ *
+ *  The first column has materials with blue, diffuse reflection only.
+ *  The second column has blue diffuse reflection, as well as specular
+ *  reflection with a low shininess exponent.
+ *  The third column has blue diffuse reflection, as well as specular
+ *  reflection with a high shininess exponent (a more concentrated highlight).
+ *  The fourth column has materials which also include an emissive component.
+ *
+ *  glTranslatef() is used to move spheres to their appropriate locations.
+ */
+
+void display(void)
+{
+    GLfloat no_mat[] = { 0.0, 0.0, 0.0, 1.0 };
+    GLfloat mat_ambient[] = { 0.7, 0.7, 0.7, 1.0 };
+    GLfloat mat_ambient_color[] = { 0.8, 0.8, 0.2, 1.0 };
+    GLfloat mat_diffuse[] = { 0.1, 0.5, 0.8, 1.0 };
+    GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
+    GLfloat no_shininess[] = { 0.0 };
+    GLfloat low_shininess[] = { 5.0 };
+    GLfloat high_shininess[] = { 100.0 };
+    GLfloat mat_emission[] = {0.3, 0.2, 0.2, 0.0};
+
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+/*  draw sphere in first row, first column
+ *  diffuse reflection only; no ambient or specular  
+ */
+    glPushMatrix();
+    glTranslatef (-3.75, 3.0, 0.0);
+    glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);
+    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
+    glMaterialfv(GL_FRONT, GL_SPECULAR, no_mat);
+    glMaterialfv(GL_FRONT, GL_SHININESS, no_shininess);
+    glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
+    glutSolidSphere(1.0, 16, 16);
+    glPopMatrix();
+
+/*  draw sphere in first row, second column
+ *  diffuse and specular reflection; low shininess; no ambient
+ */
+    glPushMatrix();
+    glTranslatef (-1.25, 3.0, 0.0);
+    glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);
+    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
+    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
+    glMaterialfv(GL_FRONT, GL_SHININESS, low_shininess);
+    glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
+    glutSolidSphere(1.0, 16, 16);
+    glPopMatrix();
+
+/*  draw sphere in first row, third column
+ *  diffuse and specular reflection; high shininess; no ambient
+ */
+    glPushMatrix();
+    glTranslatef (1.25, 3.0, 0.0);
+    glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);
+    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
+    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
+    glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);
+    glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
+    glutSolidSphere(1.0, 16, 16);
+    glPopMatrix();
+
+/*  draw sphere in first row, fourth column
+ *  diffuse reflection; emission; no ambient or specular reflection
+ */
+    glPushMatrix();
+    glTranslatef (3.75, 3.0, 0.0);
+    glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);
+    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
+    glMaterialfv(GL_FRONT, GL_SPECULAR, no_mat);
+    glMaterialfv(GL_FRONT, GL_SHININESS, no_shininess);
+    glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);
+    glutSolidSphere(1.0, 16, 16);
+    glPopMatrix();
+
+/*  draw sphere in second row, first column
+ *  ambient and diffuse reflection; no specular  
+ */
+    glPushMatrix();
+    glTranslatef (-3.75, 0.0, 0.0);
+    glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
+    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
+    glMaterialfv(GL_FRONT, GL_SPECULAR, no_mat);
+    glMaterialfv(GL_FRONT, GL_SHININESS, no_shininess);
+    glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
+    glutSolidSphere(1.0, 16, 16);
+    glPopMatrix();
+
+/*  draw sphere in second row, second column
+ *  ambient, diffuse and specular reflection; low shininess
+ */
+    glPushMatrix();
+    glTranslatef (-1.25, 0.0, 0.0);
+    glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
+    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
+    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
+    glMaterialfv(GL_FRONT, GL_SHININESS, low_shininess);
+    glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
+    glutSolidSphere(1.0, 16, 16);
+    glPopMatrix();
+
+/*  draw sphere in second row, third column
+ *  ambient, diffuse and specular reflection; high shininess
+ */
+    glPushMatrix();
+    glTranslatef (1.25, 0.0, 0.0);
+    glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
+    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
+    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
+    glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);
+    glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
+    glutSolidSphere(1.0, 16, 16);
+    glPopMatrix();
+
+/*  draw sphere in second row, fourth column
+ *  ambient and diffuse reflection; emission; no specular
+ */
+    glPushMatrix();
+    glTranslatef (3.75, 0.0, 0.0);
+    glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
+    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
+    glMaterialfv(GL_FRONT, GL_SPECULAR, no_mat);
+    glMaterialfv(GL_FRONT, GL_SHININESS, no_shininess);
+    glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);
+    glutSolidSphere(1.0, 16, 16);
+    glPopMatrix();
+
+/*  draw sphere in third row, first column
+ *  colored ambient and diffuse reflection; no specular  
+ */
+    glPushMatrix();
+    glTranslatef (-3.75, -3.0, 0.0);
+    glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient_color);
+    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
+    glMaterialfv(GL_FRONT, GL_SPECULAR, no_mat);
+    glMaterialfv(GL_FRONT, GL_SHININESS, no_shininess);
+    glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
+    glutSolidSphere(1.0, 16, 16);
+    glPopMatrix();
+
+/*  draw sphere in third row, second column
+ *  colored ambient, diffuse and specular reflection; low shininess
+ */
+    glPushMatrix();
+    glTranslatef (-1.25, -3.0, 0.0);
+    glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient_color);
+    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
+    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
+    glMaterialfv(GL_FRONT, GL_SHININESS, low_shininess);
+    glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
+    glutSolidSphere(1.0, 16, 16);
+    glPopMatrix();
+
+/*  draw sphere in third row, third column
+ *  colored ambient, diffuse and specular reflection; high shininess
+ */
+    glPushMatrix();
+    glTranslatef (1.25, -3.0, 0.0);
+    glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient_color);
+    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
+    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
+    glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);
+    glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
+    glutSolidSphere(1.0, 16, 16);
+    glPopMatrix();
+
+/*  draw sphere in third row, fourth column
+ *  colored ambient and diffuse reflection; emission; no specular
+ */
+    glPushMatrix();
+    glTranslatef (3.75, -3.0, 0.0);
+    glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient_color);
+    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
+    glMaterialfv(GL_FRONT, GL_SPECULAR, no_mat);
+    glMaterialfv(GL_FRONT, GL_SHININESS, no_shininess);
+    glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);
+    glutSolidSphere(1.0, 16, 16);
+    glPopMatrix();
+
+    glFlush();
+}
+
+void myReshape(int w, int h)
+{
+    glViewport(0, 0, w, h);
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    if (w <= (h * 2))
+       glOrtho (-6.0, 6.0, -3.0*((GLfloat)h*2)/(GLfloat)w, 
+           3.0*((GLfloat)h*2)/(GLfloat)w, -10.0, 10.0);
+    else
+       glOrtho (-6.0*(GLfloat)w/((GLfloat)h*2), 
+           6.0*(GLfloat)w/((GLfloat)h*2), -3.0, 3.0, -10.0, 10.0);
+    glMatrixMode(GL_MODELVIEW);
+}
+
+/*  Main Loop
+ *  Open window with initial window size, title bar, 
+ *  RGBA display mode, and handle input events.
+ */
+int main(int argc, char** argv)
+{
+    glutInit(&argc, argv);
+    glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
+    glutInitWindowSize (600, 450);
+    glutCreateWindow(argv[0]);
+    myinit();
+    glutReshapeFunc(myReshape);
+    glutDisplayFunc(display);
+    glutMainLoop();
+    return 0;             /* ANSI C requires main to return int. */
+}
+
diff --git a/progs/redbook/mipmap.c b/progs/redbook/mipmap.c
new file mode 100644 (file)
index 0000000..96ef394
--- /dev/null
@@ -0,0 +1,165 @@
+
+/* Copyright (c) Mark J. Kilgard, 1994. */
+
+/*
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+ */
+/*  mipmap.c
+ *  This program demonstrates using mipmaps for texture maps.
+ *  To overtly show the effect of mipmaps, each mipmap reduction
+ *  level has a solidly colored, contrasting texture image.
+ *  Thus, the quadrilateral which is drawn is drawn with several
+ *  different colors.
+ */
+#include <stdlib.h>
+#include <GL/glut.h>
+
+GLubyte mipmapImage32[32][32][3];
+GLubyte mipmapImage16[16][16][3];
+GLubyte mipmapImage8[8][8][3];
+GLubyte mipmapImage4[4][4][3];
+GLubyte mipmapImage2[2][2][3];
+GLubyte mipmapImage1[1][1][3];
+
+void makeImages(void)
+{
+    int i, j;
+    
+    for (i = 0; i < 32; i++) {
+       for (j = 0; j < 32; j++) {
+           mipmapImage32[i][j][0] = 255;
+           mipmapImage32[i][j][1] = 255;
+           mipmapImage32[i][j][2] = 0;
+       }
+    }
+    for (i = 0; i < 16; i++) {
+       for (j = 0; j < 16; j++) {
+           mipmapImage16[i][j][0] = 255;
+           mipmapImage16[i][j][1] = 0;
+           mipmapImage16[i][j][2] = 255;
+       }
+    }
+    for (i = 0; i < 8; i++) {
+       for (j = 0; j < 8; j++) {
+           mipmapImage8[i][j][0] = 255;
+           mipmapImage8[i][j][1] = 0;
+           mipmapImage8[i][j][2] = 0;
+       }
+    }
+    for (i = 0; i < 4; i++) {
+       for (j = 0; j < 4; j++) {
+           mipmapImage4[i][j][0] = 0;
+           mipmapImage4[i][j][1] = 255;
+           mipmapImage4[i][j][2] = 0;
+       }
+    }
+    for (i = 0; i < 2; i++) {
+       for (j = 0; j < 2; j++) {
+           mipmapImage2[i][j][0] = 0;
+           mipmapImage2[i][j][1] = 0;
+           mipmapImage2[i][j][2] = 255;
+       }
+    }
+    mipmapImage1[0][0][0] = 255;
+    mipmapImage1[0][0][1] = 255;
+    mipmapImage1[0][0][2] = 255;
+}
+
+void myinit(void)
+{    
+    glEnable(GL_DEPTH_TEST);
+    glDepthFunc(GL_LESS);
+    glShadeModel(GL_FLAT);
+
+    glTranslatef(0.0, 0.0, -3.6);
+    makeImages();
+    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+    glTexImage2D(GL_TEXTURE_2D, 0, 3, 32, 32, 0,
+                GL_RGB, GL_UNSIGNED_BYTE, &mipmapImage32[0][0][0]);
+    glTexImage2D(GL_TEXTURE_2D, 1, 3, 16, 16, 0,
+                GL_RGB, GL_UNSIGNED_BYTE, &mipmapImage16[0][0][0]);
+    glTexImage2D(GL_TEXTURE_2D, 2, 3, 8, 8, 0,
+                GL_RGB, GL_UNSIGNED_BYTE, &mipmapImage8[0][0][0]);
+    glTexImage2D(GL_TEXTURE_2D, 3, 3, 4, 4, 0,
+                GL_RGB, GL_UNSIGNED_BYTE, &mipmapImage4[0][0][0]);
+    glTexImage2D(GL_TEXTURE_2D, 4, 3, 2, 2, 0,
+                GL_RGB, GL_UNSIGNED_BYTE, &mipmapImage2[0][0][0]);
+    glTexImage2D(GL_TEXTURE_2D, 5, 3, 1, 1, 0,
+                GL_RGB, GL_UNSIGNED_BYTE, &mipmapImage1[0][0][0]);
+    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 
+       GL_NEAREST_MIPMAP_NEAREST);
+    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
+    glEnable(GL_TEXTURE_2D);
+}
+
+void display(void)
+{
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+    glBegin(GL_QUADS);
+    glTexCoord2f(0.0, 0.0); glVertex3f(-2.0, -1.0, 0.0);
+    glTexCoord2f(0.0, 8.0); glVertex3f(-2.0, 1.0, 0.0);
+    glTexCoord2f(8.0, 8.0); glVertex3f(2000.0, 1.0, -6000.0);
+    glTexCoord2f(8.0, 0.0); glVertex3f(2000.0, -1.0, -6000.0);
+    glEnd();
+    glFlush();
+}
+
+void myReshape(int w, int h)
+{
+    glViewport(0, 0, w, h);
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    gluPerspective(60.0, 1.0*(GLfloat)w/(GLfloat)h, 1.0, 30000.0);
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
+}
+
+int main(int argc, char** argv)
+{
+    glutInit(&argc, argv);
+    glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
+    glutInitWindowSize (500, 500);
+    glutCreateWindow (argv[0]);
+    myinit();
+    glutReshapeFunc (myReshape);
+    glutDisplayFunc(display);
+    glutMainLoop();
+    return 0;             /* ANSI C requires main to return int. */
+}
+
diff --git a/progs/redbook/model.c b/progs/redbook/model.c
new file mode 100644 (file)
index 0000000..8411ef3
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 1993-1997, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*
+ *  model.c
+ *  This program demonstrates modeling transformations
+ */
+#include <GL/glut.h>
+#include <stdlib.h>
+
+void init(void) 
+{
+   glClearColor (0.0, 0.0, 0.0, 0.0);
+   glShadeModel (GL_FLAT);
+}
+
+void draw_triangle(void)
+{
+   glBegin (GL_LINE_LOOP);
+   glVertex2f(0.0, 25.0);
+   glVertex2f(25.0, -25.0);
+   glVertex2f(-25.0, -25.0);
+   glEnd();
+}
+
+void display(void)
+{
+   glClear (GL_COLOR_BUFFER_BIT);
+   glColor3f (1.0, 1.0, 1.0);
+
+   glLoadIdentity ();
+   glColor3f (1.0, 1.0, 1.0);
+   draw_triangle ();
+
+   glEnable (GL_LINE_STIPPLE);
+   glLineStipple (1, 0xF0F0);
+   glLoadIdentity ();
+   glTranslatef (-20.0, 0.0, 0.0);
+   draw_triangle ();
+
+   glLineStipple (1, 0xF00F);
+   glLoadIdentity ();
+   glScalef (1.5, 0.5, 1.0);
+   draw_triangle ();
+
+   glLineStipple (1, 0x8888);
+   glLoadIdentity ();
+   glRotatef (90.0, 0.0, 0.0, 1.0);
+   draw_triangle ();
+   glDisable (GL_LINE_STIPPLE);
+
+   glFlush ();
+}
+
+void reshape (int w, int h)
+{
+   glViewport (0, 0, (GLsizei) w, (GLsizei) h);
+   glMatrixMode (GL_PROJECTION);
+   glLoadIdentity ();
+   if (w <= h)
+      glOrtho (-50.0, 50.0, -50.0*(GLfloat)h/(GLfloat)w,
+         50.0*(GLfloat)h/(GLfloat)w, -1.0, 1.0);
+   else
+      glOrtho (-50.0*(GLfloat)w/(GLfloat)h,
+         50.0*(GLfloat)w/(GLfloat)h, -50.0, 50.0, -1.0, 1.0);
+   glMatrixMode(GL_MODELVIEW);
+}
+
+/* ARGSUSED1 */
+void keyboard(unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 27:
+         exit(0);
+         break;
+   }
+}
+
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
+   glutInitWindowSize (500, 500); 
+   glutInitWindowPosition (100, 100);
+   glutCreateWindow (argv[0]);
+   init ();
+   glutDisplayFunc(display); 
+   glutReshapeFunc(reshape);
+   glutKeyboardFunc (keyboard);
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/redbook/movelight.c b/progs/redbook/movelight.c
new file mode 100644 (file)
index 0000000..a108cad
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 1993-1997, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*
+ *  movelight.c
+ *  This program demonstrates when to issue lighting and
+ *  transformation commands to render a model with a light
+ *  which is moved by a modeling transformation (rotate or
+ *  translate).  The light position is reset after the modeling
+ *  transformation is called.  The eye position does not change.
+ *
+ *  A sphere is drawn using a grey material characteristic.
+ *  A single light source illuminates the object.
+ *
+ *  Interaction:  pressing the left mouse button alters
+ *  the modeling transformation (x rotation) by 30 degrees.
+ *  The scene is then redrawn with the light in a new position.
+ */
+#include <GL/glut.h>
+#include <stdlib.h>
+
+static int spin = 0;
+
+/*  Initialize material property, light source, lighting model,
+ *  and depth buffer.
+ */
+void init(void) 
+{
+   glClearColor (0.0, 0.0, 0.0, 0.0);
+   glShadeModel (GL_SMOOTH);
+   glEnable(GL_LIGHTING);
+   glEnable(GL_LIGHT0);
+   glEnable(GL_DEPTH_TEST);
+}
+
+/*  Here is where the light position is reset after the modeling
+ *  transformation (glRotated) is called.  This places the
+ *  light at a new position in world coordinates.  The cube
+ *  represents the position of the light.
+ */
+void display(void)
+{
+   GLfloat position[] = { 0.0, 0.0, 1.5, 1.0 };
+
+   glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+   glPushMatrix ();
+   gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
+
+   glPushMatrix ();
+   glRotated ((GLdouble) spin, 1.0, 0.0, 0.0);
+   glLightfv (GL_LIGHT0, GL_POSITION, position);
+
+   glTranslated (0.0, 0.0, 1.5);
+   glDisable (GL_LIGHTING);
+   glColor3f (0.0, 1.0, 1.0);
+   glutWireCube (0.1);
+   glEnable (GL_LIGHTING);
+   glPopMatrix ();
+
+   glutSolidTorus (0.275, 0.85, 8, 15);
+   glPopMatrix ();
+   glFlush ();
+}
+
+void reshape (int w, int h)
+{
+   glViewport (0, 0, (GLsizei) w, (GLsizei) h);
+   glMatrixMode (GL_PROJECTION);
+   glLoadIdentity();
+   gluPerspective(40.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+}
+
+/* ARGSUSED2 */
+void mouse(int button, int state, int x, int y)
+{
+   switch (button) {
+      case GLUT_LEFT_BUTTON:
+         if (state == GLUT_DOWN) {
+            spin = (spin + 30) % 360;
+            glutPostRedisplay();
+         }
+         break;
+      default:
+         break;
+   }
+}
+
+/* ARGSUSED1 */
+void keyboard(unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 27:
+         exit(0);
+         break;
+   }
+}
+
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
+   glutInitWindowSize (500, 500); 
+   glutInitWindowPosition (100, 100);
+   glutCreateWindow (argv[0]);
+   init ();
+   glutDisplayFunc(display); 
+   glutReshapeFunc(reshape);
+   glutMouseFunc(mouse);
+   glutKeyboardFunc(keyboard);
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/redbook/nurbs.c b/progs/redbook/nurbs.c
new file mode 100644 (file)
index 0000000..513868e
--- /dev/null
@@ -0,0 +1,176 @@
+
+/* Copyright (c) Mark J. Kilgard, 1994. */
+
+/*
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+ */
+/*
+ *  nurbs.c
+ *  This program shows a NURBS (Non-uniform rational B-splines)
+ *  surface, shaped like a heart.
+ */
+#include <stdlib.h>
+#include <GL/glut.h>
+
+#define S_NUMPOINTS 13
+#define S_ORDER     3   
+#define S_NUMKNOTS  (S_NUMPOINTS + S_ORDER)
+#define T_NUMPOINTS 3
+#define T_ORDER     3 
+#define T_NUMKNOTS  (T_NUMPOINTS + T_ORDER)
+#define SQRT2    1.41421356237309504880
+
+/* initialized local data */
+
+GLfloat sknots[S_NUMKNOTS] =
+    {-1.0, -1.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0,
+      4.0,  5.0,  6.0, 7.0, 8.0, 9.0, 9.0, 9.0};
+GLfloat tknots[T_NUMKNOTS] = {1.0, 1.0, 1.0, 2.0, 2.0, 2.0};
+
+GLfloat ctlpoints[S_NUMPOINTS][T_NUMPOINTS][4] = {
+{   {4.,2.,2.,1.},{4.,1.6,2.5,1.},{4.,2.,3.0,1.}    },
+{   {5.,4.,2.,1.},{5.,4.,2.5,1.},{5.,4.,3.0,1.} },
+{   {6.,5.,2.,1.},{6.,5.,2.5,1.},{6.,5.,3.0,1.} },
+{   {SQRT2*6.,SQRT2*6.,SQRT2*2.,SQRT2},
+    {SQRT2*6.,SQRT2*6.,SQRT2*2.5,SQRT2},
+    {SQRT2*6.,SQRT2*6.,SQRT2*3.0,SQRT2}  },
+{   {5.2,6.7,2.,1.},{5.2,6.7,2.5,1.},{5.2,6.7,3.0,1.}   },
+{   {SQRT2*4.,SQRT2*6.,SQRT2*2.,SQRT2},
+    {SQRT2*4.,SQRT2*6.,SQRT2*2.5,SQRT2},
+    {SQRT2*4.,SQRT2*6.,SQRT2*3.0,SQRT2}  },
+{   {4.,5.2,2.,1.},{4.,4.6,2.5,1.},{4.,5.2,3.0,1.}  },
+{   {SQRT2*4.,SQRT2*6.,SQRT2*2.,SQRT2},
+    {SQRT2*4.,SQRT2*6.,SQRT2*2.5,SQRT2},
+    {SQRT2*4.,SQRT2*6.,SQRT2*3.0,SQRT2}  },
+{   {2.8,6.7,2.,1.},{2.8,6.7,2.5,1.},{2.8,6.7,3.0,1.}   },
+{   {SQRT2*2.,SQRT2*6.,SQRT2*2.,SQRT2},
+    {SQRT2*2.,SQRT2*6.,SQRT2*2.5,SQRT2},
+    {SQRT2*2.,SQRT2*6.,SQRT2*3.0,SQRT2}  },
+{   {2.,5.,2.,1.},{2.,5.,2.5,1.},{2.,5.,3.0,1.} },
+{   {3.,4.,2.,1.},{3.,4.,2.5,1.},{3.,4.,3.0,1.} },
+{   {4.,2.,2.,1.},{4.,1.6,2.5,1.},{4.,2.,3.0,1.}    }
+};
+
+GLUnurbsObj *theNurb;
+
+/*  Initialize material property, light source, lighting model, 
+ *  and depth buffer.
+ */
+void myinit(void)
+{
+    GLfloat mat_ambient[] = { 1.0, 1.0, 1.0, 1.0 };
+    GLfloat mat_diffuse[] = { 1.0, 0.2, 1.0, 1.0 };
+    GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
+    GLfloat mat_shininess[] = { 50.0 };
+
+    GLfloat light0_position[] = { 1.0, 0.1, 1.0, 0.0 };
+    GLfloat light1_position[] = { -1.0, 0.1, 1.0, 0.0 };
+
+    GLfloat lmodel_ambient[] = { 0.3, 0.3, 0.3, 1.0 };
+
+    glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
+    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
+    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
+    glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
+    glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
+    glLightfv(GL_LIGHT1, GL_POSITION, light1_position);
+    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
+
+    glEnable(GL_LIGHTING);
+    glEnable(GL_LIGHT0);
+    glEnable(GL_LIGHT1);
+    glDepthFunc(GL_LESS);
+    glEnable(GL_DEPTH_TEST);
+    glEnable(GL_AUTO_NORMAL);
+
+    theNurb = gluNewNurbsRenderer();
+
+    gluNurbsProperty(theNurb, GLU_SAMPLING_TOLERANCE, 25.0);
+    gluNurbsProperty(theNurb, GLU_DISPLAY_MODE, GLU_FILL);
+}
+
+void display(void)
+{
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+    glPushMatrix();
+    glTranslatef (4., 4.5, 2.5);
+    glRotatef (220.0, 1., 0., 0.);
+    glRotatef (115.0, 0., 1., 0.);
+    glTranslatef (-4., -4.5, -2.5);
+
+    gluBeginSurface(theNurb);
+    gluNurbsSurface(theNurb, 
+           S_NUMKNOTS, sknots,
+           T_NUMKNOTS, tknots,
+           4 * T_NUMPOINTS,
+           4,
+           &ctlpoints[0][0][0], 
+           S_ORDER, T_ORDER,
+           GL_MAP2_VERTEX_4);
+    gluEndSurface(theNurb);
+
+    glPopMatrix();
+    glFlush();
+}
+
+void myReshape(int w, int h)
+{
+    glViewport(0, 0, w, h);
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    glFrustum(-1.0, 1.0, -1.5, 0.5, 0.8, 10.0);
+
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
+    gluLookAt(7.0,4.5,4.0, 4.5,4.5,2.0, 6.0,-3.0,2.0);
+}
+
+/*  Main Loop
+ *  Open window with initial window size, title bar, 
+ *  RGBA display mode, and handle input events.
+ */
+int main(int argc, char** argv)
+{
+    glutInit(&argc, argv);
+    glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
+    glutCreateWindow (argv[0]);
+    myinit();
+    glutReshapeFunc (myReshape);
+    glutDisplayFunc(display);
+    glutMainLoop();
+    return 0;             /* ANSI C requires main to return int. */
+}
diff --git a/progs/redbook/pickdepth.c b/progs/redbook/pickdepth.c
new file mode 100644 (file)
index 0000000..c6d50a9
--- /dev/null
@@ -0,0 +1,203 @@
+
+/* Copyright (c) Mark J. Kilgard, 1994. */
+
+/*
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+ */
+/*
+ *  pickdepth.c
+ *  Picking is demonstrated in this program.  In 
+ *  rendering mode, three overlapping rectangles are 
+ *  drawn.  When the left mouse button is pressed, 
+ *  selection mode is entered with the picking matrix.  
+ *  Rectangles which are drawn under the cursor position
+ *  are "picked."  Pay special attention to the depth 
+ *  value range, which is returned.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <GL/glut.h>
+
+void 
+myinit(void)
+{
+  glClearColor(0.0, 0.0, 0.0, 0.0);
+  glDepthFunc(GL_LESS);
+  glEnable(GL_DEPTH_TEST);
+  glShadeModel(GL_FLAT);
+  glDepthRange(0.0, 1.0);  /* The default z mapping */
+}
+
+/*  The three rectangles are drawn.  In selection mode, 
+ *  each rectangle is given the same name.  Note that 
+ *  each rectangle is drawn with a different z value.
+ */
+void 
+drawRects(GLenum mode)
+{
+  if (mode == GL_SELECT)
+    glLoadName(1);
+  glBegin(GL_QUADS);
+  glColor3f(1.0, 1.0, 0.0);
+  glVertex3i(2, 0, 0);
+  glVertex3i(2, 6, 0);
+  glVertex3i(6, 6, 0);
+  glVertex3i(6, 0, 0);
+  glEnd();
+  if (mode == GL_SELECT)
+    glLoadName(2);
+  glBegin(GL_QUADS);
+  glColor3f(0.0, 1.0, 1.0);
+  glVertex3i(3, 2, -1);
+  glVertex3i(3, 8, -1);
+  glVertex3i(8, 8, -1);
+  glVertex3i(8, 2, -1);
+  glEnd();
+  if (mode == GL_SELECT)
+    glLoadName(3);
+  glBegin(GL_QUADS);
+  glColor3f(1.0, 0.0, 1.0);
+  glVertex3i(0, 2, -2);
+  glVertex3i(0, 7, -2);
+  glVertex3i(5, 7, -2);
+  glVertex3i(5, 2, -2);
+  glEnd();
+}
+
+/*  processHits() prints out the contents of the 
+ *  selection array.
+ */
+void 
+processHits(GLint hits, GLuint buffer[])
+{
+  unsigned int i, j;
+  GLuint names, *ptr;
+
+  printf("hits = %d\n", hits);
+  ptr = (GLuint *) buffer;
+  for (i = 0; i < hits; i++) {  /* for each hit  */
+    names = *ptr;
+    printf(" number of names for hit = %d\n", names);
+    ptr++;
+    printf("  z1 is %g;", (float) *ptr/0xffffffff);
+    ptr++;
+    printf(" z2 is %g\n", (float) *ptr/0xffffffff);
+    ptr++;
+    printf("   the name is ");
+    for (j = 0; j < names; j++) {  /* for each name */
+      printf("%d ", *ptr);
+      ptr++;
+    }
+    printf("\n");
+  }
+}
+
+/*  pickRects() sets up selection mode, name stack, 
+ *  and projection matrix for picking.  Then the objects 
+ *  are drawn.
+ */
+#define BUFSIZE 512
+
+void 
+pickRects(int button, int state, int x, int y)
+{
+  GLuint selectBuf[BUFSIZE];
+  GLint hits;
+  GLint viewport[4];
+
+  if (button != GLUT_LEFT_BUTTON || state != GLUT_DOWN)
+    return;
+
+  glGetIntegerv(GL_VIEWPORT, viewport);
+
+  glSelectBuffer(BUFSIZE, selectBuf);
+  (void) glRenderMode(GL_SELECT);
+
+  glInitNames();
+  glPushName(-1);
+
+  glMatrixMode(GL_PROJECTION);
+  glPushMatrix();
+  glLoadIdentity();
+/*  create 5x5 pixel picking region near cursor location */
+  gluPickMatrix((GLdouble) x, (GLdouble) (viewport[3] - y),
+    5.0, 5.0, viewport);
+  glOrtho(0.0, 8.0, 0.0, 8.0, -0.5, 2.5);
+  drawRects(GL_SELECT);
+  glPopMatrix();
+  glFlush();
+
+  hits = glRenderMode(GL_RENDER);
+  processHits(hits, selectBuf);
+}
+
+void 
+display(void)
+{
+  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+  drawRects(GL_RENDER);
+  glutSwapBuffers();
+}
+
+void 
+myReshape(int w, int h)
+{
+  glViewport(0, 0, w, h);
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+  glOrtho(0.0, 8.0, 0.0, 8.0, -0.5, 2.5);
+  glMatrixMode(GL_MODELVIEW);
+  glLoadIdentity();
+}
+
+/*  Main Loop
+ *  Open window with initial window size, title bar, 
+ *  RGBA display mode, depth buffer, and handle input events.
+ */
+int
+main(int argc, char **argv)
+{
+  glutInitWindowSize(200, 200);
+  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
+  glutInit(&argc, argv);
+  glutCreateWindow(argv[0]);
+  myinit();
+  glutMouseFunc(pickRects);
+  glutReshapeFunc(myReshape);
+  glutDisplayFunc(display);
+  glutMainLoop();
+  return 0;             /* ANSI C requires main to return int. */
+}
diff --git a/progs/redbook/picksquare.c b/progs/redbook/picksquare.c
new file mode 100644 (file)
index 0000000..0a12aa0
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 1993-1997, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*
+ * picksquare.c
+ * Use of multiple names and picking are demonstrated.  
+ * A 3x3 grid of squares is drawn.  When the left mouse 
+ * button is pressed, all squares under the cursor position 
+ * have their color changed.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <GL/glut.h>
+
+int board[3][3];   /*  amount of color for each square */
+
+/*  Clear color value for every square on the board   */
+void init(void)
+{
+   int i, j;
+   for (i = 0; i < 3; i++) 
+      for (j = 0; j < 3; j ++)
+         board[i][j] = 0;
+   glClearColor (0.0, 0.0, 0.0, 0.0);
+}
+
+/*  The nine squares are drawn.  In selection mode, each 
+ *  square is given two names:  one for the row and the 
+ *  other for the column on the grid.  The color of each 
+ *  square is determined by its position on the grid, and 
+ *  the value in the board[][] array.
+ */
+void drawSquares(GLenum mode)
+{
+   GLuint i, j;
+   for (i = 0; i < 3; i++) {
+      if (mode == GL_SELECT)
+         glLoadName (i);
+      for (j = 0; j < 3; j ++) {
+         if (mode == GL_SELECT)
+            glPushName (j);
+         glColor3f ((GLfloat) i/3.0, (GLfloat) j/3.0, 
+                    (GLfloat) board[i][j]/3.0);
+         glRecti (i, j, i+1, j+1);
+         if (mode == GL_SELECT)
+            glPopName ();
+      }
+   }
+}
+
+/*  processHits prints out the contents of the 
+ *  selection array.
+ */
+void processHits (GLint hits, GLuint buffer[])
+{
+   unsigned int i, j;
+   GLuint ii, jj, names, *ptr;
+
+   printf ("hits = %d\n", hits);
+   ptr = (GLuint *) buffer;
+   for (i = 0; i < hits; i++) {        /*  for each hit  */
+      names = *ptr;
+      printf (" number of names for this hit = %d\n", names); ptr++;
+      printf("  z1 is %g;", (float) *ptr/0x7fffffff); ptr++;
+      printf(" z2 is %g\n", (float) *ptr/0x7fffffff); ptr++;
+      printf ("   names are ");
+      for (j = 0; j < names; j++) { /*  for each name */
+         printf ("%d ", *ptr);
+         if (j == 0)  /*  set row and column  */
+            ii = *ptr;
+         else if (j == 1)
+            jj = *ptr;
+         ptr++;
+      }
+      printf ("\n");
+      board[ii][jj] = (board[ii][jj] + 1) % 3;
+   }
+}
+
+/*  pickSquares() sets up selection mode, name stack, 
+ *  and projection matrix for picking.  Then the 
+ *  objects are drawn.
+ */
+#define BUFSIZE 512
+
+void pickSquares(int button, int state, int x, int y)
+{
+   GLuint selectBuf[BUFSIZE];
+   GLint hits;
+   GLint viewport[4];
+
+   if (button != GLUT_LEFT_BUTTON || state != GLUT_DOWN)
+      return;
+
+   glGetIntegerv (GL_VIEWPORT, viewport);
+
+   glSelectBuffer (BUFSIZE, selectBuf);
+   (void) glRenderMode (GL_SELECT);
+
+   glInitNames();
+   glPushName(0);
+
+   glMatrixMode (GL_PROJECTION);
+   glPushMatrix ();
+   glLoadIdentity ();
+/*  create 5x5 pixel picking region near cursor location       */
+   gluPickMatrix ((GLdouble) x, (GLdouble) (viewport[3] - y), 
+                  5.0, 5.0, viewport);
+   gluOrtho2D (0.0, 3.0, 0.0, 3.0);
+   drawSquares (GL_SELECT);
+
+   glMatrixMode (GL_PROJECTION);
+   glPopMatrix ();
+   glFlush ();
+
+   hits = glRenderMode (GL_RENDER);
+   processHits (hits, selectBuf);
+   glutPostRedisplay();
+} 
+
+void display(void)
+{
+   glClear(GL_COLOR_BUFFER_BIT);
+   drawSquares (GL_RENDER);
+   glFlush();
+}
+
+void reshape(int w, int h)
+{
+   glViewport(0, 0, w, h);
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   gluOrtho2D (0.0, 3.0, 0.0, 3.0);
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+}
+
+/* ARGSUSED1 */
+void keyboard(unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 27:
+         exit(0);
+         break;
+   }
+}
+
+/* Main Loop */
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
+   glutInitWindowSize (100, 100);
+   glutInitWindowPosition (100, 100);
+   glutCreateWindow (argv[0]);
+   init ();
+   glutReshapeFunc (reshape);
+   glutDisplayFunc(display); 
+   glutMouseFunc (pickSquares);
+   glutKeyboardFunc (keyboard);
+   glutMainLoop();
+   return 0; 
+}
diff --git a/progs/redbook/plane.c b/progs/redbook/plane.c
new file mode 100644 (file)
index 0000000..2b0cca0
--- /dev/null
@@ -0,0 +1,157 @@
+
+/* Copyright (c) Mark J. Kilgard, 1994. */
+
+/*
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+ */
+/*
+ *  plane.c
+ *  This program demonstrates the use of local versus 
+ *  infinite lighting on a flat plane.
+ */
+#include <stdlib.h>
+#include <GL/glut.h>
+
+/*  Initialize material property, light source, and lighting model.
+ */
+void myinit(void)
+{
+    GLfloat mat_ambient[] = { 0.0, 0.0, 0.0, 1.0 };
+/*   mat_specular and mat_shininess are NOT default values     */
+    GLfloat mat_diffuse[] = { 0.4, 0.4, 0.4, 1.0 };
+    GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
+    GLfloat mat_shininess[] = { 15.0 };
+
+    GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 };
+    GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
+    GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
+    GLfloat lmodel_ambient[] = { 0.2, 0.2, 0.2, 1.0 };
+
+    glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
+    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
+    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
+    glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
+    glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
+    glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
+    glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
+    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
+
+    glEnable(GL_LIGHTING);
+    glEnable(GL_LIGHT0);
+    glDepthFunc(GL_LESS);
+    glEnable(GL_DEPTH_TEST);
+}
+
+void drawPlane(void)
+{
+    glBegin (GL_QUADS);
+    glNormal3f (0.0, 0.0, 1.0);
+    glVertex3f (-1.0, -1.0, 0.0);
+    glVertex3f (0.0, -1.0, 0.0);
+    glVertex3f (0.0, 0.0, 0.0);
+    glVertex3f (-1.0, 0.0, 0.0);
+
+    glNormal3f (0.0, 0.0, 1.0);
+    glVertex3f (0.0, -1.0, 0.0);
+    glVertex3f (1.0, -1.0, 0.0);
+    glVertex3f (1.0, 0.0, 0.0);
+    glVertex3f (0.0, 0.0, 0.0);
+
+    glNormal3f (0.0, 0.0, 1.0);
+    glVertex3f (0.0, 0.0, 0.0);
+    glVertex3f (1.0, 0.0, 0.0);
+    glVertex3f (1.0, 1.0, 0.0);
+    glVertex3f (0.0, 1.0, 0.0);
+
+    glNormal3f (0.0, 0.0, 1.0);
+    glVertex3f (0.0, 0.0, 0.0);
+    glVertex3f (0.0, 1.0, 0.0);
+    glVertex3f (-1.0, 1.0, 0.0);
+    glVertex3f (-1.0, 0.0, 0.0);
+    glEnd();
+}
+
+void display (void)
+{
+    GLfloat infinite_light[] = { 1.0, 1.0, 1.0, 0.0 };
+    GLfloat local_light[] = { 1.0, 1.0, 1.0, 1.0 };
+
+    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+    glPushMatrix ();
+    glTranslatef (-1.5, 0.0, 0.0);
+    glLightfv (GL_LIGHT0, GL_POSITION, infinite_light);
+    drawPlane ();
+    glPopMatrix ();
+
+    glPushMatrix ();
+    glTranslatef (1.5, 0.0, 0.0);
+    glLightfv (GL_LIGHT0, GL_POSITION, local_light);
+    drawPlane ();
+    glPopMatrix ();
+    glFlush ();
+}
+
+void myReshape(int w, int h)
+{
+    glViewport (0, 0, w, h);
+    glMatrixMode (GL_PROJECTION);
+    glLoadIdentity ();
+    if (w <= h) 
+       glOrtho (-1.5, 1.5, -1.5*(GLdouble)h/(GLdouble)w, 
+           1.5*(GLdouble)h/(GLdouble)w, -10.0, 10.0);
+    else 
+       glOrtho (-1.5*(GLdouble)w/(GLdouble)h, 
+           1.5*(GLdouble)w/(GLdouble)h, -1.5, 1.5, -10.0, 10.0);
+    glMatrixMode (GL_MODELVIEW);
+}
+
+/*  Main Loop
+ *  Open window with initial window size, title bar, 
+ *  RGBA display mode, and handle input events.
+ */
+int main(int argc, char** argv)
+{
+    glutInit(&argc, argv);
+    glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
+    glutInitWindowSize (500, 200);
+    glutCreateWindow (argv[0]);
+    myinit();
+    glutReshapeFunc (myReshape);
+    glutDisplayFunc(display);
+    glutMainLoop();
+    return 0;             /* ANSI C requires main to return int. */
+}
diff --git a/progs/redbook/planet.c b/progs/redbook/planet.c
new file mode 100644 (file)
index 0000000..e13672d
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 1993-1997, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*
+ *  planet.c
+ *  This program shows how to composite modeling transformations
+ *  to draw translated and rotated models.
+ *  Interaction:  pressing the d and y keys (day and year)
+ *  alters the rotation of the planet around the sun.
+ */
+#include <GL/glut.h>
+#include <stdlib.h>
+
+static int year = 0, day = 0;
+
+void init(void) 
+{
+   glClearColor (0.0, 0.0, 0.0, 0.0);
+   glShadeModel (GL_FLAT);
+}
+
+void display(void)
+{
+   glClear (GL_COLOR_BUFFER_BIT);
+   glColor3f (1.0, 1.0, 1.0);
+
+   glPushMatrix();
+   glutWireSphere(1.0, 20, 16);   /* draw sun */
+   glRotatef ((GLfloat) year, 0.0, 1.0, 0.0);
+   glTranslatef (2.0, 0.0, 0.0);
+   glRotatef ((GLfloat) day, 0.0, 1.0, 0.0);
+   glutWireSphere(0.2, 10, 8);    /* draw smaller planet */
+   glPopMatrix();
+   glutSwapBuffers();
+}
+
+void reshape (int w, int h)
+{
+   glViewport (0, 0, (GLsizei) w, (GLsizei) h); 
+   glMatrixMode (GL_PROJECTION);
+   glLoadIdentity ();
+   gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+   gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
+}
+
+/* ARGSUSED1 */
+void keyboard (unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 'd':
+         day = (day + 10) % 360;
+         glutPostRedisplay();
+         break;
+      case 'D':
+         day = (day - 10) % 360;
+         glutPostRedisplay();
+         break;
+      case 'y':
+         year = (year + 5) % 360;
+         glutPostRedisplay();
+         break;
+      case 'Y':
+         year = (year - 5) % 360;
+         glutPostRedisplay();
+         break;
+      case 27:
+         exit(0);
+         break;
+      default:
+         break;
+   }
+}
+
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
+   glutInitWindowSize (500, 500); 
+   glutInitWindowPosition (100, 100);
+   glutCreateWindow (argv[0]);
+   init ();
+   glutDisplayFunc(display); 
+   glutReshapeFunc(reshape);
+   glutKeyboardFunc(keyboard);
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/redbook/polyoff.c b/progs/redbook/polyoff.c
new file mode 100644 (file)
index 0000000..42887c9
--- /dev/null
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) 1993-1997, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*
+ *  polyoff.c
+ *  This program demonstrates polygon offset to draw a shaded
+ *  polygon and its wireframe counterpart without ugly visual
+ *  artifacts ("stitching").
+ */
+#include <GL/glut.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef GL_VERSION_1_1
+GLuint list;
+GLint spinx = 0;
+GLint spiny = 0;
+GLfloat tdist = 0.0;
+GLfloat polyfactor = 1.0;
+GLfloat polyunits = 1.0;
+
+/*  display() draws two spheres, one with a gray, diffuse material,
+ *  the other sphere with a magenta material with a specular highlight.
+ */
+void display (void)
+{
+    GLfloat gray[] = { 0.8, 0.8, 0.8, 1.0 };
+    GLfloat black[] = { 0.0, 0.0, 0.0, 1.0 };
+
+    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+    glPushMatrix ();
+    glTranslatef (0.0, 0.0, tdist);
+    glRotatef ((GLfloat) spinx, 1.0, 0.0, 0.0);
+    glRotatef ((GLfloat) spiny, 0.0, 1.0, 0.0);
+
+    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, gray);
+    glMaterialfv(GL_FRONT, GL_SPECULAR, black);
+    glMaterialf(GL_FRONT, GL_SHININESS, 0.0);
+    glEnable(GL_LIGHTING);
+    glEnable(GL_LIGHT0);
+    glEnable(GL_POLYGON_OFFSET_FILL);
+    glPolygonOffset(polyfactor, polyunits);
+    glCallList (list);
+    glDisable(GL_POLYGON_OFFSET_FILL);
+
+    glDisable(GL_LIGHTING);
+    glDisable(GL_LIGHT0);
+    glColor3f (1.0, 1.0, 1.0);
+    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+    glCallList (list);
+    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+
+    glPopMatrix ();
+    glFlush ();
+}
+
+/*  specify initial properties
+ *  create display list with sphere  
+ *  initialize lighting and depth buffer
+ */
+void gfxinit (void)
+{
+    GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 };
+    GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
+    GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
+    GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
+
+    GLfloat global_ambient[] = { 0.2, 0.2, 0.2, 1.0 };
+
+    glClearColor (0.0, 0.0, 0.0, 1.0);
+
+    list = glGenLists(1);
+    glNewList (list, GL_COMPILE);
+       glutSolidSphere(1.0, 20, 12);
+    glEndList ();
+
+    glEnable(GL_DEPTH_TEST);
+
+    glLightfv (GL_LIGHT0, GL_AMBIENT, light_ambient);
+    glLightfv (GL_LIGHT0, GL_DIFFUSE, light_diffuse);
+    glLightfv (GL_LIGHT0, GL_SPECULAR, light_specular);
+    glLightfv (GL_LIGHT0, GL_POSITION, light_position);
+    glLightModelfv (GL_LIGHT_MODEL_AMBIENT, global_ambient);
+}
+
+/*  call when window is resized  */
+void reshape(int width, int height)
+{
+    glViewport (0, 0, width, height);
+    glMatrixMode (GL_PROJECTION);
+    glLoadIdentity ();
+    gluPerspective(45.0, (GLdouble)width/(GLdouble)height,
+           1.0, 10.0);
+    glMatrixMode (GL_MODELVIEW);
+    glLoadIdentity ();
+    gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
+}
+
+/*  call when mouse button is pressed  */
+/* ARGSUSED2 */
+void mouse(int button, int state, int x, int y) {
+    switch (button) {
+       case GLUT_LEFT_BUTTON:
+           switch (state) {
+               case GLUT_DOWN:
+                   spinx = (spinx + 5) % 360; 
+                    glutPostRedisplay();
+                   break;
+               default:
+                   break;
+            }
+            break;
+       case GLUT_MIDDLE_BUTTON:
+           switch (state) {
+               case GLUT_DOWN:
+                   spiny = (spiny + 5) % 360; 
+                    glutPostRedisplay();
+                   break;
+               default:
+                   break;
+            }
+            break;
+       case GLUT_RIGHT_BUTTON:
+           switch (state) {
+               case GLUT_UP:
+                   exit(0);
+                   break;
+               default:
+                   break;
+            }
+            break;
+        default:
+            break;
+    }
+}
+
+/* ARGSUSED1 */
+void keyboard (unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 't':
+         if (tdist < 4.0) {
+            tdist = (tdist + 0.5);
+            glutPostRedisplay();
+         }
+         break;
+      case 'T':
+         if (tdist > -5.0) {
+            tdist = (tdist - 0.5);
+            glutPostRedisplay();
+         }
+         break;
+      case 'F':
+         polyfactor = polyfactor + 0.1;
+        printf ("polyfactor is %f\n", polyfactor);
+         glutPostRedisplay();
+         break;
+      case 'f':
+         polyfactor = polyfactor - 0.1;
+        printf ("polyfactor is %f\n", polyfactor);
+         glutPostRedisplay();
+         break;
+      case 'U':
+         polyunits = polyunits + 1.0;
+        printf ("polyunits is %f\n", polyunits);
+         glutPostRedisplay();
+         break;
+      case 'u':
+         polyunits = polyunits - 1.0;
+        printf ("polyunits is %f\n", polyunits);
+         glutPostRedisplay();
+         break;
+      default:
+         break;
+   }
+}
+
+/*  Main Loop
+ *  Open window with initial window size, title bar, 
+ *  RGBA display mode, and handle input events.
+ */
+int main(int argc, char** argv)
+{
+    glutInit(&argc, argv);
+    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
+    glutCreateWindow(argv[0]);
+    glutReshapeFunc(reshape);
+    glutDisplayFunc(display);
+    glutMouseFunc(mouse);
+    glutKeyboardFunc(keyboard);
+    gfxinit();
+    glutMainLoop();
+    return 0;
+}
+#else
+int main(int argc, char** argv)
+{
+    fprintf (stderr, "This program demonstrates a feature which is not in OpenGL Version 1.0.\n");
+    fprintf (stderr, "If your implementation of OpenGL Version 1.0 has the right extensions,\n");
+    fprintf (stderr, "you may be able to modify this program to make it run.\n");
+    return 0;
+}
+#endif
diff --git a/progs/redbook/polys.c b/progs/redbook/polys.c
new file mode 100644 (file)
index 0000000..2983bc5
--- /dev/null
@@ -0,0 +1,124 @@
+
+/* Copyright (c) Mark J. Kilgard, 1994. */
+
+/*
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+ */
+/*
+ *  polys.c
+ *  This program demonstrates polygon stippling.
+ */
+#include <stdlib.h>
+#include <GL/glut.h>
+
+void display(void)
+{
+    GLubyte fly[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x03, 0x80, 0x01, 0xC0, 0x06, 0xC0, 0x03, 0x60, 0x04, 0x60, 0x06, 0x20,
+0x04, 0x30, 0x0C, 0x20, 0x04, 0x18, 0x18, 0x20, 0x04, 0x0C, 0x30, 0x20,
+0x04, 0x06, 0x60, 0x20, 0x44, 0x03, 0xC0, 0x22, 0x44, 0x01, 0x80, 0x22,
+0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22,
+0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22, 0x66, 0x01, 0x80, 0x66,
+0x33, 0x01, 0x80, 0xCC, 0x19, 0x81, 0x81, 0x98, 0x0C, 0xC1, 0x83, 0x30,
+0x07, 0xe1, 0x87, 0xe0, 0x03, 0x3f, 0xfc, 0xc0, 0x03, 0x31, 0x8c, 0xc0,
+0x03, 0x33, 0xcc, 0xc0, 0x06, 0x64, 0x26, 0x60, 0x0c, 0xcc, 0x33, 0x30,
+0x18, 0xcc, 0x33, 0x18, 0x10, 0xc4, 0x23, 0x08, 0x10, 0x63, 0xC6, 0x08,
+0x10, 0x30, 0x0c, 0x08, 0x10, 0x18, 0x18, 0x08, 0x10, 0x00, 0x00, 0x08};
+
+    GLubyte halftone[] = {
+0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA,
+0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA,
+0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA,
+0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA,
+0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA,
+0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55};
+
+    glClear (GL_COLOR_BUFFER_BIT);
+
+/*  draw all polygons in white */
+    glColor3f (1.0, 1.0, 1.0);
+
+/*  draw one solid, unstippled rectangle,      */      
+/*  then two stippled rectangles               */
+    glRectf (25.0, 25.0, 125.0, 125.0);
+    glEnable (GL_POLYGON_STIPPLE);
+    glPolygonStipple (fly);
+    glRectf (125.0, 25.0, 225.0, 125.0);
+    glPolygonStipple (halftone);
+    glRectf (225.0, 25.0, 325.0, 125.0);
+    glDisable (GL_POLYGON_STIPPLE);
+
+    glFlush ();
+}
+
+void myinit (void) 
+{
+/*  clear background to black  */
+    glClearColor (0.0, 0.0, 0.0, 0.0);
+    glShadeModel (GL_FLAT);    
+}
+
+static void reshape(GLsizei w, GLsizei h)
+{
+    glViewport(0, 0, w, h);
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    glOrtho(0.0, (GLdouble)w, 0.0, (GLdouble)h, -1.0, 1.0);
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
+}
+
+/*  Main Loop
+ *  Open window with initial window size, title bar, 
+ *  RGBA display mode, and handle input events.
+ */
+int main(int argc, char** argv)
+{
+    glutInit(&argc, argv);
+    glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
+    glutInitWindowSize (350, 150);
+    glutCreateWindow (argv[0]);
+    myinit ();
+    glutDisplayFunc(display);
+    glutReshapeFunc(reshape);
+    glutMainLoop();
+    return 0;             /* ANSI C requires main to return int. */
+}
diff --git a/progs/redbook/quadric.c b/progs/redbook/quadric.c
new file mode 100644 (file)
index 0000000..4e46c85
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 1993-1997, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*
+ *  quadric.c
+ *  This program demonstrates the use of some of the gluQuadric*
+ *  routines. Quadric objects are created with some quadric
+ *  properties and the callback routine to handle errors.
+ *  Note that the cylinder has no top or bottom and the circle
+ *  has a hole in it.
+ */
+#include <GL/glut.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/* Win32 calling conventions. */
+#ifndef CALLBACK
+#define CALLBACK
+#endif
+
+GLuint startList;
+
+void CALLBACK errorCallback(GLenum errorCode)
+{
+   const GLubyte *estring;
+
+   estring = gluErrorString(errorCode);
+   fprintf(stderr, "Quadric Error: %s\n", estring);
+   exit(0);
+}
+
+void init(void) 
+{
+   GLUquadricObj *qobj;
+   GLfloat mat_ambient[] = { 0.5, 0.5, 0.5, 1.0 };
+   GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
+   GLfloat mat_shininess[] = { 50.0 };
+   GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
+   GLfloat model_ambient[] = { 0.5, 0.5, 0.5, 1.0 };
+
+   glClearColor(0.0, 0.0, 0.0, 0.0);
+
+   glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
+   glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
+   glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
+   glLightfv(GL_LIGHT0, GL_POSITION, light_position);
+   glLightModelfv(GL_LIGHT_MODEL_AMBIENT, model_ambient);
+
+   glEnable(GL_LIGHTING);
+   glEnable(GL_LIGHT0);
+   glEnable(GL_DEPTH_TEST);
+
+/*  Create 4 display lists, each with a different quadric object.
+ *  Different drawing styles and surface normal specifications
+ *  are demonstrated.
+ */
+   startList = glGenLists(4);
+   qobj = gluNewQuadric();
+   gluQuadricCallback(qobj, GLU_ERROR, 
+                      (GLvoid (CALLBACK*) ()) errorCallback);
+
+   gluQuadricDrawStyle(qobj, GLU_FILL); /* smooth shaded */
+   gluQuadricNormals(qobj, GLU_SMOOTH);
+   glNewList(startList, GL_COMPILE);
+      gluSphere(qobj, 0.75, 15, 10);
+   glEndList();
+
+   gluQuadricDrawStyle(qobj, GLU_FILL); /* flat shaded */
+   gluQuadricNormals(qobj, GLU_FLAT);
+   glNewList(startList+1, GL_COMPILE);
+      gluCylinder(qobj, 0.5, 0.3, 1.0, 15, 5);
+   glEndList();
+
+   gluQuadricDrawStyle(qobj, GLU_LINE); /* all polygons wireframe */
+   gluQuadricNormals(qobj, GLU_NONE);
+   glNewList(startList+2, GL_COMPILE);
+      gluDisk(qobj, 0.25, 1.0, 20, 4);
+   glEndList();
+
+   gluQuadricDrawStyle(qobj, GLU_SILHOUETTE); /* boundary only  */
+   gluQuadricNormals(qobj, GLU_NONE);
+   glNewList(startList+3, GL_COMPILE);
+      gluPartialDisk(qobj, 0.0, 1.0, 20, 4, 0.0, 225.0);
+   glEndList();
+}
+
+void display(void)
+{
+   glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+   glPushMatrix();
+
+   glEnable(GL_LIGHTING);
+   glShadeModel (GL_SMOOTH);
+   glTranslatef(-1.0, -1.0, 0.0);
+   glCallList(startList);
+
+   glShadeModel (GL_FLAT);
+   glTranslatef(0.0, 2.0, 0.0);
+   glPushMatrix();
+   glRotatef(300.0, 1.0, 0.0, 0.0);
+   glCallList(startList+1);
+   glPopMatrix();
+
+   glDisable(GL_LIGHTING);
+   glColor3f(0.0, 1.0, 1.0);
+   glTranslatef(2.0, -2.0, 0.0);
+   glCallList(startList+2);
+
+   glColor3f(1.0, 1.0, 0.0);
+   glTranslatef(0.0, 2.0, 0.0);
+   glCallList(startList+3);
+
+   glPopMatrix();
+   glFlush();
+}
+
+void reshape (int w, int h)
+{
+   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   if (w <= h)
+      glOrtho(-2.5, 2.5, -2.5*(GLfloat)h/(GLfloat)w,
+         2.5*(GLfloat)h/(GLfloat)w, -10.0, 10.0);
+   else
+      glOrtho(-2.5*(GLfloat)w/(GLfloat)h,
+         2.5*(GLfloat)w/(GLfloat)h, -2.5, 2.5, -10.0, 10.0);
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+}
+
+/* ARGSUSED1 */
+void keyboard(unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 27:
+         exit(0);
+         break;
+   }
+}
+
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
+   glutInitWindowSize(500, 500); 
+   glutInitWindowPosition(100, 100);
+   glutCreateWindow(argv[0]);
+   init();
+   glutDisplayFunc(display); 
+   glutReshapeFunc(reshape);
+   glutKeyboardFunc(keyboard);
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/redbook/robot.c b/progs/redbook/robot.c
new file mode 100644 (file)
index 0000000..94e20ac
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 1993-1997, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*
+ * robot.c
+ * This program shows how to composite modeling transformations
+ * to draw translated and rotated hierarchical models.
+ * Interaction:  pressing the s and e keys (shoulder and elbow)
+ * alters the rotation of the robot arm.
+ */
+#include <GL/glut.h>
+#include <stdlib.h>
+
+static int shoulder = 0, elbow = 0;
+
+void init(void) 
+{
+  glClearColor (0.0, 0.0, 0.0, 0.0);
+  glShadeModel (GL_FLAT);
+}
+
+void display(void)
+{
+   glClear (GL_COLOR_BUFFER_BIT);
+   glPushMatrix();
+   glTranslatef (-1.0, 0.0, 0.0);
+   glRotatef ((GLfloat) shoulder, 0.0, 0.0, 1.0);
+   glTranslatef (1.0, 0.0, 0.0);
+   glPushMatrix();
+   glScalef (2.0, 0.4, 1.0);
+   glutWireCube (1.0);
+   glPopMatrix();
+
+   glTranslatef (1.0, 0.0, 0.0);
+   glRotatef ((GLfloat) elbow, 0.0, 0.0, 1.0);
+   glTranslatef (1.0, 0.0, 0.0);
+   glPushMatrix();
+   glScalef (2.0, 0.4, 1.0);
+   glutWireCube (1.0);
+   glPopMatrix();
+
+   glPopMatrix();
+   glutSwapBuffers();
+}
+
+void reshape (int w, int h)
+{
+   glViewport (0, 0, (GLsizei) w, (GLsizei) h); 
+   glMatrixMode (GL_PROJECTION);
+   glLoadIdentity ();
+   gluPerspective(65.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+   glTranslatef (0.0, 0.0, -5.0);
+}
+
+/* ARGSUSED1 */
+void keyboard (unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 's':
+         shoulder = (shoulder + 5) % 360;
+         glutPostRedisplay();
+         break;
+      case 'S':
+         shoulder = (shoulder - 5) % 360;
+         glutPostRedisplay();
+         break;
+      case 'e':
+         elbow = (elbow + 5) % 360;
+         glutPostRedisplay();
+         break;
+      case 'E':
+         elbow = (elbow - 5) % 360;
+         glutPostRedisplay();
+         break;
+      case 27:
+         exit(0);
+         break;
+      default:
+         break;
+   }
+}
+
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
+   glutInitWindowSize (500, 500); 
+   glutInitWindowPosition (100, 100);
+   glutCreateWindow (argv[0]);
+   init ();
+   glutDisplayFunc(display); 
+   glutReshapeFunc(reshape);
+   glutKeyboardFunc(keyboard);
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/redbook/sccolorlight.c b/progs/redbook/sccolorlight.c
new file mode 100644 (file)
index 0000000..191f266
--- /dev/null
@@ -0,0 +1,127 @@
+
+/* Copyright (c) Mark J. Kilgard, 1994. */
+
+/*
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+ */
+/*
+ *  sccolorlight.c
+ *  This program demonstrates the use of a colored 
+ *  (magenta, in this example) light source.  Objects 
+ *  are drawn using a grey material characteristic.  
+ *  A single light source illuminates the objects.
+ */
+#include <stdlib.h>
+#include <GL/glut.h>
+
+/*  Initialize material property and light source.
+ */
+void myinit(void)
+{
+    GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 };
+    GLfloat light_diffuse[] = { 1.0, 0.0, 1.0, 1.0 };
+    GLfloat light_specular[] = { 1.0, 0.0, 1.0, 1.0 };
+/*     light_position is NOT default value     */
+    GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
+
+    glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
+    glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
+    glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
+    glLightfv(GL_LIGHT0, GL_POSITION, light_position);
+    
+    glEnable(GL_LIGHTING);
+    glEnable(GL_LIGHT0);
+    glDepthFunc(GL_LESS);
+    glEnable(GL_DEPTH_TEST);
+}
+
+void display(void)
+{
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+    glPushMatrix ();
+    glRotatef (20.0, 1.0, 0.0, 0.0);
+
+    glPushMatrix ();
+    glTranslatef (-0.75, 0.5, 0.0); 
+    glRotatef (90.0, 1.0, 0.0, 0.0);
+    glutSolidTorus (0.275, 0.85, 20, 20);
+    glPopMatrix ();
+
+    glPushMatrix ();
+    glTranslatef (-0.75, -0.5, 0.0); 
+    glRotatef (270.0, 1.0, 0.0, 0.0);
+    glutSolidCone (1.0, 2.0, 20, 20);
+    glPopMatrix ();
+
+    glPushMatrix ();
+    glTranslatef (0.75, 0.0, -1.0); 
+    glutSolidSphere (1.0, 20, 20);
+    glPopMatrix ();
+
+    glPopMatrix ();
+    glFlush();
+}
+
+void myReshape(int w, int h)
+{
+    glViewport(0, 0, w, h);
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    if (w <= h) 
+       glOrtho (-2.5, 2.5, -2.5*(GLfloat)h/(GLfloat)w, 
+           2.5*(GLfloat)h/(GLfloat)w, -10.0, 10.0);
+    else 
+       glOrtho (-2.5*(GLfloat)w/(GLfloat)h, 
+           2.5*(GLfloat)w/(GLfloat)h, -2.5, 2.5, -10.0, 10.0);
+    glMatrixMode(GL_MODELVIEW);
+}
+
+/*  Main Loop
+ *  Open window with initial window size, title bar, 
+ *  RGBA display mode, and handle input events.
+ */
+int main(int argc, char** argv)
+{
+    glutInit(&argc, argv);
+    glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
+    glutInitWindowSize (500, 500);
+    glutCreateWindow (argv[0]);
+    myinit();
+    glutReshapeFunc (myReshape);
+    glutDisplayFunc(display);
+    glutMainLoop();
+    return 0;             /* ANSI C requires main to return int. */
+}
diff --git a/progs/redbook/scene.c b/progs/redbook/scene.c
new file mode 100644 (file)
index 0000000..428e8bd
--- /dev/null
@@ -0,0 +1,127 @@
+
+/* Copyright (c) Mark J. Kilgard, 1994. */
+
+/*
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+ */
+/*
+ *  scene.c
+ *  This program demonstrates the use of the GL lighting model.
+ *  Objects are drawn using a grey material characteristic. 
+ *  A single light source illuminates the objects.
+ */
+#include <stdlib.h>
+#include <GL/glut.h>
+
+/*  Initialize material property and light source.
+ */
+void myinit (void)
+{
+    GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 };
+    GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
+    GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
+/*     light_position is NOT default value     */
+    GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
+
+    glLightfv (GL_LIGHT0, GL_AMBIENT, light_ambient);
+    glLightfv (GL_LIGHT0, GL_DIFFUSE, light_diffuse);
+    glLightfv (GL_LIGHT0, GL_SPECULAR, light_specular);
+    glLightfv (GL_LIGHT0, GL_POSITION, light_position);
+    
+    glEnable (GL_LIGHTING);
+    glEnable (GL_LIGHT0);
+    glDepthFunc(GL_LESS);
+    glEnable(GL_DEPTH_TEST);
+}
+
+void display (void)
+{
+    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+    glPushMatrix ();
+    glRotatef (20.0, 1.0, 0.0, 0.0);
+
+    glPushMatrix ();
+    glTranslatef (-0.75, 0.5, 0.0); 
+    glRotatef (90.0, 1.0, 0.0, 0.0);
+    glutSolidTorus (0.275, 0.85, 15, 15);
+    glPopMatrix ();
+
+    glPushMatrix ();
+    glTranslatef (-0.75, -0.5, 0.0); 
+    glRotatef (270.0, 1.0, 0.0, 0.0);
+    glutSolidCone (1.0, 2.0, 15, 15);
+    glPopMatrix ();
+
+    glPushMatrix ();
+    glTranslatef (0.75, 0.0, -1.0); 
+    glutSolidSphere (1.0, 15, 15);
+    glPopMatrix ();
+
+    glPopMatrix ();
+    glFlush ();
+}
+
+void myReshape(int w, int h)
+{
+    glViewport (0, 0, w, h);
+    glMatrixMode (GL_PROJECTION);
+    glLoadIdentity ();
+    if (w <= h) 
+       glOrtho (-2.5, 2.5, -2.5*(GLfloat)h/(GLfloat)w, 
+           2.5*(GLfloat)h/(GLfloat)w, -10.0, 10.0);
+    else 
+       glOrtho (-2.5*(GLfloat)w/(GLfloat)h, 
+           2.5*(GLfloat)w/(GLfloat)h, -2.5, 2.5, -10.0, 10.0);
+    glMatrixMode (GL_MODELVIEW);
+}
+
+/*  Main Loop
+ *  Open window with initial window size, title bar, 
+ *  RGBA display mode, and handle input events.
+ */
+int main(int argc, char** argv)
+{
+    glutInit(&argc, argv);
+    glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
+    glutInitWindowSize (500, 500);
+    glutCreateWindow (argv[0]);
+    myinit ();
+    glutReshapeFunc (myReshape);
+    glutDisplayFunc(display);
+    glutMainLoop();
+    return 0;             /* ANSI C requires main to return int. */
+}
diff --git a/progs/redbook/scenebamb.c b/progs/redbook/scenebamb.c
new file mode 100644 (file)
index 0000000..a3449b5
--- /dev/null
@@ -0,0 +1,126 @@
+
+/* Copyright (c) Mark J. Kilgard, 1994. */
+
+/*
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+ */
+/*
+ *  scenebamb.c
+ *  This program demonstrates use of a blue ambient light 
+ *  source.
+ */
+#include <stdlib.h>
+#include <GL/glut.h>
+
+/*  Initialize light source and lighting.
+ */
+void myinit(void)
+{
+    GLfloat light_ambient[] = { 0.0, 0.0, 1.0, 1.0 };
+    GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
+    GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
+/*     light_position is NOT default value     */
+    GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
+
+    glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
+    glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
+    glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
+    glLightfv(GL_LIGHT0, GL_POSITION, light_position);
+    
+    glEnable(GL_LIGHTING);
+    glEnable(GL_LIGHT0);
+    glDepthFunc(GL_LESS);
+    glEnable(GL_DEPTH_TEST);
+}
+
+void display(void)
+{
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+    glPushMatrix ();
+    glRotatef (20.0, 1.0, 0.0, 0.0);
+
+    glPushMatrix ();
+    glTranslatef (-0.75, 0.5, 0.0); 
+    glRotatef (90.0, 1.0, 0.0, 0.0);
+    glutSolidTorus (0.275, 0.85, 15, 15);
+    glPopMatrix ();
+
+    glPushMatrix ();
+    glTranslatef (-0.75, -0.5, 0.0); 
+    glRotatef (270.0, 1.0, 0.0, 0.0);
+    glutSolidCone (1.0, 2.0, 15, 15);
+    glPopMatrix ();
+
+    glPushMatrix ();
+    glTranslatef (0.75, 0.0, -1.0); 
+    glutSolidSphere (1.0, 15, 15);
+    glPopMatrix ();
+
+    glPopMatrix ();
+    glFlush();
+}
+
+void myReshape(int w, int h)
+{
+    glViewport(0, 0, w, h);
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    if (w <= h) 
+       glOrtho (-2.5, 2.5, -2.5*(GLfloat)h/(GLfloat)w, 
+           2.5*(GLfloat)h/(GLfloat)w, -10.0, 10.0);
+    else 
+       glOrtho (-2.5*(GLfloat)w/(GLfloat)h, 
+           2.5*(GLfloat)w/(GLfloat)h, -2.5, 2.5, -10.0, 10.0);
+    glMatrixMode(GL_MODELVIEW);
+}
+
+/*  Main Loop
+ *  Open window with initial window size, title bar, 
+ *  RGBA display mode, and handle input events.
+ */
+int main(int argc, char** argv)
+{
+    glutInit(&argc, argv);
+    glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
+    glutInitWindowSize (500, 500);
+    glutCreateWindow (argv[0]);
+    myinit();
+    glutReshapeFunc (myReshape);
+    glutDisplayFunc(display);
+    glutMainLoop();
+    return 0;             /* ANSI C requires main to return int. */
+}
diff --git a/progs/redbook/sceneflat.c b/progs/redbook/sceneflat.c
new file mode 100644 (file)
index 0000000..5ab2037
--- /dev/null
@@ -0,0 +1,126 @@
+
+/* Copyright (c) Mark J. Kilgard, 1994. */
+
+/*
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+ */
+/*
+ *  sceneflat.c
+ *  This program draws lighted objects with flat shading.
+ */
+#include <stdlib.h>
+#include <GL/glut.h>
+
+/*  Initialize light source and shading model (GL_FLAT).
+ */
+void myinit(void)
+{
+    GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 };
+    GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
+    GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
+/*     light_position is NOT default value     */
+    GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
+
+    glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
+    glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
+    glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
+    glLightfv(GL_LIGHT0, GL_POSITION, light_position);
+    
+    glEnable(GL_LIGHTING);
+    glEnable(GL_LIGHT0);
+    glDepthFunc(GL_LESS);
+    glEnable(GL_DEPTH_TEST);
+    glShadeModel (GL_FLAT);
+}
+
+void display(void)
+{
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+    glPushMatrix ();
+    glRotatef (20.0, 1.0, 0.0, 0.0);
+
+    glPushMatrix ();
+    glTranslatef (-0.75, 0.5, 0.0); 
+    glRotatef (90.0, 1.0, 0.0, 0.0);
+    glutSolidTorus (0.275, 0.85, 15, 15);
+    glPopMatrix ();
+
+    glPushMatrix ();
+    glTranslatef (-0.75, -0.5, 0.0); 
+    glRotatef (270.0, 1.0, 0.0, 0.0);
+    glutSolidCone (1.0, 2.0, 15, 15);
+    glPopMatrix ();
+
+    glPushMatrix ();
+    glTranslatef (0.75, 0.0, -1.0); 
+    glutSolidSphere (1.0, 15, 15);
+    glPopMatrix ();
+
+    glPopMatrix ();
+    glFlush();
+}
+
+void myReshape(int w, int h)
+{
+    glViewport(0, 0, w, h);
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    if (w <= h) 
+       glOrtho (-2.5, 2.5, -2.5*(GLfloat)h/(GLfloat)w, 
+           2.5*(GLfloat)h/(GLfloat)w, -10.0, 10.0);
+    else 
+       glOrtho (-2.5*(GLfloat)w/(GLfloat)h, 
+           2.5*(GLfloat)w/(GLfloat)h, -2.5, 2.5, -10.0, 10.0);
+    glMatrixMode(GL_MODELVIEW);
+}
+
+/*  Main Loop
+ *  Open window with initial window size, title bar, 
+ *  RGBA display mode, and handle input events.
+ */
+int main(int argc, char** argv)
+{
+    glutInit(&argc, argv);
+    glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
+    glutInitWindowSize (500, 500);
+    glutCreateWindow (argv[0]);
+    myinit();
+    glutReshapeFunc (myReshape);
+    glutDisplayFunc(display);
+    glutMainLoop();
+    return 0;             /* ANSI C requires main to return int. */
+}
diff --git a/progs/redbook/select.c b/progs/redbook/select.c
new file mode 100644 (file)
index 0000000..4f413e7
--- /dev/null
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 1993-1997, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*
+ * select.c
+ * This is an illustration of the selection mode and 
+ * name stack, which detects whether objects which collide 
+ * with a viewing volume.  First, four triangles and a 
+ * rectangular box representing a viewing volume are drawn 
+ * (drawScene routine).  The green triangle and yellow 
+ * triangles appear to lie within the viewing volume, but 
+ * the red triangle appears to lie outside it.  Then the 
+ * selection mode is entered (selectObjects routine).  
+ * Drawing to the screen ceases.  To see if any collisions 
+ * occur, the four triangles are called.  In this example, 
+ * the green triangle causes one hit with the name 1, and 
+ * the yellow triangles cause one hit with the name 3.
+ */
+#include <GL/glut.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+/* draw a triangle with vertices at (x1, y1), (x2, y2) 
+ * and (x3, y3) at z units away from the origin.
+ */
+void drawTriangle (GLfloat x1, GLfloat y1, GLfloat x2, 
+    GLfloat y2, GLfloat x3, GLfloat y3, GLfloat z)
+{
+   glBegin (GL_TRIANGLES);
+   glVertex3f (x1, y1, z);
+   glVertex3f (x2, y2, z);
+   glVertex3f (x3, y3, z);
+   glEnd ();
+}
+
+/* draw a rectangular box with these outer x, y, and z values */
+void drawViewVolume (GLfloat x1, GLfloat x2, GLfloat y1, 
+                     GLfloat y2, GLfloat z1, GLfloat z2)
+{
+   glColor3f (1.0, 1.0, 1.0);
+   glBegin (GL_LINE_LOOP);
+   glVertex3f (x1, y1, -z1);
+   glVertex3f (x2, y1, -z1);
+   glVertex3f (x2, y2, -z1);
+   glVertex3f (x1, y2, -z1);
+   glEnd ();
+
+   glBegin (GL_LINE_LOOP);
+   glVertex3f (x1, y1, -z2);
+   glVertex3f (x2, y1, -z2);
+   glVertex3f (x2, y2, -z2);
+   glVertex3f (x1, y2, -z2);
+   glEnd ();
+
+   glBegin (GL_LINES); /*  4 lines     */
+   glVertex3f (x1, y1, -z1);
+   glVertex3f (x1, y1, -z2);
+   glVertex3f (x1, y2, -z1);
+   glVertex3f (x1, y2, -z2);
+   glVertex3f (x2, y1, -z1);
+   glVertex3f (x2, y1, -z2);
+   glVertex3f (x2, y2, -z1);
+   glVertex3f (x2, y2, -z2);
+   glEnd ();
+}
+
+/* drawScene draws 4 triangles and a wire frame
+ * which represents the viewing volume.
+ */
+void drawScene (void)
+{
+   glMatrixMode (GL_PROJECTION);
+   glLoadIdentity ();
+   gluPerspective (40.0, 4.0/3.0, 1.0, 100.0);
+
+   glMatrixMode (GL_MODELVIEW);
+   glLoadIdentity ();
+   gluLookAt (7.5, 7.5, 12.5, 2.5, 2.5, -5.0, 0.0, 1.0, 0.0);
+   glColor3f (0.0, 1.0, 0.0);  /*  green triangle      */
+   drawTriangle (2.0, 2.0, 3.0, 2.0, 2.5, 3.0, -5.0);
+   glColor3f (1.0, 0.0, 0.0);  /*  red triangle        */
+   drawTriangle (2.0, 7.0, 3.0, 7.0, 2.5, 8.0, -5.0);
+   glColor3f (1.0, 1.0, 0.0);  /*  yellow triangles    */
+   drawTriangle (2.0, 2.0, 3.0, 2.0, 2.5, 3.0, 0.0);
+   drawTriangle (2.0, 2.0, 3.0, 2.0, 2.5, 3.0, -10.0);
+   drawViewVolume (0.0, 5.0, 0.0, 5.0, 0.0, 10.0);
+}
+
+/* processHits prints out the contents of the selection array
+ */
+void processHits (GLint hits, GLuint buffer[])
+{
+   unsigned int i, j;
+   GLuint names, *ptr;
+
+   printf ("hits = %d\n", hits);
+   ptr = (GLuint *) buffer;
+   for (i = 0; i < hits; i++) {        /*  for each hit  */
+      names = *ptr;
+      printf (" number of names for hit = %d\n", names); ptr++;
+      printf("  z1 is %g;", (float) *ptr/0x7fffffff); ptr++;
+      printf(" z2 is %g\n", (float) *ptr/0x7fffffff); ptr++;
+      printf ("   the name is ");
+      for (j = 0; j < names; j++) {    /*  for each name */
+         printf ("%d ", *ptr); ptr++;
+      }
+      printf ("\n");
+   }
+}
+
+/* selectObjects "draws" the triangles in selection mode, 
+ * assigning names for the triangles.  Note that the third
+ * and fourth triangles share one name, so that if either 
+ * or both triangles intersects the viewing/clipping volume, 
+ * only one hit will be registered.
+ */
+#define BUFSIZE 512
+
+void selectObjects(void)
+{
+   GLuint selectBuf[BUFSIZE];
+   GLint hits;
+
+   glSelectBuffer (BUFSIZE, selectBuf);
+   (void) glRenderMode (GL_SELECT);
+
+   glInitNames();
+   glPushName(0);
+
+   glPushMatrix ();
+   glMatrixMode (GL_PROJECTION);
+   glLoadIdentity ();
+   glOrtho (0.0, 5.0, 0.0, 5.0, 0.0, 10.0);
+   glMatrixMode (GL_MODELVIEW);
+   glLoadIdentity ();
+   glLoadName(1);
+   drawTriangle (2.0, 2.0, 3.0, 2.0, 2.5, 3.0, -5.0);
+   glLoadName(2);
+   drawTriangle (2.0, 7.0, 3.0, 7.0, 2.5, 8.0, -5.0);
+   glLoadName(3);
+   drawTriangle (2.0, 2.0, 3.0, 2.0, 2.5, 3.0, 0.0);
+   drawTriangle (2.0, 2.0, 3.0, 2.0, 2.5, 3.0, -10.0);
+   glPopMatrix ();
+   glFlush ();
+
+   hits = glRenderMode (GL_RENDER);
+   processHits (hits, selectBuf);
+} 
+
+void init (void) 
+{
+   glEnable(GL_DEPTH_TEST);
+   glShadeModel(GL_FLAT);
+}
+
+void display(void)
+{
+   glClearColor (0.0, 0.0, 0.0, 0.0);
+   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+   drawScene ();
+   selectObjects ();
+   glFlush();
+}
+
+/* ARGSUSED1 */
+void keyboard(unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 27:
+         exit(0);
+         break;
+   }
+}
+
+/*  Main Loop  */
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
+   glutInitWindowSize (200, 200);
+   glutInitWindowPosition (100, 100);
+   glutCreateWindow (argv[0]);
+   init();
+   glutDisplayFunc(display);
+   glutKeyboardFunc(keyboard);
+   glutMainLoop();
+   return 0; 
+}
diff --git a/progs/redbook/smooth.c b/progs/redbook/smooth.c
new file mode 100644 (file)
index 0000000..9d22fc9
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 1993-1997, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*
+ * smooth.c
+ * This program demonstrates smooth shading.
+ * A smooth shaded polygon is drawn in a 2-D projection.
+ */
+#include <GL/glut.h>
+#include <stdlib.h>
+
+void init(void) 
+{
+   glClearColor (0.0, 0.0, 0.0, 0.0);
+   glShadeModel (GL_SMOOTH);
+}
+
+void triangle(void)
+{
+   glBegin (GL_TRIANGLES);
+   glColor3f (1.0, 0.0, 0.0);
+   glVertex2f (5.0, 5.0);
+   glColor3f (0.0, 1.0, 0.0);
+   glVertex2f (25.0, 5.0);
+   glColor3f (0.0, 0.0, 1.0);
+   glVertex2f (5.0, 25.0);
+   glEnd();
+}
+
+void display(void)
+{
+   glClear (GL_COLOR_BUFFER_BIT);
+   triangle ();
+   glFlush ();
+}
+
+void reshape (int w, int h)
+{
+   glViewport (0, 0, (GLsizei) w, (GLsizei) h);
+   glMatrixMode (GL_PROJECTION);
+   glLoadIdentity ();
+   if (w <= h)
+      gluOrtho2D (0.0, 30.0, 0.0, 30.0 * (GLfloat) h/(GLfloat) w);
+   else
+      gluOrtho2D (0.0, 30.0 * (GLfloat) w/(GLfloat) h, 0.0, 30.0);
+   glMatrixMode(GL_MODELVIEW);
+}
+
+/* ARGSUSED1 */
+void keyboard(unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 27:
+         exit(0);
+         break;
+   }
+}
+
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
+   glutInitWindowSize (500, 500); 
+   glutInitWindowPosition (100, 100);
+   glutCreateWindow (argv[0]);
+   init ();
+   glutDisplayFunc(display); 
+   glutReshapeFunc(reshape);
+   glutKeyboardFunc (keyboard);
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/redbook/stencil.c b/progs/redbook/stencil.c
new file mode 100644 (file)
index 0000000..958cf85
--- /dev/null
@@ -0,0 +1,162 @@
+
+/* Copyright (c) Mark J. Kilgard, 1994. */
+
+/*
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+ */
+/*  stencil.c
+ *  This program draws two rotated tori in a window.  
+ *  A diamond in the center of the window masks out part 
+ *  of the scene.  Within this mask, a different model 
+ *  (a sphere) is drawn in a different color.
+ */
+#include <stdlib.h>
+#include <GL/glut.h>
+
+#define YELLOWMAT   1
+#define BLUEMAT 2
+
+void myinit (void) 
+{
+    GLfloat yellow_diffuse[] = { 0.7, 0.7, 0.0, 1.0 };
+    GLfloat yellow_specular[] = { 1.0, 1.0, 1.0, 1.0 };
+
+    GLfloat blue_diffuse[] = { 0.1, 0.1, 0.7, 1.0 };
+    GLfloat blue_specular[] = { 0.1, 1.0, 1.0, 1.0 };
+
+    GLfloat position_one[] = { 1.0, 1.0, 1.0, 0.0 };
+
+    glNewList(YELLOWMAT, GL_COMPILE);
+    glMaterialfv(GL_FRONT, GL_DIFFUSE, yellow_diffuse);
+    glMaterialfv(GL_FRONT, GL_SPECULAR, yellow_specular);
+    glMaterialf(GL_FRONT, GL_SHININESS, 64.0);
+    glEndList();
+
+    glNewList(BLUEMAT, GL_COMPILE);
+    glMaterialfv(GL_FRONT, GL_DIFFUSE, blue_diffuse);
+    glMaterialfv(GL_FRONT, GL_SPECULAR, blue_specular);
+    glMaterialf(GL_FRONT, GL_SHININESS, 45.0);
+    glEndList();
+
+    glLightfv(GL_LIGHT0, GL_POSITION, position_one);
+
+    glEnable(GL_LIGHT0);
+    glEnable(GL_LIGHTING);
+    glDepthFunc(GL_LESS);
+    glEnable(GL_DEPTH_TEST);
+
+    glClearStencil(0x0);
+    glEnable(GL_STENCIL_TEST);
+
+}
+
+/*  Draw a sphere in a diamond-shaped section in the
+ *  middle of a window with 2 tori.
+ */
+void display(void)
+{
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+/* draw blue sphere where the stencil is 1 */
+    glStencilFunc (GL_EQUAL, 0x1, 0x1);
+    glCallList (BLUEMAT);
+    glutSolidSphere (0.5, 15, 15);
+
+/* draw the tori where the stencil is not 1 */
+    glStencilFunc (GL_NOTEQUAL, 0x1, 0x1);
+    glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
+    glPushMatrix();
+       glRotatef (45.0, 0.0, 0.0, 1.0);
+       glRotatef (45.0, 0.0, 1.0, 0.0);
+       glCallList (YELLOWMAT);
+       glutSolidTorus (0.275, 0.85, 15, 15);
+       glPushMatrix();
+           glRotatef (90.0, 1.0, 0.0, 0.0);
+           glutSolidTorus (0.275, 0.85, 15, 15);
+       glPopMatrix();
+    glPopMatrix();
+
+    glFlush();
+}
+
+/*  Whenever the window is reshaped, redefine the 
+ *  coordinate system and redraw the stencil area.
+ */
+void myReshape(int w, int h)
+{
+    glViewport(0, 0, w, h);
+
+    glClear(GL_STENCIL_BUFFER_BIT);
+/* create a diamond shaped stencil area */
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    glOrtho(-3.0, 3.0, -3.0, 3.0, -1.0, 1.0);
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
+
+    glStencilFunc (GL_ALWAYS, 0x1, 0x1);
+    glStencilOp (GL_REPLACE, GL_REPLACE, GL_REPLACE);
+    glBegin(GL_QUADS);
+       glVertex3f (-1.0, 0.0, 0.0);
+       glVertex3f (0.0, 1.0, 0.0);
+       glVertex3f (1.0, 0.0, 0.0);
+       glVertex3f (0.0, -1.0, 0.0);
+    glEnd();
+
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    gluPerspective(45.0, (GLfloat) w/(GLfloat) h, 3.0, 7.0);
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
+    glTranslatef(0.0, 0.0, -5.0);
+}
+
+/*  Main Loop
+ *  Open window with initial window size, title bar, 
+ *  RGBA display mode, and handle input events.
+ */
+int main(int argc, char** argv)
+{
+    glutInit(&argc, argv);
+    glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH | GLUT_STENCIL);
+    glutInitWindowSize (400, 400);
+    glutCreateWindow (argv[0]);
+    myinit ();
+    glutReshapeFunc (myReshape);
+    glutDisplayFunc(display);
+    glutMainLoop();
+    return 0;             /* ANSI C requires main to return int. */
+}
diff --git a/progs/redbook/stroke.c b/progs/redbook/stroke.c
new file mode 100644 (file)
index 0000000..d8c75c8
--- /dev/null
@@ -0,0 +1,181 @@
+
+/* Copyright (c) Mark J. Kilgard, 1994. */
+
+/*
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+ */
+/*
+ *  stroke.c 
+ *  This program demonstrates some characters of a 
+ *  stroke (vector) font.  The characters are represented
+ *  by display lists, which are given numbers which 
+ *  correspond to the ASCII values of the characters.
+ *  Use of glCallLists() is demonstrated.
+ */
+#include <stdlib.h>
+#include <string.h>
+#include <GL/glut.h>
+
+#define PT 1
+#define STROKE 2
+#define END 3
+
+typedef struct charpoint {
+    GLfloat   x, y;
+    int    type;
+} CP;
+
+CP Adata[] = {
+    { 0, 0, PT}, {0, 9, PT}, {1, 10, PT}, {4, 10, PT}, 
+    {5, 9, PT}, {5, 0, STROKE}, {0, 5, PT}, {5, 5, END}
+};
+
+CP Edata[] = {
+    {5, 0, PT}, {0, 0, PT}, {0, 10, PT}, {5, 10, STROKE},
+    {0, 5, PT}, {4, 5, END}
+};
+
+CP Pdata[] = {
+    {0, 0, PT}, {0, 10, PT},  {4, 10, PT}, {5, 9, PT}, {5, 6, PT}, 
+    {4, 5, PT}, {0, 5, END}
+};
+
+CP Rdata[] = {
+    {0, 0, PT}, {0, 10, PT},  {4, 10, PT}, {5, 9, PT}, {5, 6, PT}, 
+    {4, 5, PT}, {0, 5, STROKE}, {3, 5, PT}, {5, 0, END}
+};
+
+CP Sdata[] = {
+    {0, 1, PT}, {1, 0, PT}, {4, 0, PT}, {5, 1, PT}, {5, 4, PT}, 
+    {4, 5, PT}, {1, 5, PT}, {0, 6, PT}, {0, 9, PT}, {1, 10, PT}, 
+    {4, 10, PT}, {5, 9, END}
+};
+
+/*  drawLetter() interprets the instructions from the array
+ *  for that letter and renders the letter with line segments.
+ */
+void drawLetter(CP *l)
+{
+    glBegin(GL_LINE_STRIP);
+    for (;;) {
+       switch (l->type) {
+           case PT:
+               glVertex2fv(&l->x);
+               break;
+           case STROKE:
+               glVertex2fv(&l->x);
+               glEnd();
+               glBegin(GL_LINE_STRIP);
+               break;
+           case END:
+               glVertex2fv(&l->x);
+               glEnd();
+               glTranslatef(8.0, 0.0, 0.0);
+               return;
+       }
+       l++;
+    }
+}
+
+/*  Create a display list for each of 6 characters     */
+void myinit (void)
+{
+    GLuint base;
+
+    glShadeModel (GL_FLAT);
+
+    base = glGenLists (128);
+    glListBase(base);
+    glNewList(base+'A', GL_COMPILE); drawLetter(Adata); glEndList();
+    glNewList(base+'E', GL_COMPILE); drawLetter(Edata); glEndList();
+    glNewList(base+'P', GL_COMPILE); drawLetter(Pdata); glEndList();
+    glNewList(base+'R', GL_COMPILE); drawLetter(Rdata); glEndList();
+    glNewList(base+'S', GL_COMPILE); drawLetter(Sdata); glEndList();
+    glNewList(base+' ', GL_COMPILE); glTranslatef(8.0, 0.0, 0.0); glEndList();
+}
+
+char *test1 = "A SPARE SERAPE APPEARS AS";
+char *test2 = "APES PREPARE RARE PEPPERS";
+
+void printStrokedString(char *s)
+{
+    GLsizei len = (GLsizei) strlen(s);
+    glCallLists(len, GL_BYTE, (GLbyte *)s);
+}
+
+void display(void)
+{
+    glClear(GL_COLOR_BUFFER_BIT);
+    glColor3f(1.0, 1.0, 1.0);
+    glPushMatrix();
+    glScalef(2.0, 2.0, 2.0);
+    glTranslatef(10.0, 30.0, 0.0);
+    printStrokedString(test1);
+    glPopMatrix();
+    glPushMatrix();
+    glScalef(2.0, 2.0, 2.0);
+    glTranslatef(10.0, 13.0, 0.0);
+    printStrokedString(test2);
+    glPopMatrix();
+    glFlush();
+}
+
+static void reshape(GLsizei w, GLsizei h)
+{
+    glViewport(0, 0, w, h);
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    glOrtho(0.0, (GLdouble)w, 0.0, (GLdouble)h, -1.0, 1.0);
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
+}
+
+/*  Main Loop
+ *  Open window with initial window size, title bar, 
+ *  RGBA display mode, and handle input events.
+ */
+int main(int argc, char** argv)
+{
+    glutInit(&argc, argv);
+    glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
+    glutInitWindowSize (440, 120);
+    glutCreateWindow (argv[0]);
+    myinit ();
+    glutDisplayFunc(display);
+    glutReshapeFunc(reshape);
+    glutMainLoop();
+    return 0;             /* ANSI C requires main to return int. */
+}
diff --git a/progs/redbook/surface.c b/progs/redbook/surface.c
new file mode 100644 (file)
index 0000000..fb2691e
--- /dev/null
@@ -0,0 +1,217 @@
+/* aux2glut conversion Copyright (c) Mark J. Kilgard, 1994, 1995 */
+
+/**
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+ */
+/**
+ *  surface.c
+ *  This program draws a NURBS surface in the shape of a 
+ *  symmetrical hill.
+ */
+#include <GL/glut.h>
+
+GLfloat ctlpoints[4][4][3];
+int showPoints = 0;
+
+GLUnurbsObj *theNurb;
+
+/*
+ *  Initializes the control points of the surface to a small hill.
+ *  The control points range from -3 to +3 in x, y, and z
+ */
+void init_surface(void)
+{
+    int u, v;
+    for (u = 0; u < 4; u++) {
+       for (v = 0; v < 4; v++) {
+           ctlpoints[u][v][0] = 2.0*((GLfloat)u - 1.5);
+           ctlpoints[u][v][1] = 2.0*((GLfloat)v - 1.5);
+
+           if ( (u == 1 || u == 2) && (v == 1 || v == 2))
+               ctlpoints[u][v][2] = 7.0;
+           else
+               ctlpoints[u][v][2] = -3.0;
+       }
+    }                          
+}                              
+                       
+/*  Initialize material property and depth buffer.
+ */
+void myinit(void)
+{
+    GLfloat mat_diffuse[] = { 0.7, 0.7, 0.7, 1.0 };
+    GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
+    GLfloat mat_shininess[] = { 100.0 };
+
+    glClearColor (0.0, 0.0, 0.0, 1.0);
+    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
+    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
+    glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
+
+    glEnable(GL_LIGHTING);
+    glEnable(GL_LIGHT0);
+    glDepthFunc(GL_LESS);
+    glEnable(GL_DEPTH_TEST);
+    glEnable(GL_AUTO_NORMAL);
+    glEnable(GL_NORMALIZE);
+
+    init_surface();
+
+    theNurb = gluNewNurbsRenderer();
+    gluNurbsProperty(theNurb, GLU_SAMPLING_TOLERANCE, 25.0);
+    gluNurbsProperty(theNurb, GLU_DISPLAY_MODE, GLU_FILL);
+
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
+    glTranslatef (0.0, 0.0, -5.0);
+}
+
+void display(void)
+{
+    GLfloat knots[8] = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0};
+    int i, j;
+
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+    glPushMatrix();
+    glRotatef(330.0, 1.,0.,0.);
+    glScalef (0.25, 0.25, 0.25);
+
+    gluBeginSurface(theNurb);
+    gluNurbsSurface(theNurb, 
+           8, knots,
+           8, knots,
+           4 * 3,
+           3,
+           &ctlpoints[0][0][0], 
+           4, 4,
+           GL_MAP2_VERTEX_3);
+    gluEndSurface(theNurb);
+
+    if(showPoints) {
+    glPointSize(5.0);
+    glDisable(GL_LIGHTING);
+    glColor3f(1.0, 1.0, 0.0);
+    glBegin(GL_POINTS);
+    for(i=0;i<4;i++) {
+      for(j=0;j<4;j++) {
+       glVertex3f(ctlpoints[i][j][0], ctlpoints[i][j][1], ctlpoints[i][j][2]);
+      }
+    }
+    glEnd();
+    glEnable(GL_LIGHTING);
+    }
+        
+    glPopMatrix();
+    glutSwapBuffers();
+}
+
+void reshape(int w, int h)
+{
+    glViewport(0, 0, w, h);
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    gluPerspective (45.0, (GLdouble)w/(GLdouble)h, 3.0, 8.0);
+
+    glMatrixMode(GL_MODELVIEW);
+}
+
+void
+menu(int value)
+{
+    switch (value) {
+    case 0:
+    case 1:
+        showPoints = value;
+       break;
+    case 2:
+        gluNurbsProperty(theNurb, GLU_DISPLAY_MODE, GLU_FILL);
+       break;
+    case 3:
+        gluNurbsProperty(theNurb, GLU_DISPLAY_MODE, GLU_OUTLINE_POLYGON);
+       break;
+    }
+    glutPostRedisplay();
+}
+
+int down = 0, lastx;
+
+/* ARGSUSED1 */
+void
+motion(int x, int y)
+{
+    if (down) {
+        glRotatef(lastx - x, 0, 1, 0);
+        lastx = x;
+        glutPostRedisplay();
+    }
+}
+
+/* ARGSUSED3 */
+void
+mouse(int button, int state, int x, int y)
+{
+    if (button == GLUT_LEFT_BUTTON) {
+        if (state == GLUT_DOWN) {
+            lastx = x;
+            down = 1;
+        } else {
+            down = 0;
+        }
+    }
+}
+
+/* Main Loop */
+int
+main(int argc, char** argv)
+{
+    glutInit(&argc, argv);
+    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB);
+    glutCreateWindow(argv[0]);
+    myinit();
+    glutReshapeFunc(reshape);
+    glutDisplayFunc(display);
+    glutCreateMenu(menu);
+    glutAddMenuEntry("Show control points", 1);
+    glutAddMenuEntry("Hide control points", 0);
+    glutAddMenuEntry("Solid", 2);
+    glutAddMenuEntry("Wireframe", 3);
+    glutAttachMenu(GLUT_RIGHT_BUTTON);
+    glutMouseFunc(mouse);
+    glutMotionFunc(motion);
+    glutMainLoop();
+    return 0;             /* ANSI C requires main to return int. */
+}
diff --git a/progs/redbook/teaambient.c b/progs/redbook/teaambient.c
new file mode 100644 (file)
index 0000000..62c091c
--- /dev/null
@@ -0,0 +1,148 @@
+
+/* Copyright (c) Mark J. Kilgard, 1994. */
+
+/**
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+ */
+/**
+ *  teaambient.c
+ *  This program renders three lighted, shaded teapots, with
+ *  different ambient values.
+ */
+#include <stdlib.h>
+#include <GL/glut.h>
+
+/*  Initialize light source and lighting model.
+ */
+void 
+myinit(void)
+{
+    GLfloat light_ambient[] =
+    {0.0, 0.0, 0.0, 1.0};
+    GLfloat light_diffuse[] =
+    {1.0, 1.0, 1.0, 1.0};
+    GLfloat light_specular[] =
+    {1.0, 1.0, 1.0, 1.0};
+/* light_position is NOT default value */
+    GLfloat light_position[] =
+    {1.0, 0.0, 0.0, 0.0};
+    GLfloat global_ambient[] =
+    {0.75, 0.75, 0.75, 1.0};
+
+    glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
+    glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
+    glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
+    glLightfv(GL_LIGHT0, GL_POSITION, light_position);
+
+    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, global_ambient);
+
+    glFrontFace(GL_CW);
+    glEnable(GL_LIGHTING);
+    glEnable(GL_LIGHT0);
+    glEnable(GL_AUTO_NORMAL);
+    glEnable(GL_NORMALIZE);
+    glDepthFunc(GL_LESS);
+    glEnable(GL_DEPTH_TEST);
+}
+
+void 
+display(void)
+{
+    GLfloat low_ambient[] =
+    {0.1, 0.1, 0.1, 1.0};
+    GLfloat more_ambient[] =
+    {0.4, 0.4, 0.4, 1.0};
+    GLfloat most_ambient[] =
+    {1.0, 1.0, 1.0, 1.0};
+
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+    /*  material has small ambient reflection */
+    glMaterialfv(GL_FRONT, GL_AMBIENT, low_ambient);
+    glMaterialf(GL_FRONT, GL_SHININESS, 40.0);
+    glPushMatrix();
+    glTranslatef(0.0, 2.0, 0.0);
+    glutSolidTeapot(1.0);
+    glPopMatrix();
+
+    /*  material has moderate ambient reflection */
+    glMaterialfv(GL_FRONT, GL_AMBIENT, more_ambient);
+    glPushMatrix();
+    glTranslatef(0.0, 0.0, 0.0);
+    glutSolidTeapot(1.0);
+    glPopMatrix();
+
+    /*  material has large ambient reflection */
+    glMaterialfv(GL_FRONT, GL_AMBIENT, most_ambient);
+    glPushMatrix();
+    glTranslatef(0.0, -2.0, 0.0);
+    glutSolidTeapot(1.0);
+    glPopMatrix();
+    glFlush();
+}
+
+void 
+myReshape(int w, int h)
+{
+    glViewport(0, 0, w, h);
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    if (w <= h)
+        glOrtho(-4.0, 4.0, -4.0 * (GLfloat) h / (GLfloat) w,
+            4.0 * (GLfloat) h / (GLfloat) w, -10.0, 10.0);
+    else
+        glOrtho(-4.0 * (GLfloat) w / (GLfloat) h,
+            4.0 * (GLfloat) w / (GLfloat) h, -4.0, 4.0, -10.0, 10.0);
+    glMatrixMode(GL_MODELVIEW);
+}
+
+/*  Main Loop
+ *  Open window with initial window size, title bar, 
+ *  RGBA display mode, and handle input events.
+ */
+int
+main(int argc, char **argv)
+{
+    glutInit(&argc, argv);
+    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
+    glutInitWindowSize(500, 500);
+    glutCreateWindow(argv[0]);
+    myinit();
+    glutReshapeFunc(myReshape);
+    glutDisplayFunc(display);
+    glutMainLoop();
+    return 0;             /* ANSI C requires main to return int. */
+}
diff --git a/progs/redbook/teapots.c b/progs/redbook/teapots.c
new file mode 100644 (file)
index 0000000..2431cae
--- /dev/null
@@ -0,0 +1,206 @@
+
+/* Copyright (c) Mark J. Kilgard, 1994. */
+
+/**
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED
+ * Permission to use, copy, modify, and distribute this software for
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission.
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * US Government Users Restricted Rights
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+ */
+/**
+ *  teapots.c
+ *  This program demonstrates lots of material properties.
+ *  A single light source illuminates the objects.
+ */
+#include <stdlib.h>
+#include <GL/glut.h>
+
+/*
+ * Initialize depth buffer, projection matrix, light source, and lighting
+ * model.  Do not specify a material property here.
+ */
+void
+myinit(void)
+{
+  GLfloat ambient[] =
+  {0.0, 0.0, 0.0, 1.0};
+  GLfloat diffuse[] =
+  {1.0, 1.0, 1.0, 1.0};
+  GLfloat position[] =
+  {0.0, 3.0, 3.0, 0.0};
+
+  GLfloat lmodel_ambient[] =
+  {0.2, 0.2, 0.2, 1.0};
+  GLfloat local_view[] =
+  {0.0};
+
+  glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
+  glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
+  glLightfv(GL_LIGHT0, GL_POSITION, position);
+  glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
+  glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, local_view);
+
+  glFrontFace(GL_CW);
+  glEnable(GL_LIGHTING);
+  glEnable(GL_LIGHT0);
+  glEnable(GL_AUTO_NORMAL);
+  glEnable(GL_NORMALIZE);
+  glEnable(GL_DEPTH_TEST);
+  glDepthFunc(GL_LESS);
+}
+
+/*
+ * Move object into position.  Use 3rd through 12th parameters to specify the
+ * material property.  Draw a teapot.
+ */
+void
+renderTeapot(GLfloat x, GLfloat y,
+  GLfloat ambr, GLfloat ambg, GLfloat ambb,
+  GLfloat difr, GLfloat difg, GLfloat difb,
+  GLfloat specr, GLfloat specg, GLfloat specb, GLfloat shine)
+{
+  float mat[4];
+
+  glPushMatrix();
+  glTranslatef(x, y, 0.0);
+  mat[0] = ambr;
+  mat[1] = ambg;
+  mat[2] = ambb;
+  mat[3] = 1.0;
+  glMaterialfv(GL_FRONT, GL_AMBIENT, mat);
+  mat[0] = difr;
+  mat[1] = difg;
+  mat[2] = difb;
+  glMaterialfv(GL_FRONT, GL_DIFFUSE, mat);
+  mat[0] = specr;
+  mat[1] = specg;
+  mat[2] = specb;
+  glMaterialfv(GL_FRONT, GL_SPECULAR, mat);
+  glMaterialf(GL_FRONT, GL_SHININESS, shine * 128.0);
+  glutSolidTeapot(1.0);
+  glPopMatrix();
+}
+
+/**
+ *  First column:  emerald, jade, obsidian, pearl, ruby, turquoise
+ *  2nd column:  brass, bronze, chrome, copper, gold, silver
+ *  3rd column:  black, cyan, green, red, white, yellow plastic
+ *  4th column:  black, cyan, green, red, white, yellow rubber
+ */
+void
+display(void)
+{
+  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+  renderTeapot(2.0, 17.0, 0.0215, 0.1745, 0.0215,
+    0.07568, 0.61424, 0.07568, 0.633, 0.727811, 0.633, 0.6);
+  renderTeapot(2.0, 14.0, 0.135, 0.2225, 0.1575,
+    0.54, 0.89, 0.63, 0.316228, 0.316228, 0.316228, 0.1);
+  renderTeapot(2.0, 11.0, 0.05375, 0.05, 0.06625,
+    0.18275, 0.17, 0.22525, 0.332741, 0.328634, 0.346435, 0.3);
+  renderTeapot(2.0, 8.0, 0.25, 0.20725, 0.20725,
+    1, 0.829, 0.829, 0.296648, 0.296648, 0.296648, 0.088);
+  renderTeapot(2.0, 5.0, 0.1745, 0.01175, 0.01175,
+    0.61424, 0.04136, 0.04136, 0.727811, 0.626959, 0.626959, 0.6);
+  renderTeapot(2.0, 2.0, 0.1, 0.18725, 0.1745,
+    0.396, 0.74151, 0.69102, 0.297254, 0.30829, 0.306678, 0.1);
+  renderTeapot(6.0, 17.0, 0.329412, 0.223529, 0.027451,
+    0.780392, 0.568627, 0.113725, 0.992157, 0.941176, 0.807843,
+    0.21794872);
+  renderTeapot(6.0, 14.0, 0.2125, 0.1275, 0.054,
+    0.714, 0.4284, 0.18144, 0.393548, 0.271906, 0.166721, 0.2);
+  renderTeapot(6.0, 11.0, 0.25, 0.25, 0.25,
+    0.4, 0.4, 0.4, 0.774597, 0.774597, 0.774597, 0.6);
+  renderTeapot(6.0, 8.0, 0.19125, 0.0735, 0.0225,
+    0.7038, 0.27048, 0.0828, 0.256777, 0.137622, 0.086014, 0.1);
+  renderTeapot(6.0, 5.0, 0.24725, 0.1995, 0.0745,
+    0.75164, 0.60648, 0.22648, 0.628281, 0.555802, 0.366065, 0.4);
+  renderTeapot(6.0, 2.0, 0.19225, 0.19225, 0.19225,
+    0.50754, 0.50754, 0.50754, 0.508273, 0.508273, 0.508273, 0.4);
+  renderTeapot(10.0, 17.0, 0.0, 0.0, 0.0, 0.01, 0.01, 0.01,
+    0.50, 0.50, 0.50, .25);
+  renderTeapot(10.0, 14.0, 0.0, 0.1, 0.06, 0.0, 0.50980392, 0.50980392,
+    0.50196078, 0.50196078, 0.50196078, .25);
+  renderTeapot(10.0, 11.0, 0.0, 0.0, 0.0,
+    0.1, 0.35, 0.1, 0.45, 0.55, 0.45, .25);
+  renderTeapot(10.0, 8.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0,
+    0.7, 0.6, 0.6, .25);
+  renderTeapot(10.0, 5.0, 0.0, 0.0, 0.0, 0.55, 0.55, 0.55,
+    0.70, 0.70, 0.70, .25);
+  renderTeapot(10.0, 2.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0,
+    0.60, 0.60, 0.50, .25);
+  renderTeapot(14.0, 17.0, 0.02, 0.02, 0.02, 0.01, 0.01, 0.01,
+    0.4, 0.4, 0.4, .078125);
+  renderTeapot(14.0, 14.0, 0.0, 0.05, 0.05, 0.4, 0.5, 0.5,
+    0.04, 0.7, 0.7, .078125);
+  renderTeapot(14.0, 11.0, 0.0, 0.05, 0.0, 0.4, 0.5, 0.4,
+    0.04, 0.7, 0.04, .078125);
+  renderTeapot(14.0, 8.0, 0.05, 0.0, 0.0, 0.5, 0.4, 0.4,
+    0.7, 0.04, 0.04, .078125);
+  renderTeapot(14.0, 5.0, 0.05, 0.05, 0.05, 0.5, 0.5, 0.5,
+    0.7, 0.7, 0.7, .078125);
+  renderTeapot(14.0, 2.0, 0.05, 0.05, 0.0, 0.5, 0.5, 0.4,
+    0.7, 0.7, 0.04, .078125);
+  glFlush();
+}
+
+void
+myReshape(int w, int h)
+{
+  glViewport(0, 0, w, h);
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+  if (w <= h)
+    glOrtho(0.0, 16.0, 0.0, 16.0 * (GLfloat) h / (GLfloat) w,
+      -10.0, 10.0);
+  else
+    glOrtho(0.0, 16.0 * (GLfloat) w / (GLfloat) h, 0.0, 16.0,
+      -10.0, 10.0);
+  glMatrixMode(GL_MODELVIEW);
+}
+
+/*
+ * Main Loop Open window with initial window size, title bar, RGBA display
+ * mode, and handle input events.
+ */
+int
+main(int argc, char **argv)
+{
+  glutInit(&argc, argv);
+  glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
+  glutCreateWindow(argv[0]);
+  myinit();
+  glutReshapeFunc(myReshape);
+  glutDisplayFunc(display);
+  glutMainLoop();
+  return 0;             /* ANSI C requires main to return int. */
+}
diff --git a/progs/redbook/tess.c b/progs/redbook/tess.c
new file mode 100644 (file)
index 0000000..cef35db
--- /dev/null
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 1993-1997, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*
+ *  tess.c
+ *  This program demonstrates polygon tessellation.
+ *  Two tesselated objects are drawn.  The first is a
+ *  rectangle with a triangular hole.  The second is a
+ *  smooth shaded, self-intersecting star.
+ *
+ *  Note the exterior rectangle is drawn with its vertices
+ *  in counter-clockwise order, but its interior clockwise.
+ *  Note the combineCallback is needed for the self-intersecting
+ *  star.  Also note that removing the TessProperty for the 
+ *  star will make the interior unshaded (WINDING_ODD).
+ */
+#include <GL/glut.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef GLU_VERSION_1_2
+
+/* Win32 calling conventions. */
+#ifndef CALLBACK
+#define CALLBACK
+#endif
+
+GLuint startList;
+
+void display (void) {
+   glClear(GL_COLOR_BUFFER_BIT);
+   glColor3f(1.0, 1.0, 1.0);
+   glCallList(startList);
+   glCallList(startList + 1);
+   glFlush();
+}
+
+void CALLBACK beginCallback(GLenum which)
+{
+   glBegin(which);
+}
+
+void CALLBACK errorCallback(GLenum errorCode)
+{
+   const GLubyte *estring;
+
+   estring = gluErrorString(errorCode);
+   fprintf(stderr, "Tessellation Error: %s\n", estring);
+   exit(0);
+}
+
+void CALLBACK endCallback(void)
+{
+   glEnd();
+}
+
+void CALLBACK vertexCallback(GLvoid *vertex)
+{
+   const GLdouble *pointer;
+
+   pointer = (GLdouble *) vertex;
+   glColor3dv(pointer+3);
+   glVertex3dv(vertex);
+}
+
+/*  combineCallback is used to create a new vertex when edges
+ *  intersect.  coordinate location is trivial to calculate,
+ *  but weight[4] may be used to average color, normal, or texture
+ *  coordinate data.  In this program, color is weighted.
+ */
+void CALLBACK combineCallback(GLdouble coords[3], 
+                     GLdouble *vertex_data[4],
+                     GLfloat weight[4], GLdouble **dataOut )
+{
+   GLdouble *vertex;
+   int i;
+
+   vertex = (GLdouble *) malloc(6 * sizeof(GLdouble));
+
+   vertex[0] = coords[0];
+   vertex[1] = coords[1];
+   vertex[2] = coords[2];
+   for (i = 3; i < 7; i++)
+      vertex[i] = weight[0] * vertex_data[0][i] 
+                  + weight[1] * vertex_data[1][i]
+                  + weight[2] * vertex_data[2][i] 
+                  + weight[3] * vertex_data[3][i];
+   *dataOut = vertex;
+}
+
+void init (void) 
+{
+   GLUtesselator *tobj;
+   GLdouble rect[4][3] = {50.0, 50.0, 0.0,
+                          200.0, 50.0, 0.0,
+                          200.0, 200.0, 0.0,
+                          50.0, 200.0, 0.0};
+   GLdouble tri[3][3] = {75.0, 75.0, 0.0,
+                         125.0, 175.0, 0.0,
+                         175.0, 75.0, 0.0};
+   GLdouble star[5][6] = {250.0, 50.0, 0.0, 1.0, 0.0, 1.0,
+                          325.0, 200.0, 0.0, 1.0, 1.0, 0.0,
+                          400.0, 50.0, 0.0, 0.0, 1.0, 1.0,
+                          250.0, 150.0, 0.0, 1.0, 0.0, 0.0,
+                          400.0, 150.0, 0.0, 0.0, 1.0, 0.0};
+
+   glClearColor(0.0, 0.0, 0.0, 0.0);
+
+   startList = glGenLists(2);
+
+   tobj = gluNewTess();
+   gluTessCallback(tobj, GLU_TESS_VERTEX, 
+                   (GLvoid (CALLBACK*) ()) &glVertex3dv);
+   gluTessCallback(tobj, GLU_TESS_BEGIN, 
+                   (GLvoid (CALLBACK*) ()) &beginCallback);
+   gluTessCallback(tobj, GLU_TESS_END, 
+                   (GLvoid (CALLBACK*) ()) &endCallback);
+   gluTessCallback(tobj, GLU_TESS_ERROR, 
+                   (GLvoid (CALLBACK*) ()) &errorCallback);
+
+   /*  rectangle with triangular hole inside  */
+   glNewList(startList, GL_COMPILE);
+   glShadeModel(GL_FLAT);    
+   gluTessBeginPolygon(tobj, NULL);
+      gluTessBeginContour(tobj);
+         gluTessVertex(tobj, rect[0], rect[0]);
+         gluTessVertex(tobj, rect[1], rect[1]);
+         gluTessVertex(tobj, rect[2], rect[2]);
+         gluTessVertex(tobj, rect[3], rect[3]);
+      gluTessEndContour(tobj);
+      gluTessBeginContour(tobj);
+         gluTessVertex(tobj, tri[0], tri[0]);
+         gluTessVertex(tobj, tri[1], tri[1]);
+         gluTessVertex(tobj, tri[2], tri[2]);
+      gluTessEndContour(tobj);
+   gluTessEndPolygon(tobj);
+   glEndList();
+
+   gluTessCallback(tobj, GLU_TESS_VERTEX, 
+                   (GLvoid (CALLBACK*) ()) &vertexCallback);
+   gluTessCallback(tobj, GLU_TESS_BEGIN, 
+                   (GLvoid (CALLBACK*) ()) &beginCallback);
+   gluTessCallback(tobj, GLU_TESS_END, 
+                   (GLvoid (CALLBACK*) ()) &endCallback);
+   gluTessCallback(tobj, GLU_TESS_ERROR, 
+                   (GLvoid (CALLBACK*) ()) &errorCallback);
+   gluTessCallback(tobj, GLU_TESS_COMBINE, 
+                   (GLvoid (CALLBACK*) ()) &combineCallback);
+
+   /*  smooth shaded, self-intersecting star  */
+   glNewList(startList + 1, GL_COMPILE);
+   glShadeModel(GL_SMOOTH);    
+   gluTessProperty(tobj, GLU_TESS_WINDING_RULE,
+                   GLU_TESS_WINDING_POSITIVE);
+   gluTessBeginPolygon(tobj, NULL);
+      gluTessBeginContour(tobj);
+         gluTessVertex(tobj, star[0], star[0]);
+         gluTessVertex(tobj, star[1], star[1]);
+         gluTessVertex(tobj, star[2], star[2]);
+         gluTessVertex(tobj, star[3], star[3]);
+         gluTessVertex(tobj, star[4], star[4]);
+      gluTessEndContour(tobj);
+   gluTessEndPolygon(tobj);
+   glEndList();
+   gluDeleteTess(tobj);
+}
+
+void reshape (int w, int h)
+{
+   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   gluOrtho2D(0.0, (GLdouble) w, 0.0, (GLdouble) h);
+}
+
+/* ARGSUSED1 */
+void keyboard(unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 27:
+         exit(0);
+         break;
+   }
+}
+
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
+   glutInitWindowSize(500, 500);
+   glutCreateWindow(argv[0]);
+   init();
+   glutDisplayFunc(display);
+   glutReshapeFunc(reshape);
+   glutKeyboardFunc(keyboard);
+   glutMainLoop();
+   return 0;  
+}
+
+#else
+int main(int argc, char** argv)
+{
+    fprintf (stderr, "This program demonstrates the new tesselator API in GLU 1.2.\n");
+    fprintf (stderr, "Your GLU library does not support this new interface, sorry.\n");
+    return 0;
+}
+#endif
diff --git a/progs/redbook/tesswind.c b/progs/redbook/tesswind.c
new file mode 100644 (file)
index 0000000..455966a
--- /dev/null
@@ -0,0 +1,290 @@
+/*
+ * Copyright (c) 1993-1997, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*
+ *  tesswind.c
+ *  This program demonstrates the winding rule polygon 
+ *  tessellation property.  Four tessellated objects are drawn, 
+ *  each with very different contours.  When the w key is pressed, 
+ *  the objects are drawn with a different winding rule.
+ */
+#include <GL/glut.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef GLU_VERSION_1_2
+
+/* Win32 calling conventions. */
+#ifndef CALLBACK
+#define CALLBACK
+#endif
+
+GLdouble currentWinding = GLU_TESS_WINDING_ODD;
+int currentShape = 0;
+GLUtesselator *tobj;
+GLuint list;
+
+/*  Make four display lists, 
+ *  each with a different tessellated object. 
+ */
+void makeNewLists (void) {
+   int i;
+   static GLdouble rects[12][3] = 
+      {50.0, 50.0, 0.0, 300.0, 50.0, 0.0, 
+       300.0, 300.0, 0.0, 50.0, 300.0, 0.0,
+       100.0, 100.0, 0.0, 250.0, 100.0, 0.0, 
+       250.0, 250.0, 0.0, 100.0, 250.0, 0.0,
+       150.0, 150.0, 0.0, 200.0, 150.0, 0.0, 
+       200.0, 200.0, 0.0, 150.0, 200.0, 0.0};
+   static GLdouble spiral[16][3] = 
+      {400.0, 250.0, 0.0, 400.0, 50.0, 0.0, 
+       50.0, 50.0, 0.0, 50.0, 400.0, 0.0, 
+       350.0, 400.0, 0.0, 350.0, 100.0, 0.0, 
+       100.0, 100.0, 0.0, 100.0, 350.0, 0.0, 
+       300.0, 350.0, 0.0, 300.0, 150.0, 0.0, 
+       150.0, 150.0, 0.0, 150.0, 300.0, 0.0, 
+       250.0, 300.0, 0.0, 250.0, 200.0, 0.0, 
+       200.0, 200.0, 0.0, 200.0, 250.0, 0.0};
+   static GLdouble quad1[4][3] = 
+      {50.0, 150.0, 0.0, 350.0, 150.0, 0.0, 
+      350.0, 200.0, 0.0, 50.0, 200.0, 0.0};
+   static GLdouble quad2[4][3] =
+      {100.0, 100.0, 0.0, 300.0, 100.0, 0.0, 
+       300.0, 350.0, 0.0, 100.0, 350.0, 0.0};
+   static GLdouble tri[3][3] =
+      {200.0, 50.0, 0.0, 250.0, 300.0, 0.0,
+       150.0, 300.0, 0.0};
+   gluTessProperty(tobj, GLU_TESS_WINDING_RULE, 
+                   currentWinding);
+
+   glNewList(list, GL_COMPILE);
+      gluTessBeginPolygon(tobj, NULL);
+         gluTessBeginContour(tobj);
+         for (i = 0; i < 4; i++)
+            gluTessVertex(tobj, rects[i], rects[i]);
+         gluTessEndContour(tobj);
+         gluTessBeginContour(tobj);
+         for (i = 4; i < 8; i++)
+            gluTessVertex(tobj, rects[i], rects[i]);
+         gluTessEndContour(tobj);
+         gluTessBeginContour(tobj);
+         for (i = 8; i < 12; i++)
+            gluTessVertex(tobj, rects[i], rects[i]);
+         gluTessEndContour(tobj);
+      gluTessEndPolygon(tobj);
+   glEndList();
+
+   glNewList(list+1, GL_COMPILE);
+      gluTessBeginPolygon(tobj, NULL);
+         gluTessBeginContour(tobj);
+         for (i = 0; i < 4; i++)
+            gluTessVertex(tobj, rects[i], rects[i]);
+         gluTessEndContour(tobj);
+         gluTessBeginContour(tobj);
+         for (i = 7; i >= 4; i--)
+            gluTessVertex(tobj, rects[i], rects[i]);
+         gluTessEndContour(tobj);
+         gluTessBeginContour(tobj);
+         for (i = 11; i >= 8; i--)
+            gluTessVertex(tobj, rects[i], rects[i]);
+         gluTessEndContour(tobj);
+      gluTessEndPolygon(tobj);
+   glEndList();
+
+   glNewList(list+2, GL_COMPILE);
+      gluTessBeginPolygon(tobj, NULL);
+         gluTessBeginContour(tobj);
+         for (i = 0; i < 16; i++)
+            gluTessVertex(tobj, spiral[i], spiral[i]);
+         gluTessEndContour(tobj);
+      gluTessEndPolygon(tobj);
+   glEndList();
+
+   glNewList(list+3, GL_COMPILE);
+      gluTessBeginPolygon(tobj, NULL);
+         gluTessBeginContour(tobj);
+         for (i = 0; i < 4; i++)
+            gluTessVertex(tobj, quad1[i], quad1[i]);
+         gluTessEndContour(tobj);
+         gluTessBeginContour(tobj);
+         for (i = 0; i < 4; i++)
+            gluTessVertex(tobj, quad2[i], quad2[i]);
+         gluTessEndContour(tobj);
+         gluTessBeginContour(tobj);
+         for (i = 0; i < 3; i++)
+            gluTessVertex(tobj, tri[i], tri[i]);
+         gluTessEndContour(tobj);
+      gluTessEndPolygon(tobj);
+   glEndList();
+}
+
+void display (void) {
+   glClear(GL_COLOR_BUFFER_BIT);
+   glColor3f(1.0, 1.0, 1.0);
+   glPushMatrix(); 
+   glCallList(list);
+   glTranslatef(0.0, 500.0, 0.0);
+   glCallList(list+1);
+   glTranslatef(500.0, -500.0, 0.0);
+   glCallList(list+2);
+   glTranslatef(0.0, 500.0, 0.0);
+   glCallList(list+3);
+   glPopMatrix(); 
+   glFlush();
+}
+
+void CALLBACK beginCallback(GLenum which)
+{
+   glBegin(which);
+}
+
+void CALLBACK errorCallback(GLenum errorCode)
+{
+   const GLubyte *estring;
+
+   estring = gluErrorString(errorCode);
+   fprintf(stderr, "Tessellation Error: %s\n", estring);
+   exit(0);
+}
+
+void CALLBACK endCallback(void)
+{
+   glEnd();
+}
+
+/*  combineCallback is used to create a new vertex when edges
+ *  intersect.  coordinate location is trivial to calculate,
+ *  but weight[4] may be used to average color, normal, or texture 
+ *  coordinate data.
+ */
+/* ARGSUSED */
+void CALLBACK combineCallback(GLdouble coords[3], GLdouble *data[4],
+                     GLfloat weight[4], GLdouble **dataOut )
+{
+   GLdouble *vertex;
+   vertex = (GLdouble *) malloc(3 * sizeof(GLdouble));
+
+   vertex[0] = coords[0];
+   vertex[1] = coords[1];
+   vertex[2] = coords[2];
+   *dataOut = vertex;
+}
+
+void init(void) 
+{
+   glClearColor(0.0, 0.0, 0.0, 0.0);
+   glShadeModel(GL_FLAT);    
+
+   tobj = gluNewTess();
+   gluTessCallback(tobj, GLU_TESS_VERTEX, 
+                   (GLvoid (CALLBACK*) ()) &glVertex3dv);
+   gluTessCallback(tobj, GLU_TESS_BEGIN, 
+                   (GLvoid (CALLBACK*) ()) &beginCallback);
+   gluTessCallback(tobj, GLU_TESS_END, 
+                   (GLvoid (CALLBACK*) ()) &endCallback);
+   gluTessCallback(tobj, GLU_TESS_ERROR, 
+                   (GLvoid (CALLBACK*) ()) &errorCallback);
+   gluTessCallback(tobj, GLU_TESS_COMBINE, 
+                   (GLvoid (CALLBACK*) ()) &combineCallback);
+
+   list = glGenLists(4);
+   makeNewLists();
+}
+
+void reshape(int w, int h)
+{
+   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   if (w <= h)
+      gluOrtho2D(0.0, 1000.0, 0.0, 1000.0 * (GLdouble)h/(GLdouble)w);
+   else
+      gluOrtho2D(0.0, 1000.0 * (GLdouble)w/(GLdouble)h, 0.0, 1000.0);
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+}
+
+/* ARGSUSED1 */
+void keyboard(unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 'w':
+      case 'W':
+         if (currentWinding == GLU_TESS_WINDING_ODD)
+            currentWinding = GLU_TESS_WINDING_NONZERO;
+         else if (currentWinding == GLU_TESS_WINDING_NONZERO)
+            currentWinding = GLU_TESS_WINDING_POSITIVE;
+         else if (currentWinding == GLU_TESS_WINDING_POSITIVE)
+            currentWinding = GLU_TESS_WINDING_NEGATIVE;
+         else if (currentWinding == GLU_TESS_WINDING_NEGATIVE)
+            currentWinding = GLU_TESS_WINDING_ABS_GEQ_TWO;
+         else if (currentWinding == GLU_TESS_WINDING_ABS_GEQ_TWO)
+            currentWinding = GLU_TESS_WINDING_ODD;
+         makeNewLists();
+         glutPostRedisplay();
+         break;
+      case 27:
+         exit(0);
+         break;
+      default:
+         break;
+   }
+}
+
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
+   glutInitWindowSize(500, 500);
+   glutCreateWindow(argv[0]);
+   init();
+   glutDisplayFunc(display);
+   glutReshapeFunc(reshape);
+   glutKeyboardFunc(keyboard);
+   glutMainLoop();
+   return 0;  
+}
+
+#else
+int main(int argc, char** argv)
+{
+    fprintf (stderr, "This program demonstrates the new tesselator API in GLU 1.2.\n");
+    fprintf (stderr, "Your GLU library does not support this new interface, sorry.\n");
+    return 0;
+}
+#endif
diff --git a/progs/redbook/texbind.c b/progs/redbook/texbind.c
new file mode 100644 (file)
index 0000000..92c226f
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 1993-1997, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*  texbind.c
+ *  This program demonstrates using glBindTexture() by 
+ *  creating and managing two textures.
+ */
+#include <GL/glut.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef GL_VERSION_1_1
+/*     Create checkerboard texture     */
+#define        checkImageWidth 64
+#define        checkImageHeight 64
+static GLubyte checkImage[checkImageHeight][checkImageWidth][4];
+static GLubyte otherImage[checkImageHeight][checkImageWidth][4];
+
+static GLuint texName[2];
+
+void makeCheckImages(void)
+{
+   int i, j, c;
+    
+   for (i = 0; i < checkImageHeight; i++) {
+      for (j = 0; j < checkImageWidth; j++) {
+         c = ((((i&0x8)==0)^((j&0x8))==0))*255;
+         checkImage[i][j][0] = (GLubyte) c;
+         checkImage[i][j][1] = (GLubyte) c;
+         checkImage[i][j][2] = (GLubyte) c;
+         checkImage[i][j][3] = (GLubyte) 255;
+         c = ((((i&0x10)==0)^((j&0x10))==0))*255;
+         otherImage[i][j][0] = (GLubyte) c;
+         otherImage[i][j][1] = (GLubyte) 0;
+         otherImage[i][j][2] = (GLubyte) 0;
+         otherImage[i][j][3] = (GLubyte) 255;
+      }
+   }
+}
+
+void init(void)
+{    
+   glClearColor (0.0, 0.0, 0.0, 0.0);
+   glShadeModel(GL_FLAT);
+   glEnable(GL_DEPTH_TEST);
+
+   makeCheckImages();
+   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+   glGenTextures(2, texName);
+   glBindTexture(GL_TEXTURE_2D, texName[0]);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, 
+                   GL_NEAREST);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 
+                   GL_NEAREST);
+   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, checkImageWidth,
+                checkImageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+                checkImage);
+
+   glBindTexture(GL_TEXTURE_2D, texName[1]);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
+   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, checkImageWidth, 
+                checkImageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 
+                otherImage);
+   glEnable(GL_TEXTURE_2D);
+}
+
+void display(void)
+{
+   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+   glBindTexture(GL_TEXTURE_2D, texName[0]);
+   glBegin(GL_QUADS);
+   glTexCoord2f(0.0, 0.0); glVertex3f(-2.0, -1.0, 0.0);
+   glTexCoord2f(0.0, 1.0); glVertex3f(-2.0, 1.0, 0.0);
+   glTexCoord2f(1.0, 1.0); glVertex3f(0.0, 1.0, 0.0);
+   glTexCoord2f(1.0, 0.0); glVertex3f(0.0, -1.0, 0.0);
+   glEnd();
+   glBindTexture(GL_TEXTURE_2D, texName[1]);
+   glBegin(GL_QUADS);
+   glTexCoord2f(0.0, 0.0); glVertex3f(1.0, -1.0, 0.0);
+   glTexCoord2f(0.0, 1.0); glVertex3f(1.0, 1.0, 0.0);
+   glTexCoord2f(1.0, 1.0); glVertex3f(2.41421, 1.0, -1.41421);
+   glTexCoord2f(1.0, 0.0); glVertex3f(2.41421, -1.0, -1.41421);
+   glEnd();
+   glFlush();
+}
+
+void reshape(int w, int h)
+{
+   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 30.0);
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+   glTranslatef(0.0, 0.0, -3.6);
+}
+
+/* ARGSUSED1 */
+void keyboard(unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 27:
+         exit(0);
+         break;
+   }
+}
+
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
+   glutInitWindowSize(250, 250);
+   glutInitWindowPosition(100, 100);
+   glutCreateWindow(argv[0]);
+   init();
+   glutReshapeFunc(reshape);
+   glutDisplayFunc(display);
+   glutKeyboardFunc (keyboard);
+   glutMainLoop();
+   return 0; 
+}
+#else
+int main(int argc, char** argv)
+{
+    fprintf (stderr, "This program demonstrates a feature which is not in OpenGL Version 1.0.\n");
+    fprintf (stderr, "If your implementation of OpenGL Version 1.0 has the right extensions,\n");
+    fprintf (stderr, "you may be able to modify this program to make it run.\n");
+    return 0;
+}
+#endif
+
diff --git a/progs/redbook/texgen.c b/progs/redbook/texgen.c
new file mode 100644 (file)
index 0000000..7c1802a
--- /dev/null
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 1993-1997, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*  texgen.c
+ *  This program draws a texture mapped teapot with 
+ *  automatically generated texture coordinates.  The
+ *  texture is rendered as stripes on the teapot.
+ *  Initially, the object is drawn with texture coordinates
+ *  based upon the object coordinates of the vertex
+ *  and distance from the plane x = 0.  Pressing the 'e'
+ *  key changes the coordinate generation to eye coordinates
+ *  of the vertex.  Pressing the 'o' key switches it back
+ *  to the object coordinates.  Pressing the 's' key 
+ *  changes the plane to a slanted one (x + y + z = 0).
+ *  Pressing the 'x' key switches it back to x = 0.
+ */
+
+#include <GL/glut.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#define        stripeImageWidth 32
+GLubyte stripeImage[4*stripeImageWidth];
+
+#ifdef GL_VERSION_1_1
+static GLuint texName;
+#endif
+
+void makeStripeImage(void)
+{
+   int j;
+    
+   for (j = 0; j < stripeImageWidth; j++) {
+      stripeImage[4*j] = (GLubyte) ((j<=4) ? 255 : 0);
+      stripeImage[4*j+1] = (GLubyte) ((j>4) ? 255 : 0);
+      stripeImage[4*j+2] = (GLubyte) 0;
+      stripeImage[4*j+3] = (GLubyte) 255;
+   }
+}
+
+/*  planes for texture coordinate generation  */
+static GLfloat xequalzero[] = {1.0, 0.0, 0.0, 0.0};
+static GLfloat slanted[] = {1.0, 1.0, 1.0, 0.0};
+static GLfloat *currentCoeff;
+static GLenum currentPlane;
+static GLint currentGenMode;
+
+void init(void)
+{
+   glClearColor (0.0, 0.0, 0.0, 0.0);
+   glEnable(GL_DEPTH_TEST);
+   glShadeModel(GL_SMOOTH);
+
+   makeStripeImage();
+   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+#ifdef GL_VERSION_1_1
+   glGenTextures(1, &texName);
+   glBindTexture(GL_TEXTURE_1D, texName);
+#endif
+   glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+   glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+   glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+#ifdef GL_VERSION_1_1
+   glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, stripeImageWidth, 0,
+                GL_RGBA, GL_UNSIGNED_BYTE, stripeImage);
+#else
+   glTexImage1D(GL_TEXTURE_1D, 0, 4, stripeImageWidth, 0,
+                GL_RGBA, GL_UNSIGNED_BYTE, stripeImage);
+#endif
+
+   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+   currentCoeff = xequalzero;
+   currentGenMode = GL_OBJECT_LINEAR;
+   currentPlane = GL_OBJECT_PLANE;
+   glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, currentGenMode);
+   glTexGenfv(GL_S, currentPlane, currentCoeff);
+
+   glEnable(GL_TEXTURE_GEN_S);
+   glEnable(GL_TEXTURE_1D);
+   glEnable(GL_CULL_FACE);
+   glEnable(GL_LIGHTING);
+   glEnable(GL_LIGHT0);
+   glEnable(GL_AUTO_NORMAL);
+   glEnable(GL_NORMALIZE);
+   glFrontFace(GL_CW);
+   glCullFace(GL_BACK);
+   glMaterialf (GL_FRONT, GL_SHININESS, 64.0);
+}
+
+void display(void)
+{
+   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+   glPushMatrix ();
+   glRotatef(45.0, 0.0, 0.0, 1.0);
+#ifdef GL_VERSION_1_1
+   glBindTexture(GL_TEXTURE_1D, texName);
+#endif
+   glutSolidTeapot(2.0);
+   glPopMatrix ();
+   glFlush();
+}
+
+void reshape(int w, int h)
+{
+   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   if (w <= h)
+      glOrtho (-3.5, 3.5, -3.5*(GLfloat)h/(GLfloat)w, 
+               3.5*(GLfloat)h/(GLfloat)w, -3.5, 3.5);
+   else
+      glOrtho (-3.5*(GLfloat)w/(GLfloat)h, 
+               3.5*(GLfloat)w/(GLfloat)h, -3.5, 3.5, -3.5, 3.5);
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+}
+
+/* ARGSUSED1 */
+void keyboard (unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 'e':
+      case 'E':
+         currentGenMode = GL_EYE_LINEAR;
+         currentPlane = GL_EYE_PLANE;
+         glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, currentGenMode);
+         glTexGenfv(GL_S, currentPlane, currentCoeff);
+         glutPostRedisplay();
+         break;
+      case 'o':
+      case 'O':
+         currentGenMode = GL_OBJECT_LINEAR;
+         currentPlane = GL_OBJECT_PLANE;
+         glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, currentGenMode);
+         glTexGenfv(GL_S, currentPlane, currentCoeff);
+         glutPostRedisplay();
+         break;
+      case 's':
+      case 'S':
+         currentCoeff = slanted;
+         glTexGenfv(GL_S, currentPlane, currentCoeff);
+         glutPostRedisplay();
+         break;
+      case 'x':
+      case 'X':
+         currentCoeff = xequalzero;
+         glTexGenfv(GL_S, currentPlane, currentCoeff);
+         glutPostRedisplay();
+         break;
+      case 27:
+         exit(0);
+         break;
+      default:
+         break;
+   }
+}
+
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
+   glutInitWindowSize(256, 256);
+   glutInitWindowPosition(100, 100);
+   glutCreateWindow (argv[0]);
+   init ();
+   glutDisplayFunc(display);
+   glutReshapeFunc(reshape);
+   glutKeyboardFunc(keyboard);
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/redbook/texprox.c b/progs/redbook/texprox.c
new file mode 100644 (file)
index 0000000..6f1e853
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 1993-1997, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*
+ *  texprox.c
+ *  The brief program illustrates use of texture proxies.
+ *  This program only prints out some messages about whether
+ *  certain size textures are supported and then exits.
+ */
+#include <GL/glut.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef GL_VERSION_1_1
+
+/* Microsoft OpenGL 1.1's <GL/gl.h> forgets to define
+   GL_TEXTURE_INTERNAL_FORMAT. */
+#ifndef GL_TEXTURE_INTERNAL_FORMAT
+#define GL_TEXTURE_INTERNAL_FORMAT GL_TEXTURE_COMPONENTS
+#endif
+
+void init(void) 
+{
+   GLint proxyComponents;
+
+   putchar('\n');
+
+   glTexImage2D(GL_PROXY_TEXTURE_2D, 0, GL_RGBA8,
+                64, 64, 0,
+                GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+   glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, 
+                            GL_TEXTURE_INTERNAL_FORMAT, &proxyComponents);
+   printf ("Proxying 64x64 level 0 RGBA8 texture (level 0)\n");
+   if (proxyComponents == GL_RGBA8)
+      printf ("proxy allocation succeeded\n");
+   else
+      printf ("proxy allocation failed\n");
+   putchar('\n');
+
+   glTexImage2D(GL_PROXY_TEXTURE_2D, 0, GL_RGBA16,
+                2048, 2048, 0,
+                GL_RGBA, GL_UNSIGNED_SHORT, NULL);
+   glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, 
+                            GL_TEXTURE_INTERNAL_FORMAT, &proxyComponents);
+   printf ("Proxying 2048x2048 level 0 RGBA16 texture (big so unlikely to be supported)\n");
+   if (proxyComponents == GL_RGBA16)
+      printf ("proxy allocation succeeded\n");
+   else
+      printf ("proxy allocation failed\n");
+   putchar('\n');
+}
+
+void display(void)
+{
+   exit(0);
+}
+
+void reshape (int w, int h)
+{
+   glViewport (0, 0, (GLsizei) w, (GLsizei) h); 
+   glMatrixMode (GL_PROJECTION);
+   glLoadIdentity ();
+}
+
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
+   glutInitWindowSize (500, 500); 
+   glutInitWindowPosition (100, 100);
+   glutCreateWindow (argv[0]);
+   init ();
+   glutDisplayFunc(display); 
+   glutReshapeFunc(reshape);
+   glutMainLoop();
+   return 0;
+}
+#else
+int main(int argc, char** argv)
+{
+    fprintf (stderr, "This program demonstrates a feature which is not in OpenGL Version 1.0.\n");
+    fprintf (stderr, "If your implementation of OpenGL Version 1.0 has the right extensions,\n");
+    fprintf (stderr, "you may be able to modify this program to make it run.\n");
+    return 0;
+}
+#endif
diff --git a/progs/redbook/texsub.c b/progs/redbook/texsub.c
new file mode 100644 (file)
index 0000000..5dc36ec
--- /dev/null
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 1993-1997, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*  texsub.c
+ *  This program texture maps a checkerboard image onto
+ *  two rectangles.  This program clamps the texture, if
+ *  the texture coordinates fall outside 0.0 and 1.0.
+ *  If the s key is pressed, a texture subimage is used to
+ *  alter the original texture.  If the r key is pressed, 
+ *  the original texture is restored.
+ */
+#include <GL/glut.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef GL_VERSION_1_1
+/*  Create checkerboard textures  */
+#define checkImageWidth 64
+#define checkImageHeight 64
+#define subImageWidth 16
+#define subImageHeight 16
+static GLubyte checkImage[checkImageHeight][checkImageWidth][4];
+static GLubyte subImage[subImageHeight][subImageWidth][4];
+
+static GLuint texName;
+
+void makeCheckImages(void)
+{
+   int i, j, c;
+    
+   for (i = 0; i < checkImageHeight; i++) {
+      for (j = 0; j < checkImageWidth; j++) {
+         c = ((((i&0x8)==0)^((j&0x8))==0))*255;
+         checkImage[i][j][0] = (GLubyte) c;
+         checkImage[i][j][1] = (GLubyte) c;
+         checkImage[i][j][2] = (GLubyte) c;
+         checkImage[i][j][3] = (GLubyte) 255;
+      }
+   }
+   for (i = 0; i < subImageHeight; i++) {
+      for (j = 0; j < subImageWidth; j++) {
+         c = ((((i&0x4)==0)^((j&0x4))==0))*255;
+         subImage[i][j][0] = (GLubyte) c;
+         subImage[i][j][1] = (GLubyte) 0;
+         subImage[i][j][2] = (GLubyte) 0;
+         subImage[i][j][3] = (GLubyte) 255;
+      }
+   }
+}
+
+void init(void)
+{    
+   glClearColor (0.0, 0.0, 0.0, 0.0);
+   glShadeModel(GL_FLAT);
+   glEnable(GL_DEPTH_TEST);
+
+   makeCheckImages();
+   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+   glGenTextures(1, &texName);
+   glBindTexture(GL_TEXTURE_2D, texName);
+
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, checkImageWidth, checkImageHeight, 
+                0, GL_RGBA, GL_UNSIGNED_BYTE, checkImage);
+}
+
+void display(void)
+{
+   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+   glEnable(GL_TEXTURE_2D);
+   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
+   glBindTexture(GL_TEXTURE_2D, texName);
+   glBegin(GL_QUADS);
+   glTexCoord2f(0.0, 0.0); glVertex3f(-2.0, -1.0, 0.0);
+   glTexCoord2f(0.0, 1.0); glVertex3f(-2.0, 1.0, 0.0);
+   glTexCoord2f(1.0, 1.0); glVertex3f(0.0, 1.0, 0.0);
+   glTexCoord2f(1.0, 0.0); glVertex3f(0.0, -1.0, 0.0);
+
+   glTexCoord2f(0.0, 0.0); glVertex3f(1.0, -1.0, 0.0);
+   glTexCoord2f(0.0, 1.0); glVertex3f(1.0, 1.0, 0.0);
+   glTexCoord2f(1.0, 1.0); glVertex3f(2.41421, 1.0, -1.41421);
+   glTexCoord2f(1.0, 0.0); glVertex3f(2.41421, -1.0, -1.41421);
+   glEnd();
+   glFlush();
+   glDisable(GL_TEXTURE_2D);
+}
+
+void reshape(int w, int h)
+{
+   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 30.0);
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+   glTranslatef(0.0, 0.0, -3.6);
+}
+
+/* ARGSUSED1 */
+void keyboard (unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 's':
+      case 'S':
+         glBindTexture(GL_TEXTURE_2D, texName);
+         glTexSubImage2D(GL_TEXTURE_2D, 0, 12, 44, subImageWidth,
+                         subImageHeight, GL_RGBA,
+                         GL_UNSIGNED_BYTE, subImage);
+         glutPostRedisplay();
+         break;
+      case 'r':
+      case 'R':
+         glBindTexture(GL_TEXTURE_2D, texName);
+         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, checkImageWidth,
+                      checkImageHeight, 0, GL_RGBA,
+                      GL_UNSIGNED_BYTE, checkImage);
+         glutPostRedisplay();
+         break;
+      case 27:
+         exit(0);
+         break;
+      default:
+         break;
+   }
+}
+
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
+   glutInitWindowSize(250, 250);
+   glutInitWindowPosition(100, 100);
+   glutCreateWindow(argv[0]);
+   init();
+   glutDisplayFunc(display);
+   glutReshapeFunc(reshape);
+   glutKeyboardFunc(keyboard);
+   glutMainLoop();
+   return 0; 
+}
+#else
+int main(int argc, char** argv)
+{
+    fprintf (stderr, "This program demonstrates a feature which is not in OpenGL Version 1.0.\n");
+    fprintf (stderr, "If your implementation of OpenGL Version 1.0 has the right extensions,\n");
+    fprintf (stderr, "you may be able to modify this program to make it run.\n");
+    return 0;
+}
+#endif
diff --git a/progs/redbook/texturesurf.c b/progs/redbook/texturesurf.c
new file mode 100644 (file)
index 0000000..89cdbcc
--- /dev/null
@@ -0,0 +1,141 @@
+
+/* Copyright (c) Mark J. Kilgard, 1994. */
+
+/*
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+ */
+/*  texturesurf.c
+ *  This program uses evaluators to generate a curved
+ *  surface and automatically generated texture coordinates.
+ */
+
+#include <stdlib.h>
+#include <GL/glut.h>
+#include <math.h>
+
+GLfloat ctrlpoints[4][4][3] = {
+    {{ -1.5, -1.5, 4.0}, { -0.5, -1.5, 2.0}, 
+       {0.5, -1.5, -1.0}, {1.5, -1.5, 2.0}}, 
+    {{ -1.5, -0.5, 1.0}, { -0.5, -0.5, 3.0}, 
+       {0.5, -0.5, 0.0}, {1.5, -0.5, -1.0}}, 
+    {{ -1.5, 0.5, 4.0}, { -0.5, 0.5, 0.0}, 
+       {0.5, 0.5, 3.0}, {1.5, 0.5, 4.0}}, 
+    {{ -1.5, 1.5, -2.0}, { -0.5, 1.5, -2.0}, 
+       {0.5, 1.5, 0.0}, {1.5, 1.5, -1.0}}
+};
+
+GLfloat texpts[2][2][2] = {{{0.0, 0.0}, {0.0, 1.0}}, 
+                       {{1.0, 0.0}, {1.0, 1.0}}};
+
+void display(void)
+{
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+    glColor3f(1.0, 1.0, 1.0);
+    glEvalMesh2(GL_FILL, 0, 20, 0, 20);
+    glFlush();
+}
+
+#define        imageWidth 64
+#define        imageHeight 64
+GLubyte image[3*imageWidth*imageHeight];
+
+void makeImage(void)
+{
+    int i, j;
+    float ti, tj;
+    
+    for (i = 0; i < imageWidth; i++) {
+       ti = 2.0*3.14159265*i/imageWidth;
+       for (j = 0; j < imageHeight; j++) {
+           tj = 2.0*3.14159265*j/imageHeight;
+
+           image[3*(imageHeight*i+j)] = (GLubyte) 127*(1.0+sin(ti));
+           image[3*(imageHeight*i+j)+1] = (GLubyte) 127*(1.0+cos(2*tj));
+           image[3*(imageHeight*i+j)+2] = (GLubyte) 127*(1.0+cos(ti+tj));
+       }
+    }
+}
+
+void myinit(void)
+{
+    glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4,
+           0, 1, 12, 4, &ctrlpoints[0][0][0]);
+    glMap2f(GL_MAP2_TEXTURE_COORD_2, 0, 1, 2, 2, 
+           0, 1, 4, 2, &texpts[0][0][0]);
+    glEnable(GL_MAP2_TEXTURE_COORD_2);
+    glEnable(GL_MAP2_VERTEX_3);
+    glMapGrid2f(20, 0.0, 1.0, 20, 0.0, 1.0);
+    makeImage();
+    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
+    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexImage2D(GL_TEXTURE_2D, 0, 3, imageWidth, imageHeight, 0,
+                GL_RGB, GL_UNSIGNED_BYTE, image);
+    glEnable(GL_TEXTURE_2D);
+    glEnable(GL_DEPTH_TEST);
+    glEnable(GL_NORMALIZE);
+    glShadeModel (GL_FLAT);
+}
+
+void myReshape(int w, int h)
+{
+    glViewport(0, 0, w, h);
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    if (w <= h)
+       glOrtho(-4.0, 4.0, -4.0*(GLfloat)h/(GLfloat)w, 
+           4.0*(GLfloat)h/(GLfloat)w, -4.0, 4.0);
+    else
+       glOrtho(-4.0*(GLfloat)w/(GLfloat)h, 
+           4.0*(GLfloat)w/(GLfloat)h, -4.0, 4.0, -4.0, 4.0);
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
+    glRotatef(85.0, 1.0, 1.0, 1.0);
+}
+
+int main(int argc, char** argv)
+{
+    glutInit(&argc, argv);
+    glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
+    glutCreateWindow (argv[0]);
+    myinit();
+    glutReshapeFunc (myReshape);
+    glutDisplayFunc(display);
+    glutMainLoop();
+    return 0;             /* ANSI C requires main to return int. */
+}
diff --git a/progs/redbook/torus.c b/progs/redbook/torus.c
new file mode 100644 (file)
index 0000000..7ae4d41
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 1993-1997, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*
+ *  torus.c
+ *  This program demonstrates the creation of a display list.
+ */
+
+#include <GL/glut.h>
+#include <stdio.h>
+#include <math.h>
+#include <stdlib.h>
+
+/* Some <math.h> files do not define M_PI... */
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+GLuint theTorus;
+
+/* Draw a torus */
+static void torus(int numc, int numt)
+{
+   int i, j, k;
+   double s, t, x, y, z, twopi;
+
+   twopi = 2 * (double)M_PI;
+   for (i = 0; i < numc; i++) {
+      glBegin(GL_QUAD_STRIP);
+      for (j = 0; j <= numt; j++) {
+         for (k = 1; k >= 0; k--) {
+            s = (i + k) % numc + 0.5;
+            t = j % numt;
+
+            x = (1+.1*cos(s*twopi/numc))*cos(t*twopi/numt);
+            y = (1+.1*cos(s*twopi/numc))*sin(t*twopi/numt);
+            z = .1 * sin(s * twopi / numc);
+            glVertex3f(x, y, z);
+         }
+      }
+      glEnd();
+   }
+}
+
+/* Create display list with Torus and initialize state */
+static void init(void)
+{
+   theTorus = glGenLists (1);
+   glNewList(theTorus, GL_COMPILE);
+   torus(8, 25);
+   glEndList();
+
+   glShadeModel(GL_FLAT);
+   glClearColor(0.0, 0.0, 0.0, 0.0);
+}
+
+/* Clear window and draw torus */
+void display(void)
+{
+   glClear(GL_COLOR_BUFFER_BIT);
+   glColor3f (1.0, 1.0, 1.0);
+   glCallList(theTorus);
+   glFlush();
+}
+
+/* Handle window resize */
+void reshape(int w, int h)
+{
+   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   gluPerspective(30, (GLfloat) w/(GLfloat) h, 1.0, 100.0);
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+   gluLookAt(0, 0, 10, 0, 0, 0, 0, 1, 0);
+}
+
+/* Rotate about x-axis when "x" typed; rotate about y-axis
+   when "y" typed; "i" returns torus to original view */
+/* ARGSUSED1 */
+void keyboard(unsigned char key, int x, int y)
+{
+   switch (key) {
+   case 'x':
+   case 'X':
+      glRotatef(30.,1.0,0.0,0.0);
+      glutPostRedisplay();
+      break;
+   case 'y':
+   case 'Y':
+      glRotatef(30.,0.0,1.0,0.0);
+      glutPostRedisplay();
+      break;
+   case 'i':
+   case 'I':
+      glLoadIdentity();
+      gluLookAt(0, 0, 10, 0, 0, 0, 0, 1, 0);
+      glutPostRedisplay();
+      break;
+   case 27:
+      exit(0);
+      break;
+   }
+}
+
+int main(int argc, char **argv)
+{
+   glutInitWindowSize(200, 200);
+   glutInit(&argc, argv);
+   glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
+   glutCreateWindow(argv[0]);
+   init();
+   glutReshapeFunc(reshape);
+   glutKeyboardFunc(keyboard);
+   glutDisplayFunc(display);
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/redbook/trim.c b/progs/redbook/trim.c
new file mode 100644 (file)
index 0000000..26f4748
--- /dev/null
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 1993-1997, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*
+ *  trim.c
+ *  This program draws a NURBS surface in the shape of a 
+ *  symmetrical hill, using both a NURBS curve and pwl
+ *  (piecewise linear) curve to trim part of the surface.
+ */
+#include <stdlib.h>
+#include <GL/glut.h>
+#include <stdio.h>
+
+
+#ifndef CALLBACK
+#define CALLBACK
+#endif
+
+
+GLfloat ctlpoints[4][4][3];
+
+GLUnurbsObj *theNurb;
+
+/*
+ *  Initializes the control points of the surface to a small hill.
+ *  The control points range from -3 to +3 in x, y, and z
+ */
+void init_surface(void)
+{
+   int u, v;
+   for (u = 0; u < 4; u++) {
+      for (v = 0; v < 4; v++) {
+         ctlpoints[u][v][0] = 2.0*((GLfloat)u - 1.5);
+         ctlpoints[u][v][1] = 2.0*((GLfloat)v - 1.5);
+
+         if ( (u == 1 || u == 2) && (v == 1 || v == 2))
+            ctlpoints[u][v][2] = 3.0;
+         else
+            ctlpoints[u][v][2] = -3.0;
+      }
+   }
+}
+
+void nurbsError(GLenum errorCode)
+{
+   const GLubyte *estring;
+
+   estring = gluErrorString(errorCode);
+   fprintf (stderr, "Nurbs Error: %s\n", estring);
+   exit (0);
+}
+                       
+/*  Initialize material property and depth buffer.
+ */
+void init(void)
+{
+   GLfloat mat_diffuse[] = { 0.7, 0.7, 0.7, 1.0 };
+   GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
+   GLfloat mat_shininess[] = { 100.0 };
+
+   glClearColor (0.0, 0.0, 0.0, 0.0);
+   glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
+   glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
+   glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
+
+   glEnable(GL_LIGHTING);
+   glEnable(GL_LIGHT0);
+   glEnable(GL_DEPTH_TEST);
+   glEnable(GL_AUTO_NORMAL);
+   glEnable(GL_NORMALIZE);
+
+   init_surface();
+
+   theNurb = gluNewNurbsRenderer();
+   gluNurbsProperty(theNurb, GLU_SAMPLING_TOLERANCE, 25.0);
+   gluNurbsProperty(theNurb, GLU_DISPLAY_MODE, GLU_FILL);
+   gluNurbsCallback(theNurb, GLU_ERROR, 
+                    (GLvoid (CALLBACK*) ()) nurbsError);
+}
+
+void display(void)
+{
+   GLfloat knots[8] = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0};
+   GLfloat edgePt[5][2] = /* counter clockwise */
+      {{0.0, 0.0}, {1.0, 0.0}, {1.0, 1.0}, {0.0, 1.0}, {0.0, 0.0}};
+   GLfloat curvePt[4][2] = /* clockwise */ 
+      {{0.25, 0.5}, {0.25, 0.75}, {0.75, 0.75}, {0.75, 0.5}};
+   GLfloat curveKnots[8] = 
+      {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0};
+   GLfloat pwlPt[4][2] = /* clockwise */ 
+      {{0.75, 0.5}, {0.5, 0.25}, {0.25, 0.5}};
+
+   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+   glPushMatrix();
+   glRotatef(330.0, 1.,0.,0.);
+   glScalef (0.5, 0.5, 0.5);
+
+   gluBeginSurface(theNurb);
+   gluNurbsSurface(theNurb, 8, knots, 8, knots,
+                   4 * 3, 3, &ctlpoints[0][0][0], 
+                   4, 4, GL_MAP2_VERTEX_3);
+   gluBeginTrim (theNurb);
+      gluPwlCurve (theNurb, 5, &edgePt[0][0], 2, GLU_MAP1_TRIM_2);
+   gluEndTrim (theNurb);
+   gluBeginTrim (theNurb);
+      gluNurbsCurve (theNurb, 8, curveKnots, 2, 
+                     &curvePt[0][0], 4, GLU_MAP1_TRIM_2);
+      gluPwlCurve (theNurb, 3, &pwlPt[0][0], 2, GLU_MAP1_TRIM_2);
+   gluEndTrim (theNurb);
+   gluEndSurface(theNurb);
+        
+   glPopMatrix();
+   glFlush();
+}
+
+void reshape(int w, int h)
+{
+   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   gluPerspective (45.0, (GLdouble)w/(GLdouble)h, 3.0, 8.0);
+
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+   glTranslatef (0.0, 0.0, -5.0);
+}
+
+/* ARGSUSED1 */
+void keyboard(unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 27:
+         exit(0);
+         break;
+   }
+}
+
+/*  Main Loop 
+ */
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
+   glutInitWindowSize (500, 500);
+   glutInitWindowPosition (100, 100);
+   glutCreateWindow(argv[0]);
+   init();
+   glutReshapeFunc(reshape);
+   glutDisplayFunc(display);
+   glutKeyboardFunc (keyboard);
+   glutMainLoop();
+   return 0; 
+}
diff --git a/progs/redbook/unproject.c b/progs/redbook/unproject.c
new file mode 100644 (file)
index 0000000..134c361
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 1993-1997, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*
+ *  unproject.c
+ *  When the left mouse button is pressed, this program 
+ *  reads the mouse position and determines two 3D points 
+ *  from which it was transformed.  Very little is displayed.
+ */
+#include <GL/glut.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+void display(void)
+{
+   glClear(GL_COLOR_BUFFER_BIT);
+   glFlush();
+}
+
+/* Change these values for a different transformation  */
+void reshape(int w, int h)
+{
+   glViewport (0, 0, (GLsizei) w, (GLsizei) h);
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   gluPerspective (45.0, (GLfloat) w/(GLfloat) h, 1.0, 100.0);
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+}
+
+void mouse(int button, int state, int x, int y) 
+{
+   GLint viewport[4];
+   GLdouble mvmatrix[16], projmatrix[16];
+   GLint realy;  /*  OpenGL y coordinate position  */
+   GLdouble wx, wy, wz;  /*  returned world x, y, z coords  */
+
+   switch (button) {
+      case GLUT_LEFT_BUTTON:
+         if (state == GLUT_DOWN) {
+            glGetIntegerv (GL_VIEWPORT, viewport);
+            glGetDoublev (GL_MODELVIEW_MATRIX, mvmatrix);
+            glGetDoublev (GL_PROJECTION_MATRIX, projmatrix);
+/*  note viewport[3] is height of window in pixels  */
+            realy = viewport[3] - (GLint) y - 1;
+            printf ("Coordinates at cursor are (%4d, %4d)\n", x, realy);
+            gluUnProject ((GLdouble) x, (GLdouble) realy, 0.0, 
+               mvmatrix, projmatrix, viewport, &wx, &wy, &wz); 
+            printf ("World coords at z=0.0 are (%f, %f, %f)\n", 
+               wx, wy, wz);
+            gluUnProject ((GLdouble) x, (GLdouble) realy, 1.0, 
+               mvmatrix, projmatrix, viewport, &wx, &wy, &wz); 
+            printf ("World coords at z=1.0 are (%f, %f, %f)\n", 
+               wx, wy, wz);
+         }
+         break;
+      case GLUT_RIGHT_BUTTON:
+         if (state == GLUT_DOWN)
+            exit(0);
+         break;
+      default:
+         break;
+   }
+}
+
+/* ARGSUSED1 */
+void keyboard(unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 27:
+         exit(0);
+         break;
+   }
+}
+   
+/* 
+ *  Open window, register input callback functions
+ */
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
+   glutInitWindowSize (500, 500); 
+   glutInitWindowPosition (100, 100);
+   glutCreateWindow (argv[0]);
+   glutDisplayFunc(display); 
+   glutReshapeFunc(reshape); 
+   glutKeyboardFunc (keyboard);
+   glutMouseFunc(mouse);
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/redbook/varray.c b/progs/redbook/varray.c
new file mode 100644 (file)
index 0000000..b22e723
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 1993-1997, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*
+ *  varray.c
+ *  This program demonstrates vertex arrays.
+ */
+#include <GL/glut.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef GL_VERSION_1_1
+#define POINTER 1
+#define INTERLEAVED 2
+
+#define DRAWARRAY 1
+#define ARRAYELEMENT  2
+#define DRAWELEMENTS 3
+
+int setupMethod = POINTER;
+int derefMethod = DRAWARRAY;
+
+void setupPointers(void)
+{
+   static GLint vertices[] = {25, 25,
+                       100, 325,
+                       175, 25,
+                       175, 325,
+                       250, 25,
+                       325, 325};
+   static GLfloat colors[] = {1.0, 0.2, 0.2,
+                       0.2, 0.2, 1.0,
+                       0.8, 1.0, 0.2,
+                       0.75, 0.75, 0.75,
+                       0.35, 0.35, 0.35,
+                       0.5, 0.5, 0.5};
+
+   glEnableClientState (GL_VERTEX_ARRAY);
+   glEnableClientState (GL_COLOR_ARRAY);
+
+   glVertexPointer (2, GL_INT, 0, vertices);
+   glColorPointer (3, GL_FLOAT, 0, colors);
+}
+
+void setupInterleave(void)
+{
+   static GLfloat intertwined[] =
+      {1.0, 0.2, 1.0, 100.0, 100.0, 0.0,
+       1.0, 0.2, 0.2, 0.0, 200.0, 0.0,
+       1.0, 1.0, 0.2, 100.0, 300.0, 0.0,
+       0.2, 1.0, 0.2, 200.0, 300.0, 0.0,
+       0.2, 1.0, 1.0, 300.0, 200.0, 0.0,
+       0.2, 0.2, 1.0, 200.0, 100.0, 0.0};
+   
+   glInterleavedArrays (GL_C3F_V3F, 0, intertwined);
+}
+
+void init(void) 
+{
+   glClearColor (0.0, 0.0, 0.0, 0.0);
+   glShadeModel (GL_SMOOTH);
+   setupPointers ();
+}
+
+void display(void)
+{
+   glClear (GL_COLOR_BUFFER_BIT);
+
+   if (derefMethod == DRAWARRAY) 
+      glDrawArrays (GL_TRIANGLES, 0, 6);
+   else if (derefMethod == ARRAYELEMENT) {
+      glBegin (GL_TRIANGLES);
+      glArrayElement (2);
+      glArrayElement (3);
+      glArrayElement (5);
+      glEnd ();
+   }
+   else if (derefMethod == DRAWELEMENTS) {
+      GLuint indices[4] = {0, 1, 3, 4};
+
+      glDrawElements (GL_POLYGON, 4, GL_UNSIGNED_INT, indices);
+   }
+   glFlush ();
+}
+
+void reshape (int w, int h)
+{
+   glViewport (0, 0, (GLsizei) w, (GLsizei) h);
+   glMatrixMode (GL_PROJECTION);
+   glLoadIdentity ();
+   gluOrtho2D (0.0, (GLdouble) w, 0.0, (GLdouble) h);
+}
+
+/* ARGSUSED2 */
+void mouse (int button, int state, int x, int y)
+{
+   switch (button) {
+      case GLUT_LEFT_BUTTON:
+         if (state == GLUT_DOWN) {
+            if (setupMethod == POINTER) {
+               setupMethod = INTERLEAVED;
+               setupInterleave();
+            }
+            else if (setupMethod == INTERLEAVED) {
+               setupMethod = POINTER;
+               setupPointers();
+            }
+            glutPostRedisplay();
+         }
+         break;
+      case GLUT_MIDDLE_BUTTON:
+      case GLUT_RIGHT_BUTTON:
+         if (state == GLUT_DOWN) {
+            if (derefMethod == DRAWARRAY) 
+               derefMethod = ARRAYELEMENT;
+            else if (derefMethod == ARRAYELEMENT) 
+               derefMethod = DRAWELEMENTS;
+            else if (derefMethod == DRAWELEMENTS) 
+               derefMethod = DRAWARRAY;
+            glutPostRedisplay();
+         }
+         break;
+      default:
+         break;
+   }
+}
+
+/* ARGSUSED1 */
+void keyboard(unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 27:
+         exit(0);
+         break;
+   }
+}
+
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
+   glutInitWindowSize (350, 350); 
+   glutInitWindowPosition (100, 100);
+   glutCreateWindow (argv[0]);
+   init ();
+   glutDisplayFunc(display); 
+   glutReshapeFunc(reshape);
+   glutMouseFunc(mouse);
+   glutKeyboardFunc (keyboard);
+   glutMainLoop();
+   return 0;
+}
+#else
+int main(int argc, char** argv)
+{
+    fprintf (stderr, "This program demonstrates a feature which is not in OpenGL Version 1.0.\n");
+    fprintf (stderr, "If your implementation of OpenGL Version 1.0 has the right extensions,\n");
+    fprintf (stderr, "you may be able to modify this program to make it run.\n");
+    return 0;
+}
+#endif
diff --git a/progs/redbook/wrap.c b/progs/redbook/wrap.c
new file mode 100644 (file)
index 0000000..c67e04a
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 1993-1997, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
+ */
+
+/*  wrap.c
+ *  This program texture maps a checkerboard image onto
+ *  two rectangles.  This program demonstrates the wrapping
+ *  modes, if the texture coordinates fall outside 0.0 and 1.0.
+ *  Interaction: Pressing the 's' and 'S' keys switch the
+ *  wrapping between clamping and repeating for the s parameter.
+ *  The 't' and 'T' keys control the wrapping for the t parameter.
+ *
+ *  If running this program on OpenGL 1.0, texture objects are
+ *  not used.
+ */
+#include <GL/glut.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+/*     Create checkerboard texture     */
+#define        checkImageWidth 64
+#define        checkImageHeight 64
+static GLubyte checkImage[checkImageHeight][checkImageWidth][4];
+
+#ifdef GL_VERSION_1_1
+static GLuint texName;
+#endif
+
+void makeCheckImage(void)
+{
+   int i, j, c;
+    
+   for (i = 0; i < checkImageHeight; i++) {
+      for (j = 0; j < checkImageWidth; j++) {
+         c = ((((i&0x8)==0)^((j&0x8))==0))*255;
+         checkImage[i][j][0] = (GLubyte) c;
+         checkImage[i][j][1] = (GLubyte) c;
+         checkImage[i][j][2] = (GLubyte) c;
+         checkImage[i][j][3] = (GLubyte) 255;
+      }
+   }
+}
+
+void init(void)
+{    
+   glClearColor (0.0, 0.0, 0.0, 0.0);
+   glShadeModel(GL_FLAT);
+   glEnable(GL_DEPTH_TEST);
+
+   makeCheckImage();
+   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+#ifdef GL_VERSION_1_1
+   glGenTextures(1, &texName);
+   glBindTexture(GL_TEXTURE_2D, texName);
+#endif
+
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+#ifdef GL_VERSION_1_1
+   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, checkImageWidth, checkImageHeight, 
+                0, GL_RGBA, GL_UNSIGNED_BYTE, checkImage);
+#else
+   glTexImage2D(GL_TEXTURE_2D, 0, 4, checkImageWidth, checkImageHeight, 
+                0, GL_RGBA, GL_UNSIGNED_BYTE, checkImage);
+#endif
+}
+
+void display(void)
+{
+   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+   glEnable(GL_TEXTURE_2D);
+   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
+#ifdef GL_VERSION_1_1
+   glBindTexture(GL_TEXTURE_2D, texName);
+#endif
+
+   glBegin(GL_QUADS);
+   glTexCoord2f(0.0, 0.0); glVertex3f(-2.0, -1.0, 0.0);
+   glTexCoord2f(0.0, 3.0); glVertex3f(-2.0, 1.0, 0.0);
+   glTexCoord2f(3.0, 3.0); glVertex3f(0.0, 1.0, 0.0);
+   glTexCoord2f(3.0, 0.0); glVertex3f(0.0, -1.0, 0.0);
+
+   glTexCoord2f(0.0, 0.0); glVertex3f(1.0, -1.0, 0.0);
+   glTexCoord2f(0.0, 3.0); glVertex3f(1.0, 1.0, 0.0);
+   glTexCoord2f(3.0, 3.0); glVertex3f(2.41421, 1.0, -1.41421);
+   glTexCoord2f(3.0, 0.0); glVertex3f(2.41421, -1.0, -1.41421);
+   glEnd();
+   glFlush();
+   glDisable(GL_TEXTURE_2D);
+}
+
+void reshape(int w, int h)
+{
+   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 30.0);
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+   glTranslatef(0.0, 0.0, -3.6);
+}
+
+/* ARGSUSED1 */
+void keyboard (unsigned char key, int x, int y)
+{
+   switch (key) {
+      case 's':
+         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+         glutPostRedisplay();
+         break;
+      case 'S':
+         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+         glutPostRedisplay();
+         break;
+      case 't':
+         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+         glutPostRedisplay();
+         break;
+      case 'T':
+         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+         glutPostRedisplay();
+         break;
+      case 27:
+         exit(0);
+         break;
+      default:
+         break;
+   }
+}
+
+int main(int argc, char** argv)
+{
+   glutInit(&argc, argv);
+   glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
+   glutInitWindowSize(250, 250);
+   glutInitWindowPosition(100, 100);
+   glutCreateWindow(argv[0]);
+   init();
+   glutDisplayFunc(display);
+   glutReshapeFunc(reshape);
+   glutKeyboardFunc(keyboard);
+   glutMainLoop();
+   return 0; 
+}
diff --git a/progs/samples/Imakefile b/progs/samples/Imakefile
new file mode 100644 (file)
index 0000000..4574932
--- /dev/null
@@ -0,0 +1,102 @@
+LOCAL_LIBRARIES = $(XLIB) $(TOP)\lib\glut.a $(TOP)\lib\Mesaglu.a $(TOP)\lib\MesaGL.a\r
+\r
+INCLUDES = -I$(TOP)\include\r
+\r
+SRCS = accum.c \\r
+      bitmap1.c \\r
+      bitmap2.c \\r
+      blendeq.c \\r
+      blendxor.c \\r
+      copy.c \\r
+      cursor.c \\r
+      depth.c \\r
+      eval.c \\r
+      fog.c \\r
+      font.c \\r
+      line.c \\r
+      logo.c \\r
+      nurb.c \\r
+      oglinfo.c \\r
+      olympic.c \\r
+      overlay.c \\r
+      point.c \\r
+      prim.c \\r
+      quad.c \\r
+      select.c \\r
+      shape.c \\r
+      speed.c \\r
+      sphere.c \\r
+      star.c \\r
+      stencil.c \\r
+      stretch.c \\r
+      texture.c \\r
+      tri.c \\r
+      wave.c\r
+\r
+PROGRAMS = ProgramTargetName(accum) \\r
+      ProgramTargetName(bitmap1) \\r
+      ProgramTargetName(bitmap2) \\r
+      ProgramTargetName(blendeq) \\r
+      ProgramTargetName(blendxor) \\r
+      ProgramTargetName(copy) \\r
+      ProgramTargetName(cursor) \\r
+      ProgramTargetName(depth) \\r
+      ProgramTargetName(eval) \\r
+      ProgramTargetName(fog) \\r
+      ProgramTargetName(font) \\r
+      ProgramTargetName(line) \\r
+      ProgramTargetName(logo) \\r
+      ProgramTargetName(nurb) \\r
+      ProgramTargetName(oglinfo) \\r
+      ProgramTargetName(olympic) \\r
+      ProgramTargetName(overlay) \\r
+      ProgramTargetName(point) \\r
+      ProgramTargetName(prim) \\r
+      ProgramTargetName(quad) \\r
+      ProgramTargetName(select) \\r
+      ProgramTargetName(shape) \\r
+      ProgramTargetName(speed) \\r
+      ProgramTargetName(sphere) \\r
+      ProgramTargetName(star) \\r
+      ProgramTargetName(stencil) \\r
+      ProgramTargetName(stretch) \\r
+      ProgramTargetName(texture) \\r
+      ProgramTargetName(tri) \\r
+      ProgramTargetName(wave)\r
+\r
+AllTarget($(PROGRAMS))\r
+\r
+NormalProgramTarget(accum,accum.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(bitmap1,bitmap1.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(bitmap2,bitmap2.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(blendeq,blendeq.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(blendxor,blendxor.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(copy,copy.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(cursor,cursor.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(depth,depth.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(eval,eval.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(fog,fog.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(font,font.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(line,line.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(logo,logo.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(nurb,nurb.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(oglinfo,oglinfo.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(olympic,olympic.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(overlay,overlay.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(point,point.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(prim,prim.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(quad,quad.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(select,select.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(shape,shape.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(speed,speed.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(sphere,sphere.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(star,star.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(stencil,stencil.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(stretch,stretch.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(texture,texture.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(tri,tri.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+NormalProgramTarget(wave,wave.o,NullParameter,$(LOCAL_LIBRARIES),NullParameter)\r
+\r
+DependTarget()\r
\r
+\1a\r
diff --git a/progs/samples/Makefile.BeOS-R4 b/progs/samples/Makefile.BeOS-R4
new file mode 100644 (file)
index 0000000..2e1e804
--- /dev/null
@@ -0,0 +1,64 @@
+# $Id: Makefile.BeOS-R4,v 1.1 1999/08/19 00:55:41 jtg Exp $
+
+# Mesa 3-D graphics library
+# Version:  3.1
+# Copyright (C) 1995-1999  Brian Paul
+#
+# This file is in the public domain.
+
+
+# Makefile for sample programs for BeOS R4
+
+
+
+
+##### MACROS #####
+
+INCDIR = ../include
+LIBDIR = ../lib
+
+GL_LIBS = -L$(LIBDIR) -L/boot/home/config/lib -Xlinker -rpath $(LIBDIR) -lbe -lglut -lMesaGLU -lMesaGL $(XLIBS)
+
+LIB_DEP = $(LIBDIR)/$(GL_LIB) $(LIBDIR)/$(GLU_LIB) $(LIBDIR)/$(GLUT_LIB)
+
+PROGS = accum bitmap1 bitmap2 blendeq blendxor copy cursor depth eval fog \
+       font line logo olympic overlay point prim select \
+       shape sphere star stencil stretch texture tri wave
+
+
+##### RULES #####
+
+.SUFFIXES:
+.SUFFIXES: .c
+
+.c: $(LIB_DEP)
+       $(CC) -I$(INCDIR) $(CFLAGS) $< $(GL_LIBS) -o $@
+
+
+
+##### TARGETS #####
+
+default:
+       @echo "Specify a target configuration"
+
+clean:
+       -rm *.o *~
+
+realclean:
+       -rm $(PROGS)
+       -rm *.o *~
+
+targets: $(PROGS)
+
+# execute all programs
+exec: $(PROGS)
+       @for prog in $(PROGS) ;                 \
+       do                                      \
+               echo -n "Running $$prog ..." ;  \
+               $$prog ;                        \
+               echo ;                          \
+       done
+
+
+include ../Make-config
+
diff --git a/progs/samples/Makefile.DJ b/progs/samples/Makefile.DJ
new file mode 100644 (file)
index 0000000..5c43b7d
--- /dev/null
@@ -0,0 +1,36 @@
+# $Id: Makefile.DJ,v 1.1 1999/08/19 00:55:41 jtg Exp $
+
+# Makefile for sample programs for MS-DOS with DJGPP
+
+##### MACROS #####
+
+INCDIR = ../include
+
+GL_LIBS =  ../lib/dosglut.a ../lib/dosglub.a ../lib/dosmesa.a
+
+LIB_DEP = $(GL_LIBS)
+
+PROGS = accum bitmap1 bitmap2 blendeq blendxor copy depth \
+       eval fog font line logo nurb olympic \
+       point prim quad select shape \
+       sphere star stencil stretch texture \
+       tri wave
+
+##### RULES #####
+
+.c: $(LIB_DEP)
+       gcc -I$(INCDIR) $(CFLAGS) $< $(LIB_DEP) -o $@
+
+
+##### TARGETS #####
+
+default: $(PROGS)
+
+clean:
+       del *. 
+
+realclean: clean
+       del *.exe
+
+
+
diff --git a/progs/samples/Makefile.X11 b/progs/samples/Makefile.X11
new file mode 100644 (file)
index 0000000..e2393e8
--- /dev/null
@@ -0,0 +1,61 @@
+# $Id: Makefile.X11,v 1.1 1999/08/19 00:55:41 jtg Exp $
+
+# Mesa 3-D graphics library
+# Version:  3.1
+# Copyright (C) 1995-1999  Brian Paul
+
+
+# Makefile for assorted SGI OpenGL demos
+
+
+
+##### MACROS #####
+
+INCDIR = ../include
+LIBDIR = ../lib
+
+GL_LIBS = -L$(LIBDIR) -lglut -lGLU -lGL -lm $(XLIBS)
+
+LIB_DEP = $(LIBDIR)/$(GL_LIB) $(LIBDIR)/$(GLU_LIB) $(LIBDIR)/$(GLUT_LIB)
+
+PROGS = accum bitmap1 bitmap2 blendeq blendxor copy cursor depth eval fog \
+       font line logo nurb oglinfo olympic overlay point prim quad select \
+       shape sphere star stencil stretch texture tri wave
+
+
+
+##### RULES #####
+
+.SUFFIXES:
+.SUFFIXES: .c
+
+.c: $(LIB_DEP)
+       $(CC) -I$(INCDIR) $(CFLAGS) $< $(GL_LIBS) -o $@
+
+
+
+##### TARGETS #####
+
+default:
+       @echo "Specify a target configuration"
+
+clean:
+       -rm *.o *~
+
+realclean:
+       -rm $(PROGS)
+       -rm *.o *~
+
+targets: $(PROGS)
+
+# execute all programs
+exec: $(PROGS)
+       @for prog in $(PROGS) ;                 \
+       do                                      \
+               echo -n "Running $$prog ..." ;  \
+               ./$$prog;                       \
+               echo ;                          \
+       done
+
+
+include ../Make-config
diff --git a/progs/samples/Makefile.dja b/progs/samples/Makefile.dja
new file mode 100644 (file)
index 0000000..f2d5382
--- /dev/null
@@ -0,0 +1,26 @@
+# $Id: Makefile.dja,v 1.1 1999/08/19 00:55:41 jtg Exp $
+
+# Makefile for sample programs for MS-DOS with DJGPP and ALLEGRO
+
+
+
+INCDIR  =   ../include
+LIBDIR  =   ../lib
+include ../common.dja
+
+ _PROGS = accum bitmap1 bitmap2 blendeq blendxor copy cursor depth    \
+          eval fog font line logo nurb oglinfo olympic overlay point  \
+          prim quad select shape sphere star stencil stretch texture  \
+          tri wave
+
+  PROGS = $(_PROGS:=.exe)
+
+
+default: $(PROGS)
+
+clean:
+       del *. 
+
+realclean: clean
+       del *.exe
+
diff --git a/progs/samples/README b/progs/samples/README
new file mode 100644 (file)
index 0000000..8531588
--- /dev/null
@@ -0,0 +1,520 @@
+/*
+ * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the name of
+ * Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
+ * ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+accum - Accumulation test.
+    - RGBA, SB/DB (SB default).
+    - cmd line options:
+       -sb     Single buffer mode.
+       -db     Double buffer mode.
+    - keys:
+       ESC     Quit
+       1       Use filled polygon mode.
+       2       Use outlined polygon mode.
+
+bitmap1 - Bitmap test.
+    - RGBA/CI (RGBA default), SB/DB (SB default).
+    - cmd line options:
+       -rgb    RGBA mode.
+       -ci     Color index mode.
+       -sb     Single buffer mode.
+       -db     Double buffer mode.
+    - keys:
+       ESC     Quit.
+
+bitmap2 - Bitmap test.
+    - RGBA/CI (RGBA default), SB/DB (SB default).
+    - cmd line options:
+       -rgb    RGBA mode.
+       -ci     Color index mode.
+       -sb     Single buffer mode.
+       -db     Double buffer mode.
+    - keys:
+       ESC     Quit.
+       1       Toggle display list mode.
+       2       Toggle color animation mode.
+
+copy - Pixel copy test.
+    - RGBA, SB/DB (SB default).
+    - cmd line options:
+       -sb             Single buffer mode.
+       -db             Double buffer mode.
+       -dr             Direct render mode.
+       -ir             Indirect render mode.
+       -f <file name>  RGB image file.
+    - keys:
+       ESC             Quit.
+       Z               Increase zoom factor.
+       z               Decrease zoom factor.
+    - mouse input:
+       Left            Copy location.
+
+cursor - Cursor test.
+    - RGBA/CI (RGBA default), SB/DB (SB default).
+    - cmd line options:
+       -rgb    RGBA mode.
+       -ci     Color index mode.
+       -sb     Single buffer mode.
+       -db     Double buffer mode.
+    - keys:
+       ESC     Quit.
+       SPACE   switch cursor color.
+
+depth - Z buffer test.
+    - RGBA/CI (RGBA default), SB/DB (SB default).
+    - cmd line options:
+       -rgb    RGBA mode.
+       -ci     Color index mode.
+       -sb     Single buffer mode.
+       -db     Double buffer mode.
+    - keys:
+       ESC     Quit.
+       1       Toggle anti-aliased mode.
+       2       Toggle stipple mode.
+
+eval - Evaluator test.
+    - RGBA, SB/DB (SB default).
+    - cmd line options:
+       -sb     Single buffer mode.
+       -db     Double buffer mode.
+    - keys:
+       ESC     Quit.
+       LEFT    Rotate.
+       RIGHT   Rotate.
+       UP      Rotate.
+       DOWN    Rotate.
+       1       Toggle dimensions.
+       2       Toggle dimensions.
+       e       Use eval mode.
+       m       Use mesh mode.
+       f       Toggle polygon mode.
+       p       Toggle point mode.
+       c       Toggle color mode.
+       t       Toggle texture mode.
+       l       Toggle lighting mode.
+
+fog - Fog test.
+    - RGBA/CI (RGBA default), SB/DB (SB default).
+    - cmd line options:
+       -rgb    RGBA mode.
+       -ci     Color index mode.
+       -sb     Single buffer mode.
+       -db     Double buffer mode.
+    - keys:
+       ESC     Quit.
+       LEFT    Rotate.
+       RIGHT   Rotate.
+       UP      Rotate.
+       DOWN    Rotate.
+       D       Increase fog density.
+       d       Decrease fog density.
+
+font - font test.
+    - RGBA/CI (RGBA default), SB/DB (SB default).
+    - cmd line options:
+       -rgb    RGBA mode.
+       -ci     Color index mode.
+       -sb     Single buffer mode.
+       -db     Double buffer mode.
+    - keys:
+       ESC     Quit.
+       Left    Shift left.
+       Right   Shift right.
+       Up      Shift up.
+       Down    Shift down.
+       n       Shift in.
+       m       Shift out.
+       q       Scale up x.
+       w       Scale down x.
+       a       Scale up y.
+       s       Scale down y.
+       z       Scale up z.
+       x       Scale down z.
+       e       Rotate clockwise x.
+       r       Rotate counter-clockwise x.
+       d       Rotate clockwise y.
+       f       Rotate counter-clockwise y.
+       c       Rotate clockwise z.
+       v       Rotate counter-clockwise z.
+
+line - Line test.
+    - RGBA/CI (RGBA default), SB/DB (SB default).
+    - cmd line options:
+       -rgb    RGBA mode.
+       -ci     Color index mode.
+       -sb     Single buffer mode.
+       -db     Double buffer mode.
+    - keys:
+       ESC     Quit.
+       W       Increase line width.
+       w       Decrease line width.
+       1       Toggle stipple mode.
+       2       Toggle anti-aliased mode.
+
+logo - Demo.
+    - RGBA/CI (RGBA default), SB/DB (SB default).
+    - cmd line options:
+       -rgb    RGBA mode.
+       -ci     Color index mode.
+       -sb     Single buffer mode.
+       -db     Double buffer mode.
+    - keys:
+       ESC     Quit.
+       LEFT    Rotate.
+       RIGHT   Rotate
+       UP      Move clipping plane.
+       DOWN    Move clipping plane.
+       Z       Translate.
+       z       Translate.
+       1       Use GL_POINT polygon mode.
+       2       Use GL_LINE polygon mode.
+       3       Use GL_FILL polygon mode.
+       p       Toggle polygon fill modes.
+       4       Use GL_NICEST for GL_POLYGON_SMOOTH_HINT.
+       5       Use anti-aliased polygon mode.
+       6       Use aliased polygon mode.
+       8       Toggle dither mode.
+       9       Toggle stipple polygon mode.
+       0       Toggle flat/smooth shading mode.
+       q       Disable cull mode.
+       w       Use front face cull mode.
+       e       Use back face cull mode.
+       r       Use clockwise front face mode.
+       t       Use counter-clockwise front face mode.
+       y       Use MSB first stipple pattern.
+       u       Use LSB first stipple pattern.
+       a       Use brick texture map.
+       s       Use checker texture map.
+       d       Disable texture map.
+       f       Use decal texture environment mode.
+       g       Use modulate texture environment mode.
+
+nurb - Nurb test.
+    - RGBA, SB/DB (SB default).
+    - cmd line options:
+       -sb     Single buffer mode.
+       -db     Double buffer mode.
+    - keys:
+       ESC     Quit.
+       LEFT    Rotate.
+       RIGHT   Rotate.
+       UP      Rotate.
+       DOWN    Rotate.
+
+olympic - Olymipic rings demo.
+    - RGBA/CI (RGBA default), SB/DB (SB default).
+    - cmd line options:
+       -rgb    RGBA mode.
+       -ci     Color index mode.
+       -sb     Single buffer mode.
+       -db     Double buffer mode.
+    - keys:
+       ESC     Quit.
+       SPACE   Restart demo.
+
+overlay - Overlay plane demo.
+    - RGBA, SB/DB (SB default).
+    - cmd line options:
+       -sb     Single buffer mode.
+       -db     Double buffer mode.
+    - keys:
+       ESC     Quit.
+       SPACE   Toggle star weird movement mode.
+       t       Toggle star turbo mode.
+
+point - Point test.
+    - RGBA/CI (RGBA default), SB/DB (SB default).
+    - cmd line options:
+       -rgb    RGBA mode.
+       -ci     Color index mode.
+       -sb     Single buffer mode.
+       -db     Double buffer mode.
+    - keys:
+       ESC     Quit.
+       LEFT    Translate.
+       RIGHT   Translate.
+       UP      Translate.
+       DOWN    Translate.
+       W       Increase point width.
+       w       Decrease point width.
+       1       Toggle anti-aliased mode.
+
+prim - Primitive test.
+    - RGBA/CI (RGBA default), SB/DB (SB default).
+    - cmd line options:
+       -rgb    RGBA mode.
+       -ci     Color index mode.
+       -sb     Single buffer mode.
+       -db     Double buffer mode.
+    - keys:
+       ESC     Quit.
+       1       Toggle flat/smooth shade mode.
+       2       Toggle outlined/filled polygon mode.
+       3       Toggle color mask mode.
+
+quad - Quadric test.
+    - RGBA/CI (RGBA default), SB/DB (SB default).
+    - cmd line options:
+       -rgb            RGBA mode.
+       -ci             Color index mode.
+       -sb             Single buffer mode.
+       -db             Double buffer mode.
+       -dr             Direct render mode.
+       -ir             Indirect render mode.
+       -f <file name>  texture file.
+    - keys:
+       ESC             Quit.
+       LEFT            Rotate.
+       RIGHT           Rotate.
+       UP              Rotate.
+       DOWN            Rotate.
+       X               Rotate.
+       x               Rotate.
+       1               Use GLU_FILL draw style.
+       2               Use GLU_POINT draw style.
+       3               Use GLU_LINE draw style.
+       4               Use GLU_SILHOUETTE draw style.
+       0               Toggle flat/smooth shade mode.
+       f               Cylce through quadrics.
+       d               Toggle orientation.
+       A               Increase number of stacks.
+       a               Decrease number of stacks.
+       S               Increase number of slices.
+       s               Decrease number of slices.
+       G               Increase radius1.
+       g               Decrease radius1.
+       J               Increase radius2.
+       j               Decrease radius2.
+       H               Increase height.
+       h               Decrease height.
+       K               Increase angle1.
+       k               Decrease angle1.
+       L               Increase angle2.
+       l               Decrease angle2.
+       z               Toggle texture mode.
+       q               Disable cull mode.
+       w               Use front face cull mode.
+       e               Use back face cull mode.
+       r               Use clockwise front face mode.
+       t               Use counter-clockwise front face mode.
+       y               Toggle dither mode.
+
+select - Selection test.
+    - RGBA, SB.
+    - cmd line options:
+    - keys:
+       ESC     Quit.
+       LEFT    Rotate.
+       RIGHT   Rotate.
+       Z       Increase zoom factor.
+       z       Decrease zoom factor.
+       d       Zoom at current mouse location.
+       f       Print feedback information.
+       l       Toggle outlined/filled polygon mode.
+    - mouse:
+       Left    Recolor selected triangle.
+       Center  Enlarge selected triangle.
+       Right   Delete selected triangle.
+
+shape - shape test.
+    - RGBA/CI (RGBA default), SB/DB (SB default).
+    - cmd line options:
+       -rgb    RGBA mode.
+       -ci     Color index mode.
+       -sb     Single buffer mode.
+       -db     Double buffer mode.
+    - keys:
+       ESC     Quit.
+       Left    Shift left.
+       Right   Shift right.
+       Up      Shift up.
+       Down    Shift down.
+       n       Shift in.
+       m       Shift out.
+       q       Scale up x.
+       w       Scale down x.
+       a       Scale up y.
+       s       Scale down y.
+       z       Scale up z.
+       x       Scale down z.
+       e       Rotate clockwise x.
+       r       Rotate counter-clockwise x.
+       d       Rotate clockwise y.
+       f       Rotate counter-clockwise y.
+       c       Rotate clockwise z.
+       v       Rotate counter-clockwise z.
+       SPACE   switch shapes.
+
+speed - Speed test.
+    - RGBA/CI (RGBA default), SB/DB (SB default).
+    - cmd line options:
+       -rgb    RGBA mode.
+       -ci     Color index mode.
+       -sb     Single buffer mode.
+       -db     Double buffer mode.
+    - keys:
+       ESC     Quit.
+       a       Toggle anti-aliased mode.
+       d       Toggle z buffering mode.
+       f       Toggle fog mode.
+       F       Toggle fog hint mode.
+       s       Toggle flat/smooth shading mode.
+       t       Toggle texturing mode.
+
+sphere - Spheremap test.
+    - RGBA, SB/DB (SB default).
+    - cmd line options:
+       -sb             Single buffer mode.
+       -db             Double buffer mode.
+       -dr             Direct render mode.
+       -ir             Indirect render mode.
+       -f <file name>  texture file.
+       -3              Use RGB components.
+       -4              Use RGBA components.
+    - keys:
+       ESC             Quit.
+        LEFT           Rotate about the y axis.
+        RIGHT          Rotate about the y axis.
+        UP             Rotate about the x axis.
+        DOWN           Rotate about the x axis.
+        a              Toggle auto rotate mode.
+        c              toggle between cylinder or cube object.
+        t              Use torus object.
+        d              Use decal texture mode.
+       m               Use modulate texture mode.
+        l              Toggle lighted mode.
+        f              Toggle fog mode.
+        0              Use nearest magification filter.
+        1              Use linear magification.
+        2              Use nearest minification filter.
+        3              Use linear minification filter. 
+        4              Use nearest-mipmap-nearest minification filter. 
+        5              Use nearest-mipmap-linear minification filter. 
+        6              Use linear-mipmap-nearest minification filter. 
+        7              Use linear-mipmap-linear minification filter. 
+
+star - Demo.
+    - RGBA, SB/DB (SB default).
+    - cmd line options:
+       -sb     Single buffer mode.
+       -db     Double buffer mode.
+    - keys:
+       ESC     Quit.
+       SPACE   Toggle weird movement mode.
+       t       Toggle turbo mode.
+
+stencil - Stencil test.
+    - RGBA, SB.
+    - cmd line options:
+
+stretch - Texture test.
+    - RGBA, SB.
+    - cmd line options:
+       -sb             Single buffer mode.
+       -db             Double buffer mode.
+       -dr             Direct render mode.
+       -ir             Indirect render mode.
+       -f <file name>  texture file.
+    - keys:
+       ESC             Quit.
+       SPACE           Start animation.
+    - mouse:
+       Left            Added stretch point.
+
+texture - Texture test.
+    - RGBA, SB/DB (SB default).
+    - cmd line options:
+       -sb             Single buffer mode.
+       -db             Double buffer mode.
+       -dr             Direct render mode.
+       -ir             Indirect render mode.
+       -f <file name>  texture file.
+    - keys:
+       ESC             Quit.
+       LEFT            Rotate.
+       RIGHT           Rotate.
+       UP              Rotate.
+       DOWN            Rotate.
+       T               Translate.
+       t               Translate.
+       s               Toggle sphere map mode.
+       0               Use nearest magification filter.
+       1               Use linear magification filter.
+       2               Use nearest minification filter.
+       3               Use linear minification filter.
+       4               Use nearest-mipmap-nearest minification filter.
+       5               Use nearest-mipmap-linear minification filter.
+       6               Use linear-mipmap-nearest minification filter.
+       7               Use linear-mipmap-linear minification filter.
+
+tri - Triangle test.
+    - RGBA/CI (RGBA default), SB/DB (SB default).
+    - cmd line options:
+       -rgb    RGBA mode.
+       -ci     Color index mode.
+       -sb     Single buffer mode.
+       -db     Double buffer mode.
+    - keys:
+       ESC     Quit.
+       LEFT    Translate.
+       RIGHT   Translate.
+       Z       Increase zoom factor.
+       z       Decrease zoom factor.
+       1       Use point polygon mode.
+       2       Use line polygon mode.
+       3       Use filled polygon mode.
+       4       Use point primitive.
+       5       Use line-loop primitive.
+       6       Use polygon primitive.
+       7       Toggle cull mode.
+       8       Use clockwise/counter-clockwise front face mode.
+       9       Toggle front/back face cull mode.
+       v       Toggle show verticies mode.
+       s       Toggle flat/smooth shade mode.
+       h       Toggle hide bottom triangle mode.
+       o       Toggle outline mode.
+       m       Toggle dither mode.
+       0       Toggle anti-aliased mode.
+
+wave - Demo.
+    - RGBA/CI (RGBA default), SB/DB (SB default).
+    - cmd line options:
+       -rgb            RGBA mode.
+       -ci             Color index mode.
+       -sb             Single buffer mode.
+       -db             Double buffer mode.
+       -dr             Direct render mode.
+       -ir             Indirect render mode.
+       -grid <x> <y>   Number of grids.
+       -size <number>  Size of grid.
+       -wave <number>  Height of wave (floating point number).
+       -frames <count> Number of frames.
+    - keys:
+       ESC             Quit.
+       c               Toggle contouring mode.
+       s               Toggle flat/smooth shade mode.
+       l               Toggle lighting mode.
+       d               Toggle depth checking mode.
+       SPACE           Toggle step/animation mode.
+       n               Single step in step mode.
+       a               Toggle spin mode.
diff --git a/progs/samples/accum.c b/progs/samples/accum.c
new file mode 100644 (file)
index 0000000..24dfc07
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the name of
+ * Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
+ * ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <GL/glut.h>
+
+
+GLenum doubleBuffer;
+GLint thing1, thing2;
+
+
+static void Init(void)
+{
+
+    glClearColor(0.0, 0.0, 0.0, 0.0);
+    glClearAccum(0.0, 0.0, 0.0, 0.0);
+
+    thing1 = glGenLists(1);
+    glNewList(thing1, GL_COMPILE);
+       glColor3f(1.0, 0.0, 0.0);
+       glRectf(-1.0, -1.0, 1.0, 0.0);
+    glEndList();
+
+    thing2 = glGenLists(1);
+    glNewList(thing2, GL_COMPILE);
+       glColor3f(0.0, 1.0, 0.0);
+       glRectf(0.0, -1.0, 1.0, 1.0);
+    glEndList();
+}
+
+static void Reshape(int width, int height)
+{
+
+    glViewport(0, 0, (GLint)width, (GLint)height);
+
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
+}
+
+static void Key(unsigned char key, int x, int y)
+{
+    (void) x;
+    (void) y;
+    switch (key) {
+      case 27:
+       exit(1);
+      case '1':
+       glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+       break;
+      case '2':
+       glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+       break;
+      default:
+       return;
+    }
+
+    glutPostRedisplay();
+}
+
+static void Draw(void)
+{
+
+    glPushMatrix();
+
+    glScalef(0.8, 0.8, 1.0);
+
+    glClear(GL_COLOR_BUFFER_BIT);
+    glCallList(thing1);
+    glAccum(GL_LOAD, 0.5);
+
+    glClear(GL_COLOR_BUFFER_BIT);
+    glCallList(thing2);
+    glAccum(GL_ACCUM, 0.5);
+
+    glAccum(GL_RETURN, 1.0);
+
+    glPopMatrix();
+
+    glFlush();
+
+    if (doubleBuffer) {
+       glutSwapBuffers();
+    }
+}
+
+static GLenum Args(int argc, char **argv)
+{
+    GLint i;
+
+    doubleBuffer = GL_FALSE;
+
+    for (i = 1; i < argc; i++) {
+       if (strcmp(argv[i], "-sb") == 0) {
+           doubleBuffer = GL_FALSE;
+       } else if (strcmp(argv[i], "-db") == 0) {
+           doubleBuffer = GL_TRUE;
+       } else {
+           printf("%s (Bad option).\n", argv[i]);
+           return GL_FALSE;
+       }
+    }
+    return GL_TRUE;
+}
+
+int main(int argc, char **argv)
+{
+    GLenum type;
+
+    glutInit(&argc, argv);
+
+    if (Args(argc, argv) == GL_FALSE) {
+       exit(1);
+    }
+
+    glutInitWindowPosition(0, 0);
+    glutInitWindowSize( 300, 300);
+
+    type = GLUT_RGB | GLUT_ACCUM;
+    type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
+    glutInitDisplayMode(type);
+
+    if (glutCreateWindow("Accum Test") == GL_FALSE) {
+       exit(1);
+    }
+
+    Init();
+
+    glutReshapeFunc(Reshape);
+    glutKeyboardFunc(Key);
+    glutDisplayFunc(Draw);
+    glutMainLoop();
+       return 0;
+}
diff --git a/progs/samples/bitmap1.c b/progs/samples/bitmap1.c
new file mode 100644 (file)
index 0000000..517d584
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the name of
+ * Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
+ * ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <GL/glut.h>
+
+
+#define OPENGL_WIDTH 24
+#define OPENGL_HEIGHT 13
+
+
+GLenum rgb, doubleBuffer, windType;
+
+float boxA[3] = {
+    0, 0, 0
+};
+float boxB[3] = {
+    -100, 0, 0
+};
+float boxC[3] = {
+    100, 0, 0
+};
+float boxD[3] = {
+    0, 95, 0
+};
+float boxE[3] = {
+    0, -105, 0
+};
+GLubyte OpenGL_bits1[] = {
+   0x00, 0x03, 0x00,
+   0x7f, 0xfb, 0xff,
+   0x7f, 0xfb, 0xff,
+   0x00, 0x03, 0x00,
+   0x3e, 0x8f, 0xb7,
+   0x63, 0xdb, 0xb0,
+   0x63, 0xdb, 0xb7,
+   0x63, 0xdb, 0xb6,
+   0x63, 0x8f, 0xf3,
+   0x63, 0x00, 0x00,
+   0x63, 0x00, 0x00,
+   0x63, 0x00, 0x00,
+   0x3e, 0x00, 0x00,
+};
+GLubyte OpenGL_bits2[] = {
+   0x00, 0x00, 0x00,
+   0xff, 0xff, 0x01,
+   0xff, 0xff, 0x01, 
+   0x00, 0x00, 0x00,
+   0xf9, 0xfc, 0x01, 
+   0x8d, 0x0d, 0x00,
+   0x8d, 0x0d, 0x00, 
+   0x8d, 0x0d, 0x00,
+   0xcc, 0x0d, 0x00, 
+   0x0c, 0x4c, 0x0a,
+   0x0c, 0x4c, 0x0e, 
+   0x8c, 0xed, 0x0e,
+   0xf8, 0x0c, 0x00, 
+};
+GLubyte logo_bits[] = {
+   0x00, 0x66, 0x66, 
+   0xff, 0x66, 0x66, 
+   0x00, 0x00, 0x00, 
+   0xff, 0x3c, 0x3c, 
+   0x00, 0x42, 0x40, 
+   0xff, 0x42, 0x40, 
+   0x00, 0x41, 0x40, 
+   0xff, 0x21, 0x20, 
+   0x00, 0x2f, 0x20, 
+   0xff, 0x20, 0x20, 
+   0x00, 0x10, 0x90, 
+   0xff, 0x10, 0x90, 
+   0x00, 0x0f, 0x10, 
+   0xff, 0x00, 0x00, 
+   0x00, 0x66, 0x66, 
+   0xff, 0x66, 0x66, 
+};
+
+#include "tkmap.c"
+
+static void Init(void)
+{
+
+    glClearColor(0.0, 0.0, 0.0, 0.0);
+    glClearIndex(0.0);
+}
+
+static void Reshape(int width, int height)
+{
+
+    glViewport(0, 0, (GLint)width, (GLint)height);
+
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    gluOrtho2D(-175, 175, -175, 175);
+    glMatrixMode(GL_MODELVIEW);
+}
+
+static void Key(unsigned char key, int x, int y)
+{
+
+    switch (key) {
+      case 27:
+        exit(1);
+    }
+}
+
+static void Draw(void)
+{
+    float mapI[2], mapIA[2], mapIR[2];
+
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    mapI[0] = 0.0;
+    mapI[1] = 1.0;
+    mapIR[0] = 0.0;
+    mapIR[1] = 0.0;
+    mapIA[0] = 1.0;
+    mapIA[1] = 1.0;
+    
+    glPixelMapfv(GL_PIXEL_MAP_I_TO_R, 2, mapIR);
+    glPixelMapfv(GL_PIXEL_MAP_I_TO_G, 2, mapI);
+    glPixelMapfv(GL_PIXEL_MAP_I_TO_B, 2, mapI);
+    glPixelMapfv(GL_PIXEL_MAP_I_TO_A, 2, mapIA);
+    glPixelTransferi(GL_MAP_COLOR, GL_TRUE);
+    
+    SetColor(COLOR_WHITE);
+    glRasterPos3fv(boxA);
+    glPixelStorei(GL_UNPACK_ROW_LENGTH, 24);
+    glPixelStorei(GL_UNPACK_SKIP_PIXELS, 8);
+    glPixelStorei(GL_UNPACK_SKIP_ROWS, 2);
+    glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
+    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+    glBitmap(16, 12, 8.0, 0.0, 0.0, 0.0, logo_bits);
+
+    glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+    glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+    glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
+    glPixelStorei(GL_UNPACK_LSB_FIRST, GL_TRUE);
+    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+    SetColor(COLOR_WHITE);
+    glRasterPos3fv(boxB);
+    glBitmap(OPENGL_WIDTH, OPENGL_HEIGHT, OPENGL_WIDTH, 0.0, OPENGL_WIDTH, 0.0,
+            OpenGL_bits1);
+    glBitmap(OPENGL_WIDTH, OPENGL_HEIGHT, OPENGL_WIDTH, 0.0, OPENGL_WIDTH, 0.0,
+            OpenGL_bits2);
+
+    SetColor(COLOR_YELLOW);
+    glRasterPos3fv(boxC);
+    glBitmap(OPENGL_WIDTH, OPENGL_HEIGHT, OPENGL_WIDTH, 0.0, OPENGL_WIDTH, 0.0,
+            OpenGL_bits1);
+    glBitmap(OPENGL_WIDTH, OPENGL_HEIGHT, OPENGL_WIDTH, 0.0, OPENGL_WIDTH, 0.0,
+            OpenGL_bits2);
+
+    SetColor(COLOR_CYAN);
+    glRasterPos3fv(boxD);
+    glBitmap(OPENGL_WIDTH, OPENGL_HEIGHT, OPENGL_WIDTH, 0.0, OPENGL_WIDTH, 0.0,
+            OpenGL_bits1);
+    glBitmap(OPENGL_WIDTH, OPENGL_HEIGHT, OPENGL_WIDTH, 0.0, OPENGL_WIDTH, 0.0,
+            OpenGL_bits2);
+
+    SetColor(COLOR_RED);
+    glRasterPos3fv(boxE);
+    glBitmap(OPENGL_WIDTH, OPENGL_HEIGHT, OPENGL_WIDTH, 0.0, OPENGL_WIDTH, 0.0,
+            OpenGL_bits1);
+    glBitmap(OPENGL_WIDTH, OPENGL_HEIGHT, OPENGL_WIDTH, 0.0, OPENGL_WIDTH, 0.0,
+            OpenGL_bits2);
+
+    glFlush();
+
+    if (doubleBuffer) {
+       glutSwapBuffers();
+    }
+}
+
+static GLenum Args(int argc, char **argv)
+{
+    GLint i;
+
+    rgb = GL_TRUE;
+    doubleBuffer = GL_FALSE;
+
+    for (i = 1; i < argc; i++) {
+       if (strcmp(argv[i], "-ci") == 0) {
+           rgb = GL_FALSE;
+       } else if (strcmp(argv[i], "-rgb") == 0) {
+           rgb = GL_TRUE;
+       } else if (strcmp(argv[i], "-sb") == 0) {
+           doubleBuffer = GL_FALSE;
+       } else if (strcmp(argv[i], "-db") == 0) {
+           doubleBuffer = GL_TRUE;
+       } else {
+           printf("%s (Bad option).\n", argv[i]);
+           return GL_FALSE;
+       }
+    }
+    return GL_TRUE;
+}
+
+int main(int argc, char **argv)
+{
+    glutInit(&argc, argv);
+
+    if (Args(argc, argv) == GL_FALSE) {
+       exit(1);
+    }
+
+    glutInitWindowPosition(0, 0); glutInitWindowSize( 300, 300);
+
+    windType = (rgb) ? GLUT_RGB : GLUT_INDEX;
+    windType |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
+    glutInitDisplayMode(windType);
+
+    if (glutCreateWindow("Bitmap Test") == GL_FALSE) {
+       exit(1);
+    }
+
+    InitMap();
+
+    Init();
+
+    glutReshapeFunc(Reshape);
+    glutKeyboardFunc(Key);
+    glutDisplayFunc(Draw);
+    glutMainLoop();
+       return 0;
+}
diff --git a/progs/samples/bitmap2.c b/progs/samples/bitmap2.c
new file mode 100644 (file)
index 0000000..5faac84
--- /dev/null
@@ -0,0 +1,787 @@
+/*
+ * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the name of
+ * Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
+ * ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <GL/glut.h>
+
+
+#define EXP_WIDTH 80
+#define EXP_HEIGHT 80
+
+
+GLenum rgb, doubleBuffer, windType;
+
+#include "tkmap.c"
+
+GLenum useLists, abuse;
+GLubyte exp_bits[7][800] = {
+    {
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x40, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x80, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x81, 0x04, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0xf2, 0x1f, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0xbe, 0x7c, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0xf6, 0x4f, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0xde, 0x7d, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0xea, 0xef, 0x01, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0xff, 0x55, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0xdd, 0xfd, 0x03, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0xbf, 0xae, 0x22, 0x36, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0xdb, 0xf7, 0x3f, 0x1e, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x80, 0x50, 0xbf, 0xbf, 0x85, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0xff, 0xe5, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0xee, 0x7e, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x74, 0x4b, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0xe8, 0x3e, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0xf8, 0x49, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x54, 0x07, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    },
+    {
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0xc0, 0x70, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x78, 0x91, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x60, 0xf1, 0x53, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x40, 0x97, 0x5c, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0xa0, 0x0c, 0x8c, 0x1b, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0xc4, 0x01, 0x00, 0xc8, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x08, 0x02, 0x00, 0x88, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x60, 0x00, 0x02, 0x40, 0x02, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x70, 0x00, 0x0c, 0x40, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x70, 0xe0, 0x0d, 0x00, 0x04, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x72, 0xc8, 0x07, 0x40, 0x08, 0x00, 0x00,
+       0x00, 0x00, 0x80, 0x02, 0x78, 0x2f, 0x40, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x40, 0x02, 0xb0, 0x0a, 0x20, 0x77, 0x00, 0x00,
+       0x00, 0x00, 0x40, 0x13, 0x10, 0x33, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0xc0, 0x02, 0x78, 0xbb, 0x81, 0x09, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x02, 0xdc, 0xe7, 0x00, 0x09, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0xac, 0x78, 0x00, 0x31, 0x00, 0x00,
+       0x00, 0x00, 0x40, 0x03, 0x74, 0x4b, 0x00, 0x03, 0x00, 0x00,
+       0x00, 0x00, 0x80, 0x02, 0xe8, 0x3e, 0x00, 0x01, 0x10, 0x00,
+       0x00, 0x00, 0x80, 0x00, 0xf8, 0x49, 0x80, 0x09, 0x1c, 0x00,
+       0x00, 0x00, 0x00, 0x0c, 0x40, 0x07, 0x00, 0x05, 0x1c, 0x00,
+       0x00, 0x00, 0x80, 0x09, 0x04, 0x80, 0x00, 0x02, 0x00, 0x00,
+       0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
+       0x00, 0x00, 0x80, 0x1d, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00,
+       0x00, 0x00, 0x80, 0xe3, 0x0b, 0x00, 0x22, 0x01, 0x00, 0x00,
+       0x00, 0x00, 0x80, 0x8f, 0x10, 0x00, 0xa0, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x80, 0x4f, 0x20, 0x78, 0x60, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x80, 0x80, 0x79, 0x18, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x78, 0x7c, 0x05, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x03, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x01, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    },
+    {
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x02, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x18, 0xc0, 0x04, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x84, 0x80, 0x04, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x80, 0x60, 0x06, 0x0c, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x80, 0x07, 0x64, 0x3a, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x20, 0x00, 0x08, 0x72, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x80, 0x3b, 0x00, 0x00, 0xc0, 0x33, 0x00, 0x00,
+       0x00, 0x00, 0xa0, 0x1b, 0x00, 0x00, 0x80, 0x42, 0x00, 0x00,
+       0x00, 0x00, 0xd0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
+       0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
+       0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00,
+       0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x50, 0x02, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+       0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00,
+       0x00, 0x30, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+       0x00, 0x80, 0x03, 0x03, 0x80, 0x00, 0x00, 0x00, 0x08, 0x00,
+       0x00, 0xe2, 0x82, 0x03, 0x00, 0x20, 0x00, 0x00, 0x40, 0x00,
+       0x00, 0x0e, 0x80, 0x03, 0x00, 0x4c, 0x00, 0x00, 0x10, 0x00,
+       0x00, 0x0e, 0x80, 0x03, 0xec, 0x10, 0x00, 0x00, 0x60, 0x00,
+       0x00, 0x12, 0x00, 0x00, 0x05, 0x93, 0x01, 0x00, 0x20, 0x00,
+       0x00, 0x12, 0x00, 0x00, 0x00, 0x5c, 0x0c, 0x00, 0x60, 0x00,
+       0x00, 0x30, 0x00, 0xc0, 0x05, 0x81, 0x10, 0x00, 0x00, 0x00,
+       0x00, 0x2c, 0x00, 0x00, 0xcc, 0x06, 0x00, 0x00, 0x20, 0x00,
+       0x00, 0x30, 0x00, 0x00, 0x28, 0x20, 0x02, 0x00, 0x00, 0x00,
+       0x00, 0x30, 0x80, 0x80, 0x22, 0x00, 0x02, 0x00, 0x00, 0x02,
+       0x00, 0x20, 0x00, 0x80, 0x02, 0x20, 0x08, 0x00, 0x20, 0x02,
+       0x00, 0x38, 0x00, 0x00, 0x00, 0x11, 0x28, 0x00, 0x20, 0x06,
+       0x00, 0x20, 0x00, 0x80, 0x0e, 0xc0, 0x21, 0x00, 0x5c, 0x00,
+       0x00, 0x24, 0x00, 0x90, 0x40, 0x58, 0x04, 0x00, 0x20, 0x01,
+       0x00, 0x24, 0x00, 0x10, 0x22, 0x02, 0x05, 0x00, 0x20, 0x02,
+       0x00, 0x00, 0x00, 0x00, 0x28, 0xb6, 0x00, 0x00, 0x20, 0x01,
+       0x00, 0x70, 0x00, 0x00, 0x18, 0xc1, 0x00, 0x00, 0xc0, 0x01,
+       0x00, 0xc0, 0x00, 0x00, 0x40, 0x83, 0x04, 0x00, 0xc0, 0x01,
+       0x00, 0x00, 0x01, 0x80, 0xfc, 0x41, 0x02, 0x00, 0x10, 0x00,
+       0x00, 0x00, 0x01, 0x00, 0x03, 0x30, 0x00, 0x00, 0x10, 0x00,
+       0x00, 0x10, 0x02, 0x00, 0x40, 0x1d, 0x00, 0x00, 0x20, 0x00,
+       0x00, 0x30, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x20, 0x00,
+       0x00, 0x00, 0x04, 0x00, 0x60, 0x00, 0x00, 0x00, 0x20, 0x00,
+       0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
+       0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01,
+       0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00,
+       0x00, 0x00, 0x38, 0x00, 0x81, 0x0f, 0x00, 0x00, 0x2a, 0x00,
+       0x00, 0x00, 0xf8, 0x02, 0x80, 0x0f, 0x00, 0x00, 0x10, 0x00,
+       0x00, 0x00, 0xf8, 0x02, 0x80, 0x0f, 0x00, 0x00, 0x08, 0x00,
+       0x00, 0x00, 0x00, 0x06, 0xc0, 0x01, 0x00, 0x00, 0x07, 0x00,
+       0x00, 0x00, 0x00, 0x14, 0xe0, 0x00, 0x00, 0x80, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x08, 0x70, 0x00, 0x00, 0x85, 0x00, 0x00,
+       0x00, 0x00, 0xc0, 0x00, 0x30, 0x00, 0x20, 0x3c, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0xe0, 0xe0, 0x80, 0x00, 0x0b, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0xe0, 0x79, 0x83, 0x80, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x80, 0x19, 0x22, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x28, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    },
+    {
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x04, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
+       0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
+       0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00,
+       0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+       0x00, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0xe0, 0x03, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+       0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00,
+       0x03, 0x00, 0x00, 0x00, 0x02, 0x90, 0x00, 0x00, 0x00, 0x40,
+       0x02, 0x02, 0x00, 0x80, 0x80, 0x00, 0x02, 0x00, 0x00, 0x00,
+       0x40, 0x00, 0x00, 0x40, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x01, 0x00, 0x20, 0x00, 0x04, 0x02, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x30, 0x28, 0x90, 0x05, 0x00, 0x00, 0x40,
+       0x00, 0x00, 0x00, 0x48, 0x05, 0x00, 0x21, 0x00, 0x00, 0x0c,
+       0x00, 0x00, 0x00, 0x84, 0x00, 0x54, 0x05, 0x00, 0x00, 0x00,
+       0x04, 0x00, 0x00, 0x40, 0x05, 0x80, 0x41, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x0e, 0x02, 0x01, 0x00, 0x00, 0x20,
+       0x00, 0x00, 0x00, 0x08, 0x20, 0x20, 0x01, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x84, 0x82, 0x00, 0x03, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x48, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x40,
+       0x04, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x21, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x90, 0x40, 0x40, 0x04, 0x00, 0x00, 0x80,
+       0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x41, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x08, 0x40, 0xa0, 0x00, 0x00, 0x00, 0x50,
+       0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00, 0x40,
+       0x40, 0x00, 0x00, 0x00, 0x40, 0x02, 0x04, 0x00, 0x00, 0x30,
+       0x00, 0x00, 0x00, 0x80, 0x84, 0x00, 0x02, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0xc2, 0x20, 0x20, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x10, 0xc0, 0x05, 0x20, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x00, 0x10,
+       0x08, 0x00, 0x00, 0x80, 0x00, 0x10, 0x10, 0x00, 0x00, 0x08,
+       0x10, 0x02, 0x00, 0x00, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+       0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+       0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x18, 0x08, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x08, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x3a, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x40, 0x04,
+       0x00, 0x60, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x04,
+       0x00, 0xb8, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
+       0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x40, 0x00, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    },
+    {
+       0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x10, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00,
+       0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x08, 0x00, 0x00,
+       0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x1f, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x80, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x40, 0x00, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00,
+       0x00, 0x00, 0x60, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x08, 0x01, 0x00, 0x01, 0x10, 0x04, 0x00, 0x00,
+       0x00, 0x40, 0x00, 0x02, 0x02, 0x90, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x03, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x1c, 0x20, 0x05, 0x00, 0x04, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x14, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x20, 0x40, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0xc4, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x06, 0x40, 0x00, 0x00, 0x40, 0x00, 0x02, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x10, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00,
+       0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x80, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x80, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
+       0x00, 0x00, 0x42, 0x00, 0x00, 0x04, 0x20, 0x01, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x20, 0x05, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x02, 0x00, 0x81, 0x07, 0x01, 0x03, 0x00, 0x00,
+       0x00, 0x00, 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x20, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x08, 0x02, 0x80, 0x20, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x80, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x80, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x80, 0x00, 0x00, 0x40, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+       0xc0, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x40, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x02, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x40, 0x0d, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    },
+    {
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x1f, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
+       0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x04, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+       0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+       0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x01, 0x10, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x00,
+       0x02, 0x02, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0xc0, 0x00, 0x40, 0x00, 0x02, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x00,
+       0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01,
+       0x00, 0x04, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+       0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
+       0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x80, 0x06, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x04, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x02, 0x20, 0x00, 0x00,
+       0x08, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00
+    },
+    {
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x04, 0x00, 0x00, 0x80, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+       0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+       0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+       0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x01, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    }
+};
+GLint exp_lists[7];
+
+
+static void Init(void)
+{
+    GLint i;
+
+    glClearColor(0.0, 0.0, 0.0, 0.0);
+    glClearIndex(0.0);
+
+    glPixelStorei(GL_UNPACK_LSB_FIRST, GL_TRUE);
+    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+    for (i = 0; i < 7; i++) {
+       exp_lists[i] = glGenLists(1);
+       glNewList(exp_lists[i], GL_COMPILE);
+           glBitmap(80, 80, 40.0, 40.0, 0.0, 0.0, exp_bits[i]);
+       glEndList();
+    }
+
+    abuse = GL_FALSE;
+    useLists = GL_TRUE;
+}
+
+static void Reshape(int width, int height)
+{
+
+    glViewport(0, 0, (GLint)width, (GLint)height);
+
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    gluOrtho2D(-175, 175, -175, 175);
+    glMatrixMode(GL_MODELVIEW);
+}
+
+static void Key(unsigned char key, int x, int y)
+{
+
+    switch (key) {
+      case 27:
+        exit(1);
+      case '1':
+       useLists = !useLists;
+        break;
+      case '2':
+       abuse = !abuse;
+        break;
+      default:
+       return;
+    }
+
+    glutPostRedisplay();
+}
+
+static void Draw(void)
+{
+    GLint i, j;
+
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    for (i = 0; i < 7; i++) {
+       for (j = 0; j < 40; j++) {
+           switch (j % 7) {
+             case 0:
+               SetColor(COLOR_YELLOW);
+               break;
+             case 1:
+               SetColor(COLOR_GREEN);
+               break;
+             case 2:
+               SetColor(COLOR_BLUE);
+               break;
+             case 3:
+               SetColor(COLOR_MAGENTA);
+               break;
+             case 4:
+               SetColor(COLOR_CYAN);
+               break;
+             case 5:
+               SetColor(COLOR_WHITE);
+               break;
+             case 6:
+               SetColor(COLOR_RED);
+               break;
+           }
+           glRasterPos3i((j*3)%5, (j*3)%8, 0);
+
+           if (useLists) {
+               glCallList(exp_lists[i]); 
+           } else {
+               glBitmap(80, 80, 40.0, 40.0, 0.0, 0.0, exp_bits[i]);
+           }
+           if (!abuse) {
+               break;
+           }
+       }
+
+       if (i == 6) {
+           break;
+       }
+
+       for (j = 0; j < 40; j++) {
+           SetColor(COLOR_BLACK);
+           glRasterPos3i((j*3)%5, (j*3)%8, 0);
+           if (useLists) {
+               glCallList(exp_lists[i]); 
+           } else {
+               glBitmap(80, 80, 40.0, 40.0, 0.0, 0.0, exp_bits[i]);
+           }
+           if (!abuse) {
+               break;
+           }
+       }
+    }
+
+    glFlush();
+
+    if (doubleBuffer) {
+       glutSwapBuffers();
+    }
+}
+
+static GLenum Args(int argc, char **argv)
+{
+    GLint i;
+
+    rgb = GL_TRUE;
+    doubleBuffer = GL_FALSE;
+
+    for (i = 1; i < argc; i++) {
+       if (strcmp(argv[i], "-ci") == 0) {
+           rgb = GL_FALSE;
+       } else if (strcmp(argv[i], "-rgb") == 0) {
+           rgb = GL_TRUE;
+       } else if (strcmp(argv[i], "-sb") == 0) {
+           doubleBuffer = GL_FALSE;
+       } else if (strcmp(argv[i], "-db") == 0) {
+           doubleBuffer = GL_TRUE;
+       } else {
+           printf("%s (Bad option).\n", argv[i]);
+           return GL_FALSE;
+       }
+    }
+    return GL_TRUE;
+}
+
+int main(int argc, char **argv)
+{
+    glutInit(&argc, argv);
+
+    if (Args(argc, argv) == GL_FALSE) {
+       exit(1);
+    }
+
+    glutInitWindowPosition(0, 0); glutInitWindowSize( 300, 300);
+
+    windType = (rgb) ? GLUT_RGB : GLUT_INDEX;
+    windType |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
+    glutInitDisplayMode(windType);
+
+    if (glutCreateWindow("Bitmap Test") == GL_FALSE) {
+       exit(1);
+    }
+
+    InitMap();
+
+    Init();
+
+    glutReshapeFunc(Reshape);
+    glutKeyboardFunc(Key);
+    glutDisplayFunc(Draw);
+    glutMainLoop();
+       return 0;
+}
diff --git a/progs/samples/blendeq.c b/progs/samples/blendeq.c
new file mode 100644 (file)
index 0000000..7be5207
--- /dev/null
@@ -0,0 +1,295 @@
+/*
+** blendeq.c - Demonstrates the use of the blend_minmax, blend_subtract,
+**    and blend_logic_op extensions using glBlendEquationEXT.
+**
+**    Over a two-color backround, draw rectangles using twelve blend
+**    options.  The values are read back as UNSIGNED_BYTE and printed
+**    in hex over each value.  These values are useful for logic
+**    op comparisons when channels are 8 bits deep.
+*/
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <GL/glut.h>
+
+
+GLenum doubleBuffer;
+static int dithering = 0;
+static int doPrint = 1;
+static int deltaY;
+GLint windW, windH;
+
+static void DrawString(const char *string)
+{
+    int i;
+
+    for (i = 0; string[i]; i++)
+       glutBitmapCharacter(GLUT_BITMAP_9_BY_15, string[i]);
+}
+
+static void Init(void)
+{
+
+    glDisable(GL_DITHER);
+    glShadeModel(GL_FLAT);
+}
+
+static void Reshape(int width, int height)
+{
+
+    windW = (GLint)width;
+    windH = (GLint)height;
+
+    glViewport(0, 0, (GLint)width, (GLint)height);
+    deltaY = windH /16;
+
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    gluOrtho2D(0, windW, 0, windH);
+    glMatrixMode(GL_MODELVIEW);
+}
+
+static void Key(unsigned char key, int x, int y)
+{
+
+    switch (key) {
+      case 27:
+       exit(1);
+      case 'd':
+       dithering = !dithering;
+       break;
+      default:
+       return;
+    }
+
+    glutPostRedisplay();
+}
+
+static void PrintColorStrings( void )
+{
+    GLubyte ubbuf[3];
+    int i, xleft, xright;
+    char colorString[18];
+
+    xleft = 5 + windW/4;
+    xright = 5 + windW/2;
+
+    for (i = windH - deltaY + 4; i > 0; i-=deltaY) {
+        glReadPixels(xleft, i+10, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, ubbuf);
+        sprintf(colorString, "(0x%x, 0x%x, 0x%x)",
+                ubbuf[0], ubbuf[1], ubbuf[2]);
+        glRasterPos2f(xleft, i);
+       DrawString(colorString);
+        glReadPixels(xright, i+10, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, ubbuf);
+        sprintf(colorString, "(0x%x, 0x%x, 0x%x)",
+                ubbuf[0], ubbuf[1], ubbuf[2]);
+        glRasterPos2f(xright, i);
+       DrawString(colorString);
+    }
+}
+
+static void Draw(void)
+{
+    int stringOffset = 5, stringx = 8;
+    int x1, x2, xleft, xright;
+    int i;
+
+    (dithering) ? glEnable(GL_DITHER) : glDisable(GL_DITHER);
+    glDisable(GL_BLEND);
+
+    glClearColor(0.5, 0.6, 0.1, 1.0);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    /* Draw background */
+    glColor3f(0.1, 0.1, 1.0);
+    glRectf(0.0, 0.0, windW/2, windH);
+
+    /* Draw labels */
+    glColor3f(0.8, 0.8, 0.0);
+    i = windH - deltaY + stringOffset;
+    glRasterPos2f(stringx, i); i -= deltaY;
+    DrawString("SOURCE");
+    glRasterPos2f(stringx, i); i -= deltaY;
+    DrawString("DEST");
+    glRasterPos2f(stringx, i); i -= deltaY;
+    DrawString("min");
+    glRasterPos2f(stringx, i); i -= deltaY;
+    DrawString("max");
+    glRasterPos2f(stringx, i); i -= deltaY;
+    DrawString("subtract");
+    glRasterPos2f(stringx, i); i -= deltaY;
+    DrawString("reverse_subtract");
+    glRasterPos2f(stringx, i); i -= deltaY;
+    DrawString("clear");
+    glRasterPos2f(stringx, i); i -= deltaY;
+    DrawString("set");
+    glRasterPos2f(stringx, i); i -= deltaY;
+    DrawString("copy");
+    glRasterPos2f(stringx, i); i -= deltaY;
+    DrawString("noop");
+    glRasterPos2f(stringx, i); i -= deltaY;
+    DrawString("and");
+    glRasterPos2f(stringx, i); i -= deltaY;
+    DrawString("invert");
+    glRasterPos2f(stringx, i); i -= deltaY;
+    DrawString("or");
+    glRasterPos2f(stringx, i); i -= deltaY;
+    DrawString("xor");
+
+
+    i = windH - deltaY;
+    x1 = windW/4;
+    x2 = 3 * windW/4;
+    xleft = 5 + windW/4;
+    xright = 5 + windW/2;
+
+    /* Draw foreground color for comparison */
+    glColor3f(0.9, 0.2, 0.8);
+    glRectf(x1, i, x2, i+deltaY);
+
+    /* Leave one rectangle of background color */
+
+    /* Begin test cases */
+    glEnable(GL_BLEND);
+    glBlendFunc(GL_ONE, GL_ONE);
+
+    i -= 2*deltaY;
+    glBlendEquationEXT(GL_MIN_EXT);
+    glRectf(x1, i, x2, i+deltaY);
+
+    i -= deltaY;
+    glBlendEquationEXT(GL_MAX_EXT);
+    glRectf(x1, i, x2, i+deltaY);
+
+    i -= deltaY;
+    glBlendEquationEXT(GL_FUNC_SUBTRACT_EXT);
+    glRectf(x1, i, x2, i+deltaY);
+
+    i -= deltaY;
+    glBlendEquationEXT(GL_FUNC_REVERSE_SUBTRACT_EXT);
+    glRectf(x1, i, x2, i+deltaY);
+
+    glBlendFunc(GL_ONE, GL_ZERO);
+    i -= deltaY;
+    glBlendEquationEXT(GL_LOGIC_OP);
+    glLogicOp(GL_CLEAR);
+    glRectf(x1, i, x2, i+deltaY);
+
+    i -= deltaY;
+    glBlendEquationEXT(GL_LOGIC_OP);
+    glLogicOp(GL_SET);
+    glRectf(x1, i, x2, i+deltaY);
+
+    i -= deltaY;
+    glBlendEquationEXT(GL_LOGIC_OP);
+    glLogicOp(GL_COPY);
+    glRectf(x1, i, x2, i+deltaY);
+
+    i -= deltaY;
+    glBlendEquationEXT(GL_LOGIC_OP);
+    glLogicOp(GL_NOOP);
+    glRectf(x1, i, x2, i+deltaY);
+
+    i -= deltaY;
+    glBlendEquationEXT(GL_LOGIC_OP);
+    glLogicOp(GL_AND);
+    glRectf(x1, i, x2, i+deltaY);
+
+    i -= deltaY;
+    glBlendEquationEXT(GL_LOGIC_OP);
+    glLogicOp(GL_INVERT);
+    glRectf(x1, i, x2, i+deltaY);
+
+    i -= deltaY;
+    glBlendEquationEXT(GL_LOGIC_OP);
+    glLogicOp(GL_OR);
+    glRectf(x1, i, x2, i+deltaY);
+
+    i -= deltaY;
+    glBlendEquationEXT(GL_LOGIC_OP);
+    glLogicOp(GL_XOR);
+    glRectf(x1, i, x2, i+deltaY);
+    glRectf(x1, i+10, x2, i+5);
+
+  if (doPrint) {
+      glDisable(GL_BLEND);
+      glColor3f(1.0, 1.0, 1.0);
+      PrintColorStrings();
+  }
+  glFlush();
+
+    if (doubleBuffer) {
+       glutSwapBuffers();
+    }
+
+}
+
+static GLenum Args(int argc, char **argv)
+{
+    GLint i;
+
+    doubleBuffer = GL_FALSE;
+
+    for (i = 1; i < argc; i++) {
+       if (strcmp(argv[i], "-sb") == 0) {
+           doubleBuffer = GL_FALSE;
+       } else if (strcmp(argv[i], "-db") == 0) {
+           doubleBuffer = GL_TRUE;
+       } else {
+           printf("%s (Bad option).\n", argv[i]);
+           return GL_FALSE;
+       }
+    }
+    return GL_TRUE;
+}
+
+int main(int argc, char **argv)
+{
+    GLenum type;
+    char *s;
+    char *extName1 = "GL_EXT_blend_logic_op";
+    char *extName2 = "GL_EXT_blend_minmax";
+    char *extName3 = "GL_EXT_blend_subtract";
+
+    glutInit(&argc, argv);
+
+    if (Args(argc, argv) == GL_FALSE) {
+       exit(1);
+    }
+
+    glutInitWindowPosition(0, 0); glutInitWindowSize( 800, 400);
+
+    type = GLUT_RGB;
+    type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
+    glutInitDisplayMode(type);
+
+    if (glutCreateWindow("Blend Equation") == GL_FALSE) {
+       exit(1);
+    }
+
+    /* Make sure blend_logic_op extension is there. */
+    s = (char *) glGetString(GL_EXTENSIONS);
+    if (!s)
+       exit(1);
+    if (strstr(s,extName1) == 0) {
+       printf("Blend_logic_op extension is not present.\n");
+       exit(1);
+    }
+    if (strstr(s,extName2) == 0) {
+       printf("Blend_minmax extension is not present.\n");
+       exit(1);
+    }
+    if (strstr(s,extName3) == 0) {
+       printf("Blend_subtract extension is not present.\n");
+       exit(1);
+    }
+
+    Init();
+
+    glutReshapeFunc(Reshape);
+    glutKeyboardFunc(Key);
+    glutDisplayFunc(Draw);
+    glutMainLoop();
+    return 0;
+}
diff --git a/progs/samples/blendxor.c b/progs/samples/blendxor.c
new file mode 100644 (file)
index 0000000..a46920d
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+** blendxor.c - Demonstrates the use of the blend_logic_op
+**    extension to draw hilights.  Using XOR to draw the same
+**    image twice restores the background to its original value.
+*/
+
+#include <stdio.h>
+#include <string.h>
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+#include <stdlib.h>
+#include <GL/glut.h>
+
+
+GLenum doubleBuffer;
+int dithering = 0;
+GLint windW, windH;
+
+static void Init(void)
+{
+    glDisable(GL_DITHER);
+    glShadeModel(GL_FLAT);
+}
+
+static void Reshape(int width, int height)
+{
+
+    windW = (GLint)width;
+    windH = (GLint)height;
+
+    glViewport(0, 0, (GLint)width, (GLint)height);
+
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    gluOrtho2D(0, 400, 0, 400);
+    glMatrixMode(GL_MODELVIEW);
+}
+
+static void Key(unsigned char key, int x, int y)
+{
+
+    switch (key) {
+      case 27:
+       exit(1);
+      case 'd':
+       dithering = !dithering;
+       break;
+      default:
+       return;
+    }
+
+    glutPostRedisplay();
+}
+
+static void Draw(void)
+{
+    int i;
+
+    glDisable(GL_BLEND);
+
+    (dithering) ? glEnable(GL_DITHER) : glDisable(GL_DITHER);
+
+    glClearColor(0.5, 0.6, 0.1, 1.0);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    /* Draw background prims */
+    glColor3f(0.1, 0.1, 1.0);
+    glBegin(GL_TRIANGLES);
+        glVertex2i(5, 5);
+        glVertex2i(130, 50);
+        glVertex2i(100,  300);
+    glEnd();
+    glColor3f(0.5, 0.2, 0.9);
+    glBegin(GL_TRIANGLES);
+        glVertex2i(200, 100);
+        glVertex2i(330, 50);
+        glVertex2i(340,  400);
+    glEnd();
+
+    glEnable(GL_BLEND);
+    glBlendEquationEXT(GL_LOGIC_OP);
+    glLogicOp(GL_XOR);
+
+    /* Draw a set of rectangles across the window */
+    glColor3f(0.9, 0.2, 0.8);
+    for(i = 0; i < 400; i+=60) {
+        glBegin(GL_POLYGON);
+            glVertex2i(i, 100);
+            glVertex2i(i+50, 100);
+            glVertex2i(i+50, 200);
+            glVertex2i(i, 200);
+        glEnd();
+    }
+    glFlush();   /* Added by Brian Paul */
+#ifndef _WIN32
+    sleep(2);
+#endif
+
+    /* Redraw  the rectangles, which should erase them */
+    for(i = 0; i < 400; i+=60) {
+        glBegin(GL_POLYGON);
+            glVertex2i(i, 100);
+            glVertex2i(i+50, 100);
+            glVertex2i(i+50, 200);
+            glVertex2i(i, 200);
+        glEnd();
+    }
+    glFlush();
+
+
+    if (doubleBuffer) {
+       glutSwapBuffers();
+    }
+}
+
+static GLenum Args(int argc, char **argv)
+{
+    GLint i;
+
+    doubleBuffer = GL_FALSE;
+
+    for (i = 1; i < argc; i++) {
+       if (strcmp(argv[i], "-sb") == 0) {
+           doubleBuffer = GL_FALSE;
+       } else if (strcmp(argv[i], "-db") == 0) {
+           doubleBuffer = GL_TRUE;
+       } else {
+           printf("%s (Bad option).\n", argv[i]);
+           return GL_FALSE;
+       }
+    }
+    return GL_TRUE;
+}
+
+int main(int argc, char **argv)
+{
+    GLenum type;
+    char *s;
+    char *extName = "GL_EXT_blend_logic_op";
+
+    glutInit(&argc, argv);
+
+    if (Args(argc, argv) == GL_FALSE) {
+       exit(1);
+    }
+
+    glutInitWindowPosition(0, 0); glutInitWindowSize( 400, 400);
+
+    type = GLUT_RGB;
+    type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
+    glutInitDisplayMode(type);
+
+    if (glutCreateWindow("Blend XOR") == GL_FALSE) {
+       exit(1);
+    }
+
+    /* Make sure blend_logic_op extension is there. */
+    s = (char *) glGetString(GL_EXTENSIONS);
+    if (!s)
+       exit(1);
+    if (strstr(s,extName) == 0) {
+       printf("Blend_logic_op extension is not present.\n");
+       exit(1);
+    }
+
+    Init();
+
+    glutReshapeFunc(Reshape);
+    glutKeyboardFunc(Key);
+    glutDisplayFunc(Draw);
+    glutMainLoop();
+       return 0;
+}
diff --git a/progs/samples/copy.c b/progs/samples/copy.c
new file mode 100644 (file)
index 0000000..391c637
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the name of
+ * Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
+ * ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <GL/glut.h>
+
+
+#include "loadppm.c"
+
+GLenum doubleBuffer;
+GLint windW, windH;
+
+char *fileName = 0;
+PPMImage *image;
+float point[3];
+float zoom;
+GLint x, y;
+
+static void Init(void)
+{
+
+    glClearColor(0.0, 0.0, 0.0, 0.0);
+
+    x = 0;
+    y = windH;
+    zoom = 1.8;
+}
+
+static void Reshape(int width, int height)
+{
+
+    windW = (GLint)width;
+    windH = (GLint)height;
+
+    glViewport(0, 0, windW, windH);
+
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    gluOrtho2D(0, windW, 0, windH);
+    glMatrixMode(GL_MODELVIEW);
+}
+
+static void Key(unsigned char key, int x, int y)
+{
+
+    switch (key) {
+      case 27:
+        exit(1);
+      case 'Z':
+       zoom += 0.2;
+       break;
+      case 'z':
+       zoom -= 0.2;
+       if (zoom < 0.2) {
+           zoom = 0.2;
+       }
+       break;
+      default:
+       return;
+    }
+
+    glutPostRedisplay();
+}
+
+static void Mouse(int button, int state, int mouseX, int mouseY)
+{
+    if (state != GLUT_DOWN)
+       return;
+    x = (GLint)mouseX;
+    y = (GLint)mouseY;
+
+    glutPostRedisplay();
+}
+
+static void Draw(void)
+{
+
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    point[0] = (windW / 2) - (image->sizeX / 2);
+    point[1] = (windH / 2) - (image->sizeY / 2);
+    point[2] = 0;
+    glRasterPos3fv(point);
+
+    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+    glPixelZoom(1.0, 1.0);
+    glDrawPixels(image->sizeX, image->sizeY, GL_RGB, GL_UNSIGNED_BYTE,
+                image->data);
+
+    point[0] = (float)x;
+    point[1] = windH - (float)y;
+    point[2] = 0.0;
+    glRasterPos3fv(point);
+
+    glPixelZoom(zoom, zoom);
+    glCopyPixels((windW/2)-(image->sizeX/2),
+                (windH/2)-(image->sizeY/2),
+                image->sizeX, image->sizeY, GL_COLOR);
+
+    glFlush();
+
+    if (doubleBuffer) {
+       glutSwapBuffers();
+    }
+}
+
+static GLenum Args(int argc, char **argv)
+{
+    GLint i;
+
+    doubleBuffer = GL_FALSE;
+
+    for (i = 1; i < argc; i++) {
+       if (strcmp(argv[i], "-sb") == 0) {
+           doubleBuffer = GL_FALSE;
+       } else if (strcmp(argv[i], "-db") == 0) {
+           doubleBuffer = GL_TRUE;
+       } else if (strcmp(argv[i], "-f") == 0) {
+           if (i+1 >= argc || argv[i+1][0] == '-') {
+               printf("-f (No file name).\n");
+               return GL_FALSE;
+           } else {
+               fileName = argv[++i];
+           }
+       } else {
+           printf("%s (Bad option).\n", argv[i]);
+           return GL_FALSE;
+       }
+    }
+    return GL_TRUE;
+}
+
+int main(int argc, char **argv)
+{
+    GLenum type;
+
+    glutInit(&argc, argv);
+
+    if (Args(argc, argv) == GL_FALSE) {
+       exit(1);
+    }
+
+    if (fileName == 0) {
+       printf("No image file.\n");
+       exit(1);
+    }
+
+    image = LoadPPM(fileName);
+
+    windW = 300;
+    windH = 300;
+    glutInitWindowPosition(0, 0); glutInitWindowSize( windW, windH);
+
+    type = GLUT_RGB;
+    type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
+    glutInitDisplayMode(type);
+
+    if (glutCreateWindow("Copy Test") == GL_FALSE) {
+       exit(1);
+    }
+
+    Init();
+
+    glutReshapeFunc(Reshape);
+    glutKeyboardFunc(Key);
+    glutMouseFunc(Mouse);
+    glutDisplayFunc(Draw);
+    glutMainLoop();
+       return 0;
+}
diff --git a/progs/samples/cursor.c b/progs/samples/cursor.c
new file mode 100644 (file)
index 0000000..de8fc58
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the name of
+ * Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
+ * ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <GL/glut.h>
+
+
+GLenum rgb, doubleBuffer, windType;
+int windX, windY;
+int cursor;
+
+
+#include "tkmap.c"
+
+static void Init(void)
+{
+    cursor = 0;
+    glutSetCursor(cursor);
+    glClearColor(0.0, 0.0, 0.0, 0.0);
+    glClearIndex(0.0);
+}
+
+static void Reshape(int width, int height)
+{
+
+    windX = width;
+    windY = height;
+    glViewport(0, 0, windX, windY);
+
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    gluOrtho2D(0, windX, 0, windY);
+    glMatrixMode(GL_MODELVIEW);
+}
+
+static void Key(unsigned char key, int x, int y)
+{
+
+    switch (key) {
+      case 27:
+        exit(1);
+      case 32:
+       cursor++;
+       if (cursor > 19) {
+           cursor = 0;
+       }
+       glutSetCursor(cursor);
+    }
+}
+
+static void Draw(void)
+{
+
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    glBegin(GL_POLYGON);
+       SetColor(COLOR_BLACK);
+       glVertex2i(0, 0);
+       SetColor(COLOR_RED);
+       glVertex2i(windX, 0);
+       SetColor(COLOR_GREEN);
+       glVertex2i(windX, windY);
+       SetColor(COLOR_BLUE);
+       glVertex2i(0, windY);
+    glEnd();
+
+    glFlush();
+
+    if (doubleBuffer) {
+       glutSwapBuffers();
+    }
+}
+
+static GLenum Args(int argc, char **argv)
+{
+    GLint i;
+
+    rgb = GL_TRUE;
+    doubleBuffer = GL_FALSE;
+
+    for (i = 1; i < argc; i++) {
+       if (strcmp(argv[i], "-ci") == 0) {
+           rgb = GL_FALSE;
+       } else if (strcmp(argv[i], "-rgb") == 0) {
+           rgb = GL_TRUE;
+       } else if (strcmp(argv[i], "-sb") == 0) {
+           doubleBuffer = GL_FALSE;
+       } else if (strcmp(argv[i], "-db") == 0) {
+           doubleBuffer = GL_TRUE;
+       } else {
+           printf("%s (Bad option).\n", argv[i]);
+           return GL_FALSE;
+       }
+    }
+    return GL_TRUE;
+}
+
+int main(int argc, char **argv)
+{
+    glutInit(&argc, argv);
+
+    if (Args(argc, argv) == GL_FALSE) {
+       exit(1);
+    }
+
+    windX = 300;
+    windY = 300;
+    glutInitWindowPosition(0, 0); glutInitWindowSize( windX, windY);
+
+    windType = (rgb) ? GLUT_RGB : GLUT_INDEX;
+    windType |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
+    glutInitDisplayMode(windType);
+
+    if (glutCreateWindow("Cursor Test") == GL_FALSE) {
+       exit(1);
+    }
+
+    InitMap();
+
+    Init();
+
+    glutReshapeFunc(Reshape);
+    glutKeyboardFunc(Key);
+    glutDisplayFunc(Draw);
+    glutMainLoop();
+       return 0;
+}
diff --git a/progs/samples/depth.c b/progs/samples/depth.c
new file mode 100644 (file)
index 0000000..afe2ec1
--- /dev/null
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the name of
+ * Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
+ * ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <GL/glut.h>
+
+
+#define CI_OFFSET_1 16
+#define CI_OFFSET_2 32
+
+
+GLenum rgb, doubleBuffer;
+
+GLenum antiAlias, stipple;
+GLubyte stippleBits[32*4] = {
+    0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+    0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+    0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+    0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+    0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+    0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+    0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+    0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+    0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+    0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+    0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+    0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+    0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+    0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+    0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+    0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+};
+
+
+#include "tkmap.c"
+
+static void Init(void)
+{
+    GLint i;
+
+    glClearColor(0.0, 0.0, 0.0, 0.0);
+    glClearIndex(0.0);
+
+    if (!rgb) {
+       for (i = 0; i < 16; i++) {
+           glutSetColor(i+CI_OFFSET_1, 0.0, 0.0, i/15.0);
+           glutSetColor(i+CI_OFFSET_2, 0.0, i/15.0, 0.0);
+       }
+    }
+
+    glPolygonStipple(stippleBits);
+
+    antiAlias = GL_FALSE;
+    stipple = GL_FALSE;
+}
+
+static void Reshape(int width, int height)
+{
+
+    glViewport(0, 0, (GLint)width, (GLint)height);
+
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    glOrtho(-1.0, 1.0, -1.0, 1.0, -0.5, 1000.0);
+    glMatrixMode(GL_MODELVIEW);
+}
+
+static void Key(unsigned char key, int x, int y)
+{
+
+    switch (key) {
+      case 27:
+       exit(1);
+      case '1':
+       antiAlias = !antiAlias;
+       break;
+      case '2':
+       stipple = !stipple;
+       break;
+      default:
+       return;
+    }
+
+    glutPostRedisplay();
+}
+
+static void Draw(void)
+{
+    GLint ci1, ci2;
+
+    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+
+    if (antiAlias) {
+       ci1 = CI_OFFSET_1;
+       ci2 = CI_OFFSET_2;
+       glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+       glEnable(GL_BLEND);
+       glEnable(GL_POLYGON_SMOOTH);
+       glDisable(GL_DEPTH_TEST);
+    } else {
+       ci1 = COLOR_BLUE;
+       ci2 = COLOR_GREEN;
+       glDisable(GL_BLEND);
+       glDisable(GL_POLYGON_SMOOTH);
+       glEnable(GL_DEPTH_TEST);
+    }
+
+    if (stipple) {
+       glEnable(GL_POLYGON_STIPPLE);
+    } else {
+       glDisable(GL_POLYGON_STIPPLE);
+    }
+
+    glBegin(GL_TRIANGLES);
+       (rgb) ? glColor3fv(RGBMap[COLOR_BLUE]) : glIndexi(ci1);
+       glVertex3f( 0.9, -0.9, -30.0);
+       glVertex3f( 0.9,  0.9, -30.0);
+       glVertex3f(-0.9,  0.0, -30.0);
+       (rgb) ? glColor3fv(RGBMap[COLOR_GREEN]) : glIndexi(ci2);
+       glVertex3f(-0.9, -0.9, -40.0);
+       glVertex3f(-0.9,  0.9, -40.0);
+       glVertex3f( 0.9,  0.0, -25.0);
+    glEnd();
+
+    glFlush();
+
+    if (doubleBuffer) {
+       glutSwapBuffers();
+    }
+}
+
+static GLenum Args(int argc, char **argv)
+{
+    GLint i;
+
+    rgb = GL_TRUE;
+    doubleBuffer = GL_FALSE;
+
+    for (i = 1; i < argc; i++) {
+       if (strcmp(argv[i], "-ci") == 0) {
+           rgb = GL_FALSE;
+       } else if (strcmp(argv[i], "-rgb") == 0) {
+           rgb = GL_TRUE;
+       } else if (strcmp(argv[i], "-sb") == 0) {
+           doubleBuffer = GL_FALSE;
+       } else if (strcmp(argv[i], "-db") == 0) {
+           doubleBuffer = GL_TRUE;
+       } else {
+           printf("%s (Bad option).\n", argv[i]);
+           return GL_FALSE;
+       }
+    }
+    return GL_TRUE;
+}
+
+int main(int argc, char **argv)
+{
+    GLenum type;
+
+    glutInit(&argc, argv);
+
+    if (Args(argc, argv) == GL_FALSE) {
+       exit(1);
+    }
+
+    glutInitWindowPosition(0, 0); glutInitWindowSize( 300, 300);
+
+    type = GLUT_DEPTH;
+    type |= (rgb) ? GLUT_RGB : GLUT_INDEX;
+    type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
+    glutInitDisplayMode(type);
+
+    if (glutCreateWindow("Depth Test") == GL_FALSE) {
+       exit(1);
+    }
+
+    InitMap();
+
+    Init();
+
+    glutReshapeFunc(Reshape);
+    glutKeyboardFunc(Key);
+    glutDisplayFunc(Draw);
+    glutMainLoop();
+       return 0;
+}
diff --git a/progs/samples/eval.c b/progs/samples/eval.c
new file mode 100644 (file)
index 0000000..3ad9c54
--- /dev/null
@@ -0,0 +1,472 @@
+/*
+ * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the name of
+ * Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
+ * ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+#include <GL/glut.h>
+
+
+#define VORDER 10
+#define CORDER 10
+#define TORDER 3
+
+#define VMAJOR_ORDER 2
+#define VMINOR_ORDER 3
+
+#define CMAJOR_ORDER 2
+#define CMINOR_ORDER 2
+
+#define TMAJOR_ORDER 2
+#define TMINOR_ORDER 2
+
+#define VDIM 4
+#define CDIM 4
+#define TDIM 2
+
+#define ONE_D 1
+#define TWO_D 2
+
+#define EVAL 3
+#define MESH 4
+
+
+GLenum doubleBuffer;
+
+float rotX = 0.0, rotY = 0.0, translateZ = -1.0;
+
+GLenum arrayType = ONE_D;
+GLenum colorType = GL_FALSE;
+GLenum textureType = GL_FALSE;
+GLenum polygonFilled = GL_FALSE;
+GLenum lighting = GL_FALSE;
+GLenum mapPoint = GL_FALSE;
+GLenum mapType = EVAL;
+
+double point1[10*4] = {
+    -0.5, 0.0, 0.0, 1.0,
+    -0.4, 0.5, 0.0, 1.0,
+    -0.3,-0.5, 0.0, 1.0,
+    -0.2, 0.5, 0.0, 1.0,
+    -0.1,-0.5, 0.0, 1.0,
+    0.0, 0.5, 0.0, 1.0,
+    0.1,-0.5, 0.0, 1.0,
+    0.2, 0.5, 0.0, 1.0,
+    0.3,-0.5, 0.0, 1.0,
+    0.4, 0.0, 0.0, 1.0,
+};
+double cpoint1[10*4] = {
+    0.0, 0.0, 1.0, 1.0,
+    0.3, 0.0, 0.7, 1.0,
+    0.6, 0.0, 0.3, 1.0,
+    1.0, 0.0, 0.0, 1.0,
+    1.0, 0.3, 0.0, 1.0,
+    1.0, 0.6, 0.0, 1.0,
+    1.0, 1.0, 0.0, 1.0,
+    1.0, 1.0, 0.5, 1.0,
+    1.0, 1.0, 1.0, 1.0,
+};
+double tpoint1[11*4] = {
+    0.0, 0.0, 0.0, 1.0,
+    0.0, 0.1, 0.0, 1.0,
+    0.0, 0.2, 0.0, 1.0,
+    0.0, 0.3, 0.0, 1.0,
+    0.0, 0.4, 0.0, 1.0,
+    0.0, 0.5, 0.0, 1.0,
+    0.0, 0.6, 0.0, 1.0,
+    0.0, 0.7, 0.0, 1.0,
+    0.0, 0.8, 0.0, 1.0,
+    0.0, 0.9, 0.0, 1.0,
+};
+double point2[2*3*4] = {
+    -0.5, -0.5,  0.5, 1.0, 
+     0.0,  1.0,  0.5, 1.0, 
+     0.5, -0.5,  0.5, 1.0,
+    -0.5,  0.5, -0.5, 1.0, 
+     0.0, -1.0, -0.5, 1.0, 
+     0.5,  0.5, -0.5, 1.0,
+};
+double cpoint2[2*2*4] = {
+    0.0, 0.0, 0.0, 1.0,
+    0.0, 0.0, 1.0, 1.0,
+    0.0, 1.0, 0.0, 1.0,
+    1.0, 1.0, 1.0, 1.0,
+};
+double tpoint2[2*2*2] = {
+    0.0, 0.0, 0.0, 1.0,
+    1.0, 0.0, 1.0, 1.0, 
+};
+float textureImage[4*2*4] =  {
+    1.0, 1.0, 1.0, 1.0,
+    1.0, 0.0, 0.0, 1.0,
+    1.0, 0.0, 0.0, 1.0,
+    1.0, 1.0, 1.0, 1.0, 
+    1.0, 1.0, 1.0, 1.0,
+    1.0, 0.0, 0.0, 1.0,
+    1.0, 0.0, 0.0, 1.0,
+    1.0, 1.0, 1.0, 1.0, 
+};
+
+
+static void Init(void)
+{
+    static float ambient[] = {0.1, 0.1, 0.1, 1.0};
+    static float diffuse[] = {1.0, 1.0, 1.0, 1.0};
+    static float position[] = {0.0, 0.0, -150.0, 0.0};
+    static float front_mat_diffuse[] = {1.0, 0.2, 1.0, 1.0};
+    static float back_mat_diffuse[] = {1.0, 1.0, 0.2, 1.0};
+    static float lmodel_ambient[] = {1.0, 1.0, 1.0, 1.0};
+    static float lmodel_twoside[] = {GL_TRUE};
+    static float decal[] = {GL_DECAL};
+    static float repeat[] = {GL_REPEAT};
+    static float nr[] = {GL_NEAREST};
+
+    glFrontFace(GL_CCW);
+
+    glEnable(GL_DEPTH_TEST);
+
+    glMap1d(GL_MAP1_VERTEX_4, 0.0, 1.0, VDIM, VORDER, point1);
+    glMap1d(GL_MAP1_COLOR_4, 0.0, 1.0, CDIM, CORDER, cpoint1);
+
+    glMap2d(GL_MAP2_VERTEX_4, 0.0, 1.0, VMINOR_ORDER*VDIM, VMAJOR_ORDER, 0.0,
+           1.0, VDIM, VMINOR_ORDER, point2);
+    glMap2d(GL_MAP2_COLOR_4, 0.0, 1.0, CMINOR_ORDER*CDIM, CMAJOR_ORDER, 0.0,
+           1.0, CDIM, CMINOR_ORDER, cpoint2);
+    glMap2d(GL_MAP2_TEXTURE_COORD_2, 0.0, 1.0, TMINOR_ORDER*TDIM,
+           TMAJOR_ORDER, 0.0, 1.0, TDIM, TMINOR_ORDER, tpoint2);
+
+    glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
+    glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
+    glLightfv(GL_LIGHT0, GL_POSITION, position);
+    
+    glMaterialfv(GL_FRONT, GL_DIFFUSE, front_mat_diffuse);
+    glMaterialfv(GL_BACK, GL_DIFFUSE, back_mat_diffuse);
+
+    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
+    glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
+
+    glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, decal);
+    glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, repeat);
+    glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, repeat);
+    glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, nr);
+    glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, nr);
+    glTexImage2D(GL_TEXTURE_2D, 0, 4, 2, 4, 0, GL_RGBA, GL_FLOAT,
+                (GLvoid *)textureImage);
+}
+
+static void DrawPoints1(void)
+{
+    GLint i;
+
+    glColor3f(0.0, 1.0, 0.0);
+    glPointSize(2);
+    glBegin(GL_POINTS);
+       for (i = 0; i < VORDER; i++) {
+           glVertex4dv(&point1[i*4]);
+       }
+    glEnd();
+}
+
+static void DrawPoints2(void)
+{
+    GLint i, j;
+
+    glColor3f(1.0, 0.0, 1.0);
+    glPointSize(2);
+    glBegin(GL_POINTS);
+       for (i = 0; i < VMAJOR_ORDER; i++) {
+           for (j = 0; j < VMINOR_ORDER; j++) {
+               glVertex4dv(&point2[i*4*VMINOR_ORDER+j*4]);
+           }
+       }
+    glEnd();
+}
+
+static void DrawMapEval1(float du)
+{
+    float u;
+
+    glColor3f(1.0, 0.0, 0.0);
+    glBegin(GL_LINE_STRIP);
+       for (u = 0.0; u < 1.0; u += du) {
+           glEvalCoord1d(u);
+       }
+       glEvalCoord1d(1.0);
+    glEnd();
+}
+
+static void DrawMapEval2(float du, float dv)
+{
+    float u, v, tmp;
+
+    glColor3f(1.0, 0.0, 0.0);
+    for (v = 0.0; v < 1.0; v += dv) {
+       glBegin(GL_QUAD_STRIP);
+           for (u = 0.0; u <= 1.0; u += du) {
+               glEvalCoord2d(u,v);
+               tmp = (v + dv < 1.0) ? (v + dv) : 1.0;
+               glEvalCoord2d(u, tmp);
+           }
+           glEvalCoord2d(1.0, v);
+           glEvalCoord2d(1.0, v+dv);
+       glEnd();
+    }
+}
+
+static void RenderEval(void)
+{
+
+    if (colorType) {
+       glEnable(GL_MAP1_COLOR_4);
+       glEnable(GL_MAP2_COLOR_4);
+    } else {
+       glDisable(GL_MAP1_COLOR_4);
+       glDisable(GL_MAP2_COLOR_4);
+    }
+
+    if (textureType) {
+       glEnable(GL_TEXTURE_2D);
+       glEnable(GL_MAP2_TEXTURE_COORD_2);
+    } else {
+       glDisable(GL_TEXTURE_2D);
+       glDisable(GL_MAP2_TEXTURE_COORD_2);
+    }
+
+    if (polygonFilled) {
+       glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+    } else {
+       glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+    }
+
+    glShadeModel(GL_SMOOTH);
+
+    switch (mapType) {
+      case EVAL:
+       switch (arrayType) {
+         case ONE_D:
+           glDisable(GL_MAP2_VERTEX_4);
+           glEnable(GL_MAP1_VERTEX_4);
+           DrawPoints1();
+           DrawMapEval1(0.1/VORDER);
+           break;
+         case TWO_D:
+           glDisable(GL_MAP1_VERTEX_4);
+           glEnable(GL_MAP2_VERTEX_4);
+           DrawPoints2();
+           DrawMapEval2(0.1/VMAJOR_ORDER,0.1/VMINOR_ORDER);
+           break;
+          default:
+            break;
+       }
+       break;
+      case MESH:
+       switch (arrayType) {
+         case ONE_D:
+           DrawPoints1();
+           glDisable(GL_MAP2_VERTEX_4);
+           glEnable (GL_MAP1_VERTEX_4);
+           glColor3f(0.0, 0.0, 1.0);
+           glMapGrid1d(40, 0.0, 1.0);
+           if (mapPoint) {
+               glPointSize(2);
+               glEvalMesh1(GL_POINT, 0, 40);
+           } else {
+               glEvalMesh1(GL_LINE, 0, 40);
+           }
+           break;
+         case TWO_D:
+           DrawPoints2();
+           glDisable(GL_MAP1_VERTEX_4);
+           glEnable(GL_MAP2_VERTEX_4);
+           glColor3f(0.0, 0.0, 1.0);
+           glMapGrid2d(20, 0.0, 1.0, 20, 0.0, 1.0);
+           if (mapPoint) {
+               glPointSize(2);
+               glEvalMesh2(GL_POINT, 0, 20, 0, 20);
+           } else if (polygonFilled) {
+               glEvalMesh2(GL_FILL, 0, 20, 0, 20);
+           } else {
+               glEvalMesh2(GL_LINE, 0, 20, 0, 20);
+           }
+           break;
+          default:
+            break;
+       }
+       break;
+      default:
+        break;
+    }
+}
+
+static void Reshape(int width, int height)
+{
+
+    glViewport(0, 0, (GLint)width, (GLint)height);
+
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    glOrtho(-1.0, 1.0, -1.0, 1.0, -0.5, 10.0);
+    glMatrixMode(GL_MODELVIEW);
+}
+
+static void Key2(int key, int x, int y)
+{
+    switch (key) {
+      case GLUT_KEY_LEFT:
+       rotY -= 30;
+       break;
+      case GLUT_KEY_RIGHT:
+       rotY += 30;
+       break;
+      case GLUT_KEY_UP:
+       rotX -= 30;
+       break;
+      case GLUT_KEY_DOWN:
+       rotX += 30;
+       break;
+      default:
+       return;
+    }
+
+    glutPostRedisplay();
+}
+
+static void Key(unsigned char key, int x, int y)
+{
+    switch (key) {
+      case 27:
+       exit(1);
+      case '1':
+       arrayType = ONE_D;
+       break;
+      case '2':
+       arrayType = TWO_D;
+       break;
+      case 'e':
+       mapType = EVAL;
+       break;
+      case 'm':
+       mapType = MESH;
+       break;
+      case 'f':
+       polygonFilled = !polygonFilled;
+       break;
+      case 'p':
+       mapPoint = !mapPoint;
+       break;
+      case 'c':
+       colorType = !colorType;
+       break;
+      case 't':
+       textureType = !textureType;
+       break;
+      case 'l':
+       lighting =! lighting;
+       if (lighting) {
+           glEnable(GL_LIGHTING);
+           glEnable(GL_LIGHT0);
+           glEnable(GL_AUTO_NORMAL);
+       } else {
+           glDisable(GL_LIGHTING);
+           glDisable(GL_LIGHT0);
+           glDisable(GL_AUTO_NORMAL);
+       }
+       break;
+      default:
+       return;
+    }
+
+    glutPostRedisplay();
+}
+
+static void Draw(void)
+{
+
+    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+
+    glPushMatrix();
+
+    glTranslatef(0.0, 0.0 , translateZ);
+    glRotatef(rotX, 1, 0, 0);
+    glRotatef(rotY, 0, 1, 0);
+    RenderEval();
+
+    glPopMatrix();
+
+    glFlush();
+
+    if (doubleBuffer) {
+       glutSwapBuffers();
+    }
+}
+
+static GLenum Args(int argc, char **argv)
+{
+    GLint i;
+
+    doubleBuffer = GL_FALSE;
+
+    for (i = 1; i < argc; i++) {
+       if (strcmp(argv[i], "-sb") == 0) {
+           doubleBuffer = GL_FALSE;
+       } else if (strcmp(argv[i], "-db") == 0) {
+           doubleBuffer = GL_TRUE;
+       } else {
+           printf("%s (Bad option).\n", argv[i]);
+           return GL_FALSE;
+       }
+    }
+    return GL_TRUE;
+}
+
+int main(int argc, char **argv)
+{
+    GLenum type;
+
+    glutInit(&argc, argv);
+
+    if (Args(argc, argv) == GL_FALSE) {
+       exit(1);
+    }
+
+    glutInitWindowPosition(0, 0); glutInitWindowSize( 300, 300);
+
+    type = GLUT_RGB | GLUT_DEPTH;
+    type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
+    glutInitDisplayMode(type);
+
+    if (glutCreateWindow("Evaluator Test") == GL_FALSE) {
+       exit(1);
+    }
+
+    Init();
+
+    glutReshapeFunc(Reshape);
+    glutKeyboardFunc(Key);
+    glutSpecialFunc(Key2);
+    glutDisplayFunc(Draw);
+    glutMainLoop();
+       return 0;
+}
diff --git a/progs/samples/fog.c b/progs/samples/fog.c
new file mode 100644 (file)
index 0000000..96534dd
--- /dev/null
@@ -0,0 +1,311 @@
+/*
+ * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the name of
+ * Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
+ * ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <GL/glut.h>
+
+GLenum rgb, doubleBuffer;
+
+#include "tkmap.c"
+
+double plane[4] = {
+    1.0, 0.0, -1.0, 0.0
+};
+float rotX = 5.0, rotY = -5.0, zTranslate = -65.0;
+float fogDensity = 0.02;
+GLint cubeList = 1;
+
+float scp[18][3] = {
+    {
+       1.000000, 0.000000, 0.000000
+    }, 
+    {
+       1.000000, 0.000000, 5.000000
+    },
+    {
+       0.707107, 0.707107, 0.000000
+    }, 
+    {
+       0.707107, 0.707107, 5.000000
+    },
+    {
+       0.000000, 1.000000, 0.000000
+    }, 
+    {
+       0.000000, 1.000000, 5.000000
+    },
+    {
+       -0.707107, 0.707107, 0.000000
+    }, 
+    {
+       -0.707107, 0.707107, 5.000000
+    },
+    {
+       -1.000000, 0.000000, 0.000000
+    }, 
+    {
+       -1.000000, 0.000000, 5.000000
+    },
+    {
+       -0.707107, -0.707107, 0.000000
+    }, 
+    {
+       -0.707107, -0.707107, 5.000000
+    },
+    {
+       0.000000, -1.000000, 0.000000
+    }, 
+    {
+       0.000000, -1.000000, 5.000000
+    },
+    {
+       0.707107, -0.707107, 0.000000
+    }, 
+    {
+       0.707107, -0.707107, 5.000000
+    },
+    {
+       1.000000, 0.000000, 0.000000
+    }, 
+    {
+       1.000000, 0.000000, 5.000000
+    },
+};
+
+
+static void Build_lists(void)
+{
+
+    glNewList(cubeList, GL_COMPILE);
+       glBegin(GL_TRIANGLE_STRIP);
+          glNormal3fv(scp[0]); glVertex3fv(scp[0]);
+          glNormal3fv(scp[0]); glVertex3fv(scp[1]);
+          glNormal3fv(scp[2]); glVertex3fv(scp[2]);
+          glNormal3fv(scp[2]); glVertex3fv(scp[3]);
+          glNormal3fv(scp[4]); glVertex3fv(scp[4]);
+          glNormal3fv(scp[4]); glVertex3fv(scp[5]);
+          glNormal3fv(scp[6]); glVertex3fv(scp[6]);
+          glNormal3fv(scp[6]); glVertex3fv(scp[7]);
+          glNormal3fv(scp[8]); glVertex3fv(scp[8]);
+          glNormal3fv(scp[8]); glVertex3fv(scp[9]);
+          glNormal3fv(scp[10]); glVertex3fv(scp[10]);
+          glNormal3fv(scp[10]); glVertex3fv(scp[11]);
+          glNormal3fv(scp[12]); glVertex3fv(scp[12]);
+          glNormal3fv(scp[12]); glVertex3fv(scp[13]);
+          glNormal3fv(scp[14]); glVertex3fv(scp[14]);
+          glNormal3fv(scp[14]); glVertex3fv(scp[15]);
+          glNormal3fv(scp[16]); glVertex3fv(scp[16]);
+          glNormal3fv(scp[16]); glVertex3fv(scp[17]);
+       glEnd();
+    glEndList();
+}
+
+static void Init(void)
+{
+    static float ambient[] = {0.1, 0.1, 0.1, 1.0};
+    static float diffuse[] = {1.0, 1.0, 1.0, 1.0};
+    static float position[] = {90.0, 90.0, 0.0, 0.0};
+    static float front_mat_shininess[] = {30.0};
+    static float front_mat_specular[] = {0.0, 0.0, 0.0, 1.0};
+    static float front_mat_diffuse[] = {0.0, 1.0, 0.0, 1.0};
+    static float back_mat_shininess[] = {50.0};
+    static float back_mat_specular[] = {0.0, 0.0, 1.0, 1.0};
+    static float back_mat_diffuse[] = {1.0, 0.0, 0.0, 1.0};
+    static float lmodel_ambient[] = {0.0, 0.0, 0.0, 1.0};
+    static float fog_color[] = {0.8, 0.8, 0.8, 1.0};
+    
+    glFrontFace(GL_CW);
+
+    glEnable(GL_DEPTH_TEST);
+
+    glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
+    glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
+    glLightfv(GL_LIGHT0, GL_POSITION, position);
+    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
+    glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
+    glEnable(GL_LIGHTING);
+    glEnable(GL_LIGHT0);
+    
+    glMaterialfv(GL_FRONT, GL_SHININESS, front_mat_shininess);
+    glMaterialfv(GL_FRONT, GL_SPECULAR, front_mat_specular);
+    glMaterialfv(GL_FRONT, GL_DIFFUSE, front_mat_diffuse);
+    glMaterialfv(GL_BACK, GL_SHININESS, back_mat_shininess);
+    glMaterialfv(GL_BACK, GL_SPECULAR, back_mat_specular);
+    glMaterialfv(GL_BACK, GL_DIFFUSE, back_mat_diffuse);
+
+    glEnable(GL_FOG);
+    glFogi(GL_FOG_MODE, GL_EXP);
+    glFogf(GL_FOG_DENSITY, fogDensity);
+    if (rgb) {
+       glFogfv(GL_FOG_COLOR, fog_color);
+       glClearColor(0.8, 0.8, 0.8, 1.0);
+    } else {
+       glFogi(GL_FOG_INDEX, 1<<5);
+       SetFogRamp(5, 3);
+       glClearIndex(128);
+    }
+
+    Build_lists();
+}
+
+static void Reshape(int width, int height)
+{
+
+    glViewport(0, 0, (GLint)width, (GLint)height);
+
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    gluPerspective(45.0, 1.0, 1.0, 200.0);
+    glMatrixMode(GL_MODELVIEW);
+}
+
+static void Key2(int key, int x, int y)
+{
+
+    switch (key) {
+      case GLUT_KEY_UP:
+       rotX -= 5;
+       break;
+      case GLUT_KEY_DOWN:
+       rotX += 5;
+       break;
+      case GLUT_KEY_LEFT:
+       rotY -= 5;
+       break;
+      case GLUT_KEY_RIGHT:
+       rotY += 5;
+       break;
+      default:
+       return;
+    }
+
+    glutPostRedisplay();
+}
+
+static void Key(unsigned char key, int x, int y)
+{
+
+    switch (key) {
+      case 27:
+       exit(1);
+      case 'D':
+       if (rgb) {
+           fogDensity *= 1.10;
+           glFogf(GL_FOG_DENSITY, fogDensity);
+       }
+       break;
+      case 'd':
+       if (rgb) {
+           fogDensity /= 1.10;
+           glFogf(GL_FOG_DENSITY, fogDensity);
+       }
+       break;
+      default:
+       return;
+    }
+
+    glutPostRedisplay();
+}
+
+static void Draw(void)
+{
+
+    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+
+    glPushMatrix();
+
+    glTranslatef(0, 0, zTranslate);
+    glRotatef(rotY, 0,1,0);
+    glRotatef(rotX, 1,0,0);
+    glScalef(1.0, 1.0, 10.0);
+
+    glCallList(cubeList);
+
+    glPopMatrix();
+
+    glFlush();
+
+    if (doubleBuffer) {
+       glutSwapBuffers();
+    }
+}
+
+static GLenum Args(int argc, char **argv)
+{
+    GLint i;
+
+    rgb = GL_TRUE;
+    doubleBuffer = GL_FALSE;
+
+    for (i = 1; i < argc; i++) {
+       if (strcmp(argv[i], "-ci") == 0) {
+           rgb = GL_FALSE;
+       } else if (strcmp(argv[i], "-rgb") == 0) {
+           rgb = GL_TRUE;
+       } else if (strcmp(argv[i], "-sb") == 0) {
+           doubleBuffer = GL_FALSE;
+       } else if (strcmp(argv[i], "-db") == 0) {
+           doubleBuffer = GL_TRUE;
+       } else {
+           printf("%s (Bad option).\n", argv[i]);
+           return GL_FALSE;
+       }
+    }
+    return GL_TRUE;
+}
+
+int main(int argc, char **argv)
+{
+    GLenum type;
+
+    glutInit(&argc, argv);
+
+    if (Args(argc, argv) == GL_FALSE) {
+       exit(1);
+    }
+
+    glutInitWindowPosition(0, 0); glutInitWindowSize( 300, 300);
+
+    type = GLUT_DEPTH;
+    type |= (rgb) ? GLUT_RGB : GLUT_INDEX;
+    type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
+    glutInitDisplayMode(type);
+
+    if (glutCreateWindow("Fog Test") == GL_FALSE) {
+       exit(1);
+    }
+
+    InitMap();
+
+    Init();
+
+    glutReshapeFunc(Reshape);
+    glutKeyboardFunc(Key);
+    glutSpecialFunc(Key2);
+    glutDisplayFunc(Draw);
+    glutMainLoop();
+       return 0;
+}
diff --git a/progs/samples/font.c b/progs/samples/font.c
new file mode 100644 (file)
index 0000000..a0091a6
--- /dev/null
@@ -0,0 +1,273 @@
+/*
+ * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the name of
+ * Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
+ * ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <GL/glut.h>
+
+
+#define OPENGL_WIDTH 24
+#define OPENGL_HEIGHT 13
+
+
+char string[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz";
+GLenum rgb, doubleBuffer, windType;
+float angleX = 0.0, angleY = 0.0, angleZ = 0.0;
+float scaleX = 1.0, scaleY = 1.0, scaleZ = 1.0;
+float shiftX = 0.0, shiftY = 0.0, shiftZ = 0.0;
+
+
+#include "tkmap.c"
+
+
+static void DrawBitmapString(void *font, const char *string)
+{
+    int i;
+
+    for (i = 0; string[i]; i++)
+       glutBitmapCharacter(font, string[i]);
+}
+
+static void DrawStrokeString(void *font, const char *string)
+{
+    int i;
+
+    for (i = 0; string[i]; i++)
+       glutStrokeCharacter(font, string[i]);
+}
+
+static void Init(void)
+{
+
+    glClearColor(0.0, 0.0, 0.0, 0.0);
+    glClearIndex(0.0);
+}
+
+static void Reshape(int width, int height)
+{
+
+    glViewport(0, 0, (GLint)width, (GLint)height);
+
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    glOrtho(-400.0, 400.0, -200.0, 200.0, -400.0, 400.0);
+    glMatrixMode(GL_MODELVIEW);
+}
+
+static void Key2(int key, int x, int y)
+{
+
+    switch (key) {
+      case GLUT_KEY_LEFT:
+       shiftX -= 20.0;
+       break;
+      case GLUT_KEY_RIGHT:
+       shiftX += 20.0;
+       break;
+      case GLUT_KEY_UP:
+       shiftY += 20.0;
+       break;
+      case GLUT_KEY_DOWN:
+       shiftY -= 20.0;
+       break;
+      default:
+       return;
+    }
+
+    glutPostRedisplay();
+}
+
+static void Key(unsigned char key, int x, int y)
+{
+
+    switch (key) {
+      case 27:
+        exit(1);
+
+      case 'n':
+       shiftZ += 20.0;
+       break;
+      case 'm':
+       shiftZ -= 20.0;
+       break;
+
+      case 'q':
+       scaleX -= 0.1;
+       if (scaleX < 0.1) {
+           scaleX = 0.1;
+       }
+       break;
+      case 'w':
+       scaleX += 0.1;
+       break;
+      case 'a':
+       scaleY -= 0.1;
+       if (scaleY < 0.1) {
+           scaleY = 0.1;
+       }
+       break;
+      case 's':
+       scaleY += 0.1;
+       break;
+      case 'z':
+       scaleZ -= 0.1;
+       if (scaleZ < 0.1) {
+           scaleZ = 0.1;
+       }
+       break;
+      case 'x':
+       scaleZ += 0.1;
+       break;
+
+      case 'e':
+       angleX -= 5.0;
+       if (angleX < 0.0) {
+           angleX = 360.0 + angleX;
+       }
+       break;
+      case 'r':
+       angleX += 5.0;
+       if (angleX > 360.0) {
+           angleX = angleX - 360.0;
+       }
+       break;
+      case 'd':
+       angleY -= 5.0;
+       if (angleY < 0.0) {
+           angleY = 360.0 + angleY;
+       }
+       break;
+      case 'f':
+       angleY += 5.0;
+       if (angleY > 360.0) {
+           angleY = angleY - 360.0;
+       }
+       break;
+      case 'c':
+       angleZ -= 5.0;
+       if (angleZ < 0.0) {
+           angleZ = 360.0 + angleZ;
+       }
+       break;
+      case 'v':
+       angleZ += 5.0;
+       if (angleZ > 360.0) {
+           angleZ = angleZ - 360.0;
+       }
+       break;
+      default:
+       return;
+    }
+
+    glutPostRedisplay();
+}
+
+static void Draw(void)
+{
+
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    SetColor(COLOR_WHITE);
+
+    glPushMatrix();
+
+    glTranslatef(shiftX, shiftY, shiftZ);
+    glRotatef(angleX, 1.0, 0.0, 0.0);
+    glRotatef(angleY, 0.0, 1.0, 0.0);
+    glRotatef(angleZ, 0.0, 0.0, 1.0);
+    glScalef(scaleX, scaleY, scaleZ);
+
+    glPushMatrix();
+    glRasterPos2f(-390.5, 0.5);
+    DrawBitmapString(GLUT_BITMAP_9_BY_15, string);
+    glPopMatrix();
+
+    glPushMatrix();
+    glTranslatef(-390.5, -30.5, 0.0);
+    DrawStrokeString(GLUT_STROKE_ROMAN, string);
+    glPopMatrix();
+
+    glPopMatrix();
+
+    glFlush();
+
+    if (doubleBuffer) {
+       glutSwapBuffers();
+    }
+}
+
+static GLenum Args(int argc, char **argv)
+{
+    GLint i;
+
+    rgb = GL_TRUE;
+    doubleBuffer = GL_FALSE;
+
+    for (i = 1; i < argc; i++) {
+       if (strcmp(argv[i], "-ci") == 0) {
+           rgb = GL_FALSE;
+       } else if (strcmp(argv[i], "-rgb") == 0) {
+           rgb = GL_TRUE;
+       } else if (strcmp(argv[i], "-sb") == 0) {
+           doubleBuffer = GL_FALSE;
+       } else if (strcmp(argv[i], "-db") == 0) {
+           doubleBuffer = GL_TRUE;
+       } else {
+           printf("%s (Bad option).\n", argv[i]);
+           return GL_FALSE;
+       }
+    }
+    return GL_TRUE;
+}
+
+int main(int argc, char **argv)
+{
+    glutInit(&argc, argv);
+
+    if (Args(argc, argv) == GL_FALSE) {
+       exit(1);
+    }
+
+    glutInitWindowPosition(0, 0); glutInitWindowSize( 800, 400);
+
+    windType = (rgb) ? GLUT_RGB : GLUT_INDEX;
+    windType |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
+    glutInitDisplayMode(windType);
+
+    if (glutCreateWindow("Font Test") == GL_FALSE) {
+       exit(1);
+    }
+
+    InitMap();
+
+    Init();
+
+    glutReshapeFunc(Reshape);
+    glutKeyboardFunc(Key);
+    glutSpecialFunc(Key2);
+    glutDisplayFunc(Draw);
+    glutMainLoop();
+       return 0;
+}
diff --git a/progs/samples/line.c b/progs/samples/line.c
new file mode 100644 (file)
index 0000000..59e1d62
--- /dev/null
@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the name of
+ * Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
+ * ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <GL/glut.h>
+
+
+#define CI_OFFSET 16
+
+
+GLenum rgb, doubleBuffer, windType;
+
+GLenum mode1, mode2;
+GLint size;
+float pntA[3] = {
+    -160.0, 0.0, 0.0
+};
+float pntB[3] = {
+    -130.0, 0.0, 0.0
+};
+float pntC[3] = {
+    -40.0, -50.0, 0.0
+};
+float pntD[3] = {
+    30.0, 60.0, 0.0
+};
+
+
+#include "tkmap.c"
+
+static void Init(void)
+{
+    GLint i;
+
+    glClearColor(0.0, 0.0, 0.0, 0.0);
+
+    glLineStipple(1, 0xF0E0);
+    glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+
+    if (!rgb) {
+       for (i = 0; i < 16; i++) {
+           glutSetColor(i+CI_OFFSET, i/15.0, i/15.0, 0.0);
+       }
+    }
+
+    mode1 = GL_FALSE;
+    mode2 = GL_FALSE;
+    size = 1;
+}
+
+static void Reshape(int width, int height)
+{
+
+    glViewport(0, 0, (GLint)width, (GLint)height);
+
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    gluOrtho2D(-175, 175, -175, 175);
+    glMatrixMode(GL_MODELVIEW);
+}
+
+static void Key(unsigned char key, int x, int y)
+{
+
+    switch (key) {
+      case 27:
+       exit(1);
+      case '1':
+       mode1 = !mode1;
+       break;
+      case '2':
+       mode2 = !mode2;
+       break;
+      case 'W':
+       size++;
+       break;
+      case 'w':
+       size--;
+       if (size < 1) {
+           size = 1;
+       }
+       break;
+      default:
+       return;
+    }
+
+    glutPostRedisplay();
+}
+
+static void Draw(void)
+{
+    GLint ci, i;
+
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    glLineWidth(size);
+
+    if (mode1) {
+       glEnable(GL_LINE_STIPPLE);
+    } else {
+       glDisable(GL_LINE_STIPPLE);
+    }
+    
+    if (mode2) {
+       ci = CI_OFFSET;
+       glEnable(GL_LINE_SMOOTH);
+       glEnable(GL_BLEND);
+    } else {
+       ci = COLOR_YELLOW;
+       glDisable(GL_LINE_SMOOTH);
+       glDisable(GL_BLEND);
+    }
+
+    glPushMatrix();
+
+    glShadeModel( GL_FLAT );
+
+    for (i = 0; i < 360; i += 5) {
+       glRotatef(5.0, 0,0,1);
+
+       (rgb) ? glColor3f(1.0, 1.0, 0.0) : glIndexi(ci);
+       glBegin(GL_LINE_STRIP);
+           glVertex3fv(pntA);
+           glVertex3fv(pntB);
+       glEnd();
+
+       glPointSize(1);
+
+       SetColor(COLOR_GREEN);
+       glBegin(GL_POINTS);
+           glVertex3fv(pntA);
+           glVertex3fv(pntB);
+       glEnd();
+    }
+
+    glPopMatrix();
+
+    glFlush();
+
+    if (doubleBuffer) {
+       glutSwapBuffers();
+    }
+}
+
+static GLenum Args(int argc, char **argv)
+{
+    GLint i;
+
+    rgb = GL_TRUE;
+    doubleBuffer = GL_FALSE;
+
+    for (i = 1; i < argc; i++) {
+       if (strcmp(argv[i], "-ci") == 0) {
+           rgb = GL_FALSE;
+       } else if (strcmp(argv[i], "-rgb") == 0) {
+           rgb = GL_TRUE;
+       } else if (strcmp(argv[i], "-sb") == 0) {
+           doubleBuffer = GL_FALSE;
+       } else if (strcmp(argv[i], "-db") == 0) {
+           doubleBuffer = GL_TRUE;
+       } else {
+           printf("%s (Bad option).\n", argv[i]);
+           return GL_FALSE;
+       }
+    }
+    return GL_TRUE;
+}
+
+int main(int argc, char **argv)
+{
+    glutInit(&argc, argv);
+
+    if (Args(argc, argv) == GL_FALSE) {
+       exit(1);
+    }
+
+    glutInitWindowPosition(0, 0); glutInitWindowSize( 300, 300);
+
+    windType = (rgb) ? GLUT_RGB : GLUT_INDEX;
+    windType |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
+    glutInitDisplayMode(windType);
+
+    if (glutCreateWindow("Line Test") == GL_FALSE) {
+       exit(1);
+    }
+
+    InitMap();
+
+    Init();
+
+    glutReshapeFunc(Reshape);
+    glutKeyboardFunc(Key);
+    glutDisplayFunc(Draw);
+    glutMainLoop();
+       return 0;
+}
diff --git a/progs/samples/loadppm.c b/progs/samples/loadppm.c
new file mode 100644 (file)
index 0000000..bf7c8dd
--- /dev/null
@@ -0,0 +1,72 @@
+
+typedef struct {
+    int sizeX, sizeY;
+    GLubyte *data;
+} PPMImage;
+
+static PPMImage *LoadPPM(const char *filename)
+{
+    char buff[16];
+    PPMImage *result;
+    FILE *fp;
+    int maxval;
+
+    fp = fopen(filename, "rb");
+    if (!fp)
+    {
+       fprintf(stderr, "Unable to open file `%s'\n", filename);
+       exit(1);
+    }
+
+    if (!fgets(buff, sizeof(buff), fp))
+    {
+       perror(filename);
+       exit(1);
+    }
+
+    if (buff[0] != 'P' || buff[1] != '6')
+    {
+       fprintf(stderr, "Invalid image format (must be `P6')\n");
+       exit(1);
+    }
+
+    result = malloc(sizeof(PPMImage));
+    if (!result)
+    {
+       fprintf(stderr, "Unable to allocate memory\n");
+       exit(1);
+    }
+
+    if (fscanf(fp, "%d %d", &result->sizeX, &result->sizeY) != 2)
+    {
+       fprintf(stderr, "Error loading image `%s'\n", filename);
+       exit(1);
+    }
+
+    if (fscanf(fp, "%d", &maxval) != 1)
+    {
+       fprintf(stderr, "Error loading image `%s'\n", filename);
+       exit(1);
+    }
+
+    while (fgetc(fp) != '\n')
+       ;
+
+    result->data = malloc(3 * result->sizeX * result->sizeY);
+    if (!result)
+    {
+       fprintf(stderr, "Unable to allocate memory\n");
+       exit(1);
+    }
+
+    if (fread(result->data, 3 * result->sizeX, result->sizeY, fp) != result->sizeY)
+    {
+       fprintf(stderr, "Error loading image `%s'\n", filename);
+       exit(1);
+    }
+
+    fclose(fp);
+
+    return result;
+}
+
diff --git a/progs/samples/logo.c b/progs/samples/logo.c
new file mode 100644 (file)
index 0000000..8f7de45
--- /dev/null
@@ -0,0 +1,1630 @@
+/* $Id: logo.c,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the name of
+ * Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
+ * ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <GL/glut.h>
+
+
+#define PI 3.141592654
+
+#define        BLACK 0
+#define        GRAY 128
+#define        WHITE 255
+#define BL 0x00
+#define WH 0xFF
+#define RD 0xA4,0x00,0x00,0xFF
+#define WT 0xFF,0xFF,0xFF,0xFF
+
+#define        CHECKIMAGEWIDTH 8
+#define        CHECKIMAGEHEIGHT 8
+#define        BRICKIMAGEWIDTH 16
+#define        BRICKIMAGEHEIGHT 16
+
+
+GLenum rgb, doubleBuffer;
+
+#include "tkmap.c"
+
+float black[3] = {0.0, 0.0, 0.0};
+float white[3] = {1.0, 1.0, 1.0};
+float gray[3] = {0.5, 0.5, 0.5};
+float blue[3] = {0.0, 0.0, 1.0};
+GLint colorIndexes[3] = {0, 200, 255};
+
+GLenum polyMode;
+GLboolean dithering;
+GLboolean shade;
+GLboolean doStipple;
+GLboolean noDraw = 0;
+GLboolean LineSmooth = GL_FALSE;
+
+double plane[4] = {1.0, 0.0, -1.0, 0.0};
+float xRotation = 30.0, yRotation = 30.0;
+float zTranslation = -15.0;
+
+GLint singleCylinder;
+GLint doubleCylinder;
+GLint elbow, logo;
+
+GLubyte checkImage[3*CHECKIMAGEWIDTH*CHECKIMAGEHEIGHT] = {
+    BL, BL, BL, WH, WH, WH, BL, BL, BL, WH, WH, WH, BL, BL, BL, WH,
+    WH, WH, BL, BL, BL, WH, WH, WH, WH, WH, WH, BL, BL, BL, WH, WH,
+    WH, BL, BL, BL, WH, WH, WH, BL, BL, BL, WH, WH, WH, BL, BL, BL,
+    BL, BL, BL, WH, WH, WH, BL, BL, BL, WH, WH, WH, BL, BL, BL, WH,
+    WH, WH, BL, BL, BL, WH, WH, WH, WH, WH, WH, BL, BL, BL, WH, WH,
+    WH, BL, BL, BL, WH, WH, WH, BL, BL, BL, WH, WH, WH, BL, BL, BL,
+    BL, BL, BL, WH, WH, WH, BL, BL, BL, WH, WH, WH, BL, BL, BL, WH,
+    WH, WH, BL, BL, BL, WH, WH, WH, WH, WH, WH, BL, BL, BL, WH, WH,
+    WH, BL, BL, BL, WH, WH, WH, BL, BL, BL, WH, WH, WH, BL, BL, BL,
+    BL, BL, BL, WH, WH, WH, BL, BL, BL, WH, WH, WH, BL, BL, BL, WH,
+    WH, WH, BL, BL, BL, WH, WH, WH, WH, WH, WH, BL, BL, BL, WH, WH,
+    WH, BL, BL, BL, WH, WH, WH, BL, BL, BL, WH, WH, WH, BL, BL, BL, 
+};
+GLubyte brickImage[4*BRICKIMAGEWIDTH*BRICKIMAGEHEIGHT] = {
+    RD, RD, RD, RD, RD, RD, RD, RD, RD, WT, RD, RD, RD, RD, RD, RD,
+    RD, RD, RD, RD, RD, RD, RD, RD, RD, WT, RD, RD, RD, RD, RD, RD,
+    RD, RD, RD, RD, RD, RD, RD, RD, RD, WT, RD, RD, RD, RD, RD, RD,
+    RD, RD, RD, RD, RD, RD, RD, RD, RD, WT, RD, RD, RD, RD, RD, RD,
+    WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT,
+    RD, RD, RD, WT, RD, RD, RD, RD, RD, RD, RD, RD, RD, WT, RD, RD,
+    RD, RD, RD, WT, RD, RD, RD, RD, RD, RD, RD, RD, RD, WT, RD, RD,
+    RD, RD, RD, WT, RD, RD, RD, RD, RD, RD, RD, RD, RD, WT, RD, RD,
+    RD, RD, RD, WT, RD, RD, RD, RD, RD, RD, RD, RD, RD, WT, RD, RD,
+    WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT,
+    RD, RD, RD, RD, RD, RD, RD, WT, RD, RD, RD, RD, RD, RD, RD, RD,
+    RD, RD, RD, RD, RD, RD, RD, WT, RD, RD, RD, RD, RD, RD, RD, RD,
+    RD, RD, RD, RD, RD, RD, RD, WT, RD, RD, RD, RD, RD, RD, RD, RD,
+    RD, RD, RD, RD, RD, RD, RD, WT, RD, RD, RD, RD, RD, RD, RD, RD,
+    WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT,
+    RD, RD, RD, RD, WT, RD, RD, RD, RD, RD, RD, RD, RD, RD, WT, RD
+};
+
+GLubyte *image = checkImage;
+GLint imageHeight = CHECKIMAGEHEIGHT;
+GLint imageWidth = CHECKIMAGEWIDTH;
+
+float decal[] = {
+    GL_DECAL,
+};
+float modulate[] = {
+    GL_MODULATE,
+};
+float repeat[] = {
+    GL_REPEAT,
+};
+float nearest[] = {
+    GL_NEAREST,
+};
+
+GLubyte stipple[4*32] = {
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+
+    0x00, 0x0F, 0xF0, 0x00,
+    0x00, 0x0F, 0xF0, 0x00,
+    0x00, 0x0F, 0xF0, 0x00,
+    0x00, 0x0F, 0xF0, 0x00,
+    0x00, 0x0F, 0xF0, 0x00,
+    0x00, 0x0F, 0xF0, 0x00,
+    0x00, 0x0F, 0xF0, 0x00,
+    0x00, 0x0F, 0xF0, 0x00,
+
+    0x00, 0x0F, 0xF0, 0x00,
+    0x00, 0x0F, 0xF0, 0x00,
+    0x00, 0x0F, 0xF0, 0x00,
+    0x00, 0x0F, 0xF0, 0x00,
+    0x00, 0x0F, 0xF0, 0x00,
+    0x00, 0x0F, 0xF0, 0x00,
+    0x00, 0x0F, 0xF0, 0x00,
+    0x00, 0x0F, 0xF0, 0x00,
+
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+};
+
+float tscp[18][2] = {
+    {
+       0.0, 0.0
+    },
+    {
+       1.0, 0.0
+    },
+    {
+       0.0, 0.125
+    },
+    {
+       1.0, 0.125
+    },
+    {
+       0.0, 0.250
+    },
+    {
+       1.0, 0.25
+    },
+    {
+       0.0, 0.375
+    },
+    {
+       1.0, 0.375
+    },
+    {
+       0.0, 0.50
+    },
+    {
+       1.0, 0.50
+    },
+    {
+       0.0, 0.625
+    },
+    {
+       1.0, 0.625
+    },
+    {
+       0.0, 0.75
+    },
+    {
+       1.0, 0.75
+    },
+    {
+       0.0, 0.875
+    },
+    {
+       1.0, 0.875
+    },
+    {
+       0.0, 1.0
+    },
+    {
+       1.0, 1.0
+    }
+};
+float scp[18][3] = {
+    {
+       1.000000, 0.000000, 0.000000
+    },
+    {
+       1.000000, 0.000000, 5.000000
+    },
+    {
+       0.707107, 0.707107, 0.000000
+    },
+    {
+       0.707107, 0.707107, 5.000000
+    },
+    {
+       0.000000, 1.000000, 0.000000
+    },
+    {
+       0.000000, 1.000000, 5.000000
+    },
+    {
+       -0.707107, 0.707107, 0.000000
+    },
+    {
+       -0.707107, 0.707107, 5.000000
+    },
+    {
+       -1.000000, 0.000000, 0.000000
+    },
+    {
+       -1.000000, 0.000000, 5.000000
+    },
+    {
+       -0.707107, -0.707107, 0.000000
+    },
+    {
+       -0.707107, -0.707107, 5.000000
+    },
+    {
+       0.000000, -1.000000, 0.000000
+    },
+    {
+       0.000000, -1.000000, 5.000000
+    },
+    {
+       0.707107, -0.707107, 0.000000
+    },
+    {
+       0.707107, -0.707107, 5.000000
+    },
+    {
+       1.000000, 0.000000, 0.000000
+    },
+    {
+       1.000000, 0.000000, 5.000000
+    }
+};
+float dcp[18][3] = {
+    {
+       1.000000, 0.000000, 0.000000
+    },
+    {
+       1.000000, 0.000000, 7.000000
+    },
+    {
+       0.707107, 0.707107, 0.000000
+    },
+    {
+       0.707107, 0.707107, 7.000000
+    },
+    {
+       0.000000, 1.000000, 0.000000
+    },
+    {
+       0.000000, 1.000000, 7.000000
+    },
+    {
+       -0.707107, 0.707107, 0.000000
+    },
+    {
+       -0.707107, 0.707107, 7.000000
+    },
+    {
+       -1.000000, 0.000000, 0.000000
+    },
+    {
+       -1.000000, 0.000000, 7.000000
+    },
+    {
+       -0.707107, -0.707107, 0.000000
+    },
+    {
+       -0.707107, -0.707107, 7.000000
+    },
+    {
+       0.000000, -1.000000, 0.000000
+    },
+    {
+       0.000000, -1.000000, 7.000000
+    },
+    {
+       0.707107, -0.707107, 0.000000
+    },
+    {
+       0.707107, -0.707107, 7.000000
+    },
+    {
+       1.000000, 0.000000, 0.000000
+    },
+    {
+       1.000000, 0.000000, 7.000000
+    }
+};
+float ep[7][9][3] = {
+    {
+       {
+           1.000000, 0.000000, 0.000000
+       },
+       {
+           0.707107, 0.707107, 0.000000
+       },
+       {
+           0.000000, 1.000000, 0.000000
+       },
+       {
+           -0.707107, 0.707107, 0.000000
+       },
+       {
+           -1.000000, 0.000000, 0.000000
+       },
+       {
+           -0.707107, -0.707107, 0.000000
+       },
+       {
+           0.000000, -1.000000, 0.000000
+       },
+       {
+           0.707107, -0.707107, 0.000000
+       },
+       {
+           1.000000, 0.000000, 0.000000
+       }
+    },
+    {
+       {
+           1.000000, 0.034074, 0.258819
+       },
+       {
+           0.707107, 0.717087, 0.075806
+       },
+       {
+           0.000000, 1.000000, 0.000000
+       },
+       {
+           -0.707107, 0.717087, 0.075806
+       },
+       {
+           -1.000000, 0.034074, 0.258819
+       },
+       {
+           -0.707107, -0.648939, 0.441832
+       },
+       {
+           0.000000, -0.931852, 0.517638
+       },
+       {
+           0.707107, -0.648939, 0.441832
+       },
+       {
+           1.000000, 0.034074, 0.258819
+       }
+    },
+    {
+       {
+           1.000000, 0.133975, 0.500000
+       },
+       {
+           0.707107, 0.746347, 0.146447
+       },
+       {
+           0.000000, 1.000000, 0.000000
+       },
+       {
+           -0.707107, 0.746347, 0.146447
+       },
+       {
+           -1.000000, 0.133975, 0.500000
+       },
+       {
+           -0.707107, -0.478398, 0.853553
+       },
+       {
+           0.000000, -0.732051, 1.000000
+       },
+       {
+           0.707107, -0.478398, 0.853553
+       },
+       {
+           1.000000, 0.133975, 0.500000
+       }
+    },
+    {
+       {
+           1.000000, 0.292893, 0.707107
+       },
+       {
+           0.707107, 0.792893, 0.207107
+       },
+       {
+           0.000000, 1.000000, 0.000000
+       },
+       {
+           -0.707107, 0.792893, 0.207107
+       },
+       {
+           -1.000000, 0.292893, 0.707107
+       },
+       {
+           -0.707107, -0.207107, 1.207107
+       },
+       {
+           0.000000, -0.414214, 1.414214
+       },
+       {
+           0.707107, -0.207107, 1.207107
+       },
+       {
+           1.000000, 0.292893, 0.707107
+       }
+    },
+    {
+       {
+           1.000000, 0.500000, 0.866025
+       },
+       {
+           0.707107, 0.853553, 0.253653
+       },
+       {
+           0.000000, 1.000000, 0.000000
+       },
+       {
+           -0.707107, 0.853553, 0.253653
+       },
+       {
+           -1.000000, 0.500000, 0.866025
+       },
+       {
+           -0.707107, 0.146447, 1.478398
+       },
+       {
+           0.000000, 0.000000, 1.732051
+       },
+       {
+           0.707107, 0.146447, 1.478398
+       },
+       {
+           1.000000, 0.500000, 0.866025
+       }
+    },
+    {
+       {
+           1.000000, 0.741181, 0.965926
+       },
+       {
+           0.707107, 0.924194, 0.282913
+       },
+       {
+           0.000000, 1.000000, 0.000000
+       },
+       {
+           -0.707107, 0.924194, 0.282913
+       },
+       {
+           -1.000000, 0.741181, 0.965926
+       },
+       {
+           -0.707107, 0.558168, 1.648939
+       },
+       {
+           0.000000, 0.482362, 1.931852
+       },
+       {
+           0.707107, 0.558168, 1.648939
+       },
+       {
+           1.000000, 0.741181, 0.965926
+       }
+    },
+    {
+       {
+           1.000000, 1.000000, 1.000000
+       },
+       {
+           0.707107, 1.000000, 0.292893
+       },
+       {
+           0.000000, 1.000000, 0.000000
+       },
+       {
+           -0.707107, 1.000000, 0.292893
+       },
+       {
+           -1.000000, 1.000000, 1.000000
+       },
+       {
+           -0.707107, 1.000000, 1.707107
+       },
+       {
+           0.000000, 1.000000, 2.000000
+       },
+       {
+           0.707107, 1.000000, 1.707107
+       },
+       {
+           1.000000, 1.000000, 1.000000
+       }
+    }
+};
+float en[7][9][3] = {
+    {
+       {
+           1.000000, 0.000000, 0.000000
+       },
+       {
+           0.707107, 0.707107, 0.000000
+       },
+       {
+           0.000000, 1.000000, 0.000000
+       },
+       {
+           -0.707107, 0.707107, 0.000000
+       },
+       {
+           -1.000000, 0.000000, 0.000000
+       },
+       {
+           -0.707107, -0.707107, 0.000000
+       },
+       {
+           0.000000, -1.000000, 0.000000
+       },
+       {
+           0.707107, -0.707107, 0.000000
+       },
+       {
+           1.000000, 0.000000, 0.000000
+       }
+    },
+    {
+       {
+           1.000000, 0.000000, 0.000000
+       },
+       {
+           0.707107, 0.683013, -0.183013
+       },
+       {
+           0.000000, 0.965926, -0.258819
+       },
+       {
+           -0.707107, 0.683013, -0.183013
+       },
+       {
+           -1.000000, 0.000000, 0.000000
+       },
+       {
+           -0.707107, -0.683013, 0.183013
+       },
+       {
+           0.000000, -0.965926, 0.258819
+       },
+       {
+           0.707107, -0.683013, 0.183013
+       },
+       {
+           1.000000, 0.000000, 0.000000
+       }
+    },
+    {
+       {
+           1.000000, 0.000000, 0.000000
+       },
+       {
+           0.707107, 0.612372, -0.353553
+       },
+       {
+           0.000000, 0.866025, -0.500000
+       },
+       {
+           -0.707107, 0.612372, -0.353553
+       },
+       {
+           -1.000000, 0.000000, 0.000000
+       },
+       {
+           -0.707107, -0.612372, 0.353553
+       },
+       {
+           0.000000, -0.866025, 0.500000
+       },
+       {
+           0.707107, -0.612372, 0.353553
+       },
+       {
+           1.000000, 0.000000, 0.000000
+       }
+    },
+    {
+       {
+           1.000000, 0.000000, 0.000000
+       },
+       {
+          /* These 3 lines added by BEP */
+           0.707107, 0.500000, -0.500000
+       },
+       {
+           0.000000, 0.707107, -0.707107
+       },
+       {
+           -0.707107, 0.500000, -0.500000
+       },
+       {
+           -1.000000, 0.000000, 0.000000
+       },
+       {
+           -0.707107, -0.500000, 0.500000
+       },
+       {
+           0.000000, -0.707107, 0.707107
+       },
+       {
+           0.707107, -0.500000, 0.500000
+       },
+       {
+           1.000000, 0.000000, 0.000000
+       }
+    },
+    {
+       {
+           1.000000, 0.000000, 0.000000
+       },
+       {
+           0.707107, 0.353553, -0.612372
+       },
+       {
+           0.000000, 0.500000, -0.866025
+       },
+       {
+           -0.707107, 0.353553, -0.612372
+       },
+       {
+           -1.000000, 0.000000, 0.000000
+       },
+       {
+           -0.707107, -0.353553, 0.612372
+       },
+       {
+           0.000000, -0.500000, 0.866025
+       },
+       {
+           0.707107, -0.353553, 0.612372
+       },
+       {
+           1.000000, 0.000000, 0.000000
+       }
+    },
+    {
+       {
+           1.000000, 0.000000, 0.000000
+       },
+       {
+           0.707107, 0.183013, -0.683013
+       },
+       {
+           0.000000, 0.258819, -0.965926
+       },
+       {
+           -0.707107, 0.183013, -0.683013
+       },
+       {
+           -1.000000, 0.000000, 0.000000
+       },
+       {
+           -0.707107, -0.183013, 0.683013
+       },
+       {
+           0.000000, -0.258819, 0.965926
+       },
+       {
+           0.707107, -0.183013, 0.683013
+       },
+       {
+           1.000000, 0.000000, 0.000000
+       }
+    },
+    {
+       {
+           1.000000, 0.000000, 0.000000
+       },
+       {
+           0.707107, 0.000000, -0.707107
+       },
+       {
+           0.000000, 0.000000, -1.000000
+       },
+       {
+           -0.707107, 0.000000, -0.707107
+       },
+       {
+           -1.000000, 0.000000, 0.000000
+       },
+       {
+           -0.707107, 0.000000, 0.707107
+       },
+       {
+           0.000000, 0.000000, 1.000000
+       },
+       {
+           0.707107, 0.000000, 0.707107
+       },
+       {
+           1.000000, 0.000000, 0.000000
+       }
+    }
+};
+float tep[7][9][2] = {
+    {
+       {
+           0,     0.0
+       },
+       {
+           0.125, 0.0
+       },
+       {
+           0.25,  0.0
+       },
+       {
+           0.375, 0.0
+       },
+       {
+           0.5,   0.0
+       },
+       {
+           0.625, 0.0
+       },
+       {
+           0.75,  0.0
+       },
+       {
+           0.875, 0.0
+       },
+       {
+           1.0,   0.0
+       }
+    },
+    {
+       {
+           0,     0.16667
+       },
+       {
+           0.125, 0.16667
+       },
+       {
+           0.25,  0.16667
+       },
+       {
+           0.375, 0.16667
+       },
+       {
+           0.5,   0.16667
+       },
+       {
+           0.625, 0.16667
+       },
+       {
+           0.75,  0.16667
+       },
+       {
+           0.875, 0.16667
+       },
+       {
+           1.0,   0.16667
+       }
+    },
+    {
+       {
+           0,     0.33333
+       },
+       {
+           0.125, 0.33333
+       },
+       {
+           0.25,  0.33333
+       },
+       {
+           0.375, 0.33333
+       },
+       {
+           0.5,   0.33333
+       },
+       {
+           0.625, 0.33333
+       },
+       {
+           0.75,  0.33333
+       },
+       {
+           0.875, 0.33333
+       },
+       {
+           1.0,   0.33333
+       }
+    },
+    {
+       {
+           0,     0.5
+       },
+       {
+           0.125, 0.5
+       },
+       {
+           0.25,  0.5
+       },
+       {
+           0.375, 0.5
+       },
+       {
+           0.5,   0.5
+       },
+       {
+           0.625, 0.5
+       },
+       {
+           0.75,  0.5
+       },
+       {
+           0.875, 0.5
+       },
+       {
+           1.0,   0.5
+       }
+    },
+    {
+       {
+           0,     0.6667
+       },
+       {
+           0.125, 0.6667
+       },
+       {
+           0.25,  0.6667
+       },
+       {
+           0.375, 0.6667
+       },
+       {
+           0.5,   0.6667
+       },
+       {
+           0.625, 0.6667
+       },
+       {
+           0.75,  0.6667
+       },
+       {
+           0.875, 0.6667
+       },
+       {
+           1.0,   0.6667
+       }
+    },
+    {
+       {
+           0,     0.83333
+       },
+       {
+           0.125, 0.83333
+       },
+       {
+           0.25,  0.83333
+       },
+       {
+           0.375, 0.83333
+       },
+       {
+           0.5,   0.83333
+       },
+       {
+           0.625, 0.83333
+       },
+       {
+           0.75,  0.83333
+       },
+       {
+           0.875, 0.83333
+       },
+       {
+           1.0,   0.83333
+       }
+    },
+    {
+       {
+           0,     1.0
+       },
+       {
+           0.125, 1.0
+       },
+       {
+           0.25,  1.0
+       },
+       {
+           0.375, 1.0
+       },
+       {
+           0.5,   1.0
+       },
+       {
+           0.625, 1.0
+       },
+       {
+           0.75,  1.0
+       },
+       {
+           0.875, 1.0
+       },
+       {
+           1.0,   1.0
+       }
+    }
+};
+
+
+static void SetUpAntiAliasedGrayScale(void)
+{
+    float color;
+    GLint i, j;
+
+    for (i = 0; i < 16; i++) {
+       color = (2 * i + 1) / 32.0;
+       for (j = 0; j < 16; j++) {
+           glutSetColor(i*16+j, color*j/15.0, color*j/15.0, color*j/15.0);
+       }
+    }
+}
+
+static void BendForward(void)
+{
+
+    glTranslatef(0.0, 1.0, 0.0);
+    glRotatef(90.0, 1, 0, 0);
+    glTranslatef(0.0, -1.0, 0.0);
+}
+
+static void BendLeft(void)
+{
+
+    glRotatef(-90.0, 0, 0, 1);
+    glTranslatef(0.0, 1.0, 0.0);
+    glRotatef(90.0, 1, 0, 0);
+    glTranslatef(0.0, -1.0, 0.0);
+}
+
+static void BendRight(void)
+{
+
+    glRotatef(90.0, 0, 0, 1);
+    glTranslatef(0.0, 1.0, 0.0);
+    glRotatef(90.0, 1, 0, 0);
+    glTranslatef(0.0, -1.0, 0.0);
+}
+
+static void BuildSingleCylinder(void)
+{
+
+    glNewList(singleCylinder, GL_COMPILE);
+
+    glBegin(GL_TRIANGLE_STRIP);
+       glNormal3fv(scp[0]); glTexCoord2fv(tscp[0]); glVertex3fv(scp[0]);
+       glNormal3fv(scp[0]); glTexCoord2fv(tscp[1]); glVertex3fv(scp[1]);
+       glNormal3fv(scp[2]); glTexCoord2fv(tscp[2]); glVertex3fv(scp[2]);
+       glNormal3fv(scp[2]); glTexCoord2fv(tscp[3]); glVertex3fv(scp[3]);
+       glNormal3fv(scp[4]); glTexCoord2fv(tscp[4]); glVertex3fv(scp[4]);
+       glNormal3fv(scp[4]); glTexCoord2fv(tscp[5]); glVertex3fv(scp[5]);
+       glNormal3fv(scp[6]); glTexCoord2fv(tscp[6]); glVertex3fv(scp[6]);
+       glNormal3fv(scp[6]); glTexCoord2fv(tscp[7]); glVertex3fv(scp[7]);
+       glNormal3fv(scp[8]); glTexCoord2fv(tscp[8]); glVertex3fv(scp[8]);
+       glNormal3fv(scp[8]); glTexCoord2fv(tscp[9]); glVertex3fv(scp[9]);
+       glNormal3fv(scp[10]); glTexCoord2fv(tscp[10]); glVertex3fv(scp[10]);
+       glNormal3fv(scp[10]); glTexCoord2fv(tscp[11]); glVertex3fv(scp[11]);
+       glNormal3fv(scp[12]); glTexCoord2fv(tscp[12]); glVertex3fv(scp[12]);
+       glNormal3fv(scp[12]); glTexCoord2fv(tscp[13]); glVertex3fv(scp[13]);
+       glNormal3fv(scp[14]); glTexCoord2fv(tscp[14]); glVertex3fv(scp[14]);
+       glNormal3fv(scp[14]); glTexCoord2fv(tscp[15]); glVertex3fv(scp[15]);
+       glNormal3fv(scp[16]); glTexCoord2fv(tscp[16]); glVertex3fv(scp[16]);
+       glNormal3fv(scp[16]); glTexCoord2fv(tscp[17]); glVertex3fv(scp[17]);
+    glEnd();
+
+    glEndList();
+}
+
+static void BuildDoubleCylinder(void)
+{
+
+    glNewList(doubleCylinder, GL_COMPILE);
+
+    glBegin(GL_TRIANGLE_STRIP);
+       glNormal3fv(dcp[0]); glTexCoord2fv(tscp[0]); glVertex3fv(dcp[0]);
+       glNormal3fv(dcp[0]); glTexCoord2fv(tscp[1]); glVertex3fv(dcp[1]);
+       glNormal3fv(dcp[2]); glTexCoord2fv(tscp[2]); glVertex3fv(dcp[2]);
+       glNormal3fv(dcp[2]); glTexCoord2fv(tscp[3]); glVertex3fv(dcp[3]);
+       glNormal3fv(dcp[4]); glTexCoord2fv(tscp[4]); glVertex3fv(dcp[4]);
+       glNormal3fv(dcp[4]); glTexCoord2fv(tscp[5]); glVertex3fv(dcp[5]);
+       glNormal3fv(dcp[6]); glTexCoord2fv(tscp[6]); glVertex3fv(dcp[6]);
+       glNormal3fv(dcp[6]); glTexCoord2fv(tscp[7]); glVertex3fv(dcp[7]);
+       glNormal3fv(dcp[8]); glTexCoord2fv(tscp[8]); glVertex3fv(dcp[8]);
+       glNormal3fv(dcp[8]); glTexCoord2fv(tscp[9]); glVertex3fv(dcp[9]);
+       glNormal3fv(dcp[10]); glTexCoord2fv(tscp[10]); glVertex3fv(dcp[10]);
+       glNormal3fv(dcp[10]); glTexCoord2fv(tscp[11]); glVertex3fv(dcp[11]);
+       glNormal3fv(dcp[12]); glTexCoord2fv(tscp[12]); glVertex3fv(dcp[12]);
+       glNormal3fv(dcp[12]); glTexCoord2fv(tscp[13]); glVertex3fv(dcp[13]);
+       glNormal3fv(dcp[14]); glTexCoord2fv(tscp[14]); glVertex3fv(dcp[14]);
+       glNormal3fv(dcp[14]); glTexCoord2fv(tscp[15]); glVertex3fv(dcp[15]);
+       glNormal3fv(dcp[16]); glTexCoord2fv(tscp[16]); glVertex3fv(dcp[16]);
+       glNormal3fv(dcp[16]); glTexCoord2fv(tscp[17]); glVertex3fv(dcp[17]);
+    glEnd();
+
+    glEndList();
+}
+
+static void BuildElbow(void)
+{
+
+    glNewList(elbow, GL_COMPILE);
+
+    glBegin(GL_TRIANGLE_STRIP);
+       glNormal3fv(en[0][0]); glTexCoord2fv(tep[0][0]); glVertex3fv(ep[0][0]);
+       glNormal3fv(en[1][0]); glTexCoord2fv(tep[1][0]); glVertex3fv(ep[1][0]);
+       glNormal3fv(en[0][1]); glTexCoord2fv(tep[0][1]); glVertex3fv(ep[0][1]);
+       glNormal3fv(en[1][1]); glTexCoord2fv(tep[1][1]); glVertex3fv(ep[1][1]);
+       glNormal3fv(en[0][2]); glTexCoord2fv(tep[0][2]); glVertex3fv(ep[0][2]);
+       glNormal3fv(en[1][2]); glTexCoord2fv(tep[1][2]); glVertex3fv(ep[1][2]);
+       glNormal3fv(en[0][3]); glTexCoord2fv(tep[0][3]); glVertex3fv(ep[0][3]);
+       glNormal3fv(en[1][3]); glTexCoord2fv(tep[1][3]); glVertex3fv(ep[1][3]);
+       glNormal3fv(en[0][4]); glTexCoord2fv(tep[0][4]); glVertex3fv(ep[0][4]);
+       glNormal3fv(en[1][4]); glTexCoord2fv(tep[1][4]); glVertex3fv(ep[1][4]);
+       glNormal3fv(en[0][5]); glTexCoord2fv(tep[0][5]); glVertex3fv(ep[0][5]);
+       glNormal3fv(en[1][5]); glTexCoord2fv(tep[1][5]); glVertex3fv(ep[1][5]);
+       glNormal3fv(en[0][6]); glTexCoord2fv(tep[0][6]); glVertex3fv(ep[0][6]);
+       glNormal3fv(en[1][6]); glTexCoord2fv(tep[1][6]); glVertex3fv(ep[1][6]);
+       glNormal3fv(en[0][7]); glTexCoord2fv(tep[0][7]); glVertex3fv(ep[0][7]);
+       glNormal3fv(en[1][7]); glTexCoord2fv(tep[1][7]); glVertex3fv(ep[1][7]);
+       glNormal3fv(en[0][8]); glTexCoord2fv(tep[0][8]); glVertex3fv(ep[0][8]);
+       glNormal3fv(en[1][8]); glTexCoord2fv(tep[1][8]); glVertex3fv(ep[1][8]);
+    glEnd();
+    glBegin(GL_TRIANGLE_STRIP);
+       glNormal3fv(en[1][0]); glTexCoord2fv(tep[1][0]); glVertex3fv(ep[1][0]);
+       glNormal3fv(en[2][0]); glTexCoord2fv(tep[2][0]); glVertex3fv(ep[2][0]);
+       glNormal3fv(en[1][1]); glTexCoord2fv(tep[1][1]); glVertex3fv(ep[1][1]);
+       glNormal3fv(en[2][1]); glTexCoord2fv(tep[2][1]); glVertex3fv(ep[2][1]);
+       glNormal3fv(en[1][2]); glTexCoord2fv(tep[1][2]); glVertex3fv(ep[1][2]);
+       glNormal3fv(en[2][2]); glTexCoord2fv(tep[2][2]); glVertex3fv(ep[2][2]);
+       glNormal3fv(en[1][3]); glTexCoord2fv(tep[1][3]); glVertex3fv(ep[1][3]);
+       glNormal3fv(en[2][3]); glTexCoord2fv(tep[2][3]); glVertex3fv(ep[2][3]);
+       glNormal3fv(en[1][4]); glTexCoord2fv(tep[1][4]); glVertex3fv(ep[1][4]);
+       glNormal3fv(en[2][4]); glTexCoord2fv(tep[2][4]); glVertex3fv(ep[2][4]);
+       glNormal3fv(en[1][5]); glTexCoord2fv(tep[1][5]); glVertex3fv(ep[1][5]);
+       glNormal3fv(en[2][5]); glTexCoord2fv(tep[2][5]); glVertex3fv(ep[2][5]);
+       glNormal3fv(en[1][6]); glTexCoord2fv(tep[1][6]); glVertex3fv(ep[1][6]);
+       glNormal3fv(en[2][6]); glTexCoord2fv(tep[2][6]); glVertex3fv(ep[2][6]);
+       glNormal3fv(en[1][7]); glTexCoord2fv(tep[1][7]); glVertex3fv(ep[1][7]);
+       glNormal3fv(en[2][7]); glTexCoord2fv(tep[2][7]); glVertex3fv(ep[2][7]);
+       glNormal3fv(en[1][8]); glTexCoord2fv(tep[1][8]); glVertex3fv(ep[1][8]);
+       glNormal3fv(en[2][8]); glTexCoord2fv(tep[2][8]); glVertex3fv(ep[2][8]);
+    glEnd();
+    glBegin(GL_TRIANGLE_STRIP);
+       glNormal3fv(en[2][0]); glTexCoord2fv(tep[2][0]); glVertex3fv(ep[2][0]);
+       glNormal3fv(en[3][0]); glTexCoord2fv(tep[3][0]); glVertex3fv(ep[3][0]);
+       glNormal3fv(en[2][1]); glTexCoord2fv(tep[2][1]); glVertex3fv(ep[2][1]);
+       glNormal3fv(en[3][1]); glTexCoord2fv(tep[3][1]); glVertex3fv(ep[3][1]);
+       glNormal3fv(en[2][2]); glTexCoord2fv(tep[2][2]); glVertex3fv(ep[2][2]);
+       glNormal3fv(en[3][2]); glTexCoord2fv(tep[3][2]); glVertex3fv(ep[3][2]);
+       glNormal3fv(en[2][3]); glTexCoord2fv(tep[2][3]); glVertex3fv(ep[2][3]);
+       glNormal3fv(en[3][3]); glTexCoord2fv(tep[3][3]); glVertex3fv(ep[3][3]);
+       glNormal3fv(en[2][4]); glTexCoord2fv(tep[2][4]); glVertex3fv(ep[2][4]);
+       glNormal3fv(en[3][4]); glTexCoord2fv(tep[3][4]); glVertex3fv(ep[3][4]);
+       glNormal3fv(en[2][5]); glTexCoord2fv(tep[2][5]); glVertex3fv(ep[2][5]);
+       glNormal3fv(en[3][5]); glTexCoord2fv(tep[3][5]); glVertex3fv(ep[3][5]);
+       glNormal3fv(en[2][6]); glTexCoord2fv(tep[2][6]); glVertex3fv(ep[2][6]);
+       glNormal3fv(en[3][6]); glTexCoord2fv(tep[3][6]); glVertex3fv(ep[3][6]);
+       glNormal3fv(en[2][7]); glTexCoord2fv(tep[2][7]); glVertex3fv(ep[2][7]);
+       glNormal3fv(en[3][7]); glTexCoord2fv(tep[3][7]); glVertex3fv(ep[3][7]);
+       glNormal3fv(en[2][8]); glTexCoord2fv(tep[2][8]); glVertex3fv(ep[2][8]);
+       glNormal3fv(en[3][8]); glTexCoord2fv(tep[3][8]); glVertex3fv(ep[3][8]);
+    glEnd();
+    glBegin(GL_TRIANGLE_STRIP);
+       glNormal3fv(en[3][0]); glTexCoord2fv(tep[3][0]); glVertex3fv(ep[3][0]);
+       glNormal3fv(en[4][0]); glTexCoord2fv(tep[4][0]); glVertex3fv(ep[4][0]);
+       glNormal3fv(en[3][1]); glTexCoord2fv(tep[3][1]); glVertex3fv(ep[3][1]);
+       glNormal3fv(en[4][1]); glTexCoord2fv(tep[4][1]); glVertex3fv(ep[4][1]);
+       glNormal3fv(en[3][2]); glTexCoord2fv(tep[3][2]); glVertex3fv(ep[3][2]);
+       glNormal3fv(en[4][2]); glTexCoord2fv(tep[4][2]); glVertex3fv(ep[4][2]);
+       glNormal3fv(en[3][3]); glTexCoord2fv(tep[3][3]); glVertex3fv(ep[3][3]);
+       glNormal3fv(en[4][3]); glTexCoord2fv(tep[4][3]); glVertex3fv(ep[4][3]);
+       glNormal3fv(en[3][4]); glTexCoord2fv(tep[3][4]); glVertex3fv(ep[3][4]);
+       glNormal3fv(en[4][4]); glTexCoord2fv(tep[4][4]); glVertex3fv(ep[4][4]);
+       glNormal3fv(en[3][5]); glTexCoord2fv(tep[3][5]); glVertex3fv(ep[3][5]);
+       glNormal3fv(en[4][5]); glTexCoord2fv(tep[4][5]); glVertex3fv(ep[4][5]);
+       glNormal3fv(en[3][6]); glTexCoord2fv(tep[3][6]); glVertex3fv(ep[3][6]);
+       glNormal3fv(en[4][6]); glTexCoord2fv(tep[4][6]); glVertex3fv(ep[4][6]);
+       glNormal3fv(en[3][7]); glTexCoord2fv(tep[3][7]); glVertex3fv(ep[3][7]);
+       glNormal3fv(en[4][7]); glTexCoord2fv(tep[4][7]); glVertex3fv(ep[4][7]);
+       glNormal3fv(en[3][8]); glTexCoord2fv(tep[3][8]); glVertex3fv(ep[3][8]);
+       glNormal3fv(en[4][8]); glTexCoord2fv(tep[4][8]); glVertex3fv(ep[4][8]);
+    glEnd();
+    glBegin(GL_TRIANGLE_STRIP);
+       glNormal3fv(en[4][0]); glTexCoord2fv(tep[4][0]); glVertex3fv(ep[4][0]);
+       glNormal3fv(en[5][0]); glTexCoord2fv(tep[5][0]); glVertex3fv(ep[5][0]);
+       glNormal3fv(en[4][1]); glTexCoord2fv(tep[4][1]); glVertex3fv(ep[4][1]);
+       glNormal3fv(en[5][1]); glTexCoord2fv(tep[5][1]); glVertex3fv(ep[5][1]);
+       glNormal3fv(en[4][2]); glTexCoord2fv(tep[4][2]); glVertex3fv(ep[4][2]);
+       glNormal3fv(en[5][2]); glTexCoord2fv(tep[5][2]); glVertex3fv(ep[5][2]);
+       glNormal3fv(en[4][3]); glTexCoord2fv(tep[4][3]); glVertex3fv(ep[4][3]);
+       glNormal3fv(en[5][3]); glTexCoord2fv(tep[5][3]); glVertex3fv(ep[5][3]);
+       glNormal3fv(en[4][4]); glTexCoord2fv(tep[4][4]); glVertex3fv(ep[4][4]);
+       glNormal3fv(en[5][4]); glTexCoord2fv(tep[5][4]); glVertex3fv(ep[5][4]);
+       glNormal3fv(en[4][5]); glTexCoord2fv(tep[4][5]); glVertex3fv(ep[4][5]);
+       glNormal3fv(en[5][5]); glTexCoord2fv(tep[5][5]); glVertex3fv(ep[5][5]);
+       glNormal3fv(en[4][6]); glTexCoord2fv(tep[4][6]); glVertex3fv(ep[4][6]);
+       glNormal3fv(en[5][6]); glTexCoord2fv(tep[5][6]); glVertex3fv(ep[5][6]);
+       glNormal3fv(en[4][7]); glTexCoord2fv(tep[4][7]); glVertex3fv(ep[4][7]);
+       glNormal3fv(en[5][7]); glTexCoord2fv(tep[5][7]); glVertex3fv(ep[5][7]);
+       glNormal3fv(en[4][8]); glTexCoord2fv(tep[4][8]); glVertex3fv(ep[4][8]);
+       glNormal3fv(en[5][8]); glTexCoord2fv(tep[5][8]); glVertex3fv(ep[5][8]);
+    glEnd();
+    glBegin(GL_TRIANGLE_STRIP);
+       glNormal3fv(en[5][0]); glTexCoord2fv(tep[5][0]); glVertex3fv(ep[5][0]);
+       glNormal3fv(en[6][0]); glTexCoord2fv(tep[6][0]); glVertex3fv(ep[6][0]);
+       glNormal3fv(en[5][1]); glTexCoord2fv(tep[5][1]); glVertex3fv(ep[5][1]);
+       glNormal3fv(en[6][1]); glTexCoord2fv(tep[6][1]); glVertex3fv(ep[6][1]);
+       glNormal3fv(en[5][2]); glTexCoord2fv(tep[5][2]); glVertex3fv(ep[5][2]);
+       glNormal3fv(en[6][2]); glTexCoord2fv(tep[6][2]); glVertex3fv(ep[6][2]);
+       glNormal3fv(en[5][3]); glTexCoord2fv(tep[5][3]); glVertex3fv(ep[5][3]);
+       glNormal3fv(en[6][3]); glTexCoord2fv(tep[6][3]); glVertex3fv(ep[6][3]);
+       glNormal3fv(en[5][4]); glTexCoord2fv(tep[5][4]); glVertex3fv(ep[5][4]);
+       glNormal3fv(en[6][4]); glTexCoord2fv(tep[6][4]); glVertex3fv(ep[6][4]);
+       glNormal3fv(en[5][5]); glTexCoord2fv(tep[5][5]); glVertex3fv(ep[5][5]);
+       glNormal3fv(en[6][5]); glTexCoord2fv(tep[6][5]); glVertex3fv(ep[6][5]);
+       glNormal3fv(en[5][6]); glTexCoord2fv(tep[5][6]); glVertex3fv(ep[5][6]);
+       glNormal3fv(en[6][6]); glTexCoord2fv(tep[6][6]); glVertex3fv(ep[6][6]);
+       glNormal3fv(en[5][7]); glTexCoord2fv(tep[5][7]); glVertex3fv(ep[5][7]);
+       glNormal3fv(en[6][7]); glTexCoord2fv(tep[6][7]); glVertex3fv(ep[6][7]);
+       glNormal3fv(en[5][8]); glTexCoord2fv(tep[5][8]); glVertex3fv(ep[5][8]);
+       glNormal3fv(en[6][8]); glTexCoord2fv(tep[6][8]); glVertex3fv(ep[6][8]);
+    glEnd();
+
+    glEndList();
+}
+
+static void BuildLogo(void)
+{
+
+    glNewList(logo, GL_COMPILE);
+
+    glTranslatef(5.5, -3.5, 4.5);
+    glTranslatef(0.0, 0.0, -7.0);
+    glCallList(doubleCylinder);
+    BendForward();
+    glCallList(elbow);
+    glTranslatef(0.0, 0.0, -7.0);
+    glCallList(doubleCylinder);
+    BendForward();
+    glCallList(elbow);
+    glTranslatef(0.0, 0.0, -5.0);
+    glCallList(singleCylinder);
+    BendRight();
+    glCallList(elbow);
+    glTranslatef(0.0, 0.0, -7.0);
+    glCallList(doubleCylinder);
+    BendForward();
+    glCallList(elbow);
+    glTranslatef(0.0, 0.0, -7.0);
+    glCallList(doubleCylinder);
+    BendForward();
+    glCallList(elbow);
+    glTranslatef(0.0, 0.0, -5.0);
+    glCallList(singleCylinder);
+    BendLeft();
+    glCallList(elbow);
+    glTranslatef(0.0, 0.0, -7.0);
+    glCallList(doubleCylinder);
+    BendForward();
+    glCallList(elbow);
+    glTranslatef(0.0, 0.0, -7.0);
+    glCallList(doubleCylinder);
+    BendForward();
+    glCallList(elbow);
+    glTranslatef(0.0, 0.0, -5.0);
+    glCallList(singleCylinder);
+    BendRight();
+    glCallList(elbow);
+    glTranslatef(0.0, 0.0, -7.0);
+    glCallList(doubleCylinder);
+    BendForward();
+    glCallList(elbow);
+    glTranslatef(0.0, 0.0, -7.0);
+    glCallList(doubleCylinder);
+    BendForward();
+    glCallList(elbow);
+    glTranslatef(0.0, 0.0, -5.0);
+    glCallList(singleCylinder);
+    BendLeft();
+    glCallList(elbow);
+    glTranslatef(0.0, 0.0, -7.0);
+    glCallList(doubleCylinder);
+    BendForward();
+    glCallList(elbow);
+    glTranslatef(0.0, 0.0, -7.0);
+    glCallList(doubleCylinder);
+    BendForward();
+    glCallList(elbow);
+    glTranslatef(0.0, 0.0, -5.0);
+    glCallList(singleCylinder);
+    BendRight();
+    glCallList(elbow);
+    glTranslatef(0.0, 0.0, -7.0);
+    glCallList(doubleCylinder);
+    BendForward();
+    glCallList(elbow);
+    glTranslatef(0.0, 0.0, -7.0);
+    glCallList(doubleCylinder);
+    BendForward();
+    glCallList(elbow);
+    glTranslatef(0.0, 0.0, -5.0);
+    glCallList(singleCylinder);
+    BendLeft();
+    glCallList(elbow);
+
+    glEndList();
+}
+
+static void BuildLists(void)
+{
+
+    singleCylinder = glGenLists(1);
+    doubleCylinder = glGenLists(1);
+    elbow = glGenLists(1);
+    logo = glGenLists(1);
+
+    BuildSingleCylinder();
+    BuildDoubleCylinder();
+    BuildElbow();
+    BuildLogo();
+}
+
+static void Init(void)
+{
+    static float ambient[] = {0.1, 0.1, 0.1, 1.0};
+    static float diffuse[] = {0.5, 1.0, 1.0, 1.0};
+    static float position[] = {90.0, 90.0, 150.0, 0.0};
+    static float front_mat_shininess[] = {30.0};
+    static float front_mat_specular[] = {0.2, 0.2, 0.2, 1.0};
+    static float front_mat_diffuse[] = {0.5, 0.28, 0.38, 1.0};
+    static float back_mat_shininess[] = {50.0};
+    static float back_mat_specular[] = {0.5, 0.5, 0.2, 1.0};
+    static float back_mat_diffuse[] = {1.0, 1.0, 0.2, 1.0};
+    static float lmodel_ambient[] = {1.0, 1.0, 1.0, 1.0};
+    static float lmodel_twoside[] = {GL_TRUE};
+
+    glClearColor(0.0, 0.0, 0.0, 0.0);
+
+    glFrontFace(GL_CW);
+
+    glEnable(GL_DEPTH_TEST);
+
+    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
+    glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
+    glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
+    glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
+    glLightfv(GL_LIGHT0, GL_POSITION, position);
+    glEnable(GL_LIGHTING);
+    glEnable(GL_LIGHT0);
+    
+    glMaterialfv(GL_FRONT, GL_SHININESS, front_mat_shininess);
+    glMaterialfv(GL_FRONT, GL_SPECULAR, front_mat_specular);
+    glMaterialfv(GL_FRONT, GL_DIFFUSE, front_mat_diffuse);
+    glMaterialfv(GL_BACK, GL_SHININESS, back_mat_shininess);
+    glMaterialfv(GL_BACK, GL_SPECULAR, back_mat_specular);
+    glMaterialfv(GL_BACK, GL_DIFFUSE, back_mat_diffuse);
+
+    glEnable(GL_CLIP_PLANE0);
+
+    if (rgb) {
+       glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, decal);
+       glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, repeat);
+       glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, repeat);
+       glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, nearest);
+       glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, nearest);
+       glTexImage2D(GL_TEXTURE_2D, 0, 3, CHECKIMAGEWIDTH, CHECKIMAGEHEIGHT, 0,
+                    GL_RGB, GL_UNSIGNED_BYTE, (GLvoid *)checkImage);
+       glEnable(GL_TEXTURE_2D);
+
+       glCullFace(GL_BACK);
+       glEnable(GL_CULL_FACE);
+    } else {
+       SetGreyRamp();
+        /* commented out by BrianP because it's the wrong way to handle a 4-bit visual!
+       if (doubleBuffer) {
+           colorIndexes[1] = 10;
+           colorIndexes[2] = 15;
+       }
+        */
+       glMaterialiv(GL_FRONT_AND_BACK, GL_COLOR_INDEXES, colorIndexes);
+    }
+
+    BuildLists();
+
+    dithering = GL_TRUE;
+    shade = GL_TRUE;
+    doStipple = GL_FALSE;
+    polyMode = GL_BACK;
+}
+
+static void Reshape(int width, int height)
+{
+    glViewport(0, 0, (GLint)width, (GLint)height);
+
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    gluPerspective(90, 1.0, 1.0, 200.0);
+    glMatrixMode(GL_MODELVIEW);
+}
+
+static void Key2(int key, int x, int y)
+{
+    (void) x;
+    (void) y;
+    switch (key) {
+      case GLUT_KEY_LEFT:
+       yRotation += 0.5;
+       break;
+      case GLUT_KEY_RIGHT:
+       yRotation -= 0.5;
+       break;
+      case GLUT_KEY_UP:
+       plane[3] += 2.0;
+       break;
+      case GLUT_KEY_DOWN:
+       plane[3] -= 2.0;
+       break;
+      default:
+       return;
+    }
+
+    glutPostRedisplay();
+}
+
+static void Key(unsigned char key, int x, int y)
+{
+    (void) x;
+    (void) y;
+    switch (key) {
+      case 27:
+       exit(1);
+
+      case 'Z':
+       zTranslation -= 1.0;
+       break;
+      case 'z':
+       zTranslation += 1.0;
+       break;
+
+      case '1':
+       glPolygonMode(polyMode, GL_POINT);
+       break;
+      case '2':
+       glPolygonMode(polyMode, GL_LINE);
+       break;
+      case '3':
+       glPolygonMode(polyMode, GL_FILL);
+       break;
+      case 'p':
+       switch (polyMode) {
+         case GL_BACK:
+           polyMode = GL_FRONT;
+           break;
+         case GL_FRONT:
+           polyMode = GL_FRONT_AND_BACK;
+           break;
+         case GL_FRONT_AND_BACK:
+           polyMode = GL_BACK;
+           break;
+          default:
+            break;
+       }
+       break;
+
+      case '4':
+       glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
+       break;
+      case '5':
+       glEnable(GL_POLYGON_SMOOTH);
+       if (rgb) {
+           glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+           glEnable(GL_BLEND);
+           glDisable(GL_DEPTH_TEST);
+       } else {
+           SetUpAntiAliasedGrayScale();
+       }
+       break;
+      case '6':
+       glDisable(GL_POLYGON_SMOOTH);
+       if (rgb) {
+           glBlendFunc(GL_ONE, GL_ZERO);
+           glDisable(GL_BLEND);
+           glEnable(GL_DEPTH_TEST);
+       } else {
+           SetGreyRamp();
+       }
+       break;
+
+      case '8':
+       dithering = !dithering;
+       (dithering) ? glEnable(GL_DITHER) : glDisable(GL_DITHER);
+       break;
+
+      case '9':
+       doStipple = !doStipple;
+       if (doStipple) {
+           glPolygonStipple(stipple);
+           glEnable(GL_POLYGON_STIPPLE);
+       } else {
+           glDisable(GL_POLYGON_STIPPLE);
+       }
+       break;
+
+      case '0':
+       shade = !shade;
+       (shade) ? glShadeModel(GL_SMOOTH) : glShadeModel(GL_FLAT);
+       break;
+
+      case 'q':
+       glDisable(GL_CULL_FACE);
+       break;
+      case 'w':
+       glEnable(GL_CULL_FACE);
+       glCullFace(GL_FRONT);
+       break;
+      case 'e':
+       glEnable(GL_CULL_FACE);
+       glCullFace(GL_BACK);
+       break;
+
+      case 'r':
+       glFrontFace(GL_CW);
+       break;
+      case 't': 
+       glFrontFace(GL_CCW);
+       break;
+      case 'y':
+       glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+       glPixelStorei(GL_UNPACK_LSB_FIRST, 0);
+       glPolygonStipple(stipple);
+       break;
+      case 'u':
+       glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+       glPixelStorei(GL_UNPACK_LSB_FIRST, 1);
+       glPolygonStipple(stipple);
+       break;
+
+      case 'a':
+       glEnable(GL_TEXTURE_2D);
+       glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, repeat);
+       glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, repeat);
+       glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, nearest);
+       glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, nearest);
+       glTexImage2D(GL_TEXTURE_2D, 0, 4, BRICKIMAGEWIDTH,
+                    BRICKIMAGEHEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+                    (GLvoid *)brickImage);
+       break;
+      case 's':
+       glEnable(GL_TEXTURE_2D);
+       glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, repeat);
+       glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, repeat);
+       glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, nearest);
+       glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, nearest);
+       glTexImage2D(GL_TEXTURE_2D, 0, 3, CHECKIMAGEWIDTH,
+                    CHECKIMAGEHEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE,
+                    (GLvoid *)checkImage);
+       break;
+      case 'd':
+       glDisable(GL_TEXTURE_2D);
+       break;
+
+      case 'f':
+       glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, decal);
+       break;
+      case 'g':
+       glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, modulate);
+       break;
+
+      case 'n':
+        /* added by BrianP */
+        noDraw = !noDraw;
+        if (noDraw) {
+           glDrawBuffer( GL_NONE );
+        }
+        else {
+           if (doubleBuffer) {
+              glDrawBuffer( GL_BACK );
+           }
+           else {
+              glDrawBuffer( GL_FRONT );
+           }
+        }
+        break;
+
+      case 'l':
+         /* Line Smooth - added by BrianP */
+         LineSmooth = !LineSmooth;
+         if (LineSmooth) {
+            glEnable(GL_LINE_SMOOTH);
+           glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+            glEnable(GL_BLEND);
+         }
+         else {
+            glDisable(GL_LINE_SMOOTH);
+           glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+            glDisable(GL_BLEND);
+         }
+         break;
+      default:
+       return;
+    }
+
+    glutPostRedisplay();
+}
+
+static void Draw(void)
+{
+
+    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+
+    glPushMatrix();
+
+    glTranslatef(0, 0, zTranslation);
+    glRotatef(30.0, 1, 0, 0);
+    glRotatef(yRotation, 0, 1, 0);
+    glClipPlane(GL_CLIP_PLANE0, plane);
+    glCallList(logo);
+
+    glPopMatrix();
+
+    glFlush();
+
+    if (doubleBuffer) {
+       glutSwapBuffers();
+    }
+}
+
+static GLenum Args(int argc, char **argv)
+{
+    GLint i;
+
+    rgb = GL_TRUE;
+    doubleBuffer = GL_FALSE;
+
+    for (i = 1; i < argc; i++) {
+       if (strcmp(argv[i], "-ci") == 0) {
+           rgb = GL_FALSE;
+       } else if (strcmp(argv[i], "-rgb") == 0) {
+           rgb = GL_TRUE;
+       } else if (strcmp(argv[i], "-sb") == 0) {
+           doubleBuffer = GL_FALSE;
+       } else if (strcmp(argv[i], "-db") == 0) {
+           doubleBuffer = GL_TRUE;
+       } else {
+           printf("%s (Bad option).\n", argv[i]);
+           return GL_FALSE;
+       }
+    }
+    return GL_TRUE;
+}
+
+int main(int argc, char **argv)
+{
+    unsigned int type;
+
+    glutInit(&argc, argv);
+
+    if (Args(argc, argv) == GL_FALSE) {
+       exit(1);
+    }
+
+    glutInitWindowPosition(0, 0); glutInitWindowSize( 300, 300);
+
+    type = GLUT_DEPTH;
+    type |= (rgb) ? GLUT_RGB : GLUT_INDEX;
+    type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
+    glutInitDisplayMode(type);
+
+    if (glutCreateWindow("Logo Test") == GL_FALSE) {
+       exit(1);
+    }
+
+    InitMap();
+
+    Init();
+
+    glutReshapeFunc(Reshape);
+    glutKeyboardFunc(Key);
+    glutSpecialFunc(Key2);
+    glutDisplayFunc(Draw);
+    glutMainLoop();
+       return 0;
+}
diff --git a/progs/samples/nurb.c b/progs/samples/nurb.c
new file mode 100644 (file)
index 0000000..f90c6ee
--- /dev/null
@@ -0,0 +1,355 @@
+/*
+ * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the name of
+ * Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
+ * ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <GL/glut.h>
+
+
+#ifndef CALLBACK
+#define CALLBACK
+#endif
+
+
+#define INREAL float
+
+#define S_NUMPOINTS 13
+#define S_ORDER     3   
+#define S_NUMKNOTS  (S_NUMPOINTS + S_ORDER)
+#define T_NUMPOINTS 3
+#define T_ORDER     3 
+#define T_NUMKNOTS  (T_NUMPOINTS + T_ORDER)
+#define SQRT_TWO    1.41421356237309504880
+
+
+typedef INREAL Point[4];
+
+
+GLenum doubleBuffer;
+
+GLenum expectedError;
+GLint rotX = 40, rotY = 40;
+INREAL sknots[S_NUMKNOTS] = {
+    -1.0, -1.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0,
+    4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 9.0, 9.0
+};
+INREAL tknots[T_NUMKNOTS] = {
+    1.0, 1.0, 1.0, 2.0, 2.0, 2.0
+};
+Point ctlpoints[S_NUMPOINTS][T_NUMPOINTS] = {
+    {
+       {
+           4.0, 2.0, 2.0, 1.0
+       },
+       {
+           4.0, 1.6, 2.5, 1.0
+       },
+       {
+           4.0, 2.0, 3.0, 1.0
+       }
+    },
+    {
+       {
+           5.0, 4.0, 2.0, 1.0
+       },
+       {
+           5.0, 4.0, 2.5, 1.0
+       },
+       {
+           5.0, 4.0, 3.0, 1.0
+       }
+    },
+    {
+       {
+           6.0, 5.0, 2.0, 1.0
+       },
+       {
+           6.0, 5.0, 2.5, 1.0
+       },
+       {
+           6.0, 5.0, 3.0, 1.0
+       }
+    },
+    {
+       {
+           SQRT_TWO*6.0, SQRT_TWO*6.0, SQRT_TWO*2.0, SQRT_TWO
+       },
+       {
+           SQRT_TWO*6.0, SQRT_TWO*6.0, SQRT_TWO*2.5, SQRT_TWO
+       },
+       {
+           SQRT_TWO*6.0, SQRT_TWO*6.0, SQRT_TWO*3.0, SQRT_TWO
+       }  
+    },
+    {
+       {
+           5.2, 6.7, 2.0, 1.0
+       },
+       {
+           5.2, 6.7, 2.5, 1.0
+       },
+       {
+           5.2, 6.7, 3.0, 1.0
+       }
+    },
+    {
+       {
+           SQRT_TWO*4.0, SQRT_TWO*6.0, SQRT_TWO*2.0, SQRT_TWO
+       },
+       {
+           SQRT_TWO*4.0, SQRT_TWO*6.0, SQRT_TWO*2.5, SQRT_TWO
+       }, 
+       {
+           SQRT_TWO*4.0, SQRT_TWO*6.0, SQRT_TWO*3.0, SQRT_TWO
+       }  
+    }, 
+    {
+       {
+           4.0, 5.2, 2.0, 1.0
+       },
+       {
+           4.0, 4.6, 2.5, 1.0
+       },
+       {
+           4.0, 5.2, 3.0, 1.0
+       }  
+    },
+    {
+       {
+           SQRT_TWO*4.0, SQRT_TWO*6.0, SQRT_TWO*2.0, SQRT_TWO
+       },
+       {
+           SQRT_TWO*4.0, SQRT_TWO*6.0, SQRT_TWO*2.5, SQRT_TWO
+       },
+       {
+           SQRT_TWO*4.0, SQRT_TWO*6.0, SQRT_TWO*3.0, SQRT_TWO
+       }  
+    },
+    {
+       {
+           2.8, 6.7, 2.0, 1.0
+       },
+       {
+           2.8, 6.7, 2.5, 1.0
+       },
+       {
+           2.8, 6.7, 3.0, 1.0
+       }   
+    },
+    {
+       {
+           SQRT_TWO*2.0, SQRT_TWO*6.0, SQRT_TWO*2.0, SQRT_TWO
+       },
+       {
+           SQRT_TWO*2.0, SQRT_TWO*6.0, SQRT_TWO*2.5, SQRT_TWO
+       },
+       {
+           SQRT_TWO*2.0, SQRT_TWO*6.0, SQRT_TWO*3.0, SQRT_TWO
+       }  
+    },
+    {
+       {
+           2.0, 5.0, 2.0, 1.0
+       },
+       {
+           2.0, 5.0, 2.5, 1.0
+       },
+       {
+           2.0, 5.0, 3.0, 1.0
+       } 
+    },
+    {
+       {
+           3.0, 4.0, 2.0, 1.0
+       },
+       {
+           3.0, 4.0, 2.5, 1.0
+       },
+       {
+           3.0, 4.0, 3.0, 1.0
+       } 
+    },
+    {
+       {
+           4.0, 2.0, 2.0, 1.0
+       },
+       {
+           4.0, 1.6, 2.5, 1.0
+       },
+       {
+           4.0, 2.0, 3.0, 1.0
+       }    
+    }
+};
+GLUnurbsObj *theNurbs;
+
+
+static void CALLBACK ErrorCallback(GLenum which)
+{
+
+    if (which != expectedError) {
+       fprintf(stderr, "Unexpected error occured (%d):\n", which);
+       fprintf(stderr, "    %s\n", (char *) gluErrorString(which));
+    }
+}
+
+static void Init(void)
+{
+
+    theNurbs = gluNewNurbsRenderer();
+    gluNurbsCallback(theNurbs, GLU_ERROR, ErrorCallback);
+
+    gluNurbsProperty(theNurbs, GLU_SAMPLING_TOLERANCE, 15.0);
+    gluNurbsProperty(theNurbs, GLU_DISPLAY_MODE, GLU_OUTLINE_PATCH);
+
+    expectedError = GLU_INVALID_ENUM;
+    gluNurbsProperty(theNurbs, ~0, 15.0);
+    expectedError = GLU_NURBS_ERROR13;
+    gluEndSurface(theNurbs);
+    expectedError = 0;
+
+    glColor3f(1.0, 1.0, 1.0);
+}
+
+static void Reshape(int width, int height)
+{
+
+    glViewport(0, 0, (GLint)width, (GLint)height);
+
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    glFrustum(-2.0, 2.0, -2.0, 2.0, 0.8, 10.0);
+    gluLookAt(7.0, 4.5, 4.0, 4.5, 4.5, 2.5, 6.0, -3.0, 2.0);
+    glMatrixMode(GL_MODELVIEW);
+}
+
+static void Key2(int key, int x, int y)
+{
+
+    switch (key) {
+      case GLUT_KEY_DOWN:
+       rotX -= 5;
+       break;
+      case GLUT_KEY_UP:
+       rotX += 5;
+       break;
+      case GLUT_KEY_LEFT:
+       rotY -= 5;
+       break;
+      case GLUT_KEY_RIGHT:
+       rotY += 5;
+       break;
+      default:
+       return;
+    }
+
+    glutPostRedisplay();
+}
+
+static void Key(unsigned char key, int x, int y)
+{
+
+    switch (key) {
+      case 27:
+       exit(1);
+    }
+}
+
+static void Draw(void)
+{
+
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    glPushMatrix();
+
+    glTranslatef(4.0, 4.5, 2.5);
+    glRotatef(rotY, 1, 0, 0);
+    glRotatef(rotX, 0, 1, 0);
+    glTranslatef(-4.0, -4.5, -2.5);
+
+    gluBeginSurface(theNurbs);
+    gluNurbsSurface(theNurbs, S_NUMKNOTS, sknots, T_NUMKNOTS, tknots,
+                   4*T_NUMPOINTS, 4, &ctlpoints[0][0][0], S_ORDER,
+                   T_ORDER, GL_MAP2_VERTEX_4);
+    gluEndSurface(theNurbs);
+
+    glPopMatrix();
+
+    glFlush();
+
+    if (doubleBuffer) {
+       glutSwapBuffers();
+    }
+}
+
+static GLenum Args(int argc, char **argv)
+{
+    GLint i;
+
+    doubleBuffer = GL_FALSE;
+
+    for (i = 1; i < argc; i++) {
+       if (strcmp(argv[i], "-sb") == 0) {
+           doubleBuffer = GL_FALSE;
+       } else if (strcmp(argv[i], "-db") == 0) {
+           doubleBuffer = GL_TRUE;
+       } else {
+           printf("%s (Bad option).\n", argv[i]);
+           return GL_FALSE;
+       }
+    }
+    return GL_TRUE;
+}
+
+int main(int argc, char **argv)
+{
+    GLenum type;
+
+    glutInit(&argc, argv);
+
+    if (Args(argc, argv) == GL_FALSE) {
+       exit(1);
+    }
+
+    glutInitWindowPosition(0, 0); glutInitWindowSize( 300, 300);
+
+    type = GLUT_RGB;
+    type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
+    glutInitDisplayMode(type);
+
+    if (glutCreateWindow("NURBS Test") == GL_FALSE) {
+       exit(1);
+    }
+
+    Init();
+
+    glutReshapeFunc(Reshape);
+    glutKeyboardFunc(Key);
+    glutSpecialFunc(Key2);
+    glutDisplayFunc(Draw);
+    glutMainLoop();
+       return 0;
+}
diff --git a/progs/samples/oglinfo.c b/progs/samples/oglinfo.c
new file mode 100644 (file)
index 0000000..4fe51ef
--- /dev/null
@@ -0,0 +1,218 @@
+/* oglinfo.c */
+
+/* This demo modified by BrianP to accomodate Mesa and test
+ * the GLX 1.1 functions.
+ */
+
+
+
+#include <GL/gl.h>
+#include <GL/glx.h>
+#include <GL/glu.h>
+#include <stdio.h>
+#include <string.h>
+
+int visual_request0[] = { None }; /* don't need much of a visual */
+int visual_request1[] = { GLX_RGBA, None }; /* in case CI failed */
+
+int main(int argc, char **argv)
+{
+  char *display_name = NULL;
+  char *string;
+  Display       *dpy;
+  int           screen_num;
+  int           major, minor;
+  XVisualInfo   *vis;
+  GLXContext    ctx;
+  Window        root,  win;
+  Colormap      cmap;
+  XSetWindowAttributes swa;
+  int dontcare;
+
+  /* parse arguments */
+  if(argc > 1) {
+    if(!strcmp(argv[1],"-display"))
+      display_name = argv[2];
+    else {
+      fprintf(stderr, "Usage: %s [-display <display>]\n",argv[0]);
+      return 0;
+    }
+  }
+
+  /* get display */
+  if (!(dpy = XOpenDisplay(display_name))) {
+    fprintf(stderr,"Error: XOpenDisplay() failed.\n");
+    return 1;
+  }
+
+  /* does the server know about OpenGL & GLX? */
+#ifndef MESA
+  if(!XQueryExtension(dpy, "GLX", &dontcare, &dontcare, &dontcare)) {
+    fprintf(stderr,"This system doesn't appear to support OpenGL\n");
+    return 1;
+  }
+#else
+  (void) dontcare;
+#endif
+
+  /* find the glx version */
+  if(glXQueryVersion(dpy, &major, &minor))
+    printf("GLX Version: %d.%d\n", major, minor);
+  else {
+    fprintf(stderr, "Error: glXQueryVersion() failed.\n");
+    return 1;
+  }
+
+  /* get screen number */
+  screen_num = DefaultScreen(dpy);
+
+/* This #ifdef isn't redundant. It keeps the build from breaking
+** if you are building on a machine that has an old (1.0) version
+** of glx.
+**
+** This program could still be *run* on a machine that has an old 
+** version of glx, even if it was *compiled* on a version that has
+** a new version.
+**
+** If compiled on a system with an old version of glx, then it will 
+** never recognize glx extensions, since that code would have been
+** #ifdef'ed out.
+*/
+#ifdef GLX_VERSION_1_1
+
+  /*
+  ** This test guarantees that glx, on the display you are inquiring,
+  ** suppports glXQueryExtensionsString().
+  */
+  if(minor > 0 || major > 1)
+    string = (char *) glXQueryExtensionsString(dpy, screen_num);
+  else
+    string = "";
+
+  if(string)
+    printf("GLX Extensions (client & server): %s\n",
+          string);
+  else {
+    fprintf(stderr, "Error: glXQueryExtensionsString() failed.\n");
+    return 1;
+  }
+
+  if (minor>0 || major>1) {
+     printf("glXGetClientString(GLX_VENDOR): %s\n", glXGetClientString(dpy,GLX_VENDOR));
+     printf("glXGetClientString(GLX_VERSION): %s\n", glXGetClientString(dpy,GLX_VERSION));
+     printf("glXGetClientString(GLX_EXTENSIONS): %s\n", glXGetClientString(dpy,GLX_EXTENSIONS));
+     printf("glXQueryServerString(GLX_VENDOR): %s\n", glXQueryServerString(dpy,screen_num,GLX_VENDOR));
+     printf("glXQueryServerString(GLX_VERSION): %s\n", glXQueryServerString(dpy,screen_num,GLX_VERSION));
+     printf("glXQueryServerString(GLX_EXTENSIONS): %s\n", glXQueryServerString(dpy,screen_num,GLX_EXTENSIONS));
+  }
+
+
+#endif
+
+   /* get any valid OpenGL visual */
+   if (!(vis = glXChooseVisual(dpy, screen_num, visual_request0)))  {
+      if (!(vis = glXChooseVisual(dpy, screen_num, visual_request1)))  {
+         fprintf(stderr,"Error: glXChooseVisual() failed.\n");
+         return 1;
+      }
+   }
+
+   /* get context */
+   ctx = glXCreateContext(dpy,vis,0,GL_TRUE);
+
+   /* root window */
+   root = RootWindow(dpy,vis->screen);
+
+   /* get RGBA colormap */
+   cmap = XCreateColormap(dpy, root, vis->visual, AllocNone);
+
+   /* get window */
+   swa.colormap = cmap;
+   swa.border_pixel = 0;
+   swa.event_mask = StructureNotifyMask;
+   win = XCreateWindow(dpy, root, 0, 0, 1, 1, 0, vis->depth,
+                      InputOutput,vis->visual,
+                      CWBorderPixel|CWColormap|CWEventMask,
+                      &swa);
+
+   glXMakeCurrent(dpy,win,ctx);
+
+  string = (char *) glGetString(GL_VERSION);
+  if(string)
+#ifdef MESA
+    printf("Mesa Version: %s\n", string);
+#else
+    printf("OpenGL Version: %s\n", string);
+#endif
+  else {
+    fprintf(stderr, "Error: glGetString(GL_VERSION) failed.\n");
+    return 1;
+  }
+
+  string = (char *) glGetString(GL_EXTENSIONS);
+
+  if(string)
+#ifdef MESA
+    printf("Mesa Extensions: %s\n", string);
+#else
+    printf("OpenGL Extensions: %s\n", string);
+#endif
+  else {
+    fprintf(stderr, "Error: glGetString(GL_EXTENSIONS) failed.\n");
+    return 1;
+  }
+
+  string = (char *) glGetString(GL_RENDERER);
+
+  if(string)
+#ifdef MESA
+    printf("Mesa Renderer: %s\n", string);
+#else
+    printf("OpenGL renderer: %s\n", string);
+#endif
+  else {
+    fprintf(stderr, "Error: glGetString(GL_RENDERER) failed.\n");
+    return 1;
+  }
+
+/*
+** This #ifdef prevents a build failure if you compile on an a
+** machine with an old GLU library. 
+**
+** If you build on a pre GLU 1.1 machine, you will never be able
+** to get glu info, even if you run on a GLU 1.1 or latter machine,
+** since the code has been #ifdef'ed out.
+*/
+#ifdef GLU_VERSION_1_1
+
+  /*
+  ** If the glx version is 1.1 or latter, gluGetString() is guaranteed
+  ** to exist.
+  */
+  if(minor > 0 || major > 1)
+    string = (char *) gluGetString(GLU_VERSION);
+  else
+    string = "1.0";
+
+  if(string)
+    printf("GLU Version: %s\n", string);
+  else {
+    fprintf(stderr, "Error: gluGetString(GLU_VERSION) failed.\n");
+    return 1;
+  }
+  
+  if(minor > 0 || major > 1)
+    string = (char *) gluGetString(GLU_EXTENSIONS);
+  else
+    string = "";
+
+  if(string)
+    printf("GLU Extensions: %s\n", string);
+  else {
+    fprintf(stderr, "Error: gluGetString(GLU_EXTENSIONS) failed.\n");
+    return 1;
+  }
+
+#endif
+  return 0;
+}
diff --git a/progs/samples/olympic.c b/progs/samples/olympic.c
new file mode 100644 (file)
index 0000000..db72002
--- /dev/null
@@ -0,0 +1,375 @@
+/*
+ * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the name of
+ * Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
+ * ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * Nov 20, 1995 use stdlib's rand()/srand() instead of random()/srand48(), etc.
+ */
+
+/* 
+ * Modified by Li Wei(liwei@aiar.xjtu.edu.cn) to be able to run in Windows
+ * 6/13
+ *
+ * Modified by Brian Paul to compile with Windows OR Unix.  7/23/97
+ */
+
+
+#define _HPUX_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <GL/glut.h>
+
+#ifndef RAND_MAX
+#  define RAND_MAX 32767
+#endif
+
+
+#define XSIZE  100
+#define YSIZE  75
+
+#define RINGS 5
+#define BLUERING 0
+#define BLACKRING 1
+#define REDRING 2
+#define YELLOWRING 3
+#define GREENRING 4
+
+#define BACKGROUND 8
+
+
+GLenum rgb, doubleBuffer;
+
+#include "tkmap.c"
+
+unsigned char rgb_colors[RINGS][3];
+int mapped_colors[RINGS];
+float dests[RINGS][3];
+float offsets[RINGS][3];
+float angs[RINGS];
+float rotAxis[RINGS][3];
+int iters[RINGS];
+GLuint theTorus;
+
+
+void FillTorus(float rc, int numc, float rt, int numt)
+{
+    int i, j, k;
+    double s, t;
+    double x, y, z;
+    double pi, twopi;
+
+    pi = 3.14159265358979323846;
+    twopi = 2 * pi;
+    for (i = 0; i < numc; i++) {
+       glBegin(GL_QUAD_STRIP);
+        for (j = 0; j <= numt; j++) {
+           for (k = 1; k >= 0; k--) {
+               s = (i + k) % numc + 0.5;
+               t = j % numt;
+
+               x = cos(t*twopi/numt) * cos(s*twopi/numc);
+               y = sin(t*twopi/numt) * cos(s*twopi/numc);
+               z = sin(s*twopi/numc);
+               glNormal3f(x, y, z);
+
+               x = (rt + rc * cos(s*twopi/numc)) * cos(t*twopi/numt);
+               y = (rt + rc * cos(s*twopi/numc)) * sin(t*twopi/numt);
+               z = rc * sin(s*twopi/numc);
+               glVertex3f(x, y, z);
+           }
+        }
+       glEnd();
+    }
+}
+
+float Clamp(int iters_left, float t)
+{
+
+    if (iters_left < 3) {
+       return 0.0;
+    }
+    return (iters_left-2)*t/iters_left;
+}
+
+void DrawScene(void)
+{
+    int i, j;
+    GLboolean goIdle;
+
+    goIdle = GL_TRUE;
+    for (i = 0; i < RINGS; i++) {
+       if (iters[i]) {
+           for (j = 0; j < 3; j++) {
+               offsets[i][j] = Clamp(iters[i], offsets[i][j]);
+           }
+           angs[i] = Clamp(iters[i], angs[i]);
+           iters[i]--;
+           goIdle = GL_FALSE;
+       }
+    }
+    if (goIdle) {
+       glutIdleFunc(NULL);
+    }
+
+    glPushMatrix();
+    
+    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+    gluLookAt(0,0,10, 0,0,0, 0,1,0);
+
+    for (i = 0; i < RINGS; i++) {
+       if (rgb) {
+           glColor3ubv(rgb_colors[i]);
+       } else {
+           glIndexi(mapped_colors[i]);
+       }
+       glPushMatrix();
+       glTranslatef(dests[i][0]+offsets[i][0], dests[i][1]+offsets[i][1],
+                    dests[i][2]+offsets[i][2]);
+       glRotatef(angs[i], rotAxis[i][0], rotAxis[i][1], rotAxis[i][2]);
+       glCallList(theTorus);
+       glPopMatrix();
+    }
+
+    glPopMatrix();
+
+    glFlush();
+    if (doubleBuffer) {
+       glutSwapBuffers();
+    }
+}
+
+float MyRand(void)
+{
+   return 10.0 * ( (float) rand() / (float) RAND_MAX - 0.5 );
+}
+
+void GLUTCALLBACK glut_post_redisplay_p(void)
+{
+      glutPostRedisplay();
+}
+
+void ReInit(void)
+{
+    int i;
+    float deviation;
+
+    deviation = MyRand() / 2;
+    deviation = deviation * deviation;
+    for (i = 0; i < RINGS; i++) {
+       offsets[i][0] = MyRand();
+       offsets[i][1] = MyRand();
+       offsets[i][2] = MyRand();
+       angs[i] = 260.0 * MyRand();
+       rotAxis[i][0] = MyRand();
+       rotAxis[i][1] = MyRand();
+       rotAxis[i][2] = MyRand();
+       iters[i] = (deviation * MyRand() + 60.0);
+    }
+    glutIdleFunc(glut_post_redisplay_p);
+}
+
+void Init(void)
+{
+    float base, height;
+    float aspect, x, y;
+    int i;
+
+    float top_y = 1.0;
+    float bottom_y = 0.0;
+    float top_z = 0.15;
+    float bottom_z = 0.69;
+    float spacing = 2.5;
+    static float lmodel_ambient[] = {0.0, 0.0, 0.0, 0.0};
+    static float lmodel_twoside[] = {GL_FALSE};
+    static float lmodel_local[] = {GL_FALSE};
+    static float light0_ambient[] = {0.1, 0.1, 0.1, 1.0};
+    static float light0_diffuse[] = {1.0, 1.0, 1.0, 0.0};
+    static float light0_position[] = {0.8660254, 0.5, 1, 0};
+    static float light0_specular[] = {1.0, 1.0, 1.0, 0.0};
+    static float bevel_mat_ambient[] = {0.0, 0.0, 0.0, 1.0};
+    static float bevel_mat_shininess[] = {40.0};
+    static float bevel_mat_specular[] = {1.0, 1.0, 1.0, 0.0};
+    static float bevel_mat_diffuse[] = {1.0, 0.0, 0.0, 0.0};
+
+    srand( (unsigned int) glutGet(GLUT_ELAPSED_TIME) );
+
+    ReInit();
+    for (i = 0; i < RINGS; i++) {
+       rgb_colors[i][0] = rgb_colors[i][1] = rgb_colors[i][2] = 0;
+    }
+    rgb_colors[BLUERING][2] = 255;
+    rgb_colors[REDRING][0] = 255;
+    rgb_colors[GREENRING][1] = 255;
+    rgb_colors[YELLOWRING][0] = 255;
+    rgb_colors[YELLOWRING][1] = 255;
+    mapped_colors[BLUERING] = COLOR_BLUE;
+    mapped_colors[REDRING] = COLOR_RED;
+    mapped_colors[GREENRING] = COLOR_GREEN;
+    mapped_colors[YELLOWRING] = COLOR_YELLOW;
+    mapped_colors[BLACKRING] = COLOR_BLACK;
+
+    dests[BLUERING][0] = -spacing;
+    dests[BLUERING][1] = top_y;
+    dests[BLUERING][2] = top_z;
+
+    dests[BLACKRING][0] = 0.0;
+    dests[BLACKRING][1] = top_y;
+    dests[BLACKRING][2] = top_z;
+
+    dests[REDRING][0] = spacing;
+    dests[REDRING][1] = top_y;
+    dests[REDRING][2] = top_z;
+
+    dests[YELLOWRING][0] = -spacing / 2.0;
+    dests[YELLOWRING][1] = bottom_y;
+    dests[YELLOWRING][2] = bottom_z;
+
+    dests[GREENRING][0] = spacing / 2.0;
+    dests[GREENRING][1] = bottom_y;
+    dests[GREENRING][2] = bottom_z;
+
+    base = 2.0; 
+    height = 2.0;
+    theTorus = glGenLists(1);
+    glNewList(theTorus, GL_COMPILE);
+    FillTorus(0.1, 8, 1.0, 25);
+    glEndList();
+
+    x = (float)XSIZE;
+    y = (float)YSIZE;
+    aspect = x / y;
+    glEnable(GL_CULL_FACE);
+    glCullFace(GL_BACK);
+    glEnable(GL_DEPTH_TEST);
+    glClearDepth(1.0);
+
+    if (rgb) {
+       glClearColor(0.5, 0.5, 0.5, 0.0);
+       glLightfv(GL_LIGHT0, GL_AMBIENT, light0_ambient);
+       glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
+       glLightfv(GL_LIGHT0, GL_SPECULAR, light0_specular);
+       glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
+       glEnable(GL_LIGHT0);
+
+       glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, lmodel_local);
+       glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
+       glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
+       glEnable(GL_LIGHTING);
+
+       glMaterialfv(GL_FRONT, GL_AMBIENT, bevel_mat_ambient);
+       glMaterialfv(GL_FRONT, GL_SHININESS, bevel_mat_shininess);
+       glMaterialfv(GL_FRONT, GL_SPECULAR, bevel_mat_specular);
+       glMaterialfv(GL_FRONT, GL_DIFFUSE, bevel_mat_diffuse);
+
+       glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
+       glEnable(GL_COLOR_MATERIAL);
+       glShadeModel(GL_SMOOTH);
+    } else {
+       glClearIndex(BACKGROUND);
+       glShadeModel(GL_FLAT);
+    }
+
+    glMatrixMode(GL_PROJECTION);
+    gluPerspective(45, 1.33, 0.1, 100.0);
+    glMatrixMode(GL_MODELVIEW);
+}
+
+void Reshape(int width, int height)
+{
+
+    glViewport(0, 0, width, height);
+}
+
+void Key(unsigned char key, int x, int y)
+{
+
+    switch (key) {
+      case 27:
+       exit(1);
+      case 32:
+       ReInit();
+       break;
+    }
+}
+
+GLenum Args(int argc, char **argv)
+{
+    GLint i;
+
+    rgb = GL_TRUE;
+    doubleBuffer = GL_FALSE;
+
+    for (i = 1; i < argc; i++) {
+       if (strcmp(argv[i], "-ci") == 0) {
+           rgb = GL_FALSE;
+       } else if (strcmp(argv[i], "-rgb") == 0) {
+           rgb = GL_TRUE;
+       } else if (strcmp(argv[i], "-sb") == 0) {
+           doubleBuffer = GL_FALSE;
+       } else if (strcmp(argv[i], "-db") == 0) {
+           doubleBuffer = GL_TRUE;
+       } else {
+           printf("%s (Bad option).\n", argv[i]);
+           return GL_FALSE;
+       }
+    }
+    return GL_TRUE;
+}
+
+int main(int argc, char **argv)
+{
+    GLenum type;
+
+    glutInit(&argc, argv);
+
+    if (Args(argc, argv) == GL_FALSE) {
+       exit(1);
+    }
+
+    glutInitWindowPosition(0, 0); glutInitWindowSize( 400, 300);
+
+    type = GLUT_DEPTH;
+    type |= (rgb) ? GLUT_RGB : GLUT_INDEX;
+    type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
+    glutInitDisplayMode(type);
+
+    if (glutCreateWindow("Olympic") == GL_FALSE) {
+        exit(1);
+    }
+
+    InitMap();
+
+    Init();
+
+    glutReshapeFunc(Reshape);
+    glutKeyboardFunc(Key);
+    glutDisplayFunc(DrawScene);
+    glutIdleFunc(glut_post_redisplay_p);
+
+    glutMainLoop();
+       return 0;
+}
diff --git a/progs/samples/overlay.c b/progs/samples/overlay.c
new file mode 100644 (file)
index 0000000..41bbc26
--- /dev/null
@@ -0,0 +1,378 @@
+/*
+ * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the name of
+ * Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
+ * ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+#include <time.h>
+#include <GL/glut.h>
+
+
+#ifndef PI
+#define PI 3.141592657
+#endif
+
+
+enum {
+    NORMAL = 0,
+    WEIRD = 1
+};
+
+enum {
+    STREAK = 0,
+    CIRCLE = 1
+};
+
+#define MAXSTARS 400
+#define MAXPOS 10000
+#define MAXWARP 10
+#define MAXANGLES 6000
+
+
+typedef struct _starRec {
+    GLint type;
+    float x[2], y[2], z[2];
+    float offsetX, offsetY, offsetR, rotation;
+} starRec;
+
+
+GLenum doubleBuffer;
+GLint windW, windH;
+
+GLenum flag = NORMAL, overlayInit = GL_FALSE;
+GLint starCount = MAXSTARS / 2;
+float speed = 1.0;
+GLint nitro = 0;
+starRec stars[MAXSTARS];
+float sinTable[MAXANGLES];
+
+
+float Sin(float angle)
+{
+
+    return (sinTable[(GLint)angle]);
+}
+
+float Cos(float angle)
+{
+
+    return (sinTable[((GLint)angle+(MAXANGLES/4))%MAXANGLES]);
+}
+
+void NewStar(GLint n, GLint d)
+{
+
+    if (rand()%4 == 0) {
+       stars[n].type = CIRCLE;
+    } else {
+       stars[n].type = STREAK;
+    }
+    stars[n].x[0] = (float)(rand() % MAXPOS - MAXPOS / 2);
+    stars[n].y[0] = (float)(rand() % MAXPOS - MAXPOS / 2);
+    stars[n].z[0] = (float)(rand() % MAXPOS + d);
+    if (rand()%4 == 0 && flag == WEIRD) {
+       stars[n].offsetX = (float)(rand() % 100 - 100 / 2);
+       stars[n].offsetY = (float)(rand() % 100 - 100 / 2);
+       stars[n].offsetR = (float)(rand() % 25 - 25 / 2);
+    } else {
+       stars[n].offsetX = 0.0;
+       stars[n].offsetY = 0.0;
+       stars[n].offsetR = 0.0;
+    }
+}
+
+void RotatePoint(float *x, float *y, float rotation)
+{
+    float tmpX, tmpY;
+
+    tmpX = *x * Cos(rotation) - *y * Sin(rotation);
+    tmpY = *y * Cos(rotation) + *x * Sin(rotation);
+    *x = tmpX;
+    *y = tmpY;
+}
+
+void MoveStars(void)
+{
+    float offset;
+    GLint n;
+
+    offset = speed * 60.0;
+
+    for (n = 0; n < starCount; n++) {
+       stars[n].x[1] = stars[n].x[0];
+       stars[n].y[1] = stars[n].y[0];
+       stars[n].z[1] = stars[n].z[0];
+       stars[n].x[0] += stars[n].offsetX;
+       stars[n].y[0] += stars[n].offsetY;
+       stars[n].z[0] -= offset;
+        stars[n].rotation += stars[n].offsetR;
+        if (stars[n].rotation > MAXANGLES) {
+            stars[n].rotation = 0.0;
+       }
+    }
+}
+
+GLenum StarPoint(GLint n)
+{
+    float x0, y0, x1, y1, width;
+    GLint i;
+
+    x0 = stars[n].x[0] * windW / stars[n].z[0];
+    y0 = stars[n].y[0] * windH / stars[n].z[0];
+    RotatePoint(&x0, &y0, stars[n].rotation);
+    x0 += windW / 2.0;
+    y0 += windH / 2.0;
+
+    if (x0 >= 0.0 && x0 < windW && y0 >= 0.0 && y0 < windH) {
+       if (stars[n].type == STREAK) {
+           x1 = stars[n].x[1] * windW / stars[n].z[1];
+           y1 = stars[n].y[1] * windH / stars[n].z[1];
+           RotatePoint(&x1, &y1, stars[n].rotation);
+           x1 += windW / 2.0;
+           y1 += windH / 2.0;
+
+           glLineWidth(MAXPOS/100.0/stars[n].z[0]+1.0);
+           glColor3f(1.0, (MAXWARP-speed)/MAXWARP, (MAXWARP-speed)/MAXWARP);
+           if (fabs(x0-x1) < 1.0 && fabs(y0-y1) < 1.0) {
+               glBegin(GL_POINTS);
+                   glVertex2f(x0, y0);
+               glEnd();
+           } else {
+               glBegin(GL_LINES);
+                   glVertex2f(x0, y0);
+                   glVertex2f(x1, y1);
+               glEnd();
+           }
+       } else {
+           width = MAXPOS / 10.0 / stars[n].z[0] + 1.0;
+           glColor3f(1.0, 0.0, 0.0);
+           glBegin(GL_POLYGON);
+               for (i = 0; i < 8; i++) {
+                   float x = x0 + width * Cos((float)i*MAXANGLES/8.0);
+                   float y = y0 + width * Sin((float)i*MAXANGLES/8.0);
+                   glVertex2f(x, y);
+               };
+           glEnd();
+       }
+       return GL_TRUE;
+    } else {
+       return GL_FALSE;
+    }
+}
+
+void ShowStars(void)
+{
+    GLint n;
+
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    for (n = 0; n < starCount; n++) {
+       if (stars[n].z[0] > speed || (stars[n].z[0] > 0.0 && speed < MAXWARP)) {
+           if (StarPoint(n) == GL_FALSE) {
+               NewStar(n, MAXPOS);
+           }
+       } else {
+           NewStar(n, MAXPOS);
+       }
+    }
+}
+
+static void Init(void)
+{
+    float angle;
+    GLint n;
+
+    srand((unsigned int)time(NULL));
+
+    for (n = 0; n < MAXSTARS; n++) {
+       NewStar(n, 100);
+    }
+
+    angle = 0.0;
+    for (n = 0; n < MAXANGLES ; n++) {
+       sinTable[n] = sin(angle);
+        angle += PI / (MAXANGLES / 2.0);
+    }
+
+    glClearColor(0.0, 0.0, 0.0, 0.0);
+
+    glDisable(GL_DITHER);
+}
+
+void Reshape(int width, int height)
+{
+
+    windW = (GLint)width;
+    windH = (GLint)height;
+
+    glutUseLayer(GLUT_OVERLAY);
+
+    glViewport(0, 0, windW, windH);
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    gluOrtho2D(-0.5, windW+0.5, -0.5, windH+0.5);
+    glMatrixMode(GL_MODELVIEW);
+    overlayInit = GL_FALSE;
+
+    glutUseLayer(GLUT_NORMAL);
+
+    glViewport(0, 0, windW, windH);
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    gluOrtho2D(-0.5, windW+0.5, -0.5, windH+0.5);
+    glMatrixMode(GL_MODELVIEW);
+}
+
+static void Key(unsigned char key, int x, int y)
+{
+
+    switch (key) {
+      case 27:
+       exit(1);
+      case 32:
+       flag = (flag == NORMAL) ? WEIRD : NORMAL;
+       break;
+      case 't':
+       nitro = 1;
+       break;
+      default:
+       return;
+    }
+}
+
+void Idle(void)
+{
+
+    if (overlayInit == GL_FALSE) {
+       glutUseLayer(GLUT_OVERLAY);
+       glClear(GL_COLOR_BUFFER_BIT);
+/*         glColor3f(1.0, 0.0, 0.0);*/
+
+       glIndexf( 2.0 );
+       glBegin(GL_POLYGON);
+           glVertex2i(windW/4-10, windH/4-10);
+           glVertex2i(windW/2-10, windH/4-10);
+           glVertex2i(windW/2-10, windH/2-10);
+           glVertex2i(windW/4-10, windH/2-10);
+       glEnd();
+
+        glIndexf( 0.0 );
+       glBegin(GL_POLYGON);
+           glVertex2i(windW/4, windH/4);
+           glVertex2i(windW/2, windH/4);
+           glVertex2i(windW/2, windH/2);
+           glVertex2i(windW/4, windH/2);
+       glEnd();
+
+        glIndexf( 1.0 );
+       glBegin(GL_POLYGON);
+           glVertex2i(windW/4+10, windH/4+10);
+           glVertex2i(windW/2+10, windH/4+10);
+           glVertex2i(windW/2+10, windH/2+10);
+           glVertex2i(windW/4+10, windH/2+10);
+       glEnd();
+
+       glutUseLayer(GLUT_NORMAL);
+       overlayInit = GL_TRUE;
+    }
+
+    MoveStars();
+    ShowStars();
+    if (nitro > 0) {
+       speed = (float)(nitro / 10) + 1.0;
+       if (speed > MAXWARP) {
+           speed = MAXWARP;
+       }
+       if (++nitro > MAXWARP*10) {
+           nitro = -nitro;
+       }
+    } else if (nitro < 0) {
+       nitro++;
+       speed = (float)(-nitro / 10) + 1.0;
+       if (speed > MAXWARP) {
+           speed = MAXWARP;
+       }
+    }
+
+    glFlush();
+    if (doubleBuffer) {
+       glutSwapBuffers();
+    }
+}
+
+static GLenum Args(int argc, char **argv)
+{
+    GLint i;
+
+    doubleBuffer = GL_FALSE;
+
+    for (i = 1; i < argc; i++) {
+       if (strcmp(argv[i], "-sb") == 0) {
+           doubleBuffer = GL_FALSE;
+       } else if (strcmp(argv[i], "-db") == 0) {
+           doubleBuffer = GL_TRUE;
+       }
+    }
+    return GL_TRUE;
+}
+
+int main(int argc, char **argv)
+{
+    GLenum type;
+
+    glutInit(&argc, argv);
+
+    if (!glutLayerGet(GLUT_OVERLAY_POSSIBLE))
+    {
+       fprintf(stderr, "Overlay not available\n");
+       return;
+    }
+
+    if (Args(argc, argv) == GL_FALSE) {
+       exit(1);
+    }
+
+    windW = 300;
+    windH = 300;
+    glutInitWindowPosition(0, 0); glutInitWindowSize( 300, 300);
+
+    type = GLUT_RGB;
+    type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
+    glutInitDisplayMode(type);
+
+    if (glutCreateWindow("Overlay Test") == GL_FALSE) {
+       exit(1);
+    }
+
+    glutEstablishOverlay();
+
+    Init();
+
+    glutReshapeFunc(Reshape);
+    glutKeyboardFunc(Key);
+    glutIdleFunc(Idle);
+    glutMainLoop();
+       return 0;
+}
diff --git a/progs/samples/point.c b/progs/samples/point.c
new file mode 100644 (file)
index 0000000..4cb6ad7
--- /dev/null
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the name of
+ * Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
+ * ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <GL/glut.h>
+
+
+#define CI_RED COLOR_RED
+#define CI_ANTI_ALIAS_GREEN 16
+#define CI_ANTI_ALIAS_YELLOW 32
+#define CI_ANTI_ALIAS_RED 48
+
+
+GLenum rgb, doubleBuffer, windType;
+GLint windW, windH;
+
+#include "tkmap.c"
+
+GLenum mode;
+GLint size;
+float point[3] = {
+    1.0, 1.0, 0.0
+};
+
+
+static void Init(void)
+{
+    GLint i;
+
+    glClearColor(0.0, 0.0, 0.0, 0.0);
+
+    glBlendFunc(GL_SRC_ALPHA, GL_ZERO);
+
+    if (!rgb) {
+       for (i = 0; i < 16; i++) {
+           glutSetColor(i+CI_ANTI_ALIAS_RED, i/15.0, 0.0, 0.0);
+           glutSetColor(i+CI_ANTI_ALIAS_YELLOW, i/15.0, i/15.0, 0.0);
+           glutSetColor(i+CI_ANTI_ALIAS_GREEN, 0.0, i/15.0, 0.0);
+       }
+    }
+
+    mode = GL_FALSE;
+    size = 1;
+}
+
+static void Reshape(int width, int height)
+{
+
+    windW = (GLint)width;
+    windH = (GLint)height;
+
+    glViewport(0, 0, width, height);
+
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    gluOrtho2D(-windW/2, windW/2, -windH/2, windH/2);
+    glMatrixMode(GL_MODELVIEW);
+}
+
+static void Key2(int key, int x, int y)
+{
+
+    switch (key) {
+      case GLUT_KEY_LEFT:
+       point[0] -= 0.25;
+       break;
+      case GLUT_KEY_RIGHT:
+       point[0] += 0.25;
+       break;
+      case GLUT_KEY_UP:
+       point[1] += 0.25;
+       break;
+      case GLUT_KEY_DOWN:
+       point[1] -= 0.25;
+       break;
+      default:
+       return;
+    }
+
+    glutPostRedisplay();
+}
+
+static void Key(unsigned char key, int x, int y)
+{
+
+    switch (key) {
+      case 27:
+       exit(1);
+      case '1':
+       mode = !mode;
+       break;
+      case 'W':
+       size++;
+       break;
+      case 'w':
+       size--;
+       if (size < 1) {
+           size = 1;
+       }
+       break;
+      default:
+       return;
+    }
+
+    glutPostRedisplay();
+}
+
+static void Draw(void)
+{
+
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    SetColor(COLOR_YELLOW);
+    glBegin(GL_LINE_STRIP);
+       glVertex2f(-windW/2, 0);
+       glVertex2f(windW/2, 0);
+    glEnd();
+    glBegin(GL_LINE_STRIP);
+       glVertex2f(0, -windH/2);
+       glVertex2f(0, windH/2);
+    glEnd();
+
+    if (mode) {
+       glEnable(GL_BLEND);
+       glEnable(GL_POINT_SMOOTH);
+    } else {
+       glDisable(GL_BLEND);
+       glDisable(GL_POINT_SMOOTH);
+    }
+
+    glPointSize(size);
+    if (mode) {
+       (rgb) ? glColor3f(1.0, 0.0, 0.0) : glIndexf(CI_ANTI_ALIAS_RED);
+    } else {
+       (rgb) ? glColor3f(1.0, 0.0, 0.0) : glIndexf(CI_RED);
+    }
+    glBegin(GL_POINTS);
+       glVertex3fv(point);
+    glEnd();
+
+    glDisable(GL_POINT_SMOOTH);
+    glDisable(GL_BLEND);
+
+    glPointSize(1);
+    SetColor(COLOR_GREEN);
+    glBegin(GL_POINTS);
+       glVertex3fv(point);
+    glEnd();
+
+    glFlush();
+
+    if (doubleBuffer) {
+       glutSwapBuffers();
+    }
+}
+
+static GLenum Args(int argc, char **argv)
+{
+    GLint i;
+
+    rgb = GL_TRUE;
+    doubleBuffer = GL_FALSE;
+
+    for (i = 1; i < argc; i++) {
+       if (strcmp(argv[i], "-ci") == 0) {
+           rgb = GL_FALSE;
+       } else if (strcmp(argv[i], "-rgb") == 0) {
+           rgb = GL_TRUE;
+       } else if (strcmp(argv[i], "-sb") == 0) {
+           doubleBuffer = GL_FALSE;
+       } else if (strcmp(argv[i], "-db") == 0) {
+           doubleBuffer = GL_TRUE;
+       } else {
+           printf("%s (Bad option).\n", argv[i]);
+           return GL_FALSE;
+       }
+    }
+    return GL_TRUE;
+}
+
+int main(int argc, char **argv)
+{
+    glutInit(&argc, argv);
+
+    if (Args(argc, argv) == GL_FALSE) {
+       exit(1);
+    }
+
+    windW = 300;
+    windH = 300;
+    glutInitWindowPosition(0, 0); glutInitWindowSize( windW, windH);
+
+    windType = (rgb) ? GLUT_RGB : GLUT_INDEX;
+    windType |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
+    glutInitDisplayMode(windType);
+
+    if (glutCreateWindow("Point Test") == GL_FALSE) {
+       exit(1);
+    }
+
+    InitMap();
+
+    Init();
+
+    glutReshapeFunc(Reshape);
+    glutKeyboardFunc(Key);
+    glutSpecialFunc(Key2);
+    glutDisplayFunc(Draw);
+    glutMainLoop();
+       return 0;
+}
diff --git a/progs/samples/prim.c b/progs/samples/prim.c
new file mode 100644 (file)
index 0000000..388e015
--- /dev/null
@@ -0,0 +1,546 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <GL/glut.h>
+
+
+#define PIXEL_CENTER(x) ((long)(x) + 0.5)
+
+#define GAP 10
+#define ROWS 3
+#define COLS 4
+
+#define OPENGL_WIDTH 48
+#define OPENGL_HEIGHT 13
+
+
+GLenum rgb, doubleBuffer, windType;
+GLint windW, windH;
+
+GLenum mode1, mode2;
+GLint boxW, boxH;
+GLubyte OpenGL_bits[] = {
+   0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 
+   0x7f, 0xfb, 0xff, 0xff, 0xff, 0x01,
+   0x7f, 0xfb, 0xff, 0xff, 0xff, 0x01, 
+   0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+   0x3e, 0x8f, 0xb7, 0xf9, 0xfc, 0x01, 
+   0x63, 0xdb, 0xb0, 0x8d, 0x0d, 0x00,
+   0x63, 0xdb, 0xb7, 0x8d, 0x0d, 0x00, 
+   0x63, 0xdb, 0xb6, 0x8d, 0x0d, 0x00,
+   0x63, 0x8f, 0xf3, 0xcc, 0x0d, 0x00, 
+   0x63, 0x00, 0x00, 0x0c, 0x4c, 0x0a,
+   0x63, 0x00, 0x00, 0x0c, 0x4c, 0x0e, 
+   0x63, 0x00, 0x00, 0x8c, 0xed, 0x0e,
+   0x3e, 0x00, 0x00, 0xf8, 0x0c, 0x00, 
+};
+
+
+#include "tkmap.c"
+
+static void Init(void)
+{
+
+    mode1 = GL_TRUE;
+    mode2 = GL_TRUE;
+}
+
+static void Reshape(int width, int height)
+{
+
+    windW = (GLint)width;
+    windH = (GLint)height;
+}
+
+static void RotateColorMask(void)
+{
+    static GLint rotation = 0;
+    
+    rotation = (rotation + 1) & 0x3;
+    switch (rotation) {
+      case 0:
+       glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+       glIndexMask( 0xff );
+       break;
+      case 1:
+       glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE);
+       glIndexMask(0xFE);
+       break;
+      case 2:
+       glColorMask(GL_TRUE, GL_FALSE, GL_TRUE, GL_TRUE);
+       glIndexMask(0xFD);
+       break;
+      case 3:
+       glColorMask(GL_TRUE, GL_TRUE, GL_FALSE, GL_TRUE);
+       glIndexMask(0xFB);
+       break;
+    }
+}
+
+static void Key(unsigned char key, int x, int y)
+{
+
+    switch (key) {
+      case 27:
+       exit(1);
+      case '1':
+       mode1 = !mode1;
+       break;
+      case '2':
+       mode2 = !mode2;
+       break;
+      case '3':
+       RotateColorMask();
+       break;
+      default:
+       return;
+    }
+
+    glutPostRedisplay();
+}
+
+static void Viewport(GLint row, GLint column)
+{
+    GLint x, y;
+
+    boxW = (windW - (COLS + 1) * GAP) / COLS;
+    boxH = (windH - (ROWS + 1) * GAP) / ROWS;
+
+    x = GAP + column * (boxW + GAP);
+    y = GAP + row * (boxH + GAP);
+
+    glViewport(x, y, boxW, boxH);
+
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    glOrtho(-boxW/2, boxW/2, -boxH/2, boxH/2, 0.0, 1.0);
+    glMatrixMode(GL_MODELVIEW);
+
+    glEnable(GL_SCISSOR_TEST);
+    glScissor(x, y, boxW, boxH);
+}
+
+static void Point(void)
+{
+    GLint i;
+
+    glBegin(GL_POINTS);
+       SetColor(COLOR_WHITE);
+       glVertex2i(0, 0);
+       for (i = 1; i < 8; i++) {
+           GLint j = i * 2;
+           SetColor(COLOR_BLACK+i);
+           glVertex2i(-j, -j);
+           glVertex2i(-j, 0);
+           glVertex2i(-j, j);
+           glVertex2i(0, j);
+           glVertex2i(j, j);
+           glVertex2i(j, 0);
+           glVertex2i(j, -j);
+           glVertex2i(0, -j);
+       }
+    glEnd();
+}
+
+static void Lines(void)
+{
+    GLint i;
+
+    glPushMatrix();
+
+    glTranslatef(-12, 0, 0);
+    for (i = 1; i < 8; i++) {
+       SetColor(COLOR_BLACK+i);
+       glBegin(GL_LINES);
+           glVertex2i(-boxW/4, -boxH/4);
+           glVertex2i(boxW/4, boxH/4);
+       glEnd();
+       glTranslatef(4, 0, 0);
+    }
+
+    glPopMatrix();
+
+    glBegin(GL_LINES);
+       glVertex2i(0, 0);
+    glEnd();
+}
+
+static void LineStrip(void)
+{
+
+    glBegin(GL_LINE_STRIP);
+       SetColor(COLOR_RED);
+       glVertex2f(PIXEL_CENTER(-boxW/4), PIXEL_CENTER(-boxH/4));
+       SetColor(COLOR_GREEN);
+       glVertex2f(PIXEL_CENTER(-boxW/4), PIXEL_CENTER(boxH/4));
+       SetColor(COLOR_BLUE);
+       glVertex2f(PIXEL_CENTER(boxW/4), PIXEL_CENTER(boxH/4));
+       SetColor(COLOR_WHITE);
+       glVertex2f(PIXEL_CENTER(boxW/4), PIXEL_CENTER(-boxH/4));
+    glEnd();
+
+    glBegin(GL_LINE_STRIP);
+       glVertex2i(0, 0);
+    glEnd();
+}
+
+static void LineLoop(void)
+{
+
+    glBegin(GL_LINE_LOOP);
+       SetColor(COLOR_RED);
+       glVertex2f(PIXEL_CENTER(-boxW/4), PIXEL_CENTER(-boxH/4));
+       SetColor(COLOR_GREEN);
+       glVertex2f(PIXEL_CENTER(-boxW/4), PIXEL_CENTER(boxH/4));
+       SetColor(COLOR_BLUE);
+       glVertex2f(PIXEL_CENTER(boxW/4), PIXEL_CENTER(boxH/4));
+       SetColor(COLOR_WHITE);
+       glVertex2f(PIXEL_CENTER(boxW/4), PIXEL_CENTER(-boxH/4));
+    glEnd();
+
+    glEnable(GL_LOGIC_OP);
+    glLogicOp(GL_XOR);
+
+    glEnable(GL_BLEND);
+    glBlendFunc(GL_ONE, GL_ONE);
+
+    SetColor(COLOR_MAGENTA);
+    glBegin(GL_LINE_LOOP);
+       glVertex2f(PIXEL_CENTER(-boxW/8), PIXEL_CENTER(-boxH/8));
+       glVertex2f(PIXEL_CENTER(-boxW/8), PIXEL_CENTER(boxH/8));
+    glEnd();
+    glBegin(GL_LINE_LOOP);
+       glVertex2f(PIXEL_CENTER(-boxW/8), PIXEL_CENTER(boxH/8+5));
+       glVertex2f(PIXEL_CENTER(boxW/8), PIXEL_CENTER(boxH/8+5));
+    glEnd();
+    glDisable(GL_LOGIC_OP);
+    glDisable(GL_BLEND);
+
+    SetColor(COLOR_GREEN);
+    glBegin(GL_POINTS);
+       glVertex2i(0, 0);
+    glEnd();
+
+    glBegin(GL_LINE_LOOP);
+       glVertex2i(0, 0);
+    glEnd();
+}
+
+static void Bitmap(void)
+{
+
+    glBegin(GL_LINES);
+       SetColor(COLOR_GREEN);
+       glVertex2i(-boxW/2, 0);
+       glVertex2i(boxW/2, 0);
+       glVertex2i(0, -boxH/2);
+       glVertex2i(0, boxH/2);
+       SetColor(COLOR_RED);
+       glVertex2i(0, -3);
+       glVertex2i(0, -3+OPENGL_HEIGHT);
+       SetColor(COLOR_BLUE);
+       glVertex2i(0, -3);
+       glVertex2i(OPENGL_WIDTH, -3);
+    glEnd();
+
+    SetColor(COLOR_GREEN);
+
+    glPixelStorei(GL_UNPACK_LSB_FIRST, GL_TRUE);
+    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+    glRasterPos2i(0, 0);
+    glBitmap(OPENGL_WIDTH, OPENGL_HEIGHT, 0, 3, 0.0, 0.0, OpenGL_bits);
+}
+
+static void Triangles(void)
+{
+
+    glBegin(GL_TRIANGLES);
+       SetColor(COLOR_GREEN);
+       glVertex2i(-boxW/4, -boxH/4);
+       SetColor(COLOR_RED);
+       glVertex2i(-boxW/8, -boxH/16);
+       SetColor(COLOR_BLUE);
+       glVertex2i(boxW/8, -boxH/16);
+
+       SetColor(COLOR_GREEN);
+       glVertex2i(-boxW/4, boxH/4);
+       SetColor(COLOR_RED);
+       glVertex2i(-boxW/8, boxH/16);
+       SetColor(COLOR_BLUE);
+       glVertex2i(boxW/8, boxH/16);
+    glEnd();
+
+    glBegin(GL_TRIANGLES);
+       glVertex2i(0, 0);
+       glVertex2i(-100, 100);
+    glEnd();
+}
+
+static void TriangleStrip(void)
+{
+
+    glBegin(GL_TRIANGLE_STRIP);
+       SetColor(COLOR_GREEN);
+       glVertex2i(-boxW/4, -boxH/4);
+       SetColor(COLOR_RED);
+       glVertex2i(-boxW/4, boxH/4);
+       SetColor(COLOR_BLUE);
+       glVertex2i(0, -boxH/4);
+       SetColor(COLOR_WHITE);
+       glVertex2i(0, boxH/4);
+       SetColor(COLOR_CYAN);
+       glVertex2i(boxW/4, -boxH/4);
+       SetColor(COLOR_YELLOW);
+       glVertex2i(boxW/4, boxH/4);
+    glEnd();
+
+    glBegin(GL_TRIANGLE_STRIP);
+       glVertex2i(0, 0);
+       glVertex2i(-100, 100);
+    glEnd();
+}
+
+static void TriangleFan(void)
+{
+    GLint vx[8][2];
+    GLint x0, y0, x1, y1, x2, y2, x3, y3;
+    GLint i;
+
+    y0 = -boxH/4;
+    y1 = y0 + boxH/2/3;
+    y2 = y1 + boxH/2/3;
+    y3 = boxH/4;
+    x0 = -boxW/4;
+    x1 = x0 + boxW/2/3;
+    x2 = x1 + boxW/2/3;
+    x3 = boxW/4;
+
+    vx[0][0] = x0; vx[0][1] = y1;
+    vx[1][0] = x0; vx[1][1] = y2;
+    vx[2][0] = x1; vx[2][1] = y3;
+    vx[3][0] = x2; vx[3][1] = y3;
+    vx[4][0] = x3; vx[4][1] = y2;
+    vx[5][0] = x3; vx[5][1] = y1;
+    vx[6][0] = x2; vx[6][1] = y0;
+    vx[7][0] = x1; vx[7][1] = y0;
+
+    glBegin(GL_TRIANGLE_FAN);
+       SetColor(COLOR_WHITE);
+       glVertex2i(0, 0);
+       for (i = 0; i < 8; i++) {
+           SetColor(COLOR_WHITE-i);
+           glVertex2iv(vx[i]);
+       }
+    glEnd();
+
+    glBegin(GL_TRIANGLE_FAN);
+       glVertex2i(0, 0);
+       glVertex2i(-100, 100);
+    glEnd();
+}
+
+static void Rect(void)
+{
+
+    SetColor(COLOR_GREEN);
+    glRecti(-boxW/4, -boxH/4, boxW/4, boxH/4);
+}
+
+static void PolygonFunc(void)
+{
+    GLint vx[8][2];
+    GLint x0, y0, x1, y1, x2, y2, x3, y3;
+    GLint i;
+
+    y0 = -boxH/4;
+    y1 = y0 + boxH/2/3;
+    y2 = y1 + boxH/2/3;
+    y3 = boxH/4;
+    x0 = -boxW/4;
+    x1 = x0 + boxW/2/3;
+    x2 = x1 + boxW/2/3;
+    x3 = boxW/4;
+
+    vx[0][0] = x0; vx[0][1] = y1;
+    vx[1][0] = x0; vx[1][1] = y2;
+    vx[2][0] = x1; vx[2][1] = y3;
+    vx[3][0] = x2; vx[3][1] = y3;
+    vx[4][0] = x3; vx[4][1] = y2;
+    vx[5][0] = x3; vx[5][1] = y1;
+    vx[6][0] = x2; vx[6][1] = y0;
+    vx[7][0] = x1; vx[7][1] = y0;
+
+    glBegin(GL_POLYGON);
+       for (i = 0; i < 8; i++) {
+           SetColor(COLOR_WHITE-i);
+           glVertex2iv(vx[i]);
+       }
+    glEnd();
+
+    glBegin(GL_POLYGON);
+       glVertex2i(0, 0);
+       glVertex2i(100, 100);
+    glEnd();
+}
+
+static void Quads(void)
+{
+
+    glBegin(GL_QUADS);
+       SetColor(COLOR_GREEN);
+       glVertex2i(-boxW/4, -boxH/4);
+       SetColor(COLOR_RED);
+       glVertex2i(-boxW/8, -boxH/16);
+       SetColor(COLOR_BLUE);
+       glVertex2i(boxW/8, -boxH/16);
+       SetColor(COLOR_WHITE);
+       glVertex2i(boxW/4, -boxH/4);
+
+       SetColor(COLOR_GREEN);
+       glVertex2i(-boxW/4, boxH/4);
+       SetColor(COLOR_RED);
+       glVertex2i(-boxW/8, boxH/16);
+       SetColor(COLOR_BLUE);
+       glVertex2i(boxW/8, boxH/16);
+       SetColor(COLOR_WHITE);
+       glVertex2i(boxW/4, boxH/4);
+    glEnd();
+
+    glBegin(GL_QUADS);
+       glVertex2i(0, 0);
+       glVertex2i(100, 100);
+       glVertex2i(-100, 100);
+    glEnd();
+}
+
+static void QuadStrip(void)
+{
+
+    glBegin(GL_QUAD_STRIP);
+       SetColor(COLOR_GREEN);
+       glVertex2i(-boxW/4, -boxH/4);
+       SetColor(COLOR_RED);
+       glVertex2i(-boxW/4, boxH/4);
+       SetColor(COLOR_BLUE);
+       glVertex2i(0, -boxH/4);
+       SetColor(COLOR_WHITE);
+       glVertex2i(0, boxH/4);
+       SetColor(COLOR_CYAN);
+       glVertex2i(boxW/4, -boxH/4);
+       SetColor(COLOR_YELLOW);
+       glVertex2i(boxW/4, boxH/4);
+    glEnd();
+
+    glBegin(GL_QUAD_STRIP);
+       glVertex2i(0, 0);
+       glVertex2i(100, 100);
+       glVertex2i(-100, 100);
+    glEnd();
+}
+
+static void Draw(void)
+{
+
+    glViewport(0, 0, windW, windH);
+    glDisable(GL_SCISSOR_TEST);
+
+    glPushAttrib(GL_COLOR_BUFFER_BIT);
+
+    glColorMask(1, 1, 1, 1);
+    glIndexMask(~0);
+
+    glClearColor(0.0, 0.0, 0.0, 0.0);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    glPopAttrib();
+
+    if (mode1) {
+       glShadeModel(GL_SMOOTH);
+    } else {
+       glShadeModel(GL_FLAT);
+    }
+
+    if (mode2) {
+       glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+    } else {
+       glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+    }
+
+    Viewport(0, 0); Point();
+    Viewport(0, 1); Lines();
+    Viewport(0, 2); LineStrip();
+    Viewport(0, 3); LineLoop();
+
+    Viewport(1, 0); Bitmap();
+
+    Viewport(1, 1); TriangleFan();
+    Viewport(1, 2); Triangles();
+    Viewport(1, 3); TriangleStrip();
+
+    Viewport(2, 0); Rect();
+    Viewport(2, 1); PolygonFunc();
+    Viewport(2, 2); Quads();
+    Viewport(2, 3); QuadStrip();
+
+    glFlush();
+
+    if (doubleBuffer) {
+       glutSwapBuffers();
+    }
+}
+
+static GLenum Args(int argc, char **argv)
+{
+    GLint i;
+
+    rgb = GL_TRUE;
+    doubleBuffer = GL_FALSE;
+
+    for (i = 1; i < argc; i++) {
+       if (strcmp(argv[i], "-ci") == 0) {
+           rgb = GL_FALSE;
+       } else if (strcmp(argv[i], "-rgb") == 0) {
+           rgb = GL_TRUE;
+       } else if (strcmp(argv[i], "-sb") == 0) {
+           doubleBuffer = GL_FALSE;
+       } else if (strcmp(argv[i], "-db") == 0) {
+           doubleBuffer = GL_TRUE;
+       } else {
+           printf("%s (Bad option).\n", argv[i]);
+           return GL_FALSE;
+       }
+    }
+    return GL_TRUE;
+}
+
+int main(int argc, char **argv)
+{
+    glutInit(&argc, argv);
+
+    if (Args(argc, argv) == GL_FALSE) {
+       exit(1);
+    }
+
+    windW = 600;
+    windH = 300;
+    glutInitWindowPosition(0, 0); glutInitWindowSize( windW, windH);
+
+    windType = (rgb) ? GLUT_RGB : GLUT_INDEX;
+    windType |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
+    glutInitDisplayMode(windType);
+
+    if (glutCreateWindow("Primitive Test") == GL_FALSE) {
+       exit(1);
+    }
+
+    InitMap();
+
+    Init();
+
+    glutReshapeFunc(Reshape);
+    glutKeyboardFunc(Key);
+    glutDisplayFunc(Draw);
+    glutMainLoop();
+       return 0;
+}
diff --git a/progs/samples/quad.c b/progs/samples/quad.c
new file mode 100644 (file)
index 0000000..8dec28b
--- /dev/null
@@ -0,0 +1,455 @@
+/*
+ * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the name of
+ * Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
+ * ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <GL/glut.h>
+
+
+#ifndef CALLBACK
+#define CALLBACK
+#endif
+
+
+#define PI 3.141592654
+#define        BLACK 0
+#define        GRAY 128
+#define        WHITE 255
+#define RD 0xA4,0x00,0x00,0xFF
+#define WT 0xFF,0xFF,0xFF,0xFF
+#define        brickImageWidth 16
+#define        brickImageHeight 16
+
+
+#include "loadppm.c"
+
+GLenum rgb, doubleBuffer;
+
+#include "tkmap.c"
+
+float black[3] = {
+    0.0, 0.0, 0.0
+};
+float blue[3] =  {
+    0.0, 0.0, 1.0
+};
+float gray[3] =  {
+    0.5, 0.5, 0.5
+};
+float white[3] = {
+    1.0, 1.0, 1.0
+};
+
+GLenum doDither = GL_TRUE;
+GLenum shade = GL_TRUE;
+GLenum texture = GL_TRUE;
+
+float xRotation = 30.0, yRotation = 30.0, zRotation = 0.0;
+GLint radius1, radius2;
+GLdouble angle1, angle2;
+GLint slices, stacks;
+GLint height;
+GLint orientation = GLU_OUTSIDE;
+GLint whichQuadric=0;
+GLUquadricObj *quadObj;
+
+GLubyte brickImage[4*brickImageWidth*brickImageHeight] = {
+    RD, RD, RD, RD, RD, RD, RD, RD, RD, WT, RD, RD, RD, RD, RD, RD,
+    RD, RD, RD, RD, RD, RD, RD, RD, RD, WT, RD, RD, RD, RD, RD, RD,
+    RD, RD, RD, RD, RD, RD, RD, RD, RD, WT, RD, RD, RD, RD, RD, RD,
+    RD, RD, RD, RD, RD, RD, RD, RD, RD, WT, RD, RD, RD, RD, RD, RD,
+    WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT,
+    RD, RD, RD, WT, RD, RD, RD, RD, RD, RD, RD, RD, RD, WT, RD, RD,
+    RD, RD, RD, WT, RD, RD, RD, RD, RD, RD, RD, RD, RD, WT, RD, RD,
+    RD, RD, RD, WT, RD, RD, RD, RD, RD, RD, RD, RD, RD, WT, RD, RD,
+    RD, RD, RD, WT, RD, RD, RD, RD, RD, RD, RD, RD, RD, WT, RD, RD,
+    WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT,
+    RD, RD, RD, RD, RD, RD, RD, WT, RD, RD, RD, RD, RD, RD, RD, RD,
+    RD, RD, RD, RD, RD, RD, RD, WT, RD, RD, RD, RD, RD, RD, RD, RD,
+    RD, RD, RD, RD, RD, RD, RD, WT, RD, RD, RD, RD, RD, RD, RD, RD,
+    RD, RD, RD, RD, RD, RD, RD, WT, RD, RD, RD, RD, RD, RD, RD, RD,
+    WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT, WT,
+    RD, RD, RD, RD, WT, RD, RD, RD, RD, RD, RD, RD, RD, RD, WT, RD
+};
+char *texFileName = 0;
+
+
+static void CALLBACK ErrorHandler(GLenum which)
+{
+
+    fprintf(stderr, "Quad Error: %s\n", gluErrorString(which));
+}
+
+static void Init(void)
+{
+    static GLint colorIndexes[3] = {0, 200, 255};
+    static float ambient[] = {0.1, 0.1, 0.1, 1.0};
+    static float diffuse[] = {0.5, 1.0, 1.0, 1.0};
+    static float position[] = {90.0, 90.0, 150.0, 0.0};
+    static float front_mat_shininess[] = {30.0};
+    static float front_mat_specular[] = {0.2, 0.2, 0.2, 1.0};
+    static float front_mat_diffuse[] = {0.5, 0.28, 0.38, 1.0};
+    static float back_mat_shininess[] = {50.0};
+    static float back_mat_specular[] = {0.5, 0.5, 0.2, 1.0};
+    static float back_mat_diffuse[] = {1.0, 1.0, 0.2, 1.0};
+    static float lmodel_ambient[] = {1.0, 1.0, 1.0, 1.0};
+    static float lmodel_twoside[] = {GL_TRUE};
+    static float decal[] = {GL_DECAL};
+    static float repeat[] = {GL_REPEAT};
+    static float nearest[] = {GL_NEAREST};
+    static PPMImage *image;
+
+    if (!rgb) {
+       SetGreyRamp();
+    }
+    glClearColor(0.0, 0.0, 0.0, 0.0);
+    
+    glEnable(GL_DEPTH_TEST);
+
+    glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
+    glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
+    glLightfv(GL_LIGHT0, GL_POSITION, position);
+    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
+    glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
+    glEnable(GL_LIGHTING);
+    glEnable(GL_LIGHT0);
+
+    glMaterialfv(GL_FRONT, GL_SHININESS, front_mat_shininess);
+    glMaterialfv(GL_FRONT, GL_SPECULAR, front_mat_specular);
+    glMaterialfv(GL_FRONT, GL_DIFFUSE, front_mat_diffuse);
+    glMaterialfv(GL_BACK, GL_SHININESS, back_mat_shininess);
+    glMaterialfv(GL_BACK, GL_SPECULAR, back_mat_specular);
+    glMaterialfv(GL_BACK, GL_DIFFUSE, back_mat_diffuse);
+    if (!rgb) {
+       glMaterialiv( GL_FRONT_AND_BACK, GL_COLOR_INDEXES, colorIndexes);
+    }
+
+    glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, decal);
+    glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, repeat);
+    glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, repeat);
+    glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, nearest);
+    glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, nearest);
+    if (texFileName) {
+       image = LoadPPM(texFileName);
+       glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+       gluBuild2DMipmaps(GL_TEXTURE_2D, 3, image->sizeX, image->sizeY,
+                         GL_RGB, GL_UNSIGNED_BYTE, image->data);
+    } else {
+       glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+       glTexImage2D(GL_TEXTURE_2D, 0, 4, brickImageWidth, brickImageHeight,
+                    0, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid *)brickImage);
+    }
+
+    quadObj = gluNewQuadric();
+    gluQuadricCallback(quadObj, GLU_ERROR, ErrorHandler);
+
+    radius1 = 10;
+    radius2 = 5;
+    angle1 = 90;
+    angle2 = 180;
+    slices = 16;
+    stacks = 10;
+    height = 20;
+}
+
+static void Reshape(int width, int height)
+{
+
+    glViewport(0, 0, (GLint)width, (GLint)height);
+
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    glFrustum(-1, 1, -1, 1, 1, 10);
+    gluLookAt(2, 2, 2, 0, 0, 0, 0, 0, 1);
+    glMatrixMode(GL_MODELVIEW);
+}
+
+static void Key2(int key, int x, int y)
+{
+
+    switch (key) {
+      case GLUT_KEY_LEFT:
+       yRotation += 5;
+       break;
+      case GLUT_KEY_RIGHT:
+       yRotation -= 5;
+       break;
+      case GLUT_KEY_UP:
+       xRotation += 5;
+       break;
+      case GLUT_KEY_DOWN:
+       xRotation -= 5;
+       break;
+      default:
+       return;
+    }
+
+    glutPostRedisplay();
+}
+
+static void Key(unsigned char key, int x, int y)
+{
+
+    switch (key) {
+      case 27:
+       exit(1);
+
+      case 'X':
+       zRotation += 5;
+       break;
+      case 'x':
+       zRotation -= 5;
+       break;
+
+      case '1':
+       gluQuadricDrawStyle(quadObj, GLU_FILL);
+       break;
+      case '2':
+       gluQuadricDrawStyle(quadObj, GLU_POINT);
+       break;
+      case '3':
+       gluQuadricDrawStyle(quadObj, GLU_LINE);
+       break;
+      case '4':
+       gluQuadricDrawStyle(quadObj, GLU_SILHOUETTE);
+       break;
+
+      case '0':
+       shade = !shade;
+       if (shade) {
+           glShadeModel(GL_SMOOTH);
+           gluQuadricNormals(quadObj, GLU_SMOOTH);
+       } else {
+           glShadeModel(GL_FLAT);
+           gluQuadricNormals(quadObj, GLU_FLAT);
+       }
+       break;
+
+      case 'A':
+       stacks++;
+       break;
+      case 'a':
+       stacks--;
+       break;
+    
+      case 'S':
+       slices++;
+       break;
+      case 's':
+       slices--;
+       break;
+
+      case 'd':
+       switch(orientation) {
+         case GLU_OUTSIDE:
+           orientation = GLU_INSIDE;
+           break;
+         case GLU_INSIDE:
+         default:
+           orientation = GLU_OUTSIDE;
+           break;
+       }
+       gluQuadricOrientation(quadObj, orientation);
+       break;
+
+      case 'f':
+       whichQuadric = (whichQuadric + 1) % 4;
+       break;
+
+      case 'G':
+       radius1 += 1;
+       break;
+      case 'g':
+       radius1 -= 1;
+       break;
+
+      case 'J':
+       radius2 += 1;
+       break;
+      case 'j':
+       radius2 -= 1;
+       break;
+
+      case 'H':
+       height += 2;
+       break;
+      case 'h':
+       height -= 2;
+       break;
+
+      case 'K':
+       angle1 += 5;
+       break;
+      case 'k':
+       angle1 -= 5;
+       break;
+
+      case 'L':
+       angle2 += 5;
+       break;
+      case 'l':
+       angle2 -= 5;
+       break;
+
+      case 'z':
+        texture = !texture;
+       if (texture) {
+           gluQuadricTexture(quadObj, GL_TRUE);
+           glEnable(GL_TEXTURE_2D);
+       } else {
+           gluQuadricTexture(quadObj, GL_FALSE);
+           glDisable(GL_TEXTURE_2D);
+       }
+       break;
+
+      case 'q':
+       glDisable(GL_CULL_FACE);
+       break;
+      case 'w':
+       glEnable(GL_CULL_FACE);
+       glCullFace(GL_FRONT);
+       break;
+      case 'e':
+       glEnable(GL_CULL_FACE);
+       glCullFace(GL_BACK);
+       break;
+
+      case 'r':
+       glFrontFace(GL_CW);
+       break;
+      case 't': 
+       glFrontFace(GL_CCW);
+       break;
+
+      case 'y':
+       doDither = !doDither;
+       (doDither) ? glEnable(GL_DITHER) : glDisable(GL_DITHER);
+       break;
+      default:
+       return;
+    }
+
+    glutPostRedisplay();
+}
+
+static void Draw(void)
+{
+
+    glLoadIdentity();
+    glRotatef(xRotation, 1, 0, 0);
+    glRotatef(yRotation, 0, 1, 0);
+    glRotatef(zRotation, 0, 0, 1);
+
+    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+
+    glColor3f(1.0, 1.0, 1.0);
+    switch (whichQuadric) {
+      case 0:
+       glTranslatef(0, 0, -height/20.0);
+       gluCylinder(quadObj, radius1/10.0, radius2/10.0, height/10.0, 
+                   slices, stacks);
+       break;
+      case 1:
+       gluSphere(quadObj, radius1/10.0, slices, stacks);
+       break;
+      case 2:
+       gluPartialDisk(quadObj, radius2/10.0, radius1/10.0, slices, 
+                      stacks, angle1, angle2);
+       break;
+      case 3:
+       gluDisk(quadObj, radius2/10.0, radius1/10.0, slices, stacks);
+       break;
+    }
+
+    glFlush();
+
+    if (doubleBuffer) {
+       glutSwapBuffers();
+    }
+}
+
+static GLenum Args(int argc, char **argv)
+{
+    GLint i;
+
+    rgb = GL_TRUE;
+    doubleBuffer = GL_FALSE;
+
+    for (i = 1; i < argc; i++) {
+       if (strcmp(argv[i], "-ci") == 0) {
+           rgb = GL_FALSE;
+       } else if (strcmp(argv[i], "-rgb") == 0) {
+           rgb = GL_TRUE;
+       } else if (strcmp(argv[i], "-sb") == 0) {
+           doubleBuffer = GL_FALSE;
+       } else if (strcmp(argv[i], "-db") == 0) {
+           doubleBuffer = GL_TRUE;
+       } else if (strcmp(argv[i], "-f") == 0) {
+           if (i+1 >= argc || argv[i+1][0] == '-') {
+               printf("-f (No file name).\n");
+               return GL_FALSE;
+           } else {
+               texFileName = argv[++i];
+           }
+       } else {
+           printf("%s (Bad option).\n", argv[i]);
+           return GL_FALSE;
+       }
+    }
+    return GL_TRUE;
+}
+
+int main(int argc, char **argv)
+{
+    GLenum type;
+
+    glutInit(&argc, argv);
+
+    if (Args(argc, argv) == GL_FALSE) {
+       exit(1);
+    }
+
+    glutInitWindowPosition(0, 0); glutInitWindowSize( 300, 300);
+
+    type = GLUT_DEPTH;
+    type |= (rgb) ? GLUT_RGB : GLUT_INDEX;
+    type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
+    glutInitDisplayMode(type);
+
+    if (glutCreateWindow("Quad Test") == GL_FALSE) {
+       exit(1);
+    }
+
+    InitMap();
+
+    Init();
+
+    glutReshapeFunc(Reshape);
+    glutKeyboardFunc(Key);
+    glutSpecialFunc(Key2);
+    glutDisplayFunc(Draw);
+    glutMainLoop();
+       return 0;
+}
diff --git a/progs/samples/rgbtoppm.c b/progs/samples/rgbtoppm.c
new file mode 100644 (file)
index 0000000..0bc7348
--- /dev/null
@@ -0,0 +1,273 @@
+
+/* texture.c - by David Blythe, SGI */
+
+/* texload is a simplistic routine for reading an SGI .rgb image file. */
+
+#include <stdio.h>
+#include <stdlib.h> 
+#include <string.h>
+
+#include <GL/glut.h>
+
+typedef struct _ImageRec {
+    unsigned short imagic;
+    unsigned short type;
+    unsigned short dim;
+    unsigned short xsize, ysize, zsize;
+    unsigned int min, max;
+    unsigned int wasteBytes;
+    char name[80];
+    unsigned long colorMap;
+    FILE *file;
+    unsigned char *tmp;
+    unsigned long rleEnd;
+    unsigned int *rowStart;
+    int *rowSize;
+} ImageRec;
+
+void
+rgbtorgb(unsigned char *r,unsigned char *g,unsigned char *b,unsigned char *l,int n) {
+    while(n--) {
+        l[0] = r[0];
+        l[1] = g[0];
+        l[2] = b[0];
+        l += 3; r++; g++; b++;
+    }
+}
+
+static void
+ConvertShort(unsigned short *array, unsigned int length) {
+    unsigned short b1, b2;
+    unsigned char *ptr;
+
+    ptr = (unsigned char *)array;
+    while (length--) {
+        b1 = *ptr++;
+        b2 = *ptr++;
+        *array++ = (b1 << 8) | (b2);
+    }
+}
+
+static void
+ConvertUint(unsigned *array, unsigned int length) {
+    unsigned int b1, b2, b3, b4;
+    unsigned char *ptr;
+
+    ptr = (unsigned char *)array;
+    while (length--) {
+        b1 = *ptr++;
+        b2 = *ptr++;
+        b3 = *ptr++;
+        b4 = *ptr++;
+        *array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4);
+    }
+}
+
+static ImageRec *ImageOpen(char *fileName)
+{
+    union {
+        int testWord;
+        char testByte[4];
+    } endianTest;
+    ImageRec *image;
+    int swapFlag;
+    int x;
+
+    endianTest.testWord = 1;
+    if (endianTest.testByte[0] == 1) {
+        swapFlag = 1;
+    } else {
+        swapFlag = 0;
+    }
+
+    image = (ImageRec *)malloc(sizeof(ImageRec));
+    if (image == NULL) {
+        fprintf(stderr, "Out of memory!\n");
+        exit(1);
+    }
+    if ((image->file = fopen(fileName, "rb")) == NULL) {
+       return NULL;
+    }
+
+    fread(image, 1, 12, image->file);
+
+    if (swapFlag) {
+        ConvertShort(&image->imagic, 6);
+    }
+
+    image->tmp = (unsigned char *)malloc(image->xsize*256);
+    if (image->tmp == NULL) {
+        fprintf(stderr, "\nOut of memory!\n");
+        exit(1);
+    }
+
+    if ((image->type & 0xFF00) == 0x0100) {
+        x = image->ysize * image->zsize * (int) sizeof(unsigned);
+        image->rowStart = (unsigned *)malloc(x);
+        image->rowSize = (int *)malloc(x);
+        if (image->rowStart == NULL || image->rowSize == NULL) {
+            fprintf(stderr, "\nOut of memory!\n");
+            exit(1);
+        }
+        image->rleEnd = 512 + (2 * x);
+        fseek(image->file, 512, SEEK_SET);
+        fread(image->rowStart, 1, x, image->file);
+        fread(image->rowSize, 1, x, image->file);
+        if (swapFlag) {
+            ConvertUint(image->rowStart, x/(int) sizeof(unsigned));
+            ConvertUint((unsigned *)image->rowSize, x/(int) sizeof(int));
+        }
+    }
+    return image;
+}
+
+static void
+ImageClose(ImageRec *image) {
+    fclose(image->file);
+    free(image->tmp);
+    free(image);
+}
+
+static void
+ImageGetRow(ImageRec *image, unsigned char *buf, int y, int z) {
+    unsigned char *iPtr, *oPtr, pixel;
+    int count;
+
+    if ((image->type & 0xFF00) == 0x0100) {
+        fseek(image->file, (long) image->rowStart[y+z*image->ysize], SEEK_SET);
+        fread(image->tmp, 1, (unsigned int)image->rowSize[y+z*image->ysize],
+              image->file);
+
+        iPtr = image->tmp;
+        oPtr = buf;
+        for (;;) {
+            pixel = *iPtr++;
+            count = (int)(pixel & 0x7F);
+            if (!count) {
+                return;
+            }
+            if (pixel & 0x80) {
+                while (count--) {
+                    *oPtr++ = *iPtr++;
+                }
+            } else {
+                pixel = *iPtr++;
+                while (count--) {
+                    *oPtr++ = pixel;
+                }
+            }
+        }
+    } else {
+        fseek(image->file, 512+(y*image->xsize)+(z*image->xsize*image->ysize),
+              SEEK_SET);
+        fread(buf, 1, image->xsize, image->file);
+    }
+}
+
+GLubyte *
+read_alpha_texture(char *name, int *width, int *height)
+{
+    unsigned char *base, *lptr;
+    ImageRec *image;
+    int y;
+
+    image = ImageOpen(name);
+    if(!image) {
+        return NULL;
+    }
+
+    (*width)=image->xsize;
+    (*height)=image->ysize;
+    if (image->zsize != 1) {
+      ImageClose(image);
+      return NULL;
+    }
+
+    base = (unsigned char *)malloc(image->xsize*image->ysize*sizeof(unsigned char));
+    lptr = base;
+    for(y=0; y<image->ysize; y++) {
+        ImageGetRow(image,lptr,y,0);
+        lptr += image->xsize;
+    }
+    ImageClose(image);
+
+    return (unsigned char *) base;
+}
+
+GLubyte *
+read_rgb_texture(char *name, int *width, int *height)
+{
+    unsigned char *base, *ptr;
+    unsigned char *rbuf, *gbuf, *bbuf, *abuf;
+    ImageRec *image;
+    int y;
+
+    image = ImageOpen(name);
+    
+    if(!image)
+        return NULL;
+    (*width)=image->xsize;
+    (*height)=image->ysize;
+    if (image->zsize != 3 && image->zsize != 4) {
+      ImageClose(image);
+      return NULL;
+    }
+
+    base = (unsigned char*)malloc(image->xsize*image->ysize*sizeof(unsigned int)*3);
+    rbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
+    gbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
+    bbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
+    abuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
+    if(!base || !rbuf || !gbuf || !bbuf || !abuf) {
+      if (base) free(base);
+      if (rbuf) free(rbuf);
+      if (gbuf) free(gbuf);
+      if (bbuf) free(bbuf);
+      if (abuf) free(abuf);
+      return NULL;
+    }
+    ptr = base;
+    for(y=0; y<image->ysize; y++) {
+        if(image->zsize == 4) {
+            ImageGetRow(image,rbuf,y,0);
+            ImageGetRow(image,gbuf,y,1);
+            ImageGetRow(image,bbuf,y,2);
+            ImageGetRow(image,abuf,y,3);  /* Discard. */
+            rgbtorgb(rbuf,gbuf,bbuf,ptr,image->xsize);
+            ptr += (image->xsize * 3);
+        } else {
+            ImageGetRow(image,rbuf,y,0);
+            ImageGetRow(image,gbuf,y,1);
+            ImageGetRow(image,bbuf,y,2);
+            rgbtorgb(rbuf,gbuf,bbuf,ptr,image->xsize);
+            ptr += (image->xsize * 3);
+        }
+    }
+    ImageClose(image);
+    free(rbuf);
+    free(gbuf);
+    free(bbuf);
+    free(abuf);
+
+    return (GLubyte *) base;
+}
+
+int main(int argc, char **argv)
+{
+       int width, height;
+       GLubyte *data;
+
+       if (argc != 2)
+       {
+               fprintf(stderr, "usage: %s <filename>\n", argv[0]);
+               return 1;
+       }
+
+       data = read_rgb_texture(argv[1], &width, &height);
+
+       printf("P6\n%d %d\n255\n", width, height);
+       fwrite(data, width * 3, height, stdout);
+
+       return 0;
+}
+
diff --git a/progs/samples/select.c b/progs/samples/select.c
new file mode 100644 (file)
index 0000000..5a73a45
--- /dev/null
@@ -0,0 +1,456 @@
+/*
+ * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the name of
+ * Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
+ * ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+#include <time.h>
+#include <GL/glut.h>
+
+
+#define MAXOBJS 10000
+#define MAXSELECT 100
+#define MAXFEED 300
+#define        SOLID 1
+#define        LINE 2
+#define        POINT 3
+
+
+GLint windW, windH;
+
+GLuint selectBuf[MAXSELECT];
+GLfloat feedBuf[MAXFEED];
+GLint vp[4];
+float zRotation = 90.0;
+float zoom = 1.0;
+GLint objectCount;
+GLint numObjects;
+struct object {
+    float v1[2];
+    float v2[2];
+    float v3[2];
+    float color[3];
+} objects[MAXOBJS];
+GLenum linePoly = GL_FALSE;
+
+
+static void InitObjects(GLint num)
+{
+    GLint i;
+    float x, y;
+
+    if (num > MAXOBJS) {
+       num = MAXOBJS;
+    }
+    if (num < 1) {
+       num = 1;
+    }
+    objectCount = num;
+
+    srand((unsigned int)time(NULL));
+    for (i = 0; i < num; i++) {
+       x = (rand() % 300) - 150;
+       y = (rand() % 300) - 150;
+
+       objects[i].v1[0] = x + (rand() % 50) - 25;
+       objects[i].v2[0] = x + (rand() % 50) - 25;
+       objects[i].v3[0] = x + (rand() % 50) - 25;
+       objects[i].v1[1] = y + (rand() % 50) - 25;
+       objects[i].v2[1] = y + (rand() % 50) - 25;
+       objects[i].v3[1] = y + (rand() % 50) - 25;
+       objects[i].color[0] = ((rand() % 100) + 50) / 150.0;
+       objects[i].color[1] = ((rand() % 100) + 50) / 150.0;
+       objects[i].color[2] = ((rand() % 100) + 50) / 150.0;
+    }
+}
+
+static void Init(void)
+{
+
+    numObjects = 10;
+    InitObjects(numObjects);
+    glGetIntegerv(GL_VIEWPORT, vp);
+}
+
+static void Reshape(int width, int height)
+{
+
+    windW = (GLint)width;
+    windH = (GLint)height;
+}
+
+static void Render(GLenum mode)
+{
+    GLint i;
+
+    for (i = 0; i < objectCount; i++) {
+       if (mode == GL_SELECT) {
+           glLoadName(i);
+       }
+       glColor3fv(objects[i].color);
+       glBegin(GL_POLYGON);
+           glVertex2fv(objects[i].v1);
+           glVertex2fv(objects[i].v2);
+           glVertex2fv(objects[i].v3);
+       glEnd();
+    }
+}
+
+static GLint DoSelect(GLint x, GLint y)
+{
+    GLint hits;
+
+    glSelectBuffer(MAXSELECT, selectBuf);
+    (void)glRenderMode(GL_SELECT);
+    glInitNames();
+    glPushName(~0);
+
+    glPushMatrix();
+
+    glViewport(0, 0, windW, windH);
+    glGetIntegerv(GL_VIEWPORT, vp);
+
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    gluPickMatrix(x, windH-y, 4, 4, vp);
+    gluOrtho2D(-175, 175, -175, 175);
+    glMatrixMode(GL_MODELVIEW);
+
+    glClearColor(0.0, 0.0, 0.0, 0.0);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    glScalef(zoom, zoom, zoom);
+    glRotatef(zRotation, 0, 0, 1);
+
+    Render(GL_SELECT);
+
+    glPopMatrix();
+    
+    hits = glRenderMode(GL_RENDER); 
+    if (hits <= 0) {
+       return -1;
+    }
+
+    return selectBuf[(hits-1)*4+3];
+}
+
+static void RecolorTri(GLint h)
+{
+
+    objects[h].color[0] = ((rand() % 100) + 50) / 150.0;
+    objects[h].color[1] = ((rand() % 100) + 50) / 150.0;
+    objects[h].color[2] = ((rand() % 100) + 50) / 150.0;
+}
+
+static void DeleteTri(GLint h)
+{
+
+    objects[h] = objects[objectCount-1];
+    objectCount--;
+}
+
+static void GrowTri(GLint h)
+{
+    float v[2];
+    float *oldV;
+    GLint i;
+
+    v[0] = objects[h].v1[0] + objects[h].v2[0] + objects[h].v3[0];
+    v[1] = objects[h].v1[1] + objects[h].v2[1] + objects[h].v3[1];
+    v[0] /= 3;
+    v[1] /= 3;
+
+    for (i = 0; i < 3; i++) {
+       switch (i) {
+         case 0:
+           oldV = objects[h].v1;
+           break;
+         case 1:
+           oldV = objects[h].v2;
+           break;
+         case 2:
+           oldV = objects[h].v3;
+           break;
+       }
+       oldV[0] = 1.5 * (oldV[0] - v[0]) + v[0];
+       oldV[1] = 1.5 * (oldV[1] - v[1]) + v[1];
+    }
+}
+
+static void Mouse(int button, int state, int mouseX, int mouseY)
+{
+    GLint hit;
+
+    if (state != GLUT_DOWN)
+       return;
+
+    hit = DoSelect((GLint)mouseX, (GLint)mouseY);
+    if (hit != -1) {
+       if (button == GLUT_LEFT_BUTTON) {
+           RecolorTri(hit);
+       }
+       if (button == GLUT_MIDDLE_BUTTON) {
+           GrowTri(hit);
+       }
+       if (button == GLUT_RIGHT_BUTTON) {
+           DeleteTri(hit);
+       }
+    }
+
+    glutPostRedisplay();
+}
+
+static void Draw(void)
+{
+
+    glPushMatrix();
+
+    glViewport(0, 0, windW, windH);
+    glGetIntegerv(GL_VIEWPORT, vp);
+
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    gluOrtho2D(-175, 175, -175, 175);
+    glMatrixMode(GL_MODELVIEW);
+
+    glClearColor(0.0, 0.0, 0.0, 0.0);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    glScalef(zoom, zoom, zoom);
+    glRotatef(zRotation, 0, 0, 1);
+
+    Render(GL_RENDER);
+
+    glPopMatrix();
+
+    glFlush();
+}
+
+static void DrawZoom(GLint x, GLint y)
+{
+
+    glPushMatrix();
+
+    glViewport(0, 0, windW, windH);
+    glGetIntegerv(GL_VIEWPORT, vp);
+
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    gluPickMatrix(x, windH-y, 4, 4, vp);
+    gluOrtho2D(-175, 175, -175, 175);
+    glMatrixMode(GL_MODELVIEW);
+
+    glClearColor(0.0, 0.0, 0.0, 0.0);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    glScalef(zoom, zoom, zoom);
+    glRotatef(zRotation, 0, 0, 1);
+
+    Render(GL_RENDER);
+
+    glPopMatrix();
+}
+
+static void DumpFeedbackVert(GLint *i, GLint n)
+{
+    GLint index;
+
+    index = *i;
+    if (index+7 > n) {
+       *i = n;
+       printf("  ???\n");
+       return;
+    }
+    printf("  (%g %g %g), color = (%4.2f %4.2f %4.2f)\n",
+          feedBuf[index],
+          feedBuf[index+1],
+          feedBuf[index+2],
+          feedBuf[index+3],
+          feedBuf[index+4],
+          feedBuf[index+5]);
+    index += 7;
+    *i = index;
+}
+
+static void DrawFeedback(GLint n)
+{
+    GLint i;
+    GLint verts;
+
+    printf("Feedback results (%d floats):\n", n);
+    for (i = 0; i < n; i++) {
+       switch ((GLint)feedBuf[i]) {
+         case GL_POLYGON_TOKEN:
+           printf("Polygon");
+           i++;
+           if (i < n) {
+               verts = (GLint)feedBuf[i];
+               i++;
+               printf(": %d vertices", verts);
+           } else {
+               verts = 0;
+           }
+           printf("\n");
+           while (verts) {
+               DumpFeedbackVert(&i, n);
+               verts--;
+           }
+           i--;
+           break;
+         case GL_LINE_TOKEN:
+           printf("Line:\n");
+           i++;
+           DumpFeedbackVert(&i, n);
+           DumpFeedbackVert(&i, n);
+           i--;
+           break;
+         case GL_LINE_RESET_TOKEN:
+           printf("Line Reset:\n");
+           i++;
+           DumpFeedbackVert(&i, n);
+           DumpFeedbackVert(&i, n);
+           i--;
+           break;
+         default:
+           printf("%9.2f\n", feedBuf[i]);
+           break;
+       }
+    }
+    if (i == MAXFEED) {
+       printf("...\n");
+    }
+    printf("\n");
+}
+
+static void DoFeedback(void) 
+{
+    GLint x;
+
+    glFeedbackBuffer(MAXFEED, GL_3D_COLOR, feedBuf);
+    (void)glRenderMode(GL_FEEDBACK);
+
+    glPushMatrix();
+
+    glViewport(0, 0, windW, windH);
+    glGetIntegerv(GL_VIEWPORT, vp);
+
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    gluOrtho2D(-175, 175, -175, 175);
+    glMatrixMode(GL_MODELVIEW);
+
+    glClearColor(0.0, 0.0, 0.0, 0.0);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    glScalef(zoom, zoom, zoom);
+    glRotatef(zRotation, 0, 0, 1);
+
+    Render(GL_FEEDBACK);
+
+    glPopMatrix();
+    
+    x = glRenderMode(GL_RENDER); 
+    if (x == -1) {
+       x = MAXFEED;
+    }
+
+    DrawFeedback((GLint)x);
+}
+
+static void Key2(int key, int x, int y)
+{
+    switch (key) {
+      case GLUT_KEY_LEFT:
+       zRotation += 0.5;
+       break;
+      case GLUT_KEY_RIGHT:
+       zRotation -= 0.5;
+       break;
+      default:
+       return;
+    }
+
+    glutPostRedisplay();
+}
+
+static void Key(unsigned char key, int x, int y)
+{
+    switch (key) {
+      case 27:
+       exit(1);
+      case 'Z':
+       zoom /= 0.75;
+       break;
+      case 'z':
+       zoom *= 0.75;
+       break;
+      case 'f':
+       DoFeedback();
+       break;
+      case 'd':
+       DrawZoom(x, y);
+       break;
+      case 'l':
+       linePoly = !linePoly;
+       if (linePoly) {
+           glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+       } else {
+           glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+       }
+       break;
+      default:
+       return;
+    }
+
+    glutPostRedisplay();
+}
+
+int main(int argc, char **argv)
+{
+    GLenum type;
+
+    glutInit(&argc, argv);
+
+    windW = 300;
+    windH = 300;
+    glutInitWindowPosition(0, 0); glutInitWindowSize( windW, windH);
+
+    type = GLUT_RGB | GLUT_SINGLE;
+    glutInitDisplayMode(type);
+
+    if (glutCreateWindow("Select Test") == GL_FALSE) {
+       exit(1);
+    }
+
+    Init();
+
+    glutReshapeFunc(Reshape);
+    glutKeyboardFunc(Key);
+    glutSpecialFunc(Key2);
+    glutMouseFunc(Mouse);
+    glutDisplayFunc(Draw);
+    glutMainLoop();
+       return 0;
+}
diff --git a/progs/samples/shape.c b/progs/samples/shape.c
new file mode 100644 (file)
index 0000000..d342ee5
--- /dev/null
@@ -0,0 +1,345 @@
+/*
+ * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the name of
+ * Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
+ * ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <GL/glut.h>
+
+
+#define OPENGL_WIDTH 24
+#define OPENGL_HEIGHT 13
+
+
+GLenum rgb, doubleBuffer, windType;
+GLint objectIndex = 0;
+GLuint bases[20];
+float angleX = 0.0, angleY = 0.0, angleZ = 0.0;
+float scaleX = 1.0, scaleY = 1.0, scaleZ = 1.0;
+float shiftX = 0.0, shiftY = 0.0, shiftZ = 0.0;
+
+
+#include "tkmap.c"
+
+static void Init(void)
+{
+
+    bases[0] = glGenLists(1);
+    glNewList(bases[0], GL_COMPILE);
+    glutWireSphere(1.0, 20, 10);
+    glEndList();
+
+    bases[1] = glGenLists(1);
+    glNewList(bases[1], GL_COMPILE);
+    glutSolidSphere(1.0, 20, 10);
+    glEndList();
+
+    bases[2] = glGenLists(1);
+    glNewList(bases[2], GL_COMPILE);
+    glutWireCube(1.0);
+    glEndList();
+
+    bases[3] = glGenLists(1);
+    glNewList(bases[3], GL_COMPILE);
+    glutSolidCube(1.0);
+    glEndList();
+
+    bases[4] = glGenLists(1);
+    glNewList(bases[4], GL_COMPILE);
+    glutWireTorus(1.0, 1.0, 10, 20);
+    glEndList();
+
+    bases[5] = glGenLists(1);
+    glNewList(bases[5], GL_COMPILE);
+    glutSolidTorus(1.0, 1.0, 10, 20);
+    glEndList();
+
+    bases[6] = glGenLists(1);
+    glNewList(bases[6], GL_COMPILE);
+    glutWireIcosahedron();
+    glEndList();
+
+    bases[7] = glGenLists(1);
+    glNewList(bases[7], GL_COMPILE);
+    glutSolidIcosahedron();
+    glEndList();
+
+    bases[8] = glGenLists(1);
+    glNewList(bases[8], GL_COMPILE);
+    glutWireOctahedron();
+    glEndList();
+
+    bases[9] = glGenLists(1);
+    glNewList(bases[9], GL_COMPILE);
+    glutSolidOctahedron();
+    glEndList();
+
+    bases[10] = glGenLists(1);
+    glNewList(bases[10], GL_COMPILE);
+    glutWireTetrahedron();
+    glEndList();
+
+    bases[11] = glGenLists(1);
+    glNewList(bases[11], GL_COMPILE);
+    glutSolidTetrahedron();
+    glEndList();
+
+    bases[12] = glGenLists(1);
+    glNewList(bases[12], GL_COMPILE);
+    glutWireDodecahedron();
+    glEndList();
+
+    bases[13] = glGenLists(1);
+    glNewList(bases[13], GL_COMPILE);
+    glutSolidDodecahedron();
+    glEndList();
+
+    bases[14] = glGenLists(1);
+    glNewList(bases[14], GL_COMPILE);
+    glutWireCone(5.0, 5.0, 20, 10);
+    glEndList();
+
+    bases[15] = glGenLists(1);
+    glNewList(bases[15], GL_COMPILE);
+    glutSolidCone(5.0, 5.0, 20, 10);
+    glEndList();
+
+    bases[16] = glGenLists(1);
+    glNewList(bases[16], GL_COMPILE);
+    glutWireTeapot(1.0);
+    glEndList();
+
+    bases[17] = glGenLists(1);
+    glNewList(bases[17], GL_COMPILE);
+    glutSolidTeapot(1.0);
+    glEndList();
+
+    glClearColor(0.0, 0.0, 0.0, 0.0);
+    glClearIndex(0.0);
+}
+
+static void Reshape(int width, int height)
+{
+
+    glViewport(0, 0, (GLint)width, (GLint)height);
+
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    glOrtho(-400.0, 400.0, -200.0, 200.0, -400.0, 400.0);
+    glMatrixMode(GL_MODELVIEW);
+}
+
+static void Key2(int key, int x, int y)
+{
+
+    switch (key) {
+      case GLUT_KEY_LEFT:
+       shiftX -= 20.0;
+       break;
+      case GLUT_KEY_RIGHT:
+       shiftX += 20.0;
+       break;
+      case GLUT_KEY_UP:
+       shiftY += 20.0;
+       break;
+      case GLUT_KEY_DOWN:
+       shiftY -= 20.0;
+       break;
+      default:
+       return;
+    }
+
+    glutPostRedisplay();
+}
+
+static void Key(unsigned char key, int x, int y)
+{
+
+    switch (key) {
+      case 27:
+        exit(1);
+
+      case 32:
+       objectIndex++;
+       if (objectIndex > 17) {
+           objectIndex = 0;
+       }
+       break;
+
+      case 'n':
+       shiftZ += 20.0;
+       break;
+      case 'm':
+       shiftZ -= 20.0;
+       break;
+
+      case 'q':
+       scaleX -= 0.1;
+       if (scaleX < 0.1) {
+           scaleX = 0.1;
+       }
+       break;
+      case 'w':
+       scaleX += 0.1;
+       break;
+      case 'a':
+       scaleY -= 0.1;
+       if (scaleY < 0.1) {
+           scaleY = 0.1;
+       }
+       break;
+      case 's':
+       scaleY += 0.1;
+       break;
+      case 'z':
+       scaleZ -= 0.1;
+       if (scaleZ < 0.1) {
+           scaleZ = 0.1;
+       }
+       break;
+      case 'x':
+       scaleZ += 0.1;
+       break;
+
+      case 'e':
+       angleX -= 5.0;
+       if (angleX < 0.0) {
+           angleX = 360.0 + angleX;
+       }
+       break;
+      case 'r':
+       angleX += 5.0;
+       if (angleX > 360.0) {
+           angleX = angleX - 360.0;
+       }
+       break;
+      case 'd':
+       angleY -= 5.0;
+       if (angleY < 0.0) {
+           angleY = 360.0 + angleY;
+       }
+       break;
+      case 'f':
+       angleY += 5.0;
+       if (angleY > 360.0) {
+           angleY = angleY - 360.0;
+       }
+       break;
+      case 'c':
+       angleZ -= 5.0;
+       if (angleZ < 0.0) {
+           angleZ = 360.0 + angleZ;
+       }
+       break;
+      case 'v':
+       angleZ += 5.0;
+       if (angleZ > 360.0) {
+           angleZ = angleZ - 360.0;
+       }
+       break;
+      default:
+       return;
+    }
+
+    glutPostRedisplay();
+}
+
+static void Draw(void)
+{
+
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    SetColor(COLOR_WHITE);
+
+    glPushMatrix();
+
+    glTranslatef(shiftX, shiftY, shiftZ);
+    glRotatef(angleX, 1.0, 0.0, 0.0);
+    glRotatef(angleY, 0.0, 1.0, 0.0);
+    glRotatef(angleZ, 0.0, 0.0, 1.0);
+    glScalef(scaleX, scaleY, scaleZ);
+
+    glCallList(bases[objectIndex]);
+    glPopMatrix();
+
+    glFlush();
+
+    if (doubleBuffer) {
+       glutSwapBuffers();
+    }
+}
+
+static GLenum Args(int argc, char **argv)
+{
+    GLint i;
+
+    rgb = GL_TRUE;
+    doubleBuffer = GL_FALSE;
+
+    for (i = 1; i < argc; i++) {
+       if (strcmp(argv[i], "-ci") == 0) {
+           rgb = GL_FALSE;
+       } else if (strcmp(argv[i], "-rgb") == 0) {
+           rgb = GL_TRUE;
+       } else if (strcmp(argv[i], "-sb") == 0) {
+           doubleBuffer = GL_FALSE;
+       } else if (strcmp(argv[i], "-db") == 0) {
+           doubleBuffer = GL_TRUE;
+       } else {
+           printf("%s (Bad option).\n", argv[i]);
+           return GL_FALSE;
+       }
+    }
+    return GL_TRUE;
+}
+
+int main(int argc, char **argv)
+{
+    glutInit(&argc, argv);
+
+    if (Args(argc, argv) == GL_FALSE) {
+       exit(1);
+    }
+
+    glutInitWindowPosition(0, 0); glutInitWindowSize( 400, 400);
+
+    windType = (rgb) ? GLUT_RGB : GLUT_INDEX;
+    windType |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
+    glutInitDisplayMode(windType);
+
+    if (glutCreateWindow("Font Test") == GL_FALSE) {
+       exit(1);
+    }
+
+    InitMap();
+
+    Init();
+
+    glutReshapeFunc(Reshape);
+    glutKeyboardFunc(Key);
+    glutSpecialFunc(Key2);
+    glutDisplayFunc(Draw);
+    glutMainLoop();
+       return 0;
+}
diff --git a/progs/samples/sphere.c b/progs/samples/sphere.c
new file mode 100644 (file)
index 0000000..154e85c
--- /dev/null
@@ -0,0 +1,1034 @@
+/*
+ * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the name of
+ * Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
+ * ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+/* BEP: renamed "nearest" as "nnearest" to avoid math.h collision on AIX */
+
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <stdlib.h>
+#include <GL/glut.h>
+
+
+#define FALSE 0
+#define TRUE  1
+#ifndef PI
+#define PI    3.14159265358979323846
+#endif
+
+
+#include "loadppm.c"
+
+int rgb;       /* unused */
+
+#include "tkmap.c"
+
+GLenum doubleBuffer;
+int W = 400, H = 400;
+
+char *imageFileName = 0;
+PPMImage *image;
+
+int numComponents;
+
+float *minFilter, *magFilter, *sWrapMode, *tWrapMode;
+float decal[] = {GL_DECAL};
+float modulate[] = {GL_MODULATE};
+float repeat[] = {GL_REPEAT};
+float clamp[] = {GL_CLAMP};
+float nnearest[] = {GL_NEAREST};
+float linear[] = {GL_LINEAR};
+float nearest_mipmap_nearest[] = {GL_NEAREST_MIPMAP_NEAREST};
+float nearest_mipmap_linear[] = {GL_NEAREST_MIPMAP_LINEAR};
+float linear_mipmap_nearest[] = {GL_LINEAR_MIPMAP_NEAREST};
+float linear_mipmap_linear[] = {GL_LINEAR_MIPMAP_LINEAR};
+GLint sphereMap[] = {GL_SPHERE_MAP};
+
+float xRotation = 0.0, yRotation = 0.0;
+float zTranslate = -4.0;
+GLenum autoRotate = TRUE;
+GLenum deepestColor = COLOR_GREEN;
+GLenum isLit = TRUE;
+GLenum isFogged = FALSE;
+float *textureEnvironment = modulate;
+
+struct MipMap {
+    int width, height;
+    unsigned char *data;
+};
+
+int cube, cage, cylinder, torus, genericObject;
+
+float c[6][4][4][3] = {
+    {
+       {
+           {
+               1.0, 1.0, -1.0
+           }, 
+           {
+               0.0, 1.0, -1.0
+           },
+           {
+               0.0, 0.0, -1.0
+           },
+           {
+               1.0, 0.0, -1.0
+           },
+       },
+       {
+           {
+               0.0, 1.0, -1.0
+           },
+           {
+               -1.0, 1.0, -1.0
+           }, 
+           {
+               -1.0, 0.0, -1.0
+           }, 
+           {
+               0.0, 0.0, -1.0
+           },
+       },
+       {
+           {
+               0.0,  0.0, -1.0
+           },
+           {
+               -1.0, 0.0, -1.0
+           },
+           {
+               -1.0, -1.0, -1.0
+           },
+           {
+               0.0, -1.0, -1.0
+           },
+       },
+       {
+           {
+               1.0, 0.0, -1.0
+           },
+           {
+               0.0, 0.0, -1.0
+           },
+           {
+               0.0, -1.0, -1.0
+           },
+           {
+               1.0, -1.0, -1.0
+           },
+       },
+    },
+    {
+       {
+           {
+               1.0, 1.0, 1.0
+           },
+           {
+               1.0, 1.0, 0.0
+           },
+           {
+               1.0, 0.0, 0.0
+           },
+           {
+               1.0, 0.0, 1.0
+           },
+       },
+       {
+           {
+               1.0, 1.0, 0.0
+           },
+           {
+               1.0, 1.0, -1.0
+           },
+           {
+               1.0, 0.0, -1.0
+           },
+           {
+               1.0, 0.0, 0.0
+           },
+       },
+       {
+           {
+               1.0, 0.0, -1.0
+           },
+           {
+               1.0, -1.0, -1.0
+           },
+           {
+               1.0, -1.0, 0.0
+           },
+           {
+               1.0, 0.0, 0.0
+           },
+       },
+       {
+           {
+               1.0, 0.0, 0.0
+           },
+           {
+               1.0, -1.0, 0.0
+           },
+           {
+               1.0, -1.0, 1.0
+           },
+           {
+               1.0, 0.0, 1.0
+           },
+       },
+    },
+    {
+       {
+           {
+               -1.0, 1.0, 1.0
+           },
+           {
+               0.0, 1.0, 1.0
+           },
+           {
+               0.0, 0.0, 1.0
+           },
+           {
+               -1.0, 0.0, 1.0
+           },
+       },
+       {
+           {
+               0.0, 1.0, 1.0
+           },
+           {
+               1.0, 1.0, 1.0
+           },
+           {
+               1.0, 0.0, 1.0
+           },
+           {
+               0.0, 0.0, 1.0
+           },
+       },
+       {
+           {
+               1.0, 0.0, 1.0
+           },
+           {
+               1.0, -1.0, 1.0
+           },
+           {
+               0.0, -1.0, 1.0
+           },
+           {
+               0.0, 0.0, 1.0
+           },
+       },
+       {
+           {
+               0.0, -1.0, 1.0
+           },
+           {
+               -1.0, -1.0, 1.0
+           },
+           {
+               -1.0, 0.0, 1.0
+           },
+           {
+               0.0, 0.0, 1.0
+           },
+       },
+    },
+    {
+       {
+           {
+               -1.0, 1.0, -1.0
+           },
+           {
+               -1.0, 1.0, 0.0
+           },
+           {
+               -1.0, 0.0, 0.0
+           },
+           {
+               -1.0, 0.0, -1.0
+           },
+       }, 
+       {
+           {
+               -1.0, 1.0, 0.0
+           },
+           {
+               -1.0, 1.0, 1.0
+           },
+           {
+               -1.0, 0.0, 1.0
+           },
+           {
+               -1.0, 0.0, 0.0
+           },
+       }, 
+       {
+           {
+               -1.0, 0.0, 1.0
+           },
+           {
+               -1.0, -1.0, 1.0
+           },
+           {
+               -1.0, -1.0, 0.0
+           },
+           {
+               -1.0, 0.0, 0.0
+           },
+       }, 
+       {
+           {
+               -1.0, -1.0, 0.0
+           },
+           {
+               -1.0, -1.0, -1.0
+           },
+           {
+               -1.0, 0.0, -1.0
+           },
+           {
+               -1.0, 0.0, 0.0
+           },
+       }, 
+    },
+    {
+       {
+           {
+               -1.0, 1.0, 1.0
+           },
+           {
+               -1.0, 1.0, 0.0
+           },
+           {
+               0.0, 1.0, 0.0
+           },
+           {
+               0.0, 1.0, 1.0
+           },
+       },
+       {
+           {
+               -1.0, 1.0, 0.0
+           },
+           {
+               -1.0, 1.0, -1.0
+           },
+           {
+               0.0, 1.0, -1.0
+           },
+           {
+               0.0, 1.0, 0.0
+           },
+       },
+       {
+           {
+               0.0, 1.0, -1.0
+           },
+           {
+               1.0, 1.0, -1.0
+           },
+           {
+               1.0, 1.0, 0.0
+           },
+           {
+               0.0, 1.0, 0.0
+           },
+       },
+       {
+           {
+               1.0, 1.0, 0.0
+           },
+           {
+               1.0, 1.0, 1.0
+           },
+           {
+               0.0, 1.0, 1.0
+           },
+           {
+               0.0, 1.0, 0.0
+           },
+       },
+    },
+    {
+       {
+           {
+               -1.0, -1.0, -1.0
+           },
+           {
+               -1.0, -1.0, 0.0
+           },
+           {
+               0.0, -1.0, 0.0
+           },
+           {
+               0.0, -1.0, -1.0
+           },
+       },
+       {
+           {
+               -1.0, -1.0, 0.0
+           },
+           {
+               -1.0, -1.0, 1.0
+           },
+           {
+               0.0, -1.0, 1.0
+           },
+           {
+               0.0, -1.0, 0.0
+           },
+       },
+       {
+           {
+               0.0, -1.0, 1.0
+           },
+           {
+               1.0, -1.0, 1.0
+           },
+           {
+               1.0, -1.0, 0.0
+           },
+           {
+               0.0, -1.0, 0.0
+           },
+       },
+       {
+           {
+               1.0, -1.0, 0.0
+           },
+           {
+               1.0, -1.0, -1.0
+           },
+           {
+               0.0, -1.0, -1.0
+           },
+           {
+               0.0, -1.0, 0.0
+           },
+       },
+    }
+};
+
+float n[6][3] = {
+    {
+       0.0, 0.0, -1.0
+    },
+    {
+       1.0, 0.0, 0.0
+    },
+    {
+       0.0, 0.0, 1.0
+    },
+    {
+       -1.0, 0.0, 0.0
+    },
+    {
+       0.0, 1.0, 0.0
+    },
+    {
+       0.0, -1.0, 0.0
+    }
+};
+
+GLfloat identity[16] = {
+    1, 0, 0, 0,
+    0, 1, 0, 0,
+    0, 0, 1, 0,
+    0, 0, 0, 1,
+};
+
+
+void BuildCylinder(int numEdges)
+{
+    int i, top = 1.0, bottom = -1.0;
+    float x[100], y[100], angle; 
+    
+    for (i = 0; i <= numEdges; i++) {
+       angle = i * 2.0 * PI / numEdges;
+       x[i] = cos(angle);   /* was cosf() */
+       y[i] = sin(angle);   /* was sinf() */
+    }
+
+    glNewList(cylinder, GL_COMPILE);
+    glBegin(GL_TRIANGLE_STRIP);
+       for (i = 0; i <= numEdges; i++) {
+           glNormal3f(x[i], y[i], 0.0);
+           glVertex3f(x[i], y[i], bottom);
+           glVertex3f(x[i], y[i], top);
+       }
+    glEnd();
+    glBegin(GL_TRIANGLE_FAN);
+       glNormal3f(0.0, 0.0, 1.0);
+       glVertex3f(0.0, 0.0, top);
+       for (i = 0; i <= numEdges; i++) {
+           glVertex3f(x[i], -y[i], top);
+       }
+    glEnd();
+    glBegin(GL_TRIANGLE_FAN);
+       glNormal3f(0.0, 0.0, -1.0);
+       glVertex3f(0.0, 0.0, bottom);
+       for (i = 0; i <= numEdges; i++) {
+           glVertex3f(x[i], y[i], bottom);
+       }
+    glEnd();
+    glEndList();
+}
+
+void BuildTorus(float rc, int numc, float rt, int numt)
+{
+    int i, j, k;
+    double s, t;
+    double x, y, z;
+    double pi, twopi;
+
+    pi = 3.14159265358979323846;
+    twopi = 2.0 * pi;
+    glNewList(torus, GL_COMPILE);
+    for (i = 0; i < numc; i++) {
+       glBegin(GL_QUAD_STRIP);
+        for (j = 0; j <= numt; j++) {
+           for (k = 0; k <= 1; k++) {
+               s = (i + k) % numc + 0.5;
+               t = j % numt;
+
+               x = cos(t*twopi/numt) * cos(s*twopi/numc);
+               y = sin(t*twopi/numt) * cos(s*twopi/numc);
+               z = sin(s*twopi/numc);
+               glNormal3f(x, y, z);
+
+               x = (rt + rc * cos(s*twopi/numc)) * cos(t*twopi/numt);
+               y = (rt + rc * cos(s*twopi/numc)) * sin(t*twopi/numt);
+               z = rc * sin(s*twopi/numc);
+               glVertex3f(x, y, z);
+           }
+        }
+       glEnd();
+    }
+    glEndList();
+}
+
+void BuildCage(void)
+{
+    int i;
+    float inc;
+    float right, left, top, bottom, front, back;
+
+    front  = 0.0;
+    back   = -8.0;
+
+    left   = -4.0;
+    bottom = -4.0;
+    right  = 4.0;
+    top    = 4.0; 
+
+    inc = 2.0 * 4.0 * 0.1;
+
+    glNewList(cage, GL_COMPILE);
+    for (i = 0; i < 10; i++) {
+
+       /*
+       ** Back
+       */
+       glBegin(GL_LINES);
+           glVertex3f(left+i*inc, top,    back);
+           glVertex3f(left+i*inc, bottom, back);
+       glEnd();
+       glBegin(GL_LINES);
+           glVertex3f(right, bottom+i*inc, back);
+           glVertex3f(left,  bottom+i*inc, back);
+       glEnd();
+
+       /*
+       ** Front
+       */
+       glBegin(GL_LINES);
+           glVertex3f(left+i*inc, top,    front);
+           glVertex3f(left+i*inc, bottom, front);
+       glEnd();
+       glBegin(GL_LINES);
+           glVertex3f(right, bottom+i*inc, front);
+           glVertex3f(left,  bottom+i*inc, front);
+       glEnd();
+
+       /*
+       ** Left
+       */
+       glBegin(GL_LINES);
+           glVertex3f(left, bottom+i*inc, front);
+           glVertex3f(left, bottom+i*inc, back);
+       glEnd();
+       glBegin(GL_LINES);
+           glVertex3f(left, top,    back+i*inc);
+           glVertex3f(left, bottom, back+i*inc);
+       glEnd();
+
+       /*
+       ** Right
+       */
+       glBegin(GL_LINES);
+           glVertex3f(right, top-i*inc, front);
+           glVertex3f(right, top-i*inc, back);
+       glEnd();
+       glBegin(GL_LINES);
+           glVertex3f(right, top,    back+i*inc);
+           glVertex3f(right, bottom, back+i*inc);
+       glEnd();
+
+       /*
+       ** Top
+       */
+       glBegin(GL_LINES);
+           glVertex3f(left+i*inc, top, front);
+           glVertex3f(left+i*inc, top, back);
+       glEnd();
+       glBegin(GL_LINES);
+           glVertex3f(right, top, back+i*inc);
+           glVertex3f(left,  top, back+i*inc);
+       glEnd();
+
+       /*
+       ** Bottom
+       */
+       glBegin(GL_LINES);
+           glVertex3f(right-i*inc, bottom, front);
+           glVertex3f(right-i*inc, bottom, back);
+       glEnd();
+       glBegin(GL_LINES);
+           glVertex3f(right, bottom, back+i*inc);
+           glVertex3f(left,  bottom, back+i*inc);
+       glEnd();
+    }
+    glEndList();
+}
+
+void BuildCube(void)
+{
+    int i, j;
+
+    glNewList(cube, GL_COMPILE);
+    for (i = 0; i < 6; i++) {
+       for (j = 0; j < 4; j++) {
+           glNormal3fv(n[i]); 
+           glBegin(GL_POLYGON);
+               glVertex3fv(c[i][j][0]);
+               glVertex3fv(c[i][j][1]);
+               glVertex3fv(c[i][j][2]);
+               glVertex3fv(c[i][j][3]);
+           glEnd();
+       }
+    }
+    glEndList();
+}
+
+void BuildLists(void)
+{
+
+    cube = glGenLists(1);
+    BuildCube();
+
+    cage = glGenLists(2);
+    BuildCage();
+
+    cylinder = glGenLists(3);
+    BuildCylinder(60);
+
+    torus = glGenLists(4);
+    BuildTorus(0.65, 20, .85, 65);
+
+    genericObject = torus;
+}
+
+void SetDeepestColor(void)
+{
+    GLint redBits, greenBits, blueBits;
+
+    glGetIntegerv(GL_RED_BITS, &redBits);
+    glGetIntegerv(GL_GREEN_BITS, &greenBits);
+    glGetIntegerv(GL_BLUE_BITS, &blueBits);
+
+    deepestColor = (redBits >= greenBits) ? COLOR_RED : COLOR_GREEN;
+    deepestColor = (deepestColor >= blueBits) ? deepestColor : COLOR_BLUE; 
+}
+
+void SetDefaultSettings(void)
+{
+
+    magFilter = nnearest;
+    minFilter = nnearest;
+    sWrapMode = repeat;
+    tWrapMode = repeat;
+    textureEnvironment = modulate;
+    autoRotate = TRUE;
+}
+
+unsigned char *AlphaPadImage(int bufSize, unsigned char *inData, int alpha)
+{
+    unsigned char *outData, *out_ptr, *in_ptr;
+    int i;
+
+    outData = (unsigned char *) malloc(bufSize * 4);
+    out_ptr = outData;
+    in_ptr = inData;
+
+    for (i = 0; i < bufSize; i++) {
+       *out_ptr++ = *in_ptr++;
+       *out_ptr++ = *in_ptr++;
+       *out_ptr++ = *in_ptr++;
+       *out_ptr++ = alpha;
+    }
+
+    free (inData);
+    return outData;
+}
+
+void Init(void)
+{
+    float ambient[] = {0.0, 0.0, 0.0, 1.0};
+    float diffuse[] = {0.0, 1.0, 0.0, 1.0};
+    float specular[] = {1.0, 1.0, 1.0, 1.0};
+    float position[] = {2.0, 2.0,  0.0, 1.0};
+    float fog_color[] = {0.0, 0.0, 0.0, 1.0};
+    float mat_ambient[] = {0.0, 0.0, 0.0, 1.0};
+    float mat_shininess[] = {90.0};
+    float mat_specular[] = {1.0, 1.0, 1.0, 1.0};
+    float mat_diffuse[] = {1.0, 1.0, 1.0, 1.0};
+    float lmodel_ambient[] = {0.0, 0.0, 0.0, 1.0};
+    float lmodel_twoside[] = {GL_TRUE};
+
+    SetDeepestColor();
+    SetDefaultSettings();
+
+    if (numComponents == 4) {
+       image = LoadPPM(imageFileName);
+       image->data = AlphaPadImage(image->sizeX*image->sizeY,
+                                    image->data, 128);
+       glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+       gluBuild2DMipmaps(GL_TEXTURE_2D, numComponents, 
+                         image->sizeX, image->sizeY, 
+                         GL_RGBA, GL_UNSIGNED_BYTE, image->data);
+    } else {
+       image = LoadPPM(imageFileName);
+       glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+       gluBuild2DMipmaps(GL_TEXTURE_2D, numComponents, 
+                         image->sizeX, image->sizeY, 
+                         GL_RGB, GL_UNSIGNED_BYTE, image->data);
+    }
+    
+    glFogf(GL_FOG_DENSITY, 0.125);
+    glFogi(GL_FOG_MODE, GL_LINEAR);
+    glFogf(GL_FOG_START, 4.0);
+    glFogf(GL_FOG_END, 9.0);
+    glFogfv(GL_FOG_COLOR, fog_color);
+
+    glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
+    glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
+    glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
+    glLightfv(GL_LIGHT0, GL_POSITION, position);
+    
+    glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
+    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
+    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse);
+    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat_ambient);
+
+    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
+    glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
+    glShadeModel(GL_SMOOTH);
+
+    glEnable(GL_LIGHTING);
+    glEnable(GL_LIGHT0);
+
+    glClearColor(0.0, 0.0, 0.0, 0.0);
+    glViewport(0, 0, W, H);
+    glEnable(GL_DEPTH_TEST);
+
+    glFrontFace(GL_CW);
+    glEnable(GL_CULL_FACE);
+    glCullFace(GL_BACK);
+
+    glEnable(GL_TEXTURE_2D);
+    glTexGeniv(GL_S, GL_TEXTURE_GEN_MODE, sphereMap);
+    glTexGeniv(GL_T, GL_TEXTURE_GEN_MODE, sphereMap);
+    glEnable(GL_TEXTURE_GEN_S);
+    glEnable(GL_TEXTURE_GEN_T);
+
+    glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
+    glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
+    glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, sWrapMode);
+    glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, tWrapMode);
+
+    glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, textureEnvironment);
+
+    BuildLists();
+}
+
+void ReInit(void)
+{
+
+    if (genericObject == torus) {
+       glEnable(GL_DEPTH_TEST);
+    } else  {
+       glDisable(GL_DEPTH_TEST);
+    }
+    if (isFogged) {
+       textureEnvironment = modulate;
+    }
+
+    glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
+    glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
+    glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, textureEnvironment);
+}
+
+void Draw(void)
+{
+
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    glFrustum(-0.2, 0.2, -0.2, 0.2, 0.15, 9.0);
+    glMatrixMode(GL_MODELVIEW);
+
+    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+    if (isFogged) {
+       glEnable(GL_FOG);
+       glColor3fv(RGBMap[deepestColor]);
+    } else {
+       glColor3fv(RGBMap[COLOR_WHITE]);
+    }
+    glDisable(GL_LIGHTING);
+    glDisable(GL_LIGHT0);
+    glDisable(GL_TEXTURE_2D);
+    glCallList(cage);
+
+    glPushMatrix();
+    glTranslatef(0.0, 0.0, zTranslate);
+    glRotatef(xRotation, 1, 0, 0);
+    glRotatef(yRotation, 0, 1, 0);
+
+    if (isLit == TRUE) {
+       glEnable(GL_LIGHTING);
+       glEnable(GL_LIGHT0);
+    }
+
+    glEnable(GL_TEXTURE_2D);
+    if (isFogged) {
+       glDisable(GL_FOG);
+    }
+    glPolygonMode(GL_FRONT, GL_FILL);
+    glColor3fv(RGBMap[deepestColor]);
+    glCallList(genericObject);
+
+    glPopMatrix();
+    glFlush();
+
+    if (autoRotate) {
+       xRotation += .75;
+       yRotation += .375;
+    } 
+    glutSwapBuffers();
+}
+
+void Reshape(int width, int height)
+{
+
+    W = width;
+    H = height;
+    ReInit();
+    glViewport( 0, 0, width, height );  /*new*/
+}
+
+void Key2(int key, int x, int y)
+{
+
+    switch (key) {
+      case GLUT_KEY_LEFT:
+       yRotation -= 0.5;
+       autoRotate = FALSE;
+       ReInit();
+       break;
+      case GLUT_KEY_RIGHT:
+       yRotation += 0.5;
+       autoRotate = FALSE;
+       ReInit();
+       break;
+      case GLUT_KEY_UP:
+       xRotation -= 0.5;
+       autoRotate = FALSE;
+       ReInit();
+       break;
+      case GLUT_KEY_DOWN:
+       xRotation += 0.5;
+       autoRotate = FALSE;
+       ReInit();
+       break;
+      default:
+       return;
+    }
+}
+
+void Key(unsigned char key, int x, int y)
+{
+
+    switch (key) {
+      case 27:
+       free(image->data);
+       exit(1);
+
+      case 'a':
+       autoRotate = !autoRotate;
+       ReInit();
+       break;
+      case 'c':
+       genericObject = (genericObject == cube) ? cylinder : cube;
+       ReInit();
+       break;
+      case 'd':
+       textureEnvironment = decal;
+       ReInit();
+       break;
+      case 'm':
+       textureEnvironment = modulate;
+       ReInit();
+       break;
+      case 'l':
+       isLit = !isLit;
+       ReInit();
+       break;
+      case 'f':
+       isFogged = !isFogged;
+       ReInit();
+       break;
+      case 't':
+       genericObject = torus;
+       ReInit();
+       break;
+      case '0':
+       magFilter = nnearest;
+       ReInit();
+       break;
+      case '1':
+       magFilter = linear;
+       ReInit();
+       break;
+      case '2':
+       minFilter = nnearest;
+       ReInit();
+       break;
+      case '3':
+       minFilter = linear;
+       ReInit();
+       break;
+      case '4':
+       minFilter = nearest_mipmap_nearest;
+       ReInit();
+       break;
+      case '5':
+       minFilter = nearest_mipmap_linear;
+       ReInit();
+       break;
+      case '6':
+       minFilter = linear_mipmap_nearest;
+       ReInit();
+       break;
+      case '7':
+       minFilter = linear_mipmap_linear;
+       ReInit();
+       break;
+      default:
+       return;
+    }
+}
+
+GLenum Args(int argc, char **argv)
+{
+    GLint i;
+
+    doubleBuffer = GL_FALSE;
+    numComponents = 4;
+
+    for (i = 1; i < argc; i++) {
+       if (strcmp(argv[i], "-sb") == 0) {
+           doubleBuffer = GL_FALSE;
+       } else if (strcmp(argv[i], "-db") == 0) {
+           doubleBuffer = GL_TRUE;
+       } else if (strcmp(argv[i], "-f") == 0) {
+           if (i+1 >= argc || argv[i+1][0] == '-') {
+               printf("-f (No file name).\n");
+               return GL_FALSE;
+           } else {
+               imageFileName = argv[++i];
+           }
+       } else if (strcmp(argv[i], "-4") == 0) {
+           numComponents = 4;
+       } else if (strcmp(argv[i], "-3") == 0) {
+           numComponents = 3;
+       } else {
+           printf("%s (Bad option).\n", argv[i]);
+           return GL_FALSE;
+       }
+    }
+    return GL_TRUE;
+}
+
+void GLUTCALLBACK glut_post_redisplay_p(void)
+{
+      glutPostRedisplay();
+}
+
+int main(int argc, char **argv)
+{
+    GLenum type;
+
+    glutInit(&argc, argv);
+
+    if (Args(argc, argv) == GL_FALSE) {
+       exit(1);
+    }
+
+    if (imageFileName == 0) {
+       printf("No image file.\n");
+       exit(1);
+    }
+
+    glutInitWindowPosition(0, 0); glutInitWindowSize( W, H);
+
+    type = GLUT_RGB | GLUT_DEPTH;
+    type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
+    glutInitDisplayMode(type);
+
+    if (glutCreateWindow("Texture Test") == GL_FALSE) {
+        exit(1);
+    }
+
+    Init();
+
+    glutReshapeFunc(Reshape);
+    glutKeyboardFunc(Key);
+    glutSpecialFunc(Key2);
+    glutDisplayFunc(Draw);
+    glutIdleFunc(glut_post_redisplay_p);
+
+    glutMainLoop();
+       return 0;
+}
diff --git a/progs/samples/star.c b/progs/samples/star.c
new file mode 100644 (file)
index 0000000..180585e
--- /dev/null
@@ -0,0 +1,331 @@
+/*
+ * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the name of
+ * Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
+ * ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+#include <GL/glut.h>
+
+
+#ifndef PI
+#define PI 3.141592657
+#endif
+
+enum {
+    NORMAL = 0,
+    WEIRD = 1
+};
+
+enum {
+    STREAK = 0,
+    CIRCLE = 1
+};
+
+#define MAXSTARS 400
+#define MAXPOS 10000
+#define MAXWARP 10
+#define MAXANGLES 6000
+
+
+typedef struct _starRec {
+    GLint type;
+    float x[2], y[2], z[2];
+    float offsetX, offsetY, offsetR, rotation;
+} starRec;
+
+
+GLenum doubleBuffer;
+GLint windW, windH;
+
+GLenum flag = NORMAL;
+GLint starCount = MAXSTARS / 2;
+float speed = 1.0;
+GLint nitro = 0;
+starRec stars[MAXSTARS];
+float sinTable[MAXANGLES];
+
+
+float Sin(float angle)
+{
+
+    return (sinTable[(GLint)angle]);
+}
+
+float Cos(float angle)
+{
+
+    return (sinTable[((GLint)angle+(MAXANGLES/4))%MAXANGLES]);
+}
+
+void NewStar(GLint n, GLint d)
+{
+
+    if (rand()%4 == 0) {
+       stars[n].type = CIRCLE;
+    } else {
+       stars[n].type = STREAK;
+    }
+    stars[n].x[0] = (float)(rand() % MAXPOS - MAXPOS / 2);
+    stars[n].y[0] = (float)(rand() % MAXPOS - MAXPOS / 2);
+    stars[n].z[0] = (float)(rand() % MAXPOS + d);
+    if (rand()%4 == 0 && flag == WEIRD) {
+       stars[n].offsetX = (float)(rand() % 100 - 100 / 2);
+       stars[n].offsetY = (float)(rand() % 100 - 100 / 2);
+       stars[n].offsetR = (float)(rand() % 25 - 25 / 2);
+    } else {
+       stars[n].offsetX = 0.0;
+       stars[n].offsetY = 0.0;
+       stars[n].offsetR = 0.0;
+    }
+}
+
+void RotatePoint(float *x, float *y, float rotation)
+{
+    float tmpX, tmpY;
+
+    tmpX = *x * Cos(rotation) - *y * Sin(rotation);
+    tmpY = *y * Cos(rotation) + *x * Sin(rotation);
+    *x = tmpX;
+    *y = tmpY;
+}
+
+void MoveStars(void)
+{
+    float offset;
+    GLint n;
+
+    offset = speed * 60.0;
+
+    for (n = 0; n < starCount; n++) {
+       stars[n].x[1] = stars[n].x[0];
+       stars[n].y[1] = stars[n].y[0];
+       stars[n].z[1] = stars[n].z[0];
+       stars[n].x[0] += stars[n].offsetX;
+       stars[n].y[0] += stars[n].offsetY;
+       stars[n].z[0] -= offset;
+        stars[n].rotation += stars[n].offsetR;
+        if (stars[n].rotation > MAXANGLES) {
+            stars[n].rotation = 0.0;
+       }
+    }
+}
+
+GLenum StarPoint(GLint n)
+{
+    float x0, y0, x1, y1, width;
+    GLint i;
+
+    x0 = stars[n].x[0] * windW / stars[n].z[0];
+    y0 = stars[n].y[0] * windH / stars[n].z[0];
+    RotatePoint(&x0, &y0, stars[n].rotation);
+    x0 += windW / 2.0;
+    y0 += windH / 2.0;
+
+    if (x0 >= 0.0 && x0 < windW && y0 >= 0.0 && y0 < windH) {
+       if (stars[n].type == STREAK) {
+           x1 = stars[n].x[1] * windW / stars[n].z[1];
+           y1 = stars[n].y[1] * windH / stars[n].z[1];
+           RotatePoint(&x1, &y1, stars[n].rotation);
+           x1 += windW / 2.0;
+           y1 += windH / 2.0;
+
+           glLineWidth(MAXPOS/100.0/stars[n].z[0]+1.0);
+           glColor3f(1.0, (MAXWARP-speed)/MAXWARP, (MAXWARP-speed)/MAXWARP);
+           if (fabs(x0-x1) < 1.0 && fabs(y0-y1) < 1.0) {
+               glBegin(GL_POINTS);
+                   glVertex2f(x0, y0);
+               glEnd();
+           } else {
+               glBegin(GL_LINES);
+                   glVertex2f(x0, y0);
+                   glVertex2f(x1, y1);
+               glEnd();
+           }
+       } else {
+           width = MAXPOS / 10.0 / stars[n].z[0] + 1.0;
+           glColor3f(1.0, 0.0, 0.0);
+           glBegin(GL_POLYGON);
+               for (i = 0; i < 8; i++) {
+                   float x = x0 + width * Cos((float)i*MAXANGLES/8.0);
+                   float y = y0 + width * Sin((float)i*MAXANGLES/8.0);
+                   glVertex2f(x, y);
+               };
+           glEnd();
+       }
+       return GL_TRUE;
+    } else {
+       return GL_FALSE;
+    }
+}
+
+void ShowStars(void)
+{
+    GLint n;
+
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    for (n = 0; n < starCount; n++) {
+       if (stars[n].z[0] > speed || (stars[n].z[0] > 0.0 && speed < MAXWARP)) {
+           if (StarPoint(n) == GL_FALSE) {
+               NewStar(n, MAXPOS);
+           }
+       } else {
+           NewStar(n, MAXPOS);
+       }
+    }
+}
+
+static void Init(void)
+{
+    float angle;
+    GLint n;
+
+    srand((unsigned int) glutGet(GLUT_ELAPSED_TIME) );
+
+    for (n = 0; n < MAXSTARS; n++) {
+       NewStar(n, 100);
+    }
+
+    angle = 0.0;
+    for (n = 0; n < MAXANGLES ; n++) {
+       sinTable[n] = sin(angle);
+        angle += PI / (MAXANGLES / 2.0);
+    }
+
+    glClearColor(0.0, 0.0, 0.0, 0.0);
+
+    glDisable(GL_DITHER);
+}
+
+void Reshape(int width, int height)
+{
+
+    windW = (GLint)width;
+    windH = (GLint)height;
+
+    glViewport(0, 0, windW, windH);
+
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    gluOrtho2D(-0.5, windW+0.5, -0.5, windH+0.5);
+    glMatrixMode(GL_MODELVIEW);
+}
+
+static void Key(unsigned char key, int x, int y)
+{
+
+    switch (key) {
+      case 27:
+       exit(1);
+      case 32:
+       flag = (flag == NORMAL) ? WEIRD : NORMAL;
+       break;
+      case 't':
+       nitro = 1;
+       break;
+      default:
+       return;
+    }
+}
+
+void Draw(void)
+{
+
+    MoveStars();
+    ShowStars();
+    if (nitro > 0) {
+       speed = (float)(nitro / 10) + 1.0;
+       if (speed > MAXWARP) {
+           speed = MAXWARP;
+       }
+       if (++nitro > MAXWARP*10) {
+           nitro = -nitro;
+       }
+    } else if (nitro < 0) {
+       nitro++;
+       speed = (float)(-nitro / 10) + 1.0;
+       if (speed > MAXWARP) {
+           speed = MAXWARP;
+       }
+    }
+
+    glFlush();
+    if (doubleBuffer) {
+       glutSwapBuffers();
+    }
+}
+
+static GLenum Args(int argc, char **argv)
+{
+    GLint i;
+
+    doubleBuffer = GL_FALSE;
+
+    for (i = 1; i < argc; i++) {
+       if (strcmp(argv[i], "-sb") == 0) {
+           doubleBuffer = GL_FALSE;
+       } else if (strcmp(argv[i], "-db") == 0) {
+           doubleBuffer = GL_TRUE;
+       }
+    }
+    return GL_TRUE;
+}
+
+void GLUTCALLBACK glut_post_redisplay_p(void)
+{
+      glutPostRedisplay();
+}
+
+int main(int argc, char **argv)
+{
+    GLenum type;
+
+    glutInit(&argc, argv);
+
+    if (Args(argc, argv) == GL_FALSE) {
+       exit(1);
+    }
+
+    windW = 300;
+    windH = 300;
+    glutInitWindowPosition(0, 0); glutInitWindowSize( 300, 300);
+
+    type = GLUT_RGB;
+    type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
+    glutInitDisplayMode(type);
+
+    if (glutCreateWindow("Stars") == GL_FALSE) {
+       exit(1);
+    }
+
+    Init();
+
+    glutReshapeFunc(Reshape);
+    glutKeyboardFunc(Key);
+    glutDisplayFunc(Draw);
+    glutIdleFunc(glut_post_redisplay_p);
+    glutMainLoop();
+       return 0;
+}
diff --git a/progs/samples/stencil.c b/progs/samples/stencil.c
new file mode 100644 (file)
index 0000000..e00bbb6
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the name of
+ * Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
+ * ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <GL/glut.h>
+
+
+static void Init(void)
+{
+   glShadeModel(GL_FLAT);
+    glClearColor(0.0, 0.0, 0.0, 0.0);
+
+    glClearStencil(0);
+    glStencilMask(1);
+    glEnable(GL_STENCIL_TEST);
+}
+
+static void Reshape(int width, int height)
+{
+
+    glViewport(0, 0, (GLint)width, (GLint)height);
+
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    glOrtho(-5.0, 5.0, -5.0, 5.0, -5.0, 5.0);
+    glMatrixMode(GL_MODELVIEW);
+}
+
+static void Key(unsigned char key, int x, int y)
+{
+
+    switch (key) {
+      case 27:
+       exit(1);
+    }
+}
+
+static void Draw(void)
+{
+
+    glClear(GL_COLOR_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
+
+    glStencilFunc(GL_ALWAYS, 1, 1);
+    glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
+
+    glColor3ub(200, 0, 0);
+    glBegin(GL_POLYGON);        
+       glVertex3i(-4, -4, 0);
+       glVertex3i( 4, -4, 0);
+       glVertex3i( 0,  4, 0);
+    glEnd();
+
+    glStencilFunc(GL_EQUAL, 1, 1);
+    glStencilOp(GL_INCR, GL_KEEP, GL_DECR);
+
+    glColor3ub(0, 200, 0);
+    glBegin(GL_POLYGON);
+       glVertex3i(3, 3, 0);
+       glVertex3i(-3, 3, 0);
+       glVertex3i(-3, -3, 0);
+       glVertex3i(3, -3, 0);
+    glEnd();
+
+    glStencilFunc(GL_EQUAL, 1, 1);
+    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+
+    glColor3ub(0, 0, 200);
+    glBegin(GL_POLYGON);
+       glVertex3i(3, 3, 0);
+       glVertex3i(-3, 3, 0);
+       glVertex3i(-3, -3, 0);
+       glVertex3i(3, -3, 0);
+    glEnd();
+
+    glFlush();
+}
+
+static GLenum Args(int argc, char **argv)
+{
+    GLint i;
+
+
+    for (i = 1; i < argc; i++) {
+       if (strcmp(argv[i], "-dr") == 0) {
+       } else {
+           printf("%s (Bad option).\n", argv[i]);
+           return GL_FALSE;
+       }
+    }
+    return GL_TRUE;
+}
+
+int main(int argc, char **argv)
+{
+    GLenum type;
+
+    glutInit(&argc, argv);
+
+    if (Args(argc, argv) == GL_FALSE) {
+       exit(1);
+    }
+
+    glutInitWindowPosition(0, 0); glutInitWindowSize( 300, 300);
+
+    type = GLUT_RGB | GLUT_SINGLE | GLUT_STENCIL;
+    glutInitDisplayMode(type);
+
+    if (glutCreateWindow("Stencil Test") == GL_FALSE) {
+       exit(1);
+    }
+
+    Init();
+
+    glutReshapeFunc(Reshape);
+    glutKeyboardFunc(Key);
+    glutDisplayFunc(Draw);
+    glutMainLoop();
+       return 0;
+}
diff --git a/progs/samples/stretch.c b/progs/samples/stretch.c
new file mode 100644 (file)
index 0000000..3f610e7
--- /dev/null
@@ -0,0 +1,375 @@
+/*
+ * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the name of
+ * Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
+ * ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <GL/glut.h>
+
+
+#define STEPCOUNT 40
+#define FALSE 0
+#define TRUE 1
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+
+
+enum {
+    OP_NOOP = 0,
+    OP_STRETCH,
+    OP_DRAWPOINT,
+    OP_DRAWIMAGE
+};
+
+
+typedef struct _cRec {
+    float x, y;
+} cRec;
+
+typedef struct _vertexRec {
+    float x, y;
+    float dX, dY;
+    float tX, tY;
+} vertexRec;
+
+
+#include "loadppm.c"
+
+GLenum doubleBuffer;
+int imageSizeX, imageSizeY;
+char *fileName = 0;
+PPMImage *image;
+cRec cList[50];
+vertexRec vList[5];
+int cCount, cIndex[2], cStep;
+GLenum op = OP_NOOP;
+
+
+void DrawImage(void)
+{
+
+    glRasterPos2i(0, 0);
+    glDrawPixels(image->sizeX, image->sizeY, GL_RGB, GL_UNSIGNED_BYTE,
+                image->data);
+
+    glFlush();
+    if (doubleBuffer) {
+       glutSwapBuffers();
+    }
+
+    glRasterPos2i(0, 0);
+    glDrawPixels(image->sizeX, image->sizeY, GL_RGB, GL_UNSIGNED_BYTE,
+                image->data);
+}
+
+void DrawPoint(void)
+{
+    int i;
+
+    glColor3f(1.0, 0.0, 1.0);
+    glPointSize(3.0);
+    glBegin(GL_POINTS);
+       for (i = 0; i < cCount; i++) {
+           glVertex2f(cList[i].x, cList[i].y);
+       }
+    glEnd();
+
+    glFlush();
+    if (doubleBuffer) {
+       glutSwapBuffers();
+    }
+}
+
+void InitVList(void)
+{
+
+    vList[0].x = 0.0;
+    vList[0].y = 0.0;
+    vList[0].dX = 0.0;
+    vList[0].dY = 0.0;
+    vList[0].tX = 0.0;
+    vList[0].tY = 0.0;
+
+    vList[1].x = (float)imageSizeX;
+    vList[1].y = 0.0;
+    vList[1].dX = 0.0;
+    vList[1].dY = 0.0;
+    vList[1].tX = 1.0;
+    vList[1].tY = 0.0;
+
+    vList[2].x = (float)imageSizeX;
+    vList[2].y = (float)imageSizeY;
+    vList[2].dX = 0.0;
+    vList[2].dY = 0.0;
+    vList[2].tX = 1.0;
+    vList[2].tY = 1.0;
+
+    vList[3].x = 0.0;
+    vList[3].y = (float)imageSizeY;
+    vList[3].dX = 0.0;
+    vList[3].dY = 0.0;
+    vList[3].tX = 0.0;
+    vList[3].tY = 1.0;
+
+    vList[4].x = cList[0].x;
+    vList[4].y = cList[0].y;
+    vList[4].dX = (cList[1].x - cList[0].x) / STEPCOUNT;
+    vList[4].dY = (cList[1].y - cList[0].y) / STEPCOUNT;
+    vList[4].tX = cList[0].x / (float)imageSizeX;
+    vList[4].tY = cList[0].y / (float)imageSizeY;
+}
+
+void ScaleImage(int sizeX, int sizeY)
+{
+    GLubyte *buf;
+
+    buf = (GLubyte *)malloc(3*sizeX*sizeY);
+    gluScaleImage(GL_RGB, image->sizeX, image->sizeY, GL_UNSIGNED_BYTE,
+                  image->data, sizeX, sizeY, GL_UNSIGNED_BYTE, buf);
+    free(image->data);
+    image->data = buf;
+    image->sizeX = sizeX;
+    image->sizeY = sizeY;
+}
+
+void SetPoint(int x, int y)
+{
+
+    cList[cCount].x = (float)x;
+    cList[cCount].y = (float)y;
+    cCount++;
+}
+
+void Stretch(void)
+{
+
+    glBegin(GL_TRIANGLES);
+       glTexCoord2f(vList[0].tX, vList[0].tY);
+       glVertex2f(vList[0].x, vList[0].y);
+       glTexCoord2f(vList[1].tX, vList[1].tY);
+       glVertex2f(vList[1].x, vList[1].y);
+       glTexCoord2f(vList[4].tX, vList[4].tY);
+       glVertex2f(vList[4].x, vList[4].y);
+    glEnd();
+
+    glBegin(GL_TRIANGLES);
+       glTexCoord2f(vList[1].tX, vList[1].tY);
+       glVertex2f(vList[1].x, vList[1].y);
+       glTexCoord2f(vList[2].tX, vList[2].tY);
+       glVertex2f(vList[2].x, vList[2].y);
+       glTexCoord2f(vList[4].tX, vList[4].tY);
+       glVertex2f(vList[4].x, vList[4].y);
+    glEnd();
+
+    glBegin(GL_TRIANGLES);
+       glTexCoord2f(vList[2].tX, vList[2].tY);
+       glVertex2f(vList[2].x, vList[2].y);
+       glTexCoord2f(vList[3].tX, vList[3].tY);
+       glVertex2f(vList[3].x, vList[3].y);
+       glTexCoord2f(vList[4].tX, vList[4].tY);
+       glVertex2f(vList[4].x, vList[4].y);
+    glEnd();
+
+    glBegin(GL_TRIANGLES);
+       glTexCoord2f(vList[3].tX, vList[3].tY);
+       glVertex2f(vList[3].x, vList[3].y);
+       glTexCoord2f(vList[0].tX, vList[0].tY);
+       glVertex2f(vList[0].x, vList[0].y);
+       glTexCoord2f(vList[4].tX, vList[4].tY);
+       glVertex2f(vList[4].x, vList[4].y);
+    glEnd();
+
+    glFlush();
+    if (doubleBuffer) {
+       glutSwapBuffers();
+    }
+
+    if (++cStep < STEPCOUNT) {
+       vList[4].x += vList[4].dX;
+       vList[4].y += vList[4].dY;
+    } else {
+       cIndex[0] = cIndex[1];
+       cIndex[1] = cIndex[1] + 1;
+       if (cIndex[1] == cCount) {
+           cIndex[1] = 0;
+       }
+       vList[4].dX = (cList[cIndex[1]].x - cList[cIndex[0]].x) / STEPCOUNT;
+       vList[4].dY = (cList[cIndex[1]].y - cList[cIndex[0]].y) / STEPCOUNT;
+       cStep = 0;
+    }
+}
+
+void Key(unsigned char key, int x, int y)
+{
+
+    switch (key) {
+      case 27:
+       free(image->data);
+        exit(1);
+      case 32:
+       if (cCount > 1) {
+           InitVList();
+           cIndex[0] = 0;
+           cIndex[1] = 1;
+           cStep = 0;
+           glEnable(GL_TEXTURE_2D);
+           op = OP_STRETCH;
+       }
+       break;
+      default:
+       return;
+    }
+
+    glutPostRedisplay();
+}
+
+void Mouse(int button, int state, int mouseX, int mouseY)
+{
+
+    if (state != GLUT_DOWN)
+       return;
+
+    if (op == OP_STRETCH) {
+       glDisable(GL_TEXTURE_2D);
+       cCount = 0;
+       op = OP_DRAWIMAGE;
+    } else {
+       SetPoint(mouseX, imageSizeY-mouseY);
+       op = OP_DRAWPOINT;
+    }
+
+    glutPostRedisplay();
+}
+
+void Animate(void)
+{
+
+    switch (op) {
+      case OP_STRETCH:
+       Stretch();
+       break;
+      case OP_DRAWPOINT:
+       DrawPoint();
+       break;
+      case OP_DRAWIMAGE:
+       DrawImage();
+       break;
+      default:
+        break;
+    }
+}
+
+static GLenum Args(int argc, char **argv)
+{
+    GLint i;
+
+    doubleBuffer = GL_FALSE;
+
+    for (i = 1; i < argc; i++) {
+       if (strcmp(argv[i], "-sb") == 0) {
+           doubleBuffer = GL_FALSE;
+       } else if (strcmp(argv[i], "-db") == 0) {
+           doubleBuffer = GL_TRUE;
+       } else if (strcmp(argv[i], "-f") == 0) {
+           if (i+1 >= argc || argv[i+1][0] == '-') {
+               printf("-f (No file name).\n");
+               return GL_FALSE;
+           } else {
+               fileName = argv[++i];
+           }
+       } else {
+           printf("%s (Bad option).\n", argv[i]);
+           return GL_FALSE;
+       }
+    }
+    return GL_TRUE;
+}
+
+void GLUTCALLBACK glut_post_redisplay_p(void)
+{
+      glutPostRedisplay();
+}
+
+int main(int argc, char **argv)
+{
+    GLenum type;
+
+    glutInit(&argc, argv);
+
+    if (Args(argc, argv) == GL_FALSE) {
+       exit(1);
+    }
+
+    if (fileName == 0) {
+       printf("No image file.\n");
+       exit(1);
+    }
+
+    image = LoadPPM(fileName);
+
+    /* changed powf and logf to pow and log -Brian */
+    imageSizeX = (int)pow(2.0, (float)((int)(log(image->sizeX)/log(2.0))));
+    imageSizeY = (int)pow(2.0, (float)((int)(log(image->sizeY)/log(2.0))));
+
+    glutInitWindowPosition(0, 0); glutInitWindowSize( imageSizeX, imageSizeY);
+
+    type = GLUT_RGB;
+    type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
+    glutInitDisplayMode(type);
+
+    if (glutCreateWindow("Stretch") == GL_FALSE) {
+        exit(1);
+    }
+
+    glViewport(0, 0, imageSizeX, imageSizeY);
+    gluOrtho2D(0, imageSizeX, 0, imageSizeY);
+    glClearColor(0.0, 0.0, 0.0, 0.0);
+
+    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+    glPixelStorei(GL_PACK_ALIGNMENT, 1);
+
+    ScaleImage(imageSizeX, imageSizeY);
+
+    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glTexImage2D(GL_TEXTURE_2D, 0, 3, image->sizeX, image->sizeY, 0,
+                 GL_RGB, GL_UNSIGNED_BYTE, (unsigned char *)image->data);
+
+    cCount = 0;
+    cIndex[0] = 0;
+    cIndex[1] = 0;
+    cStep = 0;
+    op = OP_DRAWIMAGE;
+
+    glutKeyboardFunc(Key);
+    glutMouseFunc(Mouse);
+    glutDisplayFunc(Animate);
+    glutIdleFunc(glut_post_redisplay_p);
+    glutMainLoop();
+       return 0;
+}
diff --git a/progs/samples/texture.c b/progs/samples/texture.c
new file mode 100644 (file)
index 0000000..7ee41ee
--- /dev/null
@@ -0,0 +1,474 @@
+/*
+ * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the name of
+ * Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
+ * ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <stdlib.h>
+#include <GL/glut.h>
+
+
+#include "loadppm.c"
+
+GLenum doubleBuffer;
+
+char *texFileName = 0;
+PPMImage *image;
+
+float *minFilter, *magFilter, *sWrapMode, *tWrapMode;
+float decal[] = {GL_DECAL};
+float modulate[] = {GL_MODULATE};
+float repeat[] = {GL_REPEAT};
+float clamp[] = {GL_CLAMP};
+float nr[] = {GL_NEAREST};
+float ln[] = {GL_LINEAR};
+float nr_mipmap_nr[] = {GL_NEAREST_MIPMAP_NEAREST};
+float nr_mipmap_ln[] = {GL_NEAREST_MIPMAP_LINEAR};
+float ln_mipmap_nr[] = {GL_LINEAR_MIPMAP_NEAREST};
+float ln_mipmap_ln[] = {GL_LINEAR_MIPMAP_LINEAR};
+GLint sphereMap[] = {GL_SPHERE_MAP};
+
+GLenum doSphere = GL_FALSE;
+float xRotation = 0.0, yRotation = 0.0, zTranslate = -3.125;
+
+GLint cube;
+float c[6][4][3] = {
+    {
+       {
+           1.0, 1.0, -1.0
+       },
+       {
+           -1.0, 1.0, -1.0
+       },
+       {
+           -1.0, -1.0, -1.0
+       },
+       {
+           1.0, -1.0, -1.0
+       }
+    },
+    {
+       {
+           1.0, 1.0, 1.0
+       },
+       {
+           1.0, 1.0, -1.0
+       },
+       {
+           1.0, -1.0, -1.0
+       },
+       {
+           1.0, -1.0, 1.0
+       }
+    },
+    {
+       {
+           -1.0, 1.0, 1.0
+       },
+       {
+           1.0, 1.0, 1.0
+       },
+       {
+           1.0, -1.0, 1.0
+       },
+       {
+           -1.0, -1.0, 1.0
+       }
+    },
+    {
+       {
+           -1.0, 1.0, -1.0
+       },
+       {
+           -1.0, 1.0, 1.0
+       },
+       {
+           -1.0, -1.0, 1.0
+       },
+       {
+           -1.0, -1.0, -1.0
+       }
+    },
+    {
+       {
+           -1.0, 1.0, 1.0
+       },
+       {
+           -1.0, 1.0, -1.0
+       },
+       {
+           1.0, 1.0, -1.0
+       },
+       {
+           1.0, 1.0, 1.0
+       }
+    },
+    {
+       {
+           -1.0, -1.0, -1.0
+       },
+       {
+           -1.0, -1.0, 1.0
+       },
+       {
+           1.0, -1.0, 1.0
+       },
+       {
+           1.0, -1.0, -1.0
+       }
+    }
+};
+static float n[6][3] = {
+    {
+       0.0, 0.0, -1.0
+    },
+    {
+       1.0, 0.0, 0.0
+    },
+    {
+       0.0, 0.0, 1.0
+    },
+    {
+       -1.0, 0.0, 0.0
+    },
+    {
+       0.0, 1.0, 0.0
+    },
+    {
+       0.0, -1.0, 0.0
+    }
+};
+static float t[6][4][2] = {
+    {
+       {
+           1.1,  1.1
+       },
+       {
+           -0.1, 1.1
+       },
+       {
+           -0.1, -0.1
+       },
+       {
+           1.1,  -0.1
+       }
+    },
+    {
+       {
+           1.1,  1.1
+       },
+       {
+           -0.1, 1.1
+       },
+       {
+           -0.1, -0.1
+       },
+       {
+           1.1,  -0.1
+       }
+    },
+    {
+       {
+           -0.1,  1.1
+       },
+       {
+           1.1, 1.1
+       },
+       {
+           1.1, -0.1
+       },
+       {
+           -0.1,  -0.1
+       }
+    },
+    {
+       {
+           1.1,  1.1
+       },
+       {
+           -0.1, 1.1
+       },
+       {
+           -0.1, -0.1
+       },
+       {
+           1.1,  -0.1
+       }
+    },
+    {
+       {
+           1.1,  1.1
+       },
+       {
+           -0.1, 1.1
+       },
+       {
+           -0.1, -0.1
+       },
+       {
+           1.1,  -0.1
+       }
+    },
+    {
+       {
+           1.1,  1.1
+       },
+       {
+           -0.1, 1.1
+       },
+       {
+           -0.1, -0.1
+       },
+       {
+           1.1,  -0.1
+       }
+    },
+};
+
+static void BuildCube(void)
+{
+    GLint i;
+
+    glNewList(cube, GL_COMPILE);
+    for (i = 0; i < 6; i++) {
+       glBegin(GL_POLYGON);
+           glNormal3fv(n[i]); glTexCoord2fv(t[i][0]); glVertex3fv(c[i][0]);
+           glNormal3fv(n[i]); glTexCoord2fv(t[i][1]); glVertex3fv(c[i][1]);
+           glNormal3fv(n[i]); glTexCoord2fv(t[i][2]); glVertex3fv(c[i][2]);
+           glNormal3fv(n[i]); glTexCoord2fv(t[i][3]); glVertex3fv(c[i][3]);
+       glEnd();
+    }
+    glEndList();
+}
+
+static void BuildLists(void)
+{
+
+    cube = glGenLists(1);
+    BuildCube();
+}
+
+static void Init(void)
+{
+
+    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+    gluBuild2DMipmaps(GL_TEXTURE_2D, 3, image->sizeX, image->sizeY,
+                     GL_RGB, GL_UNSIGNED_BYTE, image->data);
+    glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, decal);
+    glEnable(GL_TEXTURE_2D);
+
+    glFrontFace(GL_CCW);
+    glCullFace(GL_FRONT);
+    glEnable(GL_CULL_FACE);
+
+    BuildLists();
+
+    glClearColor(0.0, 0.0, 0.0, 0.0);
+
+    magFilter = nr;
+    minFilter = nr;
+    sWrapMode = repeat;
+    tWrapMode = repeat;
+}
+
+static void Reshape(int width, int height)
+{
+
+    glViewport(0, 0, (GLint)width, (GLint)height);
+
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    gluPerspective(145.0, 1.0, 0.01, 1000);
+    glMatrixMode(GL_MODELVIEW);
+}
+
+static void Key2(int key, int x, int y)
+{
+
+    switch (key) {
+      case GLUT_KEY_LEFT:
+       yRotation -= 0.5;
+       break;
+      case GLUT_KEY_RIGHT:
+       yRotation += 0.5;
+       break;
+      case GLUT_KEY_UP:
+       xRotation -= 0.5;
+       break;
+      case GLUT_KEY_DOWN:
+       xRotation += 0.5;
+       break;
+      default:
+       return;
+    }
+
+    glutPostRedisplay();
+}
+
+static void Key(unsigned char key, int x, int y)
+{
+
+    switch (key) {
+      case 27:
+       exit(1);
+
+      case 'T':
+       zTranslate += 0.25;
+       break;
+      case 't':
+       zTranslate -= 0.25;
+       break;
+
+      case 's':
+       doSphere = !doSphere;
+       if (doSphere) {
+           glTexGeniv(GL_S, GL_TEXTURE_GEN_MODE, sphereMap);
+           glTexGeniv(GL_T, GL_TEXTURE_GEN_MODE, sphereMap);
+           glEnable(GL_TEXTURE_GEN_S);
+           glEnable(GL_TEXTURE_GEN_T);
+       } else {
+           glDisable(GL_TEXTURE_GEN_S);
+           glDisable(GL_TEXTURE_GEN_T);
+       }
+       break;
+
+      case '0':
+       magFilter = nr;
+       break;
+      case '1':
+       magFilter = ln;
+       break;
+      case '2':
+       minFilter = nr;
+       break;
+      case '3':
+       minFilter = ln;
+       break;
+      case '4':
+       minFilter = nr_mipmap_nr;
+       break;
+      case '5':
+       minFilter = nr_mipmap_ln;
+       break;
+      case '6':
+       minFilter = ln_mipmap_nr;
+       break;
+      case '7':
+       minFilter = ln_mipmap_ln;
+       break;
+      default:
+       return;
+    }
+
+    glutPostRedisplay();
+}
+
+static void Draw(void)
+{
+
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, sWrapMode);
+    glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, tWrapMode);
+    glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
+    glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
+
+    glPushMatrix();
+
+    glTranslatef(0.0, 0.0, zTranslate);
+    glRotatef(xRotation, 1, 0, 0);
+    glRotatef(yRotation, 0, 1, 0);
+    glCallList(cube);
+
+    glPopMatrix();
+
+    glFlush();
+
+    if (doubleBuffer) {
+       glutSwapBuffers();
+    }
+}
+
+static GLenum Args(int argc, char **argv)
+{
+    GLint i;
+
+    doubleBuffer = GL_FALSE;
+
+    for (i = 1; i < argc; i++) {
+       if (strcmp(argv[i], "-sb") == 0) {
+           doubleBuffer = GL_FALSE;
+       } else if (strcmp(argv[i], "-db") == 0) {
+           doubleBuffer = GL_TRUE;
+       } else if (strcmp(argv[i], "-f") == 0) {
+           if (i+1 >= argc || argv[i+1][0] == '-') {
+               printf("-f (No file name).\n");
+               return GL_FALSE;
+           } else {
+               texFileName = argv[++i];
+           }
+       } else {
+           printf("%s (Bad option).\n", argv[i]);
+           return GL_FALSE;
+       }
+    }
+    return GL_TRUE;
+}
+
+int main(int argc, char **argv)
+{
+    GLenum type;
+
+    glutInit(&argc, argv);
+
+    if (Args(argc, argv) == GL_FALSE) {
+       exit(1);
+    }
+
+    if (texFileName == 0) {
+       printf("No image file.\n");
+       exit(1);
+    }
+
+    image = LoadPPM(texFileName);
+
+    glutInitWindowPosition(0, 0); glutInitWindowSize( 300, 300);
+
+    type = GLUT_RGB;
+    type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
+    glutInitDisplayMode(type);
+
+    if (glutCreateWindow("Texture Test") == GL_FALSE) {
+       exit(1);
+    }
+
+    Init();
+
+    glutReshapeFunc(Reshape);
+    glutKeyboardFunc(Key);
+    glutSpecialFunc(Key2);
+    glutDisplayFunc(Draw);
+    glutMainLoop();
+       return 0;
+}
diff --git a/progs/samples/tkmap.c b/progs/samples/tkmap.c
new file mode 100644 (file)
index 0000000..3ded79c
--- /dev/null
@@ -0,0 +1,71 @@
+
+enum {
+    COLOR_BLACK = 0,
+    COLOR_RED,
+    COLOR_GREEN,
+    COLOR_YELLOW,
+    COLOR_BLUE,
+    COLOR_MAGENTA,
+    COLOR_CYAN,
+    COLOR_WHITE
+};
+
+static float RGBMap[9][3] = {
+    {0, 0, 0},
+    {1, 0, 0},
+    {0, 1, 0},
+    {1, 1, 0},
+    {0, 0, 1},
+    {1, 0, 1},
+    {0, 1, 1},
+    {1, 1, 1},
+    {0.5, 0.5, 0.5}
+};
+
+static void SetColor(int c)
+{
+    if (glutGet(GLUT_WINDOW_RGBA))
+        glColor3fv(RGBMap[c]);
+    else
+        glIndexf(c);
+}
+
+static void InitMap(void)
+{
+    int i;
+
+    if (rgb)
+       return;
+
+    for (i = 0; i < 9; i++)
+           glutSetColor(i, RGBMap[i][0], RGBMap[i][1], RGBMap[i][2]);
+}
+
+static void SetFogRamp(int density, int startIndex)
+{
+    int fogValues, colorValues;
+    int i, j, k;
+    float intensity;
+
+    fogValues = 1 << density;
+    colorValues = 1 << startIndex;
+    for (i = 0; i < colorValues; i++) {
+       for (j = 0; j < fogValues; j++) {
+           k = i * fogValues + j;
+           intensity = (i * fogValues + j * colorValues) / 255.0;
+           glutSetColor(k, intensity, intensity, intensity);
+       }
+    }
+}
+
+static void SetGreyRamp(void)
+{
+    int i;
+    float intensity;
+
+    for (i = 0; i < 255; i++) {
+       intensity = i / 255.0;
+       glutSetColor(i, intensity, intensity, intensity);
+    }
+}
+
diff --git a/progs/samples/tri.c b/progs/samples/tri.c
new file mode 100644 (file)
index 0000000..7003251
--- /dev/null
@@ -0,0 +1,403 @@
+/*
+ * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the name of
+ * Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
+ * ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <GL/glut.h>
+
+
+#define        SOLID 1
+#define        LINE 2
+#define        POINT 3
+
+
+GLenum rgb, doubleBuffer, windType;
+GLint windW, windH;
+
+GLenum dithering = GL_TRUE;
+GLenum showVerticies = GL_TRUE;
+GLenum hideBottomTriangle = GL_FALSE;
+GLenum outline = GL_TRUE;
+GLenum culling = GL_FALSE;
+GLenum winding = GL_FALSE;
+GLenum face = GL_FALSE;
+GLenum state = SOLID;
+GLenum aaMode = GL_FALSE;
+GLenum shade = GL_TRUE;
+
+GLint color1, color2, color3;
+
+float zRotation = 90.0;
+float zoom = 1.0;
+
+float boxA[3] = {-100, -100, 0};
+float boxB[3] = { 100, -100, 0};
+float boxC[3] = { 100,  100, 0};
+float boxD[3] = {-100,  100, 0};
+
+float p0[3] = {-125,-80, 0};
+float p1[3] = {-125, 80, 0};
+float p2[3] = { 172,  0, 0};
+
+
+#include "tkmap.c"
+
+static void Init(void)
+{
+    float r, g, b;
+    float percent1, percent2;
+    GLint i, j;
+
+    glClearColor(0.0, 0.0, 0.0, 0.0);
+
+    glLineStipple(1, 0xF0F0);
+
+    glEnable(GL_SCISSOR_TEST);
+
+    if (!rgb) {
+       for (j = 0; j <= 12; j++) {
+           if (j <= 6) {
+               percent1 = j / 6.0;
+               r = 1.0 - 0.8 * percent1;
+               g = 0.2 + 0.8 * percent1;
+               b = 0.2;
+           } else {
+               percent1 = (j - 6) / 6.0;
+               r = 0.2;
+               g = 1.0 - 0.8 * percent1;
+               b = 0.2 + 0.8 * percent1;
+           }
+           glutSetColor(j+18, r, g, b);
+           for (i = 0; i < 16; i++) {
+               percent2 = i / 15.0;
+               glutSetColor(j*16+1+32, r*percent2, g*percent2, b*percent2);
+           }
+       }
+       color1 = 18;
+       color2 = 24;
+       color3 = 30;
+    }
+}
+
+static void Reshape(int width, int height)
+{
+
+    windW = (GLint)width;
+    windH = (GLint)height;
+}
+
+static void Key2(int key, int x, int y)
+{
+
+    switch (key) {
+      case GLUT_KEY_LEFT:
+       zRotation += 0.5;
+       break;
+      case GLUT_KEY_RIGHT:
+       zRotation -= 0.5;
+       break;
+      default:
+       return;
+    }
+
+    glutPostRedisplay();
+}
+
+static void Key(unsigned char key, int x, int y)
+{
+
+    switch (key) {
+      case 27:
+       exit(1);
+      case 'Z':
+       zoom *= 0.75;
+       break;
+      case 'z':
+       zoom /= 0.75;
+       if (zoom > 10) {
+           zoom = 10;
+       }
+       break;
+      case '1':
+       glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
+       break;
+      case '2':
+       glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+       break;
+      case '3':
+       glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+       break;
+      case '4':
+       state = POINT;
+       break;
+      case '5':
+       state = LINE;
+       break;
+      case '6':
+       state = SOLID;
+       break;
+      case '7':
+       culling = !culling;
+       break;
+      case '8':
+       winding = !winding;
+       break;
+      case '9':
+       face = !face;
+       break;
+      case 'v':
+       showVerticies = !showVerticies;
+       break;
+      case 's':
+       shade = !shade;
+       (shade) ? glShadeModel(GL_SMOOTH) : glShadeModel(GL_FLAT);
+       break;
+      case 'h':
+       hideBottomTriangle = !hideBottomTriangle;
+       break;
+      case 'o':
+       outline = !outline;
+       break;
+      case 'm':
+       dithering = !dithering;
+       break;
+      case '0':
+       aaMode = !aaMode;
+       if (aaMode) {
+           glEnable(GL_POLYGON_SMOOTH);
+           glEnable(GL_BLEND);
+           glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+           if (!rgb) {
+               color1 = 32;
+               color2 = 128;
+               color3 = 224;
+           }
+       } else {
+           glDisable(GL_POLYGON_SMOOTH);
+           glDisable(GL_BLEND);
+           if (!rgb) {
+               color1 = 18;
+               color2 = 24;
+               color3 = 30;
+           }
+       }
+       break;
+      default:
+       return;
+    }
+
+    glutPostRedisplay();
+}
+
+static void BeginPrim(void)
+{
+
+    switch (state) {
+      case SOLID:
+       glBegin(GL_POLYGON);
+       break;
+      case LINE:
+       glBegin(GL_LINE_LOOP);
+       break;
+      case POINT:
+       glBegin(GL_POINTS);
+       break;
+      default:
+        break;
+    }
+}
+
+static void EndPrim(void)
+{
+
+    glEnd();
+}
+
+static void Draw(void)
+{
+    float scaleX, scaleY;
+
+    glViewport(0, 0, windW, windH);
+
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    gluOrtho2D(-175, 175, -175, 175);
+    glMatrixMode(GL_MODELVIEW);
+
+    glScissor(0, 0, windW, windH);
+
+    (culling) ? glEnable(GL_CULL_FACE) : glDisable(GL_CULL_FACE);
+    (winding) ? glFrontFace(GL_CCW) : glFrontFace(GL_CW);
+    (face) ? glCullFace(GL_FRONT) : glCullFace(GL_BACK);
+
+    (dithering) ? glEnable(GL_DITHER) : glDisable(GL_DITHER);
+
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    SetColor(COLOR_GREEN);
+    glBegin(GL_LINE_LOOP);
+       glVertex3fv(boxA);
+       glVertex3fv(boxB);
+       glVertex3fv(boxC);
+       glVertex3fv(boxD);
+    glEnd();
+
+    if (!hideBottomTriangle) {
+       glPushMatrix();
+
+       glScalef(zoom, zoom, zoom);
+       glRotatef(zRotation, 0, 0, 1);
+
+       SetColor(COLOR_BLUE);
+       BeginPrim();
+           glVertex3fv(p0);
+           glVertex3fv(p1);
+           glVertex3fv(p2);
+       EndPrim();
+
+       if (showVerticies) {
+           (rgb) ? glColor3fv(RGBMap[COLOR_RED]) : glIndexf(color1);
+           glRectf(p0[0]-2, p0[1]-2, p0[0]+2, p0[1]+2);
+           (rgb) ? glColor3fv(RGBMap[COLOR_GREEN]) : glIndexf(color2);
+           glRectf(p1[0]-2, p1[1]-2, p1[0]+2, p1[1]+2);
+           (rgb) ? glColor3fv(RGBMap[COLOR_BLUE]) : glIndexf(color3);
+           glRectf(p2[0]-2, p2[1]-2, p2[0]+2, p2[1]+2);
+       }
+
+       glPopMatrix();
+    }
+
+    scaleX = (float)(windW - 20) / 2 / 175 * (175 - 100) + 10;
+    scaleY = (float)(windH - 20) / 2 / 175 * (175 - 100) + 10;
+
+    glViewport(scaleX, scaleY, windW-2*scaleX, windH-2*scaleY);
+
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    gluOrtho2D(-100, 100, -100, 100);
+    glMatrixMode(GL_MODELVIEW);
+
+    glScissor(scaleX, scaleY, windW-2*scaleX, windH-2*scaleY);
+
+    glPushMatrix();
+
+    glScalef(zoom, zoom, zoom);
+    glRotatef(zRotation, 0,0,1);
+
+    glPointSize(10);
+    glLineWidth(5);
+    glEnable(GL_POINT_SMOOTH);
+    glEnable(GL_LINE_STIPPLE);
+    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+    SetColor(COLOR_RED);
+    BeginPrim();
+       (rgb) ? glColor3fv(RGBMap[COLOR_RED]) : glIndexf(color1);
+       glVertex3fv(p0);
+       (rgb) ? glColor3fv(RGBMap[COLOR_GREEN]) : glIndexf(color2);
+       glVertex3fv(p1);
+       (rgb) ? glColor3fv(RGBMap[COLOR_BLUE]) : glIndexf(color3);
+       glVertex3fv(p2);
+    EndPrim();
+
+    glPointSize(1);
+    glLineWidth(1);
+    glDisable(GL_POINT_SMOOTH);
+    glDisable(GL_LINE_STIPPLE);
+    glBlendFunc(GL_ONE, GL_ZERO);
+
+    if (outline) {
+       SetColor(COLOR_WHITE);
+       glBegin(GL_LINE_LOOP);
+           glVertex3fv(p0);
+           glVertex3fv(p1);
+           glVertex3fv(p2);
+       glEnd();
+    }
+
+    glPopMatrix();
+
+    glFlush();
+
+    if (doubleBuffer) {
+       glutSwapBuffers();
+    }
+}
+
+static GLenum Args(int argc, char **argv)
+{
+    GLint i;
+
+    rgb = GL_TRUE;
+    doubleBuffer = GL_FALSE;
+
+    for (i = 1; i < argc; i++) {
+       if (strcmp(argv[i], "-ci") == 0) {
+           rgb = GL_FALSE;
+       } else if (strcmp(argv[i], "-rgb") == 0) {
+           rgb = GL_TRUE;
+       } else if (strcmp(argv[i], "-sb") == 0) {
+           doubleBuffer = GL_FALSE;
+       } else if (strcmp(argv[i], "-db") == 0) {
+           doubleBuffer = GL_TRUE;
+       } else {
+           printf("%s (Bad option).\n", argv[i]);
+           return GL_FALSE;
+       }
+    }
+    return GL_TRUE;
+}
+
+int main(int argc, char **argv)
+{
+    glutInit(&argc, argv);
+
+    if (Args(argc, argv) == GL_FALSE) {
+       exit(1);
+    }
+
+    windW = 600;
+    windH = 300;
+    glutInitWindowPosition(0, 0); glutInitWindowSize( windW, windH);
+
+    windType = (rgb) ? GLUT_RGB : GLUT_INDEX;
+    windType |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
+    glutInitDisplayMode(windType);
+
+    if (glutCreateWindow("Triangle Test") == GL_FALSE) {
+       exit(1);
+    }
+
+    InitMap();
+
+    Init();
+
+    glutReshapeFunc(Reshape);
+    glutKeyboardFunc(Key);
+    glutSpecialFunc(Key2);
+    glutDisplayFunc(Draw);
+    glutMainLoop();
+       return 0;
+}
diff --git a/progs/samples/wave.c b/progs/samples/wave.c
new file mode 100644 (file)
index 0000000..187c590
--- /dev/null
@@ -0,0 +1,602 @@
+/*
+ * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the name of
+ * Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
+ * ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+#include <GL/glut.h>
+
+#ifndef PI
+#define PI 3.14159265358979323846
+#endif
+
+#define GETCOORD(frame, x, y) (&(theMesh.coords[frame*theMesh.numCoords+(x)+(y)*(theMesh.widthX+1)]))
+#define GETFACET(frame, x, y) (&(theMesh.facets[frame*theMesh.numFacets+(x)+(y)*theMesh.widthX]))
+
+
+GLenum rgb, doubleBuffer;
+
+#include "tkmap.c"
+
+GLint colorIndexes1[3];
+GLint colorIndexes2[3];
+GLenum clearMask = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
+
+GLenum smooth = GL_FALSE;
+GLenum lighting = GL_TRUE;
+GLenum depth = GL_TRUE;
+GLenum stepMode = GL_FALSE;
+GLenum spinMode = GL_FALSE;
+GLint contouring = 0;
+
+GLint widthX, widthY;
+GLint checkerSize;
+float height;
+
+GLint frames, curFrame = 0, nextFrame = 0;
+
+struct facet {
+    float color[3];
+    float normal[3];
+};
+struct coord {
+    float vertex[3];
+    float normal[3];
+};
+struct mesh {
+    GLint widthX, widthY;
+    GLint numFacets;
+    GLint numCoords;
+    GLint frames;
+    struct coord *coords;
+    struct facet *facets;
+} theMesh;
+
+GLubyte contourTexture1[] = {
+    255, 255, 255, 255,
+    255, 255, 255, 255,
+    255, 255, 255, 255,
+    127, 127, 127, 127,
+};
+GLubyte contourTexture2[] = {
+    255, 255, 255, 255,
+    255, 127, 127, 127,
+    255, 127, 127, 127,
+    255, 127, 127, 127,
+};
+
+void GLUTCALLBACK glut_post_redisplay_p(void)
+{
+      glutPostRedisplay();
+}
+
+static void Animate(void)
+{
+    struct coord *coord;
+    struct facet *facet;
+    float *lastColor;
+    float *thisColor;
+    GLint i, j;
+
+    glClear(clearMask);
+
+    if (nextFrame || !stepMode) {
+       curFrame++;
+    }
+    if (curFrame >= theMesh.frames) {
+       curFrame = 0;
+    }
+
+    if ((nextFrame || !stepMode) && spinMode) {
+       glRotatef(5.0, 0.0, 0.0, 1.0);
+    }
+    nextFrame = 0;
+
+    for (i = 0; i < theMesh.widthX; i++) {
+       glBegin(GL_QUAD_STRIP);
+       lastColor = NULL;
+       for (j = 0; j < theMesh.widthY; j++) {
+           facet = GETFACET(curFrame, i, j);
+           if (!smooth && lighting) {
+               glNormal3fv(facet->normal);
+           }
+           if (lighting) {
+               if (rgb) {
+                   thisColor = facet->color;
+                   glColor3fv(facet->color);
+               } else {
+                   thisColor = facet->color;
+                   glMaterialfv(GL_FRONT_AND_BACK, GL_COLOR_INDEXES, 
+                                facet->color);
+               }
+           } else {
+               if (rgb) {
+                   thisColor = facet->color;
+                   glColor3fv(facet->color);
+               } else {
+                   thisColor = facet->color;
+                   glIndexf(facet->color[1]);
+               }
+           }
+
+           if (!lastColor || (thisColor[0] != lastColor[0] && smooth)) {
+               if (lastColor) {
+                   glEnd();
+                   glBegin(GL_QUAD_STRIP);
+               }
+               coord = GETCOORD(curFrame, i, j);
+               if (smooth && lighting) {
+                   glNormal3fv(coord->normal);
+               }
+               glVertex3fv(coord->vertex);
+
+               coord = GETCOORD(curFrame, i+1, j);
+               if (smooth && lighting) {
+                   glNormal3fv(coord->normal);
+               }
+               glVertex3fv(coord->vertex);
+           }
+
+           coord = GETCOORD(curFrame, i, j+1);
+           if (smooth && lighting) {
+               glNormal3fv(coord->normal);
+           }
+           glVertex3fv(coord->vertex);
+
+           coord = GETCOORD(curFrame, i+1, j+1);
+           if (smooth && lighting) {
+               glNormal3fv(coord->normal);
+           }
+           glVertex3fv(coord->vertex);
+
+           lastColor = thisColor;
+       }
+       glEnd();
+    }
+
+    glFlush();
+    if (doubleBuffer) {
+       glutSwapBuffers();
+    }
+}
+
+static void SetColorMap(void) 
+{
+    static float green[3] = {0.2, 1.0, 0.2};
+    static float red[3] = {1.0, 0.2, 0.2};
+    float *color, percent;
+    GLint *indexes, entries, i, j;
+
+    entries = glutGet(GLUT_WINDOW_COLORMAP_SIZE);
+
+    colorIndexes1[0] = 1;
+    colorIndexes1[1] = 1 + (GLint)((entries - 1) * 0.3);
+    colorIndexes1[2] = (GLint)((entries - 1) * 0.5);
+    colorIndexes2[0] = 1 + (GLint)((entries - 1) * 0.5);
+    colorIndexes2[1] = 1 + (GLint)((entries - 1) * 0.8);
+    colorIndexes2[2] = entries - 1;
+
+    for (i = 0; i < 2; i++) {
+       switch (i) {
+         case 0:
+           color = green;
+           indexes = colorIndexes1;
+           break;
+         case 1:
+           color = red;
+           indexes = colorIndexes2;
+           break;
+       }
+
+       for (j = indexes[0]; j < indexes[1]; j++) {
+           percent = 0.2 + 0.8 * (j - indexes[0]) /
+                     (float)(indexes[1] - indexes[0]);
+           glutSetColor(j, percent*color[0], percent*color[1],
+                          percent*color[2]);
+       }
+       for (j=indexes[1]; j<=indexes[2]; j++) {
+           percent = (j - indexes[1]) / (float)(indexes[2] - indexes[1]);
+           glutSetColor(j, percent*(1-color[0])+color[0],
+                          percent*(1-color[1])+color[1],
+                          percent*(1-color[2])+color[2]);
+       }
+    }
+}
+
+static void InitMesh(void)
+{
+    struct coord *coord;
+    struct facet *facet;
+    float dp1[3], dp2[3];
+    float *pt1, *pt2, *pt3;
+    float angle, d, x, y;
+    GLint numFacets, numCoords, frameNum, i, j;
+
+    theMesh.widthX = widthX;
+    theMesh.widthY = widthY;
+    theMesh.frames = frames;
+
+    numFacets = widthX * widthY;
+    numCoords = (widthX + 1) * (widthY + 1);
+
+    theMesh.numCoords = numCoords;
+    theMesh.numFacets = numFacets;
+
+    theMesh.coords = (struct coord *)malloc(frames*numCoords*
+                                           sizeof(struct coord));
+    theMesh.facets = (struct facet *)malloc(frames*numFacets*
+                                           sizeof(struct facet));
+    if (theMesh.coords == NULL || theMesh.facets == NULL) {
+       printf("Out of memory.\n");
+       exit(1);
+    }
+
+    for (frameNum = 0; frameNum < frames; frameNum++) {
+       for (i = 0; i <= widthX; i++) {
+           x = i / (float)widthX;
+           for (j = 0; j <= widthY; j++) {
+               y = j / (float)widthY;
+
+               d = sqrt(x*x+y*y);
+               if (d == 0.0) {
+                   d = 0.0001;
+               }
+               angle = 2 * PI * d + (2 * PI / frames * frameNum);
+
+               coord = GETCOORD(frameNum, i, j);
+
+               coord->vertex[0] = x - 0.5;
+               coord->vertex[1] = y - 0.5;
+               coord->vertex[2] = (height - height * d) * cos(angle);
+
+               coord->normal[0] = -(height / d) * x * ((1 - d) * 2 * PI *
+                                  sin(angle) + cos(angle));
+               coord->normal[1] = -(height / d) * y * ((1 - d) * 2 * PI *
+                                  sin(angle) + cos(angle));
+               coord->normal[2] = -1;
+
+               d = 1.0 / sqrt(coord->normal[0]*coord->normal[0]+
+                              coord->normal[1]*coord->normal[1]+1);
+               coord->normal[0] *= d;
+               coord->normal[1] *= d;
+               coord->normal[2] *= d;
+           }
+       }
+       for (i = 0; i < widthX; i++) {
+           for (j = 0; j < widthY; j++) {
+               facet = GETFACET(frameNum, i, j);
+               if (((i/checkerSize)%2)^(j/checkerSize)%2) {
+                   if (rgb) {
+                       facet->color[0] = 1.0;
+                       facet->color[1] = 0.2;
+                       facet->color[2] = 0.2;
+                   } else {
+                       facet->color[0] = colorIndexes1[0];
+                       facet->color[1] = colorIndexes1[1];
+                       facet->color[2] = colorIndexes1[2];
+                   }
+               } else {
+                   if (rgb) {
+                       facet->color[0] = 0.2;
+                       facet->color[1] = 1.0;
+                       facet->color[2] = 0.2;
+                   } else {
+                       facet->color[0] = colorIndexes2[0];
+                       facet->color[1] = colorIndexes2[1];
+                       facet->color[2] = colorIndexes2[2];
+                   }
+               }
+               pt1 = GETCOORD(frameNum, i, j)->vertex;
+               pt2 = GETCOORD(frameNum, i, j+1)->vertex;
+               pt3 = GETCOORD(frameNum, i+1, j+1)->vertex;
+
+               dp1[0] = pt2[0] - pt1[0];
+               dp1[1] = pt2[1] - pt1[1];
+               dp1[2] = pt2[2] - pt1[2];
+
+               dp2[0] = pt3[0] - pt2[0];
+               dp2[1] = pt3[1] - pt2[1];
+               dp2[2] = pt3[2] - pt2[2];
+
+               facet->normal[0] = dp1[1] * dp2[2] - dp1[2] * dp2[1];
+               facet->normal[1] = dp1[2] * dp2[0] - dp1[0] * dp2[2];
+               facet->normal[2] = dp1[0] * dp2[1] - dp1[1] * dp2[0];
+
+               d = 1.0 / sqrt(facet->normal[0]*facet->normal[0]+
+                              facet->normal[1]*facet->normal[1]+
+                              facet->normal[2]*facet->normal[2]);
+
+               facet->normal[0] *= d;
+               facet->normal[1] *= d;
+               facet->normal[2] *= d;
+           }
+       }
+    }
+}
+
+static void InitMaterials(void)
+{
+    static float ambient[] = {0.1, 0.1, 0.1, 1.0};
+    static float diffuse[] = {0.5, 1.0, 1.0, 1.0};
+    static float position[] = {90.0, 90.0, 150.0, 0.0};
+    static float front_mat_shininess[] = {60.0};
+    static float front_mat_specular[] = {0.2, 0.2, 0.2, 1.0};
+    static float front_mat_diffuse[] = {0.5, 0.28, 0.38, 1.0};
+    static float back_mat_shininess[] = {60.0};
+    static float back_mat_specular[] = {0.5, 0.5, 0.2, 1.0};
+    static float back_mat_diffuse[] = {1.0, 1.0, 0.2, 1.0};
+    static float lmodel_ambient[] = {1.0, 1.0, 1.0, 1.0};
+    static float lmodel_twoside[] = {GL_TRUE};
+
+    glMatrixMode(GL_PROJECTION);
+    gluPerspective(90.0, 1.0, 0.5, 10.0);
+
+    glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
+    glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
+    glLightfv(GL_LIGHT0, GL_POSITION, position);
+    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
+    glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
+    glEnable(GL_LIGHTING);
+    glEnable(GL_LIGHT0);
+    
+    glMaterialfv(GL_FRONT, GL_SHININESS, front_mat_shininess);
+    glMaterialfv(GL_FRONT, GL_SPECULAR, front_mat_specular);
+    glMaterialfv(GL_FRONT, GL_DIFFUSE, front_mat_diffuse);
+    glMaterialfv(GL_BACK, GL_SHININESS, back_mat_shininess);
+    glMaterialfv(GL_BACK, GL_SPECULAR, back_mat_specular);
+    glMaterialfv(GL_BACK, GL_DIFFUSE, back_mat_diffuse);
+    if (rgb) {
+       glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
+    }
+
+    if (rgb) {
+       glEnable(GL_COLOR_MATERIAL);
+    } else {
+       SetColorMap();
+    }
+}
+
+static void InitTexture(void)
+{
+
+    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+}
+
+static void Init(void)
+{
+
+    glClearColor(0.0, 0.0, 0.0, 0.0);
+
+    glShadeModel(GL_FLAT);
+    
+    glFrontFace(GL_CW);
+
+    glEnable(GL_DEPTH_TEST);
+
+    InitMaterials();
+    InitTexture();
+    InitMesh();
+
+    glMatrixMode(GL_MODELVIEW);
+    glTranslatef(0.0, 0.4, -1.8);
+    glScalef(2.0, 2.0, 2.0);
+    glRotatef(-35.0, 1.0, 0.0, 0.0);
+    glRotatef(35.0, 0.0, 0.0, 1.0);
+}
+
+static void Reshape(int width, int height)
+{
+
+    glViewport(0, 0, (GLint)width, (GLint)height);
+}
+
+static void Key(unsigned char key, int x, int y)
+{
+
+    switch (key) {
+      case 27:
+       exit(1);
+      case 'c':
+       contouring++;
+       if (contouring == 1) {
+           static GLfloat map[4] = {0, 0, 20, 0};
+
+           glTexImage2D(GL_TEXTURE_2D, 0, 3, 4, 4, 0, GL_LUMINANCE,
+                        GL_UNSIGNED_BYTE, (GLvoid *)contourTexture1);
+           glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+           glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+           glTexGenfv(GL_S, GL_OBJECT_PLANE, map);
+           glTexGenfv(GL_T, GL_OBJECT_PLANE, map);
+           glEnable(GL_TEXTURE_2D);
+           glEnable(GL_TEXTURE_GEN_S);
+           glEnable(GL_TEXTURE_GEN_T);
+       } else if (contouring == 2) {
+           static GLfloat map[4] = {0, 0, 20, 0};
+
+           glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
+           glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
+           glPushMatrix();
+           glMatrixMode(GL_MODELVIEW);
+           glLoadIdentity();
+           glTexGenfv(GL_S, GL_EYE_PLANE, map);
+           glTexGenfv(GL_T, GL_EYE_PLANE, map);
+           glPopMatrix();
+       } else {
+           contouring = 0;
+           glDisable(GL_TEXTURE_GEN_S);
+           glDisable(GL_TEXTURE_GEN_T);
+           glDisable(GL_TEXTURE_2D);
+       }
+       break;
+      case 's':
+       smooth = !smooth;
+       if (smooth) {
+           glShadeModel(GL_SMOOTH);
+       } else {
+           glShadeModel(GL_FLAT);
+       }
+       break;
+      case 'l':
+       lighting = !lighting;
+       if (lighting) {
+           glEnable(GL_LIGHTING);
+           glEnable(GL_LIGHT0);
+           if (rgb) {
+               glEnable(GL_COLOR_MATERIAL);
+           }
+       } else {
+           glDisable(GL_LIGHTING);
+           glDisable(GL_LIGHT0);
+           if (rgb) {
+               glDisable(GL_COLOR_MATERIAL);
+           }
+       }
+       break;
+      case 'd':
+       depth = !depth;
+       if (depth) {
+           glEnable(GL_DEPTH_TEST);
+           clearMask |= GL_DEPTH_BUFFER_BIT;
+       } else {
+           glDisable(GL_DEPTH_TEST);
+           clearMask &= ~GL_DEPTH_BUFFER_BIT;
+       }
+       break;
+      case 32:
+       stepMode = !stepMode;
+       if (stepMode) {
+           glutIdleFunc(0);
+       } else {
+           glutIdleFunc(glut_post_redisplay_p);
+       }
+       break;
+      case 'n':
+       if (stepMode) {
+           nextFrame = 1;
+       }
+       break;
+      case 'a':
+       spinMode = !spinMode;
+       break;
+      default:
+       return;
+    }
+    glutPostRedisplay();
+}
+
+static GLenum Args(int argc, char **argv)
+{
+    GLint i;
+
+    rgb = GL_TRUE;
+    doubleBuffer = GL_FALSE;
+    frames = 10;
+    widthX = 10;
+    widthY = 10;
+    checkerSize = 2;
+    height = 0.2;
+
+    for (i = 1; i < argc; i++) {
+       if (strcmp(argv[i], "-ci") == 0) {
+           rgb = GL_FALSE;
+       } else if (strcmp(argv[i], "-rgb") == 0) {
+           rgb = GL_TRUE;
+       } else if (strcmp(argv[i], "-sb") == 0) {
+           doubleBuffer = GL_FALSE;
+       } else if (strcmp(argv[i], "-db") == 0) {
+           doubleBuffer = GL_TRUE;
+       } else if (strcmp(argv[i], "-grid") == 0) {
+           if (i+2 >= argc || argv[i+1][0] == '-' || argv[i+2][0] == '-') {
+               printf("-grid (No numbers).\n");
+               return GL_FALSE;
+           } else {
+               widthX = atoi(argv[++i]);
+               widthY = atoi(argv[++i]);
+           }
+       } else if (strcmp(argv[i], "-size") == 0) {
+           if (i+1 >= argc || argv[i+1][0] == '-') {
+               printf("-checker (No number).\n");
+               return GL_FALSE;
+           } else {
+               checkerSize = atoi(argv[++i]);
+           }
+       } else if (strcmp(argv[i], "-wave") == 0) {
+           if (i+1 >= argc || argv[i+1][0] == '-') {
+               printf("-wave (No number).\n");
+               return GL_FALSE;
+           } else {
+               height = atof(argv[++i]);
+           }
+       } else if (strcmp(argv[i], "-frames") == 0) {
+           if (i+1 >= argc || argv[i+1][0] == '-') {
+               printf("-frames (No number).\n");
+               return GL_FALSE;
+           } else {
+               frames = atoi(argv[++i]);
+           }
+       } else {
+           printf("%s (Bad option).\n", argv[i]);
+           return GL_FALSE;
+       }
+    }
+    return GL_TRUE;
+}
+
+int main(int argc, char **argv)
+{
+    GLenum type;
+
+    glutInit(&argc, argv);
+
+    if (Args(argc, argv) == GL_FALSE) {
+       exit(1);
+    }
+
+    glutInitWindowPosition(0, 0); glutInitWindowSize( 300, 300);
+
+    type = GLUT_DEPTH;
+    type |= (rgb) ? GLUT_RGB : GLUT_INDEX;
+    type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
+    glutInitDisplayMode(type);
+
+    if (glutCreateWindow("Wave Demo") == GL_FALSE) {
+       exit(1);
+    }
+
+    InitMap();
+
+    Init();
+
+    glutReshapeFunc(Reshape);
+    glutKeyboardFunc(Key);
+    glutDisplayFunc(Animate);
+    glutIdleFunc(glut_post_redisplay_p);
+    glutMainLoop();
+       return 0;
+}
diff --git a/progs/util/README b/progs/util/README
new file mode 100644 (file)
index 0000000..ca89d34
--- /dev/null
@@ -0,0 +1,22 @@
+
+This directory is a collection of function which may be useful to
+OpenGL/Mesa programmers.
+
+
+errcheck.c     - an OpenGL error check/report function
+glutskel.c     - handy skeleton for GLUT programs
+idproj.c       - setup an identity projection
+mwmborder.c    - remove Motif window decoration/border
+winpos.c       - set absolute window raster position
+readtex.c      - load textures/mipmaps from an .rgb file
+showbuffer.[ch]        - show depth, alpha, or stencil buffer contents
+glstate.[ch]   - query/print GL state variables, for debugging, etc.
+sampleMakefile - example Makefile for making OpenGL/Mesa apps on Unix
+dumpsate.c     - dump all OpenGL state, from Stephane Rehel
+imagesgi.cpp,.h - read SGI image files
+
+
+more to come...
+
+----------------------------------------------------------------------
+$Id: README,v 1.1 1999/08/19 00:55:42 jtg Exp $
diff --git a/progs/util/dumpstate.c b/progs/util/dumpstate.c
new file mode 100644 (file)
index 0000000..4c039a4
--- /dev/null
@@ -0,0 +1,1959 @@
+
+/*
+ *
+ * From: Stephane Rehel <rehel@worldnet.fr>
+ * Date: Mon, 31 May 1999 18:40:54 -0400
+ * To: Paul Brian <brianp@ra.avid.com>
+ * Subject: OpenGL State Dump Function
+ * 
+ * Here is a function that dumps the current OpenGL state. I wrote it
+ * some time ago.
+ * 
+ * In the attachment:
+ *   + the code itself
+ *   + its output
+ * 
+ * I think Mesa is wrong on some getBooleanv(). For example, GL_VERTEX_ARRAY
+ * is queried by IsEnabled() (cf. p. 196 of the spec). But on page 193
+ * we can read that all the boolean attribs that can be queried by IsEnabled()
+ * can also be queried by IsEnabled().
+ * 
+ * I had duplicated all the enums (LOCAL_*) so that the code can run on any 
+ * OpenGL version, even if an enum is not recognized.
+ * 
+ * The code can be shipped in the public domain.
+ * 
+ * Stephane.
+ */
+
+
+/*
+ * Stephane Rehel
+ * Creation: February 5 1999
+ */
+
+#include <stdio.h>
+#include <GL/gl.h>
+
+/***************************************************************************/
+
+enum {
+        /* Data types */
+        LOCAL_GL_BYTE                         = 0x1400,
+        LOCAL_GL_UNSIGNED_BYTE                = 0x1401,
+        LOCAL_GL_SHORT                        = 0x1402,
+        LOCAL_GL_UNSIGNED_SHORT               = 0x1403,
+        LOCAL_GL_INT                          = 0x1404,
+        LOCAL_GL_UNSIGNED_INT                 = 0x1405,
+        LOCAL_GL_FLOAT                        = 0x1406,
+        LOCAL_GL_DOUBLE                       = 0x140A,
+        LOCAL_GL_2_BYTES                      = 0x1407,
+        LOCAL_GL_3_BYTES                      = 0x1408,
+        LOCAL_GL_4_BYTES                      = 0x1409,
+
+        /* Primitives */
+        LOCAL_GL_LINES                        = 0x0001,
+        LOCAL_GL_POINTS                       = 0x0000,
+        LOCAL_GL_LINE_STRIP                   = 0x0003,
+        LOCAL_GL_LINE_LOOP                    = 0x0002,
+        LOCAL_GL_TRIANGLES                    = 0x0004,
+        LOCAL_GL_TRIANGLE_STRIP               = 0x0005,
+        LOCAL_GL_TRIANGLE_FAN                 = 0x0006,
+        LOCAL_GL_QUADS                        = 0x0007,
+        LOCAL_GL_QUAD_STRIP                   = 0x0008,
+        LOCAL_GL_POLYGON                      = 0x0009,
+        LOCAL_GL_EDGE_FLAG                    = 0x0B43,
+
+        /* Vertex Arrays */
+        LOCAL_GL_VERTEX_ARRAY                 = 0x8074,
+        LOCAL_GL_NORMAL_ARRAY                 = 0x8075,
+        LOCAL_GL_COLOR_ARRAY                  = 0x8076,
+        LOCAL_GL_INDEX_ARRAY                  = 0x8077,
+        LOCAL_GL_TEXTURE_COORD_ARRAY          = 0x8078,
+        LOCAL_GL_EDGE_FLAG_ARRAY              = 0x8079,
+        LOCAL_GL_VERTEX_ARRAY_SIZE            = 0x807A,
+        LOCAL_GL_VERTEX_ARRAY_TYPE            = 0x807B,
+        LOCAL_GL_VERTEX_ARRAY_STRIDE          = 0x807C,
+        LOCAL_GL_NORMAL_ARRAY_TYPE            = 0x807E,
+        LOCAL_GL_NORMAL_ARRAY_STRIDE          = 0x807F,
+        LOCAL_GL_COLOR_ARRAY_SIZE             = 0x8081,
+        LOCAL_GL_COLOR_ARRAY_TYPE             = 0x8082,
+        LOCAL_GL_COLOR_ARRAY_STRIDE           = 0x8083,
+        LOCAL_GL_INDEX_ARRAY_TYPE             = 0x8085,
+        LOCAL_GL_INDEX_ARRAY_STRIDE           = 0x8086,
+        LOCAL_GL_TEXTURE_COORD_ARRAY_SIZE     = 0x8088,
+        LOCAL_GL_TEXTURE_COORD_ARRAY_TYPE     = 0x8089,
+        LOCAL_GL_TEXTURE_COORD_ARRAY_STRIDE   = 0x808A,
+        LOCAL_GL_EDGE_FLAG_ARRAY_STRIDE       = 0x808C,
+        LOCAL_GL_VERTEX_ARRAY_POINTER         = 0x808E,
+        LOCAL_GL_NORMAL_ARRAY_POINTER         = 0x808F,
+        LOCAL_GL_COLOR_ARRAY_POINTER          = 0x8090,
+        LOCAL_GL_INDEX_ARRAY_POINTER          = 0x8091,
+        LOCAL_GL_TEXTURE_COORD_ARRAY_POINTER  = 0x8092,
+        LOCAL_GL_EDGE_FLAG_ARRAY_POINTER      = 0x8093,
+        LOCAL_GL_V2F                          = 0x2A20,
+        LOCAL_GL_V3F                          = 0x2A21,
+        LOCAL_GL_C4UB_V2F                     = 0x2A22,
+        LOCAL_GL_C4UB_V3F                     = 0x2A23,
+        LOCAL_GL_C3F_V3F                      = 0x2A24,
+        LOCAL_GL_N3F_V3F                      = 0x2A25,
+        LOCAL_GL_C4F_N3F_V3F                  = 0x2A26,
+        LOCAL_GL_T2F_V3F                      = 0x2A27,
+        LOCAL_GL_T4F_V4F                      = 0x2A28,
+        LOCAL_GL_T2F_C4UB_V3F                 = 0x2A29,
+        LOCAL_GL_T2F_C3F_V3F                  = 0x2A2A,
+        LOCAL_GL_T2F_N3F_V3F                  = 0x2A2B,
+        LOCAL_GL_T2F_C4F_N3F_V3F              = 0x2A2C,
+        LOCAL_GL_T4F_C4F_N3F_V4F              = 0x2A2D,
+
+        /* Matrix Mode */
+        LOCAL_GL_MATRIX_MODE                  = 0x0BA0,
+        LOCAL_GL_MODELVIEW                    = 0x1700,
+        LOCAL_GL_PROJECTION                   = 0x1701,
+        LOCAL_GL_TEXTURE                      = 0x1702,
+
+        /* Points */
+        LOCAL_GL_POINT_SMOOTH                 = 0x0B10,
+        LOCAL_GL_POINT_SIZE                   = 0x0B11,
+        LOCAL_GL_POINT_SIZE_GRANULARITY       = 0x0B13,
+        LOCAL_GL_POINT_SIZE_RANGE             = 0x0B12,
+
+        /* Lines */
+        LOCAL_GL_LINE_SMOOTH                  = 0x0B20,
+        LOCAL_GL_LINE_STIPPLE                 = 0x0B24,
+        LOCAL_GL_LINE_STIPPLE_PATTERN         = 0x0B25,
+        LOCAL_GL_LINE_STIPPLE_REPEAT          = 0x0B26,
+        LOCAL_GL_LINE_WIDTH                   = 0x0B21,
+        LOCAL_GL_LINE_WIDTH_GRANULARITY       = 0x0B23,
+        LOCAL_GL_LINE_WIDTH_RANGE             = 0x0B22,
+
+        /* Polygons */
+        LOCAL_GL_POINT                        = 0x1B00,
+        LOCAL_GL_LINE                         = 0x1B01,
+        LOCAL_GL_FILL                         = 0x1B02,
+        LOCAL_GL_CCW                          = 0x0901,
+        LOCAL_GL_CW                           = 0x0900,
+        LOCAL_GL_FRONT                        = 0x0404,
+        LOCAL_GL_BACK                         = 0x0405,
+        LOCAL_GL_CULL_FACE                    = 0x0B44,
+        LOCAL_GL_CULL_FACE_MODE               = 0x0B45,
+        LOCAL_GL_POLYGON_SMOOTH               = 0x0B41,
+        LOCAL_GL_POLYGON_STIPPLE              = 0x0B42,
+        LOCAL_GL_FRONT_FACE                   = 0x0B46,
+        LOCAL_GL_POLYGON_MODE                 = 0x0B40,
+        LOCAL_GL_POLYGON_OFFSET_FACTOR        = 0x8038,
+        LOCAL_GL_POLYGON_OFFSET_UNITS         = 0x2A00,
+        LOCAL_GL_POLYGON_OFFSET_POINT         = 0x2A01,
+        LOCAL_GL_POLYGON_OFFSET_LINE          = 0x2A02,
+        LOCAL_GL_POLYGON_OFFSET_FILL          = 0x8037,
+
+        /* Display Lists */
+        LOCAL_GL_COMPILE                      = 0x1300,
+        LOCAL_GL_COMPILE_AND_EXECUTE          = 0x1301,
+        LOCAL_GL_LIST_BASE                    = 0x0B32,
+        LOCAL_GL_LIST_INDEX                   = 0x0B33,
+        LOCAL_GL_LIST_MODE                    = 0x0B30,
+
+        /* Depth buffer */
+        LOCAL_GL_NEVER                        = 0x0200,
+        LOCAL_GL_LESS                         = 0x0201,
+        LOCAL_GL_GEQUAL                       = 0x0206,
+        LOCAL_GL_LEQUAL                       = 0x0203,
+        LOCAL_GL_GREATER                      = 0x0204,
+        LOCAL_GL_NOTEQUAL                     = 0x0205,
+        LOCAL_GL_EQUAL                        = 0x0202,
+        LOCAL_GL_ALWAYS                       = 0x0207,
+        LOCAL_GL_DEPTH_TEST                   = 0x0B71,
+        LOCAL_GL_DEPTH_BITS                   = 0x0D56,
+        LOCAL_GL_DEPTH_CLEAR_VALUE            = 0x0B73,
+        LOCAL_GL_DEPTH_FUNC                   = 0x0B74,
+        LOCAL_GL_DEPTH_RANGE                  = 0x0B70,
+        LOCAL_GL_DEPTH_WRITEMASK              = 0x0B72,
+        LOCAL_GL_DEPTH_COMPONENT              = 0x1902,
+
+        /* Lighting */
+        LOCAL_GL_LIGHTING                     = 0x0B50,
+        LOCAL_GL_LIGHT0                       = 0x4000,
+        LOCAL_GL_LIGHT1                       = 0x4001,
+        LOCAL_GL_LIGHT2                       = 0x4002,
+        LOCAL_GL_LIGHT3                       = 0x4003,
+        LOCAL_GL_LIGHT4                       = 0x4004,
+        LOCAL_GL_LIGHT5                       = 0x4005,
+        LOCAL_GL_LIGHT6                       = 0x4006,
+        LOCAL_GL_LIGHT7                       = 0x4007,
+        LOCAL_GL_SPOT_EXPONENT                = 0x1205,
+        LOCAL_GL_SPOT_CUTOFF                  = 0x1206,
+        LOCAL_GL_CONSTANT_ATTENUATION         = 0x1207,
+        LOCAL_GL_LINEAR_ATTENUATION           = 0x1208,
+        LOCAL_GL_QUADRATIC_ATTENUATION        = 0x1209,
+        LOCAL_GL_AMBIENT                      = 0x1200,
+        LOCAL_GL_DIFFUSE                      = 0x1201,
+        LOCAL_GL_SPECULAR                     = 0x1202,
+        LOCAL_GL_SHININESS                    = 0x1601,
+        LOCAL_GL_EMISSION                     = 0x1600,
+        LOCAL_GL_POSITION                     = 0x1203,
+        LOCAL_GL_SPOT_DIRECTION               = 0x1204,
+        LOCAL_GL_AMBIENT_AND_DIFFUSE          = 0x1602,
+        LOCAL_GL_COLOR_INDEXES                = 0x1603,
+        LOCAL_GL_LIGHT_MODEL_TWO_SIDE         = 0x0B52,
+        LOCAL_GL_LIGHT_MODEL_LOCAL_VIEWER     = 0x0B51,
+        LOCAL_GL_LIGHT_MODEL_AMBIENT          = 0x0B53,
+        LOCAL_GL_FRONT_AND_BACK               = 0x0408,
+        LOCAL_GL_SHADE_MODEL                  = 0x0B54,
+        LOCAL_GL_FLAT                         = 0x1D00,
+        LOCAL_GL_SMOOTH                       = 0x1D01,
+        LOCAL_GL_COLOR_MATERIAL               = 0x0B57,
+        LOCAL_GL_COLOR_MATERIAL_FACE          = 0x0B55,
+        LOCAL_GL_COLOR_MATERIAL_PARAMETER     = 0x0B56,
+        LOCAL_GL_NORMALIZE                    = 0x0BA1,
+
+        /* User clipping planes */
+        LOCAL_GL_CLIP_PLANE0                  = 0x3000,
+        LOCAL_GL_CLIP_PLANE1                  = 0x3001,
+        LOCAL_GL_CLIP_PLANE2                  = 0x3002,
+        LOCAL_GL_CLIP_PLANE3                  = 0x3003,
+        LOCAL_GL_CLIP_PLANE4                  = 0x3004,
+        LOCAL_GL_CLIP_PLANE5                  = 0x3005,
+
+        /* Accumulation buffer */
+        LOCAL_GL_ACCUM_RED_BITS               = 0x0D58,
+        LOCAL_GL_ACCUM_GREEN_BITS             = 0x0D59,
+        LOCAL_GL_ACCUM_BLUE_BITS              = 0x0D5A,
+        LOCAL_GL_ACCUM_ALPHA_BITS             = 0x0D5B,
+        LOCAL_GL_ACCUM_CLEAR_VALUE            = 0x0B80,
+        LOCAL_GL_ACCUM                        = 0x0100,
+        LOCAL_GL_ADD                          = 0x0104,
+        LOCAL_GL_LOAD                         = 0x0101,
+        LOCAL_GL_MULT                         = 0x0103,
+        LOCAL_GL_RETURN                       = 0x0102,
+
+        /* Alpha testing */
+        LOCAL_GL_ALPHA_TEST                   = 0x0BC0,
+        LOCAL_GL_ALPHA_TEST_REF               = 0x0BC2,
+        LOCAL_GL_ALPHA_TEST_FUNC              = 0x0BC1,
+
+        /* Blending */
+        LOCAL_GL_BLEND                        = 0x0BE2,
+        LOCAL_GL_BLEND_SRC                    = 0x0BE1,
+        LOCAL_GL_BLEND_DST                    = 0x0BE0,
+        LOCAL_GL_ZERO                         = 0,
+        LOCAL_GL_ONE                          = 1,
+        LOCAL_GL_SRC_COLOR                    = 0x0300,
+        LOCAL_GL_ONE_MINUS_SRC_COLOR          = 0x0301,
+        LOCAL_GL_DST_COLOR                    = 0x0306,
+        LOCAL_GL_ONE_MINUS_DST_COLOR          = 0x0307,
+        LOCAL_GL_SRC_ALPHA                    = 0x0302,
+        LOCAL_GL_ONE_MINUS_SRC_ALPHA          = 0x0303,
+        LOCAL_GL_DST_ALPHA                    = 0x0304,
+        LOCAL_GL_ONE_MINUS_DST_ALPHA          = 0x0305,
+        LOCAL_GL_SRC_ALPHA_SATURATE           = 0x0308,
+        LOCAL_GL_CONSTANT_COLOR               = 0x8001,
+        LOCAL_GL_ONE_MINUS_CONSTANT_COLOR     = 0x8002,
+        LOCAL_GL_CONSTANT_ALPHA               = 0x8003,
+        LOCAL_GL_ONE_MINUS_CONSTANT_ALPHA     = 0x8004,
+
+        /* Render Mode */
+        LOCAL_GL_FEEDBACK                     = 0x1C01,
+        LOCAL_GL_RENDER                       = 0x1C00,
+        LOCAL_GL_SELECT                       = 0x1C02,
+
+        /* Feedback */
+        LOCAL_GL_2D                           = 0x0600,
+        LOCAL_GL_3D                           = 0x0601,
+        LOCAL_GL_3D_COLOR                     = 0x0602,
+        LOCAL_GL_3D_COLOR_TEXTURE             = 0x0603,
+        LOCAL_GL_4D_COLOR_TEXTURE             = 0x0604,
+        LOCAL_GL_POINT_TOKEN                  = 0x0701,
+        LOCAL_GL_LINE_TOKEN                   = 0x0702,
+        LOCAL_GL_LINE_RESET_TOKEN             = 0x0707,
+        LOCAL_GL_POLYGON_TOKEN                = 0x0703,
+        LOCAL_GL_BITMAP_TOKEN                 = 0x0704,
+        LOCAL_GL_DRAW_PIXEL_TOKEN             = 0x0705,
+        LOCAL_GL_COPY_PIXEL_TOKEN             = 0x0706,
+        LOCAL_GL_PASS_THROUGH_TOKEN           = 0x0700,
+        LOCAL_GL_FEEDBACK_BUFFER_POINTER      = 0x0DF0,
+        LOCAL_GL_FEEDBACK_BUFFER_SIZE         = 0x0DF1,
+        LOCAL_GL_FEEDBACK_BUFFER_TYPE         = 0x0DF2,
+
+        /* Selection */
+        LOCAL_GL_SELECTION_BUFFER_POINTER     = 0x0DF3,
+        LOCAL_GL_SELECTION_BUFFER_SIZE        = 0x0DF4,
+
+        /* Fog */
+        LOCAL_GL_FOG                          = 0x0B60,
+        LOCAL_GL_FOG_MODE                     = 0x0B65,
+        LOCAL_GL_FOG_DENSITY                  = 0x0B62,
+        LOCAL_GL_FOG_COLOR                    = 0x0B66,
+        LOCAL_GL_FOG_INDEX                    = 0x0B61,
+        LOCAL_GL_FOG_START                    = 0x0B63,
+        LOCAL_GL_FOG_END                      = 0x0B64,
+        LOCAL_GL_LINEAR                       = 0x2601,
+        LOCAL_GL_EXP                          = 0x0800,
+        LOCAL_GL_EXP2                         = 0x0801,
+
+        /* Logic Ops */
+        LOCAL_GL_LOGIC_OP                     = 0x0BF1,
+        LOCAL_GL_INDEX_LOGIC_OP               = 0x0BF1,
+        LOCAL_GL_COLOR_LOGIC_OP               = 0x0BF2,
+        LOCAL_GL_LOGIC_OP_MODE                = 0x0BF0,
+        LOCAL_GL_CLEAR                        = 0x1500,
+        LOCAL_GL_SET                          = 0x150F,
+        LOCAL_GL_COPY                         = 0x1503,
+        LOCAL_GL_COPY_INVERTED                = 0x150C,
+        LOCAL_GL_NOOP                         = 0x1505,
+        LOCAL_GL_INVERT                       = 0x150A,
+        LOCAL_GL_AND                          = 0x1501,
+        LOCAL_GL_NAND                         = 0x150E,
+        LOCAL_GL_OR                           = 0x1507,
+        LOCAL_GL_NOR                          = 0x1508,
+        LOCAL_GL_XOR                          = 0x1506,
+        LOCAL_GL_EQUIV                        = 0x1509,
+        LOCAL_GL_AND_REVERSE                  = 0x1502,
+        LOCAL_GL_AND_INVERTED                 = 0x1504,
+        LOCAL_GL_OR_REVERSE                   = 0x150B,
+        LOCAL_GL_OR_INVERTED                  = 0x150D,
+
+        /* Stencil */
+        LOCAL_GL_STENCIL_TEST                 = 0x0B90,
+        LOCAL_GL_STENCIL_WRITEMASK            = 0x0B98,
+        LOCAL_GL_STENCIL_BITS                 = 0x0D57,
+        LOCAL_GL_STENCIL_FUNC                 = 0x0B92,
+        LOCAL_GL_STENCIL_VALUE_MASK           = 0x0B93,
+        LOCAL_GL_STENCIL_REF                  = 0x0B97,
+        LOCAL_GL_STENCIL_FAIL                 = 0x0B94,
+        LOCAL_GL_STENCIL_PASS_DEPTH_PASS      = 0x0B96,
+        LOCAL_GL_STENCIL_PASS_DEPTH_FAIL      = 0x0B95,
+        LOCAL_GL_STENCIL_CLEAR_VALUE          = 0x0B91,
+        LOCAL_GL_STENCIL_INDEX                = 0x1901,
+        LOCAL_GL_KEEP                         = 0x1E00,
+        LOCAL_GL_REPLACE                      = 0x1E01,
+        LOCAL_GL_INCR                         = 0x1E02,
+        LOCAL_GL_DECR                         = 0x1E03,
+
+        /* Buffers, Pixel Drawing/Reading */
+        LOCAL_GL_NONE                         = 0,
+        LOCAL_GL_LEFT                         = 0x0406,
+        LOCAL_GL_RIGHT                        = 0x0407,
+        /*LOCAL_GL_FRONT                      = 0x0404, */
+        /*LOCAL_GL_BACK                       = 0x0405, */
+        /*LOCAL_GL_FRONT_AND_BACK             = 0x0408, */
+        LOCAL_GL_FRONT_LEFT                   = 0x0400,
+        LOCAL_GL_FRONT_RIGHT                  = 0x0401,
+        LOCAL_GL_BACK_LEFT                    = 0x0402,
+        LOCAL_GL_BACK_RIGHT                   = 0x0403,
+        LOCAL_GL_AUX0                         = 0x0409,
+        LOCAL_GL_AUX1                         = 0x040A,
+        LOCAL_GL_AUX2                         = 0x040B,
+        LOCAL_GL_AUX3                         = 0x040C,
+        LOCAL_GL_COLOR_INDEX                  = 0x1900,
+        LOCAL_GL_RED                          = 0x1903,
+        LOCAL_GL_GREEN                        = 0x1904,
+        LOCAL_GL_BLUE                         = 0x1905,
+        LOCAL_GL_ALPHA                        = 0x1906,
+        LOCAL_GL_LUMINANCE                    = 0x1909,
+        LOCAL_GL_LUMINANCE_ALPHA              = 0x190A,
+        LOCAL_GL_ALPHA_BITS                   = 0x0D55,
+        LOCAL_GL_RED_BITS                     = 0x0D52,
+        LOCAL_GL_GREEN_BITS                   = 0x0D53,
+        LOCAL_GL_BLUE_BITS                    = 0x0D54,
+        LOCAL_GL_INDEX_BITS                   = 0x0D51,
+        LOCAL_GL_SUBPIXEL_BITS                = 0x0D50,
+        LOCAL_GL_AUX_BUFFERS                  = 0x0C00,
+        LOCAL_GL_READ_BUFFER                  = 0x0C02,
+        LOCAL_GL_DRAW_BUFFER                  = 0x0C01,
+        LOCAL_GL_DOUBLEBUFFER                 = 0x0C32,
+        LOCAL_GL_STEREO                       = 0x0C33,
+        LOCAL_GL_BITMAP                       = 0x1A00,
+        LOCAL_GL_COLOR                        = 0x1800,
+        LOCAL_GL_DEPTH                        = 0x1801,
+        LOCAL_GL_STENCIL                      = 0x1802,
+        LOCAL_GL_DITHER                       = 0x0BD0,
+        LOCAL_GL_RGB                          = 0x1907,
+        LOCAL_GL_RGBA                         = 0x1908,
+
+        /* Implementation limits */
+        LOCAL_GL_MAX_LIST_NESTING             = 0x0B31,
+        LOCAL_GL_MAX_ATTRIB_STACK_DEPTH       = 0x0D35,
+        LOCAL_GL_MAX_MODELVIEW_STACK_DEPTH    = 0x0D36,
+        LOCAL_GL_MAX_NAME_STACK_DEPTH         = 0x0D37,
+        LOCAL_GL_MAX_PROJECTION_STACK_DEPTH   = 0x0D38,
+        LOCAL_GL_MAX_TEXTURE_STACK_DEPTH      = 0x0D39,
+        LOCAL_GL_MAX_EVAL_ORDER               = 0x0D30,
+        LOCAL_GL_MAX_LIGHTS                   = 0x0D31,
+        LOCAL_GL_MAX_CLIP_PLANES              = 0x0D32,
+        LOCAL_GL_MAX_TEXTURE_SIZE             = 0x0D33,
+        LOCAL_GL_MAX_PIXEL_MAP_TABLE          = 0x0D34,
+        LOCAL_GL_MAX_VIEWPORT_DIMS            = 0x0D3A,
+        LOCAL_GL_MAX_CLIENT_ATTRIB_STACK_DEPTH= 0x0D3B,
+
+        /* Gets */
+        LOCAL_GL_ATTRIB_STACK_DEPTH           = 0x0BB0,
+        LOCAL_GL_CLIENT_ATTRIB_STACK_DEPTH    = 0x0BB1,
+        LOCAL_GL_COLOR_CLEAR_VALUE            = 0x0C22,
+        LOCAL_GL_COLOR_WRITEMASK              = 0x0C23,
+        LOCAL_GL_CURRENT_INDEX                = 0x0B01,
+        LOCAL_GL_CURRENT_COLOR                = 0x0B00,
+        LOCAL_GL_CURRENT_NORMAL               = 0x0B02,
+        LOCAL_GL_CURRENT_RASTER_COLOR         = 0x0B04,
+        LOCAL_GL_CURRENT_RASTER_DISTANCE      = 0x0B09,
+        LOCAL_GL_CURRENT_RASTER_INDEX         = 0x0B05,
+        LOCAL_GL_CURRENT_RASTER_POSITION      = 0x0B07,
+        LOCAL_GL_CURRENT_RASTER_TEXTURE_COORDS = 0x0B06,
+        LOCAL_GL_CURRENT_RASTER_POSITION_VALID = 0x0B08,
+        LOCAL_GL_CURRENT_TEXTURE_COORDS       = 0x0B03,
+        LOCAL_GL_INDEX_CLEAR_VALUE            = 0x0C20,
+        LOCAL_GL_INDEX_MODE                   = 0x0C30,
+        LOCAL_GL_INDEX_WRITEMASK              = 0x0C21,
+        LOCAL_GL_MODELVIEW_MATRIX             = 0x0BA6,
+        LOCAL_GL_MODELVIEW_STACK_DEPTH        = 0x0BA3,
+        LOCAL_GL_NAME_STACK_DEPTH             = 0x0D70,
+        LOCAL_GL_PROJECTION_MATRIX            = 0x0BA7,
+        LOCAL_GL_PROJECTION_STACK_DEPTH       = 0x0BA4,
+        LOCAL_GL_RENDER_MODE                  = 0x0C40,
+        LOCAL_GL_RGBA_MODE                    = 0x0C31,
+        LOCAL_GL_TEXTURE_MATRIX               = 0x0BA8,
+        LOCAL_GL_TEXTURE_STACK_DEPTH          = 0x0BA5,
+        LOCAL_GL_VIEWPORT                     = 0x0BA2,
+
+
+        /* Evaluators */
+        LOCAL_GL_AUTO_NORMAL                  = 0x0D80,
+        LOCAL_GL_MAP1_COLOR_4                 = 0x0D90,
+        LOCAL_GL_MAP1_GRID_DOMAIN             = 0x0DD0,
+        LOCAL_GL_MAP1_GRID_SEGMENTS           = 0x0DD1,
+        LOCAL_GL_MAP1_INDEX                   = 0x0D91,
+        LOCAL_GL_MAP1_NORMAL                  = 0x0D92,
+        LOCAL_GL_MAP1_TEXTURE_COORD_1         = 0x0D93,
+        LOCAL_GL_MAP1_TEXTURE_COORD_2         = 0x0D94,
+        LOCAL_GL_MAP1_TEXTURE_COORD_3         = 0x0D95,
+        LOCAL_GL_MAP1_TEXTURE_COORD_4         = 0x0D96,
+        LOCAL_GL_MAP1_VERTEX_3                = 0x0D97,
+        LOCAL_GL_MAP1_VERTEX_4                = 0x0D98,
+        LOCAL_GL_MAP2_COLOR_4                 = 0x0DB0,
+        LOCAL_GL_MAP2_GRID_DOMAIN             = 0x0DD2,
+        LOCAL_GL_MAP2_GRID_SEGMENTS           = 0x0DD3,
+        LOCAL_GL_MAP2_INDEX                   = 0x0DB1,
+        LOCAL_GL_MAP2_NORMAL                  = 0x0DB2,
+        LOCAL_GL_MAP2_TEXTURE_COORD_1         = 0x0DB3,
+        LOCAL_GL_MAP2_TEXTURE_COORD_2         = 0x0DB4,
+        LOCAL_GL_MAP2_TEXTURE_COORD_3         = 0x0DB5,
+        LOCAL_GL_MAP2_TEXTURE_COORD_4         = 0x0DB6,
+        LOCAL_GL_MAP2_VERTEX_3                = 0x0DB7,
+        LOCAL_GL_MAP2_VERTEX_4                = 0x0DB8,
+        LOCAL_GL_COEFF                        = 0x0A00,
+        LOCAL_GL_DOMAIN                       = 0x0A02,
+        LOCAL_GL_ORDER                        = 0x0A01,
+
+        /* Hints */
+        LOCAL_GL_FOG_HINT                     = 0x0C54,
+        LOCAL_GL_LINE_SMOOTH_HINT             = 0x0C52,
+        LOCAL_GL_PERSPECTIVE_CORRECTION_HINT  = 0x0C50,
+        LOCAL_GL_POINT_SMOOTH_HINT            = 0x0C51,
+        LOCAL_GL_POLYGON_SMOOTH_HINT          = 0x0C53,
+        LOCAL_GL_DONT_CARE                    = 0x1100,
+        LOCAL_GL_FASTEST                      = 0x1101,
+        LOCAL_GL_NICEST                       = 0x1102,
+
+        /* Scissor box */
+        LOCAL_GL_SCISSOR_TEST                 = 0x0C11,
+        LOCAL_GL_SCISSOR_BOX                  = 0x0C10,
+
+        /* Pixel Mode / Transfer */
+        LOCAL_GL_MAP_COLOR                    = 0x0D10,
+        LOCAL_GL_MAP_STENCIL                  = 0x0D11,
+        LOCAL_GL_INDEX_SHIFT                  = 0x0D12,
+        LOCAL_GL_INDEX_OFFSET                 = 0x0D13,
+        LOCAL_GL_RED_SCALE                    = 0x0D14,
+        LOCAL_GL_RED_BIAS                     = 0x0D15,
+        LOCAL_GL_GREEN_SCALE                  = 0x0D18,
+        LOCAL_GL_GREEN_BIAS                   = 0x0D19,
+        LOCAL_GL_BLUE_SCALE                   = 0x0D1A,
+        LOCAL_GL_BLUE_BIAS                    = 0x0D1B,
+        LOCAL_GL_ALPHA_SCALE                  = 0x0D1C,
+        LOCAL_GL_ALPHA_BIAS                   = 0x0D1D,
+        LOCAL_GL_DEPTH_SCALE                  = 0x0D1E,
+        LOCAL_GL_DEPTH_BIAS                   = 0x0D1F,
+        LOCAL_GL_PIXEL_MAP_S_TO_S_SIZE        = 0x0CB1,
+        LOCAL_GL_PIXEL_MAP_I_TO_I_SIZE        = 0x0CB0,
+        LOCAL_GL_PIXEL_MAP_I_TO_R_SIZE        = 0x0CB2,
+        LOCAL_GL_PIXEL_MAP_I_TO_G_SIZE        = 0x0CB3,
+        LOCAL_GL_PIXEL_MAP_I_TO_B_SIZE        = 0x0CB4,
+        LOCAL_GL_PIXEL_MAP_I_TO_A_SIZE        = 0x0CB5,
+        LOCAL_GL_PIXEL_MAP_R_TO_R_SIZE        = 0x0CB6,
+        LOCAL_GL_PIXEL_MAP_G_TO_G_SIZE        = 0x0CB7,
+        LOCAL_GL_PIXEL_MAP_B_TO_B_SIZE        = 0x0CB8,
+        LOCAL_GL_PIXEL_MAP_A_TO_A_SIZE        = 0x0CB9,
+        LOCAL_GL_PIXEL_MAP_S_TO_S             = 0x0C71,
+        LOCAL_GL_PIXEL_MAP_I_TO_I             = 0x0C70,
+        LOCAL_GL_PIXEL_MAP_I_TO_R             = 0x0C72,
+        LOCAL_GL_PIXEL_MAP_I_TO_G             = 0x0C73,
+        LOCAL_GL_PIXEL_MAP_I_TO_B             = 0x0C74,
+        LOCAL_GL_PIXEL_MAP_I_TO_A             = 0x0C75,
+        LOCAL_GL_PIXEL_MAP_R_TO_R             = 0x0C76,
+        LOCAL_GL_PIXEL_MAP_G_TO_G             = 0x0C77,
+        LOCAL_GL_PIXEL_MAP_B_TO_B             = 0x0C78,
+        LOCAL_GL_PIXEL_MAP_A_TO_A             = 0x0C79,
+        LOCAL_GL_PACK_ALIGNMENT               = 0x0D05,
+        LOCAL_GL_PACK_LSB_FIRST               = 0x0D01,
+        LOCAL_GL_PACK_ROW_LENGTH              = 0x0D02,
+        LOCAL_GL_PACK_SKIP_PIXELS             = 0x0D04,
+        LOCAL_GL_PACK_SKIP_ROWS               = 0x0D03,
+        LOCAL_GL_PACK_SWAP_BYTES              = 0x0D00,
+        LOCAL_GL_UNPACK_ALIGNMENT             = 0x0CF5,
+        LOCAL_GL_UNPACK_LSB_FIRST             = 0x0CF1,
+        LOCAL_GL_UNPACK_ROW_LENGTH            = 0x0CF2,
+        LOCAL_GL_UNPACK_SKIP_PIXELS           = 0x0CF4,
+        LOCAL_GL_UNPACK_SKIP_ROWS             = 0x0CF3,
+        LOCAL_GL_UNPACK_SWAP_BYTES            = 0x0CF0,
+        LOCAL_GL_ZOOM_X                       = 0x0D16,
+        LOCAL_GL_ZOOM_Y                       = 0x0D17,
+
+        /* Texture mapping */
+        LOCAL_GL_TEXTURE_ENV                  = 0x2300,
+        LOCAL_GL_TEXTURE_ENV_MODE             = 0x2200,
+        LOCAL_GL_TEXTURE_1D                   = 0x0DE0,
+        LOCAL_GL_TEXTURE_2D                   = 0x0DE1,
+        LOCAL_GL_TEXTURE_WRAP_S               = 0x2802,
+        LOCAL_GL_TEXTURE_WRAP_T               = 0x2803,
+        LOCAL_GL_TEXTURE_MAG_FILTER           = 0x2800,
+        LOCAL_GL_TEXTURE_MIN_FILTER           = 0x2801,
+        LOCAL_GL_TEXTURE_ENV_COLOR            = 0x2201,
+        LOCAL_GL_TEXTURE_GEN_S                = 0x0C60,
+        LOCAL_GL_TEXTURE_GEN_T                = 0x0C61,
+        LOCAL_GL_TEXTURE_GEN_MODE             = 0x2500,
+        LOCAL_GL_TEXTURE_BORDER_COLOR         = 0x1004,
+        LOCAL_GL_TEXTURE_WIDTH                = 0x1000,
+        LOCAL_GL_TEXTURE_HEIGHT               = 0x1001,
+        LOCAL_GL_TEXTURE_BORDER               = 0x1005,
+        LOCAL_GL_TEXTURE_COMPONENTS           = 0x1003,
+        LOCAL_GL_TEXTURE_RED_SIZE             = 0x805C,
+        LOCAL_GL_TEXTURE_GREEN_SIZE           = 0x805D,
+        LOCAL_GL_TEXTURE_BLUE_SIZE            = 0x805E,
+        LOCAL_GL_TEXTURE_ALPHA_SIZE           = 0x805F,
+        LOCAL_GL_TEXTURE_LUMINANCE_SIZE       = 0x8060,
+        LOCAL_GL_TEXTURE_INTENSITY_SIZE       = 0x8061,
+        LOCAL_GL_NEAREST_MIPMAP_NEAREST       = 0x2700,
+        LOCAL_GL_NEAREST_MIPMAP_LINEAR        = 0x2702,
+        LOCAL_GL_LINEAR_MIPMAP_NEAREST        = 0x2701,
+        LOCAL_GL_LINEAR_MIPMAP_LINEAR         = 0x2703,
+        LOCAL_GL_OBJECT_LINEAR                = 0x2401,
+        LOCAL_GL_OBJECT_PLANE                 = 0x2501,
+        LOCAL_GL_EYE_LINEAR                   = 0x2400,
+        LOCAL_GL_EYE_PLANE                    = 0x2502,
+        LOCAL_GL_SPHERE_MAP                   = 0x2402,
+        LOCAL_GL_DECAL                        = 0x2101,
+        LOCAL_GL_MODULATE                     = 0x2100,
+        LOCAL_GL_NEAREST                      = 0x2600,
+        LOCAL_GL_REPEAT                       = 0x2901,
+        LOCAL_GL_CLAMP                        = 0x2900,
+        LOCAL_GL_S                            = 0x2000,
+        LOCAL_GL_T                            = 0x2001,
+        LOCAL_GL_R                            = 0x2002,
+        LOCAL_GL_Q                            = 0x2003,
+        LOCAL_GL_TEXTURE_GEN_R                = 0x0C62,
+        LOCAL_GL_TEXTURE_GEN_Q                = 0x0C63,
+
+        /* GL 1.1 texturing */
+        LOCAL_GL_PROXY_TEXTURE_1D             = 0x8063,
+        LOCAL_GL_PROXY_TEXTURE_2D             = 0x8064,
+        LOCAL_GL_TEXTURE_PRIORITY             = 0x8066,
+        LOCAL_GL_TEXTURE_RESIDENT             = 0x8067,
+        LOCAL_GL_TEXTURE_BINDING_1D           = 0x8068,
+        LOCAL_GL_TEXTURE_BINDING_2D           = 0x8069,
+        LOCAL_GL_TEXTURE_INTERNAL_FORMAT      = 0x1003,
+
+        /* GL 1.2 texturing */
+        LOCAL_GL_PACK_SKIP_IMAGES             = 0x806B,
+        LOCAL_GL_PACK_IMAGE_HEIGHT            = 0x806C,
+        LOCAL_GL_UNPACK_SKIP_IMAGES           = 0x806D,
+        LOCAL_GL_UNPACK_IMAGE_HEIGHT          = 0x806E,
+        LOCAL_GL_TEXTURE_3D                   = 0x806F,
+        LOCAL_GL_PROXY_TEXTURE_3D             = 0x8070,
+        LOCAL_GL_TEXTURE_DEPTH                = 0x8071,
+        LOCAL_GL_TEXTURE_WRAP_R               = 0x8072,
+        LOCAL_GL_MAX_3D_TEXTURE_SIZE          = 0x8073,
+        LOCAL_GL_TEXTURE_BINDING_3D           = 0x806A,
+
+        /* Internal texture formats (GL 1.1) */
+        LOCAL_GL_ALPHA4                       = 0x803B,
+        LOCAL_GL_ALPHA8                       = 0x803C,
+        LOCAL_GL_ALPHA12                      = 0x803D,
+        LOCAL_GL_ALPHA16                      = 0x803E,
+        LOCAL_GL_LUMINANCE4                   = 0x803F,
+        LOCAL_GL_LUMINANCE8                   = 0x8040,
+        LOCAL_GL_LUMINANCE12                  = 0x8041,
+        LOCAL_GL_LUMINANCE16                  = 0x8042,
+        LOCAL_GL_LUMINANCE4_ALPHA4            = 0x8043,
+        LOCAL_GL_LUMINANCE6_ALPHA2            = 0x8044,
+        LOCAL_GL_LUMINANCE8_ALPHA8            = 0x8045,
+        LOCAL_GL_LUMINANCE12_ALPHA4           = 0x8046,
+        LOCAL_GL_LUMINANCE12_ALPHA12          = 0x8047,
+        LOCAL_GL_LUMINANCE16_ALPHA16          = 0x8048,
+        LOCAL_GL_INTENSITY                    = 0x8049,
+        LOCAL_GL_INTENSITY4                   = 0x804A,
+        LOCAL_GL_INTENSITY8                   = 0x804B,
+        LOCAL_GL_INTENSITY12                  = 0x804C,
+        LOCAL_GL_INTENSITY16                  = 0x804D,
+        LOCAL_GL_R3_G3_B2                     = 0x2A10,
+        LOCAL_GL_RGB4                         = 0x804F,
+        LOCAL_GL_RGB5                         = 0x8050,
+        LOCAL_GL_RGB8                         = 0x8051,
+        LOCAL_GL_RGB10                        = 0x8052,
+        LOCAL_GL_RGB12                        = 0x8053,
+        LOCAL_GL_RGB16                        = 0x8054,
+        LOCAL_GL_RGBA2                        = 0x8055,
+        LOCAL_GL_RGBA4                        = 0x8056,
+        LOCAL_GL_RGB5_A1                      = 0x8057,
+        LOCAL_GL_RGBA8                        = 0x8058,
+        LOCAL_GL_RGB10_A2                     = 0x8059,
+        LOCAL_GL_RGBA12                       = 0x805A,
+        LOCAL_GL_RGBA16                       = 0x805B,
+
+        /* Utility */
+        LOCAL_GL_VENDOR                       = 0x1F00,
+        LOCAL_GL_RENDERER                     = 0x1F01,
+        LOCAL_GL_VERSION                      = 0x1F02,
+        LOCAL_GL_EXTENSIONS                   = 0x1F03,
+
+        /* Errors */
+        LOCAL_GL_INVALID_VALUE                = 0x0501,
+        LOCAL_GL_INVALID_ENUM                 = 0x0500,
+        LOCAL_GL_INVALID_OPERATION            = 0x0502,
+        LOCAL_GL_STACK_OVERFLOW               = 0x0503,
+        LOCAL_GL_STACK_UNDERFLOW              = 0x0504,
+        LOCAL_GL_OUT_OF_MEMORY                = 0x0505,
+
+        /*
+         * Extensions
+         */
+
+        /* LOCAL_GL_EXT_blend_minmax and LOCAL_GL_EXT_blend_color */
+        LOCAL_GL_CONSTANT_COLOR_EXT                   = 0x8001,
+        LOCAL_GL_ONE_MINUS_CONSTANT_COLOR_EXT         = 0x8002,
+        LOCAL_GL_CONSTANT_ALPHA_EXT                   = 0x8003,
+        LOCAL_GL_ONE_MINUS_CONSTANT_ALPHA_EXT         = 0x8004,
+        LOCAL_GL_BLEND_EQUATION_EXT                   = 0x8009,
+        LOCAL_GL_MIN_EXT                              = 0x8007,
+        LOCAL_GL_MAX_EXT                              = 0x8008,
+        LOCAL_GL_FUNC_ADD_EXT                         = 0x8006,
+        LOCAL_GL_FUNC_SUBTRACT_EXT                    = 0x800A,
+        LOCAL_GL_FUNC_REVERSE_SUBTRACT_EXT            = 0x800B,
+        LOCAL_GL_BLEND_COLOR_EXT                      = 0x8005,
+
+        /* LOCAL_GL_EXT_polygon_offset */
+        LOCAL_GL_POLYGON_OFFSET_EXT                   = 0x8037,
+        LOCAL_GL_POLYGON_OFFSET_FACTOR_EXT            = 0x8038,
+        LOCAL_GL_POLYGON_OFFSET_BIAS_EXT              = 0x8039,
+
+        /* LOCAL_GL_EXT_vertex_array */
+        LOCAL_GL_VERTEX_ARRAY_EXT                     = 0x8074,
+        LOCAL_GL_NORMAL_ARRAY_EXT                     = 0x8075,
+        LOCAL_GL_COLOR_ARRAY_EXT                      = 0x8076,
+        LOCAL_GL_INDEX_ARRAY_EXT                      = 0x8077,
+        LOCAL_GL_TEXTURE_COORD_ARRAY_EXT              = 0x8078,
+        LOCAL_GL_EDGE_FLAG_ARRAY_EXT                  = 0x8079,
+        LOCAL_GL_VERTEX_ARRAY_SIZE_EXT                = 0x807A,
+        LOCAL_GL_VERTEX_ARRAY_TYPE_EXT                = 0x807B,
+        LOCAL_GL_VERTEX_ARRAY_STRIDE_EXT              = 0x807C,
+        LOCAL_GL_VERTEX_ARRAY_COUNT_EXT               = 0x807D,
+        LOCAL_GL_NORMAL_ARRAY_TYPE_EXT                = 0x807E,
+        LOCAL_GL_NORMAL_ARRAY_STRIDE_EXT              = 0x807F,
+        LOCAL_GL_NORMAL_ARRAY_COUNT_EXT               = 0x8080,
+        LOCAL_GL_COLOR_ARRAY_SIZE_EXT                 = 0x8081,
+        LOCAL_GL_COLOR_ARRAY_TYPE_EXT                 = 0x8082,
+        LOCAL_GL_COLOR_ARRAY_STRIDE_EXT               = 0x8083,
+        LOCAL_GL_COLOR_ARRAY_COUNT_EXT                = 0x8084,
+        LOCAL_GL_INDEX_ARRAY_TYPE_EXT                 = 0x8085,
+        LOCAL_GL_INDEX_ARRAY_STRIDE_EXT               = 0x8086,
+        LOCAL_GL_INDEX_ARRAY_COUNT_EXT                = 0x8087,
+        LOCAL_GL_TEXTURE_COORD_ARRAY_SIZE_EXT         = 0x8088,
+        LOCAL_GL_TEXTURE_COORD_ARRAY_TYPE_EXT         = 0x8089,
+        LOCAL_GL_TEXTURE_COORD_ARRAY_STRIDE_EXT       = 0x808A,
+        LOCAL_GL_TEXTURE_COORD_ARRAY_COUNT_EXT        = 0x808B,
+        LOCAL_GL_EDGE_FLAG_ARRAY_STRIDE_EXT           = 0x808C,
+        LOCAL_GL_EDGE_FLAG_ARRAY_COUNT_EXT            = 0x808D,
+        LOCAL_GL_VERTEX_ARRAY_POINTER_EXT             = 0x808E,
+        LOCAL_GL_NORMAL_ARRAY_POINTER_EXT             = 0x808F,
+        LOCAL_GL_COLOR_ARRAY_POINTER_EXT              = 0x8090,
+        LOCAL_GL_INDEX_ARRAY_POINTER_EXT              = 0x8091,
+        LOCAL_GL_TEXTURE_COORD_ARRAY_POINTER_EXT      = 0x8092,
+        LOCAL_GL_EDGE_FLAG_ARRAY_POINTER_EXT          = 0x8093,
+
+        /* LOCAL_GL_EXT_texture_object */
+        LOCAL_GL_TEXTURE_PRIORITY_EXT                 = 0x8066,
+        LOCAL_GL_TEXTURE_RESIDENT_EXT                 = 0x8067,
+        LOCAL_GL_TEXTURE_1D_BINDING_EXT               = 0x8068,
+        LOCAL_GL_TEXTURE_2D_BINDING_EXT               = 0x8069,
+
+        /* LOCAL_GL_EXT_texture3D */
+        LOCAL_GL_PACK_SKIP_IMAGES_EXT                 = 0x806B,
+        LOCAL_GL_PACK_IMAGE_HEIGHT_EXT                = 0x806C,
+        LOCAL_GL_UNPACK_SKIP_IMAGES_EXT               = 0x806D,
+        LOCAL_GL_UNPACK_IMAGE_HEIGHT_EXT              = 0x806E,
+        LOCAL_GL_TEXTURE_3D_EXT                       = 0x806F,
+        LOCAL_GL_PROXY_TEXTURE_3D_EXT                 = 0x8070,
+        LOCAL_GL_TEXTURE_DEPTH_EXT                    = 0x8071,
+        LOCAL_GL_TEXTURE_WRAP_R_EXT                   = 0x8072,
+        LOCAL_GL_MAX_3D_TEXTURE_SIZE_EXT              = 0x8073,
+        LOCAL_GL_TEXTURE_3D_BINDING_EXT               = 0x806A,
+
+        /* LOCAL_GL_EXT_paletted_texture */
+        LOCAL_GL_TABLE_TOO_LARGE_EXT                  = 0x8031,
+        LOCAL_GL_COLOR_TABLE_FORMAT_EXT               = 0x80D8,
+        LOCAL_GL_COLOR_TABLE_WIDTH_EXT                = 0x80D9,
+        LOCAL_GL_COLOR_TABLE_RED_SIZE_EXT             = 0x80DA,
+        LOCAL_GL_COLOR_TABLE_GREEN_SIZE_EXT           = 0x80DB,
+        LOCAL_GL_COLOR_TABLE_BLUE_SIZE_EXT            = 0x80DC,
+        LOCAL_GL_COLOR_TABLE_ALPHA_SIZE_EXT           = 0x80DD,
+        LOCAL_GL_COLOR_TABLE_LUMINANCE_SIZE_EXT       = 0x80DE,
+        LOCAL_GL_COLOR_TABLE_INTENSITY_SIZE_EXT       = 0x80DF,
+        LOCAL_GL_TEXTURE_INDEX_SIZE_EXT               = 0x80ED,
+        LOCAL_GL_COLOR_INDEX1_EXT                     = 0x80E2,
+        LOCAL_GL_COLOR_INDEX2_EXT                     = 0x80E3,
+        LOCAL_GL_COLOR_INDEX4_EXT                     = 0x80E4,
+        LOCAL_GL_COLOR_INDEX8_EXT                     = 0x80E5,
+        LOCAL_GL_COLOR_INDEX12_EXT                    = 0x80E6,
+        LOCAL_GL_COLOR_INDEX16_EXT                    = 0x80E7,
+
+        /* LOCAL_GL_EXT_shared_texture_palette */
+        LOCAL_GL_SHARED_TEXTURE_PALETTE_EXT           = 0x81FB,
+
+        /* LOCAL_GL_EXT_point_parameters */
+        LOCAL_GL_POINT_SIZE_MIN_EXT                   = 0x8126,
+        LOCAL_GL_POINT_SIZE_MAX_EXT                   = 0x8127,
+        LOCAL_GL_POINT_FADE_THRESHOLD_SIZE_EXT        = 0x8128,
+        LOCAL_GL_DISTANCE_ATTENUATION_EXT             = 0x8129,
+
+        /* LOCAL_GL_EXT_rescale_normal */
+        LOCAL_GL_RESCALE_NORMAL_EXT                   = 0x803A,
+
+        /* LOCAL_GL_EXT_abgr */
+        LOCAL_GL_ABGR_EXT                             = 0x8000,
+
+        /* LOCAL_GL_SGIS_multitexture */
+        LOCAL_GL_SELECTED_TEXTURE_SGIS                = 0x835C,
+        LOCAL_GL_SELECTED_TEXTURE_COORD_SET_SGIS      = 0x835D,
+        LOCAL_GL_MAX_TEXTURES_SGIS                    = 0x835E,
+        LOCAL_GL_TEXTURE0_SGIS                        = 0x835F,
+        LOCAL_GL_TEXTURE1_SGIS                        = 0x8360,
+        LOCAL_GL_TEXTURE2_SGIS                        = 0x8361,
+        LOCAL_GL_TEXTURE3_SGIS                        = 0x8362,
+        LOCAL_GL_TEXTURE_COORD_SET_SOURCE_SGIS        = 0x8363,
+
+        /* LOCAL_GL_EXT_multitexture */
+        LOCAL_GL_SELECTED_TEXTURE_EXT                 = 0x83C0,
+        LOCAL_GL_SELECTED_TEXTURE_COORD_SET_EXT       = 0x83C1,
+        LOCAL_GL_SELECTED_TEXTURE_TRANSFORM_EXT       = 0x83C2,
+        LOCAL_GL_MAX_TEXTURES_EXT                     = 0x83C3,
+        LOCAL_GL_MAX_TEXTURE_COORD_SETS_EXT           = 0x83C4,
+        LOCAL_GL_TEXTURE_ENV_COORD_SET_EXT            = 0x83C5,
+        LOCAL_GL_TEXTURE0_EXT                         = 0x83C6,
+        LOCAL_GL_TEXTURE1_EXT                         = 0x83C7,
+        LOCAL_GL_TEXTURE2_EXT                         = 0x83C8,
+        LOCAL_GL_TEXTURE3_EXT                         = 0x83C9,
+
+        /* LOCAL_GL_SGIS_texture_edge_clamp */
+        LOCAL_GL_CLAMP_TO_EDGE_SGIS                   = 0x812F,
+
+        /* OpenGL 1.2 */
+        LOCAL_GL_RESCALE_NORMAL                       = 0x803A,
+        LOCAL_GL_CLAMP_TO_EDGE                        = 0x812F,
+        LOCAL_GL_MAX_ELEMENTS_VERTICES                = 0xF0E8,
+        LOCAL_GL_MAX_ELEMENTS_INDICES                 = 0xF0E9,
+        LOCAL_GL_BGR                                  = 0x80E0,
+        LOCAL_GL_BGRA                                 = 0x80E1,
+        LOCAL_GL_UNSIGNED_BYTE_3_3_2                  = 0x8032,
+        LOCAL_GL_UNSIGNED_BYTE_2_3_3_REV              = 0x8362,
+        LOCAL_GL_UNSIGNED_SHORT_5_6_5                 = 0x8363,
+        LOCAL_GL_UNSIGNED_SHORT_5_6_5_REV             = 0x8364,
+        LOCAL_GL_UNSIGNED_SHORT_4_4_4_4               = 0x8033,
+        LOCAL_GL_UNSIGNED_SHORT_4_4_4_4_REV           = 0x8365,
+        LOCAL_GL_UNSIGNED_SHORT_5_5_5_1               = 0x8034,
+        LOCAL_GL_UNSIGNED_SHORT_1_5_5_5_REV           = 0x8366,
+        LOCAL_GL_UNSIGNED_INT_8_8_8_8                 = 0x8035,
+        LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV             = 0x8367,
+        LOCAL_GL_UNSIGNED_INT_10_10_10_2              = 0x8036,
+        LOCAL_GL_UNSIGNED_INT_2_10_10_10_REV          = 0x8368,
+        LOCAL_GL_LIGHT_MODEL_COLOR_CONTROL            = 0x81F8,
+        LOCAL_GL_SINGLE_COLOR                         = 0x81F9,
+        LOCAL_GL_SEPARATE_SPECULAR_COLOR              = 0x81FA,
+        LOCAL_GL_TEXTURE_MIN_LOD                      = 0x813A,
+        LOCAL_GL_TEXTURE_MAX_LOD                      = 0x813B,
+        LOCAL_GL_TEXTURE_BASE_LEVEL                   = 0x813C,
+        LOCAL_GL_TEXTURE_MAX_LEVEL                    = 0x813D
+};
+
+typedef struct { GLenum e; const char* name; } ENUM;
+#define EDEF(VAR) { (GLenum)(LOCAL_GL_##VAR), #VAR }
+
+static ENUM enums[] =
+  {
+  EDEF(BYTE),
+  EDEF(UNSIGNED_BYTE),
+  EDEF(SHORT),
+  EDEF(UNSIGNED_SHORT),
+  EDEF(INT),
+  EDEF(UNSIGNED_INT),
+  EDEF(FLOAT),
+  EDEF(DOUBLE),
+  EDEF(2_BYTES),
+  EDEF(3_BYTES),
+  EDEF(4_BYTES),
+/*
+  EDEF(LINES),
+  EDEF(POINTS),
+  EDEF(LINE_STRIP),
+  EDEF(LINE_LOOP),
+  EDEF(TRIANGLES),
+  EDEF(TRIANGLE_STRIP),
+  EDEF(TRIANGLE_FAN),
+  EDEF(QUADS),
+  EDEF(QUAD_STRIP),
+  EDEF(POLYGON),
+  EDEF(EDGE_FLAG),
+*/
+  EDEF(VERTEX_ARRAY),
+  EDEF(NORMAL_ARRAY),
+  EDEF(COLOR_ARRAY),
+  EDEF(INDEX_ARRAY),
+  EDEF(TEXTURE_COORD_ARRAY),
+  EDEF(EDGE_FLAG_ARRAY),
+  EDEF(VERTEX_ARRAY_SIZE),
+  EDEF(VERTEX_ARRAY_TYPE),
+  EDEF(VERTEX_ARRAY_STRIDE),
+  EDEF(NORMAL_ARRAY_TYPE),
+  EDEF(NORMAL_ARRAY_STRIDE),
+  EDEF(COLOR_ARRAY_SIZE),
+  EDEF(COLOR_ARRAY_TYPE),
+  EDEF(COLOR_ARRAY_STRIDE),
+  EDEF(INDEX_ARRAY_TYPE),
+  EDEF(INDEX_ARRAY_STRIDE),
+  EDEF(TEXTURE_COORD_ARRAY_SIZE),
+  EDEF(TEXTURE_COORD_ARRAY_TYPE),
+  EDEF(TEXTURE_COORD_ARRAY_STRIDE),
+  EDEF(EDGE_FLAG_ARRAY_STRIDE),
+  EDEF(VERTEX_ARRAY_POINTER),
+  EDEF(NORMAL_ARRAY_POINTER),
+  EDEF(COLOR_ARRAY_POINTER),
+  EDEF(INDEX_ARRAY_POINTER),
+  EDEF(TEXTURE_COORD_ARRAY_POINTER),
+  EDEF(EDGE_FLAG_ARRAY_POINTER),
+  EDEF(V2F),
+  EDEF(V3F),
+  EDEF(C4UB_V2F),
+  EDEF(C4UB_V3F),
+  EDEF(C3F_V3F),
+  EDEF(N3F_V3F),
+  EDEF(C4F_N3F_V3F),
+  EDEF(T2F_V3F),
+  EDEF(T4F_V4F),
+  EDEF(T2F_C4UB_V3F),
+  EDEF(T2F_C3F_V3F),
+  EDEF(T2F_N3F_V3F),
+  EDEF(T2F_C4F_N3F_V3F),
+  EDEF(T4F_C4F_N3F_V4F),
+  EDEF(MATRIX_MODE),
+  EDEF(MODELVIEW),
+  EDEF(PROJECTION),
+  EDEF(TEXTURE),
+  EDEF(POINT_SMOOTH),
+  EDEF(POINT_SIZE),
+  EDEF(POINT_SIZE_GRANULARITY),
+  EDEF(POINT_SIZE_RANGE),
+  EDEF(LINE_SMOOTH),
+  EDEF(LINE_STIPPLE),
+  EDEF(LINE_STIPPLE_PATTERN),
+  EDEF(LINE_STIPPLE_REPEAT),
+  EDEF(LINE_WIDTH),
+  EDEF(LINE_WIDTH_GRANULARITY),
+  EDEF(LINE_WIDTH_RANGE),
+  EDEF(POINT),
+  EDEF(LINE),
+  EDEF(FILL),
+  EDEF(CCW),
+  EDEF(CW),
+  EDEF(FRONT),
+  EDEF(BACK),
+  EDEF(CULL_FACE),
+  EDEF(CULL_FACE_MODE),
+  EDEF(POLYGON_SMOOTH),
+  EDEF(POLYGON_STIPPLE),
+  EDEF(FRONT_FACE),
+  EDEF(POLYGON_MODE),
+  EDEF(POLYGON_OFFSET_FACTOR),
+  EDEF(POLYGON_OFFSET_UNITS),
+  EDEF(POLYGON_OFFSET_POINT),
+  EDEF(POLYGON_OFFSET_LINE),
+  EDEF(POLYGON_OFFSET_FILL),
+  EDEF(COMPILE),
+  EDEF(COMPILE_AND_EXECUTE),
+  EDEF(LIST_BASE),
+  EDEF(LIST_INDEX),
+  EDEF(LIST_MODE),
+  EDEF(NEVER),
+  EDEF(LESS),
+  EDEF(GEQUAL),
+  EDEF(LEQUAL),
+  EDEF(GREATER),
+  EDEF(NOTEQUAL),
+  EDEF(EQUAL),
+  EDEF(ALWAYS),
+  EDEF(DEPTH_TEST),
+  EDEF(DEPTH_BITS),
+  EDEF(DEPTH_CLEAR_VALUE),
+  EDEF(DEPTH_FUNC),
+  EDEF(DEPTH_RANGE),
+  EDEF(DEPTH_WRITEMASK),
+  EDEF(DEPTH_COMPONENT),
+  EDEF(LIGHTING),
+  EDEF(LIGHT0),
+  EDEF(LIGHT1),
+  EDEF(LIGHT2),
+  EDEF(LIGHT3),
+  EDEF(LIGHT4),
+  EDEF(LIGHT5),
+  EDEF(LIGHT6),
+  EDEF(LIGHT7),
+  EDEF(SPOT_EXPONENT),
+  EDEF(SPOT_CUTOFF),
+  EDEF(CONSTANT_ATTENUATION),
+  EDEF(LINEAR_ATTENUATION),
+  EDEF(QUADRATIC_ATTENUATION),
+  EDEF(AMBIENT),
+  EDEF(DIFFUSE),
+  EDEF(SPECULAR),
+  EDEF(SHININESS),
+  EDEF(EMISSION),
+  EDEF(POSITION),
+  EDEF(SPOT_DIRECTION),
+  EDEF(AMBIENT_AND_DIFFUSE),
+  EDEF(COLOR_INDEXES),
+  EDEF(LIGHT_MODEL_TWO_SIDE),
+  EDEF(LIGHT_MODEL_LOCAL_VIEWER),
+  EDEF(LIGHT_MODEL_AMBIENT),
+  EDEF(FRONT_AND_BACK),
+  EDEF(SHADE_MODEL),
+  EDEF(FLAT),
+  EDEF(SMOOTH),
+  EDEF(COLOR_MATERIAL),
+  EDEF(COLOR_MATERIAL_FACE),
+  EDEF(COLOR_MATERIAL_PARAMETER),
+  EDEF(NORMALIZE),
+  EDEF(CLIP_PLANE0),
+  EDEF(CLIP_PLANE1),
+  EDEF(CLIP_PLANE2),
+  EDEF(CLIP_PLANE3),
+  EDEF(CLIP_PLANE4),
+  EDEF(CLIP_PLANE5),
+  EDEF(ACCUM_RED_BITS),
+  EDEF(ACCUM_GREEN_BITS),
+  EDEF(ACCUM_BLUE_BITS),
+  EDEF(ACCUM_ALPHA_BITS),
+  EDEF(ACCUM_CLEAR_VALUE),
+  EDEF(ACCUM),
+  EDEF(ADD),
+  EDEF(LOAD),
+  EDEF(MULT),
+  EDEF(RETURN),
+  EDEF(ALPHA_TEST),
+  EDEF(ALPHA_TEST_REF),
+  EDEF(ALPHA_TEST_FUNC),
+  EDEF(BLEND),
+  EDEF(BLEND_SRC),
+  EDEF(BLEND_DST),
+  EDEF(ZERO),
+  EDEF(ONE),
+  EDEF(SRC_COLOR),
+  EDEF(ONE_MINUS_SRC_COLOR),
+  EDEF(DST_COLOR),
+  EDEF(ONE_MINUS_DST_COLOR),
+  EDEF(SRC_ALPHA),
+  EDEF(ONE_MINUS_SRC_ALPHA),
+  EDEF(DST_ALPHA),
+  EDEF(ONE_MINUS_DST_ALPHA),
+  EDEF(SRC_ALPHA_SATURATE),
+  EDEF(CONSTANT_COLOR),
+  EDEF(ONE_MINUS_CONSTANT_COLOR),
+  EDEF(CONSTANT_ALPHA),
+  EDEF(ONE_MINUS_CONSTANT_ALPHA),
+  EDEF(FEEDBACK),
+  EDEF(RENDER),
+  EDEF(SELECT),
+  EDEF(2D),
+  EDEF(3D),
+  EDEF(3D_COLOR),
+  EDEF(3D_COLOR_TEXTURE),
+  EDEF(4D_COLOR_TEXTURE),
+  EDEF(POINT_TOKEN),
+  EDEF(LINE_TOKEN),
+  EDEF(LINE_RESET_TOKEN),
+  EDEF(POLYGON_TOKEN),
+  EDEF(BITMAP_TOKEN),
+  EDEF(DRAW_PIXEL_TOKEN),
+  EDEF(COPY_PIXEL_TOKEN),
+  EDEF(PASS_THROUGH_TOKEN),
+  EDEF(FEEDBACK_BUFFER_POINTER),
+  EDEF(FEEDBACK_BUFFER_SIZE),
+  EDEF(FEEDBACK_BUFFER_TYPE),
+  EDEF(SELECTION_BUFFER_POINTER),
+  EDEF(SELECTION_BUFFER_SIZE),
+  EDEF(FOG),
+  EDEF(FOG_MODE),
+  EDEF(FOG_DENSITY),
+  EDEF(FOG_COLOR),
+  EDEF(FOG_INDEX),
+  EDEF(FOG_START),
+  EDEF(FOG_END),
+  EDEF(LINEAR),
+  EDEF(EXP),
+  EDEF(EXP2),
+  EDEF(LOGIC_OP),
+  EDEF(INDEX_LOGIC_OP),
+  EDEF(COLOR_LOGIC_OP),
+  EDEF(LOGIC_OP_MODE),
+  EDEF(CLEAR),
+  EDEF(SET),
+  EDEF(COPY),
+  EDEF(COPY_INVERTED),
+  EDEF(NOOP),
+  EDEF(INVERT),
+  EDEF(AND),
+  EDEF(NAND),
+  EDEF(OR),
+  EDEF(NOR),
+  EDEF(XOR),
+  EDEF(EQUIV),
+  EDEF(AND_REVERSE),
+  EDEF(AND_INVERTED),
+  EDEF(OR_REVERSE),
+  EDEF(OR_INVERTED),
+  EDEF(STENCIL_TEST),
+  EDEF(STENCIL_WRITEMASK),
+  EDEF(STENCIL_BITS),
+  EDEF(STENCIL_FUNC),
+  EDEF(STENCIL_VALUE_MASK),
+  EDEF(STENCIL_REF),
+  EDEF(STENCIL_FAIL),
+  EDEF(STENCIL_PASS_DEPTH_PASS),
+  EDEF(STENCIL_PASS_DEPTH_FAIL),
+  EDEF(STENCIL_CLEAR_VALUE),
+  EDEF(STENCIL_INDEX),
+  EDEF(KEEP),
+  EDEF(REPLACE),
+  EDEF(INCR),
+  EDEF(DECR),
+  EDEF(NONE),
+  EDEF(LEFT),
+  EDEF(RIGHT),
+  EDEF(FRONT_LEFT),
+  EDEF(FRONT_RIGHT),
+  EDEF(BACK_LEFT),
+  EDEF(BACK_RIGHT),
+  EDEF(AUX0),
+  EDEF(AUX1),
+  EDEF(AUX2),
+  EDEF(AUX3),
+  EDEF(COLOR_INDEX),
+  EDEF(RED),
+  EDEF(GREEN),
+  EDEF(BLUE),
+  EDEF(ALPHA),
+  EDEF(LUMINANCE),
+  EDEF(LUMINANCE_ALPHA),
+  EDEF(ALPHA_BITS),
+  EDEF(RED_BITS),
+  EDEF(GREEN_BITS),
+  EDEF(BLUE_BITS),
+  EDEF(INDEX_BITS),
+  EDEF(SUBPIXEL_BITS),
+  EDEF(AUX_BUFFERS),
+  EDEF(READ_BUFFER),
+  EDEF(DRAW_BUFFER),
+  EDEF(DOUBLEBUFFER),
+  EDEF(STEREO),
+  EDEF(BITMAP),
+  EDEF(COLOR),
+  EDEF(DEPTH),
+  EDEF(STENCIL),
+  EDEF(DITHER),
+  EDEF(RGB),
+  EDEF(RGBA),
+  EDEF(MAX_LIST_NESTING),
+  EDEF(MAX_ATTRIB_STACK_DEPTH),
+  EDEF(MAX_MODELVIEW_STACK_DEPTH),
+  EDEF(MAX_NAME_STACK_DEPTH),
+  EDEF(MAX_PROJECTION_STACK_DEPTH),
+  EDEF(MAX_TEXTURE_STACK_DEPTH),
+  EDEF(MAX_EVAL_ORDER),
+  EDEF(MAX_LIGHTS),
+  EDEF(MAX_CLIP_PLANES),
+  EDEF(MAX_TEXTURE_SIZE),
+  EDEF(MAX_PIXEL_MAP_TABLE),
+  EDEF(MAX_VIEWPORT_DIMS),
+  EDEF(MAX_CLIENT_ATTRIB_STACK_DEPTH),
+  EDEF(ATTRIB_STACK_DEPTH),
+  EDEF(CLIENT_ATTRIB_STACK_DEPTH),
+  EDEF(COLOR_CLEAR_VALUE),
+  EDEF(COLOR_WRITEMASK),
+  EDEF(CURRENT_INDEX),
+  EDEF(CURRENT_COLOR),
+  EDEF(CURRENT_NORMAL),
+  EDEF(CURRENT_RASTER_COLOR),
+  EDEF(CURRENT_RASTER_DISTANCE),
+  EDEF(CURRENT_RASTER_INDEX),
+  EDEF(CURRENT_RASTER_POSITION),
+  EDEF(CURRENT_RASTER_TEXTURE_COORDS),
+  EDEF(CURRENT_RASTER_POSITION_VALID),
+  EDEF(CURRENT_TEXTURE_COORDS),
+  EDEF(INDEX_CLEAR_VALUE),
+  EDEF(INDEX_MODE),
+  EDEF(INDEX_WRITEMASK),
+  EDEF(MODELVIEW_MATRIX),
+  EDEF(MODELVIEW_STACK_DEPTH),
+  EDEF(NAME_STACK_DEPTH),
+  EDEF(PROJECTION_MATRIX),
+  EDEF(PROJECTION_STACK_DEPTH),
+  EDEF(RENDER_MODE),
+  EDEF(RGBA_MODE),
+  EDEF(TEXTURE_MATRIX),
+  EDEF(TEXTURE_STACK_DEPTH),
+  EDEF(VIEWPORT),
+  EDEF(AUTO_NORMAL),
+  EDEF(MAP1_COLOR_4),
+  EDEF(MAP1_GRID_DOMAIN),
+  EDEF(MAP1_GRID_SEGMENTS),
+  EDEF(MAP1_INDEX),
+  EDEF(MAP1_NORMAL),
+  EDEF(MAP1_TEXTURE_COORD_1),
+  EDEF(MAP1_TEXTURE_COORD_2),
+  EDEF(MAP1_TEXTURE_COORD_3),
+  EDEF(MAP1_TEXTURE_COORD_4),
+  EDEF(MAP1_VERTEX_3),
+  EDEF(MAP1_VERTEX_4),
+  EDEF(MAP2_COLOR_4),
+  EDEF(MAP2_GRID_DOMAIN),
+  EDEF(MAP2_GRID_SEGMENTS),
+  EDEF(MAP2_INDEX),
+  EDEF(MAP2_NORMAL),
+  EDEF(MAP2_TEXTURE_COORD_1),
+  EDEF(MAP2_TEXTURE_COORD_2),
+  EDEF(MAP2_TEXTURE_COORD_3),
+  EDEF(MAP2_TEXTURE_COORD_4),
+  EDEF(MAP2_VERTEX_3),
+  EDEF(MAP2_VERTEX_4),
+  EDEF(COEFF),
+  EDEF(DOMAIN),
+  EDEF(ORDER),
+  EDEF(FOG_HINT),
+  EDEF(LINE_SMOOTH_HINT),
+  EDEF(PERSPECTIVE_CORRECTION_HINT),
+  EDEF(POINT_SMOOTH_HINT),
+  EDEF(POLYGON_SMOOTH_HINT),
+  EDEF(DONT_CARE),
+  EDEF(FASTEST),
+  EDEF(NICEST),
+  EDEF(SCISSOR_TEST),
+  EDEF(SCISSOR_BOX),
+  EDEF(MAP_COLOR),
+  EDEF(MAP_STENCIL),
+  EDEF(INDEX_SHIFT),
+  EDEF(INDEX_OFFSET),
+  EDEF(RED_SCALE),
+  EDEF(RED_BIAS),
+  EDEF(GREEN_SCALE),
+  EDEF(GREEN_BIAS),
+  EDEF(BLUE_SCALE),
+  EDEF(BLUE_BIAS),
+  EDEF(ALPHA_SCALE),
+  EDEF(ALPHA_BIAS),
+  EDEF(DEPTH_SCALE),
+  EDEF(DEPTH_BIAS),
+  EDEF(PIXEL_MAP_S_TO_S_SIZE),
+  EDEF(PIXEL_MAP_I_TO_I_SIZE),
+  EDEF(PIXEL_MAP_I_TO_R_SIZE),
+  EDEF(PIXEL_MAP_I_TO_G_SIZE),
+  EDEF(PIXEL_MAP_I_TO_B_SIZE),
+  EDEF(PIXEL_MAP_I_TO_A_SIZE),
+  EDEF(PIXEL_MAP_R_TO_R_SIZE),
+  EDEF(PIXEL_MAP_G_TO_G_SIZE),
+  EDEF(PIXEL_MAP_B_TO_B_SIZE),
+  EDEF(PIXEL_MAP_A_TO_A_SIZE),
+  EDEF(PIXEL_MAP_S_TO_S),
+  EDEF(PIXEL_MAP_I_TO_I),
+  EDEF(PIXEL_MAP_I_TO_R),
+  EDEF(PIXEL_MAP_I_TO_G),
+  EDEF(PIXEL_MAP_I_TO_B),
+  EDEF(PIXEL_MAP_I_TO_A),
+  EDEF(PIXEL_MAP_R_TO_R),
+  EDEF(PIXEL_MAP_G_TO_G),
+  EDEF(PIXEL_MAP_B_TO_B),
+  EDEF(PIXEL_MAP_A_TO_A),
+  EDEF(PACK_ALIGNMENT),
+  EDEF(PACK_LSB_FIRST),
+  EDEF(PACK_ROW_LENGTH),
+  EDEF(PACK_SKIP_PIXELS),
+  EDEF(PACK_SKIP_ROWS),
+  EDEF(PACK_SWAP_BYTES),
+  EDEF(UNPACK_ALIGNMENT),
+  EDEF(UNPACK_LSB_FIRST),
+  EDEF(UNPACK_ROW_LENGTH),
+  EDEF(UNPACK_SKIP_PIXELS),
+  EDEF(UNPACK_SKIP_ROWS),
+  EDEF(UNPACK_SWAP_BYTES),
+  EDEF(ZOOM_X),
+  EDEF(ZOOM_Y),
+  EDEF(TEXTURE_ENV),
+  EDEF(TEXTURE_ENV_MODE),
+  EDEF(TEXTURE_1D),
+  EDEF(TEXTURE_2D),
+  EDEF(TEXTURE_WRAP_S),
+  EDEF(TEXTURE_WRAP_T),
+  EDEF(TEXTURE_MAG_FILTER),
+  EDEF(TEXTURE_MIN_FILTER),
+  EDEF(TEXTURE_ENV_COLOR),
+  EDEF(TEXTURE_GEN_S),
+  EDEF(TEXTURE_GEN_T),
+  EDEF(TEXTURE_GEN_MODE),
+  EDEF(TEXTURE_BORDER_COLOR),
+  EDEF(TEXTURE_WIDTH),
+  EDEF(TEXTURE_HEIGHT),
+  EDEF(TEXTURE_BORDER),
+  EDEF(TEXTURE_COMPONENTS),
+  EDEF(TEXTURE_RED_SIZE),
+  EDEF(TEXTURE_GREEN_SIZE),
+  EDEF(TEXTURE_BLUE_SIZE),
+  EDEF(TEXTURE_ALPHA_SIZE),
+  EDEF(TEXTURE_LUMINANCE_SIZE),
+  EDEF(TEXTURE_INTENSITY_SIZE),
+  EDEF(NEAREST_MIPMAP_NEAREST),
+  EDEF(NEAREST_MIPMAP_LINEAR),
+  EDEF(LINEAR_MIPMAP_NEAREST),
+  EDEF(LINEAR_MIPMAP_LINEAR),
+  EDEF(OBJECT_LINEAR),
+  EDEF(OBJECT_PLANE),
+  EDEF(EYE_LINEAR),
+  EDEF(EYE_PLANE),
+  EDEF(SPHERE_MAP),
+  EDEF(DECAL),
+  EDEF(MODULATE),
+  EDEF(NEAREST),
+  EDEF(REPEAT),
+  EDEF(CLAMP),
+  EDEF(S),
+  EDEF(T),
+  EDEF(R),
+  EDEF(Q),
+  EDEF(TEXTURE_GEN_R),
+  EDEF(TEXTURE_GEN_Q),
+  EDEF(PROXY_TEXTURE_1D),
+  EDEF(PROXY_TEXTURE_2D),
+  EDEF(TEXTURE_PRIORITY),
+  EDEF(TEXTURE_RESIDENT),
+  EDEF(TEXTURE_BINDING_1D),
+  EDEF(TEXTURE_BINDING_2D),
+  EDEF(TEXTURE_INTERNAL_FORMAT),
+  EDEF(PACK_SKIP_IMAGES),
+  EDEF(PACK_IMAGE_HEIGHT),
+  EDEF(UNPACK_SKIP_IMAGES),
+  EDEF(UNPACK_IMAGE_HEIGHT),
+  EDEF(TEXTURE_3D),
+  EDEF(PROXY_TEXTURE_3D),
+  EDEF(TEXTURE_DEPTH),
+  EDEF(TEXTURE_WRAP_R),
+  EDEF(MAX_3D_TEXTURE_SIZE),
+  EDEF(TEXTURE_BINDING_3D),
+  EDEF(ALPHA4),
+  EDEF(ALPHA8),
+  EDEF(ALPHA12),
+  EDEF(ALPHA16),
+  EDEF(LUMINANCE4),
+  EDEF(LUMINANCE8),
+  EDEF(LUMINANCE12),
+  EDEF(LUMINANCE16),
+  EDEF(LUMINANCE4_ALPHA4),
+  EDEF(LUMINANCE6_ALPHA2),
+  EDEF(LUMINANCE8_ALPHA8),
+  EDEF(LUMINANCE12_ALPHA4),
+  EDEF(LUMINANCE12_ALPHA12),
+  EDEF(LUMINANCE16_ALPHA16),
+  EDEF(INTENSITY),
+  EDEF(INTENSITY4),
+  EDEF(INTENSITY8),
+  EDEF(INTENSITY12),
+  EDEF(INTENSITY16),
+  EDEF(R3_G3_B2),
+  EDEF(RGB4),
+  EDEF(RGB5),
+  EDEF(RGB8),
+  EDEF(RGB10),
+  EDEF(RGB12),
+  EDEF(RGB16),
+  EDEF(RGBA2),
+  EDEF(RGBA4),
+  EDEF(RGB5_A1),
+  EDEF(RGBA8),
+  EDEF(RGB10_A2),
+  EDEF(RGBA12),
+  EDEF(RGBA16),
+  EDEF(VENDOR),
+  EDEF(RENDERER),
+  EDEF(VERSION),
+  EDEF(EXTENSIONS),
+  EDEF(INVALID_VALUE),
+  EDEF(INVALID_ENUM),
+  EDEF(INVALID_OPERATION),
+  EDEF(STACK_OVERFLOW),
+  EDEF(STACK_UNDERFLOW),
+  EDEF(OUT_OF_MEMORY),
+
+  /* extensions */
+  EDEF(CONSTANT_COLOR_EXT),
+  EDEF(ONE_MINUS_CONSTANT_COLOR_EXT),
+  EDEF(CONSTANT_ALPHA_EXT),
+  EDEF(ONE_MINUS_CONSTANT_ALPHA_EXT),
+  EDEF(BLEND_EQUATION_EXT),
+  EDEF(MIN_EXT),
+  EDEF(MAX_EXT),
+  EDEF(FUNC_ADD_EXT),
+  EDEF(FUNC_SUBTRACT_EXT),
+  EDEF(FUNC_REVERSE_SUBTRACT_EXT),
+  EDEF(BLEND_COLOR_EXT),
+  EDEF(POLYGON_OFFSET_EXT),
+  EDEF(POLYGON_OFFSET_FACTOR_EXT),
+  EDEF(POLYGON_OFFSET_BIAS_EXT),
+  EDEF(VERTEX_ARRAY_EXT),
+  EDEF(NORMAL_ARRAY_EXT),
+  EDEF(COLOR_ARRAY_EXT),
+  EDEF(INDEX_ARRAY_EXT),
+  EDEF(TEXTURE_COORD_ARRAY_EXT),
+  EDEF(EDGE_FLAG_ARRAY_EXT),
+  EDEF(VERTEX_ARRAY_SIZE_EXT),
+  EDEF(VERTEX_ARRAY_TYPE_EXT),
+  EDEF(VERTEX_ARRAY_STRIDE_EXT),
+  EDEF(VERTEX_ARRAY_COUNT_EXT),
+  EDEF(NORMAL_ARRAY_TYPE_EXT),
+  EDEF(NORMAL_ARRAY_STRIDE_EXT),
+  EDEF(NORMAL_ARRAY_COUNT_EXT),
+  EDEF(COLOR_ARRAY_SIZE_EXT),
+  EDEF(COLOR_ARRAY_TYPE_EXT),
+  EDEF(COLOR_ARRAY_STRIDE_EXT),
+  EDEF(COLOR_ARRAY_COUNT_EXT),
+  EDEF(INDEX_ARRAY_TYPE_EXT),
+  EDEF(INDEX_ARRAY_STRIDE_EXT),
+  EDEF(INDEX_ARRAY_COUNT_EXT),
+  EDEF(TEXTURE_COORD_ARRAY_SIZE_EXT),
+  EDEF(TEXTURE_COORD_ARRAY_TYPE_EXT),
+  EDEF(TEXTURE_COORD_ARRAY_STRIDE_EXT),
+  EDEF(TEXTURE_COORD_ARRAY_COUNT_EXT),
+  EDEF(EDGE_FLAG_ARRAY_STRIDE_EXT),
+  EDEF(EDGE_FLAG_ARRAY_COUNT_EXT),
+  EDEF(VERTEX_ARRAY_POINTER_EXT),
+  EDEF(NORMAL_ARRAY_POINTER_EXT),
+  EDEF(COLOR_ARRAY_POINTER_EXT),
+  EDEF(INDEX_ARRAY_POINTER_EXT),
+  EDEF(TEXTURE_COORD_ARRAY_POINTER_EXT),
+  EDEF(EDGE_FLAG_ARRAY_POINTER_EXT),
+  EDEF(TEXTURE_PRIORITY_EXT),
+  EDEF(TEXTURE_RESIDENT_EXT),
+  EDEF(TEXTURE_1D_BINDING_EXT),
+  EDEF(TEXTURE_2D_BINDING_EXT),
+  EDEF(PACK_SKIP_IMAGES_EXT),
+  EDEF(PACK_IMAGE_HEIGHT_EXT),
+  EDEF(UNPACK_SKIP_IMAGES_EXT),
+  EDEF(UNPACK_IMAGE_HEIGHT_EXT),
+  EDEF(TEXTURE_3D_EXT),
+  EDEF(PROXY_TEXTURE_3D_EXT),
+  EDEF(TEXTURE_DEPTH_EXT),
+  EDEF(TEXTURE_WRAP_R_EXT),
+  EDEF(MAX_3D_TEXTURE_SIZE_EXT),
+  EDEF(TEXTURE_3D_BINDING_EXT),
+  EDEF(TABLE_TOO_LARGE_EXT),
+  EDEF(COLOR_TABLE_FORMAT_EXT),
+  EDEF(COLOR_TABLE_WIDTH_EXT),
+  EDEF(COLOR_TABLE_RED_SIZE_EXT),
+  EDEF(COLOR_TABLE_GREEN_SIZE_EXT),
+  EDEF(COLOR_TABLE_BLUE_SIZE_EXT),
+  EDEF(COLOR_TABLE_ALPHA_SIZE_EXT),
+  EDEF(COLOR_TABLE_LUMINANCE_SIZE_EXT),
+  EDEF(COLOR_TABLE_INTENSITY_SIZE_EXT),
+  EDEF(TEXTURE_INDEX_SIZE_EXT),
+  EDEF(COLOR_INDEX1_EXT),
+  EDEF(COLOR_INDEX2_EXT),
+  EDEF(COLOR_INDEX4_EXT),
+  EDEF(COLOR_INDEX8_EXT),
+  EDEF(COLOR_INDEX12_EXT),
+  EDEF(COLOR_INDEX16_EXT),
+  EDEF(SHARED_TEXTURE_PALETTE_EXT),
+  EDEF(POINT_SIZE_MIN_EXT),
+  EDEF(POINT_SIZE_MAX_EXT),
+  EDEF(POINT_FADE_THRESHOLD_SIZE_EXT),
+  EDEF(DISTANCE_ATTENUATION_EXT),
+  EDEF(RESCALE_NORMAL_EXT),
+  EDEF(ABGR_EXT),
+  EDEF(SELECTED_TEXTURE_SGIS),
+  EDEF(SELECTED_TEXTURE_COORD_SET_SGIS),
+  EDEF(MAX_TEXTURES_SGIS),
+  EDEF(TEXTURE0_SGIS),
+  EDEF(TEXTURE1_SGIS),
+  EDEF(TEXTURE2_SGIS),
+  EDEF(TEXTURE3_SGIS),
+  EDEF(TEXTURE_COORD_SET_SOURCE_SGIS),
+  EDEF(SELECTED_TEXTURE_EXT),
+  EDEF(SELECTED_TEXTURE_COORD_SET_EXT),
+  EDEF(SELECTED_TEXTURE_TRANSFORM_EXT),
+  EDEF(MAX_TEXTURES_EXT),
+  EDEF(MAX_TEXTURE_COORD_SETS_EXT),
+  EDEF(TEXTURE_ENV_COORD_SET_EXT),
+  EDEF(TEXTURE0_EXT),
+  EDEF(TEXTURE1_EXT),
+  EDEF(TEXTURE2_EXT),
+  EDEF(TEXTURE3_EXT),
+  EDEF(CLAMP_TO_EDGE_SGIS),
+  EDEF(RESCALE_NORMAL),
+  EDEF(CLAMP_TO_EDGE),
+  EDEF(MAX_ELEMENTS_VERTICES),
+  EDEF(MAX_ELEMENTS_INDICES),
+  EDEF(BGR),
+  EDEF(BGRA),
+  EDEF(UNSIGNED_BYTE_3_3_2),
+  EDEF(UNSIGNED_BYTE_2_3_3_REV),
+  EDEF(UNSIGNED_SHORT_5_6_5),
+  EDEF(UNSIGNED_SHORT_5_6_5_REV),
+  EDEF(UNSIGNED_SHORT_4_4_4_4),
+  EDEF(UNSIGNED_SHORT_4_4_4_4_REV),
+  EDEF(UNSIGNED_SHORT_5_5_5_1),
+  EDEF(UNSIGNED_SHORT_1_5_5_5_REV),
+  EDEF(UNSIGNED_INT_8_8_8_8),
+  EDEF(UNSIGNED_INT_8_8_8_8_REV),
+  EDEF(UNSIGNED_INT_10_10_10_2),
+  EDEF(UNSIGNED_INT_2_10_10_10_REV),
+  EDEF(LIGHT_MODEL_COLOR_CONTROL),
+  EDEF(SINGLE_COLOR),
+  EDEF(SEPARATE_SPECULAR_COLOR),
+  EDEF(TEXTURE_MIN_LOD),
+  EDEF(TEXTURE_MAX_LOD),
+  EDEF(TEXTURE_BASE_LEVEL),
+  EDEF(TEXTURE_MAX_LEVEL)
+};
+
+#undef EDEF
+
+#define N_ENUMS (sizeof(enums) / sizeof(ENUM))
+
+/***************************************************************************/
+
+static void print_enum_name( FILE* OUT, GLenum e )
+{
+  int i, found= 0;
+  for( i= 0; i < N_ENUMS; ++i )
+    {
+    if( enums[i].e == e )
+      {
+      if( found )
+        fprintf( OUT, "/" );
+      found= 1;
+      fprintf( OUT, "%s", enums[i].name );
+      }
+    }
+  if( ! found )
+    fprintf( OUT, "*UNKNOWN* [%04x]", (int)e );
+  fprintf( OUT, "\n" );
+}
+
+#define BOOL_STRING(b) (b ? "true" : "false")
+
+#define VAR_ENUM(VAR)                            \
+        {                                        \
+        GLint e= 0;                              \
+        glGetIntegerv(GL_##VAR,&e);              \
+        fprintf( OUT, "%s: ", #VAR );            \
+        print_enum_name( OUT, (GLenum) e );      \
+        }
+
+#define VAR_FLOAT4(VAR)                          \
+        {                                        \
+        GLfloat f[4];                            \
+        f[0]= f[1]= f[2]= f[3]= 0.0;             \
+        glGetFloatv(GL_##VAR,f);                 \
+        fprintf( OUT, "%s: [%f %f %f %f]\n",     \
+                 #VAR, f[0], f[1], f[2], f[3] ); \
+        }
+
+#define VAR_MAT_FLOAT4(VAR)                        \
+        {                                          \
+        GLfloat f[4];                              \
+        f[0]= f[1]= f[2]= f[3]= 0.0;               \
+        glGetMaterialfv(GL_FRONT,GL_##VAR,f);      \
+        fprintf( OUT, "FRONT_%s: [%f %f %f %f]\n", \
+                 #VAR, f[0], f[1], f[2], f[3] );   \
+        glGetMaterialfv(GL_BACK,GL_##VAR,f);       \
+        fprintf( OUT, " BACK_%s: [%f %f %f %f]\n", \
+                 #VAR, f[0], f[1], f[2], f[3] );   \
+        }
+
+#define VAR_LIGHT_FLOAT4(LIGHT,VAR)                     \
+        {                                               \
+        GLfloat f[4];                                   \
+        f[0]= f[1]= f[2]= f[3]= 0.0;                    \
+        glGetLightfv(GL_LIGHT0+LIGHT,GL_##VAR,f);       \
+        fprintf( OUT, "LIGHT%d.%s: [%f %f %f %f]\n",    \
+                 LIGHT, #VAR, f[0], f[1], f[2], f[3] ); \
+        }
+
+#define VAR_LIGHT_FLOAT3(LIGHT,VAR)               \
+        {                                         \
+        GLfloat f[3];                             \
+        f[0]= f[1]= f[2]= 0.0;                    \
+        glGetLightfv(GL_LIGHT0+LIGHT,GL_##VAR,f); \
+        fprintf( OUT, "LIGHT%d.%s: [%f %f %f]\n", \
+                 LIGHT, #VAR, f[0], f[1], f[2] ); \
+        }
+
+#define VAR_FLOAT3(VAR)                    \
+        {                                  \
+        GLfloat f[3];                      \
+        f[0]= f[1]= f[2]= 0.0;             \
+        glGetFloatv(GL_##VAR,f) ;          \
+        fprintf( OUT, "%s: [%f %f %f]\n",  \
+                 #VAR, f[0], f[1], f[2] ); \
+        }
+#define VAR_FLOAT2(VAR)                \
+        {                              \
+        GLfloat f[2];                  \
+        f[0]= f[1]= 0.0;               \
+        glGetFloatv(GL_##VAR,f);       \
+        fprintf( OUT, "%s: [%f %f]\n", \
+                 #VAR, f[0], f[1] );   \
+        }
+
+#define VAR_COLOR(VAR)    VAR_FLOAT4(VAR)
+#define VAR_TEXCOORD(VAR) VAR_FLOAT4(VAR)
+#define VAR_NORMAL(VAR)   VAR_FLOAT3(VAR)
+
+#define VAR_MAT_COLOR(VAR)         VAR_MAT_FLOAT4(VAR)
+#define VAR_LIGHT_COLOR(LIGHT,VAR) VAR_LIGHT_FLOAT4(LIGHT,VAR)
+
+#define VAR_FLOAT(VAR)                       \
+        {                                    \
+        GLfloat f= 0.0;                      \
+        glGetFloatv(GL_##VAR,&f);            \
+        fprintf( OUT, "%s: %f\n", #VAR, f ); \
+        }
+
+#define VAR_MAT_FLOAT(VAR)                         \
+        {                                          \
+        GLfloat f= 0.0;                            \
+        glGetMaterialfv(GL_FRONT,GL_##VAR,&f);     \
+        fprintf( OUT, "FRONT_%s: %f\n", #VAR, f ); \
+        glGetMaterialfv(GL_BACK,GL_##VAR,&f);      \
+        fprintf( OUT, " BACK_%s: %f\n", #VAR, f ); \
+        }
+
+#define VAR_LIGHT_FLOAT(LIGHT,VAR)                 \
+        {                                          \
+        GLfloat f= 0.0;                            \
+        glGetLightfv(GL_LIGHT0+LIGHT,GL_##VAR,&f); \
+        fprintf( OUT, "LIGHT%d.%s: %f\n",          \
+                 LIGHT, #VAR, f );                 \
+        }
+
+#define VAR_INT(VAR)                         \
+        {                                    \
+        GLint i= 0;                          \
+        glGetIntegerv(GL_##VAR,&i);          \
+        fprintf( OUT, "%s: %d\n", #VAR, (int)i ); \
+        }
+#define VAR_INTEGER(VAR) VAR_INT(VAR)
+#define VAR_INDEX(VAR)   VAR_INT(VAR)
+#define VAR_HEXINT(VAR)                        \
+        {                                      \
+        GLint i= 0;                            \
+        glGetIntegerv(GL_##VAR,&i);            \
+        fprintf( OUT, "%s: 0x%04x\n", #VAR, (int)i ); \
+        }
+#define VAR_INT4(VAR)                            \
+        {                                        \
+        GLint i[4];                              \
+        i[0]= i[1]= i[2]= i[3]= 0;               \
+        glGetIntegerv(GL_##VAR,i);               \
+        fprintf( OUT, "%s: [%d %d %d %d]\n",     \
+                 #VAR, (int)i[0], (int)i[1], (int)i[2], (int)i[3] ); \
+        }
+#define VAR_BOOL(VAR)                                     \
+        {                                                 \
+        GLboolean b= 0;                                   \
+        glGetBooleanv(GL_##VAR,&b);                       \
+        fprintf( OUT, "%s: %s\n", #VAR, BOOL_STRING(b) ); \
+        }
+#define VAR_BOOL4(VAR)                                    \
+        {                                                 \
+        GLboolean b[4];                                   \
+        b[0]= b[1]= b[2]= b[3]= 0;                        \
+        glGetBooleanv(GL_##VAR,b);                        \
+        fprintf( OUT, "%s: [%s %s %s %s]\n",              \
+                 #VAR,                                    \
+                 BOOL_STRING(b[0]),                       \
+                 BOOL_STRING(b[1]),                       \
+                 BOOL_STRING(b[2]),                       \
+                 BOOL_STRING(b[3]) );                     \
+        }
+#define VAR_PTR(VAR)                         \
+        {                                    \
+        GLvoid* p= 0;                        \
+        glGetPointerv(GL_##VAR,&p);          \
+        fprintf( OUT, "%s: %p\n", #VAR, p ); \
+        }
+#define VAR_MATRIX(VAR)                                    \
+        {                                                  \
+        GLfloat m[16];                                     \
+        int i;                                             \
+        for( i= 0; i < 16; ++i ) m[i]= 0.0;                \
+        glGetFloatv(GL_##VAR,m);                           \
+        fprintf( OUT,                                      \
+                 "%s:\n\t[%+.6f %+.6f %+.6f %+.6f]\n\t[%+.6f %+.6f %+.6f 
+%+.6f]\n\t[%+.6f %+.6f %+.6f %+.6f]\n\t[%+.6f %+.6f %+.6f %+.6f]\n", \
+                 #VAR,                                     \
+                 m[0+0*4], m[0+1*4], m[0+2*4], m[0+3*4],   \
+                 m[1+0*4], m[1+1*4], m[1+2*4], m[1+3*4],   \
+                 m[2+0*4], m[2+1*4], m[2+2*4], m[2+3*4],   \
+                 m[3+0*4], m[3+1*4], m[3+2*4], m[3+3*4] ); \
+        }
+
+/***************************************************************************/
+
+/*
+#define OUT stderr
+*/
+void dump_opengl_state( FILE* OUT )
+{
+  int i;
+  GLint n_lights= 0;
+
+  glGetIntegerv( GL_MAX_LIGHTS, &n_lights );
+
+  VAR_COLOR(CURRENT_COLOR)
+  VAR_INDEX(CURRENT_INDEX)
+  VAR_TEXCOORD(CURRENT_TEXTURE_COORDS)
+  VAR_NORMAL(CURRENT_NORMAL)
+  VAR_FLOAT4(CURRENT_RASTER_POSITION)
+  VAR_FLOAT(CURRENT_RASTER_DISTANCE)
+  VAR_COLOR(CURRENT_RASTER_COLOR)
+  VAR_INDEX(CURRENT_RASTER_INDEX)
+  VAR_TEXCOORD(CURRENT_RASTER_TEXTURE_COORDS)
+  VAR_BOOL(CURRENT_RASTER_POSITION_VALID)
+  VAR_BOOL(EDGE_FLAG)
+
+  VAR_BOOL   (VERTEX_ARRAY)
+  VAR_INTEGER(VERTEX_ARRAY_SIZE)
+  VAR_ENUM   (VERTEX_ARRAY_TYPE)
+  VAR_INTEGER(VERTEX_ARRAY_STRIDE)
+  VAR_PTR    (VERTEX_ARRAY_POINTER)
+
+  VAR_BOOL   (NORMAL_ARRAY)
+  VAR_ENUM   (NORMAL_ARRAY_TYPE)
+  VAR_INTEGER(NORMAL_ARRAY_STRIDE)
+  VAR_PTR    (NORMAL_ARRAY_POINTER)
+
+  VAR_BOOL   (COLOR_ARRAY)
+  VAR_INTEGER(COLOR_ARRAY_SIZE)
+  VAR_ENUM   (COLOR_ARRAY_TYPE)
+  VAR_INTEGER(COLOR_ARRAY_STRIDE)
+  VAR_PTR    (COLOR_ARRAY_POINTER)
+
+  VAR_BOOL   (INDEX_ARRAY)
+  VAR_ENUM   (INDEX_ARRAY_TYPE)
+  VAR_INTEGER(INDEX_ARRAY_STRIDE)
+  VAR_PTR    (INDEX_ARRAY_POINTER)
+
+  VAR_BOOL   (TEXTURE_COORD_ARRAY)
+  VAR_INTEGER(TEXTURE_COORD_ARRAY_SIZE)
+  VAR_ENUM   (TEXTURE_COORD_ARRAY_TYPE)
+  VAR_INTEGER(TEXTURE_COORD_ARRAY_STRIDE)
+  VAR_PTR    (TEXTURE_COORD_ARRAY_POINTER)
+
+  VAR_BOOL   (EDGE_FLAG_ARRAY)
+  VAR_INTEGER(EDGE_FLAG_ARRAY_STRIDE)
+  VAR_PTR    (EDGE_FLAG_ARRAY_POINTER)
+
+  VAR_MATRIX(MODELVIEW_MATRIX)
+  VAR_MATRIX(PROJECTION_MATRIX)
+  VAR_MATRIX(TEXTURE_MATRIX)
+  VAR_INT4(VIEWPORT)
+  VAR_FLOAT2(DEPTH_RANGE)
+  VAR_INT(MODELVIEW_STACK_DEPTH)
+  VAR_INT(PROJECTION_STACK_DEPTH)
+  VAR_INT(TEXTURE_STACK_DEPTH)
+  VAR_ENUM(MATRIX_MODE)
+  VAR_BOOL(NORMALIZE)
+  VAR_BOOL(RESCALE_NORMAL_EXT)
+  VAR_BOOL(CLIP_PLANE0)
+  VAR_BOOL(CLIP_PLANE1)
+  VAR_BOOL(CLIP_PLANE2)
+  VAR_BOOL(CLIP_PLANE3)
+  VAR_BOOL(CLIP_PLANE4)
+  VAR_BOOL(CLIP_PLANE5)
+  /* + glGetClipPlane() */
+
+  VAR_COLOR(FOG_COLOR)
+  VAR_INDEX(FOG_INDEX)
+  VAR_FLOAT(FOG_DENSITY)
+  VAR_FLOAT(FOG_START)
+  VAR_FLOAT(FOG_END)
+  VAR_ENUM(FOG_MODE)
+  VAR_BOOL(FOG)
+  VAR_ENUM(SHADE_MODEL)
+
+  VAR_BOOL(LIGHTING)
+  VAR_BOOL(COLOR_MATERIAL)
+  VAR_ENUM(COLOR_MATERIAL_PARAMETER)
+  VAR_ENUM(COLOR_MATERIAL_FACE)
+
+  VAR_MAT_COLOR(AMBIENT)
+  VAR_MAT_COLOR(DIFFUSE)
+  VAR_MAT_COLOR(SPECULAR)
+  VAR_MAT_COLOR(EMISSION)
+  VAR_MAT_FLOAT(SHININESS)
+
+  VAR_COLOR(LIGHT_MODEL_AMBIENT)
+  VAR_BOOL(LIGHT_MODEL_LOCAL_VIEWER)
+  VAR_BOOL(LIGHT_MODEL_TWO_SIDE)
+/*  VAR_ENUM(LIGHT_MODEL_COLOR_CONTROL)*/
+
+  for( i= 0; i < n_lights; ++i )
+    {
+    GLboolean b= 0;
+
+    glGetBooleanv( GL_LIGHT0 + i, &b );
+    fprintf( OUT, "LIGHT%d: %s\n", i, BOOL_STRING(b) );
+
+    if( ! b )
+      continue;
+
+    VAR_LIGHT_COLOR(i,AMBIENT)
+    VAR_LIGHT_COLOR(i,DIFFUSE)
+    VAR_LIGHT_COLOR(i,SPECULAR)
+    VAR_LIGHT_FLOAT4(i,POSITION)
+    VAR_LIGHT_FLOAT(i,CONSTANT_ATTENUATION)
+    VAR_LIGHT_FLOAT(i,LINEAR_ATTENUATION)
+    VAR_LIGHT_FLOAT(i,QUADRATIC_ATTENUATION)
+    VAR_LIGHT_FLOAT3(i,SPOT_DIRECTION)
+    VAR_LIGHT_FLOAT(i,SPOT_EXPONENT)
+    VAR_LIGHT_FLOAT(i,SPOT_CUTOFF)
+    /* COLOR_INDEXES */
+    }
+
+  VAR_FLOAT(POINT_SIZE)
+  VAR_BOOL(POINT_SMOOTH)
+  VAR_FLOAT(LINE_WIDTH)
+  VAR_BOOL(LINE_SMOOTH)
+  VAR_HEXINT(LINE_STIPPLE_PATTERN)
+  VAR_INT(LINE_STIPPLE_REPEAT)
+  VAR_BOOL(LINE_STIPPLE)
+  VAR_BOOL(CULL_FACE)
+  VAR_ENUM(CULL_FACE_MODE)
+  VAR_ENUM(FRONT_FACE)
+  VAR_BOOL(POLYGON_SMOOTH)
+  VAR_ENUM(POLYGON_MODE)
+  VAR_FLOAT(POLYGON_OFFSET_FACTOR)
+  VAR_FLOAT(POLYGON_OFFSET_UNITS)
+  VAR_BOOL(POLYGON_OFFSET_POINT)
+  VAR_BOOL(POLYGON_OFFSET_LINE)
+  VAR_BOOL(POLYGON_OFFSET_FILL)
+  /* GetPolygonStipple */
+  VAR_BOOL(POLYGON_STIPPLE)
+
+  VAR_BOOL(TEXTURE_1D)
+  VAR_BOOL(TEXTURE_2D)
+/*  VAR_BOOL(TEXTURE_3D)*/
+
+  VAR_INT(TEXTURE_BINDING_1D)
+  VAR_INT(TEXTURE_BINDING_2D)
+/*  VAR_INT(TEXTURE_BINDING_3D)*/
+
+  /* GetTexImage() */
+  /* GetTexLevelParameter() */
+  /* GetTexEnv() */
+
+  VAR_BOOL(TEXTURE_GEN_S)
+  VAR_BOOL(TEXTURE_GEN_T)
+  VAR_BOOL(TEXTURE_GEN_R)
+  VAR_BOOL(TEXTURE_GEN_Q)
+
+  /* GetTexGen() */
+
+  VAR_BOOL(SCISSOR_TEST)
+  VAR_INT4(SCISSOR_BOX)
+  VAR_BOOL(ALPHA_TEST)
+  VAR_ENUM(ALPHA_TEST_FUNC)
+  VAR_FLOAT(ALPHA_TEST_REF)
+  VAR_BOOL(STENCIL_TEST)
+  VAR_ENUM(STENCIL_FUNC)
+  VAR_HEXINT(STENCIL_VALUE_MASK)
+  VAR_INT(STENCIL_REF)
+  VAR_ENUM(STENCIL_FAIL)
+  VAR_ENUM(STENCIL_PASS_DEPTH_FAIL)
+  VAR_ENUM(STENCIL_PASS_DEPTH_PASS)
+  VAR_BOOL(DEPTH_TEST)
+  VAR_ENUM(DEPTH_FUNC)
+  VAR_BOOL(BLEND)
+  VAR_ENUM(BLEND_SRC)
+  VAR_ENUM(BLEND_DST)
+
+  VAR_BOOL(DITHER)
+  VAR_BOOL(LOGIC_OP) /* INDEX_LOGIC_OP */
+  VAR_BOOL(COLOR_LOGIC_OP)
+
+  VAR_ENUM(DRAW_BUFFER)
+  VAR_INT(INDEX_WRITEMASK)
+  VAR_BOOL4(COLOR_WRITEMASK)
+  VAR_BOOL(DEPTH_WRITEMASK)
+  VAR_HEXINT(STENCIL_WRITEMASK)
+  VAR_COLOR(COLOR_CLEAR_VALUE)
+  VAR_INDEX(INDEX_CLEAR_VALUE)
+  VAR_FLOAT(DEPTH_CLEAR_VALUE)
+  VAR_INT(STENCIL_CLEAR_VALUE)
+  VAR_FLOAT(ACCUM_CLEAR_VALUE)
+
+  VAR_BOOL(UNPACK_SWAP_BYTES)
+  VAR_BOOL(UNPACK_LSB_FIRST)
+#ifdef UNPACK_IMAGE_HEIGHT
+  VAR_INT(UNPACK_IMAGE_HEIGHT)
+#endif
+#ifdef UNPACK_SKIP_IMAGES
+  VAR_INT(UNPACK_SKIP_IMAGES)
+#endif
+  VAR_INT(UNPACK_ROW_LENGTH)
+  VAR_INT(UNPACK_SKIP_ROWS)
+  VAR_INT(UNPACK_SKIP_PIXELS)
+  VAR_INT(UNPACK_ALIGNMENT)
+
+  VAR_BOOL(PACK_SWAP_BYTES)
+  VAR_BOOL(PACK_LSB_FIRST)
+#ifdef PACK_IMAGE_HEIGHT
+  VAR_INT(PACK_IMAGE_HEIGHT)
+#endif
+#ifdef PACK_SKIP_IMAGES
+  VAR_INT(PACK_SKIP_IMAGES)
+#endif
+  VAR_INT(PACK_ROW_LENGTH)
+  VAR_INT(PACK_SKIP_ROWS)
+  VAR_INT(PACK_SKIP_PIXELS)
+  VAR_INT(PACK_ALIGNMENT)
+
+  VAR_BOOL(MAP_COLOR)
+  VAR_BOOL(MAP_STENCIL)
+  VAR_INT(INDEX_SHIFT)
+  VAR_INT(INDEX_OFFSET)
+  VAR_FLOAT(RED_SCALE)
+  VAR_FLOAT(GREEN_SCALE)
+  VAR_FLOAT(BLUE_SCALE)
+  VAR_FLOAT(ALPHA_SCALE)
+  VAR_FLOAT(DEPTH_SCALE)
+  VAR_FLOAT(RED_BIAS)
+  VAR_FLOAT(GREEN_BIAS)
+  VAR_FLOAT(BLUE_BIAS)
+  VAR_FLOAT(ALPHA_BIAS)
+  VAR_FLOAT(DEPTH_BIAS)
+
+  VAR_FLOAT(ZOOM_X)
+  VAR_FLOAT(ZOOM_Y)
+
+  VAR_ENUM(READ_BUFFER)
+
+  VAR_BOOL(AUTO_NORMAL)
+
+  VAR_ENUM(PERSPECTIVE_CORRECTION_HINT)
+  VAR_ENUM(POINT_SMOOTH_HINT)
+  VAR_ENUM(LINE_SMOOTH_HINT)
+  VAR_ENUM(POLYGON_SMOOTH_HINT)
+  VAR_ENUM(FOG_HINT)
+
+  VAR_INT(MAX_LIGHTS)
+  VAR_INT(MAX_CLIP_PLANES)
+  VAR_INT(MAX_MODELVIEW_STACK_DEPTH)
+  VAR_INT(MAX_PROJECTION_STACK_DEPTH)
+  VAR_INT(MAX_TEXTURE_STACK_DEPTH)
+  VAR_INT(SUBPIXEL_BITS)
+#ifdef GL_MAX_3D_TEXTURE_SIZE
+  VAR_INT(MAX_3D_TEXTURE_SIZE)
+#endif
+  VAR_INT(MAX_TEXTURE_SIZE)
+  VAR_INT(MAX_PIXEL_MAP_TABLE)
+  VAR_INT(MAX_NAME_STACK_DEPTH)
+  VAR_INT(MAX_LIST_NESTING)
+  VAR_INT(MAX_EVAL_ORDER)
+  VAR_INT(MAX_VIEWPORT_DIMS)
+  VAR_INT(MAX_ATTRIB_STACK_DEPTH)
+  VAR_INT(MAX_CLIENT_ATTRIB_STACK_DEPTH)
+  VAR_INT(AUX_BUFFERS)
+  VAR_BOOL(RGBA_MODE)
+  VAR_BOOL(INDEX_MODE)
+  VAR_BOOL(DOUBLEBUFFER)
+  VAR_BOOL(STEREO)
+#ifdef GL_ALIASED_POINT_SIZE_RANGE
+  VAR_FLOAT2(ALIASED_POINT_SIZE_RANGE)
+#endif
+#ifdef GL_POINT_SIZE_RANGE
+  VAR_FLOAT2(POINT_SIZE_RANGE) /* SMOOTH_POINT_SIZE_RANGE */
+#endif
+  VAR_FLOAT(POINT_SIZE_GRANULARITY) /* SMOOTH_POINT_SIZE_GRANULARITY */
+#ifdef GL_ALIASED_LINE_WIDTH_RANGE
+  VAR_FLOAT2(ALIASED_LINE_WIDTH_RANGE)
+#endif
+  VAR_FLOAT2(LINE_WIDTH_RANGE) /* SMOOTH_LINE_WIDTH_RANGE */
+  VAR_FLOAT(LINE_WIDTH_GRANULARITY) /* SMOOTH_LINE_WIDTH_GRANULARITY */
+
+#ifdef GL_MAX_ELEMENTS_INDICES
+  VAR_INT(MAX_ELEMENTS_INDICES)
+#endif
+#ifdef GL_MAX_ELEMENTS_VERTICES
+  VAR_INT(MAX_ELEMENTS_VERTICES)
+#endif
+  VAR_INT(RED_BITS)
+  VAR_INT(GREEN_BITS)
+  VAR_INT(BLUE_BITS)
+  VAR_INT(ALPHA_BITS)
+  VAR_INT(INDEX_BITS)
+  VAR_INT(DEPTH_BITS)
+  VAR_INT(STENCIL_BITS)
+  VAR_INT(ACCUM_RED_BITS)
+  VAR_INT(ACCUM_GREEN_BITS)
+  VAR_INT(ACCUM_BLUE_BITS)
+  VAR_INT(ACCUM_ALPHA_BITS)
+
+  VAR_INT(LIST_BASE)
+  VAR_INT(LIST_INDEX)
+  VAR_ENUM(LIST_MODE)
+  VAR_INT(ATTRIB_STACK_DEPTH)
+  VAR_INT(CLIENT_ATTRIB_STACK_DEPTH)
+  VAR_INT(NAME_STACK_DEPTH)
+  VAR_ENUM(RENDER_MODE)
+  VAR_PTR(SELECTION_BUFFER_POINTER)
+  VAR_INT(SELECTION_BUFFER_SIZE)
+  VAR_PTR(FEEDBACK_BUFFER_POINTER)
+  VAR_INT(FEEDBACK_BUFFER_SIZE)
+  VAR_ENUM(FEEDBACK_BUFFER_TYPE)
+
+  /* glGetError() */
+}
+
+/***************************************************************************/
+
+/*#define TEST*/
+#ifdef TEST
+
+#include <GL/glut.h>
+
+int main( int argc, char *argv[] )
+{
+   glutInit( &argc, argv );
+   glutInitWindowPosition(0, 0);
+   glutInitWindowSize(400, 300);
+   glutInitDisplayMode(GLUT_RGB);
+   glutCreateWindow(argv[0]);
+   dump_opengl_state(stdout);
+   return 0;
+}
+
+#endif
+
diff --git a/progs/util/errcheck.c b/progs/util/errcheck.c
new file mode 100644 (file)
index 0000000..fe9c297
--- /dev/null
@@ -0,0 +1,27 @@
+/* errcheck.c */
+
+
+/*
+ * Call this function in your rendering loop to check for GL errors
+ * during development.  Remove from release code.
+ *
+ * Written by Brian Paul and in the public domain.
+ */
+
+
+#include <GL/gl.h>
+#include <GL/glu.h>
+#incldue <stdio.h>
+
+
+
+GLboolean CheckError( const char *message )
+{
+   GLenum error = glGetError();
+   if (error) {
+      char *err = (char *) gluErrorString( error );
+      fprintf( stderr, "GL Error: %s at %s\n", err, message );
+      return GL_TRUE;
+   }
+   return GL_FALSE;
+}
diff --git a/progs/util/glstate.c b/progs/util/glstate.c
new file mode 100644 (file)
index 0000000..4c5db13
--- /dev/null
@@ -0,0 +1,504 @@
+/* $Id: glstate.c,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
+
+/*
+ * Print GL state information (for debugging)
+ * Copyright (C) 1998  Brian Paul
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/*
+ * $Log: glstate.c,v $
+ * Revision 1.1  1999/08/19 00:55:42  jtg
+ * Initial revision
+ *
+ * Revision 1.4  1999/06/19 01:36:43  brianp
+ * more features added
+ *
+ * Revision 1.3  1999/02/24 05:16:20  brianp
+ * added still more records to EnumTable
+ *
+ * Revision 1.2  1998/11/24 03:47:54  brianp
+ * added more records to EnumTable
+ *
+ * Revision 1.1  1998/11/24 03:41:16  brianp
+ * Initial revision
+ *
+ */
+
+
+
+#include <assert.h>
+#include <GL/gl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "glstate.h"
+
+
+#define FLOAT       1
+#define INT         2
+#define DOUBLE      3
+#define BOOLEAN     4
+#define ENUM        5
+#define VOID        6
+#define LAST_TOKEN ~0
+
+
+struct EnumRecord {
+   GLenum enumerator;   /* GLenum constant */
+   const char *string;  /* string name */
+   int getType;         /* INT, FLOAT, DOUBLE, BOOLEAN, ENUM, or VOID */
+   int getCount;      /* number of values returned by the glGet*v() call */
+};
+
+
+/* XXX Lots more records to add here!  Help, anyone? */
+
+static struct EnumRecord EnumTable[] = {
+   { GL_ACCUM_RED_BITS, "GL_ACCUM_RED_BITS", INT, 1 },
+   { GL_ACCUM_GREEN_BITS, "GL_ACCUM_GREEN_BITS", INT, 1 },
+   { GL_ACCUM_BLUE_BITS, "GL_ACCUM_BLUE_BITS", INT, 1 },
+   { GL_ACCUM_ALPHA_BITS, "GL_ACCUM_ALPHA_BITS", INT, 1 },
+   { GL_ACCUM_CLEAR_VALUE, "GL_ACCUM_CLEAR_VALUE", FLOAT, 4 },
+   { GL_ALPHA_BIAS, "GL_ALPHA_BIAS", FLOAT, 1 },
+   { GL_ALPHA_BITS, "GL_ALPHA_BITS", INT, 1 },
+   { GL_ALPHA_SCALE, "GL_ALPHA_SCALE", FLOAT, 1 },
+   { GL_ALPHA_TEST, "GL_ALPHA_TEST", BOOLEAN, 1 },
+   { GL_ALPHA_TEST_FUNC, "GL_ALPHA_TEST_FUNC", ENUM, 1 },
+   { GL_ALWAYS, "GL_ALWAYS", ENUM, 0 },
+   { GL_ALPHA_TEST_REF, "GL_ALPHA_TEST_REF", FLOAT, 1 },
+   { GL_ATTRIB_STACK_DEPTH, "GL_ATTRIB_STACK_DEPTH", INT, 1 },
+   { GL_AUTO_NORMAL, "GL_AUTO_NORMAL", BOOLEAN, 1 },
+   { GL_AUX_BUFFERS, "GL_AUX_BUFFERS", INT, 1 },
+   { GL_BLEND, "GL_BLEND", BOOLEAN, 1 },
+   { GL_BLEND_DST, "GL_BLEND_DST", ENUM, 1 },
+   { GL_BLEND_SRC, "GL_BLEND_SRC", ENUM, 1 },
+   { GL_BLUE_BIAS, "GL_BLUE_BIAS", FLOAT, 1 },
+   { GL_BLUE_BITS, "GL_BLUE_BITS", INT, 1 },
+   { GL_BLUE_SCALE, "GL_BLUE_SCALE", FLOAT, 1 },
+
+   { GL_CLAMP_TO_EDGE, "GL_CLAMP_TO_EDGE", ENUM, 0 },
+   { GL_CLEAR, "GL_CLEAR", ENUM, 0 },
+   { GL_CLIENT_ATTRIB_STACK_DEPTH, "GL_CLIENT_ATTRIB_STACK_DEPTH", INT, 1 },
+   { GL_CLIP_PLANE0, "GL_CLIP_PLANE0", BOOLEAN, 1 },
+   { GL_CLIP_PLANE1, "GL_CLIP_PLANE1", BOOLEAN, 1 },
+   { GL_CLIP_PLANE2, "GL_CLIP_PLANE2", BOOLEAN, 1 },
+   { GL_CLIP_PLANE3, "GL_CLIP_PLANE3", BOOLEAN, 1 },
+   { GL_CLIP_PLANE4, "GL_CLIP_PLANE4", BOOLEAN, 1 },
+   { GL_CLIP_PLANE5, "GL_CLIP_PLANE5", BOOLEAN, 1 },
+   { GL_COEFF, "GL_COEEF", ENUM, 0 },
+   { GL_COLOR, "GL_COLOR", ENUM, 0 },
+   { GL_COLOR_BUFFER_BIT, "GL_COLOR_BUFFER_BIT", ENUM, 0 },
+   { GL_COLOR_CLEAR_VALUE, "GL_COLOR_CLEAR_VALUE", FLOAT, 4 },
+   { GL_COLOR_INDEX, "GL_COLOR_INDEX", ENUM, 0 },
+   { GL_COLOR_MATERIAL, "GL_COLOR_MATERIAL", BOOLEAN, 1 },
+   { GL_COLOR_MATERIAL_FACE, "GL_COLOR_MATERIAL_FACE", ENUM, 1 },
+   { GL_COLOR_MATERIAL_PARAMETER, "GL_COLOR_MATERIAL_PARAMETER", ENUM, 1 },
+   { GL_COLOR_WRITEMASK, "GL_COLOR_WRITEMASK", BOOLEAN, 4 },
+   { GL_COMPILE, "GL_COMPILE", ENUM, 0 },
+   { GL_COMPILE_AND_EXECUTE, "GL_COMPILE_AND_EXECUTE", ENUM, 0 },
+   { GL_COPY, "GL_COPY", ENUM, 0 },
+   { GL_COPY_INVERTED, "GL_COPY_INVERTED", ENUM, 0 },
+   { GL_COPY_PIXEL_TOKEN, "GL_COPY_PIXEL_TOKEN", ENUM, 0 },
+   { GL_CULL_FACE, "GL_CULL_FACE", BOOLEAN, 1 },
+   { GL_CULL_FACE_MODE, "GL_CULL_FACE_MODE", ENUM, 1 },
+   { GL_CURRENT_BIT, "GL_CURRENT_BIT", ENUM, 0 },
+   { GL_CURRENT_COLOR, "GL_CURRENT_COLOR", FLOAT, 4 },
+   { GL_CURRENT_INDEX, "GL_CURRENT_INDEX", INT, 1 },
+   { GL_CURRENT_NORMAL, "GL_CURRENT_NORMAL", FLOAT, 3 },
+   { GL_CURRENT_RASTER_COLOR, "GL_CURRENT_RASTER_COLOR", FLOAT, 4 },
+   { GL_CURRENT_RASTER_DISTANCE, "GL_CURRENT_RASTER_DISTANCE", FLOAT, 1 },
+   { GL_CURRENT_RASTER_INDEX, "GL_CURRENT_RASTER_INDEX", INT, 1 },
+   { GL_CURRENT_RASTER_POSITION, "GL_CURRENT_RASTER_POSITION", FLOAT, 4 },
+   { GL_CURRENT_RASTER_TEXTURE_COORDS, "GL_CURRENT_RASTER_TEXTURE_COORDS", FLOAT, 4 },
+   { GL_CURRENT_RASTER_POSITION_VALID, "GL_CURRENT_RASTER_POSITION_VALID", BOOLEAN, 1 },
+   { GL_CURRENT_TEXTURE_COORDS, "GL_CURRENT_TEXTURE_COORDS", FLOAT, 4 },
+   { GL_CW, "GL_CW", ENUM, 0 },
+   { GL_CCW, "GL_CCW", ENUM, 0 },
+
+   { GL_DECAL, "GL_DECAL", ENUM, 0 },
+   { GL_DECR, "GL_DECR", ENUM, 0 },
+   { GL_DEPTH, "GL_DEPTH", ENUM, 0 },
+   { GL_DEPTH_BIAS, "GL_DEPTH_BIAS", FLOAT, 1 },
+   { GL_DEPTH_BITS, "GL_DEPTH_BITS", INT, 1 },
+   { GL_DEPTH_BUFFER_BIT, "GL_DEPTH_BUFFER_BIT", ENUM, 0 },
+   { GL_DEPTH_CLEAR_VALUE, "GL_DEPTH_CLEAR_VALUE", FLOAT, 1 },
+   { GL_DEPTH_COMPONENT, "GL_DEPTH_COMPONENT", ENUM, 0 },
+   { GL_DEPTH_FUNC, "GL_DEPTH_FUNC", ENUM, 1 },
+   { GL_DEPTH_RANGE, "GL_DEPTH_RANGE", FLOAT, 2 },
+   { GL_DEPTH_SCALE, "GL_DEPTH_SCALE", FLOAT, 1 },
+   { GL_DEPTH_TEST, "GL_DEPTH_TEST", ENUM, 1 },
+   { GL_DEPTH_WRITEMASK, "GL_DEPTH_WRITEMASK", BOOLEAN, 1 },
+   { GL_DIFFUSE, "GL_DIFFUSE", ENUM, 0 },  /*XXX*/
+   { GL_DITHER, "GL_DITHER", BOOLEAN, 1 },
+   { GL_DOMAIN, "GL_DOMAIN", ENUM, 0 },
+   { GL_DONT_CARE, "GL_DONT_CARE", ENUM, 0 },
+   { GL_DOUBLE, "GL_DOUBLE", ENUM, 0 },
+   { GL_DOUBLEBUFFER, "GL_DOUBLEBUFFER", BOOLEAN, 1},
+   { GL_DRAW_BUFFER, "GL_DRAW_BUFFER", ENUM, 1 },
+   { GL_DRAW_PIXEL_TOKEN, "GL_DRAW_PIXEL_TOKEN", ENUM, 0 },
+   { GL_DST_ALPHA, "GL_DST_ALPHA", ENUM, 0 },
+   { GL_DST_COLOR, "GL_DST_COLOR", ENUM, 0 },
+
+   { GL_EDGE_FLAG, "GL_EDGE_FLAG", BOOLEAN, 1 },
+   /* XXX GL_EDGE_FLAG_ARRAY_* */
+   { GL_EMISSION, "GL_EMISSION", ENUM, 0 }, /* XXX */
+   { GL_ENABLE_BIT, "GL_ENABLE_BIT", ENUM, 0 },
+   { GL_EQUAL, "GL_EQUAL", ENUM, 0 },
+   { GL_EQUIV, "GL_EQUIV", ENUM, 0 },
+   { GL_EVAL_BIT, "GL_EVAL_BIT", ENUM, 0 },
+   { GL_EXP, "GL_EXP", ENUM, 0 },
+   { GL_EXP2, "GL_EXP2", ENUM, 0 },
+   { GL_EXTENSIONS, "GL_EXTENSIONS", ENUM, 0 },
+   { GL_EYE_LINEAR, "GL_EYE_LINEAR", ENUM, 0 },
+   { GL_EYE_PLANE, "GL_EYE_PLANE", ENUM, 0 },
+
+   { GL_FALSE, "GL_FALSE", ENUM, 0 },
+   { GL_FASTEST, "GL_FASTEST", ENUM, 0 },
+   { GL_FEEDBACK, "GL_FEEDBACK", ENUM, 0 },
+   { GL_FEEDBACK_BUFFER_POINTER, "GL_FEEDBACK_BUFFER_POINTER", VOID, 0 },
+   { GL_FEEDBACK_BUFFER_SIZE, "GL_FEEDBACK_BUFFER_SIZE", INT, 1 },
+   { GL_FEEDBACK_BUFFER_TYPE, "GL_FEEDBACK_BUFFER_TYPE", INT, 1 },
+   { GL_FILL, "GL_FILL", ENUM, 0 },
+   { GL_FLAT, "GL_FLAT", ENUM, 0 },
+   { GL_FLOAT, "GL_FLOAT", ENUM, 0 },
+   { GL_FOG, "GL_FOG", BOOLEAN, 1 },
+   { GL_FOG_BIT, "GL_FOG_BIT", ENUM, 0 },
+   { GL_FOG_COLOR, "GL_FOG_COLOR", FLOAT, 4 },
+   { GL_FOG_DENSITY, "GL_FOG_DENSITY", FLOAT, 1 },
+   { GL_FOG_END, "GL_FOG_END", FLOAT, 1 },
+   { GL_FOG_HINT, "GL_FOG_HINT", ENUM, 1 },
+   { GL_FOG_INDEX, "GL_FOG_INDEX", INT, 1 },
+   { GL_FOG_MODE, "GL_FOG_MODE", ENUM, 1 },
+   { GL_FOG_START, "GL_FOG_START", FLOAT, 1 },
+   { GL_FRONT, "GL_FRONT", ENUM, 0 },
+   { GL_FRONT_AND_BACK, "GL_FRONT_AND_BACK", ENUM, 0 },
+   { GL_FRONT_FACE, "GL_FRONT_FACE", ENUM, 1 },
+   { GL_FRONT_LEFT, "GL_FRONT_LEFT", ENUM, 0 },
+   { GL_FRONT_RIGHT, "GL_FRONT_RIGHT", ENUM, 0 },
+
+   { GL_GEQUAL, "GL_GEQUAL", ENUM, 0 },
+   { GL_GREATER, "GL_GREATER", ENUM, 0 },
+   { GL_GREEN, "GL_GREEN", ENUM, 0 },
+   { GL_GREEN_BIAS, "GL_GREEN_BIAS", FLOAT, 1 },
+   { GL_GREEN_BITS, "GL_GREEN_BITS", INT, 1 },
+   { GL_GREEN_SCALE, "GL_GREEN_SCALE", FLOAT, 1 },
+
+
+
+   { GL_LESS, "GL_LESS", ENUM, 0 },
+   { GL_LEQUAL, "GL_LEQUAL", ENUM, 0 },
+   { GL_LIGHTING, "GL_LIGHTING", BOOLEAN, 1 },
+   { GL_LINE_SMOOTH, "GL_LINE_SMOOTH", BOOLEAN, 1 },
+   { GL_LINE_STIPPLE, "GL_LINE_STIPPLE", BOOLEAN, 1 },
+   { GL_LINE_STIPPLE_PATTERN, "GL_LINE_STIPPLE_PATTERN", INT, 1 },
+   { GL_LINE_STIPPLE_REPEAT, "GL_LINE_STIPPLE_REPEAT", INT, 1 },
+   { GL_LINE_WIDTH, "GL_LINE_WIDTH", FLOAT, 1 },
+
+   { GL_MODELVIEW_MATRIX, "GL_MODELVIEW_MATRIX", DOUBLE, 16 },
+
+   { GL_NEVER, "GL_NEVER", ENUM, 0 },
+   { GL_NOTEQUAL, "GL_NOTEQUAL", ENUM, 0 },
+
+   { GL_PROJECTION_MATRIX, "GL_PROJECTION_MATRIX", FLOAT, 16 },
+
+   { GL_PACK_SWAP_BYTES, "GL_PACK_SWAP_BYTES", INT, 1 },
+   { GL_PACK_LSB_FIRST, "GL_PACK_LSB_FIRST", INT, 1 },
+   { GL_PACK_ROW_LENGTH, "GL_PACK_ROW_LENGTH", INT, 1 },
+   { GL_PACK_SKIP_PIXELS, "GL_PACK_SKIP_PIXELS", INT, 1 },
+   { GL_PACK_SKIP_ROWS, "GL_PACK_SKIP_ROWS", INT, 1 },
+   { GL_PACK_ALIGNMENT, "GL_PACK_ALIGNMENT", INT, 1 },
+
+   { GL_TRUE, "GL_TRUE", ENUM, 0 },
+
+   { GL_UNPACK_SWAP_BYTES, "GL_UNPACK_SWAP_BYTES", INT, 1 },
+   { GL_UNPACK_LSB_FIRST, "GL_UNPACK_LSB_FIRST", INT, 1 },
+   { GL_UNPACK_ROW_LENGTH, "GL_UNPACK_ROW_LENGTH", INT, 1 },
+   { GL_UNPACK_SKIP_PIXELS, "GL_UNPACK_SKIP_PIXELS", INT, 1 },
+   { GL_UNPACK_SKIP_ROWS, "GL_UNPACK_SKIP_ROWS", INT, 1 },
+   { GL_UNPACK_ALIGNMENT, "GL_UNPACK_ALIGNMENT", INT, 1 },
+
+   { GL_VIEWPORT, "GL_VIEWPORT", INT, 4 },
+
+
+   /*
+    * Extensions
+    */
+
+#if defined(GL_EXT_blend_minmax)
+   { GL_BLEND_EQUATION_EXT, "GL_BLEND_EQUATION_EXT", ENUM, 1 },
+#endif
+#if defined(GL_EXT_blend_color)
+   { GL_BLEND_COLOR_EXT, "GL_BLEND_COLOR_EXT", FLOAT, 4 },
+#endif
+#if defined(GL_EXT_point_parameters)
+   { GL_DISTANCE_ATTENUATION_EXT, "GL_DISTANCE_ATTENUATION_EXT", FLOAT, 1 },
+#endif
+#if defined(GL_INGR_blend_func_separate)
+   { GL_BLEND_SRC_RGB_INGR, "GL_BLEND_SRC_RGB_INGR", ENUM, 1 },
+   { GL_BLEND_DST_RGB_INGR, "GL_BLEND_DST_RGB_INGR", ENUM, 1 },
+   { GL_BLEND_SRC_ALPHA_INGR, "GL_BLEND_SRC_ALPHA_INGR", ENUM, 1 },
+   { GL_BLEND_DST_ALPHA_INGR, "GL_BLEND_DST_ALPHA_INGR", ENUM, 1 },
+#endif
+
+
+   { LAST_TOKEN, "", 0, 0 }
+};
+
+
+static const struct EnumRecord *FindRecord( GLenum var )
+{
+   int i;
+   for (i = 0; EnumTable[i].enumerator != LAST_TOKEN; i++) {
+      if (EnumTable[i].enumerator == var) {
+        return &EnumTable[i];
+      }
+   }
+   return NULL;
+}
+
+
+
+/*
+ * Return the string label for the given enum.
+ */
+const char *GetEnumString( GLenum var )
+{
+   const struct EnumRecord *rec = FindRecord(var);
+   if (rec)
+      return rec->string;
+   else
+      return NULL;
+}
+
+
+
+/*
+ * Print current value of the given state variable.
+ */
+void PrintState( int indent, GLenum var )
+{
+   const struct EnumRecord *rec = FindRecord(var);
+
+   while (indent-- > 0)
+      putchar(' ');
+
+   if (rec) {
+      if (rec->getCount <= 0) {
+         assert(rec->getType == ENUM);
+         printf("%s is not a state variable\n", rec->string);
+      }
+      else {
+         switch (rec->getType) {
+             case INT:
+                {
+                   GLint values[100];
+                   int i;
+                   glGetIntegerv(rec->enumerator, values);
+                   printf("%s = ", rec->string);
+                   for (i = 0; i < rec->getCount; i++)
+                      printf("%d ", values[i]);
+                   printf("\n");
+                }
+                break;
+             case FLOAT:
+                {
+                   GLfloat values[100];
+                   int i;
+                   glGetFloatv(rec->enumerator, values);
+                   printf("%s = ", rec->string);
+                   for (i = 0; i < rec->getCount; i++)
+                      printf("%f ", values[i]);
+                   printf("\n");
+                }
+                break;
+             case DOUBLE:
+                {
+                   GLdouble values[100];
+                   int i;
+                   glGetDoublev(rec->enumerator, values);
+                   printf("%s = ", rec->string);
+                   for (i = 0; i < rec->getCount; i++)
+                      printf("%f ", (float) values[i]);
+                   printf("\n");
+                }
+                break;
+             case BOOLEAN:
+                {
+                   GLboolean values[100];
+                   int i;
+                   glGetBooleanv(rec->enumerator, values);
+                   printf("%s = ", rec->string);
+                   for (i = 0; i < rec->getCount; i++)
+                      printf("%s ", values[i] ? "GL_TRUE" : "GL_FALSE");
+                   printf("\n");
+                }
+                break;
+             case ENUM:
+                {
+                   GLint values[100];
+                   int i;
+                   glGetIntegerv(rec->enumerator, values);
+                   printf("%s = ", rec->string);
+                   for (i = 0; i < rec->getCount; i++) {
+                      const char *str = GetEnumString((GLenum) values[i]);
+                      if (str)
+                         printf("%s ", str);
+                      else
+                         printf("??? ");
+                   }
+                   printf("\n");
+                }
+                break;
+             case VOID:
+                {
+                   GLvoid *values[100];
+                   int i;
+                   glGetPointerv(rec->enumerator, values);
+                   printf("%s = ", rec->string);
+                   for (i = 0; i < rec->getCount; i++) {
+                      printf("%p ", values[i]);
+                   }
+                   printf("\n");
+                }
+                break;
+             default:
+                printf("fatal error in PrintState()\n");
+                abort();
+         }
+      }
+   }
+   else {
+      printf("Unknown GLenum passed to PrintState()\n");
+   }
+}
+
+
+
+/*
+ * Print all glPixelStore-related state.
+ * NOTE: Should write similar functions for lighting, texturing, etc.
+ */
+void PrintPixelStoreState( void )
+{
+   const GLenum enums[] = {
+      GL_PACK_SWAP_BYTES,
+      GL_PACK_LSB_FIRST,
+      GL_PACK_ROW_LENGTH,
+      GL_PACK_SKIP_PIXELS,
+      GL_PACK_SKIP_ROWS,
+      GL_PACK_ALIGNMENT,
+      GL_UNPACK_SWAP_BYTES,
+      GL_UNPACK_LSB_FIRST,
+      GL_UNPACK_ROW_LENGTH,
+      GL_UNPACK_SKIP_PIXELS,
+      GL_UNPACK_SKIP_ROWS,
+      GL_UNPACK_ALIGNMENT,
+      0
+   };
+   int i;
+   printf("Pixel pack/unpack state:\n");
+   for (i = 0; enums[i]; i++) {
+      PrintState(3, enums[i]);
+   }
+}
+
+
+
+
+/*
+ * Print all state for the given attribute group.
+ */
+void PrintAttribState( GLbitfield attrib )
+{
+   static const GLenum depth_buffer_enums[] = {
+      GL_DEPTH_FUNC,
+      GL_DEPTH_CLEAR_VALUE,
+      GL_DEPTH_TEST,
+      GL_DEPTH_WRITEMASK,
+      0
+   };
+   static const GLenum fog_enums[] = {
+      GL_FOG,
+      GL_FOG_COLOR,
+      GL_FOG_DENSITY,
+      GL_FOG_START,
+      GL_FOG_END,
+      GL_FOG_INDEX,
+      GL_FOG_MODE,
+      0
+   };
+   static const GLenum line_enums[] = {
+      GL_LINE_SMOOTH,
+      GL_LINE_STIPPLE,
+      GL_LINE_STIPPLE_PATTERN,
+      GL_LINE_STIPPLE_REPEAT,
+      GL_LINE_WIDTH,
+      0
+   };
+
+   const GLenum *enumList = NULL;
+
+   switch (attrib) {
+      case GL_DEPTH_BUFFER_BIT:
+         enumList = depth_buffer_enums;
+         printf("GL_DEPTH_BUFFER_BIT state:\n");
+         break;
+      case GL_FOG_BIT:
+         enumList = fog_enums;
+         printf("GL_FOG_BIT state:\n");
+         break;
+      case GL_LINE_BIT:
+         enumList = line_enums;
+         printf("GL_LINE_BIT state:\n");
+         break;
+      default:
+         printf("Bad value in PrintAttribState()\n");
+   }
+
+   if (enumList) {
+      int i;
+      for (i = 0; enumList[i]; i++)
+         PrintState(3, enumList[i]);
+   }
+}
+
+
+/*#define TEST*/
+#ifdef TEST
+
+#include <GL/glut.h>
+
+int main( int argc, char *argv[] )
+{
+   glutInit( &argc, argv );
+   glutInitWindowPosition(0, 0);
+   glutInitWindowSize(400, 300);
+   glutInitDisplayMode(GLUT_RGB);
+   glutCreateWindow(argv[0]);
+   PrintAttribState(GL_DEPTH_BUFFER_BIT);
+   PrintAttribState(GL_FOG_BIT);
+   PrintAttribState(GL_LINE_BIT);
+   PrintState(0, GL_ALPHA_BITS);
+   PrintState(0, GL_VIEWPORT);
+   PrintState(0, GL_ALPHA_TEST_FUNC);
+   PrintState(0, GL_MODELVIEW_MATRIX);
+   PrintState(0, GL_ALWAYS);
+   PrintPixelStoreState();
+   return 0;
+}
+
+#endif
diff --git a/progs/util/glstate.h b/progs/util/glstate.h
new file mode 100644 (file)
index 0000000..1aa4d21
--- /dev/null
@@ -0,0 +1,53 @@
+/* $Id: glstate.h,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
+
+/*
+ * Print GL state information (for debugging)
+ * Copyright (C) 1998  Brian Paul
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/*
+ * $Log: glstate.h,v $
+ * Revision 1.1  1999/08/19 00:55:42  jtg
+ * Initial revision
+ *
+ * Revision 1.2  1999/06/19 01:36:43  brianp
+ * more features added
+ *
+ * Revision 1.1  1998/11/24 03:41:16  brianp
+ * Initial revision
+ *
+ */
+
+
+#ifndef GLSTATE_H
+#define GLSTATE_H
+
+
+#include <GL/gl.h>
+
+
+extern const char *GetNameString( GLenum var );
+
+extern void PrintState( int indent, GLenum var );
+
+extern void PrintAttribState( GLbitfield attrib );
+
+extern void PrintPixelStoreState( void );
+
+
+#endif
diff --git a/progs/util/glutskel.c b/progs/util/glutskel.c
new file mode 100644 (file)
index 0000000..8c283f8
--- /dev/null
@@ -0,0 +1,145 @@
+/* $Id: glutskel.c,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
+
+/*
+ * A skeleton/template GLUT program
+ *
+ * Written by Brian Paul and in the public domain.
+ */
+
+
+/*
+ * $Log: glutskel.c,v $
+ * Revision 1.1  1999/08/19 00:55:42  jtg
+ * Initial revision
+ *
+ * Revision 1.2  1998/11/07 14:20:14  brianp
+ * added simple rotation, animation of cube
+ *
+ * Revision 1.1  1998/11/07 14:14:37  brianp
+ * Initial revision
+ *
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <GL/glut.h>
+
+
+static GLfloat Xrot = 0, Yrot = 0, Zrot = 0;
+static GLboolean Anim = GL_FALSE;
+
+
+static void Idle( void )
+{
+   Xrot += 3.0;
+   Yrot += 4.0;
+   Zrot += 2.0;
+   glutPostRedisplay();
+}
+
+
+static void Display( void )
+{
+   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+
+   glPushMatrix();
+   glRotatef(Xrot, 1, 0, 0);
+   glRotatef(Yrot, 0, 1, 0);
+   glRotatef(Zrot, 0, 0, 1);
+
+   glutSolidCube(2.0);
+
+   glPopMatrix();
+
+   glutSwapBuffers();
+}
+
+
+static void Reshape( int width, int height )
+{
+   glViewport( 0, 0, width, height );
+   glMatrixMode( GL_PROJECTION );
+   glLoadIdentity();
+   glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 25.0 );
+   glMatrixMode( GL_MODELVIEW );
+   glLoadIdentity();
+   glTranslatef( 0.0, 0.0, -15.0 );
+}
+
+
+static void Key( unsigned char key, int x, int y )
+{
+   const GLfloat step = 3.0;
+   (void) x;
+   (void) y;
+   switch (key) {
+      case 'a':
+         Anim = !Anim;
+         if (Anim)
+            glutIdleFunc(Idle);
+         else
+            glutIdleFunc(NULL);
+         break;
+      case 'z':
+         Zrot -= step;
+         break;
+      case 'Z':
+         Zrot += step;
+         break;
+      case 27:
+         exit(0);
+         break;
+   }
+   glutPostRedisplay();
+}
+
+
+static void SpecialKey( int key, int x, int y )
+{
+   const GLfloat step = 3.0;
+   (void) x;
+   (void) y;
+   switch (key) {
+      case GLUT_KEY_UP:
+         Xrot -= step;
+         break;
+      case GLUT_KEY_DOWN:
+         Xrot += step;
+         break;
+      case GLUT_KEY_LEFT:
+         Yrot -= step;
+         break;
+      case GLUT_KEY_RIGHT:
+         Yrot += step;
+         break;
+   }
+   glutPostRedisplay();
+}
+
+
+static void Init( void )
+{
+   /* setup lighting, etc */
+   glEnable(GL_DEPTH_TEST);
+   glEnable(GL_LIGHTING);
+   glEnable(GL_LIGHT0);
+}
+
+
+int main( int argc, char *argv[] )
+{
+   glutInit( &argc, argv );
+   glutInitWindowPosition( 0, 0 );
+   glutInitWindowSize( 400, 400 );
+   glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
+   glutCreateWindow(argv[0]);
+   glutReshapeFunc( Reshape );
+   glutKeyboardFunc( Key );
+   glutSpecialFunc( SpecialKey );
+   glutDisplayFunc( Display );
+   Init();
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/util/idproj.c b/progs/util/idproj.c
new file mode 100644 (file)
index 0000000..d5ee340
--- /dev/null
@@ -0,0 +1,26 @@
+/* idproj.c */
+
+
+/*
+ * Setup an identity projection such that glVertex(x,y) maps to
+ * window coordinate (x,y).
+ *
+ * Written by Brian Paul and in the public domain.
+ */
+
+
+
+
+
+void IdentityProjection( GLint x, GLint y, GLsizei width, GLsizei height )
+{
+   glViewport( x, y, width, height );
+   glMatrixMode( GL_PROJECTION );
+   glLoadIdentity();
+   glOrtho( (GLdouble) x, (GLdouble) y,
+            (GLdouble) width, (GLdouble) height,
+            -1.0, 1.0 );
+   glMatrixMode( GL_MODELVIEW );
+   glLoadIdentity();
+}
+
diff --git a/progs/util/imagesgi.cpp b/progs/util/imagesgi.cpp
new file mode 100644 (file)
index 0000000..f5128aa
--- /dev/null
@@ -0,0 +1,369 @@
+/******************************************************************************
+** Filename       : imageSgi.cpp
+**                  UNCLASSIFIED
+**
+** Description    : Utility to read SGI image format files.  This code was
+**                  originally a SGI image loading utility provided with the
+**                  Mesa 3D library @ http://www.mesa3d.org by Brain Paul.
+**                  This has been extended to read all SGI image formats
+**                  (e.g. INT, INTA, RGB, RGBA).
+**
+** Revision History:
+**   Date       Name   Description
+**   06/07/99   BRC    Initial Release
+**
+** Note:
+**
+** The SGI Image Data (if not RLE)
+**
+**   If the image is stored verbatim (without RLE), then image data directly
+**   follows the 512 byte header.  The data for each scanline of the first
+**   channel is written first.  If the image has more than 1 channel, all
+**   the data for the first channel is written, followed by the remaining
+**   channels.  If the BPC value is 1, then each scanline is written as XSIZE
+**   bytes.  If the BPC value is 2, then each scanline is written as XSIZE
+**   shorts.  These shorts are stored in the byte order described above.
+**
+******************************************************************************/
+#define __IMAGESGI_CPP
+
+#include "imagesgi.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <assert.h>
+
+struct sImageSgiRaw
+{
+   struct sImageSgiHeader header;
+   unsigned char *chan0;
+   unsigned char *chan1;
+   unsigned char *chan2;
+   unsigned char *chan3;
+   unsigned int *rowStart;
+   int *rowSize;
+};
+
+// Static routines
+static struct sImageSgiRaw *ImageSgiRawOpen(char const * const fileName);
+static void ImageSgiRawClose(struct sImageSgiRaw *raw);
+static void ImageSgiRawGetRow(struct sImageSgiRaw *raw, unsigned char *buf,
+   int y, int z);
+static void ImageSgiRawGetData(struct sImageSgiRaw *raw, struct sImageSgi 
+*final);
+static void *SwitchEndian16(void *value);
+static void *SwitchEndian32(void *value);
+
+// Static variables
+FILE *mFp = NULL;
+unsigned char *mChanTmp = NULL;
+
+
+/*****************************************************************************/
+struct sImageSgi *ImageSgiOpen(char const * const fileName)
+{
+   struct sImageSgiRaw *raw = NULL;
+   struct sImageSgi *final = NULL;
+
+   raw = ImageSgiRawOpen(fileName);
+   final = new struct sImageSgi;
+
+   assert(final);
+   if(final)
+   {
+      final->header = raw->header;
+      final->data = NULL;
+      ImageSgiRawGetData(raw, final);
+      ImageSgiRawClose(raw);
+   }
+
+   return final;
+} // ImageSgiRawOpen
+
+
+/*****************************************************************************/
+void ImageSgiClose(struct sImageSgi *image)
+{
+
+   if(image)
+   {
+      if(image->data)
+         delete[] image->data;
+      image->data = NULL;
+      delete image;
+   }
+   image = NULL;
+
+   return;
+} // ImageSgiClose
+
+
+/*****************************************************************************/
+static struct sImageSgiRaw *ImageSgiRawOpen(char const * const fileName)
+{
+   struct sImageSgiRaw *raw = NULL;
+   int x;
+   int i;
+   bool swapFlag = false;
+   union
+   {
+      int testWord;
+      char testByte[4];
+   } endianTest;
+   endianTest.testWord = 1;
+
+   // Determine endianess of platform.
+   if(endianTest.testByte[0] == 1)
+      swapFlag = true;
+   else
+      swapFlag = false;
+
+   raw = new struct sImageSgiRaw;
+
+   assert(raw);
+   if(raw)
+   {
+      raw->chan0 = NULL;
+      raw->chan1 = NULL;
+      raw->chan2 = NULL;
+      raw->chan3 = NULL;
+      raw->rowStart = NULL;
+      raw->rowSize = NULL;
+      mFp = fopen(fileName, "rb");
+      assert(mFp);
+
+      fread(&raw->header, sizeof(struct sImageSgiHeader), 1, mFp);
+      if(swapFlag == true)
+      {
+         SwitchEndian16(&raw->header.magic);
+         SwitchEndian16(&raw->header.type);
+         SwitchEndian16(&raw->header.dim);
+         SwitchEndian16(&raw->header.xsize);
+         SwitchEndian16(&raw->header.ysize);
+         SwitchEndian16(&raw->header.zsize);
+      }
+
+      mChanTmp = new unsigned char[raw->header.xsize * raw->header.ysize];
+      assert(mChanTmp);
+      switch(raw->header.zsize)
+      {
+      case 4:
+         raw->chan3 = new unsigned char[raw->header.xsize * 
+raw->header.ysize];
+         assert(raw->chan3);
+      case 3:
+         raw->chan2 = new unsigned char[raw->header.xsize * 
+raw->header.ysize];
+         assert(raw->chan2);
+      case 2:
+         raw->chan1 = new unsigned char[raw->header.xsize * 
+raw->header.ysize];
+         assert(raw->chan1);
+      case 1:
+         raw->chan0 = new unsigned char[raw->header.xsize * 
+raw->header.ysize];
+         assert(raw->chan0);
+      }
+
+      if(raw->header.type == IMAGE_SGI_TYPE_RLE)
+      {
+         x = raw->header.ysize * raw->header.zsize * sizeof(unsigned int);
+         raw->rowStart = new unsigned int[x];
+         raw->rowSize = new int[x];
+
+         fseek(mFp, sizeof(struct sImageSgiHeader), SEEK_SET);
+         fread(raw->rowStart, 1, x, mFp);
+         fread(raw->rowSize, 1, x, mFp);
+
+         if(swapFlag == true)
+         {
+            for(i=0; i<x/sizeof(unsigned int); i++)
+               SwitchEndian32(&raw->rowStart[i]);
+            for(i=0; i<x/sizeof(int); i++)
+               SwitchEndian32(&raw->rowSize[i]);
+         }
+
+      }
+
+   }
+
+   return raw;
+} // ImageSgiRawOpen
+
+
+/*****************************************************************************/
+static void ImageSgiRawClose(struct sImageSgiRaw *raw)
+{
+
+   fclose(mFp);
+   mFp = NULL;
+
+   if(mChanTmp)
+      delete[] mChanTmp;
+   mChanTmp = NULL;
+
+   if(raw->chan0)
+      delete[] raw->chan0;
+   raw->chan0 = NULL;
+
+   if(raw->chan1)
+      delete[] raw->chan1;
+   raw->chan1 = NULL;
+
+   if(raw->chan2)
+      delete[] raw->chan2;
+   raw->chan2 = NULL;
+
+   if(raw->chan3)
+      delete[] raw->chan3;
+   raw->chan3 = NULL;
+
+   if(raw)
+      delete raw;
+   raw = NULL;
+
+   return;
+} // ImageSgiRawClose
+
+
+/*****************************************************************************/
+static void ImageSgiRawGetRow(struct sImageSgiRaw *raw, unsigned char *buf,
+   int y, int z)
+{
+   unsigned char *iPtr = NULL;
+   unsigned char *oPtr = NULL;
+   unsigned char pixel;
+   int count;
+
+   if((raw->header.type & 0xFF00) == 0x0100)
+   {
+      fseek(mFp, raw->rowStart[y+z*raw->header.ysize], SEEK_SET);
+      fread(mChanTmp, 1, (unsigned int)raw->rowSize[y+z*raw->header.ysize], 
+mFp);
+      iPtr = mChanTmp;
+      oPtr = buf;
+      while(1)
+      {
+         pixel = *iPtr++;
+         count = (int)(pixel & 0x7F);
+         if(!count)
+         {
+            return;
+         }
+         if (pixel & 0x80)
+         {
+            while (count--)
+            {
+               *oPtr++ = *iPtr++;
+            }
+         }
+         else
+         {
+            pixel = *iPtr++;
+            while (count--)
+            {
+               *oPtr++ = pixel;
+            }
+         }
+      }
+   }
+   else
+   {
+      fseek(mFp,
+         sizeof(struct sImageSgiHeader)+(y*raw->header.xsize) +
+            (z*raw->header.xsize*raw->header.ysize),
+         SEEK_SET);
+      fread(buf, 1, raw->header.xsize, mFp);
+   }
+
+   return;
+} // ImageSgiRawGetRow
+
+
+/*****************************************************************************/
+static void ImageSgiRawGetData(struct sImageSgiRaw *raw, struct sImageSgi 
+*final)
+{
+   unsigned char *ptr = NULL;
+   int i, j;
+
+   final->data =
+      new unsigned 
+char[raw->header.xsize*raw->header.ysize*raw->header.zsize];
+   assert(final->data);
+
+   ptr = final->data;
+   for(i=0; i<raw->header.ysize; i++)
+   {
+      switch(raw->header.zsize)
+      {
+      case 1:
+         ImageSgiRawGetRow(raw, raw->chan0, i, 0);
+         for(j=0; j<raw->header.xsize; j++)
+            *(ptr++) = raw->chan0[j];
+         break;
+      case 2:
+         ImageSgiRawGetRow(raw, raw->chan0, i, 0);
+         ImageSgiRawGetRow(raw, raw->chan1, i, 1);
+         for(j=0; j<raw->header.xsize; j++)
+         {
+            *(ptr++) = raw->chan0[j];
+            *(ptr++) = raw->chan1[j];
+         }
+         break;
+      case 3:
+         ImageSgiRawGetRow(raw, raw->chan0, i, 0);
+         ImageSgiRawGetRow(raw, raw->chan1, i, 1);
+         ImageSgiRawGetRow(raw, raw->chan2, i, 2);
+         for(j=0; j<raw->header.xsize; j++)
+         {
+            *(ptr++) = raw->chan0[j];
+            *(ptr++) = raw->chan1[j];
+            *(ptr++) = raw->chan2[j];
+         }
+         break;
+      case 4:
+         ImageSgiRawGetRow(raw, raw->chan0, i, 0);
+         ImageSgiRawGetRow(raw, raw->chan1, i, 1);
+         ImageSgiRawGetRow(raw, raw->chan2, i, 2);
+         ImageSgiRawGetRow(raw, raw->chan3, i, 3);
+         for(j=0; j<raw->header.xsize; j++)
+         {
+            *(ptr++) = raw->chan0[j];
+            *(ptr++) = raw->chan1[j];
+            *(ptr++) = raw->chan2[j];
+            *(ptr++) = raw->chan3[j];
+         }
+         break;
+      }
+   }
+
+   return;
+} // ImageSgiRawGetData
+
+
+/*****************************************************************************/
+static void *SwitchEndian16(void *value)
+{
+   short value16 = *(short *) value;
+   value16 = ((value16 & 0xff00) >> 8L) +
+             ((value16 & 0x00ff) << 8L);
+   *(short *)value = value16;
+   return value;
+} // SwitchEndian16
+
+
+/*****************************************************************************/
+static void *SwitchEndian32(void *value)
+{
+   int value32 = *(int *) value;
+   value32 = ((value32 & 0xff000000) >> 24L) +
+             ((value32 & 0x00ff0000) >> 8)   +
+             ((value32 & 0x0000ff00) << 8)   +
+             ((value32 & 0x000000ff) << 24L);
+   *(int *)value = value32;
+   return value;
+} // SwitchEndian32
+
diff --git a/progs/util/imagesgi.h b/progs/util/imagesgi.h
new file mode 100644 (file)
index 0000000..e5ecece
--- /dev/null
@@ -0,0 +1,55 @@
+/******************************************************************************
+** Filename       : imageSgi.h
+**                  UNCLASSIFIED
+**
+** Description    : Utility to read SGI image format files.  This code was
+**                  originally a SGI image loading utility provided with the
+**                  Mesa 3D library @ http://www.mesa3d.org by Brain Paul.
+**                  This has been extended to read all SGI image formats
+**                  (e.g. INT, INTA, RGB, RGBA).
+**
+** Revision History:
+**   Date       Name   Description
+**   06/08/99   BRC    Initial Release
+**
+******************************************************************************/
+
+#ifndef __IMAGESGI_H
+#define __IMAGESGI_H
+
+#define IMAGE_SGI_TYPE_VERBATIM 0
+#define IMAGE_SGI_TYPE_RLE      1
+
+struct sImageSgiHeader          // 512 bytes
+{
+  short magic;                  // IRIS image file magic number (474)
+  char type;                    // Storage format (e.g. RLE or VERBATIM)
+  char numBytesPerPixelChannel; // Number of bytes per pixel channel
+  unsigned short dim;           // Number of dimensions (1 to 3)
+  unsigned short xsize;         // Width (in pixels)
+  unsigned short ysize;         // Height (in pixels)
+  unsigned short zsize;         // Number of channels (1 to 4)
+  int minimumPixelValue;        // Minimum pixel value (0 to 255)
+  int maximumPixelValue;        // Maximum pixel value (0 to 255)
+  char padding1[4];             // (ignored)
+  char imageName[80];           // Image name
+  int colormap;                 // colormap ID (0=normal, 0=dithered,
+                                // 2=screen, 3=colormap)
+  char padding2[404];           // (ignored)
+};
+
+struct sImageSgi
+{
+   struct sImageSgiHeader header;
+   unsigned char *data;
+};
+
+#ifndef __IMAGESGI_CPP
+
+// RGB image load utility
+extern struct sImageSgi *ImageSgiOpen(char const * const fileName);
+extern void ImageSgiClose(struct sImageSgi *image);
+
+#endif
+
+#endif /* __IMAGESGI_H */
diff --git a/progs/util/mwmborder.c b/progs/util/mwmborder.c
new file mode 100644 (file)
index 0000000..b61ffb5
--- /dev/null
@@ -0,0 +1,91 @@
+/* mwmborder.c */
+
+
+/*
+ * This function shows how to remove the border, title bar, resize button,
+ * etc from a Motif window frame from inside an Xlib-based application.
+ *
+ * Brian Paul  19 Sep 1995   brianp@ssec.wisc.edu
+ *
+ * This code is in the public domain.
+ */
+
+
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+
+#define HAVE_MOTIF
+#ifdef HAVE_MOTIF
+
+#include <X11/Xm/MwmUtil.h>
+
+#else
+
+/* bit definitions for MwmHints.flags */
+#define MWM_HINTS_FUNCTIONS     (1L << 0)
+#define MWM_HINTS_DECORATIONS   (1L << 1)
+#define MWM_HINTS_INPUT_MODE    (1L << 2)
+#define MWM_HINTS_STATUS        (1L << 3)
+
+/* bit definitions for MwmHints.decorations */
+#define MWM_DECOR_ALL           (1L << 0)
+#define MWM_DECOR_BORDER        (1L << 1)
+#define MWM_DECOR_RESIZEH       (1L << 2)
+#define MWM_DECOR_TITLE         (1L << 3)
+#define MWM_DECOR_MENU          (1L << 4)
+#define MWM_DECOR_MINIMIZE      (1L << 5)
+#define MWM_DECOR_MAXIMIZE      (1L << 6)
+
+typedef struct
+{
+    unsigned long       flags;
+    unsigned long       functions;
+    unsigned long       decorations;
+    long                inputMode;
+    unsigned long       status;
+} PropMotifWmHints;
+
+#define PROP_MOTIF_WM_HINTS_ELEMENTS    5
+
+#endif
+
+
+
+/*
+ * Specify which Motif window manager border decorations to put on a
+ * top-level window.  For example, you can specify that a window is not
+ * resizabe, or omit the titlebar, or completely remove all decorations.
+ * Input:  dpy - the X display
+ *         w - the X window
+ *         flags - bitwise-OR of the MWM_DECOR_xxx symbols in X11/Xm/MwmUtil.h
+ *                 indicating what decoration elements to enable.  Zero would
+ *                 be no decoration.
+ */
+void set_mwm_border( Display *dpy, Window w, unsigned long flags )
+{
+   PropMotifWmHints motif_hints;
+   Atom prop, proptype;
+
+   /* setup the property */
+   motif_hints.flags = MWM_HINTS_DECORATIONS;
+   motif_hints.decorations = flags;
+
+   /* get the atom for the property */
+   prop = XInternAtom( dpy, "_MOTIF_WM_HINTS", True );
+   if (!prop) {
+      /* something went wrong! */
+      return;
+   }
+
+   /* not sure this is correct, seems to work, XA_WM_HINTS didn't work */
+   proptype = prop;
+
+   XChangeProperty( dpy, w,                         /* display, window */
+                    prop, proptype,                 /* property, type */
+                    32,                             /* format: 32-bit datums */
+                    PropModeReplace,                /* mode */
+                    (unsigned char *) &motif_hints, /* data */
+                    PROP_MOTIF_WM_HINTS_ELEMENTS    /* nelements */
+                  );
+}
+
diff --git a/progs/util/readtex.c b/progs/util/readtex.c
new file mode 100644 (file)
index 0000000..7799416
--- /dev/null
@@ -0,0 +1,353 @@
+/* readtex.c */
+
+/*
+ * Read an SGI .rgb image file and generate a mipmap texture set.
+ * Much of this code was borrowed from SGI's tk OpenGL toolkit.
+ */
+
+
+
+#include <GL/gl.h>
+#include <GL/glu.h>
+#include <stdio.h>
+#include <stdlib.h> 
+#include <string.h>
+
+
+#ifndef SEEK_SET
+#  define SEEK_SET 0
+#endif
+
+
+/*
+** RGB Image Structure
+*/
+
+typedef struct _TK_RGBImageRec {
+   GLint sizeX, sizeY;
+   GLint components;
+   unsigned char *data;
+} TK_RGBImageRec;
+
+
+
+/******************************************************************************/
+
+typedef struct _rawImageRec {
+    unsigned short imagic;
+    unsigned short type;
+    unsigned short dim;
+    unsigned short sizeX, sizeY, sizeZ;
+    unsigned long min, max;
+    unsigned long wasteBytes;
+    char name[80];
+    unsigned long colorMap;
+    FILE *file;
+    unsigned char *tmp, *tmpR, *tmpG, *tmpB, *tmpA;
+    unsigned long rleEnd;
+    GLuint *rowStart;
+    GLint *rowSize;
+} rawImageRec;
+
+/******************************************************************************/
+
+static void ConvertShort(unsigned short *array, long length)
+{
+   unsigned long b1, b2;
+   unsigned char *ptr;
+
+   ptr = (unsigned char *)array;
+   while (length--) {
+      b1 = *ptr++;
+      b2 = *ptr++;
+      *array++ = (unsigned short) ((b1 << 8) | (b2));
+   }
+}
+
+static void ConvertLong(GLuint *array, long length)
+{
+   unsigned long b1, b2, b3, b4;
+   unsigned char *ptr;
+
+   ptr = (unsigned char *)array;
+   while (length--) {
+      b1 = *ptr++;
+      b2 = *ptr++;
+      b3 = *ptr++;
+      b4 = *ptr++;
+      *array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4);
+   }
+}
+
+static rawImageRec *RawImageOpen(const char *fileName)
+{
+   union {
+      int testWord;
+      char testByte[4];
+   } endianTest;
+   rawImageRec *raw;
+   GLenum swapFlag;
+   int x;
+
+   endianTest.testWord = 1;
+   if (endianTest.testByte[0] == 1) {
+      swapFlag = GL_TRUE;
+   } else {
+      swapFlag = GL_FALSE;
+   }
+
+   raw = (rawImageRec *)malloc(sizeof(rawImageRec));
+   if (raw == NULL) {
+      fprintf(stderr, "Out of memory!\n");
+      return NULL;
+   }
+   if ((raw->file = fopen(fileName, "rb")) == NULL) {
+      perror(fileName);
+      return NULL;
+   }
+
+   fread(raw, 1, 12, raw->file);
+
+   if (swapFlag) {
+      ConvertShort(&raw->imagic, 6);
+   }
+
+   raw->tmp = (unsigned char *)malloc(raw->sizeX*256);
+   raw->tmpR = (unsigned char *)malloc(raw->sizeX*256);
+   raw->tmpG = (unsigned char *)malloc(raw->sizeX*256);
+   raw->tmpB = (unsigned char *)malloc(raw->sizeX*256);
+   if (raw->sizeZ==4) {
+      raw->tmpA = (unsigned char *)malloc(raw->sizeX*256);
+   }
+   if (raw->tmp == NULL || raw->tmpR == NULL || raw->tmpG == NULL ||
+       raw->tmpB == NULL) {
+      fprintf(stderr, "Out of memory!\n");
+      return NULL;
+   }
+
+   if ((raw->type & 0xFF00) == 0x0100) {
+      x = raw->sizeY * raw->sizeZ * sizeof(GLuint);
+      raw->rowStart = (GLuint *)malloc(x);
+      raw->rowSize = (GLint *)malloc(x);
+      if (raw->rowStart == NULL || raw->rowSize == NULL) {
+         fprintf(stderr, "Out of memory!\n");
+         return NULL;
+      }
+      raw->rleEnd = 512 + (2 * x);
+      fseek(raw->file, 512, SEEK_SET);
+      fread(raw->rowStart, 1, x, raw->file);
+      fread(raw->rowSize, 1, x, raw->file);
+      if (swapFlag) {
+         ConvertLong(raw->rowStart, (long) (x/sizeof(GLuint)));
+         ConvertLong((GLuint *)raw->rowSize, (long) (x/sizeof(GLint)));
+      }
+   }
+   return raw;
+}
+
+static void RawImageClose(rawImageRec *raw)
+{
+
+   fclose(raw->file);
+   free(raw->tmp);
+   free(raw->tmpR);
+   free(raw->tmpG);
+   free(raw->tmpB);
+   if (raw->sizeZ>3) {
+      free(raw->tmpA);
+   }
+   free(raw);
+}
+
+static void RawImageGetRow(rawImageRec *raw, unsigned char *buf, int y, int z)
+{
+   unsigned char *iPtr, *oPtr, pixel;
+   int count, done = 0;
+
+   if ((raw->type & 0xFF00) == 0x0100) {
+      fseek(raw->file, (long) raw->rowStart[y+z*raw->sizeY], SEEK_SET);
+      fread(raw->tmp, 1, (unsigned int)raw->rowSize[y+z*raw->sizeY],
+            raw->file);
+      
+      iPtr = raw->tmp;
+      oPtr = buf;
+      while (!done) {
+         pixel = *iPtr++;
+         count = (int)(pixel & 0x7F);
+         if (!count) {
+                        done = 1;
+            return;
+         }
+         if (pixel & 0x80) {
+            while (count--) {
+               *oPtr++ = *iPtr++;
+            }
+         } else {
+            pixel = *iPtr++;
+            while (count--) {
+               *oPtr++ = pixel;
+            }
+         }
+      }
+   } else {
+      fseek(raw->file, 512+(y*raw->sizeX)+(z*raw->sizeX*raw->sizeY),
+            SEEK_SET);
+      fread(buf, 1, raw->sizeX, raw->file);
+   }
+}
+
+
+static void RawImageGetData(rawImageRec *raw, TK_RGBImageRec *final)
+{
+   unsigned char *ptr;
+   int i, j;
+
+   final->data = (unsigned char *)malloc((raw->sizeX+1)*(raw->sizeY+1)*4);
+   if (final->data == NULL) {
+      fprintf(stderr, "Out of memory!\n");
+   }
+
+   ptr = final->data;
+   for (i = 0; i < (int)(raw->sizeY); i++) {
+      RawImageGetRow(raw, raw->tmpR, i, 0);
+      RawImageGetRow(raw, raw->tmpG, i, 1);
+      RawImageGetRow(raw, raw->tmpB, i, 2);
+      if (raw->sizeZ>3) {
+         RawImageGetRow(raw, raw->tmpA, i, 3);
+      }
+      for (j = 0; j < (int)(raw->sizeX); j++) {
+         *ptr++ = *(raw->tmpR + j);
+         *ptr++ = *(raw->tmpG + j);
+         *ptr++ = *(raw->tmpB + j);
+         if (raw->sizeZ>3) {
+            *ptr++ = *(raw->tmpA + j);
+         }
+      }
+   }
+}
+
+
+static TK_RGBImageRec *tkRGBImageLoad(const char *fileName)
+{
+   rawImageRec *raw;
+   TK_RGBImageRec *final;
+
+   raw = RawImageOpen(fileName);
+   if (!raw) {
+      fprintf(stderr, "File not found\n");
+      return NULL;
+   }
+   final = (TK_RGBImageRec *)malloc(sizeof(TK_RGBImageRec));
+   if (final == NULL) {
+      fprintf(stderr, "Out of memory!\n");
+      return NULL;
+   }
+   final->sizeX = raw->sizeX;
+   final->sizeY = raw->sizeY;
+   final->components = raw->sizeZ;
+   RawImageGetData(raw, final);
+   RawImageClose(raw);
+   return final;
+}
+
+
+static void FreeImage( TK_RGBImageRec *image )
+{
+   free(image->data);
+   free(image);
+}
+
+
+/*
+ * Load an SGI .rgb file and generate a set of 2-D mipmaps from it.
+ * Input:  imageFile - name of .rgb to read
+ *         intFormat - internal texture format to use, or number of components
+ * Return:  GL_TRUE if success, GL_FALSE if error.
+ */
+GLboolean LoadRGBMipmaps( const char *imageFile, GLint intFormat )
+{
+   GLint error;
+   GLenum format;
+   TK_RGBImageRec *image;
+
+   image = tkRGBImageLoad( imageFile );
+   if (!image) {
+      return GL_FALSE;
+   }
+
+   if (image->components==3) {
+      format = GL_RGB;
+   }
+   else if (image->components==4) {
+      format = GL_RGBA;
+   }
+   else {
+      /* not implemented */
+      fprintf(stderr,
+              "Error in LoadRGBMipmaps %d-component images not implemented\n",
+              image->components );
+      return GL_FALSE;
+   }
+
+   error = gluBuild2DMipmaps( GL_TEXTURE_2D,
+                              intFormat,
+                              image->sizeX, image->sizeY,
+                              format,
+                              GL_UNSIGNED_BYTE,
+                              image->data );
+
+   FreeImage(image);
+   return error ? GL_FALSE : GL_TRUE;
+}
+
+
+
+/*
+ * Load an SGI .rgb file and return a pointer to the image data.
+ * Input:  imageFile - name of .rgb to read
+ * Output:  width - width of image
+ *          height - height of image
+ *          format - format of image (GL_RGB or GL_RGBA)
+ * Return:  pointer to image data or NULL if error
+ */
+GLubyte *LoadRGBImage( const char *imageFile, GLint *width, GLint *height,
+                       GLenum *format )
+{
+   TK_RGBImageRec *image;
+   GLint bytes;
+   GLubyte *buffer;
+
+   image = tkRGBImageLoad( imageFile );
+   if (!image) {
+      return NULL;
+   }
+
+   if (image->components==3) {
+      *format = GL_RGB;
+   }
+   else if (image->components==4) {
+      *format = GL_RGBA;
+   }
+   else {
+      /* not implemented */
+      fprintf(stderr,
+              "Error in LoadRGBImage %d-component images not implemented\n",
+              image->components );
+      return NULL;
+   }
+
+   *width = image->sizeX;
+   *height = image->sizeY;
+
+   bytes = image->sizeX * image->sizeY * image->components;
+   buffer = (GLubyte *) malloc(bytes);
+   if (!buffer)
+      return NULL;
+
+   memcpy( (void *) buffer, (void *) image->data, bytes );
+
+   FreeImage(image);
+
+   return buffer;
+}
+
diff --git a/progs/util/sampleMakefile b/progs/util/sampleMakefile
new file mode 100644 (file)
index 0000000..ebb57ff
--- /dev/null
@@ -0,0 +1,49 @@
+# $Id: sampleMakefile,v 1.1 1999/08/19 00:55:42 jtg Exp $
+
+# Sample makefile for compiling OpenGL/Mesa applications on Unix.
+# This example assumes Linux with gcc.
+
+# This makefile is in the public domain
+
+# $Log: sampleMakefile,v $
+# Revision 1.1  1999/08/19 00:55:42  jtg
+# Initial revision
+#
+# Revision 1.1  1999/02/24 05:20:45  brianp
+# Initial revision
+#
+
+
+CC = gcc
+
+CFLAGS = -c -g -ansi -pedantic -Wall
+
+INCDIRS = -I. -I../include
+
+LIBDIRS = -L../lib -L/usr/X11/lib
+
+LIBS = -lglut -lMesaGLU -lMesaGL -lX11 -lXext -lXmu -lXt -lXi -lSM -lICE -lm
+
+OBJECTS = main.o \
+       file1.o \
+       file2.o \
+       file3.o
+
+
+PROGRAMS = myprogram
+
+
+.c.o:
+       $(CC) $(CFLAGS) $(INCDIRS) $< -o $@
+
+
+
+default: $(PROGRAMS)
+
+
+dtenvmap: $(OBJECTS)
+       $(CC) $(OBJECTS) $(LIBDIRS) $(LIBS) -o $@
+
+
+clean:
+       rm -f *.o
diff --git a/progs/util/showbuffer.c b/progs/util/showbuffer.c
new file mode 100644 (file)
index 0000000..17f84dc
--- /dev/null
@@ -0,0 +1,192 @@
+/* showbuffer.c */
+
+
+/*
+ * Copy the depth buffer to the color buffer as a grayscale image.
+ * Useful for inspecting the depth buffer values.
+ *
+ * This program is in the public domain.
+ *
+ * Brian Paul   November 4, 1998
+ */
+
+
+#include <assert.h>
+#include <stdlib.h>
+#include <GL/gl.h>
+#include "showbuffer.h"
+
+
+
+/*
+ * Copy the depth buffer values into the current color buffer as a
+ * grayscale image.
+ * Input:  winWidth, winHeight - size of the window
+ *         zBlack - the Z value which should map to black (usually 1)
+ *         zWhite - the Z value which should map to white (usually 0)
+ */
+void
+ShowDepthBuffer( GLsizei winWidth, GLsizei winHeight,
+                 GLfloat zBlack, GLfloat zWhite )
+{
+   GLfloat *depthValues;
+
+   assert(zBlack >= 0.0);
+   assert(zBlack <= 1.0);
+   assert(zWhite >= 0.0);
+   assert(zWhite <= 1.0);
+   assert(zBlack != zWhite);
+
+   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+   glPixelStorei(GL_PACK_ALIGNMENT, 1);
+
+   /* Read depth values */
+   depthValues = (GLfloat *) malloc(winWidth * winHeight * sizeof(GLfloat));
+   assert(depthValues);
+   glReadPixels(0, 0, winWidth, winHeight, GL_DEPTH_COMPONENT,
+                GL_FLOAT, depthValues);
+
+   /* Map Z values from [zBlack, zWhite] to gray levels in [0, 1] */
+   /* Not using glPixelTransfer() because it's broke on some systems! */
+   if (zBlack != 0.0 || zWhite != 1.0) {
+      GLfloat scale = 1.0 / (zWhite - zBlack);
+      GLfloat bias = -zBlack * scale;
+      int n = winWidth * winHeight;
+      int i;
+      for (i = 0; i < n; i++)
+         depthValues[i] = depthValues[i] * scale + bias;
+   }
+
+   /* save GL state */
+   glPushAttrib(GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT |
+                GL_TRANSFORM_BIT | GL_VIEWPORT_BIT);
+
+   /* setup raster pos for glDrawPixels */
+   glMatrixMode(GL_PROJECTION);
+   glPushMatrix();
+   glLoadIdentity();
+
+   glOrtho(0.0, (GLdouble) winWidth, 0.0, (GLdouble) winHeight, -1.0, 1.0);
+   glMatrixMode(GL_MODELVIEW);
+   glPushMatrix();
+   glLoadIdentity();
+
+   glDisable(GL_STENCIL_TEST);
+   glDisable(GL_DEPTH_TEST);
+   glRasterPos2f(0, 0);
+
+   glDrawPixels(winWidth, winHeight, GL_LUMINANCE, GL_FLOAT, depthValues);
+
+   glPopMatrix();
+   glMatrixMode(GL_PROJECTION);
+   glPopMatrix();
+   free(depthValues);
+
+   glPopAttrib();
+}
+
+
+
+
+/*
+ * Copy the alpha channel values into the current color buffer as a
+ * grayscale image.
+ * Input:  winWidth, winHeight - size of the window
+ */
+void
+ShowAlphaBuffer( GLsizei winWidth, GLsizei winHeight )
+{
+   GLubyte *alphaValues;
+
+   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+   glPixelStorei(GL_PACK_ALIGNMENT, 1);
+
+   /* Read alpha values */
+   alphaValues = (GLubyte *) malloc(winWidth * winHeight * sizeof(GLubyte));
+   assert(alphaValues);
+   glReadPixels(0, 0, winWidth, winHeight, GL_ALPHA, GL_UNSIGNED_BYTE, alphaValues);
+
+   /* save GL state */
+   glPushAttrib(GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL |
+                GL_TRANSFORM_BIT | GL_VIEWPORT_BIT);
+
+   /* setup raster pos for glDrawPixels */
+   glMatrixMode(GL_PROJECTION);
+   glPushMatrix();
+   glLoadIdentity();
+
+   glOrtho(0.0, (GLdouble) winWidth, 0.0, (GLdouble) winHeight, -1.0, 1.0);
+   glMatrixMode(GL_MODELVIEW);
+   glPushMatrix();
+   glLoadIdentity();
+
+   glDisable(GL_STENCIL_TEST);
+   glDisable(GL_DEPTH_TEST);
+   glRasterPos2f(0, 0);
+
+   glDrawPixels(winWidth, winHeight, GL_LUMINANCE, GL_UNSIGNED_BYTE, alphaValues);
+
+   glPopMatrix();
+   glMatrixMode(GL_PROJECTION);
+   glPopMatrix();
+   free(alphaValues);
+
+   glPopAttrib();
+}
+
+
+
+/*
+ * Copy the stencil buffer values into the current color buffer as a
+ * grayscale image.
+ * Input:  winWidth, winHeight - size of the window
+ *         scale, bias - scale and bias to apply to stencil values for display
+ */
+void
+ShowStencilBuffer( GLsizei winWidth, GLsizei winHeight,
+                   GLfloat scale, GLfloat bias )
+{
+   GLubyte *stencilValues;
+
+   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+   glPixelStorei(GL_PACK_ALIGNMENT, 1);
+
+   /* Read stencil values */
+   stencilValues = (GLubyte *) malloc(winWidth * winHeight * sizeof(GLubyte));
+   assert(stencilValues);
+   glReadPixels(0, 0, winWidth, winHeight, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, stencilValues);
+
+   /* save GL state */
+   glPushAttrib(GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT |
+                GL_PIXEL_MODE_BIT | GL_TRANSFORM_BIT | GL_VIEWPORT_BIT);
+
+   /* setup raster pos for glDrawPixels */
+   glMatrixMode(GL_PROJECTION);
+   glPushMatrix();
+   glLoadIdentity();
+
+   glOrtho(0.0, (GLdouble) winWidth, 0.0, (GLdouble) winHeight, -1.0, 1.0);
+   glMatrixMode(GL_MODELVIEW);
+   glPushMatrix();
+   glLoadIdentity();
+
+   glDisable(GL_STENCIL_TEST);
+   glDisable(GL_DEPTH_TEST);
+   glRasterPos2f(0, 0);
+
+   glPixelTransferf(GL_RED_SCALE, scale);
+   glPixelTransferf(GL_RED_BIAS, bias);
+   glPixelTransferf(GL_GREEN_SCALE, scale);
+   glPixelTransferf(GL_GREEN_BIAS, bias);
+   glPixelTransferf(GL_BLUE_SCALE, scale);
+   glPixelTransferf(GL_BLUE_BIAS, bias);
+
+   glDrawPixels(winWidth, winHeight, GL_LUMINANCE, GL_UNSIGNED_BYTE, stencilValues);
+
+   glPopMatrix();
+   glMatrixMode(GL_PROJECTION);
+   glPopMatrix();
+   free(stencilValues);
+
+   glPopAttrib();
+}
diff --git a/progs/util/showbuffer.h b/progs/util/showbuffer.h
new file mode 100644 (file)
index 0000000..63533d8
--- /dev/null
@@ -0,0 +1,36 @@
+/* showbuffer. h*/
+
+/*
+ * Copy the depth buffer to the color buffer as a grayscale image.
+ * Useful for inspecting the depth buffer values.
+ *
+ * This program is in the public domain.
+ *
+ * Brian Paul   November 4, 1998
+ */
+
+
+#ifndef SHOWBUFFER_H
+#define SHOWBUFFER_H
+
+
+#include <GL/gl.h>
+
+
+
+extern void
+ShowDepthBuffer( GLsizei winWidth, GLsizei winHeight,
+                 GLfloat zBlack, GLfloat zWhite );
+
+
+extern void
+ShowAlphaBuffer( GLsizei winWidth, GLsizei winHeight );
+
+
+extern void
+ShowStencilBuffer( GLsizei winWidth, GLsizei winHeight,
+                   GLfloat scale, GLfloat bias );
+
+
+
+#endif
diff --git a/progs/util/winpos.c b/progs/util/winpos.c
new file mode 100644 (file)
index 0000000..5ad98fd
--- /dev/null
@@ -0,0 +1,42 @@
+/* winpos.c */
+
+
+/*
+ * Set the current raster position to a specific window
+ * coordinate.  Also see the GL_MESA_window_pos extension.
+ *
+ * Written by Brian Paul and in the public domain.
+ */
+
+
+void WindowPos( GLfloat x, GLfloat y, GLfloat z )
+{
+   GLfloat fx, fy;
+
+   /* Push current matrix mode and viewport attributes */
+   glPushAttrib( GL_TRANSFORM_BIT | GL_VIEWPORT_BIT );
+
+   /* Setup projection parameters */
+   glMatrixMode( GL_PROJECTION );
+   glPushMatrix();
+   glLoadIdentity();
+   glMatrixMode( GL_MODELVIEW );
+   glPushMatrix();
+   glLoadIdentity();
+
+   glDepthRange( z, z );
+   glViewport( (int) x - 1, (int) y - 1, 2, 2 );
+
+   /* set the raster (window) position */
+   fx = x - (int) x;
+   fy = y - (int) y;
+   glRasterPos3f( fx, fy, 0.0 );
+
+   /* restore matrices, viewport and matrix mode */
+   glPopMatrix();
+   glMatrixMode( GL_PROJECTION );
+   glPopMatrix();
+
+   glPopAttrib();
+}
+
diff --git a/progs/xdemos/Makefile.X11 b/progs/xdemos/Makefile.X11
new file mode 100644 (file)
index 0000000..ab5dce4
--- /dev/null
@@ -0,0 +1,58 @@
+# $Id: Makefile.X11,v 1.1 1999/08/19 00:55:43 jtg Exp $
+
+# Mesa 3-D graphics library
+# Version:  3.1
+# Copyright (C) 1995-1999  Brian Paul
+
+# Makefile for non-GLUT (X11, SVGA, etc) demo programs
+
+
+##### MACROS #####
+
+INCDIR = ../include
+LIBDIR = ../lib
+
+GL_LIBS = -L$(LIBDIR) -lglut -lGLU -lGL -lm $(XLIBS)
+
+LIB_DEP = $(LIBDIR)/$(GL_LIB) $(LIBDIR)/$(GLU_LIB) $(LIBDIR)/$(GLUT_LIB)
+
+PROGS = glxdemo glxpixmap offset xdemo
+
+
+
+##### RULES #####
+
+.SUFFIXES:
+.SUFFIXES: .c
+
+.c: $(LIB_DEP)
+       $(CC) -I$(INCDIR) $(CFLAGS) $< $(GL_LIBS) -o $@
+
+
+
+##### TARGETS #####
+
+default:
+       @echo "Specify a target configuration"
+
+clean:
+       -rm *.o *~
+
+realclean:
+       -rm $(PROGS)
+       -rm *.o *~
+
+targets: $(PROGS)
+
+# execute all programs
+exec: $(PROGS)
+       @for prog in $(PROGS) ;                 \
+       do                                      \
+               echo -n "Running $$prog ..." ;  \
+               $$prog ;                        \
+               echo ;                          \
+       done
+
+
+include ../Make-config
+
diff --git a/progs/xdemos/descrip.mms b/progs/xdemos/descrip.mms
new file mode 100644 (file)
index 0000000..aa56c1c
--- /dev/null
@@ -0,0 +1,79 @@
+# Makefile for demo programs for VMS
+# contributed by Jouk Jansen  joukj@crys.chem.uva.nl
+
+
+.first
+       define gl [-.include.gl]
+
+.include [-]mms-config.
+
+##### MACROS #####
+
+INCDIR = [-.include]
+CFLAGS = /include=$(INCDIR)/define=(FBIND=1)
+
+GL_LIBS = [-.lib]libMesaaux/l,libMesatk/l,libMesaGLU/l,libMesaGL/l,$(XLIBS)
+
+LIB_DEP = [-.lib]$(GL_LIB) [-.lib]$(GLU_LIB) [-.lib]$(TK_LIB) [-.lib]$(AUX_LIB)
+
+PROGS = bounce.exe;,gamma.exe;,gears.exe;,glxdemo.exe;,glxpixmap.exe;,\
+       isosurf.exe;,offset.exe;,osdemo.exe;,spin.exe;,test0.exe;,\
+       texobj.exe;,xdemo.exe;,reflect.exe;,winpos.exe;
+
+
+
+##### RULES #####
+
+
+##### TARGETS #####
+default :
+       mms $(PROGS)
+
+clean :
+       delete *.obj;*
+
+realclean :
+       delete $(PROGS)
+       delete *.obj;*
+
+bounce.exe; : bounce.obj $(LIB_DEP)
+       link bounce,$(GL_LIBS)
+       
+gamma.exe; : gamma.obj $(LIB_DEP)
+       link gamma,$(GL_LIBS)
+
+gears.exe; : gears.obj $(LIB_DEP)
+       link gears,$(GL_LIBS)
+
+glxdemo.exe; : glxdemo.obj $(LIB_DEP)
+       link glxdemo,$(GL_LIBS)
+
+glxpixmap.exe; : glxpixmap.obj $(LIB_DEP)
+       link glxpixmap,$(GL_LIBS)
+
+isosurf.exe; : isosurf.obj $(LIB_DEP)
+       link isosurf,$(GL_LIBS)
+
+offset.exe; : offset.obj $(LIB_DEP)
+       link offset,$(GL_LIBS)
+
+osdemo.exe; : osdemo.obj $(LIB_DEP)
+       link osdemo,$(GL_LIBS)
+
+spin.exe; : spin.obj $(LIB_DEP)
+       link spin,$(GL_LIBS)
+
+test0.exe; : test0.obj $(LIB_DEP)
+       link test0,$(GL_LIBS)
+
+texobj.exe; : texobj.obj $(LIB_DEP)
+       link texobj,$(GL_LIBS)
+
+xdemo.exe; : xdemo.obj $(LIB_DEP)
+       link xdemo,$(GL_LIBS)
+
+reflect.exe; : reflect.obj $(LIB_DEP)
+       link reflect,$(GL_LIBS)
+
+winpos.exe; : winpos.obj $(LIB_DEP)
+       link winpos,$(GL_LIBS)
diff --git a/progs/xdemos/glxdemo.c b/progs/xdemos/glxdemo.c
new file mode 100644 (file)
index 0000000..c49cd85
--- /dev/null
@@ -0,0 +1,136 @@
+/* $Id: glxdemo.c,v 1.1 1999/08/19 00:55:43 jtg Exp $ */
+
+
+/*
+ * A demonstration of using the GLX functions.  This program is in the
+ * public domain.
+ *
+ * Brian Paul
+ */
+
+
+/*
+ * $Log: glxdemo.c,v $
+ * Revision 1.1  1999/08/19 00:55:43  jtg
+ * Initial revision
+ *
+ * Revision 3.0  1998/02/21 02:16:54  brianp
+ * initial rev
+ *
+ */
+
+
+#include <GL/gl.h>
+#include <GL/glx.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+
+static void redraw( Display *dpy, Window w )
+{
+   printf("Redraw event\n");
+
+   glClear( GL_COLOR_BUFFER_BIT );
+
+   glColor3f( 1.0, 1.0, 0.0 );
+   glRectf( -0.8, -0.8, 0.8, 0.8 );
+
+   glXSwapBuffers( dpy, w );
+}
+
+
+
+static void resize( unsigned int width, unsigned int height )
+{
+   printf("Resize event\n");
+   glViewport( 0, 0, width, height );
+   glMatrixMode( GL_PROJECTION );
+   glLoadIdentity();
+   glOrtho( -1.0, 1.0, -1.0, 1.0, -1.0, 1.0 );
+}
+
+
+
+static Window make_rgb_db_window( Display *dpy,
+                                 unsigned int width, unsigned int height )
+{
+   int attrib[] = { GLX_RGBA,
+                   GLX_RED_SIZE, 1,
+                   GLX_GREEN_SIZE, 1,
+                   GLX_BLUE_SIZE, 1,
+                   GLX_DOUBLEBUFFER,
+                   None };
+   int scrnum;
+   XSetWindowAttributes attr;
+   unsigned long mask;
+   Window root;
+   Window win;
+   GLXContext ctx;
+   XVisualInfo *visinfo;
+
+   scrnum = DefaultScreen( dpy );
+   root = RootWindow( dpy, scrnum );
+
+   visinfo = glXChooseVisual( dpy, scrnum, attrib );
+   if (!visinfo) {
+      printf("Error: couldn't get an RGB, Double-buffered visual\n");
+      exit(1);
+   }
+
+   /* window attributes */
+   attr.background_pixel = 0;
+   attr.border_pixel = 0;
+   attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
+   attr.event_mask = StructureNotifyMask | ExposureMask;
+   mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
+
+   win = XCreateWindow( dpy, root, 0, 0, width, height,
+                       0, visinfo->depth, InputOutput,
+                       visinfo->visual, mask, &attr );
+
+   ctx = glXCreateContext( dpy, visinfo, NULL, True );
+
+   glXMakeCurrent( dpy, win, ctx );
+
+   return win;
+}
+
+
+static void event_loop( Display *dpy )
+{
+   XEvent event;
+
+   while (1) {
+      XNextEvent( dpy, &event );
+
+      switch (event.type) {
+        case Expose:
+           redraw( dpy, event.xany.window );
+           break;
+        case ConfigureNotify:
+           resize( event.xconfigure.width, event.xconfigure.height );
+           break;
+      }
+   }
+}
+
+
+
+int main( int argc, char *argv[] )
+{
+   Display *dpy;
+   Window win;
+
+   dpy = XOpenDisplay(NULL);
+
+   win = make_rgb_db_window( dpy, 300, 300 );
+
+   glShadeModel( GL_FLAT );
+   glClearColor( 0.5, 0.5, 0.5, 1.0 );
+
+   XMapWindow( dpy, win );
+
+   event_loop( dpy );
+   return 0;
+}
diff --git a/progs/xdemos/glxpixmap.c b/progs/xdemos/glxpixmap.c
new file mode 100644 (file)
index 0000000..e4a62c7
--- /dev/null
@@ -0,0 +1,160 @@
+/* $Id: glxpixmap.c,v 1.1 1999/08/19 00:55:43 jtg Exp $ */
+
+
+/*
+ * A demonstration of using the GLXPixmap functions.  This program is in
+ * the public domain.
+ *
+ * Brian Paul
+ */
+
+
+/*
+ * $Id: glxpixmap.c,v 1.1 1999/08/19 00:55:43 jtg Exp $
+ */
+
+
+#include <GL/gl.h>
+#include <GL/glx.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+
+static GLXContext ctx;
+static XVisualInfo *visinfo;
+static GC gc;
+
+
+
+static Window make_rgb_window( Display *dpy,
+                                 unsigned int width, unsigned int height )
+{
+   int attrib[] = { GLX_RGBA,
+                   GLX_RED_SIZE, 1,
+                   GLX_GREEN_SIZE, 1,
+                   GLX_BLUE_SIZE, 1,
+                   None };
+   int scrnum;
+   XSetWindowAttributes attr;
+   unsigned long mask;
+   Window root;
+   Window win;
+
+   scrnum = DefaultScreen( dpy );
+   root = RootWindow( dpy, scrnum );
+
+   visinfo = glXChooseVisual( dpy, scrnum, attrib );
+   if (!visinfo) {
+      printf("Error: couldn't get an RGB, Double-buffered visual\n");
+      exit(1);
+   }
+
+   /* window attributes */
+   attr.background_pixel = 0;
+   attr.border_pixel = 0;
+   /* TODO: share root colormap if possible */
+   attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
+   attr.event_mask = StructureNotifyMask | ExposureMask;
+   mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
+
+   win = XCreateWindow( dpy, root, 0, 0, width, height,
+                       0, visinfo->depth, InputOutput,
+                       visinfo->visual, mask, &attr );
+
+   /* make an X GC so we can do XCopyArea later */
+   gc = XCreateGC( dpy, win, 0, NULL );
+
+   ctx = glXCreateContext( dpy, visinfo, NULL, True );
+
+   return win;
+}
+
+
+static GLXPixmap make_pixmap( Display *dpy, Window win,
+                              unsigned int width, unsigned int height )
+{
+   Pixmap pm;
+   GLXPixmap glxpm;
+   XWindowAttributes attr;
+
+   pm = XCreatePixmap( dpy, win, width, height, visinfo->depth );
+   XGetWindowAttributes( dpy, win, &attr );
+
+   /*
+    * IMPORTANT:
+    *   Use the glXCreateGLXPixmapMESA funtion when using Mesa because
+    *   Mesa needs to know the colormap associated with a pixmap in order
+    *   to render correctly.  This is because Mesa allows RGB rendering
+    *   into any kind of visual, not just TrueColor or DirectColor.
+    */
+#ifdef GLX_MESA_pixmap_colormap
+   glxpm = glXCreateGLXPixmapMESA( dpy, visinfo, pm, attr.colormap );
+#else
+   /* This will work with Mesa too if the visual is TrueColor or DirectColor */
+   glxpm = glXCreateGLXPixmap( dpy, visinfo, pm );
+#endif
+
+   return glxpm;
+}
+
+
+
+static void event_loop( Display *dpy, GLXPixmap pm )
+{
+   XEvent event;
+
+   while (1) {
+      XNextEvent( dpy, &event );
+
+      switch (event.type) {
+        case Expose:
+           printf("Redraw\n");
+           /* copy the image from GLXPixmap to window */
+           XCopyArea( dpy, pm, event.xany.window,  /* src, dest */
+                      gc, 0, 0, 300, 300,          /* gc, src pos, size */
+                      0, 0 );                      /* dest pos */
+           break;
+        case ConfigureNotify:
+           /* nothing */
+           break;
+      }
+   }
+}
+
+
+
+int main( int argc, char *argv[] )
+{
+   Display *dpy;
+   Window win;
+   GLXPixmap pm;
+
+   dpy = XOpenDisplay(NULL);
+
+   win = make_rgb_window( dpy, 300, 300 );
+   pm = make_pixmap( dpy, win, 300, 300 );
+
+#ifdef JUNK
+   glXMakeCurrent( dpy, win, ctx );  /*to make sure ctx is properly initialized*/
+#endif
+
+   glXMakeCurrent( dpy, pm, ctx );
+
+   /* Render an image into the pixmap */
+   glShadeModel( GL_FLAT );
+   glClearColor( 0.5, 0.5, 0.5, 1.0 );
+   glClear( GL_COLOR_BUFFER_BIT );
+   glViewport( 0, 0, 300, 300 );
+   glOrtho( -1.0, 1.0, -1.0, 1.0, -1.0, 1.0 );
+   glColor3f( 0.0, 1.0, 1.0 );
+   glRectf( -0.75, -0.75, 0.75, 0.75 );
+   glFlush();
+
+   /* when a redraw is needed we'll just copy the pixmap image to the window */
+
+   XMapWindow( dpy, win );
+
+   event_loop( dpy, pm );
+   return 0;
+}
diff --git a/progs/xdemos/offset.c b/progs/xdemos/offset.c
new file mode 100644 (file)
index 0000000..158e52a
--- /dev/null
@@ -0,0 +1,323 @@
+/****************************************************************************
+Copyright 1995 by Silicon Graphics Incorporated, Mountain View, California.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL SILICON GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+
+****************************************************************************/
+
+/*
+ * Derived from code written by Kurt Akeley, November 1992
+ *
+ *     Uses PolygonOffset to draw hidden-line images.  PolygonOffset
+ *         shifts the z values of polygons an amount that is
+ *         proportional to their slope in screen z.  This keeps
+ *         the lines, which are drawn without displacement, from
+ *         interacting with their respective polygons, and
+ *         thus eliminates line dropouts.
+ *
+ *     The left image shows an ordinary antialiased wireframe image.
+ *     The center image shows an antialiased hidden-line image without
+ *         PolygonOffset.
+ *     The right image shows an antialiased hidden-line image using
+ *         PolygonOffset to reduce artifacts.
+ *
+ *     Drag with a mouse button pressed to rotate the models.
+ *     Press the escape key to exit.
+ */
+
+/*
+ * Modified for OpenGL 1.1 glPolygonOffset() conventions
+ */
+
+
+#include <GL/glx.h>
+#include <GL/glu.h>
+#include <X11/keysym.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+/*#undef GL_EXT_polygon_offset   uncomment to use new version*/
+
+
+#ifndef EXIT_FAILURE
+#  define EXIT_FAILURE    1
+#endif
+#ifndef EXIT_SUCCESS
+#  define EXIT_SUCCESS    0
+#endif
+
+#define MAXQUAD 6
+
+typedef float Vertex[3];
+
+typedef Vertex Quad[4];
+
+/* data to define the six faces of a unit cube */
+Quad quads[MAXQUAD] = {
+   { {0,0,0}, {1,0,0}, {1,1,0}, {0,1,0} },
+   { {0,0,1}, {1,0,1}, {1,1,1}, {0,1,1} },
+   { {0,0,0}, {1,0,0}, {1,0,1}, {0,0,1} },
+   { {0,1,0}, {1,1,0}, {1,1,1}, {0,1,1} },
+   { {0,0,0}, {0,0,1}, {0,1,1}, {0,1,0} },
+   { {1,0,0}, {1,0,1}, {1,1,1}, {1,1,0} }
+};
+
+#define WIREFRAME      0
+#define HIDDEN_LINE    1
+
+static void error(const char* prog, const char* msg);
+static void cubes(int mx, int my, int mode);
+static void fill(Quad quad);
+static void outline(Quad quad);
+static void draw_hidden(Quad quad, int mode);
+static void process_input(Display *dpy, Window win);
+static int query_extension(char* extName);
+
+static int attributeList[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1,
+    GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 1, None };
+
+static int dimension = 3;
+
+int main(int argc, char** argv) {
+    Display *dpy;
+    XVisualInfo *vi;
+    XSetWindowAttributes swa;
+    Window win;
+    GLXContext cx;
+
+    dpy = XOpenDisplay(0);
+    if (!dpy) error(argv[0], "can't open display");
+
+    vi = glXChooseVisual(dpy, DefaultScreen(dpy), attributeList);
+    if (!vi) error(argv[0], "no suitable visual");
+
+    cx = glXCreateContext(dpy, vi, 0, GL_TRUE);
+
+    swa.colormap = XCreateColormap(dpy, RootWindow(dpy, vi->screen),
+                                   vi->visual, AllocNone);
+
+    swa.border_pixel = 0;
+    swa.event_mask = ExposureMask | StructureNotifyMask | KeyPressMask |
+       ButtonPressMask | ButtonMotionMask;
+    win = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 0, 0, 900, 300,
+                       0, vi->depth, InputOutput, vi->visual,
+                       CWBorderPixel|CWColormap|CWEventMask, &swa);
+    XStoreName(dpy, win, "hiddenline");
+    XMapWindow(dpy, win);
+
+    glXMakeCurrent(dpy, win, cx);
+
+    /* check for the polygon offset extension */
+#ifndef GL_VERSION_1_1
+    if (!query_extension("GL_EXT_polygon_offset"))
+        error(argv[0], "polygon_offset extension is not available");
+#else
+   (void) query_extension;
+#endif
+
+    /* set up viewing parameters */
+    glMatrixMode(GL_PROJECTION);
+    gluPerspective(20, 1, 0.1, 20);
+    glMatrixMode(GL_MODELVIEW);
+    glTranslatef(0, 0, -15);
+
+    /* set other relevant state information */
+    glEnable(GL_DEPTH_TEST);
+
+#ifdef GL_EXT_polygon_offset
+    printf("using 1.0 offset extension\n");
+    glPolygonOffsetEXT( 1.0, 0.00001 );
+#else
+    printf("using 1.1 offset\n");
+    glPolygonOffset( 1.0, 0.5 );
+#endif
+
+    glShadeModel( GL_FLAT );
+    glDisable( GL_DITHER );
+
+    /* process events until the user presses ESC */
+    while (1) process_input(dpy, win);
+
+    return 0;
+}
+
+static void
+draw_scene(int mx, int my) {
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+    glPushMatrix();
+    glTranslatef(-1.7, 0.0, 0.0);
+    cubes(mx, my, WIREFRAME);
+    glPopMatrix();
+
+    glPushMatrix();
+    cubes(mx, my, HIDDEN_LINE);
+    glPopMatrix();
+
+    glPushMatrix();
+    glTranslatef(1.7, 0.0, 0.0);
+#ifdef GL_EXT_polygon_offset
+    glEnable(GL_POLYGON_OFFSET_EXT);
+#else
+    glEnable(GL_POLYGON_OFFSET_FILL);
+#endif
+    cubes(mx, my, HIDDEN_LINE);
+#ifdef GL_EXT_polygon_offset
+    glDisable(GL_POLYGON_OFFSET_EXT);
+#else
+    glDisable(GL_POLYGON_OFFSET_FILL);
+#endif
+    glPopMatrix();
+}
+
+
+static void
+cubes(int mx, int my, int mode) {
+    int x, y, z, i;
+
+    /* track the mouse */
+    glRotatef(mx / 2.0, 0, 1, 0);
+    glRotatef(my / 2.0, 1, 0, 0);
+
+    /* draw the lines as hidden polygons */
+    glTranslatef(-0.5, -0.5, -0.5);
+    glScalef(1.0/dimension, 1.0/dimension, 1.0/dimension);
+    for (z = 0; z < dimension; z++) {
+       for (y = 0; y < dimension; y++) {
+           for (x = 0; x < dimension; x++) {
+               glPushMatrix();
+               glTranslatef(x, y, z);
+               glScalef(0.8, 0.8, 0.8);
+               for (i = 0; i < MAXQUAD; i++)
+                   draw_hidden(quads[i], mode);
+               glPopMatrix();
+           }
+       }
+    }
+}
+
+static void
+fill(Quad quad) {
+    /* draw a filled polygon */
+    glBegin(GL_QUADS);
+    glVertex3fv(quad[0]);
+    glVertex3fv(quad[1]);
+    glVertex3fv(quad[2]);
+    glVertex3fv(quad[3]);
+    glEnd();
+}
+
+static void
+outline(Quad quad) {
+    /* draw an outlined polygon */
+    glBegin(GL_LINE_LOOP);
+    glVertex3fv(quad[0]);
+    glVertex3fv(quad[1]);
+    glVertex3fv(quad[2]);
+    glVertex3fv(quad[3]);
+    glEnd();
+}
+
+static void
+draw_hidden(Quad quad, int mode) {
+    if (mode == HIDDEN_LINE) {
+       glColor3f(0, 0, 0);
+       fill(quad);
+    }
+
+    /* draw the outline using white, optionally fill the interior with black */
+    glColor3f(1, 1, 1);
+    outline(quad);
+}
+
+static void
+process_input(Display *dpy, Window win) {
+    XEvent event;
+    static int prevx, prevy;
+    static int deltax = 90, deltay = 40;
+
+    do {
+       char buf[31];
+       KeySym keysym;
+
+       XNextEvent(dpy, &event);
+       switch(event.type) {
+       case Expose:
+           break;
+       case ConfigureNotify: {
+           /* this approach preserves a 1:1 viewport aspect ratio */
+           int vX, vY, vW, vH;
+           int eW = event.xconfigure.width, eH = event.xconfigure.height;
+           if (eW >= eH) {
+               vX = 0;
+               vY = (eH - eW) >> 1;
+               vW = vH = eW;
+           } else {
+               vX = (eW - eH) >> 1;
+               vY = 0;
+               vW = vH = eH;
+           }
+           glViewport(vX, vY, vW, vH);
+           }
+           break;
+       case KeyPress:
+           (void) XLookupString(&event.xkey, buf, sizeof(buf), &keysym, NULL);
+           switch (keysym) {
+           case XK_Escape:
+               exit(EXIT_SUCCESS);
+           default:
+               break;
+           }
+       case ButtonPress:
+           prevx = event.xbutton.x;
+           prevy = event.xbutton.y;
+           break;
+       case MotionNotify:
+           deltax += (event.xbutton.x - prevx); prevx = event.xbutton.x;
+           deltay += (event.xbutton.y - prevy); prevy = event.xbutton.y;
+           break;
+       default:
+           break;
+       }
+    } while (XPending(dpy));
+
+    draw_scene(deltax, deltay);
+    glXSwapBuffers(dpy, win);
+}
+
+static void
+error(const char *prog, const char *msg) {
+    fprintf(stderr, "%s: %s\n", prog, msg);
+    exit(EXIT_FAILURE);
+}
+
+static int
+query_extension(char* extName) {
+    char *p = (char *) glGetString(GL_EXTENSIONS);
+    char *end = p + strlen(p);
+    while (p < end) {
+        int n = strcspn(p, " ");
+        if ((strlen(extName) == n) && (strncmp(extName, p, n) == 0))
+            return GL_TRUE;
+        p += (n + 1);
+    }
+    return GL_FALSE;
+}
+
diff --git a/progs/xdemos/shape.c b/progs/xdemos/shape.c
new file mode 100644 (file)
index 0000000..94b9b1f
--- /dev/null
@@ -0,0 +1,305 @@
+/* $Id: shape.c,v 1.1 1999/08/19 00:55:43 jtg Exp $ */
+
+/*
+ * Example of using the X "shape" extension with OpenGL:  render a spinning
+ * cube inside of a non-rectangular window.
+ *
+ * Press ESC to exit.  Press up/down to change window shape.
+ *
+ * To compile add "shape" to the PROGS list in Makefile.
+ *
+ * Brian Paul
+ * June 16, 1997
+ *
+ * This program is in the public domain.
+ */
+
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/keysym.h>
+#include <X11/extensions/shape.h>
+#include <GL/glx.h>
+
+#ifndef PI
+#define PI 3.1415926
+#endif
+
+
+static int Width=500, Height=500;
+
+static float Xangle = 0.0, Yangle = 0.0;
+static int Redraw = 0;
+static int Sides = 5;
+static int MinSides = 3;
+static int MaxSides = 20;
+
+
+/*
+ * Draw the OpenGL stuff and do a SwapBuffers.
+ */
+static void display(Display *dpy, Window win)
+{
+   float scale = 1.7;
+
+   glClear(GL_COLOR_BUFFER_BIT);
+
+   glPushMatrix();
+
+   glScalef(scale, scale, scale);
+   glRotatef(Xangle, 1.0, 0.0, 0.0);
+   glRotatef(Yangle, 0.0, 1.0, 0.0);
+
+   glColor3f(1.0, 1.0, 1.0);
+   glBegin(GL_LINE_LOOP);
+   glVertex3f(-1.0, -1.0, -1.0);
+   glVertex3f( 1.0, -1.0, -1.0);
+   glVertex3f( 1.0,  1.0, -1.0);
+   glVertex3f(-1.0,  1.0, -1.0);
+   glEnd();
+
+   glBegin(GL_LINE_LOOP);
+   glVertex3f(-1.0, -1.0, 1.0);
+   glVertex3f( 1.0, -1.0, 1.0);
+   glVertex3f( 1.0,  1.0, 1.0);
+   glVertex3f(-1.0,  1.0, 1.0);
+   glEnd();
+
+   glBegin(GL_LINES);
+   glVertex3f(-1.0, -1.0, -1.0);   glVertex3f(-1.0, -1.0, 1.0);
+   glVertex3f( 1.0, -1.0, -1.0);   glVertex3f( 1.0, -1.0, 1.0);
+   glVertex3f( 1.0,  1.0, -1.0);   glVertex3f( 1.0,  1.0, 1.0);
+   glVertex3f(-1.0,  1.0, -1.0);   glVertex3f(-1.0,  1.0, 1.0);
+   glEnd();
+
+   glPopMatrix();
+
+   glXSwapBuffers(dpy, win);
+}
+
+
+/*
+ * Called when no events are pending.
+ */
+static void idle(void)
+{
+   Xangle += 2.0;
+   Yangle += 3.3;
+   Redraw = 1;
+}
+
+
+/*
+ * This is called when we have to recompute the window shape bitmask.
+ * We just generate an n-sided regular polygon here but any other shape
+ * would be possible.
+ */
+static void make_shape_mask(Display *dpy, Window win, int width, int height,
+                            int sides)
+{
+   Pixmap shapeMask;
+   XGCValues xgcv;
+   GC gc;
+
+   /* allocate 1-bit deep pixmap and a GC */
+   shapeMask = XCreatePixmap(dpy, win, width, height, 1);
+   gc = XCreateGC(dpy, shapeMask, 0, &xgcv);
+
+   /* clear shapeMask to zeros */
+   XSetForeground(dpy, gc, 0);
+   XFillRectangle(dpy, shapeMask, gc, 0, 0, width, height);
+
+   /* draw mask */
+   XSetForeground(dpy, gc, 1);
+   {
+      int cx = width / 2;
+      int cy = height / 2;
+      float angle = 0.0;
+      float step = 2.0 * PI / sides;
+      float radius = width / 2;
+      int i;
+      XPoint points[100];
+      for (i=0;i<sides;i++) {
+         int x = cx + radius * sin(angle);
+         int y = cy - radius * cos(angle);
+         points[i].x = x;
+         points[i].y = y;
+         angle += step;
+      }
+      XFillPolygon(dpy, shapeMask, gc, points, sides, Convex, CoordModeOrigin);
+   }
+
+   /* This is the only SHAPE extension call- simple! */
+   XShapeCombineMask(dpy, win, ShapeBounding, 0, 0, shapeMask, ShapeSet);
+
+   XFreeGC(dpy, gc);
+   XFreePixmap(dpy, shapeMask);
+}
+
+
+/*
+ * Called when window is resized.  Do OpenGL viewport and projection stuff.
+ */
+static void reshape(int width, int height)
+{
+   glViewport(0, 0, width, height);
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   glFrustum(-1.0, 1.0, -1.0, 1.0, 3.0, 20.0);
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+   glTranslatef(0.0, 0.0, -10.0);
+}
+
+
+/*
+ * Process X events.
+ */
+static void event_loop(Display *dpy, Window win)
+{
+   while (1) {
+      XEvent event;
+      if (XPending(dpy)) {
+         XNextEvent(dpy, &event);
+         switch (event.type) {
+            case Expose:
+               display(dpy, event.xexpose.window);
+               break;
+            case ConfigureNotify:
+               Width = event.xconfigure.width;
+               Height = event.xconfigure.height,
+               make_shape_mask(dpy, win, Width, Height, Sides);
+               reshape(Width, Height);
+               break;
+            case KeyPress:
+               {
+                  char buf[100];
+                  KeySym keySym;
+                  XComposeStatus stat;
+                  XLookupString(&event.xkey, buf, sizeof(buf), &keySym, &stat);
+                  switch (keySym) {
+                     case XK_Escape:
+                        exit(0);
+                        break;
+                     case XK_Up:
+                        Sides++;
+                        if (Sides>MaxSides) Sides = MaxSides;
+                        make_shape_mask(dpy, win, Width, Height, Sides);
+                        break;
+                     case XK_Down:
+                        Sides--;
+                        if (Sides<MinSides) Sides = MinSides;
+                        make_shape_mask(dpy, win, Width, Height, Sides);
+                        break;
+                  }
+               }
+               break;
+            default:
+               ;;
+         }
+      }
+      else {
+         idle();
+         if (Redraw) {
+            display(dpy, win);
+            Redraw = 0;
+         }
+      }
+   }
+}
+
+
+/*
+ * Allocate a "nice" colormap.  This could be better (HP-CR support, etc).
+ */
+static Colormap alloc_colormap(Display *dpy, Window parent, Visual *vis)
+{
+   Screen *scr = DefaultScreenOfDisplay(dpy);
+   int scrnum = DefaultScreen(dpy);
+
+   if (MaxCmapsOfScreen(scr)==1 && vis==DefaultVisual(dpy, scrnum)) {
+      /* The window and root are of the same visual type so */
+      /* share the root colormap. */
+      return DefaultColormap(dpy, scrnum);
+   }
+   else {
+      return XCreateColormap(dpy, parent, vis, AllocNone);
+   }
+}
+
+
+int main(int argc, char *argv[])
+{
+   static int glAttribs[] = {
+      GLX_DOUBLEBUFFER,
+      GLX_RGBA,
+      GLX_DEPTH_SIZE, 1,
+      None
+   };
+   Display *dpy;
+   XVisualInfo *visInfo;
+   int scrn;
+   Window root;
+   Colormap cmap;
+   Window win;
+   XSetWindowAttributes winAttribs;
+   unsigned long winAttribsMask;
+   GLXContext glCtx;
+   int ignore;
+
+   dpy = XOpenDisplay(NULL);
+   if (!dpy) {
+      fprintf(stderr, "Couldn't open default display\n");
+      return 1;
+   }
+
+   /* check that we can use the shape extension */
+   if (!XQueryExtension(dpy, "SHAPE", &ignore, &ignore, &ignore )) {
+      fprintf(stderr, "Display doesn't support shape extension\n");
+      return 1;
+   }
+
+   scrn = DefaultScreen(dpy);
+
+   root = RootWindow(dpy, scrn);
+
+   visInfo = glXChooseVisual(dpy, scrn, glAttribs);
+   if (!visInfo) {
+      fprintf(stderr, "Couldn't get RGB, DB, Z visual\n");
+      return 1;
+   }
+
+   glCtx = glXCreateContext(dpy, visInfo, 0, True);
+   if (!glCtx) {
+      fprintf(stderr, "Couldn't create GL context\n");
+      return 1;
+   }
+
+   cmap = alloc_colormap(dpy, root, visInfo->visual);
+   if (!cmap) {
+      fprintf(stderr, "Couln't create colormap\n");
+      return 1;
+   }
+
+   winAttribs.border_pixel = 0;
+   winAttribs.colormap = cmap;
+   winAttribs.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
+   winAttribsMask = CWBorderPixel | CWColormap | CWEventMask;
+   win = XCreateWindow(dpy, root, 0, 0, Width, Height, 0,
+                       visInfo->depth, InputOutput,
+                       visInfo->visual,
+                       winAttribsMask, &winAttribs);
+   XMapWindow(dpy, win);
+
+   glXMakeCurrent(dpy, win, glCtx);
+
+   printf("Press ESC to exit.\n");
+   printf("Press up/down to change window shape.\n");
+
+   event_loop(dpy, win);
+
+   return 0;
+}
diff --git a/progs/xdemos/vgears.c b/progs/xdemos/vgears.c
new file mode 100644 (file)
index 0000000..13d030a
--- /dev/null
@@ -0,0 +1,282 @@
+/* $ID$ */
+
+/*
+ * Spinning gears demo for Linux SVGA/Mesa interface in 32K color mode.
+ *
+ * Compile with:  gcc vgears.c -I../include -L../lib -lMesaGL -lX11 -lXext
+ *   -lvga -lm -o vgears
+ *
+ * This program is in the public domain.
+ * Brian Paul, January 1996
+ */
+
+
+#include <vga.h>
+#include <math.h>
+#include "GL/svgamesa.h"
+#include "GL/gl.h"
+
+
+int width = 800, height = 600;
+
+SVGAMesaContext vmc;
+
+
+
+/*
+ * Draw a gear wheel.  You'll probably want to call this function when
+ * building a display list since we do a lot of trig here.
+ *
+ * Input:  inner_radius - radius of hole at center
+ *         outer_radius - radius at center of teeth
+ *         width - width of gear
+ *         teeth - number of teeth
+ *         tooth_depth - depth of tooth
+ */
+static void gear( GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
+                 GLint teeth, GLfloat tooth_depth )
+{
+   GLint i;
+   GLfloat r0, r1, r2;
+   GLfloat angle, da;
+   GLfloat u, v, len;
+
+   r0 = inner_radius;
+   r1 = outer_radius - tooth_depth/2.0;
+   r2 = outer_radius + tooth_depth/2.0;
+
+   da = 2.0*M_PI / teeth / 4.0;
+
+   glShadeModel( GL_FLAT );
+
+   glNormal3f( 0.0, 0.0, 1.0 );
+
+   /* draw front face */
+   glBegin( GL_QUAD_STRIP );
+   for (i=0;i<=teeth;i++) {
+      angle = i * 2.0*M_PI / teeth;
+      glVertex3f( r0*cos(angle), r0*sin(angle), width*0.5 );
+      glVertex3f( r1*cos(angle), r1*sin(angle), width*0.5 );
+      glVertex3f( r0*cos(angle), r0*sin(angle), width*0.5 );
+      glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), width*0.5 );
+   }
+   glEnd();
+
+   /* draw front sides of teeth */
+   glBegin( GL_QUADS );
+   da = 2.0*M_PI / teeth / 4.0;
+   for (i=0;i<teeth;i++) {
+      angle = i * 2.0*M_PI / teeth;
+
+      glVertex3f( r1*cos(angle),      r1*sin(angle),      width*0.5 );
+      glVertex3f( r2*cos(angle+da),   r2*sin(angle+da),   width*0.5 );
+      glVertex3f( r2*cos(angle+2*da), r2*sin(angle+2*da), width*0.5 );
+      glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), width*0.5 );
+   }
+   glEnd();
+
+
+   glNormal3f( 0.0, 0.0, -1.0 );
+
+   /* draw back face */
+   glBegin( GL_QUAD_STRIP );
+   for (i=0;i<=teeth;i++) {
+      angle = i * 2.0*M_PI / teeth;
+      glVertex3f( r1*cos(angle), r1*sin(angle), -width*0.5 );
+      glVertex3f( r0*cos(angle), r0*sin(angle), -width*0.5 );
+      glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), -width*0.5 );
+      glVertex3f( r0*cos(angle), r0*sin(angle), -width*0.5 );
+   }
+   glEnd();
+
+   /* draw back sides of teeth */
+   glBegin( GL_QUADS );
+   da = 2.0*M_PI / teeth / 4.0;
+   for (i=0;i<teeth;i++) {
+      angle = i * 2.0*M_PI / teeth;
+
+      glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), -width*0.5 );
+      glVertex3f( r2*cos(angle+2*da), r2*sin(angle+2*da), -width*0.5 );
+      glVertex3f( r2*cos(angle+da),   r2*sin(angle+da),   -width*0.5 );
+      glVertex3f( r1*cos(angle),      r1*sin(angle),      -width*0.5 );
+   }
+   glEnd();
+
+
+   /* draw outward faces of teeth */
+   glBegin( GL_QUAD_STRIP );
+   for (i=0;i<teeth;i++) {
+      angle = i * 2.0*M_PI / teeth;
+
+      glVertex3f( r1*cos(angle),      r1*sin(angle),       width*0.5 );
+      glVertex3f( r1*cos(angle),      r1*sin(angle),      -width*0.5 );
+      u = r2*cos(angle+da) - r1*cos(angle);
+      v = r2*sin(angle+da) - r1*sin(angle);
+      len = sqrt( u*u + v*v );
+      u /= len;
+      v /= len;
+      glNormal3f( v, -u, 0.0 );
+      glVertex3f( r2*cos(angle+da),   r2*sin(angle+da),    width*0.5 );
+      glVertex3f( r2*cos(angle+da),   r2*sin(angle+da),   -width*0.5 );
+      glNormal3f( cos(angle), sin(angle), 0.0 );
+      glVertex3f( r2*cos(angle+2*da), r2*sin(angle+2*da),  width*0.5 );
+      glVertex3f( r2*cos(angle+2*da), r2*sin(angle+2*da), -width*0.5 );
+      u = r1*cos(angle+3*da) - r2*cos(angle+2*da);
+      v = r1*sin(angle+3*da) - r2*sin(angle+2*da);
+      glNormal3f( v, -u, 0.0 );
+      glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da),  width*0.5 );
+      glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), -width*0.5 );
+      glNormal3f( cos(angle), sin(angle), 0.0 );
+   }
+
+   glVertex3f( r1*cos(0), r1*sin(0), width*0.5 );
+   glVertex3f( r1*cos(0), r1*sin(0), -width*0.5 );
+
+   glEnd();
+
+
+   glShadeModel( GL_SMOOTH );
+
+   /* draw inside radius cylinder */
+   glBegin( GL_QUAD_STRIP );
+   for (i=0;i<=teeth;i++) {
+      angle = i * 2.0*M_PI / teeth;
+      glNormal3f( -cos(angle), -sin(angle), 0.0 );
+      glVertex3f( r0*cos(angle), r0*sin(angle), -width*0.5 );
+      glVertex3f( r0*cos(angle), r0*sin(angle), width*0.5 );
+   }
+   glEnd();
+      
+}
+
+
+static GLfloat view_rotx=20.0, view_roty=30.0, view_rotz=0.0;
+static GLint gear1, gear2, gear3;
+static GLfloat angle = 0.0;
+
+static GLuint limit;
+static GLuint count = 1;
+
+
+static void draw( void )
+{
+   angle += 2.0;
+
+   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+
+   glPushMatrix();
+   glRotatef( view_rotx, 1.0, 0.0, 0.0 );
+   glRotatef( view_roty, 0.0, 1.0, 0.0 );
+   glRotatef( view_rotz, 0.0, 0.0, 1.0 );
+
+   glPushMatrix();
+   glTranslatef( -3.0, -2.0, 0.0 );
+   glRotatef( angle, 0.0, 0.0, 1.0 );
+   glCallList(gear1);
+   glPopMatrix();
+
+   glPushMatrix();
+   glTranslatef( 3.1, -2.0, 0.0 );
+   glRotatef( -2.0*angle-9.0, 0.0, 0.0, 1.0 );
+   glCallList(gear2);
+   glPopMatrix();
+
+   glPushMatrix();
+   glTranslatef( -3.1, 4.2, 0.0 );
+   glRotatef( -2.0*angle-25.0, 0.0, 0.0, 1.0 );
+   glCallList(gear3);
+   glPopMatrix();
+
+   glPopMatrix();
+
+   SVGAMesaSwapBuffers();
+}
+
+
+static void init( void )
+{
+   static GLfloat pos[4] = {5.0, 5.0, 10.0, 1.0 };
+   static GLfloat red[4] = {0.8, 0.1, 0.0, 1.0 };
+   static GLfloat green[4] = {0.0, 0.8, 0.2, 1.0 };
+   static GLfloat blue[4] = {0.2, 0.2, 1.0, 1.0 };
+
+   GLfloat w = (float) width / (float) height;
+   GLfloat h = 1.0;
+
+   glLightfv( GL_LIGHT0, GL_POSITION, pos );
+   glEnable( GL_CULL_FACE );
+   glEnable( GL_LIGHTING );
+   glEnable( GL_LIGHT0 );
+   glEnable( GL_DEPTH_TEST );
+
+   /* make the gears */
+   gear1 = glGenLists(1);
+   glNewList(gear1, GL_COMPILE);
+   glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red );
+   gear( 1.0, 4.0, 1.0, 20, 0.7 );
+   glEndList();
+
+   gear2 = glGenLists(1);
+   glNewList(gear2, GL_COMPILE);
+   glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green );
+   gear( 0.5, 2.0, 2.0, 10, 0.7 );
+   glEndList();
+
+   gear3 = glGenLists(1);
+   glNewList(gear3, GL_COMPILE);
+   glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue );
+   gear( 1.3, 2.0, 0.5, 10, 0.7 );
+   glEndList();
+
+   glEnable( GL_NORMALIZE );
+
+
+   glViewport( 0, 0, width, height );
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   if (width>height) {
+      GLfloat w = (GLfloat) width / (GLfloat) height;
+      glFrustum( -w, w, -1.0, 1.0, 5.0, 60.0 );
+   }
+   else {
+      GLfloat h = (GLfloat) height / (GLfloat) width;
+      glFrustum( -1.0, 1.0, -h, h, 5.0, 60.0 );
+   }
+
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+   glTranslatef( 0.0, 0.0, -40.0 );
+}
+
+void setup( void )
+{
+   vga_init();
+
+   vga_setmode(G800x600x32K);
+/*   gl_setcontextvga(G800x600x32K);*/
+
+   vmc = SVGAMesaCreateContext(GL_TRUE);
+   SVGAMesaMakeCurrent( vmc );
+}
+
+
+void end( void )
+{
+   SVGAMesaDestroyContext( vmc );
+
+   vga_setmode( TEXT );
+}
+
+
+int main( int argc, char *argv[] )
+{
+   int i;
+
+   setup();
+   init();
+   for (i=0;i<4;i++) {
+      draw(); /*SVGAMesaSwapBuffers();*/
+   }
+   end();
+   return 0;
+}
diff --git a/progs/xdemos/vindex.c b/progs/xdemos/vindex.c
new file mode 100644 (file)
index 0000000..f9e3192
--- /dev/null
@@ -0,0 +1,66 @@
+/* $Id: vindex.c,v 1.1 1999/08/19 00:55:43 jtg Exp $ */
+
+/*
+ * Test Linux 8-bit SVGA/Mesa color index mode
+ *
+ * Compile with:  gcc vindex.c -I../include -L../lib -lMesaGL -lX11 -lXext
+ *   -lvga -lm -o vindex
+ *
+ * This program is in the public domain.
+ * Brian Paul, January 1996
+ */
+
+
+
+#include <vga.h>
+#include "GL/svgamesa.h"
+#include "GL/gl.h"
+
+
+
+static GLint width = 640, height = 480;
+
+
+
+static void display( void )
+{
+   int i, j;
+   int w, h;
+
+   glViewport( 0, 0, width, height );
+   glMatrixMode( GL_PROJECTION );
+   glLoadIdentity();
+   glOrtho( 0.0, (GLfloat) width, 0.0, (GLfloat) height, -1.0, 1.0 );
+
+   glClear( GL_COLOR_BUFFER_BIT );
+
+   w = width / 16;
+   h = height / 16;
+   for (i=0;i<16;i++) {
+      for (j=0;j<16;j++) {
+         glIndexi( i*16+j );
+         glRecti( i*w, j*h, i*w+w, j*h+h );
+      }
+   }
+}
+
+
+
+int main( int argc, char *argv[] )
+{
+   SVGAMesaContext vmc;
+   int i;
+
+   vga_init();
+   vga_setmode( G640x480x256 );
+
+   vmc = SVGAMesaCreateContext( GL_FALSE );
+   SVGAMesaMakeCurrent( vmc );
+
+   display();
+   sleep(3);
+
+   SVGAMesaDestroyContext( vmc );
+   vga_setmode( TEXT );
+   return 0;
+}
diff --git a/progs/xdemos/vtest.c b/progs/xdemos/vtest.c
new file mode 100644 (file)
index 0000000..f0900b6
--- /dev/null
@@ -0,0 +1,83 @@
+/* $Id: vtest.c,v 1.1 1999/08/19 00:55:43 jtg Exp $ */
+
+/*
+ * Test SVGA/Mesa interface in 32K color mode.
+ *
+ * Compile with:  gcc vtest.c -I../include -L../lib -lMesaGL -lX11 -lXext
+ *   -lvga -lm -o vtest
+ *
+ * This program is in the public domain.
+ * Brian Paul, January 1996
+ */
+
+
+
+#include <vga.h>
+#include "GL/svgamesa.h"
+#include "GL/gl.h"
+
+
+SVGAMesaContext vmc;
+
+
+
+void setup( void )
+{
+   vga_init();
+
+   vga_setmode(G800x600x32K);
+/*   gl_setcontextvga(G800x600x32K);*/
+
+   vmc = SVGAMesaCreateContext( GL_FALSE );  /* single buffered */
+   SVGAMesaMakeCurrent( vmc );
+}
+
+
+void test( void )
+{
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   glOrtho( -1.0, 1.0, -1.0, 1.0, -1.0, 1.0 );
+   glMatrixMode(GL_MODELVIEW);
+
+   glClear( GL_COLOR_BUFFER_BIT );
+
+   glBegin( GL_LINES );
+   glColor3f( 1.0, 0.0, 0.0 );
+   glVertex2f( -0.5, 0.5 );
+   glVertex2f(  0.5, 0.5 );
+   glColor3f( 0.0, 1.0, 0.0 );
+   glVertex2f( -0.5, 0.25 );
+   glVertex2f(  0.5, 0.25 );
+   glColor3f( 0.0, 0.0, 1.0 );
+   glVertex2f( -0.5, 0.0 );
+   glVertex2f(  0.5, 0.0 );
+   glEnd();
+
+   glBegin( GL_POLYGON );
+   glColor3f( 1.0, 0.0, 0.0 );
+   glVertex2f( 0.0, 0.7 );
+   glColor3f( 0.0, 1.0, 0.0 );
+   glVertex2f( -0.5, -0.5 );
+   glColor3f( 0.0, 0.0, 1.0 );
+   glVertex2f(  0.5, -0.5 );
+   glEnd();
+
+   sleep(3);
+}
+
+void end( void )
+{
+   SVGAMesaDestroyContext( vmc );
+
+   vga_setmode( TEXT );
+}
+
+
+int main( int argc, char *argv[] )
+{
+   setup();
+   test();
+   end();
+   return 0;
+}
diff --git a/progs/xdemos/xdemo.c b/progs/xdemos/xdemo.c
new file mode 100644 (file)
index 0000000..13facba
--- /dev/null
@@ -0,0 +1,347 @@
+/* $Id: xdemo.c,v 1.1 1999/08/19 00:55:43 jtg Exp $ */
+
+
+/*
+ * Very simple demo of how to use the Mesa/X11 interface instead of the
+ * glx, tk or aux toolkits.  I highly recommend using the GLX interface
+ * instead of the X/Mesa interface, however.
+ *
+ * This program is in the public domain.
+ *
+ * Brian Paul
+ */
+
+
+/*
+ * $Log: xdemo.c,v $
+ * Revision 1.1  1999/08/19 00:55:43  jtg
+ * Initial revision
+ *
+ * Revision 3.0  1998/02/21 02:16:54  brianp
+ * initial rev
+ *
+ */
+
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include "GL/xmesa.h"
+#include "GL/gl.h"
+
+
+
+static GLint Black, Red, Green, Blue;
+
+
+
+static void make_window( char *title, int color_flag )
+{
+   int x = 10, y = 10, width = 400, height = 300;
+   Display *dpy;
+   int scr;
+   Window root, win;
+   Colormap cmap;
+   XColor xcolor;
+   int attr_flags;
+   XVisualInfo *visinfo;
+   XSetWindowAttributes attr;
+   XTextProperty tp;
+   XSizeHints sh;
+   XEvent e;
+   XMesaContext context;
+   XMesaVisual visual;
+   XMesaBuffer buffer;
+
+
+   /*
+    * Do the usual X things to make a window.
+    */
+
+   dpy = XOpenDisplay(NULL);
+   if (!dpy) {
+      printf("Couldn't open default display!\n");
+      exit(1);
+   }
+
+   scr = DefaultScreen(dpy);
+   root = RootWindow(dpy, scr);
+
+   /* alloc visinfo struct */
+   visinfo = (XVisualInfo *) malloc( sizeof(XVisualInfo) );
+
+   /* Get a visual and colormap */
+   if (color_flag) {
+      /* Open TrueColor window */
+
+/*
+      if (!XMatchVisualInfo( dpy, scr, 24, TrueColor, visinfo )) {
+        printf("Couldn't get 24-bit TrueColor visual!\n");
+        exit(1);
+      }
+*/
+      if (!XMatchVisualInfo( dpy, scr, 8, PseudoColor, visinfo )) {
+        printf("Couldn't get 8-bit PseudoColor visual!\n");
+        exit(1);
+      }
+
+      cmap = XCreateColormap( dpy, root, visinfo->visual, AllocNone );
+      Black = Red = Green = Blue = 0;
+   }
+   else {
+      /* Open color index window */
+
+      if (!XMatchVisualInfo( dpy, scr, 8, PseudoColor, visinfo )) {
+        printf("Couldn't get 8-bit PseudoColor visual\n");
+        exit(1);
+      }
+
+      cmap = XCreateColormap( dpy, root, visinfo->visual, AllocNone );
+
+      /* Allocate colors */
+      xcolor.red   = 0x0;
+      xcolor.green = 0x0;
+      xcolor.blue  = 0x0;
+      xcolor.flags = DoRed | DoGreen | DoBlue;
+      if (!XAllocColor( dpy, cmap, &xcolor )) {
+        printf("Couldn't allocate black!\n");
+        exit(1);
+      }
+      Black = xcolor.pixel;
+
+      xcolor.red   = 0xffff;
+      xcolor.green = 0x0;
+      xcolor.blue  = 0x0;
+      xcolor.flags = DoRed | DoGreen | DoBlue;
+      if (!XAllocColor( dpy, cmap, &xcolor )) {
+        printf("Couldn't allocate red!\n");
+        exit(1);
+      }
+      Red = xcolor.pixel;
+
+      xcolor.red   = 0x0;
+      xcolor.green = 0xffff;
+      xcolor.blue  = 0x0;
+      xcolor.flags = DoRed | DoGreen | DoBlue;
+      if (!XAllocColor( dpy, cmap, &xcolor )) {
+        printf("Couldn't allocate green!\n");
+        exit(1);
+      }
+      Green = xcolor.pixel;
+
+      xcolor.red   = 0x0;
+      xcolor.green = 0x0;
+      xcolor.blue  = 0xffff;
+      xcolor.flags = DoRed | DoGreen | DoBlue;
+      if (!XAllocColor( dpy, cmap, &xcolor )) {
+        printf("Couldn't allocate blue!\n");
+        exit(1);
+      }
+      Blue = xcolor.pixel;
+   }
+
+   /* set window attributes */
+   attr.colormap = cmap;
+   attr.event_mask = ExposureMask | StructureNotifyMask;
+   attr.border_pixel = BlackPixel( dpy, scr );
+   attr.background_pixel = BlackPixel( dpy, scr );
+   attr_flags = CWColormap | CWEventMask | CWBorderPixel | CWBackPixel;
+
+   /* Create the window */
+   win = XCreateWindow( dpy, root, x,y, width, height, 0,
+                           visinfo->depth, InputOutput,
+                           visinfo->visual,
+                           attr_flags, &attr);
+   if (!win) {
+      printf("Couldn't open window!\n");
+      exit(1);
+   }
+
+   XStringListToTextProperty(&title, 1, &tp);
+   sh.flags = USPosition | USSize;
+   XSetWMProperties(dpy, win, &tp, &tp, 0, 0, &sh, 0, 0);
+   XMapWindow(dpy, win);
+   while (1) {
+      XNextEvent( dpy, &e );
+      if (e.type == MapNotify && e.xmap.window == win) {
+        break;
+      }
+   }
+
+
+   /*
+    * Now do the special Mesa/Xlib stuff!
+    */
+
+   visual = XMesaCreateVisual( dpy, visinfo,
+                              (GLboolean) color_flag,
+                               GL_FALSE,  /* alpha_flag */
+                               GL_FALSE,  /* db_flag */
+                               GL_FALSE,  /* stereo flag */
+                               GL_FALSE,  /* ximage_flag */
+                               0,         /* depth size */
+                               0,         /* stencil size */
+                               0,         /* accum_size */
+                               0          /* level */
+                              );
+   if (!visual) {
+      printf("Couldn't create Mesa/X visual!\n");
+      exit(1);
+   }
+
+   /* Create a Mesa rendering context */
+   context = XMesaCreateContext( visual,
+                                 NULL       /* share_list */
+                               );
+   if (!context) {
+      printf("Couldn't create Mesa/X context!\n");
+      exit(1);
+   }
+
+   buffer = XMesaCreateWindowBuffer( visual, win );
+   if (!buffer) {
+      printf("Couldn't create Mesa/X buffer!\n");
+      exit(1);
+   }
+
+
+   XMesaMakeCurrent( context, buffer );
+
+   /* Ready to render! */
+}
+
+
+
+static void draw_cube( void )
+{
+   /* X faces */
+   glIndexi( Red );
+   glColor3f( 1.0, 0.0, 0.0 );
+   glBegin( GL_POLYGON );
+   glVertex3f( 1.0, 1.0, 1.0 );
+   glVertex3f( 1.0, -1.0, 1.0 );
+   glVertex3f( 1.0, -1.0, -1.0 );
+   glVertex3f( 1.0, 1.0, -1.0 );
+   glEnd();
+
+   glBegin( GL_POLYGON );
+   glVertex3f( -1.0, 1.0, 1.0 );
+   glVertex3f( -1.0, 1.0, -1.0 );
+   glVertex3f( -1.0, -1.0, -1.0 );
+   glVertex3f( -1.0, -1.0, 1.0 );
+   glEnd();
+
+   /* Y faces */
+   glIndexi( Green );
+   glColor3f( 0.0, 1.0, 0.0 );
+   glBegin( GL_POLYGON );
+   glVertex3f(  1.0, 1.0,  1.0 );
+   glVertex3f(  1.0, 1.0, -1.0 );
+   glVertex3f( -1.0, 1.0, -1.0 );
+   glVertex3f( -1.0, 1.0,  1.0 );
+   glEnd();
+
+   glBegin( GL_POLYGON );
+   glVertex3f(  1.0, -1.0,  1.0 );
+   glVertex3f( -1.0, -1.0,  1.0 );
+   glVertex3f( -1.0, -1.0, -1.0 );
+   glVertex3f(  1.0, -1.0, -1.0 );
+   glEnd();
+
+   /* Z faces */
+   glIndexi( Blue );
+   glColor3f( 0.0, 0.0, 1.0 );
+   glBegin( GL_POLYGON );
+   glVertex3f(  1.0,  1.0,  1.0 );
+   glVertex3f( -1.0,  1.0,  1.0 );
+   glVertex3f( -1.0, -1.0,  1.0 );
+   glVertex3f(  1.0, -1.0,  1.0 );
+   glEnd();
+
+   glBegin( GL_POLYGON );
+   glVertex3f(  1.0, 1.0, -1.0 );
+   glVertex3f(  1.0,-1.0, -1.0 );
+   glVertex3f( -1.0,-1.0, -1.0 );
+   glVertex3f( -1.0, 1.0, -1.0 );
+   glEnd();
+}
+
+
+
+
+static void display_loop( void )
+{
+   GLfloat xrot, yrot, zrot;
+
+   xrot = yrot = zrot = 0.0;
+
+   glClearColor( 0.0, 0.0, 0.0, 0.0 );
+   glClearIndex( Black );
+
+   glMatrixMode( GL_PROJECTION );
+   glLoadIdentity();
+   glFrustum( -1.0, 1.0,  -1.0, 1.0,  1.0, 10.0 );
+   glTranslatef( 0.0, 0.0, -5.0 );
+
+   glMatrixMode( GL_MODELVIEW );
+   glLoadIdentity();
+
+   glCullFace( GL_BACK );
+   glEnable( GL_CULL_FACE );
+
+   glShadeModel( GL_FLAT );
+
+   while (1) {
+      glClear( GL_COLOR_BUFFER_BIT );
+      glPushMatrix();
+      glRotatef( xrot, 1.0, 0.0, 0.0 );
+      glRotatef( yrot, 0.0, 1.0, 0.0 );
+      glRotatef( zrot, 0.0, 0.0, 1.0 );
+
+      draw_cube();
+
+      glPopMatrix();
+      glFinish();
+
+      xrot += 10.0;
+      yrot += 7.0;
+      zrot -= 3.0;
+   }
+
+}
+
+
+
+
+int main( int argc, char *argv[] )
+{
+   int mode = 0;
+
+   if (argc >= 2)
+   {
+        if (strcmp(argv[1],"-ci")==0)
+           mode = 0;
+        else if (strcmp(argv[1],"-rgb")==0)
+           mode = 1;
+        else
+        {
+           printf("Bad flag: %s\n", argv[1]);
+           printf("Specify -ci for 8-bit color index or -rgb for RGB mode\n");
+           exit(1);
+        }
+   }
+   else
+   {
+        printf("Specify -ci for 8-bit color index or -rgb for RGB mode\n");
+        printf("Defaulting to  8-bit color index\n");
+   }
+
+   make_window( argv[0], mode );
+
+   display_loop();
+   return 0;
+}
+
diff --git a/progs/xdemos/xfont.c b/progs/xdemos/xfont.c
new file mode 100644 (file)
index 0000000..31bfb4b
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+ */
+/*
+ *  xfont.c
+ *  Draws some text in a bitmapped font.  Uses glBitmap() 
+ *  and other pixel routines.  Also demonstrates use of 
+ *  display lists.
+ */
+#include <GL/gl.h>
+#include <GL/glu.h>
+#include <GL/glx.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "glaux.h"
+
+GLuint base;
+
+void makeRasterFont(void)
+{
+    XFontStruct *fontInfo;
+    Font id;
+    unsigned int first, last;
+    Display *xdisplay;
+
+    xdisplay = auxXDisplay ();
+    fontInfo = XLoadQueryFont(xdisplay, 
+       "-adobe-helvetica-medium-r-normal--17-120-100-100-p-88-iso8859-1");
+    if (fontInfo == NULL) {
+        printf ("no font found\n");
+       exit (0);
+    }
+
+    id = fontInfo->fid;
+    first = fontInfo->min_char_or_byte2;
+    last = fontInfo->max_char_or_byte2;
+
+    base = glGenLists((GLuint) last+1);
+    if (base == 0) {
+        printf ("out of display lists\n");
+       exit (0);
+    }
+    glXUseXFont(id, first, last-first+1, base+first);
+/*    *height = fontInfo->ascent + fontInfo->descent;
+    *width = fontInfo->max_bounds.width;  */
+}
+
+void printString(char *s)
+{
+    glPushAttrib (GL_LIST_BIT);
+    glListBase(base);
+    glCallLists(strlen(s), GL_UNSIGNED_BYTE, (GLubyte *)s);
+    glPopAttrib ();
+}
+
+void myinit (void) 
+{
+    makeRasterFont ();
+    glShadeModel (GL_FLAT);    
+}
+
+void display(void)
+{
+    GLfloat white[3] = { 1.0, 1.0, 1.0 };
+    int i, j;
+    char teststring[33];
+
+    glClear(GL_COLOR_BUFFER_BIT);
+    glColor3fv(white);
+    for (i = 32; i < 127; i += 32) {
+       glRasterPos2i(20, 200 - 18*(GLint) i/32);
+       for (j = 0; j < 32; j++)
+           teststring[j] = (char) (i+j);
+       teststring[32] = 0;
+       printString(teststring);
+    }
+    glRasterPos2i(20, 100);
+    printString("The quick brown fox jumps");
+    glRasterPos2i(20, 82);
+    printString("over a lazy dog.");
+    glFlush ();
+}
+
+void myReshape(int w, int h)
+{
+    glViewport(0, 0, w, h);
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    glOrtho (0.0, (GLfloat) w, 0.0, (GLfloat) h, -1.0, 1.0);
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
+}
+
+/*  Main Loop
+ *  Open window with initial window size, title bar, 
+ *  RGBA display mode, and handle input events.
+ */
+int main(int argc, char** argv)
+{
+    auxInitDisplayMode (AUX_SINGLE | AUX_RGB);
+    auxInitPosition (0, 0, 500, 500);
+    if (!auxInitWindow (argv[0]))
+       auxQuit();
+    auxReshapeFunc (myReshape);
+    myinit ();
+    auxMainLoop(display);
+    return 0;
+}
+
+
+
+
diff --git a/src/glu/mesa/Makefile.BeOS b/src/glu/mesa/Makefile.BeOS
new file mode 100644 (file)
index 0000000..d1e489c
--- /dev/null
@@ -0,0 +1,73 @@
+# Makefile for GLU for BeOS contributed by
+# Tinic Uro <5uro@informatik.uni-hamburg.de>
+
+# Mesa 3-D graphics library
+# Version:  2.6
+# Copyright (C) 1995-1997  Brian Paul
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the Free
+# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+
+##### MACROS #####
+
+VPATH = RCS
+
+INCDIR = ../include
+LIBDIR = ../lib
+
+SOURCES = glu.c mipmap.c nurbs.c nurbscrv.c nurbssrf.c nurbsutl.c \
+       project.c quadric.c tess.c tesselat.c polytest.c
+
+OBJECTS = $(SOURCES:.c=.o)
+
+
+
+##### RULES #####
+
+.c.o:
+       $(CC) -c -i . -i- -i $(INCDIR) $(CFLAGS) $<
+
+
+
+##### TARGETS #####
+
+default:
+       @echo "Specify a target configuration"
+
+clean:
+       -rm *.o *~
+
+targets: $(LIBDIR)/$(GLU_LIB)
+
+# Make the library:
+$(LIBDIR)/$(GLU_LIB): $(OBJECTS)
+       $(MAKELIB) $(GLU_LIB) 2 6 $(OBJECTS)
+#      $(RANLIB) $(GLU_LIB)
+       mv $(GLU_LIB)* $(LIBDIR)
+
+include ../Make-config
+
+include depend
+
+
+
+#
+# Run 'make depend' to update the dependencies if you change what's included
+# by any source file.
+# 
+depend: $(SOURCES)
+       makedepend -fdepend -Y -I../include $(SOURCES)
+
diff --git a/src/glu/mesa/Makefile.BeOS-R4 b/src/glu/mesa/Makefile.BeOS-R4
new file mode 100644 (file)
index 0000000..d664534
--- /dev/null
@@ -0,0 +1,85 @@
+# Makefile for GLU for BeOS R4
+
+# Mesa 3-D graphics library
+# Version:  3.1
+# Copyright (C) 1995-1999  Brian Paul
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the Free
+# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+# $Id: Makefile.BeOS-R4,v 1.1 1999/08/19 00:55:42 jtg Exp $
+
+# $Log: Makefile.BeOS-R4,v $
+# Revision 1.1  1999/08/19 00:55:42  jtg
+# Initial revision
+#
+# Revision 1.2  1999/02/02 04:44:40  brianp
+# fixed some problems
+#
+# Revision 1.1  1999/01/19 04:10:02  brianp
+# Initial revision
+#
+
+
+
+##### MACROS #####
+
+VPATH = RCS
+
+INCDIR = ../include
+LIBDIR = ../lib
+
+SOURCES = glu.c mipmap.c nurbs.c nurbscrv.c nurbssrf.c nurbsutl.c \
+       project.c quadric.c tess.c tesselat.c polytest.c
+
+OBJECTS = $(SOURCES:.c=.o)
+
+
+
+##### TARGETS #####
+
+default:
+       @echo "Specify a target configuration"
+
+clean:
+       -rm *.o *~
+
+targets: $(LIBDIR)/$(GLU_LIB)
+
+# Make the library:
+$(LIBDIR)/$(GLU_LIB): $(OBJECTS)
+       $(MAKELIB) $(GLU_LIB) $(MAJOR) $(MINOR) -L$(LIBDIR) -lMesaGL $(OBJECTS)
+       mv $(GLU_LIB)* $(LIBDIR)
+
+include ../Make-config
+
+include depend
+
+
+
+##### RULES #####
+
+.c.o:
+       $(CC) -c -I. -I../ -I$(INCDIR) $(CFLAGS) $<
+
+
+
+#
+# Run 'make depend' to update the dependencies if you change what's included
+# by any source file.
+# 
+depend: $(SOURCES)
+       makedepend -fdepend -Y -I../include $(SOURCES)
+
diff --git a/src/glu/mesa/Makefile.X11 b/src/glu/mesa/Makefile.X11
new file mode 100644 (file)
index 0000000..c155aea
--- /dev/null
@@ -0,0 +1,57 @@
+# $Id: Makefile.X11,v 1.1 1999/08/19 00:55:42 jtg Exp $
+
+# Mesa 3-D graphics library
+# Version:  3.1
+# Copyright (C) 1995-1999  Brian Paul
+
+# Makefile for GLU library
+
+
+##### MACROS #####
+
+VPATH = RCS
+
+INCDIR = ../include
+LIBDIR = ../lib
+
+SOURCES = glu.c mipmap.c nurbs.c nurbscrv.c nurbssrf.c nurbsutl.c \
+       project.c quadric.c tess.c tesselat.c polytest.c
+
+OBJECTS = $(SOURCES:.c=.o)
+
+
+
+##### RULES #####
+
+.c.o:
+       $(CC) -c -I$(INCDIR) $(CFLAGS) $<
+
+
+
+##### TARGETS #####
+
+default:
+       @echo "Specify a target configuration"
+
+clean:
+       -rm *.o *~
+
+targets: $(LIBDIR)/$(GLU_LIB)
+
+# Make the library:
+$(LIBDIR)/$(GLU_LIB): $(OBJECTS)
+       $(MAKELIB) $(GLU_LIB) $(MAJOR) $(MINOR) $(OBJECTS)
+       mv $(GLU_LIB)* $(LIBDIR)
+
+include ../Make-config
+
+include depend
+
+
+
+#
+# Run 'make depend' to update the dependencies if you change what's included
+# by any source file.
+# 
+dep: $(SOURCES)
+       makedepend -fdepend -Y -I../include $(SOURCES)
diff --git a/src/glu/mesa/MesaGLU.def b/src/glu/mesa/MesaGLU.def
new file mode 100644 (file)
index 0000000..8b1c444
--- /dev/null
@@ -0,0 +1,54 @@
+LIBRARY MESAGLU\r
+DESCRIPTION 'GLU for Windows Mesa'\r
+EXETYPE WINDOWS\r
+CODE MOVEABLE DISCARDABLE\r
+DATA MOVEABLE SINGLE\r
+HEAPSIZE 256000\r
+\r
+STACKSIZE 4096\r
+\r
+EXPORTS\r
+    gluLookAt\r
+    gluOrtho2D\r
+    gluPerspective\r
+    gluPickMatrix\r
+    gluProject\r
+    gluUnProject\r
+    gluErrorString\r
+    gluScaleImage\r
+    gluBuild1DMipmaps\r
+    gluBuild2DMipmaps\r
+    gluNewQuadric\r
+    gluDeleteQuadric\r
+    gluQuadricDrawStyle\r
+    gluQuadricOrientation\r
+    gluQuadricNormals\r
+    gluQuadricTexture\r
+    gluQuadricCallback\r
+    gluCylinder\r
+    gluSphere\r
+    gluDisk\r
+    gluPartialDisk\r
+    gluNewNurbsRenderer\r
+    gluDeleteNurbsRenderer\r
+    gluLoadSamplingMatrices\r
+    gluNurbsProperty\r
+    gluGetNurbsProperty\r
+    gluBeginCurve\r
+    gluEndCurve\r
+    gluNurbsCurve\r
+    gluBeginSurface\r
+    gluEndSurface\r
+    gluNurbsSurface\r
+    gluBeginTrim\r
+    gluEndTrim\r
+    gluPwlCurve\r
+    gluNurbsCallback\r
+    gluNewTess\r
+    gluTessCallback\r
+    gluDeleteTess\r
+    gluBeginPolygon\r
+    gluEndPolygon\r
+    gluNextContour\r
+    gluTessVertex\r
+    gluGetString\r
diff --git a/src/glu/mesa/README1 b/src/glu/mesa/README1
new file mode 100644 (file)
index 0000000..7596857
--- /dev/null
@@ -0,0 +1,195 @@
+
+Notes on the GLU polygon tesselation facility implemented by Bogdan Sikorski...
+
+
+
+The tesselation module is provided under the same terms as the Mesa
+package.
+
+This is the first release of polygon tesselation code for Mesa.
+It was written during my very little free time, so lets name it:
+"its not perfect". If someone hates pointers, don't look at the code.
+I preffer dynamic allocation versus static. But _all_ ideas, suggestions,
+bug reports and fixes are welcome (if You want, also flames). I am aware
+that many things could have been written using better techniques, but time
+that I could devote to this library was very limited. It is not well commented,
+excuse me. Also I am thinking of continuing working on this code to improve,
+fix and polish it. And make it as compliant as possible to the OpenGL, so
+software ports from OpenGL to Mesa will work correctly. If You know of any
+differences in behaviour, expected input/output between Mesa tesselation library
+and OpenGL, please send me a note. I explain later on why I am not
+confident with this code.
+
+I tried to be fully compliant with the OpenGL routines. By "tried" I mean that
+up to my knowledge it behaves as OpenGL tesselation routines. Just recently
+I began to experiment with OpenGL (actually only Mesa), and also have
+no access to any machine providing official implementation of OpenGL,
+nor access to books (particulary Addison-Wesley publications). Thus my
+knowledge on how the original tesselation code works, what kind of data
+it expects etc. is based _only_ on the publicly available documentation
+provided by SGI. Namely:
+
+* "The OpenGL Graphics System Utility Library" by K.P.Smith
+       (Silicon Graphics, 1992)
+* "The OpenGL Graphics Interface" by M.Segal and K.Akeley
+       (Silicon Graphics, 19??)
+* "OpenGL and X, Part 1: Introduction" by M.J.Kilgard
+       (Silicon Graphics, 1994)
+* "OpenGL and X, Part 2: Using OpenGL with Xlib" by M.J.Kilgard
+       (Silicon Graphics, 1994)
+* "OpenGL Graphics with the X Window System" by P.Karlton
+       (Silicon Graphics, 1993)
+* Online Docs - Appendix C of OpenGL Programming Guide, Polygon Tesselation
+        (partial text cut and sent by e-mail)
+
+
+The tesselation routines use slightly different prototypes than the ones
+specified in the mentioned above publications. The _only_ differences are
+the enumeration types which are not GLenum, but are GLUenum. So the
+implemented routines have following prototypes:
+
+GLUtringulatorObj *gluNewTess(void);
+
+void gluTessCallback(GLUtriangulatorObj *,GLUenum,void (*)());
+                                          ^^^^^^^
+void gluBeginPolygon(GLUtriangulatorObj *);
+
+void gluTessVertex(GLUtriangulatorObj *,GLdouble [3],void *);
+
+void gluNextContour(GLUtriangulatorObj *,GLUenum);
+                                         ^^^^^^^
+void gluEndPolygon(GLUtriangulatorObj *);
+
+const GLubyte *gluErrorString(GLUenum);
+                              ^^^^^^^
+       prototypes for callback functions:
+
+void <begin>(GLUenum);
+             ^^^^^^^
+void <edgeFlag>(GLboolean);
+void <vertex>(void *);
+void <end>(void);
+void <error>(GLUenum);
+             ^^^^^^^
+
+The begin callback will be called only with GLU_TRIANGLES. No support
+for traingle fans or strips yet.        
+
+In case of errors an internal error variable is set to the appropiate 
+error enum values (GLU_TESS_ERROR?). Initially it is set to GLU_NO_ERROR.
+The OpenGL library provides 8 error conditions, the tesselation code
+of Mesa provides 9. They are:
+
+GLU_TESS_ERROR1: missing gluEndPolygon                  /* same as OpenGL */
+GLU_TESS_ERROR2: missing gluBeginPolygon                /* same as OpenGL */
+GLU_TESS_ERROR3: misoriented contour                    /* not used in Mesa
+                         in OpenGL is bad orientation or intersecting edges */
+GLU_TESS_ERROR4: vertex/edge intersection               /* same as OpenGL */
+GLU_TESS_ERROR5: misoriented or self-intersecting loops /* same as OpenGL */
+GLU_TESS_ERROR6: coincident vertices                    /* same as OpenGL */
+GLU_TESS_ERROR7: colinear vertices                      /* OpenGL's illegal data */
+GLU_TESS_ERROR8: intersecting edges                     /* same as OpenGL */
+GLU_TESS_ERROR9: not coplanar contours                  /* new for Mesa */
+
+The Mesa tesselation code ignores all data and calls after detecting an error
+codition. This means that a _new_ tesselation object must be used for further
+triangulations. Maybe this is too restrictive, and will be lifted in
+future versions.
+
+The tesselation code completely ignores the type parameter passed in
+gluNextContour. It also doesn't check if the passed parameter is a legal
+enum value - ignores silently (maybe at least this should be checked).
+The reason I chose this behaviour is based on what I read in the 
+beforementioned documents. I cite:
+
+"....
+void gluNextContour(GLUtriangulatorObj *tessobj, GLenum type);
+
+Marks the beginning of the next contour when multiple contours make up the
+boundary of the polygon to be tessellated. type can be GLU_EXTERIOR,
+GLU_INTERIOR, GLU_CCW, GLU_CW, or GLU_UNKNOWN. These serve only as 
+to the tessellation. If you get them right, the tessellation might
+go faster. If you get them wrong, they're ignored, and the tesselation still
+works.
+....."
+
+I hope You agree with me that my decision was correct. Mesa tesselation
+_always_ checks by itself the interrelations between contours. Just as if
+all contours were specified with the type GLU_UNKNOWN.
+
+One of OpenGL's policy is not to check all error conditions - rely sometimes
+that the user "got things right". This is justified, since exhausting
+error checking is timeconsuming, and would significantly slow down
+a correct application. The Mesa tesselation code assumes only _one_ condition
+when triangulating - all vertices in a contour are planar. This is _not_
+checked for correctness. Trying to tesselate such objects will lead to
+unpredictable output.
+
+And now we arrive to the moment where I would like to list the required
+(but checked for) conditions for triangulation, as well as summarize the
+library:
+
+* all contours in a single tesselation cycle _must_ be coplanar - if not
+       an error is raised (and if provided a call to the error callback
+       is made)
+* the contours can be passed in _any_ order, exteriors and holes can be
+       intermixed within a tesselation cycle and the correct hierarchy
+       will be determined by the library; thus specifying first holes then
+       exteriors, then holes within holes form a valid input.
+* a hole within a hole is consider to be a yet another exterior contour
+* multiple exterior contours (polygons) can be tesselated in one cycle;
+       _but_ this significantly degrades performance since many tests will be
+       performed for every contour pair; if You want triangulation to be fast
+       tesselate a single polygon (with possible holes) one at a time.
+* orientation of exterior contours is arbitray, but if it has holes,
+       all interior holes of this particular exterior contour _must_ have an
+       opposite orientation.
+* the output triangles have the same orientation as the exterior contour
+       that forms them
+* each triangle is "enclosed" within the begin and end callbacks;
+       this is not efficent, but was made on purpose; so if triangulation
+       results in 2 triangles the following callbacks will be made in such
+       order:
+       <begin>(GLU_TRAINGLES)
+       <vertex>(...) /* 3 vertices of first triangle */
+       <vertex>(...)
+       <vertex>(...)
+       <end>()
+       <begin>(GLU_TRAINGLES)
+       <vertex>(...) /* 3 vertices of second triangle */
+       <vertex>(...)
+       <vertex>(...)
+       <end>()
+       Of course only when begin, vertex, and end callback were provided,
+       otherwise no output is done (actually tesselation does not take place).
+* You will notice that some output traingles are very "thin"; there
+       exist possible several ways to traingulate a polygon, but "smart" code
+       avoiding such cases would require time to write, and will impact on
+       execution speed.
+* like OpenGL, no new vertices are introduced during triangulation
+* if the edgeflag callback is provided it will be called whenever
+       the just-about-to be output vertex begins a different type of edge
+       than the previous vertices; always before the first output a call
+       is made with GL_TRUE, to allow synchronization.
+* all intermediate computations are done using GLdouble type, and comparisons
+       are biased with a precision value (EPSILON defined in tess.h)
+* the point_in_poly function is my adaptation of code from the
+       comp.graphics.alg newsgroup FAQ (originally written by Mr. Wm. Randolph
+       Franklin, modified by Scott Anguish).
+* the edge_edge_intersect test is also an adopted code from comp.graphics.alg
+       newsgroup FAQ
+* the general idea for traingulation used in this library is described in
+       the book "Computational Geometry in C" by Joseph O'Rourke.
+
+
+Excuse my English, its not my mother tongue. I should be available for some
+time uner the following e-mail address. But For how long I am not certain.
+Once I am settled in my new place, I'll post on the Mesa mailing list
+my new address.
+
+(PS: today is my last day of work here, I'm changing my job).
+
+Bogdan. ( bogdan@dia.unisa.it )
+
+Apr 28, 1995.
+
diff --git a/src/glu/mesa/README2 b/src/glu/mesa/README2
new file mode 100644 (file)
index 0000000..3c99591
--- /dev/null
@@ -0,0 +1,43 @@
+The current NURBS implementation has no trimming facilities yet.
+
+The code is not well commented.
+
+1) Normal calculus fails for special cases of NURBS (independent
+  of the NURBS modules)
+  Those cases arise when for u or v, some control points
+  for a fixed value of that parameter form the same point.
+  Imagine a Bezier patch degenerated into a "triangle".
+
+  v ^          0,1,2        order=3
+    |            *
+    |
+    |       3*  4*  5*
+    |
+    |    6*     7*     8*
+    |
+    |
+    +------------------------> u
+
+  The calculus of du derivative at triple point (0,1 and 2) will fail.
+  As a result, the normal vector will be 0.
+  The eval2.c code has to be changed to handle the above situation.
+
+2) Adjacent NURBS surfaces ("sharing" the same control points along
+  the "joining" edge) will be sampled with the same factor.
+  This prevents the formation of "cracks".
+  When the control polygon of the "shared" edge is not the same,
+  cracks might appear.
+
+The sampling tolerance is sometimes not respected!
+A NURBS object is broken into Bezier curves/surfaces. If one of such
+Bezier objects has a local high curvature with other portions of it
+relatively flat then the high curvature part will be sampled more dense that
+its flatter regions.
+The flat regions might be tesselated into quads having sides of length
+greater than the current sampling tolernace setting.
+I believe such behaviour is acceptable, though not along the concept of
+sampling tolerance.
+
+February 20, 1996.
+
+Bogdan.  
diff --git a/src/glu/mesa/all.h b/src/glu/mesa/all.h
new file mode 100644 (file)
index 0000000..3712ca8
--- /dev/null
@@ -0,0 +1,69 @@
+/* $Id: all.h,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  2.3
+ * Copyright (C) 1995-1997  Brian Paul
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/*
+ * $Log: all.h,v $
+ * Revision 1.1  1999/08/19 00:55:42  jtg
+ * Initial revision
+ *
+ * Revision 1.2  1997/11/20 00:28:20  brianp
+ * changed PCH to PC_HEADER
+ *
+ * Revision 1.1  1997/05/28 02:29:14  brianp
+ * Initial revision
+ *
+ */
+
+
+/*
+ * This file includes all .h files needed for the GLU source code for
+ * the purpose of precompiled headers.
+ *
+ * If the preprocessor symbol PCH is defined at compile time then each
+ * of the .c files will #include "all.h" only, instead of a bunch of
+ * individual .h files.
+ */
+
+
+#ifndef GLU_ALL_H
+#define GLU_ALL_H
+
+
+#ifndef PC_HEADER
+  This is an error.  all.h should be included only if PCH is defined.
+#endif
+
+
+#include <assert.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "GL/gl.h"
+#include "GL/glu.h"
+#include "gluP.h"
+#include "nurbs.h"
+#include "tess.h"
+
+
+#endif /*GLU_ALL_H*/
diff --git a/src/glu/mesa/descrip.mms b/src/glu/mesa/descrip.mms
new file mode 100644 (file)
index 0000000..b660f69
--- /dev/null
@@ -0,0 +1,62 @@
+# Makefile for GLU for VMS
+# contributed by Jouk Jansen  joukj@crys.chem.uva.nl
+
+.first
+       define gl [-.include.gl]
+
+.include [-]mms-config.
+
+##### MACROS #####
+
+VPATH = RCS
+
+INCDIR = $disk2:[-.include]
+LIBDIR = [-.lib]
+CFLAGS = /include=$(INCDIR)/define=(FBIND=1)
+
+SOURCES = glu.c mipmap.c nurbs.c nurbscrv.c nurbssrf.c nurbsutl.c \
+       project.c quadric.c tess.c tesselat.c polytest.c
+
+OBJECTS =glu.obj,mipmap.obj,nurbs.obj,nurbscrv.obj,nurbssrf.obj,nurbsutl.obj,\
+       project.obj,quadric.obj,tess.obj,tesselat.obj,polytest.obj
+
+
+
+##### RULES #####
+
+VERSION=MesaGlu V3.1
+
+##### TARGETS #####
+
+# Make the library:
+$(LIBDIR)$(GLU_LIB) : $(OBJECTS)
+.ifdef SHARE
+  @ WRITE_ SYS$OUTPUT "  generating mesagl1.opt"
+  @ OPEN_/WRITE FILE  mesagl1.opt
+  @ WRITE_ FILE "!"
+  @ WRITE_ FILE "! mesagl1.opt generated by DESCRIP.$(MMS_EXT)" 
+  @ WRITE_ FILE "!"
+  @ WRITE_ FILE "IDENTIFICATION=""$(VERSION)"""
+  @ WRITE_ FILE "GSMATCH=LEQUAL,3,1
+  @ WRITE_ FILE "$(OBJECTS)"
+  @ WRITE_ FILE "[-.lib]libmesagl.exe/SHARE"
+  @ WRITE_ FILE "SYS$SHARE:DECW$XEXTLIBSHR/SHARE"
+  @ WRITE_ FILE "SYS$SHARE:DECW$XLIBSHR/SHARE"
+  @ CLOSE_ FILE
+  @ WRITE_ SYS$OUTPUT "  generating mesagl.map ..."
+  @ LINK_/NODEB/NOSHARE/NOEXE/MAP=mesagl.map/FULL mesagl1.opt/OPT
+  @ WRITE_ SYS$OUTPUT "  analyzing mesagl.map ..."
+  @ @[-.vms]ANALYZE_MAP.COM mesagl.map mesagl.opt
+  @ WRITE_ SYS$OUTPUT "  linking $(GLU_LIB) ..."
+  @ LINK_/noinform/NODEB/SHARE=$(GLU_LIB)/MAP=mesagl.map/FULL mesagl1.opt/opt,mesagl.opt/opt
+.else
+  @ $(MAKELIB) $(GLU_LIB) $(OBJECTS)
+.endif
+  @ rename $(GLU_LIB)* $(LIBDIR)
+
+clean :
+       delete *.obj;*
+       purge
+
+include mms_depend.
+
diff --git a/src/glu/mesa/glu.c b/src/glu/mesa/glu.c
new file mode 100644 (file)
index 0000000..2cceb8b
--- /dev/null
@@ -0,0 +1,335 @@
+/* $Id: glu.c,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * Copyright (C) 1995-1999  Brian Paul
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/*
+ * $Log: glu.c,v $
+ * Revision 1.1  1999/08/19 00:55:42  jtg
+ * Initial revision
+ *
+ * Revision 1.13  1999/03/31 19:07:28  brianp
+ * added GL_EXT_abgr to extensions
+ *
+ * Revision 1.12  1999/02/06 06:12:41  brianp
+ * updated version string to 3.1
+ *
+ * Revision 1.11  1999/01/03 03:23:15  brianp
+ * now using GLAPIENTRY and GLCALLBACK keywords (Ted Jump)
+ *
+ * Revision 1.10  1998/04/22 00:35:50  brianp
+ * changed version to 3.0
+ *
+ * Revision 1.9  1997/12/09 03:03:32  brianp
+ * changed version to 2.6
+ *
+ * Revision 1.8  1997/10/04 01:30:20  brianp
+ * changed version to 2.5
+ *
+ * Revision 1.7  1997/08/13 01:25:21  brianp
+ * changed version string to 2.4
+ *
+ * Revision 1.6  1997/07/24 01:28:44  brianp
+ * changed precompiled header symbol from PCH to PC_HEADER
+ *
+ * Revision 1.5  1997/07/13 22:59:11  brianp
+ * added const to viewport parameter of gluPickMatrix()
+ *
+ * Revision 1.4  1997/05/28 02:29:38  brianp
+ * added support for precompiled headers (PCH), inserted APIENTRY keyword
+ *
+ * Revision 1.3  1997/04/12 16:19:02  brianp
+ * changed version to 2.3
+ *
+ * Revision 1.2  1997/03/11 00:58:34  brianp
+ * changed version to 2.2
+ *
+ * Revision 1.1  1996/09/27 01:19:39  brianp
+ * Initial revision
+ *
+ */
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "gluP.h"
+#endif
+
+
+/*
+ * Miscellaneous utility functions
+ */
+
+
+#ifndef M_PI
+#define M_PI 3.1415926536
+#endif
+#define EPS 0.00001
+
+
+
+
+void GLAPIENTRY gluLookAt( GLdouble eyex, GLdouble eyey, GLdouble eyez,
+                         GLdouble centerx, GLdouble centery, GLdouble centerz,
+                         GLdouble upx, GLdouble upy, GLdouble upz )
+{
+   GLdouble m[16];
+   GLdouble x[3], y[3], z[3];
+   GLdouble mag;
+
+   /* Make rotation matrix */
+
+   /* Z vector */
+   z[0] = eyex - centerx;
+   z[1] = eyey - centery;
+   z[2] = eyez - centerz;
+   mag = sqrt( z[0]*z[0] + z[1]*z[1] + z[2]*z[2] );
+   if (mag) {  /* mpichler, 19950515 */
+      z[0] /= mag;
+      z[1] /= mag;
+      z[2] /= mag;
+   }
+
+   /* Y vector */
+   y[0] = upx;
+   y[1] = upy;
+   y[2] = upz;
+
+   /* X vector = Y cross Z */
+   x[0] =  y[1]*z[2] - y[2]*z[1];
+   x[1] = -y[0]*z[2] + y[2]*z[0];
+   x[2] =  y[0]*z[1] - y[1]*z[0];
+
+   /* Recompute Y = Z cross X */
+   y[0] =  z[1]*x[2] - z[2]*x[1];
+   y[1] = -z[0]*x[2] + z[2]*x[0];
+   y[2] =  z[0]*x[1] - z[1]*x[0];
+
+   /* mpichler, 19950515 */
+   /* cross product gives area of parallelogram, which is < 1.0 for
+    * non-perpendicular unit-length vectors; so normalize x, y here
+    */
+
+   mag = sqrt( x[0]*x[0] + x[1]*x[1] + x[2]*x[2] );
+   if (mag) {
+      x[0] /= mag;
+      x[1] /= mag;
+      x[2] /= mag;
+   }
+
+   mag = sqrt( y[0]*y[0] + y[1]*y[1] + y[2]*y[2] );
+   if (mag) {
+      y[0] /= mag;
+      y[1] /= mag;
+      y[2] /= mag;
+   }
+
+#define M(row,col)  m[col*4+row]
+   M(0,0) = x[0];  M(0,1) = x[1];  M(0,2) = x[2];  M(0,3) = 0.0;
+   M(1,0) = y[0];  M(1,1) = y[1];  M(1,2) = y[2];  M(1,3) = 0.0;
+   M(2,0) = z[0];  M(2,1) = z[1];  M(2,2) = z[2];  M(2,3) = 0.0;
+   M(3,0) = 0.0;   M(3,1) = 0.0;   M(3,2) = 0.0;   M(3,3) = 1.0;
+#undef M
+   glMultMatrixd( m );
+
+   /* Translate Eye to Origin */
+   glTranslated( -eyex, -eyey, -eyez );
+
+}
+
+
+
+void GLAPIENTRY gluOrtho2D( GLdouble left, GLdouble right,
+                          GLdouble bottom, GLdouble top )
+{
+   glOrtho( left, right, bottom, top, -1.0, 1.0 );
+}
+
+
+
+void GLAPIENTRY gluPerspective( GLdouble fovy, GLdouble aspect,
+                              GLdouble zNear, GLdouble zFar )
+{
+   GLdouble xmin, xmax, ymin, ymax;
+
+   ymax = zNear * tan( fovy * M_PI / 360.0 );
+   ymin = -ymax;
+
+   xmin = ymin * aspect;
+   xmax = ymax * aspect;
+
+   glFrustum( xmin, xmax, ymin, ymax, zNear, zFar );
+}
+
+
+
+void GLAPIENTRY gluPickMatrix( GLdouble x, GLdouble y,
+                             GLdouble width, GLdouble height,
+                             const GLint viewport[4] )
+{
+   GLfloat m[16];
+   GLfloat sx, sy;
+   GLfloat tx, ty;
+
+   sx = viewport[2] / width;
+   sy = viewport[3] / height;
+   tx = (viewport[2] + 2.0 * (viewport[0] - x)) / width;
+   ty = (viewport[3] + 2.0 * (viewport[1] - y)) / height;
+
+#define M(row,col)  m[col*4+row]
+   M(0,0) = sx;   M(0,1) = 0.0;  M(0,2) = 0.0;  M(0,3) = tx;
+   M(1,0) = 0.0;  M(1,1) = sy;   M(1,2) = 0.0;  M(1,3) = ty;
+   M(2,0) = 0.0;  M(2,1) = 0.0;  M(2,2) = 1.0;  M(2,3) = 0.0;
+   M(3,0) = 0.0;  M(3,1) = 0.0;  M(3,2) = 0.0;  M(3,3) = 1.0;
+#undef M
+
+   glMultMatrixf( m );
+}
+
+
+
+const GLubyte* GLAPIENTRY gluErrorString( GLenum errorCode )
+{
+   static char *tess_error[] = {
+      "missing gluEndPolygon",
+      "missing gluBeginPolygon",
+      "misoriented contour",
+      "vertex/edge intersection",
+      "misoriented or self-intersecting loops",
+      "coincident vertices",
+      "colinear vertices",
+      "intersecting edges",
+      "not coplanar contours"
+   };
+   static char *nurbs_error[] = {
+      "spline order un-supported",
+      "too few knots",
+      "valid knot range is empty",
+      "decreasing knot sequence knot",
+      "knot multiplicity greater than order of spline",
+      "endcurve() must follow bgncurve()",
+      "bgncurve() must precede endcurve()",
+      "missing or extra geometric data",
+      "can't draw pwlcurves",
+      "missing bgncurve()",
+      "missing bgnsurface()",
+      "endtrim() must precede endsurface()",
+      "bgnsurface() must precede endsurface()",
+      "curve of improper type passed as trim curve",
+      "bgnsurface() must precede bgntrim()",
+      "endtrim() must follow bgntrim()",
+      "bgntrim() must precede endtrim()",
+      "invalid or missing trim curve",
+      "bgntrim() must precede pwlcurve()",
+      "pwlcurve referenced twice",
+      "pwlcurve and nurbscurve mixed",
+      "improper usage of trim data type",
+      "nurbscurve referenced twice",
+      "nurbscurve and pwlcurve mixed",
+      "nurbssurface referenced twice",
+      "invalid property",
+      "endsurface() must follow bgnsurface()",
+      "misoriented trim curves",
+      "intersecting trim curves",
+      "UNUSED",
+      "unconnected trim curves",
+      "unknown knot error",
+      "negative vertex count encountered",
+      "negative byte-stride encounteed",
+      "unknown type descriptor",
+      "null control array or knot vector",
+      "duplicate point on pwlcurve"
+   };
+
+   /* GL Errors */
+   if (errorCode==GL_NO_ERROR) {
+      return (GLubyte *) "no error";
+   }
+   else if (errorCode==GL_INVALID_VALUE) {
+      return (GLubyte *) "invalid value";
+   }
+   else if (errorCode==GL_INVALID_ENUM) {
+      return (GLubyte *) "invalid enum";
+   }
+   else if (errorCode==GL_INVALID_OPERATION) {
+      return (GLubyte *) "invalid operation";
+   }
+   else if (errorCode==GL_STACK_OVERFLOW) {
+      return (GLubyte *) "stack overflow";
+   }
+   else if (errorCode==GL_STACK_UNDERFLOW) {
+      return (GLubyte *) "stack underflow";
+   }
+   else if (errorCode==GL_OUT_OF_MEMORY) {
+      return (GLubyte *) "out of memory";
+   }
+   /* GLU Errors */
+   else if (errorCode==GLU_NO_ERROR) {
+      return (GLubyte *) "no error";
+   }
+   else if (errorCode==GLU_INVALID_ENUM) {
+      return (GLubyte *) "invalid enum";
+   }
+   else if (errorCode==GLU_INVALID_VALUE) {
+      return (GLubyte *) "invalid value";
+   }
+   else if (errorCode==GLU_OUT_OF_MEMORY) {
+      return (GLubyte *) "out of memory";
+   }
+   else if (errorCode==GLU_INCOMPATIBLE_GL_VERSION) {
+      return (GLubyte *) "incompatible GL version";
+   }
+   else if (errorCode>=GLU_TESS_ERROR1 && errorCode<=GLU_TESS_ERROR9) {
+      return (GLubyte *) tess_error[errorCode-GLU_TESS_ERROR1];
+   }
+   else if (errorCode>=GLU_NURBS_ERROR1 && errorCode<=GLU_NURBS_ERROR37) {
+      return (GLubyte *) nurbs_error[errorCode-GLU_NURBS_ERROR1];
+   }
+   else {
+      return NULL;
+   }
+}
+
+
+
+/*
+ * New in GLU 1.1
+ */
+
+const GLubyte* GLAPIENTRY gluGetString( GLenum name )
+{
+   static char *extensions = "GL_EXT_abgr";
+   static char *version = "1.1 Mesa 3.1";
+
+   switch (name) {
+      case GLU_EXTENSIONS:
+         return (GLubyte *) extensions;
+      case GLU_VERSION:
+        return (GLubyte *) version;
+      default:
+        return NULL;
+   }
+}
+
diff --git a/src/glu/mesa/gluP.h b/src/glu/mesa/gluP.h
new file mode 100644 (file)
index 0000000..1d036ee
--- /dev/null
@@ -0,0 +1,83 @@
+/* $Id: gluP.h,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * Copyright (C) 1995-1999  Brian Paul
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/*
+ * $Log: gluP.h,v $
+ * Revision 1.1  1999/08/19 00:55:42  jtg
+ * Initial revision
+ *
+ * Revision 1.4  1999/01/03 03:23:15  brianp
+ * now using GLAPIENTRY and GLCALLBACK keywords (Ted Jump)
+ *
+ * Revision 1.3  1997/08/01 22:25:27  brianp
+ * check for Cygnus Win32 (Stephen Rehel)
+ *
+ * Revision 1.2  1997/05/27 02:59:46  brianp
+ * added defines for APIENTRY and CALLBACK if not compiling on Win32
+ *
+ * Revision 1.1  1996/09/27 01:19:39  brianp
+ * Initial revision
+ *
+ */
+
+
+
+/*
+ * This file allows the GLU code to be compiled either with the Mesa
+ * headers or with the real OpenGL headers.
+ */
+
+
+#ifndef GLUP_H
+#define GLUP_H
+
+
+#include "GL/gl.h"
+#include "GL/glu.h"
+
+
+#ifndef MESA
+   /* If we're using the real OpenGL header files... */
+#  define GLU_TESS_ERROR9      100159
+#endif
+
+
+#define GLU_NO_ERROR           GL_NO_ERROR
+
+
+/* for Sun: */
+#ifdef SUNOS4
+#define MEMCPY( DST, SRC, BYTES) \
+       memcpy( (char *) (DST), (char *) (SRC), (int) (BYTES) )
+#else
+#define MEMCPY( DST, SRC, BYTES) \
+       memcpy( (void *) (DST), (void *) (SRC), (size_t) (BYTES) )
+#endif
+
+
+#ifndef NULL
+#  define NULL 0
+#endif
+
+
+#endif
diff --git a/src/glu/mesa/mipmap.c b/src/glu/mesa/mipmap.c
new file mode 100644 (file)
index 0000000..24af0ba
--- /dev/null
@@ -0,0 +1,790 @@
+/* $Id: mipmap.c,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * Copyright (C) 1995-1999  Brian Paul
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/*
+ * $Log: mipmap.c,v $
+ * Revision 1.1  1999/08/19 00:55:42  jtg
+ * Initial revision
+ *
+ * Revision 1.13  1999/03/05 17:49:06  brianp
+ * added support for GL_EXT_abgr (devernay@istar.fr)
+ *
+ * Revision 1.12  1999/01/03 03:23:15  brianp
+ * now using GLAPIENTRY and GLCALLBACK keywords (Ted Jump)
+ *
+ * Revision 1.11  1998/09/18 02:44:03  brianp
+ * further changes to gluScaleImage() per Randy Frank
+ *
+ * Revision 1.10  1998/09/17 03:20:26  brianp
+ * fixed another bug in gluScaleImage() per Sven Panne
+ *
+ * Revision 1.9  1998/07/31 03:06:20  brianp
+ * tweaked the gluScaleImage() function per Randy Frank
+ *
+ * Revision 1.8  1998/07/08 01:02:53  brianp
+ * if gluBuildxDMipmaps() width or height <= 0 return GLU_INVALID_VALUE
+ *
+ * Revision 1.7  1998/07/01 00:18:02  brianp
+ * if gluBuildxDMipmaps() width or height <= 0 just return 0
+ *
+ * Revision 1.6  1998/06/01 01:06:41  brianp
+ * small update for Next/OpenStep from Alexander Mai
+ *
+ * Revision 1.5  1997/07/24 01:28:44  brianp
+ * changed precompiled header symbol from PCH to PC_HEADER
+ *
+ * Revision 1.4  1997/06/23 00:22:56  brianp
+ * added dummy() call to work around an MSVC 4.1 bug
+ *
+ * Revision 1.3  1997/05/28 02:29:38  brianp
+ * added support for precompiled headers (PCH), inserted APIENTRY keyword
+ *
+ * Revision 1.2  1997/05/24 13:32:25  brianp
+ * undef EPSILON in case it's already defined
+ *
+ * Revision 1.1  1996/09/27 01:19:39  brianp
+ * Initial revision
+ *
+ */
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <assert.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "gluP.h"
+#endif
+
+
+/*
+ * Compute ceiling of integer quotient of A divided by B:
+ */
+#define CEILING( A, B )  ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 )
+
+
+
+#ifdef EPSILON
+#undef EPSILON
+#endif
+#define EPSILON 0.001
+
+
+/* To work around optimizer bug in MSVC4.1 */
+#if defined(__WIN32__) && !defined(OPENSTEP)
+void dummy(GLuint j, GLuint k){
+}
+#else
+#define dummy(J, K)
+#endif
+
+
+GLint GLAPIENTRY gluScaleImage( GLenum format,
+                              GLint widthin, GLint heightin,
+                              GLenum typein, const void *datain,
+                              GLint widthout, GLint heightout,
+                              GLenum typeout, void *dataout )
+{
+   GLint components, i, j, k;
+   GLfloat *tempin, *tempout;
+   GLfloat sx, sy;
+   GLint unpackrowlength, unpackalignment, unpackskiprows, unpackskippixels;
+   GLint packrowlength, packalignment, packskiprows, packskippixels;
+   GLint sizein, sizeout;
+   GLint rowstride, rowlen;
+
+
+   /* Determine number of components per pixel */
+   switch (format) {
+      case GL_COLOR_INDEX:
+      case GL_STENCIL_INDEX:
+      case GL_DEPTH_COMPONENT:
+      case GL_RED:
+      case GL_GREEN:
+      case GL_BLUE:
+      case GL_ALPHA:
+      case GL_LUMINANCE:
+         components = 1;
+        break;
+      case GL_LUMINANCE_ALPHA:
+        components = 2;
+        break;
+      case GL_RGB:
+        components = 3;
+        break;
+      case GL_RGBA:
+#ifdef GL_EXT_abgr
+      case GL_ABGR_EXT:
+#endif
+        components = 4;
+        break;
+      default:
+        return GLU_INVALID_ENUM;
+   }
+
+   /* Determine bytes per input datum */
+   switch (typein) {
+      case GL_UNSIGNED_BYTE:   sizein = sizeof(GLubyte);       break;
+      case GL_BYTE:            sizein = sizeof(GLbyte);        break;
+      case GL_UNSIGNED_SHORT:  sizein = sizeof(GLushort);      break;
+      case GL_SHORT:           sizein = sizeof(GLshort);       break;
+      case GL_UNSIGNED_INT:    sizein = sizeof(GLuint);        break;
+      case GL_INT:             sizein = sizeof(GLint);         break;
+      case GL_FLOAT:           sizein = sizeof(GLfloat);       break;
+      case GL_BITMAP:
+        /* not implemented yet */
+      default:
+        return GL_INVALID_ENUM;
+   }
+
+   /* Determine bytes per output datum */
+   switch (typeout) {
+      case GL_UNSIGNED_BYTE:   sizeout = sizeof(GLubyte);      break;
+      case GL_BYTE:            sizeout = sizeof(GLbyte);       break;
+      case GL_UNSIGNED_SHORT:  sizeout = sizeof(GLushort);     break;
+      case GL_SHORT:           sizeout = sizeof(GLshort);      break;
+      case GL_UNSIGNED_INT:    sizeout = sizeof(GLuint);       break;
+      case GL_INT:             sizeout = sizeof(GLint);        break;
+      case GL_FLOAT:           sizeout = sizeof(GLfloat);      break;
+      case GL_BITMAP:
+        /* not implemented yet */
+      default:
+        return GL_INVALID_ENUM;
+   }
+
+   /* Get glPixelStore state */
+   glGetIntegerv( GL_UNPACK_ROW_LENGTH, &unpackrowlength );
+   glGetIntegerv( GL_UNPACK_ALIGNMENT, &unpackalignment );
+   glGetIntegerv( GL_UNPACK_SKIP_ROWS, &unpackskiprows );
+   glGetIntegerv( GL_UNPACK_SKIP_PIXELS, &unpackskippixels );
+   glGetIntegerv( GL_PACK_ROW_LENGTH, &packrowlength );
+   glGetIntegerv( GL_PACK_ALIGNMENT, &packalignment );
+   glGetIntegerv( GL_PACK_SKIP_ROWS, &packskiprows );
+   glGetIntegerv( GL_PACK_SKIP_PIXELS, &packskippixels );
+
+   /* Allocate storage for intermediate images */
+   tempin = (GLfloat *) malloc( widthin * heightin
+                               * components * sizeof(GLfloat) );
+   if (!tempin) {
+      return GLU_OUT_OF_MEMORY;
+   }
+   tempout = (GLfloat *) malloc( widthout * heightout
+                                * components * sizeof(GLfloat) );
+   if (!tempout) {
+      free( tempin );
+      return GLU_OUT_OF_MEMORY;
+   }
+
+
+   /*
+    * Unpack the pixel data and convert to floating point
+    */
+
+   if (unpackrowlength>0) {
+      rowlen = unpackrowlength;
+   }
+   else {
+      rowlen = widthin;
+   }
+   if (sizein >= unpackalignment) {
+      rowstride = components * rowlen;
+   }
+   else {
+      rowstride = unpackalignment/sizein
+               * CEILING( components * rowlen * sizein, unpackalignment );
+   }
+
+   switch (typein) {
+      case GL_UNSIGNED_BYTE:
+        k = 0;
+        for (i=0;i<heightin;i++) {
+           GLubyte *ubptr = (GLubyte *) datain
+                          + i * rowstride
+                          + unpackskiprows * rowstride
+                          + unpackskippixels * components;
+           for (j=0;j<widthin*components;j++) {
+               dummy(j, k);
+              tempin[k++] = (GLfloat) *ubptr++;
+           }
+        }
+        break;
+      case GL_BYTE:
+        k = 0;
+        for (i=0;i<heightin;i++) {
+           GLbyte *bptr = (GLbyte *) datain
+                        + i * rowstride
+                        + unpackskiprows * rowstride
+                        + unpackskippixels * components;
+           for (j=0;j<widthin*components;j++) {
+               dummy(j, k);
+              tempin[k++] = (GLfloat) *bptr++;
+           }
+        }
+        break;
+      case GL_UNSIGNED_SHORT:
+        k = 0;
+        for (i=0;i<heightin;i++) {
+           GLushort *usptr = (GLushort *) datain
+                           + i * rowstride
+                           + unpackskiprows * rowstride
+                           + unpackskippixels * components;
+           for (j=0;j<widthin*components;j++) {
+               dummy(j, k);
+              tempin[k++] = (GLfloat) *usptr++;
+           }
+        }
+        break;
+      case GL_SHORT:
+        k = 0;
+        for (i=0;i<heightin;i++) {
+           GLshort *sptr = (GLshort *) datain
+                         + i * rowstride
+                         + unpackskiprows * rowstride
+                         + unpackskippixels * components;
+           for (j=0;j<widthin*components;j++) {
+               dummy(j, k);
+              tempin[k++] = (GLfloat) *sptr++;
+           }
+        }
+        break;
+      case GL_UNSIGNED_INT:
+        k = 0;
+        for (i=0;i<heightin;i++) {
+           GLuint *uiptr = (GLuint *) datain
+                         + i * rowstride
+                         + unpackskiprows * rowstride
+                         + unpackskippixels * components;
+           for (j=0;j<widthin*components;j++) {
+               dummy(j, k);
+              tempin[k++] = (GLfloat) *uiptr++;
+           }
+        }
+        break;
+      case GL_INT:
+        k = 0;
+        for (i=0;i<heightin;i++) {
+           GLint *iptr = (GLint *) datain
+                       + i * rowstride
+                       + unpackskiprows * rowstride
+                       + unpackskippixels * components;
+           for (j=0;j<widthin*components;j++) {
+               dummy(j, k);
+              tempin[k++] = (GLfloat) *iptr++;
+           }
+        }
+        break;
+      case GL_FLOAT:
+        k = 0;
+        for (i=0;i<heightin;i++) {
+           GLfloat *fptr = (GLfloat *) datain
+                         + i * rowstride
+                         + unpackskiprows * rowstride
+                         + unpackskippixels * components;
+           for (j=0;j<widthin*components;j++) {
+               dummy(j, k);
+              tempin[k++] = *fptr++;
+           }
+        }
+        break;
+      default:
+        return GLU_INVALID_ENUM;
+   }
+
+
+   /*
+    * Scale the image!
+    */
+
+   if (widthout > 1)
+      sx = (GLfloat) (widthin-1) / (GLfloat) (widthout-1);
+   else
+      sx = (GLfloat) (widthin-1);
+   if (heightout > 1)
+      sy = (GLfloat) (heightin-1) / (GLfloat) (heightout-1);
+   else
+      sy = (GLfloat) (heightin-1);
+
+/*#define POINT_SAMPLE*/
+#ifdef POINT_SAMPLE
+   for (i=0;i<heightout;i++) {
+      GLint ii = i * sy;
+      for (j=0;j<widthout;j++) {
+        GLint jj = j * sx;
+
+        GLfloat *src = tempin + (ii * widthin + jj) * components;
+        GLfloat *dst = tempout + (i * widthout + j) * components;
+
+        for (k=0;k<components;k++) {
+           *dst++ = *src++;
+        }
+      }
+   }
+#else
+   if (sx<1.0 && sy<1.0) {
+      /* magnify both width and height:  use weighted sample of 4 pixels */
+      GLint i0, i1, j0, j1;
+      GLfloat alpha, beta;
+      GLfloat *src00, *src01, *src10, *src11;
+      GLfloat s1, s2;
+      GLfloat *dst;
+
+      for (i=0;i<heightout;i++) {
+        i0 = i * sy;
+        i1 = i0 + 1;
+        if (i1 >= heightin) i1 = heightin-1;
+/*      i1 = (i+1) * sy - EPSILON;*/
+        alpha = i*sy - i0;
+        for (j=0;j<widthout;j++) {
+           j0 = j * sx;
+           j1 = j0 + 1;
+           if (j1 >= widthin) j1 = widthin-1;
+/*         j1 = (j+1) * sx - EPSILON; */
+           beta = j*sx - j0;
+
+           /* compute weighted average of pixels in rect (i0,j0)-(i1,j1) */
+           src00 = tempin + (i0 * widthin + j0) * components;
+           src01 = tempin + (i0 * widthin + j1) * components;
+           src10 = tempin + (i1 * widthin + j0) * components;
+           src11 = tempin + (i1 * widthin + j1) * components;
+
+           dst = tempout + (i * widthout + j) * components;
+
+           for (k=0;k<components;k++) {
+              s1 = *src00++ * (1.0-beta) + *src01++ * beta;
+              s2 = *src10++ * (1.0-beta) + *src11++ * beta;
+              *dst++ = s1 * (1.0-alpha) + s2 * alpha;
+           }
+        }
+      }
+   }
+   else {
+      /* shrink width and/or height:  use an unweighted box filter */
+      GLint i0, i1;
+      GLint j0, j1;
+      GLint ii, jj;
+      GLfloat sum, *dst;
+
+      for (i=0;i<heightout;i++) {
+        i0 = i * sy;
+        i1 = i0 + 1;
+        if (i1 >= heightin) i1 = heightin-1; 
+/*      i1 = (i+1) * sy - EPSILON; */
+        for (j=0;j<widthout;j++) {
+           j0 = j * sx;
+           j1 = j0 + 1;
+           if (j1 >= widthin) j1 = widthin-1;
+/*         j1 = (j+1) * sx - EPSILON; */
+
+           dst = tempout + (i * widthout + j) * components;
+
+           /* compute average of pixels in the rectangle (i0,j0)-(i1,j1) */
+           for (k=0;k<components;k++) {
+              sum = 0.0;
+              for (ii=i0;ii<=i1;ii++) {
+                 for (jj=j0;jj<=j1;jj++) {
+                    sum += *(tempin + (ii * widthin + jj) * components + k);
+                 }
+              }
+              sum /= (j1-j0+1) * (i1-i0+1);
+              *dst++ = sum;
+           }
+        }
+      }
+   }
+#endif
+
+
+   /*
+    * Return output image
+    */
+
+   if (packrowlength>0) {
+      rowlen = packrowlength;
+   }
+   else {
+      rowlen = widthout;
+   }
+   if (sizeout >= packalignment) {
+      rowstride = components * rowlen;
+   }
+   else {
+      rowstride = packalignment/sizeout
+               * CEILING( components * rowlen * sizeout, packalignment );
+   }
+
+   switch (typeout) {
+      case GL_UNSIGNED_BYTE:
+        k = 0;
+        for (i=0;i<heightout;i++) {
+           GLubyte *ubptr = (GLubyte *) dataout
+                          + i * rowstride
+                          + packskiprows * rowstride
+                          + packskippixels * components;
+           for (j=0;j<widthout*components;j++) {
+               dummy(j, k+i);
+              *ubptr++ = (GLubyte) tempout[k++];
+           }
+        }
+        break;
+      case GL_BYTE:
+        k = 0;
+        for (i=0;i<heightout;i++) {
+           GLbyte *bptr = (GLbyte *) dataout
+                        + i * rowstride
+                        + packskiprows * rowstride
+                        + packskippixels * components;
+           for (j=0;j<widthout*components;j++) {
+               dummy(j, k+i);
+              *bptr++ = (GLbyte) tempout[k++];
+           }
+        }
+        break;
+      case GL_UNSIGNED_SHORT:
+        k = 0;
+        for (i=0;i<heightout;i++) {
+           GLushort *usptr = (GLushort *) dataout
+                           + i * rowstride
+                           + packskiprows * rowstride
+                           + packskippixels * components;
+           for (j=0;j<widthout*components;j++) {
+               dummy(j, k+i);
+              *usptr++ = (GLushort) tempout[k++];
+           }
+        }
+        break;
+      case GL_SHORT:
+        k = 0;
+        for (i=0;i<heightout;i++) {
+           GLshort *sptr = (GLshort *) dataout
+                         + i * rowstride
+                         + packskiprows * rowstride
+                         + packskippixels * components;
+           for (j=0;j<widthout*components;j++) {
+               dummy(j, k+i);
+              *sptr++ = (GLshort) tempout[k++];
+           }
+        }
+        break;
+      case GL_UNSIGNED_INT:
+        k = 0;
+        for (i=0;i<heightout;i++) {
+           GLuint *uiptr = (GLuint *) dataout
+                         + i * rowstride
+                         + packskiprows * rowstride
+                         + packskippixels * components;
+           for (j=0;j<widthout*components;j++) {
+               dummy(j, k+i);
+              *uiptr++ = (GLuint) tempout[k++];
+           }
+        }
+        break;
+      case GL_INT:
+        k = 0;
+        for (i=0;i<heightout;i++) {
+           GLint *iptr = (GLint *) dataout
+                       + i * rowstride
+                       + packskiprows * rowstride
+                       + packskippixels * components;
+           for (j=0;j<widthout*components;j++) {
+               dummy(j, k+i);
+              *iptr++ = (GLint) tempout[k++];
+           }
+        }
+        break;
+      case GL_FLOAT:
+        k = 0;
+        for (i=0;i<heightout;i++) {
+           GLfloat *fptr = (GLfloat *) dataout
+                         + i * rowstride
+                         + packskiprows * rowstride
+                         + packskippixels * components;
+           for (j=0;j<widthout*components;j++) {
+               dummy(j, k+i);
+              *fptr++ = tempout[k++];
+           }
+        }
+        break;
+      default:
+        return GLU_INVALID_ENUM;
+   }
+
+
+   /* free temporary image storage */
+   free( tempin );
+   free( tempout );
+
+   return 0;
+}
+
+
+
+/*
+ * Return the largest k such that 2^k <= n.
+ */
+static GLint ilog2( GLint n )
+{
+   GLint k;
+
+   if (n<=0) return 0;
+   for (k=0; n>>=1; k++) ;
+   return k;
+}
+
+
+
+/*
+ * Find the value nearest to n which is also a power of two.
+ */
+static GLint round2( GLint n )
+{
+   GLint m;
+
+   for (m=1; m<n; m*=2)
+     ;
+
+   /* m>=n */
+   if (m-n <= n-m/2) {
+      return m;
+   }
+   else {
+      return m/2;
+   }
+}
+
+
+/*
+ * Given an pixel format and datatype, return the number of bytes to
+ * store one pixel.
+ */
+static GLint bytes_per_pixel( GLenum format, GLenum type )
+{
+   GLint n, m;
+
+   switch (format) {
+      case GL_COLOR_INDEX:
+      case GL_STENCIL_INDEX:
+      case GL_DEPTH_COMPONENT:
+      case GL_RED:
+      case GL_GREEN:
+      case GL_BLUE:
+      case GL_ALPHA:
+      case GL_LUMINANCE:
+        n = 1;
+        break;
+      case GL_LUMINANCE_ALPHA:
+        n = 2;
+        break;
+      case GL_RGB:
+        n = 3;
+        break;
+      case GL_RGBA:
+#ifdef GL_EXT_abgr
+      case GL_ABGR_EXT:
+#endif
+        n = 4;
+        break;
+      default:
+        n = 0;
+   }
+
+   switch (type) {
+      case GL_UNSIGNED_BYTE:   m = sizeof(GLubyte);    break;
+      case GL_BYTE:            m = sizeof(GLbyte);     break;
+      case GL_BITMAP:          m = 1;                  break;
+      case GL_UNSIGNED_SHORT:  m = sizeof(GLushort);   break;
+      case GL_SHORT:           m = sizeof(GLshort);    break;
+      case GL_UNSIGNED_INT:    m = sizeof(GLuint);     break;
+      case GL_INT:             m = sizeof(GLint);      break;
+      case GL_FLOAT:           m = sizeof(GLfloat);    break;
+      default:                 m = 0;
+   }
+
+   return n * m;
+}
+
+
+
+/*
+ * WARNING: This function isn't finished and has never been tested!!!!
+ */
+GLint GLAPIENTRY gluBuild1DMipmaps( GLenum target, GLint components,
+                                  GLint width, GLenum format,
+                                  GLenum type, const void *data )
+{
+   GLubyte *texture;
+   GLint levels, max_levels;
+   GLint new_width, max_width;
+   GLint i, j, k, l;
+
+   if (width < 1)
+      return GLU_INVALID_VALUE;
+
+   glGetIntegerv( GL_MAX_TEXTURE_SIZE, &max_width );
+   max_levels = ilog2( max_width ) + 1;
+
+   /* Compute how many mipmap images to make */
+   levels = ilog2( width ) + 1;
+   if (levels>max_levels) {
+      levels = max_levels;
+   }
+
+   new_width = 1 << (levels-1);
+
+   texture = (GLubyte *) malloc( new_width * components );
+   if (!texture) {
+      return GLU_OUT_OF_MEMORY;
+   }
+
+   if (width != new_width) {
+      /* initial rescaling */
+      switch (type) {
+        case GL_UNSIGNED_BYTE:
+           {
+              GLubyte *ub_data = (GLubyte *) data;
+              for (i=0;i<new_width;i++) {
+                 j = i * width / new_width;
+                 for (k=0;k<components;k++) {
+                    texture[i*components+k] = ub_data[j*components+k];
+                 }
+              }
+           }
+           break;
+        default:
+           /* Not implemented */
+           return GLU_ERROR;
+      }
+   }
+
+   /* generate and load mipmap images */
+   for (l=0;l<levels;l++) {
+      glTexImage1D( GL_TEXTURE_1D, l, components, new_width, 0,
+                   format, GL_UNSIGNED_BYTE, texture );
+
+      /* Scale image down to 1/2 size */
+      new_width = new_width / 2;
+      for (i=0;i<new_width;i++) {
+        for (k=0;k<components;k++) {
+           GLint sample1, sample2;
+           sample1 = (GLint) texture[i*2*components+k];
+           sample2 = (GLint) texture[(i*2+1)*components+k];
+           texture[i*components+k] = (GLubyte) ((sample1 + sample2) / 2);
+        }
+      }
+   }
+
+   free( texture );
+
+   /* make sure remaining mipmap levels are removed */
+   for (l=levels;l<max_levels;l++) {
+      glTexImage1D( GL_TEXTURE_1D, l, components, 0, 0,
+                   format, GL_UNSIGNED_BYTE, NULL );
+   }
+
+   return 0;
+}
+
+
+
+GLint GLAPIENTRY gluBuild2DMipmaps( GLenum target, GLint components,
+                                  GLint width, GLint height, GLenum format,
+                                  GLenum type, const void *data )
+{
+   GLint w, h, maxsize;
+   void *image, *newimage;
+   GLint neww, newh, level, bpp;
+   int error;
+
+   if (width < 1 || height < 1)
+      return GLU_INVALID_VALUE;
+
+   glGetIntegerv( GL_MAX_TEXTURE_SIZE, &maxsize );
+
+   w = round2( width );
+   if (w>maxsize) {
+      w = maxsize;
+   }
+   h = round2( height );
+   if (h>maxsize) {
+      h = maxsize;
+   }
+
+   bpp = bytes_per_pixel( format, type );
+   if (bpp==0) {
+      /* probably a bad format or type enum */
+      return GLU_INVALID_ENUM;
+   }
+
+   if (w!=width || h!=height) {
+      /* must rescale image to get "top" mipmap texture image */
+      image = malloc( (w+4) * h * bpp );
+      if (!image) {
+        return GLU_OUT_OF_MEMORY;
+      }
+      error = gluScaleImage( format, width, height, type, data,
+                            w, h, type, image );
+      if (error) {
+        return error;
+      }
+   }
+   else {
+      image = (void *) data;
+   }
+
+   level = 0;
+   while (1) {
+      glTexImage2D( target, level, components, w, h, 0, format, type, image );
+
+      if (w==1 && h==1)  break;
+
+      neww = (w<2) ? 1 : w/2;
+      newh = (h<2) ? 1 : h/2;
+      newimage = malloc( (neww+4) * newh * bpp );
+      if (!newimage) {
+        return GLU_OUT_OF_MEMORY;
+      }
+
+      error =  gluScaleImage( format, w, h, type, image,
+                             neww, newh, type, newimage );
+      if (error) {
+        return error;
+      }
+
+      if (image!=data) {
+        free( image );
+      }
+      image = newimage;
+
+      w = neww;
+      h = newh;
+      level++;
+   }
+
+   if (image!=data) {
+      free( image );
+   }
+
+   return 0;
+}
+
diff --git a/src/glu/mesa/mms_depend b/src/glu/mesa/mms_depend
new file mode 100644 (file)
index 0000000..372e3ff
--- /dev/null
@@ -0,0 +1,13 @@
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+glu.obj : gluP.h [-.include.gl]gl.h [-.include.gl]glu.h
+mipmap.obj : gluP.h [-.include.gl]gl.h [-.include.gl]glu.h
+nurbs.obj : gluP.h [-.include.gl]gl.h [-.include.gl]glu.h nurbs.h
+nurbscrv.obj : nurbs.h gluP.h [-.include.gl]gl.h [-.include.gl]glu.h
+nurbssrf.obj : gluP.h [-.include.gl]gl.h [-.include.gl]glu.h nurbs.h
+nurbsutl.obj : gluP.h [-.include.gl]gl.h [-.include.gl]glu.h nurbs.h
+project.obj : gluP.h [-.include.gl]gl.h [-.include.gl]glu.h
+quadric.obj : gluP.h [-.include.gl]gl.h [-.include.gl]glu.h
+tess.obj : gluP.h [-.include.gl]gl.h [-.include.gl]glu.h tess.h
+tesselat.obj : gluP.h [-.include.gl]gl.h [-.include.gl]glu.h tess.h
+polytest.obj : gluP.h [-.include.gl]gl.h [-.include.gl]glu.h tess.h
diff --git a/src/glu/mesa/nurbs.c b/src/glu/mesa/nurbs.c
new file mode 100644 (file)
index 0000000..65bc6f8
--- /dev/null
@@ -0,0 +1,715 @@
+/* $Id: nurbs.c,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * Copyright (C) 1995-1999  Brian Paul
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/*
+ * $Log: nurbs.c,v $
+ * Revision 1.1  1999/08/19 00:55:42  jtg
+ * Initial revision
+ *
+ * Revision 1.14  1999/01/03 03:23:15  brianp
+ * now using GLAPIENTRY and GLCALLBACK keywords (Ted Jump)
+ *
+ * Revision 1.13  1998/06/01 01:07:49  brianp
+ * small update for Next/OpenStep from Alexander Mai
+ *
+ * Revision 1.12  1998/03/15 18:14:30  brianp
+ * fixed a compiler cast warning
+ *
+ * Revision 1.11  1998/02/07 14:29:11  brianp
+ * fixed casting problem in gluNurbsCallback, again
+ *
+ * Revision 1.10  1998/02/04 00:21:20  brianp
+ * fixed cygnus compilation problem (Stephane Rehel)
+ *
+ * Revision 1.9  1998/01/16 03:35:26  brianp
+ * fixed Windows compilation warnings (Theodore Jump)
+ *
+ * Revision 1.8  1997/09/17 01:51:48  brianp
+ * changed glu*Callback() functions to match prototype in glu.h
+ *
+ * Revision 1.7  1997/07/24 01:28:44  brianp
+ * changed precompiled header symbol from PCH to PC_HEADER
+ *
+ * Revision 1.6  1997/07/24 01:26:31  brianp
+ * added CALLBACK keyword to gluNurbsCallback()
+ *
+ * Revision 1.5  1997/05/28 02:29:38  brianp
+ * added support for precompiled headers (PCH), inserted APIENTRY keyword
+ *
+ * Revision 1.4  1997/05/27 03:17:22  brianp
+ * minor clean-up
+ *
+ * Revision 1.3  1997/05/27 03:00:16  brianp
+ * incorporated Bogdan's new NURBS code
+ *
+ * Revision 1.2  1996/09/27 23:11:23  brianp
+ * ifdef'd out unimplemented trimmed nurbs code
+ *
+ * Revision 1.1  1996/09/27 01:19:39  brianp
+ * Initial revision
+ *
+ */
+
+
+/*
+ * NURBS implementation written by Bogdan Sikorski (bogdan@cira.it)
+ * See README2 for more info.
+ */
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#include "gluP.h"
+#include "nurbs.h"
+#endif
+
+
+void
+call_user_error( GLUnurbsObj *nobj, GLenum error )
+{
+    nobj->error=error;
+    if(nobj->error_callback != NULL) {
+        (*(nobj->error_callback))(error);
+    }
+    else {
+       printf("NURBS error %d %s\n", error, (char *) gluErrorString(error) );
+    }
+}
+
+
+
+GLUnurbsObj * GLAPIENTRY gluNewNurbsRenderer( void )
+{
+   GLUnurbsObj *n;
+   GLfloat tmp_viewport[4];
+   GLint i,j;
+
+   n = (GLUnurbsObj *) malloc( sizeof(GLUnurbsObj) );
+   if (n) {
+      /* init */
+      n->culling=GL_FALSE;
+      n->nurbs_type=GLU_NURBS_NONE;
+      n->error=GLU_NO_ERROR;
+      n->error_callback=NULL;
+      n->auto_load_matrix=GL_TRUE;
+      n->sampling_tolerance=50.0;
+      n->parametric_tolerance=0.5;
+      n->u_step = n->v_step = 100;
+      n->sampling_method = GLU_PATH_LENGTH;
+      n->display_mode=GLU_FILL;
+      /* in case the user doesn't supply the sampling matrices */
+      /* set projection and modelview to identity */
+      for(i=0;i<4;i++)
+          for(j=0;j<4;j++)
+              if(i==j)
+              {
+                n->sampling_matrices.model[i*4+j]=1.0;
+                n->sampling_matrices.proj[i*4+j]=1.0;
+            }
+            else
+              {
+                n->sampling_matrices.model[i*4+j]=0.0;
+                n->sampling_matrices.proj[i*4+j]=0.0;
+            }
+      /* and set the viewport sampling matrix to current ciewport */
+      glGetFloatv(GL_VIEWPORT,tmp_viewport);
+      for(i=0;i<4;i++)
+          n->sampling_matrices.viewport[i]=tmp_viewport[i];
+      n->trim=NULL;
+   }
+   return n;
+}
+
+
+
+void GLAPIENTRY gluDeleteNurbsRenderer( GLUnurbsObj *nobj )
+{
+   if (nobj) {
+      free( nobj );
+   }
+}
+
+
+
+void GLAPIENTRY gluLoadSamplingMatrices( GLUnurbsObj *nobj,
+                  const GLfloat modelMatrix[16],
+                  const GLfloat projMatrix[16],
+                  const GLint viewport[4] )
+{
+    GLint    i;
+
+    for(i=0;i<16;i++)
+    {
+        nobj->sampling_matrices.model[i]=modelMatrix[i];
+        nobj->sampling_matrices.proj[i]=projMatrix[i];
+    }
+    for(i=0;i<4;i++)
+        nobj->sampling_matrices.viewport[i]=viewport[i];
+}
+
+
+void GLAPIENTRY gluNurbsProperty( GLUnurbsObj *nobj, GLenum property, GLfloat value )
+{
+   GLenum val;
+
+   switch (property) {
+      case GLU_SAMPLING_TOLERANCE:
+           if(value <= 0.0)
+           {
+               call_user_error(nobj,GLU_INVALID_VALUE);
+               return;
+         }
+         nobj->sampling_tolerance=value;
+         break;
+      case GLU_PARAMETRIC_TOLERANCE:
+           if(value <= 0.0)
+           {
+               call_user_error(nobj,GLU_INVALID_VALUE);
+               return;
+         }
+         nobj->parametric_tolerance=value;
+         break;
+      case GLU_U_STEP:
+           if(value <= 0.0)
+           {
+               call_user_error(nobj,GLU_INVALID_VALUE);
+               return;
+         }
+         nobj->u_step=(GLint)value;
+         break;
+      case GLU_V_STEP:
+           if(value <= 0.0)
+           {
+               call_user_error(nobj,GLU_INVALID_VALUE);
+               return;
+         }
+         nobj->v_step=(GLint)value;
+         break;
+      case GLU_SAMPLING_METHOD:
+                val = (GLenum)value;
+         if(val!=GLU_PATH_LENGTH && val!=GLU_PARAMETRIC_ERROR && val!=GLU_DOMAIN_DISTANCE)
+         {
+             call_user_error(nobj,GLU_INVALID_ENUM);
+             return;
+         }
+                nobj->sampling_method=val;
+         break;
+      case GLU_DISPLAY_MODE:
+         val=(GLenum)value;
+         if(val!=GLU_FILL && val!=GLU_OUTLINE_POLYGON && val!=GLU_OUTLINE_PATCH)
+         {
+             call_user_error(nobj,GLU_INVALID_ENUM);
+             return;
+         }
+         if(nobj->nurbs_type==GLU_NURBS_CURVE)
+         {
+             call_user_error(nobj,GLU_NURBS_ERROR26);
+             return;
+         }
+         nobj->display_mode=val;
+if(val==GLU_OUTLINE_PATCH)
+    fprintf(stderr,"NURBS, for the moment, can display only in POLYGON mode\n");
+         break;
+      case GLU_CULLING:
+         val=(GLenum)value;
+         if(val!=GL_TRUE && val!=GL_FALSE)
+         {
+             call_user_error(nobj,GLU_INVALID_ENUM);
+             return;
+         }
+         nobj->culling = (GLboolean) value;
+         break;
+      case GLU_AUTO_LOAD_MATRIX:
+         val=(GLenum)value;
+         if(val!=GL_TRUE && val!=GL_FALSE)
+         {
+             call_user_error(nobj,GLU_INVALID_ENUM);
+             return;
+         }
+         nobj->auto_load_matrix = (GLboolean) value;
+         break;
+      default:
+         call_user_error(nobj,GLU_NURBS_ERROR26);
+   }
+}
+
+
+void GLAPIENTRY gluGetNurbsProperty( GLUnurbsObj *nobj, GLenum property, GLfloat *value )
+{
+   switch (property) {
+      case GLU_SAMPLING_TOLERANCE:
+         *value = nobj->sampling_tolerance;
+         break;
+      case GLU_DISPLAY_MODE:
+         *value = (GLfloat) (GLint) nobj->display_mode;
+         break;
+      case GLU_CULLING:
+         *value = nobj->culling ? 1.0 : 0.0;
+         break;
+      case GLU_AUTO_LOAD_MATRIX:
+         *value = nobj->auto_load_matrix ? 1.0 : 0.0;
+         break;
+      default:
+         call_user_error(nobj,GLU_INVALID_ENUM);
+   }
+}
+
+
+
+void GLAPIENTRY gluBeginCurve( GLUnurbsObj *nobj )
+{
+    if(nobj->nurbs_type==GLU_NURBS_CURVE)
+    {
+        call_user_error(nobj,GLU_NURBS_ERROR6);
+        return;
+    }
+    nobj->nurbs_type=GLU_NURBS_CURVE;
+    nobj->curve.geom.type=GLU_INVALID_ENUM;
+    nobj->curve.color.type=GLU_INVALID_ENUM;
+    nobj->curve.texture.type=GLU_INVALID_ENUM;
+    nobj->curve.normal.type=GLU_INVALID_ENUM;
+}
+
+
+void GLAPIENTRY gluEndCurve( GLUnurbsObj * nobj )
+{
+    if(nobj->nurbs_type==GLU_NURBS_NONE)
+    {
+        call_user_error(nobj,GLU_NURBS_ERROR7);
+        return;
+    }
+    if(nobj->curve.geom.type==GLU_INVALID_ENUM)
+    {
+        call_user_error(nobj,GLU_NURBS_ERROR8);
+        nobj->nurbs_type=GLU_NURBS_NONE;
+        return;
+    }
+    glPushAttrib( (GLbitfield) (GL_EVAL_BIT | GL_ENABLE_BIT) );
+    glDisable(GL_MAP1_VERTEX_3);
+    glDisable(GL_MAP1_VERTEX_4);
+    glDisable(GL_MAP1_INDEX);
+    glDisable(GL_MAP1_COLOR_4);
+    glDisable(GL_MAP1_NORMAL);
+    glDisable(GL_MAP1_TEXTURE_COORD_1);
+    glDisable(GL_MAP1_TEXTURE_COORD_2);
+    glDisable(GL_MAP1_TEXTURE_COORD_3);
+    glDisable(GL_MAP1_TEXTURE_COORD_4);
+    glDisable(GL_MAP2_VERTEX_3);
+    glDisable(GL_MAP2_VERTEX_4);
+    glDisable(GL_MAP2_INDEX);
+    glDisable(GL_MAP2_COLOR_4);
+    glDisable(GL_MAP2_NORMAL);
+    glDisable(GL_MAP2_TEXTURE_COORD_1);
+    glDisable(GL_MAP2_TEXTURE_COORD_2);
+    glDisable(GL_MAP2_TEXTURE_COORD_3);
+    glDisable(GL_MAP2_TEXTURE_COORD_4);
+    do_nurbs_curve(nobj);
+    glPopAttrib();
+    nobj->nurbs_type=GLU_NURBS_NONE;
+}
+
+
+void GLAPIENTRY gluNurbsCurve( GLUnurbsObj *nobj, GLint nknots, GLfloat *knot,
+            GLint stride, GLfloat *ctlarray, GLint order, GLenum type )
+{
+    if(nobj->nurbs_type==GLU_NURBS_TRIM)
+    {
+#if 0
+/* TODO: NOT IMPLEMENTED YET */
+        nurbs_trim *ptr1;
+        trim_list *ptr2;
+
+        if(type!=GLU_MAP1_TRIM_2 && type!=GLU_MAP1_TRIM_3)
+        {
+            call_user_error(nobj,GLU_NURBS_ERROR14);
+            return;
+        }
+        for(ptr1=nobj->trim;ptr1->next;ptr1=ptr1->next);
+        if(ptr1->trim_loop)
+        {
+            for(ptr2=ptr1->trim_loop;ptr2->next;ptr2=ptr2->next);
+            if((ptr2->next=(trim_list *)malloc(sizeof(trim_list)))==NULL)
+            {
+                call_user_error(nobj,GLU_OUT_OF_MEMORY);
+                return;
+            }
+            ptr2=ptr2->next;
+        }
+        else
+        {
+            if((ptr2=(trim_list *)malloc(sizeof(trim_list)))==NULL)
+            {
+                call_user_error(nobj,GLU_OUT_OF_MEMORY);
+                return;
+            }
+            ptr1->trim_loop=ptr2;
+        }
+        ptr2->trim_type=GLU_TRIM_NURBS;
+        ptr2->curve.nurbs_curve.knot_count=nknots;
+        ptr2->curve.nurbs_curve.knot=knot;
+        ptr2->curve.nurbs_curve.stride=stride;
+        ptr2->curve.nurbs_curve.ctrlarray=ctlarray;
+        ptr2->curve.nurbs_curve.order=order;
+        ptr2->curve.nurbs_curve.dim= (type==GLU_MAP1_TRIM_2 ? 2 : 3 );
+        ptr2->curve.nurbs_curve.type=type;
+        ptr2->next=NULL;
+#endif
+    }
+    else
+    {
+        if(type==GLU_MAP1_TRIM_2 || type==GLU_MAP1_TRIM_3)
+        {
+            call_user_error(nobj,GLU_NURBS_ERROR22);
+            return;
+        }
+        if(nobj->nurbs_type!=GLU_NURBS_CURVE)
+        {
+            call_user_error(nobj,GLU_NURBS_ERROR10);
+            return;
+        }
+        switch(type)
+        {
+            case GL_MAP1_VERTEX_3:
+            case GL_MAP1_VERTEX_4:
+                if(nobj->curve.geom.type!=GLU_INVALID_ENUM)
+                {
+                    call_user_error(nobj,GLU_NURBS_ERROR8);
+                    return;
+                }
+                nobj->curve.geom.type=type;
+                nobj->curve.geom.knot_count=nknots;
+                nobj->curve.geom.knot=knot;
+                nobj->curve.geom.stride=stride;
+                nobj->curve.geom.ctrlarray=ctlarray;
+                nobj->curve.geom.order=order;
+                break;
+            case GL_MAP1_INDEX:
+            case GL_MAP1_COLOR_4:
+                nobj->curve.color.type=type;
+                nobj->curve.color.knot_count=nknots;
+                nobj->curve.color.knot=knot;
+                nobj->curve.color.stride=stride;
+                nobj->curve.color.ctrlarray=ctlarray;
+                nobj->curve.color.order=order;
+                break;
+            case GL_MAP1_NORMAL:
+                nobj->curve.normal.type=type;
+                nobj->curve.normal.knot_count=nknots;
+                nobj->curve.normal.knot=knot;
+                nobj->curve.normal.stride=stride;
+                nobj->curve.normal.ctrlarray=ctlarray;
+                nobj->curve.normal.order=order;
+                break;
+            case GL_MAP1_TEXTURE_COORD_1:
+            case GL_MAP1_TEXTURE_COORD_2:
+            case GL_MAP1_TEXTURE_COORD_3:
+            case GL_MAP1_TEXTURE_COORD_4:
+                nobj->curve.texture.type=type;
+                nobj->curve.texture.knot_count=nknots;
+                nobj->curve.texture.knot=knot;
+                nobj->curve.texture.stride=stride;
+                nobj->curve.texture.ctrlarray=ctlarray;
+                nobj->curve.texture.order=order;
+                break;
+            default:
+                 call_user_error(nobj,GLU_INVALID_ENUM);
+        }
+    }
+}
+
+
+void GLAPIENTRY gluBeginSurface( GLUnurbsObj *nobj )
+{
+    switch(nobj->nurbs_type)
+    {
+        case GLU_NURBS_NONE:
+            nobj->nurbs_type=GLU_NURBS_SURFACE;
+            nobj->surface.geom.type=GLU_INVALID_ENUM;
+            nobj->surface.color.type=GLU_INVALID_ENUM;
+            nobj->surface.texture.type=GLU_INVALID_ENUM;
+            nobj->surface.normal.type=GLU_INVALID_ENUM;
+            break;
+        case GLU_NURBS_TRIM:
+            call_user_error(nobj,GLU_NURBS_ERROR16);
+            break;
+        case GLU_NURBS_SURFACE:
+        case GLU_NURBS_NO_TRIM:
+        case GLU_NURBS_TRIM_DONE:
+            call_user_error(nobj,GLU_NURBS_ERROR27);
+            break;
+        case GLU_NURBS_CURVE:
+            call_user_error(nobj,GLU_NURBS_ERROR6);
+            break;
+    }
+}
+
+
+void GLAPIENTRY gluEndSurface( GLUnurbsObj * nobj )
+{
+    switch(nobj->nurbs_type)
+    {
+        case GLU_NURBS_NONE:
+            call_user_error(nobj,GLU_NURBS_ERROR13);
+            break;
+        case GLU_NURBS_TRIM:
+            call_user_error(nobj,GLU_NURBS_ERROR12);
+            break;
+        case GLU_NURBS_TRIM_DONE:
+/*            if(nobj->trim->trim_loop==NULL)
+            {
+                call_user_error(nobj,GLU_NURBS_ERROR18);
+                return;
+            }*/
+            /* no break - fallthrough */
+        case GLU_NURBS_NO_TRIM:
+            glPushAttrib( (GLbitfield)
+                               (GL_EVAL_BIT | GL_ENABLE_BIT | GL_POLYGON_BIT) );
+            glDisable(GL_MAP2_VERTEX_3);
+            glDisable(GL_MAP2_VERTEX_4);
+            glDisable(GL_MAP2_INDEX);
+            glDisable(GL_MAP2_COLOR_4);
+            glDisable(GL_MAP2_NORMAL);
+            glDisable(GL_MAP2_TEXTURE_COORD_1);
+            glDisable(GL_MAP2_TEXTURE_COORD_2);
+            glDisable(GL_MAP2_TEXTURE_COORD_3);
+            glDisable(GL_MAP2_TEXTURE_COORD_4);
+/*            glDisable(GL_MAP1_VERTEX_3);
+            glDisable(GL_MAP1_VERTEX_4);
+            glDisable(GL_MAP1_INDEX);
+            glDisable(GL_MAP1_COLOR_4);
+            glDisable(GL_MAP1_NORMAL);
+            glDisable(GL_MAP1_TEXTURE_COORD_1);
+            glDisable(GL_MAP1_TEXTURE_COORD_2);
+            glDisable(GL_MAP1_TEXTURE_COORD_3);
+            glDisable(GL_MAP1_TEXTURE_COORD_4);*/
+            do_nurbs_surface(nobj);
+            glPopAttrib();
+            break;
+        default:
+            call_user_error(nobj,GLU_NURBS_ERROR8);
+    }
+    nobj->nurbs_type=GLU_NURBS_NONE;
+}
+
+
+void GLAPIENTRY gluNurbsSurface( GLUnurbsObj *nobj,
+              GLint sknot_count, GLfloat *sknot,
+              GLint tknot_count, GLfloat *tknot,
+              GLint s_stride, GLint t_stride,
+              GLfloat *ctrlarray,
+              GLint sorder, GLint torder,
+              GLenum type )
+{
+    if(nobj->nurbs_type==GLU_NURBS_NO_TRIM || nobj->nurbs_type==GLU_NURBS_TRIM ||
+        nobj->nurbs_type==GLU_NURBS_TRIM_DONE)
+    {
+        if(type==GL_MAP2_VERTEX_3 || type==GL_MAP2_VERTEX_4)
+        {
+            call_user_error(nobj,GLU_NURBS_ERROR8);
+            return;
+        }
+    }
+    else
+    if(nobj->nurbs_type!=GLU_NURBS_SURFACE)
+    {
+        call_user_error(nobj,GLU_NURBS_ERROR11);
+        return;
+    }
+    switch(type)
+    {
+        case GL_MAP2_VERTEX_3:
+        case GL_MAP2_VERTEX_4:
+            nobj->surface.geom.sknot_count=sknot_count;
+            nobj->surface.geom.sknot=sknot;
+            nobj->surface.geom.tknot_count=tknot_count;
+            nobj->surface.geom.tknot=tknot;
+            nobj->surface.geom.s_stride=s_stride;
+            nobj->surface.geom.t_stride=t_stride;
+            nobj->surface.geom.ctrlarray=ctrlarray;
+            nobj->surface.geom.sorder=sorder;
+            nobj->surface.geom.torder=torder;
+            nobj->surface.geom.type=type;
+            nobj->nurbs_type=GLU_NURBS_NO_TRIM;
+            break;
+        case GL_MAP2_INDEX:
+        case GL_MAP2_COLOR_4:
+            nobj->surface.color.sknot_count=sknot_count;
+            nobj->surface.color.sknot=sknot;
+            nobj->surface.color.tknot_count=tknot_count;
+            nobj->surface.color.tknot=tknot;
+            nobj->surface.color.s_stride=s_stride;
+            nobj->surface.color.t_stride=t_stride;
+            nobj->surface.color.ctrlarray=ctrlarray;
+            nobj->surface.color.sorder=sorder;
+            nobj->surface.color.torder=torder;
+            nobj->surface.color.type=type;
+            break;
+        case GL_MAP2_NORMAL:
+            nobj->surface.normal.sknot_count=sknot_count;
+            nobj->surface.normal.sknot=sknot;
+            nobj->surface.normal.tknot_count=tknot_count;
+            nobj->surface.normal.tknot=tknot;
+            nobj->surface.normal.s_stride=s_stride;
+            nobj->surface.normal.t_stride=t_stride;
+            nobj->surface.normal.ctrlarray=ctrlarray;
+            nobj->surface.normal.sorder=sorder;
+            nobj->surface.normal.torder=torder;
+            nobj->surface.normal.type=type;
+            break;
+        case GL_MAP2_TEXTURE_COORD_1:
+        case GL_MAP2_TEXTURE_COORD_2:
+        case GL_MAP2_TEXTURE_COORD_3:
+        case GL_MAP2_TEXTURE_COORD_4:
+            nobj->surface.texture.sknot_count=sknot_count;
+            nobj->surface.texture.sknot=sknot;
+            nobj->surface.texture.tknot_count=tknot_count;
+            nobj->surface.texture.tknot=tknot;
+            nobj->surface.texture.s_stride=s_stride;
+            nobj->surface.texture.t_stride=t_stride;
+            nobj->surface.texture.ctrlarray=ctrlarray;
+            nobj->surface.texture.sorder=sorder;
+            nobj->surface.texture.torder=torder;
+            nobj->surface.texture.type=type;
+            break;
+        default:
+             call_user_error(nobj,GLU_INVALID_ENUM);
+    }
+}
+
+
+void GLAPIENTRY
+gluNurbsCallback( GLUnurbsObj *nobj, GLenum which, void (GLCALLBACK *fn)())
+{
+#if defined(__CYGWIN32__) || defined(OPENSTEP)
+    nobj->error_callback = (void(*)(GLenum))fn;
+#else
+    nobj->error_callback = (void(GLCALLBACK*)(GLenum))fn;
+#endif
+
+    if(which!=GLU_ERROR)
+        call_user_error(nobj,GLU_INVALID_ENUM);
+}
+
+void GLAPIENTRY
+gluBeginTrim( GLUnurbsObj *nobj )
+{
+#if 0
+    nurbs_trim *ptr;
+#endif
+
+    if(nobj->nurbs_type!=GLU_NURBS_TRIM_DONE)
+        if(nobj->nurbs_type!=GLU_NURBS_NO_TRIM)
+        {
+            call_user_error(nobj,GLU_NURBS_ERROR15);
+            return;
+        }
+    nobj->nurbs_type=GLU_NURBS_TRIM;
+fprintf(stderr,"NURBS - trimming not supported yet\n");
+#if 0
+    if((ptr=(nurbs_trim *)malloc(sizeof(nurbs_trim)))==NULL)
+    {
+        call_user_error(nobj,GLU_OUT_OF_MEMORY);
+        return;
+    }
+    if(nobj->trim)
+    {
+        nurbs_trim *tmp_ptr;
+
+        for(tmp_ptr=nobj->trim;tmp_ptr->next;tmp_ptr=tmp_ptr->next);
+        tmp_ptr->next=ptr;
+    }
+    else
+        nobj->trim=ptr;
+    ptr->trim_loop=NULL;
+    ptr->segments=NULL;
+    ptr->next=NULL;
+#endif
+}
+
+void GLAPIENTRY
+gluPwlCurve( GLUnurbsObj *nobj, GLint count, GLfloat *array, GLint stride,
+    GLenum type)
+{
+#if 0
+    nurbs_trim *ptr1;
+    trim_list *ptr2;
+#endif
+    if(nobj->nurbs_type==GLU_NURBS_CURVE)
+    {
+        call_user_error(nobj,GLU_NURBS_ERROR9);
+        return;
+    }
+    if(nobj->nurbs_type==GLU_NURBS_NONE)
+    {
+        call_user_error(nobj,GLU_NURBS_ERROR19);
+        return;
+    }
+    if(type!=GLU_MAP1_TRIM_2 && type!=GLU_MAP1_TRIM_3)
+    {
+        call_user_error(nobj,GLU_NURBS_ERROR14);
+        return;
+    }
+#if 0
+    for(ptr1=nobj->trim;ptr1->next;ptr1=ptr1->next);
+    if(ptr1->trim_loop)
+    {
+        for(ptr2=ptr1->trim_loop;ptr2->next;ptr2=ptr2->next);
+        if((ptr2->next=(trim_list *)malloc(sizeof(trim_list)))==NULL)
+        {
+            call_user_error(nobj,GLU_OUT_OF_MEMORY);
+            return;
+        }
+        ptr2=ptr2->next;
+    }
+    else
+    {
+        if((ptr2=(trim_list *)malloc(sizeof(trim_list)))==NULL)
+        {
+            call_user_error(nobj,GLU_OUT_OF_MEMORY);
+            return;
+        }
+        ptr1->trim_loop=ptr2;
+    }
+    ptr2->trim_type=GLU_TRIM_PWL;
+    ptr2->curve.pwl_curve.pt_count=count;
+    ptr2->curve.pwl_curve.ctrlarray=array;
+    ptr2->curve.pwl_curve.stride=stride;
+    ptr2->curve.pwl_curve.dim= (type==GLU_MAP1_TRIM_2 ? 2 : 3 );
+    ptr2->curve.pwl_curve.type=type;
+    ptr2->next=NULL;
+#endif
+}
+
+void GLAPIENTRY
+gluEndTrim( GLUnurbsObj *nobj )
+{
+    if(nobj->nurbs_type!=GLU_NURBS_TRIM)
+    {
+        call_user_error(nobj,GLU_NURBS_ERROR17);
+        return;
+    }
+    nobj->nurbs_type=GLU_NURBS_TRIM_DONE;
+}
+
diff --git a/src/glu/mesa/nurbs.h b/src/glu/mesa/nurbs.h
new file mode 100644 (file)
index 0000000..fc2b4f7
--- /dev/null
@@ -0,0 +1,252 @@
+/* $Id: nurbs.h,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * Copyright (C) 1995-1999  Brian Paul
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/*
+ * $Log: nurbs.h,v $
+ * Revision 1.1  1999/08/19 00:55:42  jtg
+ * Initial revision
+ *
+ * Revision 1.5  1999/02/27 13:55:31  brianp
+ * fixed BeOS-related GLU typedef problems
+ *
+ * Revision 1.4  1999/01/03 03:23:15  brianp
+ * now using GLAPIENTRY and GLCALLBACK keywords (Ted Jump)
+ *
+ * Revision 1.3  1997/05/27 03:18:23  brianp
+ * minor clean-up
+ *
+ * Revision 1.2  1997/05/27 03:00:16  brianp
+ * incorporated Bogdan's new NURBS code
+ *
+ * Revision 1.1  1996/09/27 01:19:39  brianp
+ * Initial revision
+ *
+ */
+
+
+/*
+ * NURBS implementation written by Bogdan Sikorski (bogdan@cira.it)
+ * See README2 for more info.
+ */
+
+
+#ifndef NURBS_H
+#define NURBS_H
+
+
+#define EPSILON 1e-06 /* epsilon for double precision compares */
+
+typedef enum
+{
+       GLU_NURBS_CURVE, GLU_NURBS_SURFACE, GLU_NURBS_TRIM, GLU_NURBS_NO_TRIM,
+       GLU_NURBS_TRIM_DONE, GLU_NURBS_NONE
+} GLU_nurbs_enum;
+
+typedef enum
+{
+       GLU_TRIM_NURBS, GLU_TRIM_PWL
+} GLU_trim_enum;
+
+typedef struct
+{
+       GLint   sknot_count;
+       GLfloat *sknot;
+       GLint   tknot_count;
+       GLfloat *tknot;
+       GLint   s_stride;
+       GLint   t_stride;
+       GLfloat *ctrlarray;
+       GLint   sorder;
+       GLint   torder;
+       GLint   dim;
+       GLenum  type;
+} surface_attribs;
+
+typedef struct
+{
+       surface_attribs geom;
+       surface_attribs color;
+       surface_attribs texture;
+       surface_attribs normal;
+} nurbs_surface;
+
+typedef struct
+{
+       GLint                   knot_count;
+       GLfloat                 *knot;
+       GLint                   stride;
+       GLfloat                 *ctrlarray;
+       GLint                   order;
+       GLint                   dim;
+       GLenum                  type;
+} curve_attribs;
+
+typedef struct
+{
+       GLint                   pt_count;
+       GLfloat                 *ctrlarray;
+       GLint                   stride;
+       GLint                   dim;
+       GLenum                  type;
+} pwl_curve_attribs;
+
+typedef struct
+{
+       curve_attribs   geom;
+       curve_attribs   color;
+       curve_attribs   texture;
+       curve_attribs   normal;
+} nurbs_curve;
+
+typedef struct trim_list_str
+{
+       GLU_trim_enum                   trim_type;
+       union
+       {
+               pwl_curve_attribs       pwl_curve;
+               curve_attribs           nurbs_curve;
+       }                                               curve;
+       struct trim_list_str    *next;
+} trim_list;
+
+typedef struct seg_trim_str
+{
+       GLfloat                         *points;
+       GLint                           pt_cnt,seg_array_len;
+       struct seg_trim_str     *next;
+} trim_segments;
+
+typedef struct nurbs_trim_str
+{
+       trim_list                               *trim_loop;
+       trim_segments                   *segments;
+       struct nurbs_trim_str   *next;
+} nurbs_trim;
+
+typedef struct
+{
+       GLfloat model[16],proj[16],viewport[4];
+} culling_and_sampling_str;
+
+struct GLUnurbs {
+       GLboolean               culling;
+       GLenum                  error;
+       void                    (GLCALLBACK *error_callback)( GLenum err );
+       GLenum                  display_mode;
+       GLU_nurbs_enum  nurbs_type;
+       GLboolean               auto_load_matrix;
+       culling_and_sampling_str
+                                       sampling_matrices;
+       GLenum                  sampling_method;
+       GLfloat                 sampling_tolerance;
+       GLfloat                 parametric_tolerance;
+       GLint                   u_step, v_step;
+       nurbs_surface   surface;
+       nurbs_curve             curve;
+       nurbs_trim              *trim;
+};
+
+typedef struct
+{
+       GLfloat         *knot;
+       GLint           nknots;
+       GLfloat         *unified_knot;
+       GLint           unified_nknots;
+       GLint           order;
+       GLint           t_min,t_max;
+       GLint           delta_nknots;
+       GLboolean       open_at_begin,open_at_end;
+       GLfloat         *new_knot;
+       GLfloat         *alpha;
+} knot_str_type;
+
+typedef struct
+{
+       GLfloat *geom_ctrl;
+       GLint   geom_s_stride,geom_t_stride;
+       GLfloat **geom_offsets;
+       GLint   geom_s_pt_cnt,geom_t_pt_cnt;
+       GLfloat *color_ctrl;
+       GLint   color_s_stride,color_t_stride;
+       GLfloat **color_offsets;
+       GLint   color_s_pt_cnt,color_t_pt_cnt;
+       GLfloat *normal_ctrl;
+       GLint   normal_s_stride,normal_t_stride;
+       GLfloat **normal_offsets;
+       GLint   normal_s_pt_cnt,normal_t_pt_cnt;
+       GLfloat *texture_ctrl;
+       GLint   texture_s_stride,texture_t_stride;
+       GLfloat **texture_offsets;
+       GLint   texture_s_pt_cnt,texture_t_pt_cnt;
+       GLint   s_bezier_cnt,t_bezier_cnt;
+} new_ctrl_type;
+
+extern void call_user_error( GLUnurbsObj *nobj, GLenum error );
+
+extern GLenum test_knot(GLint nknots, GLfloat *knot, GLint order);
+
+extern GLenum explode_knot(knot_str_type *the_knot);
+
+extern GLenum calc_alphas(knot_str_type *the_knot);
+
+extern GLenum calc_new_ctrl_pts(GLfloat *ctrl,GLint stride,knot_str_type *the_knot,
+       GLint dim,GLfloat **new_ctrl,GLint *ncontrol);
+
+extern GLenum glu_do_sampling_crv(GLUnurbsObj *nobj, GLfloat *new_ctrl,GLint n_ctrl,
+       GLint order,GLint dim,GLint **factors);
+
+extern GLenum glu_do_sampling_3D(GLUnurbsObj *nobj, new_ctrl_type *new_ctrl,
+       int **sfactors, GLint **tfactors);
+
+extern GLenum glu_do_sampling_uv(GLUnurbsObj *nobj, new_ctrl_type *new_ctrl,
+       int **sfactors, GLint **tfactors);
+
+extern GLenum glu_do_sampling_param_3D(GLUnurbsObj *nobj, new_ctrl_type *new_ctrl,
+       int **sfactors, GLint **tfactors);
+
+extern GLboolean fine_culling_test_2D(GLUnurbsObj *nobj, GLfloat *ctrl, GLint n_ctrl,
+       GLint stride, GLint dim);
+
+extern GLboolean fine_culling_test_3D(GLUnurbsObj *nobj, GLfloat *ctrl,
+       GLint s_n_ctrl, GLint t_n_ctrl, GLint s_stride, GLint t_stride, GLint dim);
+
+extern void do_nurbs_curve( GLUnurbsObj *nobj);
+
+extern void do_nurbs_surface( GLUnurbsObj *nobj);
+
+extern GLenum patch_trimming(GLUnurbsObj *nobj,new_ctrl_type *new_ctrl,
+       GLint *sfactors, GLint *tfactors);
+
+extern void collect_unified_knot(knot_str_type *dest, knot_str_type *src,
+       GLfloat maximal_min_knot, GLfloat minimal_max_knot);
+
+extern GLenum select_knot_working_range(GLUnurbsObj *nobj,knot_str_type *geom_knot,
+       knot_str_type *color_knot, knot_str_type *normal_knot,
+       knot_str_type *texture_knot);
+
+extern void free_unified_knots(knot_str_type *geom_knot, knot_str_type *color_knot,
+       knot_str_type *normal_knot, knot_str_type *texture_knot);
+
+
+
+#endif
diff --git a/src/glu/mesa/nurbscrv.c b/src/glu/mesa/nurbscrv.c
new file mode 100644 (file)
index 0000000..022818b
--- /dev/null
@@ -0,0 +1,500 @@
+/* $Id: nurbscrv.c,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  2.4
+ * Copyright (C) 1995-1997  Brian Paul
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/*
+ * $Log: nurbscrv.c,v $
+ * Revision 1.1  1999/08/19 00:55:42  jtg
+ * Initial revision
+ *
+ * Revision 1.6  1997/07/24 01:28:44  brianp
+ * changed precompiled header symbol from PCH to PC_HEADER
+ *
+ * Revision 1.5  1997/05/28 02:29:38  brianp
+ * added support for precompiled headers (PCH), inserted APIENTRY keyword
+ *
+ * Revision 1.4  1997/05/27 03:21:22  brianp
+ * minor clean-up
+ *
+ * Revision 1.3  1997/05/27 03:00:16  brianp
+ * incorporated Bogdan's new NURBS code
+ *
+ * Revision 1.2  1996/09/27 23:12:22  brianp
+ * added return 0 to get_surface_dim() to silence warning
+ *
+ * Revision 1.1  1996/09/27 01:19:39  brianp
+ * Initial revision
+ *
+ */
+
+
+/*
+ * NURBS implementation written by Bogdan Sikorski (bogdan@cira.it)
+ * See README2 for more info.
+ */
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <math.h>
+#include <stdlib.h>
+#include "gluP.h"
+#include "nurbs.h"
+#endif
+
+
+static int
+get_curve_dim(GLenum type)
+{
+       switch(type)
+       {
+               case GL_MAP1_VERTEX_3:                  return 3;
+               case GL_MAP1_VERTEX_4:                  return 4;
+               case GL_MAP1_INDEX:                             return 1;
+               case GL_MAP1_COLOR_4:                   return 4;
+               case GL_MAP1_NORMAL:                    return 3;
+               case GL_MAP1_TEXTURE_COORD_1:   return 1;
+               case GL_MAP1_TEXTURE_COORD_2:   return 2;
+               case GL_MAP1_TEXTURE_COORD_3:   return 3;
+               case GL_MAP1_TEXTURE_COORD_4:   return 4;
+                default:  abort();  /* TODO: is this OK? */
+       }
+        return 0; /*never get here*/
+}
+
+static GLenum
+test_nurbs_curve(GLUnurbsObj *nobj, curve_attribs *attribs)
+{
+       GLenum err;
+       GLint tmp_int;
+
+       if(attribs->order < 0)
+       {
+               call_user_error(nobj,GLU_INVALID_VALUE);
+               return GLU_ERROR;
+       }
+       glGetIntegerv(GL_MAX_EVAL_ORDER,&tmp_int);
+       if(attribs->order > tmp_int || attribs->order < 2)
+       {
+               call_user_error(nobj,GLU_NURBS_ERROR1);
+               return GLU_ERROR;
+       }
+       if(attribs->knot_count < attribs->order +2)
+       {
+               call_user_error(nobj,GLU_NURBS_ERROR2);
+               return GLU_ERROR;
+       }
+       if(attribs->stride < 0)
+       {
+               call_user_error(nobj,GLU_NURBS_ERROR34);
+               return GLU_ERROR;
+       }
+       if(attribs->knot==NULL || attribs->ctrlarray==NULL)
+       {
+               call_user_error(nobj,GLU_NURBS_ERROR36);
+               return GLU_ERROR;
+       }
+       if((err=test_knot(attribs->knot_count,attribs->knot,attribs->order))
+               !=GLU_NO_ERROR)
+       {
+               call_user_error(nobj,err);
+               return GLU_ERROR;
+       }
+       return GLU_NO_ERROR;
+}
+
+static GLenum
+test_nurbs_curves(GLUnurbsObj *nobj)
+{
+       /* test the geometric data */
+       if(test_nurbs_curve(nobj,&(nobj->curve.geom))!=GLU_NO_ERROR)
+               return GLU_ERROR;
+       /* now test the attributive data */
+       /* color */
+       if(nobj->curve.color.type!=GLU_INVALID_ENUM)
+               if(test_nurbs_curve(nobj,&(nobj->curve.color))!=GLU_NO_ERROR)
+                       return GLU_ERROR;
+       /* normal */
+       if(nobj->curve.normal.type!=GLU_INVALID_ENUM)
+               if(test_nurbs_curve(nobj,&(nobj->curve.normal))!=GLU_NO_ERROR)
+                       return GLU_ERROR;
+       /* texture */
+       if(nobj->curve.texture.type!=GLU_INVALID_ENUM)
+               if(test_nurbs_curve(nobj,&(nobj->curve.texture))!=GLU_NO_ERROR)
+                       return GLU_ERROR;
+       return GLU_NO_ERROR;
+}
+
+/* prepare the knot information structures */
+static GLenum
+fill_knot_structures(GLUnurbsObj *nobj,knot_str_type *geom_knot,
+       knot_str_type *color_knot, knot_str_type *normal_knot,
+       knot_str_type *texture_knot)
+{
+       GLint order;
+       GLfloat *knot;
+       GLint nknots;
+       GLint t_min,t_max;
+
+       geom_knot->unified_knot=NULL;
+       knot=geom_knot->knot=nobj->curve.geom.knot;
+       nknots=geom_knot->nknots=nobj->curve.geom.knot_count;
+       order=geom_knot->order=nobj->curve.geom.order;
+       geom_knot->delta_nknots=0;
+       t_min=geom_knot->t_min=order-1;
+       t_max=geom_knot->t_max=nknots-order;
+       if(fabs(knot[t_min]-knot[t_max])<EPSILON)
+       {
+               call_user_error(nobj,GLU_NURBS_ERROR3);
+               return GLU_ERROR;
+       }
+       if(fabs(knot[0]-knot[t_min])<EPSILON)
+       {
+               /* knot open at beggining */
+               geom_knot->open_at_begin=GL_TRUE;
+       }
+       else
+               geom_knot->open_at_begin=GL_FALSE;
+       if(fabs(knot[t_max]-knot[nknots-1])<EPSILON)
+       {
+               /* knot open at end */
+               geom_knot->open_at_end=GL_TRUE;
+       }
+       else
+               geom_knot->open_at_end=GL_FALSE;
+       if(nobj->curve.color.type!=GLU_INVALID_ENUM)
+       {
+               color_knot->unified_knot=(GLfloat *)1;
+               knot=color_knot->knot=nobj->curve.color.knot;
+               nknots=color_knot->nknots=nobj->curve.color.knot_count;
+               order=color_knot->order=nobj->curve.color.order;
+               color_knot->delta_nknots=0;
+               t_min=color_knot->t_min=order-1;
+               t_max=color_knot->t_max=nknots-order;
+               if(fabs(knot[t_min]-knot[t_max])<EPSILON)
+               {
+                       call_user_error(nobj,GLU_NURBS_ERROR3);
+                       return GLU_ERROR;
+               }
+               if(fabs(knot[0]-knot[t_min])<EPSILON)
+               {
+                       /* knot open at beggining */
+                       color_knot->open_at_begin=GL_TRUE;
+               }
+               else
+                       color_knot->open_at_begin=GL_FALSE;
+               if(fabs(knot[t_max]-knot[nknots-1])<EPSILON)
+               {
+                       /* knot open at end */
+                       color_knot->open_at_end=GL_TRUE;
+               }
+               else
+                       color_knot->open_at_end=GL_FALSE;
+       }
+       else
+               color_knot->unified_knot=NULL;
+       if(nobj->curve.normal.type!=GLU_INVALID_ENUM)
+       {
+               normal_knot->unified_knot=(GLfloat *)1;
+               knot=normal_knot->knot=nobj->curve.normal.knot;
+               nknots=normal_knot->nknots=nobj->curve.normal.knot_count;
+               order=normal_knot->order=nobj->curve.normal.order;
+               normal_knot->delta_nknots=0;
+               t_min=normal_knot->t_min=order-1;
+               t_max=normal_knot->t_max=nknots-order;
+               if(fabs(knot[t_min]-knot[t_max])<EPSILON)
+               {
+                       call_user_error(nobj,GLU_NURBS_ERROR3);
+                       return GLU_ERROR;
+               }
+               if(fabs(knot[0]-knot[t_min])<EPSILON)
+               {
+                       /* knot open at beggining */
+                       normal_knot->open_at_begin=GL_TRUE;
+               }
+               else
+                       normal_knot->open_at_begin=GL_FALSE;
+               if(fabs(knot[t_max]-knot[nknots-1])<EPSILON)
+               {
+                       /* knot open at end */
+                       normal_knot->open_at_end=GL_TRUE;
+               }
+               else
+                       normal_knot->open_at_end=GL_FALSE;
+       }
+       else
+               normal_knot->unified_knot=NULL;
+       if(nobj->curve.texture.type!=GLU_INVALID_ENUM)
+       {
+               texture_knot->unified_knot=(GLfloat *)1;
+               knot=texture_knot->knot=nobj->curve.texture.knot;
+               nknots=texture_knot->nknots=nobj->curve.texture.knot_count;
+               order=texture_knot->order=nobj->curve.texture.order;
+               texture_knot->delta_nknots=0;
+               t_min=texture_knot->t_min=order-1;
+               t_max=texture_knot->t_max=nknots-order;
+               if(fabs(knot[t_min]-knot[t_max])<EPSILON)
+               {
+                       call_user_error(nobj,GLU_NURBS_ERROR3);
+                       return GLU_ERROR;
+               }
+               if(fabs(knot[0]-knot[t_min])<EPSILON)
+               {
+                       /* knot open at beggining */
+                       texture_knot->open_at_begin=GL_TRUE;
+               }
+               else
+                       texture_knot->open_at_begin=GL_FALSE;
+               if(fabs(knot[t_max]-knot[nknots-1])<EPSILON)
+               {
+                       /* knot open at end */
+                       texture_knot->open_at_end=GL_TRUE;
+               }
+               else
+                       texture_knot->open_at_end=GL_FALSE;
+       }
+       else
+               texture_knot->unified_knot=NULL;
+       return GLU_NO_ERROR;
+}
+
+/* covert the NURBS curve into a series of adjacent Bezier curves */
+static GLenum
+convert_curve(knot_str_type *the_knot, curve_attribs *attrib,
+       GLfloat **new_ctrl,GLint *ncontrol)
+{
+       GLenum err;
+
+       if((err=explode_knot(the_knot))!=GLU_NO_ERROR)
+       {
+               if(the_knot->unified_knot)
+               {
+                       free(the_knot->unified_knot);
+                       the_knot->unified_knot=NULL;
+               }
+               return err;
+       }
+       if(the_knot->unified_knot)
+       {
+               free(the_knot->unified_knot);
+               the_knot->unified_knot=NULL;
+       }
+       if((err=calc_alphas(the_knot))!=GLU_NO_ERROR)
+       {
+               free(the_knot->new_knot);
+               return err;
+       }
+       free(the_knot->new_knot);
+       if((err=calc_new_ctrl_pts(attrib->ctrlarray,attrib->stride,the_knot,
+                                                       attrib->dim,new_ctrl,ncontrol))
+               !=GLU_NO_ERROR)
+       {
+               free(the_knot->alpha);
+               return err;
+       }
+       free(the_knot->alpha);
+       return GLU_NO_ERROR;
+}
+
+/* covert curves - geometry and possible attribute ones into equivalent */
+/* sequence of adjacent Bezier curves */
+static GLenum
+convert_curves(GLUnurbsObj *nobj, GLfloat **new_geom_ctrl,
+       GLint *ncontrol, GLfloat **new_color_ctrl, GLfloat **new_normal_ctrl,
+       GLfloat **new_texture_ctrl)
+{
+       knot_str_type   geom_knot,color_knot,normal_knot,texture_knot;
+       GLint                   junk;
+       GLenum                  err;
+
+       *new_color_ctrl=*new_normal_ctrl=*new_texture_ctrl=NULL;
+
+       if(fill_knot_structures(nobj,&geom_knot,&color_knot,&normal_knot,
+                       &texture_knot)!=GLU_NO_ERROR)
+               return GLU_ERROR;
+
+       /* unify knots - all knots should have the same number of working */
+       /* ranges */
+       if((err=select_knot_working_range(nobj,&geom_knot,&color_knot,&normal_knot,
+                               &texture_knot))!=GLU_NO_ERROR)
+       {
+               return err;
+       }
+       /* convert the geometry curve */
+       nobj->curve.geom.dim=get_curve_dim(nobj->curve.geom.type);
+       if((err=convert_curve(&geom_knot,&(nobj->curve.geom),new_geom_ctrl,
+                                               ncontrol))!=GLU_NO_ERROR)
+       {
+               free_unified_knots(&geom_knot,&color_knot,&normal_knot,&texture_knot);
+               call_user_error(nobj,err);
+               return err;
+       }
+       /* if additional attributive curves are given convert them as well */
+       if(color_knot.unified_knot)
+       {
+               nobj->curve.color.dim=get_curve_dim(nobj->curve.color.type);
+               if((err=convert_curve(&color_knot,&(nobj->curve.color),
+                       new_color_ctrl,&junk))!=GLU_NO_ERROR)
+               {
+                       free_unified_knots(&geom_knot,&color_knot,&normal_knot,&texture_knot);
+                       free(*new_geom_ctrl);
+                       call_user_error(nobj,err);
+                       return err;
+               }
+       }
+       if(normal_knot.unified_knot)
+       {
+               nobj->curve.normal.dim=get_curve_dim(nobj->curve.normal.type);
+               if((err=convert_curve(&normal_knot,&(nobj->curve.normal),
+                       new_normal_ctrl,&junk))!=GLU_NO_ERROR)
+               {
+                       free_unified_knots(&geom_knot,&color_knot,&normal_knot,&texture_knot);
+                       free(*new_geom_ctrl);
+                       if(*new_color_ctrl)
+                               free(*new_color_ctrl);
+                       call_user_error(nobj,err);
+                       return err;
+               }
+       }
+       if(texture_knot.unified_knot)
+       {
+               nobj->curve.texture.dim=get_curve_dim(nobj->curve.texture.type);
+               if((err=convert_curve(&texture_knot,&(nobj->curve.texture),
+                       new_texture_ctrl,&junk))!=GLU_NO_ERROR)
+               {
+                       free_unified_knots(&geom_knot,&color_knot,&normal_knot,&texture_knot);
+                       free(*new_geom_ctrl);
+                       if(*new_color_ctrl)
+                               free(*new_color_ctrl);
+                       if(*new_normal_ctrl)
+                               free(*new_normal_ctrl);
+                       call_user_error(nobj,err);
+                       return err;
+               }
+       }
+       return GLU_NO_ERROR;
+}
+
+/* main NURBS curve procedure */
+void do_nurbs_curve( GLUnurbsObj *nobj)
+{
+       GLint geom_order,color_order=0,normal_order=0,texture_order=0;
+       GLenum geom_type;
+       GLint n_ctrl;
+       GLfloat *new_geom_ctrl,*new_color_ctrl,*new_normal_ctrl,*new_texture_ctrl;
+       GLfloat *geom_ctrl,*color_ctrl,*normal_ctrl,*texture_ctrl;
+       GLint *factors;
+       GLint i,j;
+       GLint geom_dim,color_dim=0,normal_dim=0,texture_dim=0;
+
+       /* test the user supplied data */
+       if(test_nurbs_curves(nobj)!=GLU_NO_ERROR)
+               return;
+
+       if(convert_curves(nobj,&new_geom_ctrl,&n_ctrl,&new_color_ctrl,
+                                       &new_normal_ctrl,&new_texture_ctrl)!=GLU_NO_ERROR)
+               return;
+
+       geom_order=nobj->curve.geom.order;
+       geom_type=nobj->curve.geom.type;
+       geom_dim=nobj->curve.geom.dim;
+
+       if(glu_do_sampling_crv(nobj,new_geom_ctrl,n_ctrl,geom_order,geom_dim,
+                                               &factors)
+               !=GLU_NO_ERROR)
+       {
+               free(new_geom_ctrl);
+               if(new_color_ctrl)
+                       free(new_color_ctrl);
+               if(new_normal_ctrl)
+                       free(new_normal_ctrl);
+               if(new_texture_ctrl)
+                       free(new_texture_ctrl);
+               return;
+       }
+       glEnable(geom_type);
+       if(new_color_ctrl)
+       {
+               glEnable(nobj->curve.color.type);
+               color_dim=nobj->curve.color.dim;
+               color_ctrl=new_color_ctrl;
+               color_order=nobj->curve.color.order;
+       }
+       if(new_normal_ctrl)
+       {
+               glEnable(nobj->curve.normal.type);
+               normal_dim=nobj->curve.normal.dim;
+               normal_ctrl=new_normal_ctrl;
+               normal_order=nobj->curve.normal.order;
+       }
+       if(new_texture_ctrl)
+       {
+               glEnable(nobj->curve.texture.type);
+               texture_dim=nobj->curve.texture.dim;
+               texture_ctrl=new_texture_ctrl;
+               texture_order=nobj->curve.texture.order;
+       }
+       for(i=0 , j=0, geom_ctrl=new_geom_ctrl;
+               i<n_ctrl;
+               i+=geom_order , j++ , geom_ctrl+=geom_order*geom_dim)
+       {
+               if(fine_culling_test_2D(nobj,geom_ctrl,geom_order,geom_dim,geom_dim))
+               {
+                       color_ctrl+=color_order*color_dim;
+                       normal_ctrl+=normal_order*normal_dim;
+                       texture_ctrl+=texture_order*texture_dim;
+                       continue;
+               }
+               glMap1f(geom_type, 0.0, 1.0, geom_dim, geom_order, geom_ctrl);
+               if(new_color_ctrl)
+               {
+                       glMap1f(nobj->curve.color.type, 0.0, 1.0, color_dim,
+                               color_order,color_ctrl);
+                       color_ctrl+=color_order*color_dim;
+               }
+               if(new_normal_ctrl)
+               {
+                       glMap1f(nobj->curve.normal.type, 0.0, 1.0, normal_dim,
+                               normal_order,normal_ctrl);
+                       normal_ctrl+=normal_order*normal_dim;
+               }
+               if(new_texture_ctrl)
+               {
+                       glMap1f(nobj->curve.texture.type, 0.0, 1.0, texture_dim,
+                               texture_order,texture_ctrl);
+                       texture_ctrl+=texture_order*texture_dim;
+               }
+               glMapGrid1f(factors[j],0.0,1.0);
+               glEvalMesh1(GL_LINE,0,factors[j]);
+       }
+       free(new_geom_ctrl);
+       free(factors);
+       if(new_color_ctrl)
+               free(new_color_ctrl);
+       if(new_normal_ctrl)
+               free(new_normal_ctrl);
+       if(new_texture_ctrl)
+               free(new_texture_ctrl);
+}
+
+
diff --git a/src/glu/mesa/nurbssrf.c b/src/glu/mesa/nurbssrf.c
new file mode 100644 (file)
index 0000000..57eb956
--- /dev/null
@@ -0,0 +1,1422 @@
+/* $Id: nurbssrf.c,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  2.4
+ * Copyright (C) 1995-1997  Brian Paul
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/*
+ * $Log: nurbssrf.c,v $
+ * Revision 1.1  1999/08/19 00:55:42  jtg
+ * Initial revision
+ *
+ * Revision 1.7  1997/07/24 01:28:44  brianp
+ * changed precompiled header symbol from PCH to PC_HEADER
+ *
+ * Revision 1.6  1997/06/23 00:22:07  brianp
+ * include <string.h>
+ *
+ * Revision 1.5  1997/05/28 02:29:38  brianp
+ * added support for precompiled headers (PCH), inserted APIENTRY keyword
+ *
+ * Revision 1.4  1997/05/27 03:20:35  brianp
+ * minor clean-up
+ *
+ * Revision 1.3  1997/05/27 03:00:16  brianp
+ * incorporated Bogdan's new NURBS code
+ *
+ * Revision 1.2  1996/09/27 23:13:02  brianp
+ * added return 0 to get_surface_dim() to silence warning
+ *
+ * Revision 1.1  1996/09/27 01:19:39  brianp
+ * Initial revision
+ *
+ */
+
+
+/*
+ * NURBS implementation written by Bogdan Sikorski (bogdan@cira.it)
+ * See README2 for more info.
+ */
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include "gluP.h"
+#include "nurbs.h"
+#endif
+
+
+static int
+get_surface_dim(GLenum type)
+{
+       switch(type)
+       {
+               case GL_MAP2_VERTEX_3:                  return 3;
+               case GL_MAP2_VERTEX_4:                  return 4;
+               case GL_MAP2_INDEX:                             return 1;
+               case GL_MAP2_COLOR_4:                   return 4;
+               case GL_MAP2_NORMAL:                    return 3;
+               case GL_MAP2_TEXTURE_COORD_1:   return 1;
+               case GL_MAP2_TEXTURE_COORD_2:   return 2;
+               case GL_MAP2_TEXTURE_COORD_3:   return 3;
+               case GL_MAP2_TEXTURE_COORD_4:   return 4;
+                default:  abort();  /* TODO: is this OK? */
+       }
+        return 0; /*never get here*/
+}
+
+static GLenum
+test_nurbs_surface(GLUnurbsObj *nobj, surface_attribs *attrib)
+{
+       GLenum err;
+       GLint tmp_int;
+
+       if(attrib->sorder < 0 || attrib->torder < 0)
+       {
+               call_user_error(nobj,GLU_INVALID_VALUE);
+               return GLU_ERROR;
+       }
+       glGetIntegerv(GL_MAX_EVAL_ORDER,&tmp_int);
+       if(attrib->sorder > tmp_int || attrib->sorder < 2)
+       {
+               call_user_error(nobj,GLU_NURBS_ERROR1);
+               return GLU_ERROR;
+       }
+       if(attrib->torder > tmp_int || attrib->torder < 2)
+       {
+               call_user_error(nobj,GLU_NURBS_ERROR1);
+               return GLU_ERROR;
+       }
+       if(attrib->sknot_count < attrib->sorder +2)
+       {
+               call_user_error(nobj,GLU_NURBS_ERROR2);
+               return GLU_ERROR;
+       }
+       if(attrib->tknot_count < attrib->torder +2)
+       {
+               call_user_error(nobj,GLU_NURBS_ERROR2);
+               return GLU_ERROR;
+       }
+       if(attrib->s_stride < 0 || attrib->t_stride < 0)
+       {
+               call_user_error(nobj,GLU_NURBS_ERROR34);
+               return GLU_ERROR;
+       }
+       if(attrib->sknot==NULL || attrib->tknot==NULL || attrib->ctrlarray==NULL)
+       {
+               call_user_error(nobj,GLU_NURBS_ERROR36);
+               return GLU_ERROR;
+       }
+       if((err=test_knot(attrib->tknot_count,attrib->tknot,attrib->torder))
+               !=GLU_NO_ERROR)
+       {
+               call_user_error(nobj,err);
+               return GLU_ERROR;
+       }
+       if((err=test_knot(attrib->sknot_count,attrib->sknot,attrib->sorder))
+               !=GLU_NO_ERROR)
+       {
+               call_user_error(nobj,err);
+               return GLU_ERROR;
+       }
+       return GLU_NO_ERROR;
+}
+
+static GLenum
+test_nurbs_surfaces(GLUnurbsObj *nobj)
+{
+       /* test the geometric data */
+       if(test_nurbs_surface(nobj,&(nobj->surface.geom))!=GLU_NO_ERROR)
+               return GLU_ERROR;
+       /* now test the attributive data */
+       /* color */
+       if(nobj->surface.color.type!=GLU_INVALID_ENUM)
+               if(test_nurbs_surface(nobj,&(nobj->surface.color))!=GLU_NO_ERROR)
+                       return GLU_ERROR;
+       /* normal */
+       if(nobj->surface.normal.type!=GLU_INVALID_ENUM)
+               if(test_nurbs_surface(nobj,&(nobj->surface.normal))!=GLU_NO_ERROR)
+                       return GLU_ERROR;
+       /* texture */
+       if(nobj->surface.texture.type!=GLU_INVALID_ENUM)
+               if(test_nurbs_surface(nobj,&(nobj->surface.texture))!=GLU_NO_ERROR)
+                       return GLU_ERROR;
+       return GLU_NO_ERROR;
+}
+
+static GLenum
+convert_surf(knot_str_type *s_knot, knot_str_type *t_knot,
+       surface_attribs *attrib, GLfloat **new_ctrl,
+       GLint *s_n_ctrl, GLint *t_n_ctrl)
+{
+       GLfloat **tmp_ctrl;
+       GLfloat *ctrl_offset;
+       GLint tmp_n_control;
+       GLint i,j,t_cnt,s_cnt;
+       GLint tmp_stride;
+       GLint dim;
+       GLenum err;
+
+       /* valid range is empty? */
+       if((s_knot->unified_knot !=NULL && s_knot->unified_nknots==0) || 
+               (t_knot->unified_knot !=NULL && t_knot->unified_nknots==0))
+       {
+               if(s_knot->unified_knot)
+               {
+                       free(s_knot->unified_knot);
+                       s_knot->unified_knot=NULL;
+               }
+               if(t_knot->unified_knot)
+               {
+                       free(t_knot->unified_knot);
+                       t_knot->unified_knot=NULL;
+               }
+               *s_n_ctrl=0;
+               *t_n_ctrl=0;
+               return GLU_NO_ERROR;
+       }
+       t_cnt=attrib->tknot_count-attrib->torder;
+       s_cnt=attrib->sknot_count-attrib->sorder;
+       if((tmp_ctrl=(GLfloat **)malloc(sizeof(GLfloat *)*t_cnt))==NULL)
+               return GLU_OUT_OF_MEMORY;
+       if((err=explode_knot(s_knot))!=GLU_NO_ERROR)
+       {
+               free(tmp_ctrl);
+               if(s_knot->unified_knot)
+               {
+                       free(s_knot->unified_knot);
+                       s_knot->unified_knot=NULL;
+               }
+               return err;
+       }
+       if(s_knot->unified_knot)
+       {
+               free(s_knot->unified_knot);
+               s_knot->unified_knot=NULL;
+       }
+       if((err=calc_alphas(s_knot))!=GLU_NO_ERROR)
+       {
+               free(tmp_ctrl);
+               free(s_knot->new_knot);
+               return err;
+       }
+       free(s_knot->new_knot);
+       ctrl_offset=attrib->ctrlarray;
+       dim=attrib->dim;
+       for(i=0;i<t_cnt;i++)
+       {
+               if((err=calc_new_ctrl_pts(ctrl_offset,attrib->s_stride,s_knot,
+                       dim,&(tmp_ctrl[i]),&tmp_n_control))!=GLU_NO_ERROR)
+               {
+                       for(--i;i<=0;i--)
+                               free(tmp_ctrl[i]);
+                       free(tmp_ctrl);
+                       free(s_knot->alpha);
+                       return err;
+               }
+               ctrl_offset+=attrib->t_stride;
+       }
+       free(s_knot->alpha);
+       tmp_stride=dim*tmp_n_control;
+       if((*new_ctrl=(GLfloat *)malloc(sizeof(GLfloat)*tmp_stride*t_cnt))
+               ==NULL)
+       {
+               for(i=0;i<t_cnt;i++)
+                       free(tmp_ctrl[i]);
+               free(tmp_ctrl);
+               return GLU_OUT_OF_MEMORY;
+       }
+       for(i=0;i<tmp_n_control;i++)
+               for(j=0;j<t_cnt;j++)
+                       MEMCPY(*new_ctrl+j*dim+i*dim*t_cnt,tmp_ctrl[j]+dim*i,
+                               sizeof(GLfloat)*dim);
+       for(i=0;i<t_cnt;i++)
+               free(tmp_ctrl[i]);
+       free(tmp_ctrl);
+       *s_n_ctrl=tmp_n_control;
+       
+       if((tmp_ctrl=(GLfloat **)malloc(sizeof(GLfloat *)*(*s_n_ctrl)))==NULL)
+       {
+               return GLU_OUT_OF_MEMORY;
+       }
+       if((err=explode_knot(t_knot))!=GLU_NO_ERROR)
+       {
+               free(tmp_ctrl);
+               if(t_knot->unified_knot)
+               {
+                       free(t_knot->unified_knot);
+                       t_knot->unified_knot=NULL;
+               }
+               return err;
+       }
+       if(t_knot->unified_knot)
+       {
+               free(t_knot->unified_knot);
+               t_knot->unified_knot=NULL;
+       }
+       if((err=calc_alphas(t_knot))!=GLU_NO_ERROR)
+       {
+               free(tmp_ctrl);
+               free(t_knot->new_knot);
+               return err;
+       }
+       free(t_knot->new_knot);
+       ctrl_offset=*new_ctrl;
+       for(i=0;i<(*s_n_ctrl);i++)
+       {
+               if((err=calc_new_ctrl_pts(ctrl_offset,dim,t_knot,
+                       dim,&(tmp_ctrl[i]),&tmp_n_control))!=GLU_NO_ERROR)
+               {
+                       for(--i;i<=0;i--)
+                               free(tmp_ctrl[i]);
+                       free(tmp_ctrl);
+                       free(t_knot->alpha);
+                       return err;
+               }
+               ctrl_offset+=dim*t_cnt;
+       }
+       free(t_knot->alpha);
+       free(*new_ctrl);
+       tmp_stride=dim*tmp_n_control;
+       if((*new_ctrl=(GLfloat *)malloc(sizeof(GLfloat)*tmp_stride*(*s_n_ctrl)))
+               ==NULL)
+       {
+               for(i=0;i<(*s_n_ctrl);i++)
+                       free(tmp_ctrl[i]);
+               free(tmp_ctrl);
+               return GLU_OUT_OF_MEMORY;
+       }
+       for(i=0;i<(*s_n_ctrl);i++)
+       {
+               MEMCPY(*new_ctrl+i*tmp_stride,tmp_ctrl[i],sizeof(GLfloat)*tmp_stride);
+               free(tmp_ctrl[i]);
+       }
+       free(tmp_ctrl);
+       *t_n_ctrl=tmp_n_control;
+       return GLU_NO_ERROR;
+}
+
+/* prepare the knot information structures */
+static GLenum
+fill_knot_structures(GLUnurbsObj *nobj,
+       knot_str_type *geom_s_knot, knot_str_type *geom_t_knot,
+       knot_str_type *color_s_knot, knot_str_type *color_t_knot,
+       knot_str_type *normal_s_knot,  knot_str_type *normal_t_knot,
+       knot_str_type *texture_s_knot, knot_str_type *texture_t_knot)
+{
+       GLint order;
+       GLfloat *knot;
+       GLint nknots;
+       GLint t_min,t_max;
+
+       geom_s_knot->unified_knot=NULL;
+       knot=geom_s_knot->knot=nobj->surface.geom.sknot;
+       nknots=geom_s_knot->nknots=nobj->surface.geom.sknot_count;
+       order=geom_s_knot->order=nobj->surface.geom.sorder;
+       geom_s_knot->delta_nknots=0;
+       t_min=geom_s_knot->t_min=order-1;
+       t_max=geom_s_knot->t_max=nknots-order;
+       if(fabs(knot[t_min]-knot[t_max])<EPSILON)
+       {
+               call_user_error(nobj,GLU_NURBS_ERROR3);
+               return GLU_ERROR;
+       }
+       if(fabs(knot[0]-knot[t_min])<EPSILON)
+       {
+               /* knot open at beggining */
+               geom_s_knot->open_at_begin=GL_TRUE;
+       }
+       else
+               geom_s_knot->open_at_begin=GL_FALSE;
+       if(fabs(knot[t_max]-knot[nknots-1])<EPSILON)
+       {
+               /* knot open at end */
+               geom_s_knot->open_at_end=GL_TRUE;
+       }
+       else
+               geom_s_knot->open_at_end=GL_FALSE;
+       geom_t_knot->unified_knot=NULL;
+       knot=geom_t_knot->knot=nobj->surface.geom.tknot;
+       nknots=geom_t_knot->nknots=nobj->surface.geom.tknot_count;
+       order=geom_t_knot->order=nobj->surface.geom.torder;
+       geom_t_knot->delta_nknots=0;
+       t_min=geom_t_knot->t_min=order-1;
+       t_max=geom_t_knot->t_max=nknots-order;
+       if(fabs(knot[t_min]-knot[t_max])<EPSILON)
+       {
+               call_user_error(nobj,GLU_NURBS_ERROR3);
+               return GLU_ERROR;
+       }
+       if(fabs(knot[0]-knot[t_min])<EPSILON)
+       {
+               /* knot open at beggining */
+               geom_t_knot->open_at_begin=GL_TRUE;
+       }
+       else
+               geom_t_knot->open_at_begin=GL_FALSE;
+       if(fabs(knot[t_max]-knot[nknots-1])<EPSILON)
+       {
+               /* knot open at end */
+               geom_t_knot->open_at_end=GL_TRUE;
+       }
+       else
+               geom_t_knot->open_at_end=GL_FALSE;
+
+       if(nobj->surface.color.type!=GLU_INVALID_ENUM)
+       {
+               color_s_knot->unified_knot=(GLfloat *)1;
+               knot=color_s_knot->knot=nobj->surface.color.sknot;
+               nknots=color_s_knot->nknots=nobj->surface.color.sknot_count;
+               order=color_s_knot->order=nobj->surface.color.sorder;
+               color_s_knot->delta_nknots=0;
+               t_min=color_s_knot->t_min=order-1;
+               t_max=color_s_knot->t_max=nknots-order;
+               if(fabs(knot[t_min]-knot[t_max])<EPSILON)
+               {
+                       call_user_error(nobj,GLU_NURBS_ERROR3);
+                       return GLU_ERROR;
+               }
+               if(fabs(knot[0]-knot[t_min])<EPSILON)
+               {
+                       /* knot open at beggining */
+                       color_s_knot->open_at_begin=GL_TRUE;
+               }
+               else
+                       color_s_knot->open_at_begin=GL_FALSE;
+               if(fabs(knot[t_max]-knot[nknots-1])<EPSILON)
+               {
+                       /* knot open at end */
+                       color_s_knot->open_at_end=GL_TRUE;
+               }
+               else
+                       color_s_knot->open_at_end=GL_FALSE;
+               color_t_knot->unified_knot=(GLfloat *)1;
+               knot=color_t_knot->knot=nobj->surface.color.tknot;
+               nknots=color_t_knot->nknots=nobj->surface.color.tknot_count;
+               order=color_t_knot->order=nobj->surface.color.torder;
+               color_t_knot->delta_nknots=0;
+               t_min=color_t_knot->t_min=order-1;
+               t_max=color_t_knot->t_max=nknots-order;
+               if(fabs(knot[t_min]-knot[t_max])<EPSILON)
+               {
+                       call_user_error(nobj,GLU_NURBS_ERROR3);
+                       return GLU_ERROR;
+               }
+               if(fabs(knot[0]-knot[t_min])<EPSILON)
+               {
+                       /* knot open at beggining */
+                       color_t_knot->open_at_begin=GL_TRUE;
+               }
+               else
+                       color_t_knot->open_at_begin=GL_FALSE;
+               if(fabs(knot[t_max]-knot[nknots-1])<EPSILON)
+               {
+                       /* knot open at end */
+                       color_t_knot->open_at_end=GL_TRUE;
+               }
+               else
+                       color_t_knot->open_at_end=GL_FALSE;
+       }
+       else
+       {
+               color_s_knot->unified_knot=NULL;
+               color_t_knot->unified_knot=NULL;
+       }
+
+       if(nobj->surface.normal.type!=GLU_INVALID_ENUM)
+       {
+               normal_s_knot->unified_knot=(GLfloat *)1;
+               knot=normal_s_knot->knot=nobj->surface.normal.sknot;
+               nknots=normal_s_knot->nknots=nobj->surface.normal.sknot_count;
+               order=normal_s_knot->order=nobj->surface.normal.sorder;
+               normal_s_knot->delta_nknots=0;
+               t_min=normal_s_knot->t_min=order-1;
+               t_max=normal_s_knot->t_max=nknots-order;
+               if(fabs(knot[t_min]-knot[t_max])<EPSILON)
+               {
+                       call_user_error(nobj,GLU_NURBS_ERROR3);
+                       return GLU_ERROR;
+               }
+               if(fabs(knot[0]-knot[t_min])<EPSILON)
+               {
+                       /* knot open at beggining */
+                       normal_s_knot->open_at_begin=GL_TRUE;
+               }
+               else
+                       normal_s_knot->open_at_begin=GL_FALSE;
+               if(fabs(knot[t_max]-knot[nknots-1])<EPSILON)
+               {
+                       /* knot open at end */
+                       normal_s_knot->open_at_end=GL_TRUE;
+               }
+               else
+                       normal_s_knot->open_at_end=GL_FALSE;
+               normal_t_knot->unified_knot=(GLfloat *)1;
+               knot=normal_t_knot->knot=nobj->surface.normal.tknot;
+               nknots=normal_t_knot->nknots=nobj->surface.normal.tknot_count;
+               order=normal_t_knot->order=nobj->surface.normal.torder;
+               normal_t_knot->delta_nknots=0;
+               t_min=normal_t_knot->t_min=order-1;
+               t_max=normal_t_knot->t_max=nknots-order;
+               if(fabs(knot[t_min]-knot[t_max])<EPSILON)
+               {
+                       call_user_error(nobj,GLU_NURBS_ERROR3);
+                       return GLU_ERROR;
+               }
+               if(fabs(knot[0]-knot[t_min])<EPSILON)
+               {
+                       /* knot open at beggining */
+                       normal_t_knot->open_at_begin=GL_TRUE;
+               }
+               else
+                       normal_t_knot->open_at_begin=GL_FALSE;
+               if(fabs(knot[t_max]-knot[nknots-1])<EPSILON)
+               {
+                       /* knot open at end */
+                       normal_t_knot->open_at_end=GL_TRUE;
+               }
+               else
+                       normal_t_knot->open_at_end=GL_FALSE;
+       }
+       else
+       {
+               normal_s_knot->unified_knot=NULL;
+               normal_t_knot->unified_knot=NULL;
+       }
+
+       if(nobj->surface.texture.type!=GLU_INVALID_ENUM)
+       {
+               texture_s_knot->unified_knot=(GLfloat *)1;
+               knot=texture_s_knot->knot=nobj->surface.texture.sknot;
+               nknots=texture_s_knot->nknots=nobj->surface.texture.sknot_count;
+               order=texture_s_knot->order=nobj->surface.texture.sorder;
+               texture_s_knot->delta_nknots=0;
+               t_min=texture_s_knot->t_min=order-1;
+               t_max=texture_s_knot->t_max=nknots-order;
+               if(fabs(knot[t_min]-knot[t_max])<EPSILON)
+               {
+                       call_user_error(nobj,GLU_NURBS_ERROR3);
+                       return GLU_ERROR;
+               }
+               if(fabs(knot[0]-knot[t_min])<EPSILON)
+               {
+                       /* knot open at beggining */
+                       texture_s_knot->open_at_begin=GL_TRUE;
+               }
+               else
+                       texture_s_knot->open_at_begin=GL_FALSE;
+               if(fabs(knot[t_max]-knot[nknots-1])<EPSILON)
+               {
+                       /* knot open at end */
+                       texture_s_knot->open_at_end=GL_TRUE;
+               }
+               else
+                       texture_s_knot->open_at_end=GL_FALSE;
+               texture_t_knot->unified_knot=(GLfloat *)1;
+               knot=texture_t_knot->knot=nobj->surface.texture.tknot;
+               nknots=texture_t_knot->nknots=nobj->surface.texture.tknot_count;
+               order=texture_t_knot->order=nobj->surface.texture.torder;
+               texture_t_knot->delta_nknots=0;
+               t_min=texture_t_knot->t_min=order-1;
+               t_max=texture_t_knot->t_max=nknots-order;
+               if(fabs(knot[t_min]-knot[t_max])<EPSILON)
+               {
+                       call_user_error(nobj,GLU_NURBS_ERROR3);
+                       return GLU_ERROR;
+               }
+               if(fabs(knot[0]-knot[t_min])<EPSILON)
+               {
+                       /* knot open at beggining */
+                       texture_t_knot->open_at_begin=GL_TRUE;
+               }
+               else
+                       texture_t_knot->open_at_begin=GL_FALSE;
+               if(fabs(knot[t_max]-knot[nknots-1])<EPSILON)
+               {
+                       /* knot open at end */
+                       texture_t_knot->open_at_end=GL_TRUE;
+               }
+               else
+                       texture_t_knot->open_at_end=GL_FALSE;
+       }
+       else
+       {
+               texture_s_knot->unified_knot=NULL;
+               texture_t_knot->unified_knot=NULL;
+       }
+       return GLU_NO_ERROR;
+}
+
+void
+free_new_ctrl(new_ctrl_type *p)
+{
+       if(p->geom_ctrl)
+               free(p->geom_ctrl);
+       if(p->geom_offsets)
+               free(p->geom_offsets);
+       if(p->color_ctrl)
+       {
+               free(p->color_ctrl);
+               if(p->color_offsets)
+                       free(p->color_offsets);
+       }
+       if(p->normal_ctrl)
+       {
+               free(p->normal_ctrl);
+               if(p->normal_offsets)
+                       free(p->normal_offsets);
+       }
+       if(p->texture_ctrl)
+       {
+               free(p->texture_ctrl);
+               if(p->texture_offsets)
+                       free(p->texture_offsets);
+       }
+}
+
+/* convert surfaces - geometry and possible attribute ones into equivalent */
+/* sequence of adjacent Bezier patches */
+static GLenum
+convert_surfs(GLUnurbsObj *nobj, new_ctrl_type *new_ctrl)
+{
+       knot_str_type   geom_s_knot,color_s_knot,normal_s_knot,texture_s_knot;
+       knot_str_type   geom_t_knot,color_t_knot,normal_t_knot,texture_t_knot;
+       GLenum                  err;
+
+       if((err=fill_knot_structures(nobj,&geom_s_knot,&geom_t_knot,
+               &color_s_knot,&color_t_knot,&normal_s_knot,&normal_t_knot,
+               &texture_s_knot,&texture_t_knot)) !=GLU_NO_ERROR)
+       {
+               return err;
+       }
+       /* unify knots - all knots should have the same working range */
+       if((err=select_knot_working_range(nobj,&geom_s_knot,&color_s_knot,
+               &normal_s_knot,&texture_s_knot)) !=GLU_NO_ERROR)
+       {
+               call_user_error(nobj,err);
+               return err;
+       }
+       if((err=select_knot_working_range(nobj,&geom_t_knot,&color_t_knot,
+               &normal_t_knot,&texture_t_knot)) !=GLU_NO_ERROR)
+       {
+               free_unified_knots(&geom_s_knot,&color_s_knot,&normal_s_knot,
+                       &texture_s_knot);
+               call_user_error(nobj,err);
+               return err;
+       }
+
+       /* convert the geometry surface */
+       nobj->surface.geom.dim=get_surface_dim(nobj->surface.geom.type);
+       if((err=convert_surf(&geom_s_knot,&geom_t_knot,&(nobj->surface.geom),
+               &(new_ctrl->geom_ctrl),&(new_ctrl->geom_s_pt_cnt),
+               &(new_ctrl->geom_t_pt_cnt)))!=GLU_NO_ERROR)
+       {
+               free_unified_knots(&geom_s_knot,&color_s_knot,&normal_s_knot,
+                       &texture_s_knot);
+               free_unified_knots(&geom_t_knot,&color_t_knot,&normal_t_knot,
+                       &texture_t_knot);
+               call_user_error(nobj,err);
+               return err;
+       }
+       /* if additional attributive surfaces are given convert them as well */
+       if(color_s_knot.unified_knot)
+       {
+               nobj->surface.color.dim=get_surface_dim(nobj->surface.color.type);
+               if((err=convert_surf(&color_s_knot,&color_t_knot,&(nobj->surface.color),
+                       &(new_ctrl->color_ctrl),&(new_ctrl->color_s_pt_cnt),
+                       &(new_ctrl->color_t_pt_cnt)))!=GLU_NO_ERROR)
+               {
+                       free_unified_knots(&color_s_knot,&color_s_knot,&normal_s_knot,
+                               &texture_s_knot);
+                       free_unified_knots(&color_t_knot,&color_t_knot,&normal_t_knot,
+                               &texture_t_knot);
+                       free_new_ctrl(new_ctrl);
+                       call_user_error(nobj,err);
+                       return err;
+               }
+       }
+       if(normal_s_knot.unified_knot)
+       {
+               nobj->surface.normal.dim=get_surface_dim(nobj->surface.normal.type);
+               if((err=convert_surf(&normal_s_knot,&normal_t_knot,
+                       &(nobj->surface.normal),
+                       &(new_ctrl->normal_ctrl),&(new_ctrl->normal_s_pt_cnt),
+                       &(new_ctrl->normal_t_pt_cnt)))!=GLU_NO_ERROR)
+               {
+                       free_unified_knots(&normal_s_knot,&normal_s_knot,&normal_s_knot,
+                               &texture_s_knot);
+                       free_unified_knots(&normal_t_knot,&normal_t_knot,&normal_t_knot,
+                               &texture_t_knot);
+                       free_new_ctrl(new_ctrl);
+                       call_user_error(nobj,err);
+                       return err;
+               }
+       }
+       if(texture_s_knot.unified_knot)
+       {
+               nobj->surface.texture.dim=get_surface_dim(nobj->surface.texture.type);
+               if((err=convert_surf(&texture_s_knot,&texture_t_knot,
+                       &(nobj->surface.texture),
+                       &(new_ctrl->texture_ctrl),&(new_ctrl->texture_s_pt_cnt),
+                       &(new_ctrl->texture_t_pt_cnt)))!=GLU_NO_ERROR)
+               {
+                       free_unified_knots(&texture_s_knot,&texture_s_knot,&texture_s_knot,
+                               &texture_s_knot);
+                       free_unified_knots(&texture_t_knot,&texture_t_knot,&texture_t_knot,
+                               &texture_t_knot);
+                       free_new_ctrl(new_ctrl);
+                       call_user_error(nobj,err);
+                       return err;
+               }
+       }
+       return GLU_NO_ERROR;
+}
+
+/* tesselate the "boundary" Bezier edge strips */
+void
+tesselate_strip_t_line(GLint top_start,GLint top_end,GLint top_z,
+       GLint bottom_start,GLint bottom_end,GLint bottom_z,GLint bottom_domain)
+{
+       GLint top_cnt,bottom_cnt,tri_cnt,k;
+       GLint direction;
+
+       top_cnt=top_end-top_start;
+       direction= (top_cnt>=0 ? 1: -1);
+       bottom_cnt=bottom_end-bottom_start;
+       glBegin(GL_LINES);
+       while(top_cnt)
+       {
+               if(bottom_cnt)
+                       tri_cnt=top_cnt/bottom_cnt;
+               else
+                       tri_cnt=abs(top_cnt);
+               for(k=0;k<=tri_cnt;k++ , top_start+=direction)
+               {
+                       glEvalCoord2f((GLfloat)bottom_z/bottom_domain,
+                               (GLfloat)bottom_start/bottom_domain);
+                       glEvalPoint2(top_z,top_start);
+               }
+               if(bottom_cnt)
+               {
+                       glEvalCoord2f((GLfloat)bottom_z/bottom_domain,
+                               (GLfloat)bottom_start/bottom_domain);
+                       bottom_start+=direction;
+                       top_start-=direction;
+                       glEvalCoord2f((GLfloat)bottom_z/bottom_domain,
+                               (GLfloat)bottom_start/bottom_domain);
+                       glEvalCoord2f((GLfloat)bottom_z/bottom_domain,
+                               (GLfloat)bottom_start/bottom_domain);
+                       glEvalPoint2(top_z,top_start);
+               }
+               top_cnt-=direction*tri_cnt;
+               bottom_cnt-=direction;
+       }
+       glEnd();
+}
+
+void
+tesselate_strip_t_fill(GLint top_start,GLint top_end,GLint top_z,
+       GLint bottom_start,GLint bottom_end,GLint bottom_z,GLint bottom_domain)
+{
+       GLint top_cnt,bottom_cnt,tri_cnt,k;
+       GLint direction;
+
+       top_cnt=top_end-top_start;
+       direction= (top_cnt>=0 ? 1: -1);
+       bottom_cnt=bottom_end-bottom_start;
+       while(top_cnt)
+       {
+               if(bottom_cnt)
+                       tri_cnt=top_cnt/bottom_cnt;
+               else
+                       tri_cnt=abs(top_cnt);
+               glBegin(GL_TRIANGLE_FAN);
+               glEvalCoord2f((GLfloat)bottom_z/bottom_domain,
+                       (GLfloat)bottom_start/bottom_domain);
+               for(k=0;k<=tri_cnt;k++ , top_start+=direction)
+                       glEvalPoint2(top_z,top_start);
+               if(bottom_cnt)
+               {
+                       bottom_start+=direction;
+                       top_start-=direction;
+                       glEvalCoord2f((GLfloat)bottom_z/bottom_domain,
+                               (GLfloat)bottom_start/bottom_domain);
+               }
+               glEnd();
+               top_cnt-=direction*tri_cnt;
+               bottom_cnt-=direction;
+       }
+}
+
+void
+tesselate_strip_t(GLenum display_mode, GLint top_start, GLint top_end, 
+       GLint top_z, GLint bottom_start, GLint bottom_end, GLint bottom_z, 
+       GLint bottom_domain)
+{
+       if(display_mode==GL_FILL)
+               tesselate_strip_t_fill(top_start,top_end,top_z,bottom_start,
+                       bottom_end,bottom_z,bottom_domain);
+       else
+               tesselate_strip_t_line(top_start,top_end,top_z,bottom_start,
+                       bottom_end,bottom_z,bottom_domain);
+}
+       
+
+void
+tesselate_strip_s_fill(GLint top_start, GLint top_end, GLint top_z,
+       GLint bottom_start, GLint bottom_end, GLint bottom_z, GLfloat bottom_domain)
+{
+       GLint top_cnt,bottom_cnt,tri_cnt,k;
+       GLint direction;
+
+       top_cnt=top_end-top_start;
+       direction= (top_cnt>=0 ? 1: -1);
+       bottom_cnt=bottom_end-bottom_start;
+       while(top_cnt)
+       {
+               if(bottom_cnt)
+                       tri_cnt=top_cnt/bottom_cnt;
+               else
+                       tri_cnt=abs(top_cnt);
+               glBegin(GL_TRIANGLE_FAN);
+               glEvalCoord2f((GLfloat)bottom_start/bottom_domain,
+                       (GLfloat)bottom_z/bottom_domain);
+               for(k=0;k<=tri_cnt;k++ , top_start+=direction)
+                       glEvalPoint2(top_start,top_z);
+               if(bottom_cnt)
+               {
+                       bottom_start+=direction;
+                       top_start-=direction;
+                       glEvalCoord2f((GLfloat)bottom_start/bottom_domain,
+                               (GLfloat)bottom_z/bottom_domain);
+               }
+               glEnd();
+               top_cnt-=direction*tri_cnt;
+               bottom_cnt-=direction;
+       }
+}
+
+void
+tesselate_strip_s_line(GLint top_start, GLint top_end, GLint top_z,
+       GLint bottom_start, GLint bottom_end, GLint bottom_z, GLfloat bottom_domain)
+{
+       GLint top_cnt,bottom_cnt,tri_cnt,k;
+       GLint direction;
+
+       top_cnt=top_end-top_start;
+       direction= (top_cnt>=0 ? 1: -1);
+       bottom_cnt=bottom_end-bottom_start;
+       glBegin(GL_LINES);
+       while(top_cnt)
+       {
+               if(bottom_cnt)
+                       tri_cnt=top_cnt/bottom_cnt;
+               else
+                       tri_cnt=abs(top_cnt);
+               for(k=0;k<=tri_cnt;k++ , top_start+=direction)
+               {
+                       glEvalCoord2f((GLfloat)bottom_start/bottom_domain,
+                               (GLfloat)bottom_z/bottom_domain);
+                       glEvalPoint2(top_start,top_z);
+               }
+               if(bottom_cnt)
+               {
+                       glEvalCoord2f((GLfloat)bottom_start/bottom_domain,
+                               (GLfloat)bottom_z/bottom_domain);
+                       bottom_start+=direction;
+                       top_start-=direction;
+                       glEvalCoord2f((GLfloat)bottom_start/bottom_domain,
+                               (GLfloat)bottom_z/bottom_domain);
+                       glEvalPoint2(top_start,top_z);
+                       glEvalCoord2f((GLfloat)bottom_start/bottom_domain,
+                               (GLfloat)bottom_z/bottom_domain);
+               }
+               top_cnt-=direction*tri_cnt;
+               bottom_cnt-=direction;
+       }
+       glEnd();
+}
+
+void
+tesselate_strip_s(GLenum display_mode, GLint top_start, GLint top_end,
+       GLint top_z, GLint bottom_start, GLint bottom_end, GLint bottom_z,
+       GLfloat bottom_domain)
+{
+       if(display_mode==GL_FILL)
+               tesselate_strip_s_fill(top_start,top_end,top_z,bottom_start,
+                       bottom_end,bottom_z,bottom_domain);
+       else
+               tesselate_strip_s_line(top_start,top_end,top_z,bottom_start,
+                       bottom_end,bottom_z,bottom_domain);
+}
+
+void
+tesselate_bottom_left_corner(GLenum display_mode, GLfloat s_1, GLfloat t_1)
+{
+       if(display_mode==GL_FILL)
+       {
+               glBegin(GL_TRIANGLE_FAN);
+               glEvalPoint2(1,1);
+               glEvalCoord2f(s_1,0.0);
+               glEvalCoord2f(0.0,0.0);
+               glEvalCoord2f(0.0,t_1);
+       }
+       else
+       {
+               glBegin(GL_LINES);
+               glEvalCoord2f(0.0,0.0);
+               glEvalCoord2f(0.0,t_1);
+               glEvalCoord2f(0.0,0.0);
+               glEvalPoint2(1,1);
+               glEvalCoord2f(0.0,0.0);
+               glEvalCoord2f(s_1,0.0);
+       }
+       glEnd();
+}
+
+void
+tesselate_bottom_right_corner(GLenum display_mode, GLint v_top,GLint v_bottom,
+       GLfloat s_1, GLfloat t_1)
+{
+       if(display_mode==GL_FILL)
+       {
+               glBegin(GL_TRIANGLE_FAN);
+               glEvalPoint2(1,v_top);
+               glEvalCoord2f(0.0,v_bottom*t_1);
+               glEvalCoord2f(0.0,(v_bottom+1)*t_1);
+               glEvalCoord2f(s_1,(v_bottom+1)*t_1);
+       }
+       else
+       {
+               glBegin(GL_LINES);
+               glEvalCoord2f(0.0,(v_bottom+1)*t_1);
+               glEvalPoint2(1,v_top);
+               glEvalCoord2f(0.0,(v_bottom+1)*t_1);
+               glEvalCoord2f(0.0,v_bottom*t_1);
+               glEvalCoord2f(0.0,(v_bottom+1)*t_1);
+               glEvalCoord2f(s_1,(v_bottom+1)*t_1);
+       }
+       glEnd();
+}
+
+void
+tesselate_top_left_corner(GLenum display_mode, GLint u_right, GLint u_left,
+       GLfloat s_1, GLfloat t_1)
+{
+       if(display_mode==GL_FILL)
+       {
+               glBegin(GL_TRIANGLE_FAN);
+               glEvalPoint2(u_right,1);
+               glEvalCoord2f((u_left+1)*s_1,t_1);
+               glEvalCoord2f((u_left+1)*s_1,0.0);
+               glEvalCoord2f(u_left*s_1,0.0);
+       }
+       else
+       {
+               glBegin(GL_LINES);
+               glEvalCoord2f((u_left+1)*s_1,0.0);
+               glEvalPoint2(u_right,1);
+               glEvalCoord2f((u_left+1)*s_1,0.0);
+               glEvalCoord2f(u_left*s_1,0.0);
+               glEvalCoord2f((u_left+1)*s_1,0.0);
+               glEvalCoord2f((u_left+1)*s_1,t_1);
+       }
+       glEnd();
+}
+
+void
+tesselate_top_right_corner(GLenum display_mode, GLint u_left, GLint v_bottom,
+       GLint u_right, GLint v_top, GLfloat s_1, GLfloat t_1)
+{
+       if(display_mode==GL_FILL)
+       {
+               glBegin(GL_TRIANGLE_FAN);
+               glEvalPoint2(u_left,v_bottom);
+               glEvalCoord2f((u_right-1)*s_1,v_top*t_1);
+               glEvalCoord2f(u_right*s_1,v_top*t_1);
+               glEvalCoord2f(u_right*s_1,(v_top-1)*t_1);
+       }
+       else
+       {
+               glBegin(GL_LINES);
+               glEvalCoord2f(u_right*s_1,v_top*t_1);
+               glEvalPoint2(u_left,v_bottom);
+               glEvalCoord2f(u_right*s_1,v_top*t_1);
+               glEvalCoord2f(u_right*s_1,(v_top-1)*t_1);
+               glEvalCoord2f(u_right*s_1,v_top*t_1);
+               glEvalCoord2f((u_right-1)*s_1,v_top*t_1);
+       }
+       glEnd();
+}
+
+/* do mesh mapping of Bezier */
+static void
+nurbs_map_bezier(GLenum display_mode,GLint *sfactors,GLint *tfactors,
+       GLint s_bezier_cnt, GLint t_bezier_cnt, GLint s, GLint t)
+{
+       GLint           top,bottom,right,left;
+
+
+       if(s==0)
+       {
+               top=*(tfactors+t*3);
+               bottom=*(tfactors+t*3+1);
+       }
+       else
+       if(s==s_bezier_cnt-1)
+       {
+               top=*(tfactors+t*3+2);
+               bottom=*(tfactors+t*3);
+       }
+       else
+       {
+               top=bottom=*(tfactors+t*3);
+       }
+       if(t==0)
+       {
+               left=*(sfactors+s*3+1);
+               right=*(sfactors+s*3);
+       }
+       else
+       if(t==t_bezier_cnt-1)
+       {
+               left=*(sfactors+s*3);
+               right=*(sfactors+s*3+2);
+       }
+       else
+       {
+               left=right=*(sfactors+s*3);
+       }
+
+       if(top>bottom)
+       {
+               if(left<right)
+               {
+                       glMapGrid2f(right, 0.0, 1.0, top, 0.0, 1.0);
+                       glEvalMesh2(display_mode,1,right, 1, top);
+                       tesselate_strip_s(display_mode,1,right,1,1,left,0,(GLfloat)left);
+                       tesselate_bottom_left_corner(display_mode,(GLfloat)(1.0/left),
+                               (GLfloat)(1.0/bottom));
+/*                     tesselate_strip_t(display_mode,1,top,1,1,bottom,0,(GLfloat)bottom);*/
+                       tesselate_strip_t(display_mode,top,1,1,bottom,1,0,(GLfloat)bottom);
+               }
+               else
+               if(left==right)
+               {
+                       glMapGrid2f(right, 0.0, 1.0, top, 0.0, 1.0);
+                       glEvalMesh2(display_mode,1,right, 0, top);
+/*                     tesselate_strip_t(display_mode,0,top,1,0,bottom,0,(GLfloat)bottom);*/
+                       tesselate_strip_t(display_mode,top,0,1,bottom,0,0,(GLfloat)bottom);
+               }
+               else
+               {
+                       glMapGrid2f(left, 0.0, 1.0, top, 0.0, 1.0);
+                       glEvalMesh2(display_mode,1,left, 0, top-1);
+/*                     tesselate_strip_t(display_mode,0,top-1,1,0,bottom-1,0,
+                               (GLfloat)bottom);*/
+                       tesselate_strip_t(display_mode,top-1,0,1,bottom-1,0,0,
+                               (GLfloat)bottom);
+                       tesselate_bottom_right_corner(display_mode,top-1,bottom-1,
+                               (GLfloat)(1.0/right),(GLfloat)(1.0/bottom));
+/*                     tesselate_strip_s(display_mode,1,left,top-1,1,right,right,
+                               (GLfloat)right);*/
+                       tesselate_strip_s(display_mode,left,1,top-1,right,1,right,
+                               (GLfloat)right);
+               }
+       }
+       else
+       if(top==bottom)
+       {
+               if(left<right)
+               {
+                       glMapGrid2f(right, 0.0, 1.0, top, 0.0, 1.0);
+                       glEvalMesh2(display_mode,0,right, 1, top);
+                       tesselate_strip_s(display_mode,0,right,1,0,left,0,(GLfloat)left);
+               }
+               else
+               if(left==right)
+               {
+                       glMapGrid2f(right, 0.0, 1.0, top, 0.0, 1.0);
+                       glEvalMesh2(display_mode,0,right, 0, top);
+               }
+               else
+               {
+                       glMapGrid2f(left, 0.0, 1.0, top, 0.0, 1.0);
+                       glEvalMesh2(display_mode,0,left, 0, top-1);
+/*                     tesselate_strip_s(display_mode,0,left,top-1,0,right,right,
+                               (GLfloat)right);*/
+                       tesselate_strip_s(display_mode,left,0,top-1,right,0,right,
+                               (GLfloat)right);
+               }
+       }
+       else
+       {
+               if(left<right)
+               {
+                       glMapGrid2f(right, 0.0, 1.0, bottom, 0.0, 1.0);
+                       glEvalMesh2(display_mode,0,right-1, 1, bottom);
+                       tesselate_strip_s(display_mode,0,right-1,1,0,left-1,0,
+                               (GLfloat)left);
+                       tesselate_top_left_corner(display_mode,right-1,left-1,
+                               (GLfloat)(1.0/left),(GLfloat)(1.0/top));
+                       tesselate_strip_t(display_mode,1,bottom,right-1,1,top,top,
+                               (GLfloat)top);
+               }
+               else
+               if(left==right)
+               {
+                       glMapGrid2f(right, 0.0, 1.0, bottom, 0.0, 1.0);
+                       glEvalMesh2(display_mode,0,right-1, 0, bottom);
+                       tesselate_strip_t(display_mode,0,bottom,right-1,0,top,top,
+                               (GLfloat)top);
+               }
+               else
+               {
+                       glMapGrid2f(left, 0.0, 1.0, bottom, 0.0, 1.0);
+                       glEvalMesh2(display_mode,0,left-1, 0, bottom-1);
+                       tesselate_strip_t(display_mode,0,bottom-1,left-1,0,top-1,top,
+                               (GLfloat)top);
+                       tesselate_top_right_corner(display_mode,left-1,bottom-1,right,top,
+                               (GLfloat)(1.0/right),(GLfloat)(1.0/top));
+/*                     tesselate_strip_s(display_mode,0,left-1,bottom-1,0,right-1,right,
+                               (GLfloat)right);*/
+                       tesselate_strip_s(display_mode,left-1,0,bottom-1,right-1,0,right,
+                               (GLfloat)right);
+               }
+       }
+}
+
+/* draw NURBS surface in OUTLINE POLYGON mode */
+static void
+draw_polygon_mode( GLenum display_mode, GLUnurbsObj *nobj,
+       new_ctrl_type *new_ctrl, GLint *sfactors, GLint *tfactors )
+{
+       GLsizei                         offset;
+       GLint                           t_bezier_cnt,s_bezier_cnt;
+       GLboolean                       do_color,do_normal,do_texture;
+       GLint                           i,j;
+
+       t_bezier_cnt=new_ctrl->t_bezier_cnt;
+       s_bezier_cnt=new_ctrl->s_bezier_cnt;
+       glEnable(nobj->surface.geom.type);
+       if(new_ctrl->color_ctrl)
+       {
+               glEnable(nobj->surface.color.type);
+               do_color=GL_TRUE;
+       }
+       else
+               do_color=GL_FALSE;
+       if(new_ctrl->normal_ctrl)
+       {
+               glEnable(nobj->surface.normal.type);
+               do_normal=GL_TRUE;
+       }
+       else
+               do_normal=GL_FALSE;
+       if(new_ctrl->texture_ctrl)
+       {
+               glEnable(nobj->surface.texture.type);
+               do_texture=GL_TRUE;
+       }
+       else
+               do_texture=GL_FALSE;
+       for(j=0; j<s_bezier_cnt; j++)
+       {
+               for(i=0; i<t_bezier_cnt; i++)
+               {
+                       offset=j*t_bezier_cnt + i;
+                       if(fine_culling_test_3D(nobj,*(new_ctrl->geom_offsets + offset),
+                                       nobj->surface.geom.sorder,nobj->surface.geom.torder,
+                                       new_ctrl->geom_s_stride,new_ctrl->geom_t_stride,
+                                       nobj->surface.geom.dim))
+                               continue;
+                       glMap2f(nobj->surface.geom.type,0.0,1.0,new_ctrl->geom_s_stride,
+                               nobj->surface.geom.sorder,0.0,1.0,new_ctrl->geom_t_stride,
+                               nobj->surface.geom.torder,*(new_ctrl->geom_offsets + offset));
+                       if(do_color)
+                       {
+                               glMap2f(nobj->surface.color.type,0.0,1.0,
+                                       new_ctrl->color_s_stride,nobj->surface.color.sorder,
+                                       0.0,1.0,new_ctrl->color_t_stride,nobj->surface.color.torder,
+                                       *(new_ctrl->color_offsets + offset));
+                       }
+                       if(do_normal)
+                       {
+                               glMap2f(nobj->surface.normal.type,0.0,1.0,
+                                       new_ctrl->normal_s_stride,nobj->surface.normal.sorder,
+                                       0.0,1.0,new_ctrl->normal_t_stride,
+                                       nobj->surface.normal.torder,
+                                       *(new_ctrl->normal_offsets+offset));
+                       }
+                       if(do_texture)
+                       {
+                               glMap2f(nobj->surface.texture.type,0.0,1.0,
+                                       new_ctrl->texture_s_stride,nobj->surface.texture.sorder,
+                                       0.0,1.0,new_ctrl->texture_t_stride,
+                                       nobj->surface.texture.torder,
+                                       *(new_ctrl->texture_offsets+offset));
+                       }
+/*                     glMapGrid2f(sfactors[j*3+0],0.0,1.0,tfactors[i*3+0],0.0,1.0);
+                       glEvalMesh2(display_mode,0,sfactors[j*3+0],0,tfactors[i*3+0]);*/
+                       nurbs_map_bezier(display_mode,sfactors,tfactors,s_bezier_cnt,
+                               t_bezier_cnt,j,i);
+               }
+       }
+}
+
+
+
+/* draw NURBS surface in OUTLINE POLYGON mode */
+#if 0
+static void
+draw_patch_mode( GLenum display_mode, GLUnurbsObj *nobj,
+       new_ctrl_type *new_ctrl, GLint *sfactors, GLint *tfactors )
+{
+       GLsizei                         offset;
+       GLint                           t_bezier_cnt,s_bezier_cnt;
+       GLboolean                       do_color,do_normal,do_texture;
+       GLint                           i,j;
+
+       t_bezier_cnt=new_ctrl->t_bezier_cnt;
+       s_bezier_cnt=new_ctrl->s_bezier_cnt;
+       glEnable(nobj->surface.geom.type);
+       if(new_ctrl->color_ctrl)
+       {
+               glEnable(nobj->surface.color.type);
+               do_color=GL_TRUE;
+       }
+       else
+               do_color=GL_FALSE;
+       if(new_ctrl->normal_ctrl)
+       {
+               glEnable(nobj->surface.normal.type);
+               do_normal=GL_TRUE;
+       }
+       else
+               do_normal=GL_FALSE;
+       if(new_ctrl->texture_ctrl)
+       {
+               glEnable(nobj->surface.texture.type);
+               do_texture=GL_TRUE;
+       }
+       else
+               do_texture=GL_FALSE;
+       for(j=0; j<s_bezier_cnt; j++)
+       {
+               for(i=0; i<t_bezier_cnt; i++)
+               {
+                       offset=j*t_bezier_cnt + i;
+                       if(fine_culling_test_3D(nobj,*(new_ctrl->geom_offsets + offset),
+                                       nobj->surface.geom.sorder,nobj->surface.geom.torder,
+                                       new_ctrl->geom_s_stride,new_ctrl->geom_t_stride,
+                                       nobj->surface.geom.dim))
+                               continue;
+                       glMap2f(nobj->surface.geom.type,0.0,1.0,new_ctrl->geom_s_stride,
+                               nobj->surface.geom.sorder,0.0,1.0,new_ctrl->geom_t_stride,
+                               nobj->surface.geom.torder,*(new_ctrl->geom_offsets + offset));
+                       if(do_color)
+                       {
+                               glMap2f(nobj->surface.color.type,0.0,1.0,
+                                       new_ctrl->color_s_stride,nobj->surface.color.sorder,
+                                       0.0,1.0,new_ctrl->color_t_stride,nobj->surface.color.torder,
+                                       *(new_ctrl->color_offsets + offset));
+                       }
+                       if(do_normal)
+                       {
+                               glMap2f(nobj->surface.normal.type,0.0,1.0,
+                                       new_ctrl->normal_s_stride,nobj->surface.normal.sorder,
+                                       0.0,1.0,new_ctrl->normal_t_stride,
+                                       nobj->surface.normal.torder,
+                                       *(new_ctrl->normal_offsets+offset));
+                       }
+                       if(do_texture)
+                       {
+                               glMap2f(nobj->surface.texture.type,0.0,1.0,
+                                       new_ctrl->texture_s_stride,nobj->surface.texture.sorder,
+                                       0.0,1.0,new_ctrl->texture_t_stride,
+                                       nobj->surface.texture.torder,
+                                       *(new_ctrl->texture_offsets+offset));
+                       }
+                       nurbs_map_bezier(display_mode,sfactors,tfactors,s_bezier_cnt,
+                               t_bezier_cnt,i,j);
+/*                     glMapGrid2f(sfactors[j],0.0,1.0,tfactors[i],0.0,1.0);
+                       glEvalMesh2(display_mode,0,sfactors[j],0,tfactors[i]);*/
+               }
+       }
+}
+#endif
+
+
+
+void
+init_new_ctrl(new_ctrl_type *p)
+{
+       p->geom_ctrl=p->color_ctrl=p->normal_ctrl=p->texture_ctrl=NULL;
+       p->geom_offsets=p->color_offsets=p->normal_offsets=p->texture_offsets=NULL;
+       p->s_bezier_cnt=p->t_bezier_cnt=0;
+}
+
+GLenum
+augment_new_ctrl(GLUnurbsObj *nobj, new_ctrl_type *p)
+{
+       GLsizei offset_size;
+       GLint   i,j;
+
+       p->s_bezier_cnt=(p->geom_s_pt_cnt)/(nobj->surface.geom.sorder);
+       p->t_bezier_cnt=(p->geom_t_pt_cnt)/(nobj->surface.geom.torder);
+       offset_size=(p->s_bezier_cnt)*(p->t_bezier_cnt);
+       p->geom_t_stride=nobj->surface.geom.dim;
+       p->geom_s_stride=(p->geom_t_pt_cnt)*(nobj->surface.geom.dim);
+       p->color_t_stride=nobj->surface.color.dim;
+       p->color_s_stride=(p->color_t_pt_cnt)*(nobj->surface.color.dim);
+       p->normal_t_stride=nobj->surface.normal.dim;
+       p->normal_s_stride=(p->normal_t_pt_cnt)*(nobj->surface.normal.dim);
+       p->texture_t_stride=nobj->surface.texture.dim;
+       p->texture_s_stride=(p->texture_t_pt_cnt)*(nobj->surface.texture.dim);
+       if((p->geom_offsets=(GLfloat **)malloc(sizeof(GLfloat *)*offset_size))==NULL)
+       {
+               call_user_error(nobj,GLU_OUT_OF_MEMORY);
+               return GLU_ERROR;
+       }
+       if(p->color_ctrl)
+               if((p->color_offsets=(GLfloat **)malloc(sizeof(GLfloat *)*offset_size))==NULL)
+               {
+                       free_new_ctrl(p);
+                       call_user_error(nobj,GLU_OUT_OF_MEMORY);
+                       return GLU_ERROR;
+               }
+       if(p->normal_ctrl)
+               if((p->normal_offsets=(GLfloat **)malloc(sizeof(GLfloat *)*offset_size))==NULL)
+               {
+                       free_new_ctrl(p);
+                       call_user_error(nobj,GLU_OUT_OF_MEMORY);
+                       return GLU_ERROR;
+               }
+       if(p->texture_ctrl)
+               if((p->texture_offsets=(GLfloat **)malloc(sizeof(GLfloat *)*offset_size))==NULL)
+               {
+                       free_new_ctrl(p);
+                       call_user_error(nobj,GLU_OUT_OF_MEMORY);
+                       return GLU_ERROR;
+               }
+       for(i=0;i<p->s_bezier_cnt;i++)
+               for(j=0;j<p->t_bezier_cnt;j++)
+                       *(p->geom_offsets + i*(p->t_bezier_cnt) + j) =
+                               p->geom_ctrl + i*(nobj->surface.geom.sorder)*
+                               (nobj->surface.geom.dim)*(p->geom_t_pt_cnt) +
+                               j*(nobj->surface.geom.dim)*(nobj->surface.geom.torder);
+       if(p->color_ctrl)
+               for(i=0;i<p->s_bezier_cnt;i++)
+                       for(j=0;j<p->t_bezier_cnt;j++)
+                               *(p->color_offsets + i*(p->t_bezier_cnt) + j) =
+                                       p->color_ctrl + i*(nobj->surface.color.sorder)*
+                                       (nobj->surface.color.dim)*(p->color_t_pt_cnt) +
+                                       j*(nobj->surface.color.dim)*(nobj->surface.color.torder);
+       if(p->normal_ctrl)
+               for(i=0;i<p->s_bezier_cnt;i++)
+                       for(j=0;j<p->t_bezier_cnt;j++)
+                               *(p->normal_offsets + i*(p->t_bezier_cnt) + j) =
+                                       p->normal_ctrl + i*(nobj->surface.normal.sorder)*
+                                       (nobj->surface.normal.dim)*(p->normal_t_pt_cnt) +
+                                       j*(nobj->surface.normal.dim)*(nobj->surface.normal.torder);
+       if(p->texture_ctrl)
+               for(i=0;i<p->s_bezier_cnt;i++)
+                       for(j=0;j<p->t_bezier_cnt;j++)
+                               *(p->texture_offsets + i*(p->t_bezier_cnt) + j) =
+                                       p->texture_ctrl + i*(nobj->surface.texture.sorder)*
+                                       (nobj->surface.texture.dim)*(p->texture_t_pt_cnt) +
+                                       j*(nobj->surface.texture.dim)*(nobj->surface.texture.torder);
+       return GLU_NO_ERROR;
+}
+
+/* main NURBS surface procedure */
+void
+do_nurbs_surface( GLUnurbsObj *nobj )
+{
+       GLint                   *sfactors,*tfactors;
+       new_ctrl_type   new_ctrl;
+
+       /* test user supplied data */
+       if(test_nurbs_surfaces(nobj)!=GLU_NO_ERROR)
+               return;
+
+       init_new_ctrl(&new_ctrl);
+
+       if(convert_surfs(nobj,&new_ctrl)!=GLU_NO_ERROR)
+               return;
+       if(augment_new_ctrl(nobj,&new_ctrl)!=GLU_NO_ERROR)
+               return;
+       switch(nobj->sampling_method)
+       {
+               case GLU_PATH_LENGTH:
+                       if(glu_do_sampling_3D(nobj,&new_ctrl,&sfactors,&tfactors)!=
+                               GLU_NO_ERROR)
+                       {
+                               free_new_ctrl(&new_ctrl);
+                               return;
+                       }
+                       break;
+               case GLU_DOMAIN_DISTANCE:
+                       if(glu_do_sampling_uv(nobj,&new_ctrl,&sfactors,&tfactors)!=
+                               GLU_NO_ERROR)
+                       {
+                               free_new_ctrl(&new_ctrl);
+                               return;
+                       }
+                       break;
+               case GLU_PARAMETRIC_ERROR:
+                       if(glu_do_sampling_param_3D(nobj,&new_ctrl,&sfactors,&tfactors)!=
+                               GLU_NO_ERROR)
+                       {
+                               free_new_ctrl(&new_ctrl);
+                               return;
+                       }
+                       break;
+               default:
+                       abort();
+       }
+       glFrontFace(GL_CW);
+       switch(nobj->display_mode)
+       {
+               case GLU_FILL:
+/*                     if(polygon_trimming(nobj,&new_ctrl,sfactors,tfactors)==GLU_NO_ERROR)*/
+                               draw_polygon_mode(GL_FILL,nobj,&new_ctrl,sfactors,tfactors);
+                       break;
+               case GLU_OUTLINE_POLYGON:
+                       /* TODO - missing trimming handeling */
+/* just for now - no OUTLINE_PATCH mode 
+                       draw_patch_mode(GL_LINE,nobj,&new_ctrl,sfactors,tfactors);
+                       break; */
+               case GLU_OUTLINE_PATCH:
+/*                     if(polygon_trimming(nobj,&new_ctrl,sfactors,tfactors)==GLU_NO_ERROR)*/
+                               draw_polygon_mode(GL_LINE,nobj,&new_ctrl,sfactors,tfactors);
+                       break;
+               default:
+                       abort();  /* TODO: is this OK? */
+       }
+       free(sfactors);
+       free(tfactors);
+       free_new_ctrl(&new_ctrl);
+}
+
diff --git a/src/glu/mesa/nurbsutl.c b/src/glu/mesa/nurbsutl.c
new file mode 100644 (file)
index 0000000..f0f166c
--- /dev/null
@@ -0,0 +1,1403 @@
+/* $Id: nurbsutl.c,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  2.4
+ * Copyright (C) 1995-1997  Brian Paul
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/*
+ * $Log: nurbsutl.c,v $
+ * Revision 1.1  1999/08/19 00:55:42  jtg
+ * Initial revision
+ *
+ * Revision 1.8  1999/06/08 00:44:51  brianp
+ * OpenStep updates (pete@ohm.york.ac.uk)
+ *
+ * Revision 1.7  1998/07/26 02:07:59  brianp
+ * updated for Windows compilation per Ted Jump
+ *
+ * Revision 1.6  1997/10/29 02:02:20  brianp
+ * various MS Windows compiler changes (David Bucciarelli, v20 3dfx driver)
+ *
+ * Revision 1.5  1997/07/24 01:28:44  brianp
+ * changed precompiled header symbol from PCH to PC_HEADER
+ *
+ * Revision 1.4  1997/05/28 02:29:38  brianp
+ * added support for precompiled headers (PCH), inserted APIENTRY keyword
+ *
+ * Revision 1.3  1997/05/27 03:19:54  brianp
+ * minor clean-up
+ *
+ * Revision 1.2  1997/05/27 03:00:16  brianp
+ * incorporated Bogdan's new NURBS code
+ *
+ * Revision 1.1  1996/09/27 01:19:39  brianp
+ * Initial revision
+ *
+ */
+
+
+/*
+ * NURBS implementation written by Bogdan Sikorski (bogdan@cira.it)
+ * See README2 for more info.
+ */
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <math.h>
+#include <stdlib.h>
+#include "gluP.h"
+#include "nurbs.h"
+#endif
+
+
+GLenum
+test_knot(GLint nknots, GLfloat *knot, GLint order)
+{
+       GLsizei i;
+       GLint knot_mult;
+       GLfloat tmp_knot;
+
+       tmp_knot=knot[0];
+       knot_mult=1;
+       for(i=1;i<nknots;i++)
+       {
+               if(knot[i] < tmp_knot)
+                       return GLU_NURBS_ERROR4;
+               if(fabs(tmp_knot-knot[i]) > EPSILON)
+               {
+                       if(knot_mult>order)
+                               return GLU_NURBS_ERROR5;
+                       knot_mult=1;
+                       tmp_knot=knot[i];
+               }
+               else
+                       ++knot_mult;
+       }
+       return GLU_NO_ERROR;
+}
+
+static int
+/* qsort function */
+#if defined(WIN32) && !defined(OPENSTEP)
+__cdecl
+#endif
+knot_sort(const void *a, const void *b)
+{
+       GLfloat x,y;
+
+       x=*((GLfloat *)a);
+       y=*((GLfloat *)b);
+       if(fabs(x-y) < EPSILON)
+               return 0;
+       if(x > y)
+               return 1;
+       return -1;
+}
+
+/* insert into dest knot all values within the valid range from src knot */
+/* that do not appear in dest */
+void
+collect_unified_knot(knot_str_type *dest, knot_str_type *src,
+       GLfloat maximal_min_knot, GLfloat minimal_max_knot)
+{
+       GLfloat *src_knot,*dest_knot;
+       GLint src_t_min,src_t_max,dest_t_min,dest_t_max;
+       GLint src_nknots,dest_nknots;
+       GLint i,j,k,new_cnt;
+       GLboolean       not_found_flag;
+
+       src_knot=src->unified_knot;
+       dest_knot=dest->unified_knot;
+       src_t_min=src->t_min;
+       src_t_max=src->t_max;
+       dest_t_min=dest->t_min;
+       dest_t_max=dest->t_max;
+       src_nknots=src->unified_nknots;
+       dest_nknots=dest->unified_nknots;
+
+       k=new_cnt=dest_nknots;
+       for(i=src_t_min;i<=src_t_max;i++)
+               if(src_knot[i] - maximal_min_knot > -EPSILON &&
+               src_knot[i] - minimal_max_knot < EPSILON)
+       {
+               not_found_flag=GL_TRUE;
+               for(j=dest_t_min;j<=dest_t_max;j++)
+                       if(fabs(dest_knot[j]-src_knot[i]) < EPSILON)
+                       {
+                               not_found_flag=GL_FALSE;
+                               break;
+                       }
+               if(not_found_flag)
+               {
+                       /* knot from src is not in dest - add this knot to dest */
+                       dest_knot[k++]=src_knot[i];
+                       ++new_cnt;
+                       ++(dest->t_max); /* the valid range widens */
+                       ++(dest->delta_nknots); /* increment the extra knot value counter */
+               }
+       }
+       dest->unified_nknots=new_cnt;
+       qsort((void *)dest_knot,(size_t)new_cnt,(size_t)sizeof(GLfloat),
+               &knot_sort);
+}
+
+/* basing on the new common knot range for all attributes set */
+/* t_min and t_max values for each knot - they will be used later on */
+/* by explode_knot() and calc_new_ctrl_pts */
+static void
+set_new_t_min_t_max(knot_str_type *geom_knot, knot_str_type *color_knot,
+       knot_str_type *normal_knot, knot_str_type *texture_knot,
+       GLfloat maximal_min_knot, GLfloat minimal_max_knot)
+{
+       GLuint  t_min,t_max,cnt;
+
+       if(minimal_max_knot-maximal_min_knot < EPSILON)
+       {
+               /* knot common range empty */
+               geom_knot->t_min=geom_knot->t_max=0;
+               color_knot->t_min=color_knot->t_max=0;
+               normal_knot->t_min=normal_knot->t_max=0;
+               texture_knot->t_min=texture_knot->t_max=0;
+       }
+       else
+       {
+               if(geom_knot->unified_knot!=NULL)
+               {
+                       cnt=geom_knot->unified_nknots;
+                       for(t_min=0;t_min<cnt;t_min++)
+                               if(fabs((geom_knot->unified_knot)[t_min] - maximal_min_knot) <
+                                               EPSILON)
+                                       break;
+                       for(t_max=cnt-1;t_max;t_max--)
+                               if(fabs((geom_knot->unified_knot)[t_max] - minimal_max_knot) < 
+                                               EPSILON)
+                                       break;
+               }
+               else
+               if(geom_knot->nknots)
+               {
+                       cnt=geom_knot->nknots;
+                       for(t_min=0;t_min<cnt;t_min++)
+                               if(fabs((geom_knot->knot)[t_min] - maximal_min_knot) < EPSILON)
+                                       break;
+                       for(t_max=cnt-1;t_max;t_max--)
+                               if(fabs((geom_knot->knot)[t_max] - minimal_max_knot) < EPSILON)
+                                       break;
+               }
+               geom_knot->t_min=t_min;
+               geom_knot->t_max=t_max;
+               if(color_knot->unified_knot!=NULL)
+               {
+                       cnt=color_knot->unified_nknots;
+                       for(t_min=0;t_min<cnt;t_min++)
+                               if(fabs((color_knot->unified_knot)[t_min] - maximal_min_knot) <
+                                               EPSILON)
+                                       break;
+                       for(t_max=cnt-1;t_max;t_max--)
+                               if(fabs((color_knot->unified_knot)[t_max] - minimal_max_knot) < 
+                                               EPSILON)
+                                       break;
+                       color_knot->t_min=t_min;
+                       color_knot->t_max=t_max;
+               }
+               if(normal_knot->unified_knot!=NULL)
+               {
+                       cnt=normal_knot->unified_nknots;
+                       for(t_min=0;t_min<cnt;t_min++)
+                               if(fabs((normal_knot->unified_knot)[t_min] - maximal_min_knot) <
+                                               EPSILON)
+                                       break;
+                       for(t_max=cnt-1;t_max;t_max--)
+                               if(fabs((normal_knot->unified_knot)[t_max] - minimal_max_knot) < 
+                                               EPSILON)
+                                       break;
+                       normal_knot->t_min=t_min;
+                       normal_knot->t_max=t_max;
+               }
+               if(texture_knot->unified_knot!=NULL)
+               {
+                       cnt=texture_knot->unified_nknots;
+                       for(t_min=0;t_min<cnt;t_min++)
+                               if(fabs((texture_knot->unified_knot)[t_min] - maximal_min_knot) 
+                                               < EPSILON)
+                                       break;
+                       for(t_max=cnt-1;t_max;t_max--)
+                               if(fabs((texture_knot->unified_knot)[t_max] - minimal_max_knot) 
+                                               < EPSILON)
+                                       break;
+                       texture_knot->t_min=t_min;
+                       texture_knot->t_max=t_max;
+               }
+       }
+}
+
+/* modify all knot valid ranges in such a way that all have the same */
+/* range, common to all knots */
+/* do this by knot insertion */
+GLenum
+select_knot_working_range(GLUnurbsObj *nobj,knot_str_type *geom_knot,
+       knot_str_type *color_knot, knot_str_type *normal_knot,
+       knot_str_type *texture_knot)
+{
+       GLint max_nknots;
+       GLfloat maximal_min_knot,minimal_max_knot;
+       GLint i;
+
+       /* find the maximum modified knot length */
+       max_nknots=geom_knot->nknots;
+       if(color_knot->unified_knot)
+               max_nknots+=color_knot->nknots;
+       if(normal_knot->unified_knot)
+               max_nknots+=normal_knot->nknots;
+       if(texture_knot->unified_knot)
+               max_nknots+=texture_knot->nknots;
+       maximal_min_knot=(geom_knot->knot)[geom_knot->t_min];
+       minimal_max_knot=(geom_knot->knot)[geom_knot->t_max];
+       /* any attirb data ? */
+       if(max_nknots!=geom_knot->nknots)
+       {
+               /* allocate space for the unified knots */
+               if((geom_knot->unified_knot=
+                               (GLfloat *)malloc(sizeof(GLfloat)*max_nknots))==NULL)
+               {
+                       call_user_error(nobj,GLU_OUT_OF_MEMORY);
+                       return GLU_ERROR;
+               }
+               /* copy the original knot to the unified one */
+               geom_knot->unified_nknots=geom_knot->nknots;
+               for(i=0;i<geom_knot->nknots;i++)
+                       (geom_knot->unified_knot)[i]=(geom_knot->knot)[i];
+               if(color_knot->unified_knot)
+               {
+                       if((color_knot->knot)[color_knot->t_min] - maximal_min_knot >
+                                       EPSILON)
+                               maximal_min_knot=(color_knot->knot)[color_knot->t_min];
+                       if(minimal_max_knot - (color_knot->knot)[color_knot->t_max] >
+                                       EPSILON)
+                               minimal_max_knot=(color_knot->knot)[color_knot->t_max];
+                       if((color_knot->unified_knot=
+                                       (GLfloat *)malloc(sizeof(GLfloat)*max_nknots))==NULL)
+                       {
+                               free(geom_knot->unified_knot);
+                               call_user_error(nobj,GLU_OUT_OF_MEMORY);
+                               return GLU_ERROR;
+                       }
+                       /* copy the original knot to the unified one */
+                       color_knot->unified_nknots=color_knot->nknots;
+                       for(i=0;i<color_knot->nknots;i++)
+                               (color_knot->unified_knot)[i]=(color_knot->knot)[i];
+               }
+               if(normal_knot->unified_knot)
+               {
+                       if((normal_knot->knot)[normal_knot->t_min] - maximal_min_knot >
+                                       EPSILON)
+                               maximal_min_knot=(normal_knot->knot)[normal_knot->t_min];
+                       if(minimal_max_knot - (normal_knot->knot)[normal_knot->t_max] >
+                                       EPSILON)
+                               minimal_max_knot=(normal_knot->knot)[normal_knot->t_max];
+                       if((normal_knot->unified_knot=
+                                       (GLfloat *)malloc(sizeof(GLfloat)*max_nknots))==NULL)
+                       {
+                               free(geom_knot->unified_knot);
+                               free(color_knot->unified_knot);
+                               call_user_error(nobj,GLU_OUT_OF_MEMORY);
+                               return GLU_ERROR;
+                       }
+                       /* copy the original knot to the unified one */
+                       normal_knot->unified_nknots=normal_knot->nknots;
+                       for(i=0;i<normal_knot->nknots;i++)
+                               (normal_knot->unified_knot)[i]=(normal_knot->knot)[i];
+               }
+               if(texture_knot->unified_knot)
+               {
+                       if((texture_knot->knot)[texture_knot->t_min] - maximal_min_knot >
+                                       EPSILON)
+                               maximal_min_knot=(texture_knot->knot)[texture_knot->t_min];
+                       if(minimal_max_knot - (texture_knot->knot)[texture_knot->t_max] >
+                                       EPSILON)
+                               minimal_max_knot=(texture_knot->knot)[texture_knot->t_max];
+                       if((texture_knot->unified_knot=
+                                       (GLfloat *)malloc(sizeof(GLfloat)*max_nknots))==NULL)
+                       {
+                               free(geom_knot->unified_knot);
+                               free(color_knot->unified_knot);
+                               free(normal_knot->unified_knot);
+                               call_user_error(nobj,GLU_OUT_OF_MEMORY);
+                               return GLU_ERROR;
+                       }
+                       /* copy the original knot to the unified one */
+                       texture_knot->unified_nknots=texture_knot->nknots;
+                       for(i=0;i<texture_knot->nknots;i++)
+                               (texture_knot->unified_knot)[i]=(texture_knot->knot)[i];
+               }
+               /* work on the geometry knot with all additional knot values */
+               /* appearing in attirbutive knots */
+               if(minimal_max_knot-maximal_min_knot < EPSILON)
+               {
+                       /* empty working range */
+                       geom_knot->unified_nknots=0;
+                       color_knot->unified_nknots=0;
+                       normal_knot->unified_nknots=0;
+                       texture_knot->unified_nknots=0;
+               }
+               else
+               {
+                       if(color_knot->unified_knot)
+                               collect_unified_knot(geom_knot,color_knot,maximal_min_knot,
+                                       minimal_max_knot);
+                       if(normal_knot->unified_knot)
+                               collect_unified_knot(geom_knot,normal_knot,maximal_min_knot,
+                                       minimal_max_knot);
+                       if(texture_knot->unified_knot)
+                               collect_unified_knot(geom_knot,texture_knot,maximal_min_knot,
+                                       minimal_max_knot);
+                       /* since we have now built the "unified" geometry knot */
+                       /* add same knot values to all attributive knots */
+                       if(color_knot->unified_knot)
+                               collect_unified_knot(color_knot,geom_knot,maximal_min_knot,
+                                       minimal_max_knot);
+                       if(normal_knot->unified_knot)
+                               collect_unified_knot(normal_knot,geom_knot,maximal_min_knot,
+                                       minimal_max_knot);
+                       if(texture_knot->unified_knot)
+                               collect_unified_knot(texture_knot,geom_knot,maximal_min_knot,
+                                       minimal_max_knot);
+               }
+       }
+       set_new_t_min_t_max(geom_knot,color_knot,normal_knot,texture_knot,
+               maximal_min_knot,minimal_max_knot);
+       return GLU_NO_ERROR;
+}
+
+void
+free_unified_knots(knot_str_type *geom_knot, knot_str_type *color_knot,
+       knot_str_type *normal_knot, knot_str_type *texture_knot)
+{
+       if(geom_knot->unified_knot)
+               free(geom_knot->unified_knot);
+       if(color_knot->unified_knot)
+               free(color_knot->unified_knot);
+       if(normal_knot->unified_knot)
+               free(normal_knot->unified_knot);
+       if(texture_knot->unified_knot)
+               free(texture_knot->unified_knot);
+}
+
+GLenum
+explode_knot(knot_str_type *the_knot)
+{
+       GLfloat *knot,*new_knot;
+       GLint nknots,n_new_knots=0;
+       GLint t_min,t_max;
+       GLint ord;
+       GLsizei i,j,k;
+       GLfloat tmp_float;
+
+       if(the_knot->unified_knot)
+       {
+               knot=the_knot->unified_knot;
+               nknots=the_knot->unified_nknots;
+       }
+       else
+       {
+               knot=the_knot->knot;
+               nknots=the_knot->nknots;
+       }
+       ord=the_knot->order;
+       t_min=the_knot->t_min;
+       t_max=the_knot->t_max;
+
+       for(i=t_min;i<=t_max;)
+       {
+               tmp_float=knot[i];
+               for(j=0;j<ord && (i+j)<=t_max;j++)
+                       if(fabs(tmp_float-knot[i+j])>EPSILON)
+                               break;
+               n_new_knots+=ord-j;
+               i+=j;
+       }
+       /* alloc space for new_knot */
+       if((new_knot=(GLfloat *)malloc(sizeof(GLfloat)*(nknots+n_new_knots)))==NULL)
+       {
+               return GLU_OUT_OF_MEMORY;
+       }
+       /* fill in new knot */
+       for(j=0;j<t_min;j++)
+               new_knot[j]=knot[j];
+       for(i=j;i<=t_max;i++)
+       {
+               tmp_float=knot[i];
+               for(k=0;k<ord;k++)
+               {
+                       new_knot[j++]=knot[i];
+                       if(tmp_float==knot[i+1])
+                               i++;
+               }
+       }
+       for(i=t_max+1;i<(int)nknots;i++)
+               new_knot[j++]=knot[i];
+       /* fill in the knot structure */
+       the_knot->new_knot=new_knot;
+       the_knot->delta_nknots+=n_new_knots;
+       the_knot->t_max+=n_new_knots;
+       return GLU_NO_ERROR;
+}
+
+GLenum
+calc_alphas(knot_str_type *the_knot)
+{
+       GLfloat tmp_float;
+       int i,j,k,m,n;
+       int order;
+       GLfloat *alpha,*alpha_new,*tmp_alpha;
+       GLfloat denom;
+       GLfloat *knot,*new_knot;
+
+
+       knot=the_knot->knot;
+       order=the_knot->order;
+       new_knot=the_knot->new_knot;
+       n=the_knot->nknots-the_knot->order;
+       m=n+the_knot->delta_nknots;
+       if((alpha=(GLfloat *)malloc(sizeof(GLfloat)*n*m))==NULL)
+       {
+               return GLU_OUT_OF_MEMORY;
+       }
+       if((alpha_new=(GLfloat *)malloc(sizeof(GLfloat)*n*m))==NULL)
+       {
+               free(alpha);
+               return GLU_OUT_OF_MEMORY;
+       }
+       for(j=0;j<m;j++)
+       {
+               for(i=0;i<n;i++)
+               {
+                       if((knot[i] <= new_knot[j]) && (new_knot[j] < knot[i+1]))
+                               tmp_float=1.0;
+                       else
+                               tmp_float=0.0;
+                       alpha[i+j*n]=tmp_float;
+               }
+       }
+       for(k=1;k<order;k++)
+       {
+               for(j=0;j<m;j++)
+                       for(i=0;i<n;i++)
+                       {
+                               denom=knot[i+k]-knot[i];
+                               if(fabs(denom)<EPSILON)
+                                       tmp_float=0.0;
+                               else
+                                       tmp_float=(new_knot[j+k]-knot[i])/denom*
+                                               alpha[i+j*n];
+                               denom=knot[i+k+1]-knot[i+1];
+                               if(fabs(denom)>EPSILON)
+                                       tmp_float+=(knot[i+k+1]-new_knot[j+k])/denom*
+                                               alpha[(i+1)+j*n];
+                               alpha_new[i+j*n]=tmp_float;
+                       }
+               tmp_alpha=alpha_new;
+               alpha_new=alpha;
+               alpha=tmp_alpha;
+       }
+       the_knot->alpha=alpha;
+       free(alpha_new);
+       return GLU_NO_ERROR;
+}
+
+GLenum
+calc_new_ctrl_pts(GLfloat *ctrl,GLint stride,knot_str_type *the_knot,
+       GLint dim,GLfloat **new_ctrl,GLint *ncontrol)
+{
+       GLsizei i,j,k,l,m,n;
+       GLsizei index1,index2;
+       GLfloat *alpha;
+       GLfloat *new_knot;
+
+       new_knot=the_knot->new_knot;
+       n=the_knot->nknots-the_knot->order;
+       alpha=the_knot->alpha;
+
+       m=the_knot->t_max+1-the_knot->t_min-the_knot->order;
+       k=the_knot->t_min;
+       /* allocate space for new control points */
+       if((*new_ctrl=(GLfloat *)malloc(sizeof(GLfloat)*dim*m))==NULL)
+       {
+               return GLU_OUT_OF_MEMORY;
+       }
+       for(j=0;j<m;j++)
+       {
+               for(l=0;l<dim;l++)
+                       (*new_ctrl)[j*dim+l]=0.0;
+               for(i=0;i<n;i++)
+               {
+                       index1=i+(j+k)*n;
+                       index2=i*stride;
+                       for(l=0;l<dim;l++)
+                               (*new_ctrl)[j*dim+l]+=alpha[index1]*ctrl[index2+l];
+               }
+       }
+       *ncontrol=(GLint)m;
+       return GLU_NO_ERROR;
+}
+
+static GLint
+calc_factor(GLfloat *pts,GLint order,GLint indx,GLint stride,GLfloat tolerance,
+       GLint dim)
+{
+       GLdouble model[16],proj[16];
+       GLint viewport[4];
+       GLdouble x,y,z,w,winx1,winy1,winz,winx2,winy2;
+       GLint i;
+       GLdouble len,dx,dy;
+
+       glGetDoublev(GL_MODELVIEW_MATRIX,model);
+       glGetDoublev(GL_PROJECTION_MATRIX,proj);
+       glGetIntegerv(GL_VIEWPORT,viewport);
+       if(dim==4)
+       {
+               w=(GLdouble)pts[indx+3];
+               x=(GLdouble)pts[indx]/w;
+               y=(GLdouble)pts[indx+1]/w;
+               z=(GLdouble)pts[indx+2]/w;
+               gluProject(x,y,z,model,proj,viewport,&winx1,&winy1,&winz);
+               len=0.0;
+               for(i=1;i<order;i++)
+               {
+                       w=(GLdouble)pts[indx+i*stride+3];
+                       x=(GLdouble)pts[indx+i*stride]/w;
+                       y=(GLdouble)pts[indx+i*stride+1]/w;
+                       z=(GLdouble)pts[indx+i*stride+2]/w;
+                       if(gluProject(x,y,z,model,proj,viewport,&winx2,&winy2,&winz))
+                       {
+                               dx=winx2-winx1;
+                               dy=winy2-winy1;
+                               len+=sqrt(dx*dx+dy*dy);
+                       }
+                       winx1=winx2; winy1=winy2;
+               }
+       }
+       else
+       {
+               x=(GLdouble)pts[indx];
+               y=(GLdouble)pts[indx+1];
+               if(dim==2)
+                       z=0.0;
+               else
+                       z=(GLdouble)pts[indx+2];
+               gluProject(x,y,z,model,proj,viewport,&winx1,&winy1,&winz);
+               len=0.0;
+               for(i=1;i<order;i++)
+               {
+                       x=(GLdouble)pts[indx+i*stride];
+                       y=(GLdouble)pts[indx+i*stride+1];
+                       if(dim==2)
+                               z=0.0;
+                       else
+                               z=(GLdouble)pts[indx+i*stride+2];
+                       if(gluProject(x,y,z,model,proj,viewport,&winx2,&winy2,&winz))
+                       {
+                               dx=winx2-winx1;
+                               dy=winy2-winy1;
+                               len+=sqrt(dx*dx+dy*dy);
+                       }
+                       winx1=winx2; winy1=winy2;
+               }
+       }
+       len /= tolerance;
+       return ((GLint)len+1);
+}
+
+/* we can't use the Mesa evaluators - no way to get the point coords */
+/* so we use our own Bezier point calculus routines */
+/* because I'm lazy, I reuse the ones from eval.c */
+
+static void
+bezier_curve(GLfloat *cp, GLfloat *out, GLfloat t,
+       GLuint dim, GLuint order, GLint offset)
+{
+       GLfloat s, powert;
+       GLuint i, k, bincoeff;
+
+       if(order >= 2)
+       { 
+               bincoeff = order-1;
+               s = 1.0-t;
+
+               for(k=0; k<dim; k++)
+                       out[k] = s*cp[k] + bincoeff*t*cp[offset+k];
+
+               for(i=2, cp+=2*offset, powert=t*t; i<order; i++, powert*=t, cp +=offset)
+               {
+                       bincoeff *= order-i;
+                       bincoeff /= i;
+
+                       for(k=0; k<dim; k++)
+                               out[k] = s*out[k] + bincoeff*powert*cp[k];
+               }
+       }
+       else /* order=1 -> constant curve */
+       { 
+               for(k=0; k<dim; k++)
+                       out[k] = cp[k];
+       } 
+}
+
+static GLint
+calc_parametric_factor(GLfloat *pts,GLint order,GLint indx,GLint stride,
+       GLfloat tolerance,GLint dim)
+{
+       GLdouble model[16],proj[16];
+       GLint viewport[4];
+       GLdouble x,y,z,w,x1,y1,z1,x2,y2,z2,x3,y3,z3;
+       GLint i;
+       GLint P;
+       GLfloat bez_pt[4];
+       GLdouble len=0.0,tmp,z_med;
+
+       P = 2*(order+2);
+       glGetDoublev(GL_MODELVIEW_MATRIX,model);
+       glGetDoublev(GL_PROJECTION_MATRIX,proj);
+       glGetIntegerv(GL_VIEWPORT,viewport);
+       z_med = (viewport[2] + viewport[3]) * 0.5;
+       switch(dim)
+       {
+               case 4:
+                       for(i=1;i<P;i++)
+                       {
+                               bezier_curve(pts+indx, bez_pt, (GLfloat)i/(GLfloat)P, 4,
+                                       order,stride);
+                               w = (GLdouble)bez_pt[3];
+                               x = (GLdouble)bez_pt[0] / w;
+                               y = (GLdouble)bez_pt[1] / w;
+                               z = (GLdouble)bez_pt[2] / w;
+                               gluProject(x,y,z,model,proj,viewport,&x3,&y3,&z3);
+                               z3 *= z_med;
+                               bezier_curve(pts+indx, bez_pt, (GLfloat)(i-1)/(GLfloat)P, 4,
+                                       order,stride);
+                               w = (GLdouble)bez_pt[3];
+                               x = (GLdouble)bez_pt[0] / w;
+                               y = (GLdouble)bez_pt[1] / w;
+                               z = (GLdouble)bez_pt[2] / w;
+                               gluProject(x,y,z,model,proj,viewport,&x1,&y1,&z1);
+                               z1 *= z_med;
+                               bezier_curve(pts+indx, bez_pt, (GLfloat)(i+1)/(GLfloat)P, 4,
+                                       order,stride);
+                               w = (GLdouble)bez_pt[3];
+                               x = (GLdouble)bez_pt[0] / w;
+                               y = (GLdouble)bez_pt[1] / w;
+                               z = (GLdouble)bez_pt[2] / w;
+                               gluProject(x,y,z,model,proj,viewport,&x2,&y2,&z2);
+                               z2 *= z_med;
+                               /* calc distance between point (x3,y3,z3) and line segment */
+                               /* <x1,y1,z1><x2,y2,z2> */
+                               x = x2-x1;
+                               y = y2-y1;
+                               z = z2-z1;
+                               tmp = sqrt(x*x+y*y+z*z);
+                               x /= tmp;
+                               y /= tmp;
+                               z /= tmp;
+                               tmp = x3*x+y3*y+z3*z-x1*x-y1*y-z1*z;
+                               x = x1+x*tmp-x3;
+                               y = y1+y*tmp-y3;
+                               z = z1+z*tmp-z3;
+                               tmp = sqrt(x*x+y*y+z*z);
+                               if(tmp > len)
+                                       len = tmp;
+                       }
+                       break;
+               case 3:
+                       for(i=1;i<P;i++)
+                       {
+                               bezier_curve(pts+indx, bez_pt, (GLfloat)i/(GLfloat)P, 3,
+                                       order,stride);
+                               x = (GLdouble)bez_pt[0];
+                               y = (GLdouble)bez_pt[1];
+                               z = (GLdouble)bez_pt[2];
+                               gluProject(x,y,z,model,proj,viewport,&x3,&y3,&z3);
+                               z3 *= z_med;
+                               bezier_curve(pts+indx, bez_pt, (GLfloat)(i-1)/(GLfloat)P, 3,
+                                       order,stride);
+                               x = (GLdouble)bez_pt[0];
+                               y = (GLdouble)bez_pt[1];
+                               z = (GLdouble)bez_pt[2];
+                               gluProject(x,y,z,model,proj,viewport,&x1,&y1,&z1);
+                               z1 *= z_med;
+                               bezier_curve(pts+indx, bez_pt, (GLfloat)(i+1)/(GLfloat)P, 3,
+                                       order,stride);
+                               x = (GLdouble)bez_pt[0];
+                               y = (GLdouble)bez_pt[1];
+                               z = (GLdouble)bez_pt[2];
+                               gluProject(x,y,z,model,proj,viewport,&x2,&y2,&z2);
+                               z2 *= z_med;
+                               /* calc distance between point (x3,y3,z3) and line segment */
+                               /* <x1,y1,z1><x2,y2,z2> */
+                               x = x2-x1;
+                               y = y2-y1;
+                               z = z2-z1;
+                               tmp = sqrt(x*x+y*y+z*z);
+                               x /= tmp;
+                               y /= tmp;
+                               z /= tmp;
+                               tmp = x3*x+y3*y+z3*z-x1*x-y1*y-z1*z;
+                               x = x1+x*tmp-x3;
+                               y = y1+y*tmp-y3;
+                               z = z1+z*tmp-z3;
+                               tmp = sqrt(x*x+y*y+z*z);
+                               if(tmp > len)
+                                       len = tmp;
+                       }
+                       break;
+               case 2:
+                       for(i=1;i<P;i++)
+                       {
+                               bezier_curve(pts+indx, bez_pt, (GLfloat)i/(GLfloat)P, 2,
+                                       order,stride);
+                               x = (GLdouble)bez_pt[0];
+                               y = (GLdouble)bez_pt[1];
+                               z = 0.0;
+                               gluProject(x,y,z,model,proj,viewport,&x3,&y3,&z3);
+                               z3 *= z_med;
+                               bezier_curve(pts+indx, bez_pt, (GLfloat)(i-1)/(GLfloat)P, 2,
+                                       order,stride);
+                               x = (GLdouble)bez_pt[0];
+                               y = (GLdouble)bez_pt[1];
+                               z = 0.0;
+                               gluProject(x,y,z,model,proj,viewport,&x1,&y1,&z1);
+                               z1 *= z_med;
+                               bezier_curve(pts+indx, bez_pt, (GLfloat)(i+1)/(GLfloat)P, 2,
+                                       order,stride);
+                               x = (GLdouble)bez_pt[0];
+                               y = (GLdouble)bez_pt[1];
+                               z = 0.0;
+                               gluProject(x,y,z,model,proj,viewport,&x2,&y2,&z2);
+                               z2 *= z_med;
+                               /* calc distance between point (x3,y3,z3) and line segment */
+                               /* <x1,y1,z1><x2,y2,z2> */
+                               x = x2-x1;
+                               y = y2-y1;
+                               z = z2-z1;
+                               tmp = sqrt(x*x+y*y+z*z);
+                               x /= tmp;
+                               y /= tmp;
+                               z /= tmp;
+                               tmp = x3*x+y3*y+z3*z-x1*x-y1*y-z1*z;
+                               x = x1+x*tmp-x3;
+                               y = y1+y*tmp-y3;
+                               z = z1+z*tmp-z3;
+                               tmp = sqrt(x*x+y*y+z*z);
+                               if(tmp > len)
+                                       len = tmp;
+                       }
+                       break;
+
+       }
+       if(len < tolerance)
+               return (order);
+       else
+               return (GLint)(sqrt(len/tolerance)*(order+2)+1);
+}
+
+static GLenum
+calc_sampling_3D(new_ctrl_type *new_ctrl, GLfloat tolerance, GLint dim,
+       GLint uorder, GLint vorder, GLint **ufactors, GLint **vfactors)
+{
+       GLfloat         *ctrl;
+       GLint           tmp_factor1,tmp_factor2;
+       GLint           ufactor_cnt,vfactor_cnt;
+       GLint           offset1,offset2,offset3;
+       GLint           i,j;
+
+       ufactor_cnt=new_ctrl->s_bezier_cnt;
+       vfactor_cnt=new_ctrl->t_bezier_cnt;
+       if((*ufactors=(GLint *)malloc(sizeof(GLint)*ufactor_cnt*3))
+                       ==NULL)
+       {
+               return GLU_OUT_OF_MEMORY;
+       }
+       if((*vfactors=(GLint *)malloc(sizeof(GLint)*vfactor_cnt*3))
+                       ==NULL)
+       {
+               free(*ufactors);
+               return GLU_OUT_OF_MEMORY;
+       }
+       ctrl=new_ctrl->geom_ctrl;
+       offset1=new_ctrl->geom_t_stride*vorder;
+       offset2=new_ctrl->geom_s_stride*uorder;
+       for(j=0;j<vfactor_cnt;j++)
+       {
+               *(*vfactors+j*3+1)=tmp_factor1=calc_factor(ctrl,vorder,
+                       j*offset1,dim,tolerance,dim);
+               /* loop ufactor_cnt-1 times */
+               for(i=1;i<ufactor_cnt;i++)
+               {
+                       tmp_factor2=calc_factor(ctrl,vorder,
+                               j*offset1+i*offset2,dim,tolerance,dim);
+                       if(tmp_factor2>tmp_factor1)
+                               tmp_factor1=tmp_factor2;
+               }
+               /* last time for the opposite edge */
+               *(*vfactors+j*3+2)=tmp_factor2=calc_factor(ctrl,vorder,
+                       j*offset1+i*offset2-new_ctrl->geom_s_stride,
+                       dim,tolerance,dim);
+               if(tmp_factor2>tmp_factor1)
+                       *(*vfactors+j*3)=tmp_factor2;
+               else
+                       *(*vfactors+j*3)=tmp_factor1;
+       }
+       offset3=new_ctrl->geom_s_stride;
+       offset2=new_ctrl->geom_s_stride*uorder;
+       for(j=0;j<ufactor_cnt;j++)
+       {
+               *(*ufactors+j*3+1)=tmp_factor1=calc_factor(ctrl,uorder,
+                       j*offset2,offset3,tolerance,dim);
+               /* loop vfactor_cnt-1 times */
+               for(i=1;i<vfactor_cnt;i++)
+               {
+                       tmp_factor2=calc_factor(ctrl,uorder,
+                               j*offset2+i*offset1,offset3,tolerance,dim);
+                       if(tmp_factor2>tmp_factor1)
+                               tmp_factor1=tmp_factor2;
+               }
+               /* last time for the opposite edge */
+               *(*ufactors+j*3+2)=tmp_factor2=calc_factor(ctrl,uorder,
+                       j*offset2+i*offset1-new_ctrl->geom_t_stride,
+                       offset3,tolerance,dim);
+               if(tmp_factor2>tmp_factor1)
+                       *(*ufactors+j*3)=tmp_factor2;
+               else
+                       *(*ufactors+j*3)=tmp_factor1;
+       }
+       return GL_NO_ERROR;
+}
+
+static GLenum
+calc_sampling_param_3D(new_ctrl_type *new_ctrl, GLfloat tolerance, GLint dim,
+       GLint uorder, GLint vorder, GLint **ufactors, GLint **vfactors)
+{
+       GLfloat         *ctrl;
+       GLint           tmp_factor1,tmp_factor2;
+       GLint           ufactor_cnt,vfactor_cnt;
+       GLint           offset1,offset2,offset3;
+       GLint           i,j;
+
+       ufactor_cnt=new_ctrl->s_bezier_cnt;
+       vfactor_cnt=new_ctrl->t_bezier_cnt;
+       if((*ufactors=(GLint *)malloc(sizeof(GLint)*ufactor_cnt*3))
+                       ==NULL)
+       {
+               return GLU_OUT_OF_MEMORY;
+       }
+       if((*vfactors=(GLint *)malloc(sizeof(GLint)*vfactor_cnt*3))
+                       ==NULL)
+       {
+               free(*ufactors);
+               return GLU_OUT_OF_MEMORY;
+       }
+       ctrl=new_ctrl->geom_ctrl;
+       offset1=new_ctrl->geom_t_stride*vorder;
+       offset2=new_ctrl->geom_s_stride*uorder;
+       for(j=0;j<vfactor_cnt;j++)
+       {
+               *(*vfactors+j*3+1)=tmp_factor1=calc_parametric_factor(ctrl,vorder,
+                       j*offset1,dim,tolerance,dim);
+               /* loop ufactor_cnt-1 times */
+               for(i=1;i<ufactor_cnt;i++)
+               {
+                       tmp_factor2=calc_parametric_factor(ctrl,vorder,
+                               j*offset1+i*offset2,dim,tolerance,dim);
+                       if(tmp_factor2>tmp_factor1)
+                               tmp_factor1=tmp_factor2;
+               }
+               /* last time for the opposite edge */
+               *(*vfactors+j*3+2)=tmp_factor2=calc_parametric_factor(ctrl,vorder,
+                       j*offset1+i*offset2-new_ctrl->geom_s_stride,
+                       dim,tolerance,dim);
+               if(tmp_factor2>tmp_factor1)
+                       *(*vfactors+j*3)=tmp_factor2;
+               else
+                       *(*vfactors+j*3)=tmp_factor1;
+       }
+       offset3=new_ctrl->geom_s_stride;
+       offset2=new_ctrl->geom_s_stride*uorder;
+       for(j=0;j<ufactor_cnt;j++)
+       {
+               *(*ufactors+j*3+1)=tmp_factor1=calc_parametric_factor(ctrl,uorder,
+                       j*offset2,offset3,tolerance,dim);
+               /* loop vfactor_cnt-1 times */
+               for(i=1;i<vfactor_cnt;i++)
+               {
+                       tmp_factor2=calc_parametric_factor(ctrl,uorder,
+                               j*offset2+i*offset1,offset3,tolerance,dim);
+                       if(tmp_factor2>tmp_factor1)
+                               tmp_factor1=tmp_factor2;
+               }
+               /* last time for the opposite edge */
+               *(*ufactors+j*3+2)=tmp_factor2=calc_parametric_factor(ctrl,uorder,
+                       j*offset2+i*offset1-new_ctrl->geom_t_stride,
+                       offset3,tolerance,dim);
+               if(tmp_factor2>tmp_factor1)
+                       *(*ufactors+j*3)=tmp_factor2;
+               else
+                       *(*ufactors+j*3)=tmp_factor1;
+       }
+       return GL_NO_ERROR;
+}
+
+static GLenum
+calc_sampling_2D(GLfloat *ctrl, GLint cnt, GLint order,
+       GLfloat tolerance, GLint dim, GLint **factors)
+{
+       GLint           factor_cnt;
+       GLint           tmp_factor;
+       GLint           offset;
+       GLint           i;
+
+       factor_cnt=cnt/order;
+       if((*factors=(GLint *)malloc(sizeof(GLint)*factor_cnt))==NULL)
+       {
+               return GLU_OUT_OF_MEMORY;
+       }
+       offset=order*dim;
+       for(i=0;i<factor_cnt;i++)
+       {
+               tmp_factor=calc_factor(ctrl,order,i*offset,dim,tolerance,dim);
+               if(tmp_factor == 0)
+                       (*factors)[i]=1;
+               else
+                       (*factors)[i]=tmp_factor;
+       }
+       return GL_NO_ERROR;
+}
+
+static void
+set_sampling_and_culling( GLUnurbsObj *nobj )
+{
+       if(nobj->auto_load_matrix==GL_FALSE)
+       {
+               GLint i;
+               GLfloat m[4];
+
+               glPushAttrib( (GLbitfield) (GL_VIEWPORT_BIT | GL_TRANSFORM_BIT));
+               for(i=0;i<4;i++)
+                       m[i]=nobj->sampling_matrices.viewport[i];
+               glViewport(m[0],m[1],m[2],m[3]);
+               glMatrixMode(GL_PROJECTION);
+               glPushMatrix();
+               glLoadMatrixf(nobj->sampling_matrices.proj);
+               glMatrixMode(GL_MODELVIEW);
+               glPushMatrix();
+               glLoadMatrixf(nobj->sampling_matrices.model);
+       }
+}
+
+static void
+revert_sampling_and_culling( GLUnurbsObj *nobj )
+{
+       if(nobj->auto_load_matrix==GL_FALSE)
+       {
+               glMatrixMode(GL_MODELVIEW);
+               glPopMatrix();
+               glMatrixMode(GL_PROJECTION);
+               glPopMatrix();
+               glPopAttrib();
+       }
+}
+
+GLenum
+glu_do_sampling_3D( GLUnurbsObj *nobj, new_ctrl_type *new_ctrl,
+       GLint **sfactors, GLint **tfactors)
+{
+       GLint   dim;
+       GLenum  err;
+
+       *sfactors=NULL;
+       *tfactors=NULL;
+       dim=nobj->surface.geom.dim;
+       set_sampling_and_culling(nobj);
+       if((err=calc_sampling_3D(new_ctrl,nobj->sampling_tolerance,dim,
+               nobj->surface.geom.sorder,nobj->surface.geom.torder,
+               sfactors,tfactors))==GLU_ERROR)
+       {
+               revert_sampling_and_culling(nobj);
+               call_user_error(nobj,err);
+               return GLU_ERROR;
+       }
+       revert_sampling_and_culling(nobj);
+       return GLU_NO_ERROR;
+}
+
+GLenum
+glu_do_sampling_uv( GLUnurbsObj *nobj, new_ctrl_type *new_ctrl,
+       GLint **sfactors, GLint **tfactors)
+{
+       GLint   s_cnt, t_cnt, i;
+       GLint   u_steps, v_steps;
+
+       s_cnt = new_ctrl->s_bezier_cnt;
+       t_cnt = new_ctrl->t_bezier_cnt;
+       *sfactors=NULL;
+       *tfactors=NULL;
+       if((*sfactors=(GLint *)malloc(sizeof(GLint)*s_cnt*3))
+                       ==NULL)
+       {
+               return GLU_OUT_OF_MEMORY;
+       }
+       if((*tfactors=(GLint *)malloc(sizeof(GLint)*t_cnt*3))
+                       ==NULL)
+       {
+               free(*sfactors);
+               return GLU_OUT_OF_MEMORY;
+       }
+       u_steps = nobj->u_step;
+       v_steps = nobj->v_step;
+       for(i=0; i<s_cnt; i++)
+       {
+               *(*sfactors+i*3) = u_steps;
+               *(*sfactors+i*3+1) = u_steps;
+               *(*sfactors+i*3+2) = u_steps;
+       }
+       for(i=0; i<t_cnt; i++)
+       {
+               *(*tfactors+i*3) = v_steps;
+               *(*tfactors+i*3+1) = v_steps;
+               *(*tfactors+i*3+2) = v_steps;
+       }
+       return GLU_NO_ERROR;
+}
+
+GLenum
+glu_do_sampling_param_3D( GLUnurbsObj *nobj, new_ctrl_type *new_ctrl,
+       GLint **sfactors, GLint **tfactors)
+{
+       GLint   dim;
+       GLenum  err;
+
+       *sfactors=NULL;
+       *tfactors=NULL;
+       dim=nobj->surface.geom.dim;
+       set_sampling_and_culling(nobj);
+       if((err=calc_sampling_param_3D(new_ctrl,nobj->parametric_tolerance,dim,
+               nobj->surface.geom.sorder,nobj->surface.geom.torder,
+               sfactors,tfactors))==GLU_ERROR)
+       {
+               revert_sampling_and_culling(nobj);
+               call_user_error(nobj,err);
+               return GLU_ERROR;
+       }
+       revert_sampling_and_culling(nobj);
+       return GLU_NO_ERROR;
+}
+
+GLenum
+glu_do_sampling_2D( GLUnurbsObj *nobj, GLfloat *ctrl, GLint cnt, GLint order,
+       GLint dim, GLint **factors)
+{
+       GLenum err;
+
+       set_sampling_and_culling(nobj);
+       err=calc_sampling_2D(ctrl,cnt,order,nobj->sampling_tolerance,dim,
+               factors);
+       revert_sampling_and_culling(nobj);
+       return err;
+}
+
+
+GLenum
+glu_do_sampling_u( GLUnurbsObj *nobj, GLfloat *ctrl, GLint cnt, GLint order,
+       GLint dim, GLint **factors)
+{
+       GLint   i;
+       GLint   u_steps;
+
+       cnt /= order;
+       if((*factors=(GLint *)malloc(sizeof(GLint)*cnt))
+                       ==NULL)
+       {
+               return GLU_OUT_OF_MEMORY;
+       }
+       u_steps = nobj->u_step;
+       for(i=0; i<cnt; i++)
+               (*factors)[i] = u_steps;
+       return GLU_NO_ERROR;
+}
+
+GLenum
+glu_do_sampling_param_2D( GLUnurbsObj *nobj, GLfloat *ctrl, GLint cnt,
+       GLint order, GLint dim, GLint **factors)
+{
+       GLint   i;
+       GLint   u_steps;
+       GLfloat tolerance;
+
+       set_sampling_and_culling(nobj);
+       tolerance = nobj->parametric_tolerance;
+       cnt /= order;
+       if((*factors=(GLint *)malloc(sizeof(GLint)*cnt))
+                       ==NULL)
+       {
+               revert_sampling_and_culling(nobj);
+               return GLU_OUT_OF_MEMORY;
+       }
+       u_steps = nobj->u_step;
+       for(i=0; i<cnt; i++)
+       {
+               (*factors)[i] = calc_parametric_factor(ctrl,order,0,
+                       dim,tolerance,dim);
+
+       }
+       revert_sampling_and_culling(nobj);
+       return GLU_NO_ERROR;
+}
+
+GLenum
+glu_do_sampling_crv( GLUnurbsObj *nobj, GLfloat *ctrl, GLint cnt, GLint order,
+       GLint dim, GLint **factors)
+{
+       GLenum err;
+
+       *factors=NULL;
+       switch(nobj->sampling_method)
+       {
+               case GLU_PATH_LENGTH:
+                       if((err=glu_do_sampling_2D(nobj,ctrl,cnt,order,dim,factors))!=
+                               GLU_NO_ERROR)
+                       {
+                               call_user_error(nobj,err);
+                               return GLU_ERROR;
+                       }
+                       break;
+               case GLU_DOMAIN_DISTANCE:
+                       if((err=glu_do_sampling_u(nobj,ctrl,cnt,order,dim,factors))!=
+                               GLU_NO_ERROR)
+                       {
+                               call_user_error(nobj,err);
+                               return GLU_ERROR;
+                       }
+                       break;
+               case GLU_PARAMETRIC_ERROR:
+                       if((err=glu_do_sampling_param_2D(nobj,ctrl,cnt,order,dim,factors))!=
+                               GLU_NO_ERROR)
+                       {
+                               call_user_error(nobj,err);
+                               return GLU_ERROR;
+                       }
+                       break;
+               default:
+                       abort();
+       }
+
+       return GLU_NO_ERROR;
+}
+
+/* TODO - i don't like this culling - this one just tests if at least one */
+/* ctrl point lies within the viewport . Also the point_in_viewport() */
+/* should be included in the fnctions for efficiency reasons */
+
+static GLboolean
+point_in_viewport(GLfloat *pt, GLint dim)
+{
+       GLdouble model[16],proj[16];
+       GLint viewport[4];
+       GLdouble x,y,z,w,winx,winy,winz;
+
+       glGetDoublev(GL_MODELVIEW_MATRIX,model);
+       glGetDoublev(GL_PROJECTION_MATRIX,proj);
+       glGetIntegerv(GL_VIEWPORT,viewport);
+       if(dim==3)
+       {
+               x=(GLdouble)pt[0];
+               y=(GLdouble)pt[1];
+               z=(GLdouble)pt[2];
+               gluProject(x,y,z,model,proj,viewport,&winx,&winy,&winz);
+       }
+       else
+       {
+               w=(GLdouble)pt[3];
+               x=(GLdouble)pt[0]/w;
+               y=(GLdouble)pt[1]/w;
+               z=(GLdouble)pt[2]/w;
+               gluProject(x,y,z,model,proj,viewport,&winx,&winy,&winz);
+       }
+       if((GLint)winx >= viewport[0] && (GLint)winx < viewport[2] &&
+                       (GLint)winy >= viewport[1] && (GLint)winy < viewport[3])
+               return GL_TRUE;
+       return GL_FALSE;
+}
+
+GLboolean
+fine_culling_test_3D(GLUnurbsObj *nobj,GLfloat *pts,GLint s_cnt,GLint t_cnt,
+       GLint s_stride,GLint t_stride, GLint dim)
+{
+       GLint   i,j;
+
+       if(nobj->culling==GL_FALSE)
+               return GL_FALSE;
+       set_sampling_and_culling(nobj);
+       
+       if(dim==3)
+       {
+               for(i=0;i<s_cnt;i++)
+                       for(j=0;j<t_cnt;j++)
+                               if(point_in_viewport(pts+i*s_stride+j*t_stride,dim))
+                               {
+                                       revert_sampling_and_culling(nobj);
+                                       return GL_FALSE;
+                               }
+       }
+       else
+       {
+               for(i=0;i<s_cnt;i++)
+                       for(j=0;j<t_cnt;j++)
+                               if(point_in_viewport(pts+i*s_stride+j*t_stride,dim))
+                               {
+                                       revert_sampling_and_culling(nobj);
+                                       return GL_FALSE;
+                               }
+       }
+       revert_sampling_and_culling(nobj);
+       return GL_TRUE;
+}
+
+/*GLboolean
+fine_culling_test_3D(GLUnurbsObj *nobj,GLfloat *pts,GLint s_cnt,GLint t_cnt,
+       GLint s_stride,GLint t_stride, GLint dim)
+{
+       GLint           visible_cnt;
+       GLfloat         feedback_buffer[5];
+       GLsizei         buffer_size;
+       GLint           i,j;
+
+       if(nobj->culling==GL_FALSE)
+               return GL_FALSE;
+       buffer_size=5;
+       set_sampling_and_culling(nobj);
+       
+       glFeedbackBuffer(buffer_size,GL_2D,feedback_buffer);
+       glRenderMode(GL_FEEDBACK);
+       if(dim==3)
+       {
+               for(i=0;i<s_cnt;i++)
+               {
+                       glBegin(GL_LINE_LOOP);
+                       for(j=0;j<t_cnt;j++)
+                               glVertex3fv(pts+i*s_stride+j*t_stride);
+                       glEnd();
+               }
+               for(j=0;j<t_cnt;j++)
+               {
+                       glBegin(GL_LINE_LOOP);
+                       for(i=0;i<s_cnt;i++)
+                               glVertex3fv(pts+i*s_stride+j*t_stride);
+                       glEnd();
+               }
+       }
+       else
+       {
+               for(i=0;i<s_cnt;i++)
+               {
+                       glBegin(GL_LINE_LOOP);
+                       for(j=0;j<t_cnt;j++)
+                               glVertex4fv(pts+i*s_stride+j*t_stride);
+                       glEnd();
+               }
+               for(j=0;j<t_cnt;j++)
+               {
+                       glBegin(GL_LINE_LOOP);
+                       for(i=0;i<s_cnt;i++)
+                               glVertex4fv(pts+i*s_stride+j*t_stride);
+                       glEnd();
+               }
+       }
+       visible_cnt=glRenderMode(GL_RENDER);
+
+       revert_sampling_and_culling(nobj);
+       return (GLboolean)(visible_cnt==0);
+}*/
+
+GLboolean
+fine_culling_test_2D(GLUnurbsObj *nobj,GLfloat *pts,GLint cnt,
+       GLint stride, GLint dim)
+{
+       GLint   i;
+
+       if(nobj->culling==GL_FALSE)
+               return GL_FALSE;
+       set_sampling_and_culling(nobj);
+       
+       if(dim==3)
+       {
+               for(i=0;i<cnt;i++)
+                       if(point_in_viewport(pts+i*stride,dim))
+                       {
+                               revert_sampling_and_culling(nobj);
+                               return GL_FALSE;
+                       }
+       }
+       else
+       {
+               for(i=0;i<cnt;i++)
+                       if(point_in_viewport(pts+i*stride,dim))
+                       {
+                               revert_sampling_and_culling(nobj);
+                               return GL_FALSE;
+                       }
+       }
+       revert_sampling_and_culling(nobj);
+       return GL_TRUE;
+}
+
+/*GLboolean
+fine_culling_test_2D(GLUnurbsObj *nobj,GLfloat *pts,GLint cnt,
+       GLint stride, GLint dim)
+{
+       GLint           visible_cnt;
+       GLfloat         feedback_buffer[5];
+       GLsizei         buffer_size;
+       GLint           i;
+
+       if(nobj->culling==GL_FALSE)
+               return GL_FALSE;
+       buffer_size=5;
+       set_sampling_and_culling(nobj);
+       
+       glFeedbackBuffer(buffer_size,GL_2D,feedback_buffer);
+       glRenderMode(GL_FEEDBACK);
+       glBegin(GL_LINE_LOOP);
+       if(dim==3)
+       {
+               for(i=0;i<cnt;i++)
+                       glVertex3fv(pts+i*stride);
+       }
+       else
+       {
+               for(i=0;i<cnt;i++)
+                       glVertex4fv(pts+i*stride);
+       }
+       glEnd();
+       visible_cnt=glRenderMode(GL_RENDER);
+
+       revert_sampling_and_culling(nobj);
+       return (GLboolean)(visible_cnt==0);
+}*/
+
diff --git a/src/glu/mesa/polytest.c b/src/glu/mesa/polytest.c
new file mode 100644 (file)
index 0000000..9b42c63
--- /dev/null
@@ -0,0 +1,1049 @@
+/* $Id: polytest.c,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  2.4
+ * Copyright (C) 1995-1997  Brian Paul
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/*
+ * $Log: polytest.c,v $
+ * Revision 1.1  1999/08/19 00:55:42  jtg
+ * Initial revision
+ *
+ * Revision 1.7  1999/06/08 00:44:51  brianp
+ * OpenStep updates (pete@ohm.york.ac.uk)
+ *
+ * Revision 1.6  1998/07/26 02:08:52  brianp
+ * updated for Windows compilation per Ted Jump
+ *
+ * Revision 1.5  1997/10/29 02:02:20  brianp
+ * various MS Windows compiler changes (David Bucciarelli, v20 3dfx driver)
+ *
+ * Revision 1.4  1997/07/24 01:28:44  brianp
+ * changed precompiled header symbol from PCH to PC_HEADER
+ *
+ * Revision 1.3  1997/05/28 02:29:38  brianp
+ * added support for precompiled headers (PCH), inserted APIENTRY keyword
+ *
+ * Revision 1.2  1997/05/08 01:53:21  brianp
+ * fixed memory leak in free_current_polygon() reported by Randy Frank
+ *
+ * Revision 1.1  1996/09/27 01:19:39  brianp
+ * Initial revision
+ *
+ */
+
+
+/*
+ * This file is part of the polygon tesselation code contributed by
+ * Bogdan Sikorski
+ */
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <math.h>
+#include <stdlib.h>
+#include "gluP.h"
+#include "tess.h"
+#endif
+
+
+
+static GLenum store_polygon_as_contour(GLUtriangulatorObj *);
+static void free_current_polygon(tess_polygon *);
+static void prepare_projection_info(GLUtriangulatorObj *);
+static GLdouble twice_the_polygon_area(tess_vertex *,tess_vertex *);
+static GLenum verify_edge_vertex_intersections(GLUtriangulatorObj *);
+void tess_find_contour_hierarchies(GLUtriangulatorObj *);
+static GLenum test_for_overlapping_contours(GLUtriangulatorObj *);
+static GLenum contours_overlap(tess_contour *, tess_polygon *);
+static GLenum is_contour_contained_in(tess_contour *,tess_contour *);
+static void add_new_exterior(GLUtriangulatorObj *,tess_contour *);
+static void add_new_interior(GLUtriangulatorObj *,tess_contour *,
+       tess_contour *);
+static void add_interior_with_hierarchy_check(GLUtriangulatorObj *,
+       tess_contour *,tess_contour *);
+static void reverse_hierarchy_and_add_exterior(GLUtriangulatorObj *,
+       tess_contour *,tess_contour *);
+static GLboolean point_in_polygon(tess_contour *,GLdouble,GLdouble);
+static void shift_interior_to_exterior(GLUtriangulatorObj *,tess_contour *);
+static void add_exterior_with_check(GLUtriangulatorObj *,tess_contour *,
+       tess_contour *);
+static GLenum cut_out_hole(GLUtriangulatorObj *,tess_contour *,
+       tess_contour *);
+static GLenum merge_hole_with_contour(GLUtriangulatorObj *,
+       tess_contour *,tess_contour *,tess_vertex *,
+       tess_vertex *);
+
+static GLenum
+find_normal(GLUtriangulatorObj *tobj)
+{
+       tess_polygon *polygon=tobj->current_polygon;
+       tess_vertex *va,*vb,*vc;
+       GLdouble A,B,C;
+       GLdouble A0,A1,A2,B0,B1,B2;
+
+       va=polygon->vertices;
+       vb=va->next;
+       A0=vb->location[0]-va->location[0];
+       A1=vb->location[1]-va->location[1];
+       A2=vb->location[2]-va->location[2];
+       for(vc=vb->next;vc!=va;vc=vc->next)
+       {
+               B0=vc->location[0]-va->location[0];
+               B1=vc->location[1]-va->location[1];
+               B2=vc->location[2]-va->location[2];
+               A=A1*B2-A2*B1;
+               B=A2*B0-A0*B2;
+               C=A0*B1-A1*B0;
+               if(fabs(A)>EPSILON || fabs(B)>EPSILON || fabs(C)>EPSILON)
+               {
+                       polygon->A=A;
+                       polygon->B=B;
+                       polygon->C=C;
+                       polygon->D= -A*va->location[0]-B*va->location[1]-C*va->location[2];
+                       return GLU_NO_ERROR;
+               }
+       }
+       tess_call_user_error(tobj,GLU_TESS_ERROR7);
+       return GLU_ERROR;
+}
+
+void
+tess_test_polygon( GLUtriangulatorObj *tobj )
+{
+       tess_polygon *polygon=tobj->current_polygon;
+
+       /* any vertices defined? */
+       if(polygon->vertex_cnt<3)
+       {
+               free_current_polygon(polygon);
+               return;
+       }
+       /* wrap pointers */
+       polygon->last_vertex->next=polygon->vertices;
+       polygon->vertices->previous=polygon->last_vertex;
+       /* determine the normal */
+       if(find_normal(tobj)==GLU_ERROR)
+               return;
+       /* compare the normals of previously defined contours and this one */
+       /* first contour define ? */
+       if(tobj->contours==NULL)
+       {
+               tobj->A=polygon->A;
+               tobj->B=polygon->B;
+               tobj->C=polygon->C;
+               tobj->D=polygon->D;
+               /* determine the best projection to use */
+               if(fabs(polygon->A) > fabs(polygon->B))
+                       if(fabs(polygon->A) > fabs(polygon->C))
+                               tobj->projection=OYZ;
+                       else
+                               tobj->projection=OXY;
+               else
+                       if(fabs(polygon->B) > fabs(polygon->C))
+                               tobj->projection=OXZ;
+                       else
+                               tobj->projection=OXY;
+       }
+       else
+       {
+               GLdouble a[3],b[3];
+               tess_vertex *vertex=polygon->vertices;
+
+               a[0]=tobj->A;
+               a[1]=tobj->B;
+               a[2]=tobj->C;
+               b[0]=polygon->A;
+               b[1]=polygon->B;
+               b[2]=polygon->C;
+
+               /* compare the normals */
+               if( fabs(a[1]*b[2]-a[2]*b[1]) > EPSILON ||
+                       fabs(a[2]*b[0]-a[0]*b[2]) > EPSILON ||
+                       fabs(a[0]*b[1]-a[1]*b[0]) > EPSILON)
+               {
+                       /* not coplanar */
+                       tess_call_user_error(tobj,GLU_TESS_ERROR9);
+                       return;
+               }
+               /* the normals are parallel - test for plane equation */
+               if(fabs(a[0]*vertex->location[0]+a[1]*vertex->location[1]+
+                       a[2]*vertex->location[2]+tobj->D) > EPSILON)
+               {
+                       /* not the same plane */
+                       tess_call_user_error(tobj,GLU_TESS_ERROR9);
+                       return;
+               }
+       }
+       prepare_projection_info(tobj);
+       if(verify_edge_vertex_intersections(tobj)==GLU_ERROR)
+               return;
+       if(test_for_overlapping_contours(tobj)==GLU_ERROR)
+               return;
+       if(store_polygon_as_contour(tobj)==GLU_ERROR)
+               return;
+}
+
+static GLenum test_for_overlapping_contours(GLUtriangulatorObj *tobj)
+{
+       tess_contour *contour;
+       tess_polygon *polygon;
+
+       polygon=tobj->current_polygon;
+       for(contour=tobj->contours;contour!=NULL;contour=contour->next)
+               if(contours_overlap(contour,polygon)!=GLU_NO_ERROR)
+               {
+                       tess_call_user_error(tobj,GLU_TESS_ERROR5);
+                       return GLU_ERROR;
+               }
+       return GLU_NO_ERROR;
+}
+
+static GLenum store_polygon_as_contour(GLUtriangulatorObj *tobj)
+{
+       tess_polygon *polygon=tobj->current_polygon;
+       tess_contour *contour=tobj->contours;
+
+       /* the first contour defined */
+       if(contour==NULL)
+       {
+               if((contour=(tess_contour *)malloc(
+                       sizeof(tess_contour)))==NULL)
+               {
+                       tess_call_user_error(tobj,GLU_OUT_OF_MEMORY);
+                       free_current_polygon(polygon);
+                       return GLU_ERROR;
+               }
+               tobj->contours=tobj->last_contour=contour;
+               contour->next=contour->previous=NULL;
+       }
+       else
+       {
+               if((contour=(tess_contour *)malloc(
+                       sizeof(tess_contour)))==NULL)
+               {
+                       tess_call_user_error(tobj,GLU_OUT_OF_MEMORY);
+                       free_current_polygon(polygon);
+                       return GLU_ERROR;
+               }
+               contour->previous=tobj->last_contour;
+               tobj->last_contour->next=contour;
+               tobj->last_contour=contour;
+               contour->next=NULL;
+       }
+       /* mark all vertices in new contour as not special */
+       /* and all are boundary edges */
+       {
+               tess_vertex *vertex;
+               GLuint vertex_cnt,i;
+
+               for(vertex=polygon->vertices , i=0 , vertex_cnt=polygon->vertex_cnt;
+                       i<vertex_cnt;
+                       vertex=vertex->next , i++)
+               {
+                       vertex->shadow_vertex=NULL;
+                       vertex->edge_flag=GL_TRUE;
+               }
+       }
+       contour->vertex_cnt=polygon->vertex_cnt;
+       contour->area=polygon->area;
+       contour->orientation=polygon->orientation;
+       contour->type=GLU_UNKNOWN;
+       contour->vertices=polygon->vertices;
+       contour->last_vertex=polygon->last_vertex;
+       polygon->vertices=polygon->last_vertex=NULL;
+       polygon->vertex_cnt=0;
+       ++(tobj->contour_cnt);
+       return GLU_NO_ERROR;
+}
+
+static void free_current_polygon(tess_polygon *polygon)
+{
+       tess_vertex *vertex,*vertex_tmp;
+       GLuint  i;
+
+       /* free current_polygon structures */
+       for(vertex=polygon->vertices,i=0;i<polygon->vertex_cnt;i++)
+       {
+               vertex_tmp=vertex->next;
+               free(vertex);
+               vertex=vertex_tmp;
+       }
+       polygon->vertices=polygon->last_vertex=NULL;
+       polygon->vertex_cnt=0;
+}
+
+static void prepare_projection_info(GLUtriangulatorObj *tobj)
+{
+       tess_polygon *polygon=tobj->current_polygon;
+       tess_vertex *vertex,*last_vertex_ptr;
+       GLdouble area;
+
+       last_vertex_ptr=polygon->last_vertex;
+       switch(tobj->projection)
+       {
+               case OXY:
+                       for(vertex=polygon->vertices;vertex!=last_vertex_ptr;
+                               vertex=vertex->next)
+                       {
+                               vertex->x=vertex->location[0];
+                               vertex->y=vertex->location[1];
+                       }
+                       last_vertex_ptr->x=last_vertex_ptr->location[0];
+                       last_vertex_ptr->y=last_vertex_ptr->location[1];
+                       break;
+               case OXZ:
+                       for(vertex=polygon->vertices;vertex!=last_vertex_ptr;
+                               vertex=vertex->next)
+                       {
+                               vertex->x=vertex->location[0];
+                               vertex->y=vertex->location[2];
+                       }
+                       last_vertex_ptr->x=last_vertex_ptr->location[0];
+                       last_vertex_ptr->y=last_vertex_ptr->location[2];
+                       break;
+               case OYZ:
+                       for(vertex=polygon->vertices;vertex!=last_vertex_ptr;
+                               vertex=vertex->next)
+                       {
+                               vertex->x=vertex->location[1];
+                               vertex->y=vertex->location[2];
+                       }
+                       last_vertex_ptr->x=last_vertex_ptr->location[1];
+                       last_vertex_ptr->y=last_vertex_ptr->location[2];
+                       break;
+       }
+       area=twice_the_polygon_area(polygon->vertices,polygon->last_vertex);
+       if(area >= 0.0)
+       {
+               polygon->orientation=GLU_CCW;
+               polygon->area=area;
+       }
+       else
+       {
+               polygon->orientation=GLU_CW;
+               polygon->area= -area;
+       }
+}
+
+static GLdouble twice_the_polygon_area(tess_vertex *vertex,
+       tess_vertex *last_vertex)
+{
+       tess_vertex *next;
+       GLdouble area,x,y;
+
+       area=0.0;
+       x=vertex->x;
+       y=vertex->y;
+       vertex=vertex->next;
+       for(; vertex!=last_vertex; vertex=vertex->next)
+       {
+               next=vertex->next;
+               area+=(vertex->x - x)*(next->y - y) - (vertex->y - y)*(next->x - x);
+       }
+       return area;
+}
+
+/* test if edges ab and cd intersect */
+/* if not return GLU_NO_ERROR, else if cross return GLU_TESS_ERROR8, */
+/* else if adjacent return GLU_TESS_ERROR4 */
+static GLenum edge_edge_intersect(
+       tess_vertex *a,
+       tess_vertex *b,
+       tess_vertex *c,
+       tess_vertex *d)
+{
+       GLdouble denom,r,s;
+       GLdouble xba,ydc,yba,xdc,yac,xac;
+
+       xba=b->x - a->x;
+       yba=b->y - a->y;
+       xdc=d->x - c->x;
+       ydc=d->y - c->y;
+       xac=a->x - c->x;
+       yac=a->y - c->y;
+       denom= xba*ydc - yba*xdc;
+       r = yac*xdc - xac*ydc;
+       /* parallel? */
+       if(fabs(denom) < EPSILON)
+       {
+               if(fabs(r) < EPSILON)
+               {
+                       /* colinear */
+                       if(fabs(xba) < EPSILON)
+                       {
+                               /* compare the Y coordinate */
+                               if(yba > 0.0)
+                               {
+                                       if((fabs(a->y - c->y)<EPSILON && fabs(c->y - b->y)<EPSILON)
+                                               ||
+                                               (fabs(a->y - d->y)<EPSILON && fabs(d->y - b->y)<EPSILON))
+                                       return GLU_TESS_ERROR4;
+
+                               }
+                               else
+                               {
+                                       if((fabs(b->y - c->y)<EPSILON && fabs(c->y - a->y)<EPSILON)
+                                               ||
+                                               (fabs(b->y - d->y)<EPSILON && fabs(d->y - a->y)<EPSILON))
+                                       return GLU_TESS_ERROR4;
+                               }
+                       }
+                       else
+                       {
+                               /* compare the X coordinate */
+                               if(xba > 0.0)
+                               {
+                                       if((fabs(a->x - c->x)<EPSILON && fabs(c->x - b->x)<EPSILON)
+                                               ||
+                                               (fabs(a->x - d->x)<EPSILON && fabs(d->x - b->x)<EPSILON))
+                                       return GLU_TESS_ERROR4;
+                               }
+                               else
+                               {
+                                       if((fabs(b->x - c->x)<EPSILON && fabs(c->x - a->x)<EPSILON)
+                                               ||
+                                               (fabs(b->x - d->x)<EPSILON && fabs(d->x - a->x)<EPSILON))
+                                       return GLU_TESS_ERROR4;
+                               }
+                       }
+               }
+               return GLU_NO_ERROR;
+       }
+       r /= denom;
+       s = (yac*xba - xac*yba) / denom;
+       /* test if one vertex lies on other edge */
+       if(((fabs(r) < EPSILON || (r < 1.0+EPSILON && r > 1.0-EPSILON)) &&
+               s > -EPSILON && s < 1.0+EPSILON) ||
+               ((fabs(s) < EPSILON || (s < 1.0+EPSILON && s > 1.0-EPSILON)) &&
+               r > -EPSILON && r < 1.0+EPSILON))
+       {
+               return GLU_TESS_ERROR4;
+       }
+       /* test for crossing */
+       if(r > -EPSILON && r < 1.0+EPSILON &&
+               s > -EPSILON && s < 1.0+EPSILON)
+       {
+               return GLU_TESS_ERROR8;
+       }
+       return GLU_NO_ERROR;
+}
+
+static GLenum verify_edge_vertex_intersections(GLUtriangulatorObj *tobj)
+{
+       tess_polygon *polygon=tobj->current_polygon;
+       tess_vertex *vertex1,*last_vertex,*vertex2;
+       GLenum test;
+
+       last_vertex=polygon->last_vertex;
+       vertex1=last_vertex;
+       for(vertex2=vertex1->next->next;
+               vertex2->next!=last_vertex;
+               vertex2=vertex2->next)
+       {
+               test=edge_edge_intersect(vertex1,vertex1->next,vertex2,
+                       vertex2->next);
+               if(test!=GLU_NO_ERROR)
+               {
+                       tess_call_user_error(tobj,test);
+                       return GLU_ERROR;
+               }
+       }
+       for(vertex1=polygon->vertices;
+               vertex1->next->next!=last_vertex;
+               vertex1=vertex1->next)
+       {
+               for(vertex2=vertex1->next->next;
+                       vertex2!=last_vertex;
+                       vertex2=vertex2->next)
+               {
+                       test=edge_edge_intersect(vertex1,vertex1->next,vertex2,
+                               vertex2->next);
+                       if(test!=GLU_NO_ERROR)
+                       {
+                               tess_call_user_error(tobj,test);
+                               return GLU_ERROR;
+                       }
+               }
+       }
+       return GLU_NO_ERROR;
+}
+
+static int
+#if defined(WIN32) && !defined(OPENSTEP)
+__cdecl
+#endif
+area_compare(const void *a,const void *b)
+{
+       GLdouble area1,area2;
+
+       area1=(*((tess_contour **)a))->area;
+       area2=(*((tess_contour **)b))->area;
+       if(area1 < area2)
+               return 1;
+       if(area1 > area2)
+               return -1;
+       return 0;
+}
+
+void tess_find_contour_hierarchies(GLUtriangulatorObj *tobj)
+{
+       tess_contour **contours; /* dinamic array of pointers */
+       tess_contour *tmp_contour_ptr=tobj->contours;
+       GLuint cnt,i;
+       GLenum result;
+       GLboolean hierarchy_changed;
+
+       /* any contours? */
+       if(tobj->contour_cnt < 2)
+       {
+               tobj->contours->type=GLU_EXTERIOR;
+               return;
+       }
+       if((contours=(tess_contour **)
+               malloc(sizeof(tess_contour *)*(tobj->contour_cnt)))==NULL)
+       {
+               tess_call_user_error(tobj,GLU_OUT_OF_MEMORY);
+               return;
+       }
+       for(tmp_contour_ptr=tobj->contours , cnt=0;
+               tmp_contour_ptr!=NULL;
+               tmp_contour_ptr=tmp_contour_ptr->next)
+               contours[cnt++]=tmp_contour_ptr;
+       /* now sort the contours in decreasing area size order */
+       qsort((void *)contours,(size_t)cnt,(size_t)sizeof(tess_contour *),area_compare);
+       /* we leave just the first contour - remove others from list */
+       tobj->contours=contours[0];
+       tobj->contours->next=tobj->contours->previous=NULL;
+       tobj->last_contour=tobj->contours;
+       tobj->contour_cnt=1;
+       /* first contour is the one with greatest area */
+       /* must be EXTERIOR */
+       tobj->contours->type=GLU_EXTERIOR;
+       tmp_contour_ptr=tobj->contours;
+       /* now we play! */
+       for(i=1;i<cnt;i++)
+       {
+               hierarchy_changed=GL_FALSE;
+               for(tmp_contour_ptr=tobj->contours;
+                       tmp_contour_ptr!=NULL;
+                       tmp_contour_ptr=tmp_contour_ptr->next)
+               {
+                       if(tmp_contour_ptr->type==GLU_EXTERIOR)
+                       {
+                               /* check if contour completely contained in EXTERIOR */
+                               result=is_contour_contained_in(tmp_contour_ptr,contours[i]);
+                               switch(result)
+                               {
+                                       case GLU_INTERIOR:
+                                               /* now we have to check if contour is inside interiors */
+                                               /* or not */
+                                               /* any interiors? */
+                                               if(tmp_contour_ptr->next!=NULL &&
+                                                       tmp_contour_ptr->next->type==GLU_INTERIOR)
+                                               {
+                                                       /* for all interior, check if inside any of them */
+                                                       /* if not inside any of interiors, its another */
+                                                       /* interior */
+                                                       /* or it may contain some interiors, then change */
+                                                       /* the contained interiors to exterior ones */
+                                                       add_interior_with_hierarchy_check(tobj,
+                                                               tmp_contour_ptr,contours[i]);
+                                               }
+                                               else
+                                               {
+                                                       /* not in interior, add as new interior contour */
+                                                       add_new_interior(tobj,tmp_contour_ptr,contours[i]);
+                                               }
+                                               hierarchy_changed=GL_TRUE;
+                                               break;
+                                       case GLU_EXTERIOR:
+                                               /* ooops, the marked as EXTERIOR (contours[i]) is */
+                                               /* actually an interior of tmp_contour_ptr */
+                                               /*  reverse the local hierarchy */
+                                               reverse_hierarchy_and_add_exterior(tobj,tmp_contour_ptr,
+                                                       contours[i]);
+                                               hierarchy_changed=GL_TRUE;
+                                               break;
+                                       case GLU_NO_ERROR:
+                                               break;
+                                       default:
+                                               abort();
+                               }
+                       }
+                       if(hierarchy_changed)
+                               break; /* break from for loop */
+               }
+               if(hierarchy_changed==GL_FALSE)
+               {
+                       /* disjoint with all contours, add to contour list */
+                       add_new_exterior(tobj,contours[i]);
+               }
+       }
+       free(contours);
+}
+
+/* returns GLU_INTERIOR if inner is completey enclosed within outer */
+/* returns GLU_EXTERIOR if outer is completely enclosed within inner */
+/* returns GLU_NO_ERROR if contours are disjoint */
+static GLenum is_contour_contained_in(
+       tess_contour *outer,
+       tess_contour *inner)
+{
+       GLenum relation_flag;
+
+       /* set relation_flag to relation of containment of first inner vertex */
+       /* regarding outer contour */
+       if(point_in_polygon(outer,inner->vertices->x,inner->vertices->y))
+               relation_flag=GLU_INTERIOR;
+       else
+               relation_flag=GLU_EXTERIOR;
+       if(relation_flag==GLU_INTERIOR)
+               return GLU_INTERIOR;
+       if(point_in_polygon(inner,outer->vertices->x,outer->vertices->y))
+               return GLU_EXTERIOR;
+       return GLU_NO_ERROR;
+}
+
+static GLboolean point_in_polygon(
+       tess_contour *contour,
+       GLdouble x,
+       GLdouble y)
+{
+       tess_vertex *v1,*v2;
+       GLuint i,vertex_cnt;
+       GLdouble xp1,yp1,xp2,yp2;
+       GLboolean tst;
+
+       tst=GL_FALSE;
+       v1=contour->vertices;
+       v2=contour->vertices->previous;
+       for(i=0 , vertex_cnt=contour->vertex_cnt;
+               i < vertex_cnt;
+               i++)
+       {
+               xp1=v1->x;
+               yp1=v1->y;
+               xp2=v2->x;
+               yp2=v2->y;
+               if ((((yp1<=y) && (y<yp2)) || ((yp2<=y)  && (y<yp1))) &&
+                       (x < (xp2 - xp1) * (y - yp1) /  (yp2 - yp1) + xp1))
+                               tst = (tst==GL_FALSE ? GL_TRUE : GL_FALSE);
+               v2=v1;
+               v1=v1->next;
+       }
+       return tst;
+}
+
+static GLenum contours_overlap(
+       tess_contour *contour,
+       tess_polygon *polygon)
+{
+       tess_vertex *vertex1,*vertex2;
+       GLuint vertex1_cnt,vertex2_cnt,i,j;
+       GLenum test;
+
+       vertex1=contour->vertices;
+       vertex2=polygon->vertices;
+       vertex1_cnt=contour->vertex_cnt;
+       vertex2_cnt=polygon->vertex_cnt;
+       for(i=0; i<vertex1_cnt; vertex1=vertex1->next , i++)
+       {
+               for(j=0; j<vertex2_cnt; vertex2=vertex2->next , j++)
+                       if((test=edge_edge_intersect(vertex1,vertex1->next,vertex2,
+                               vertex2->next))!=GLU_NO_ERROR)
+                               return test;
+       }
+       return GLU_NO_ERROR;
+}
+
+static void add_new_exterior(
+       GLUtriangulatorObj *tobj,
+       tess_contour *contour)
+{
+       contour->type=GLU_EXTERIOR;
+       contour->next=NULL;
+       contour->previous=tobj->last_contour;
+       tobj->last_contour->next=contour;
+       tobj->last_contour=contour;
+}
+
+static void add_new_interior(
+       GLUtriangulatorObj *tobj,
+       tess_contour *outer,
+       tess_contour *contour)
+{
+       contour->type=GLU_INTERIOR;
+       contour->next=outer->next;
+       contour->previous=outer;
+       if(outer->next!=NULL)
+               outer->next->previous=contour;
+       outer->next=contour;
+       if(tobj->last_contour==outer)
+               tobj->last_contour=contour;
+}
+
+static void add_interior_with_hierarchy_check(
+       GLUtriangulatorObj *tobj,
+       tess_contour *outer,
+       tess_contour *contour)
+{
+       tess_contour *ptr;
+
+       /* for all interiors of outer check if they are interior of contour */
+       /* if so, change that interior to exterior and move it of of the */
+       /* interior sequence */
+       if(outer->next!=NULL && outer->next->type==GLU_INTERIOR)
+       {
+               GLenum test;
+
+               for(ptr=outer->next;ptr!=NULL && ptr->type==GLU_INTERIOR;ptr=ptr->next)
+               {
+                       test=is_contour_contained_in(ptr,contour);
+                       switch(test)
+                       {
+                               case GLU_INTERIOR:
+                                       /* contour is contained in one of the interiors */
+                                       /* check if possibly contained in other exteriors */
+                                       /* move ptr to first EXTERIOR */
+                                       for(;ptr!=NULL && ptr->type==GLU_INTERIOR;ptr=ptr->next);
+                                       if(ptr==NULL)
+                                               /* another exterior */
+                                               add_new_exterior(tobj,contour);
+                                       else
+                                               add_exterior_with_check(tobj,ptr,contour);
+                                       return;
+                               case GLU_EXTERIOR:
+                                       /* one of the interiors is contained in the contour */
+                                       /* change it to EXTERIOR, and shift it away from the */
+                                       /* interior sequence */
+                                       shift_interior_to_exterior(tobj,ptr);
+                                       break;
+                               case GLU_NO_ERROR:
+                                       /* disjoint */
+                                       break;
+                               default:
+                                       abort();
+                       }
+               }
+       }
+       /* add contour to the interior sequence */
+       add_new_interior(tobj,outer,contour);
+}
+
+static void reverse_hierarchy_and_add_exterior(
+       GLUtriangulatorObj *tobj,
+       tess_contour *outer,
+       tess_contour *contour)
+{
+       tess_contour *ptr;
+
+       /* reverse INTERIORS to EXTERIORS */
+       /* any INTERIORS? */
+       if(outer->next!=NULL && outer->next->type==GLU_INTERIOR)
+               for(ptr=outer->next;ptr!=NULL && ptr->type==GLU_INTERIOR;ptr=ptr->next)
+                       ptr->type=GLU_EXTERIOR;
+       /* the outer now becomes inner */
+       outer->type=GLU_INTERIOR;
+       /* contour is the EXTERIOR */
+       contour->next=outer;
+       if(tobj->contours==outer)
+       {
+               /* first contour beeing reversed */
+               contour->previous=NULL;
+               tobj->contours=contour;
+       }
+       else
+       {
+               outer->previous->next=contour;
+               contour->previous=outer->previous;
+       }
+       outer->previous=contour;
+}
+
+static void shift_interior_to_exterior(
+       GLUtriangulatorObj *tobj,
+       tess_contour *contour)
+{
+       contour->previous->next=contour->next;
+       if(contour->next!=NULL)
+               contour->next->previous=contour->previous;
+       else
+               tobj->last_contour=contour->previous;
+}
+
+static void add_exterior_with_check(
+       GLUtriangulatorObj *tobj,
+       tess_contour *outer,
+       tess_contour *contour)
+{
+       GLenum test;
+
+       /* this contour might be interior to further exteriors - check */
+       /* if not, just add as a new exterior */
+       for(;outer!=NULL && outer->type==GLU_EXTERIOR;outer=outer->next)
+       {
+               test=is_contour_contained_in(outer,contour);
+               switch(test)
+               {
+                       case GLU_INTERIOR:
+                               /* now we have to check if contour is inside interiors */
+                               /* or not */
+                               /* any interiors? */
+                               if(outer->next!=NULL && outer->next->type==GLU_INTERIOR)
+                               {
+                                       /* for all interior, check if inside any of them */
+                                       /* if not inside any of interiors, its another */
+                                       /* interior */
+                                       /* or it may contain some interiors, then change */
+                                       /* the contained interiors to exterior ones */
+                                       add_interior_with_hierarchy_check(tobj,
+                                               outer,contour);
+                               }
+                               else
+                               {
+                                       /* not in interior, add as new interior contour */
+                                       add_new_interior(tobj,outer,contour);
+                               }
+                               return;
+                       case GLU_NO_ERROR:
+                               /* disjoint */
+                               break;
+                       default:
+                               abort();
+               }
+       }
+       /* add contour to the exterior sequence */
+       add_new_exterior(tobj,contour);
+}
+
+void tess_handle_holes(GLUtriangulatorObj *tobj)
+{
+       tess_contour *contour,*hole;
+       GLenum exterior_orientation;
+
+       /* verify hole orientation */
+       for(contour=tobj->contours;contour!=NULL;)
+       {
+               exterior_orientation=contour->orientation;
+               for(contour=contour->next;
+                       contour!=NULL && contour->type==GLU_INTERIOR;
+                       contour=contour->next)
+               {
+                       if(contour->orientation==exterior_orientation)
+                       {
+                               tess_call_user_error(tobj,GLU_TESS_ERROR5);
+                               return;
+                       }
+               }
+       }
+       /* now cut-out holes */
+       for(contour=tobj->contours;contour!=NULL;)
+       {
+               hole=contour->next;
+               while(hole!=NULL && hole->type==GLU_INTERIOR)
+               {
+                       if(cut_out_hole(tobj,contour,hole)==GLU_ERROR)
+                               return;
+                       hole=contour->next;
+               }
+               contour=contour->next;
+       }
+}
+
+static GLenum cut_out_hole(
+       GLUtriangulatorObj *tobj,
+       tess_contour *contour,
+       tess_contour *hole)
+{
+       tess_contour *tmp_hole;
+       tess_vertex *v1,*v2,*tmp_vertex;
+       GLuint vertex1_cnt,vertex2_cnt,tmp_vertex_cnt;
+       GLuint i,j,k;
+       GLenum test;
+
+       /* find an edge connecting contour and hole not intersecting any other */
+       /* edge belonging to either the contour or any of the other holes */
+       for(v1=contour->vertices , vertex1_cnt=contour->vertex_cnt , i=0;
+               i<vertex1_cnt;
+               i++ , v1=v1->next)
+       {
+               for(v2=hole->vertices , vertex2_cnt=hole->vertex_cnt , j=0;
+                       j<vertex2_cnt;
+                       j++ , v2=v2->next)
+               {
+                       /* does edge (v1,v2) intersect any edge of contour */
+                       for(tmp_vertex=contour->vertices , tmp_vertex_cnt=contour->vertex_cnt ,
+                                       k=0;
+                               k<tmp_vertex_cnt;
+                               tmp_vertex=tmp_vertex->next , k++)
+                       {
+                               /* skip edge tests for edges directly connected */
+                               if(v1==tmp_vertex || v1==tmp_vertex->next)
+                                       continue;
+                               test=edge_edge_intersect(v1,v2,tmp_vertex,tmp_vertex->next);
+                               if(test!=GLU_NO_ERROR)
+                                       break;
+                       }
+                       if(test==GLU_NO_ERROR)
+                       {
+                               /* does edge (v1,v2) intersect any edge of hole */
+                               for(tmp_vertex=hole->vertices ,
+                                               tmp_vertex_cnt=hole->vertex_cnt , k=0;
+                                       k<tmp_vertex_cnt;
+                                       tmp_vertex=tmp_vertex->next , k++)
+                               {
+                                       /* skip edge tests for edges directly connected */
+                                       if(v2==tmp_vertex || v2==tmp_vertex->next)
+                                               continue;
+                                       test=edge_edge_intersect(v1,v2,tmp_vertex,tmp_vertex->next);
+                                       if(test!=GLU_NO_ERROR)
+                                               break;
+                               }
+                               if(test==GLU_NO_ERROR)
+                               {
+                                       /* does edge (v1,v2) intersect any other hole? */
+                                       for(tmp_hole=hole->next;
+                                               tmp_hole!=NULL && tmp_hole->type==GLU_INTERIOR;
+                                               tmp_hole=tmp_hole->next)
+                                       {
+                                               /* does edge (v1,v2) intersect any edge of hole */
+                                               for(tmp_vertex=tmp_hole->vertices ,
+                                                               tmp_vertex_cnt=tmp_hole->vertex_cnt , k=0;
+                                                       k<tmp_vertex_cnt;
+                                                       tmp_vertex=tmp_vertex->next , k++)
+                                               {
+                                                       test=edge_edge_intersect(v1,v2,tmp_vertex,
+                                                               tmp_vertex->next);
+                                                       if(test!=GLU_NO_ERROR)
+                                                               break;
+                                               }
+                                               if(test!=GLU_NO_ERROR)
+                                                       break;
+                                       }
+                               }
+                       }
+                       if(test==GLU_NO_ERROR)
+                       {
+                               /* edge (v1,v2) is good for eliminating the hole */
+                               if(merge_hole_with_contour(tobj,contour,hole,v1,v2)
+                                       ==GLU_NO_ERROR)
+                                       return GLU_NO_ERROR;
+                               else
+                                       return GLU_ERROR;
+                       }
+               }
+       }
+       /* other holes are blocking all possible connections of hole */
+       /* with contour, we shift this hole as the last hole and retry */
+       for(tmp_hole=hole;
+               tmp_hole!=NULL && tmp_hole->type==GLU_INTERIOR;
+               tmp_hole=tmp_hole->next);
+       contour->next=hole->next;
+       hole->next->previous=contour;
+       if(tmp_hole==NULL)
+       {
+               /* last EXTERIOR contour, shift hole as last contour */
+               hole->next=NULL;
+               hole->previous=tobj->last_contour;
+               tobj->last_contour->next=hole;
+               tobj->last_contour=hole;
+       }
+       else
+       {
+               tmp_hole->previous->next=hole;
+               hole->previous=tmp_hole->previous;
+               tmp_hole->previous=hole;
+               hole->next=tmp_hole;
+       }
+       hole=contour->next;
+       /* try once again - recurse */
+       return cut_out_hole(tobj,contour,hole);
+}
+
+static GLenum merge_hole_with_contour(
+       GLUtriangulatorObj *tobj,
+       tess_contour *contour,
+       tess_contour *hole,
+       tess_vertex *v1,
+       tess_vertex *v2)
+{
+       tess_vertex *v1_new,*v2_new;
+
+       /* make copies of v1 and v2, place them respectively after their originals */
+       if((v1_new=(tess_vertex *)malloc(sizeof(tess_vertex)))==NULL)
+       {
+               tess_call_user_error(tobj,GLU_OUT_OF_MEMORY);
+               return GLU_ERROR;
+       }
+       if((v2_new=(tess_vertex *)malloc(sizeof(tess_vertex)))==NULL)
+       {
+               tess_call_user_error(tobj,GLU_OUT_OF_MEMORY);
+               return GLU_ERROR;
+       }
+       v1_new->edge_flag=GL_TRUE;
+       v1_new->data=v1->data;
+       v1_new->location[0]=v1->location[0];
+       v1_new->location[1]=v1->location[1];
+       v1_new->location[2]=v1->location[2];
+       v1_new->x=v1->x;
+       v1_new->y=v1->y;
+       v1_new->shadow_vertex=v1;
+       v1->shadow_vertex=v1_new;
+       v1_new->next=v1->next;
+       v1_new->previous=v1;
+       v1->next->previous=v1_new;
+       v1->next=v1_new;
+       v2_new->edge_flag=GL_TRUE;
+       v2_new->data=v2->data;
+       v2_new->location[0]=v2->location[0];
+       v2_new->location[1]=v2->location[1];
+       v2_new->location[2]=v2->location[2];
+       v2_new->x=v2->x;
+       v2_new->y=v2->y;
+       v2_new->shadow_vertex=v2;
+       v2->shadow_vertex=v2_new;
+       v2_new->next=v2->next;
+       v2_new->previous=v2;
+       v2->next->previous=v2_new;
+       v2->next=v2_new;
+       /* link together the two lists */
+       v1->next=v2_new;
+       v2_new->previous=v1;
+       v2->next=v1_new;
+       v1_new->previous=v2;
+       /* update the vertex count of the contour */
+       contour->vertex_cnt += hole->vertex_cnt+2;
+       /* remove the INTERIOR contour */
+       contour->next=hole->next;
+       if(hole->next!=NULL)
+               hole->next->previous=contour;
+       free(hole);
+       /* update tobj structure */
+       --(tobj->contour_cnt);
+       if(contour->last_vertex==v1)
+               contour->last_vertex=v1_new;
+       /* mark two vertices with edge_flag */
+       v2->edge_flag=GL_FALSE;
+       v1->edge_flag=GL_FALSE;
+       return GLU_NO_ERROR;
+}
diff --git a/src/glu/mesa/project.c b/src/glu/mesa/project.c
new file mode 100644 (file)
index 0000000..32142c9
--- /dev/null
@@ -0,0 +1,318 @@
+/* $Id: project.c,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * Copyright (C) 1995-1999  Brian Paul
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/*
+ * $Log: project.c,v $
+ * Revision 1.1  1999/08/19 00:55:42  jtg
+ * Initial revision
+ *
+ * Revision 1.7  1999/01/03 03:23:15  brianp
+ * now using GLAPIENTRY and GLCALLBACK keywords (Ted Jump)
+ *
+ * Revision 1.6  1998/07/08 01:43:43  brianp
+ * new version of invert_matrix()  (also in src/matrix.c)
+ *
+ * Revision 1.5  1997/07/24 01:28:44  brianp
+ * changed precompiled header symbol from PCH to PC_HEADER
+ *
+ * Revision 1.4  1997/05/28 02:29:38  brianp
+ * added support for precompiled headers (PCH), inserted APIENTRY keyword
+ *
+ * Revision 1.3  1997/04/11 23:22:42  brianp
+ * added divide by zero checks to gluProject() and gluUnproject()
+ *
+ * Revision 1.2  1997/01/29 19:05:29  brianp
+ * faster invert_matrix() function from Stephane Rehel
+ *
+ * Revision 1.1  1996/09/27 01:19:39  brianp
+ * Initial revision
+ *
+ */
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include "gluP.h"
+#endif
+
+
+/*
+ * This code was contributed by Marc Buffat (buffat@mecaflu.ec-lyon.fr).
+ * Thanks Marc!!!
+ */
+
+
+
+/* implementation de gluProject et gluUnproject */
+/* M. Buffat 17/2/95 */
+
+
+
+/*
+ * Transform a point (column vector) by a 4x4 matrix.  I.e.  out = m * in
+ * Input:  m - the 4x4 matrix
+ *         in - the 4x1 vector
+ * Output:  out - the resulting 4x1 vector.
+ */
+static void transform_point( GLdouble out[4], const GLdouble m[16],
+                            const GLdouble in[4] )
+{
+#define M(row,col)  m[col*4+row]
+   out[0] = M(0,0) * in[0] + M(0,1) * in[1] + M(0,2) * in[2] + M(0,3) * in[3];
+   out[1] = M(1,0) * in[0] + M(1,1) * in[1] + M(1,2) * in[2] + M(1,3) * in[3];
+   out[2] = M(2,0) * in[0] + M(2,1) * in[1] + M(2,2) * in[2] + M(2,3) * in[3];
+   out[3] = M(3,0) * in[0] + M(3,1) * in[1] + M(3,2) * in[2] + M(3,3) * in[3];
+#undef M
+}
+
+
+
+
+/*
+ * Perform a 4x4 matrix multiplication  (product = a x b).
+ * Input:  a, b - matrices to multiply
+ * Output:  product - product of a and b
+ */
+static void matmul( GLdouble *product, const GLdouble *a, const GLdouble *b )
+{
+   /* This matmul was contributed by Thomas Malik */
+   GLdouble temp[16];
+   GLint i;
+
+#define A(row,col)  a[(col<<2)+row]
+#define B(row,col)  b[(col<<2)+row]
+#define T(row,col)  temp[(col<<2)+row]
+
+   /* i-te Zeile */
+   for (i = 0; i < 4; i++)
+     {
+       T(i, 0) = A(i, 0) * B(0, 0) + A(i, 1) * B(1, 0) + A(i, 2) * B(2, 0) + A(i, 3) * B(3, 0);
+       T(i, 1) = A(i, 0) * B(0, 1) + A(i, 1) * B(1, 1) + A(i, 2) * B(2, 1) + A(i, 3) * B(3, 1);
+       T(i, 2) = A(i, 0) * B(0, 2) + A(i, 1) * B(1, 2) + A(i, 2) * B(2, 2) + A(i, 3) * B(3, 2);
+       T(i, 3) = A(i, 0) * B(0, 3) + A(i, 1) * B(1, 3) + A(i, 2) * B(2, 3) + A(i, 3) * B(3, 3);
+     }
+
+#undef A
+#undef B
+#undef T
+   MEMCPY( product, temp, 16*sizeof(GLdouble) );
+}
+
+
+static GLdouble Identity[16] = {
+   1.0, 0.0, 0.0, 0.0,
+   0.0, 1.0, 0.0, 0.0,
+   0.0, 0.0, 1.0, 0.0,
+   0.0, 0.0, 0.0, 1.0
+};
+
+
+
+/*
+ * Compute inverse of 4x4 transformation matrix.
+ * Code contributed by Jacques Leroy jle@star.be
+ * Return GL_TRUE for success, GL_FALSE for failure (singular matrix)
+ */
+static GLboolean invert_matrix( const GLdouble *m, GLdouble *out )
+{
+/* NB. OpenGL Matrices are COLUMN major. */
+#define SWAP_ROWS(a, b) { GLdouble *_tmp = a; (a)=(b); (b)=_tmp; }
+#define MAT(m,r,c) (m)[(c)*4+(r)]
+
+ GLdouble wtmp[4][8];
+ GLdouble m0, m1, m2, m3, s;
+ GLdouble *r0, *r1, *r2, *r3;
+
+ r0 = wtmp[0], r1 = wtmp[1], r2 = wtmp[2], r3 = wtmp[3];
+
+ r0[0] = MAT(m,0,0), r0[1] = MAT(m,0,1),
+ r0[2] = MAT(m,0,2), r0[3] = MAT(m,0,3),
+ r0[4] = 1.0, r0[5] = r0[6] = r0[7] = 0.0,
+
+ r1[0] = MAT(m,1,0), r1[1] = MAT(m,1,1),
+ r1[2] = MAT(m,1,2), r1[3] = MAT(m,1,3),
+ r1[5] = 1.0, r1[4] = r1[6] = r1[7] = 0.0,
+
+ r2[0] = MAT(m,2,0), r2[1] = MAT(m,2,1),
+ r2[2] = MAT(m,2,2), r2[3] = MAT(m,2,3),
+ r2[6] = 1.0, r2[4] = r2[5] = r2[7] = 0.0,
+
+ r3[0] = MAT(m,3,0), r3[1] = MAT(m,3,1),
+ r3[2] = MAT(m,3,2), r3[3] = MAT(m,3,3),
+ r3[7] = 1.0, r3[4] = r3[5] = r3[6] = 0.0;
+
+ /* choose pivot - or die */
+ if (fabs(r3[0])>fabs(r2[0])) SWAP_ROWS(r3, r2);
+ if (fabs(r2[0])>fabs(r1[0])) SWAP_ROWS(r2, r1);
+ if (fabs(r1[0])>fabs(r0[0])) SWAP_ROWS(r1, r0);
+ if (0.0 == r0[0])  return GL_FALSE;
+
+ /* eliminate first variable     */
+ m1 = r1[0]/r0[0]; m2 = r2[0]/r0[0]; m3 = r3[0]/r0[0];
+ s = r0[1]; r1[1] -= m1 * s; r2[1] -= m2 * s; r3[1] -= m3 * s;
+ s = r0[2]; r1[2] -= m1 * s; r2[2] -= m2 * s; r3[2] -= m3 * s;
+ s = r0[3]; r1[3] -= m1 * s; r2[3] -= m2 * s; r3[3] -= m3 * s;
+ s = r0[4];
+ if (s != 0.0) { r1[4] -= m1 * s; r2[4] -= m2 * s; r3[4] -= m3 * s; }
+ s = r0[5];
+ if (s != 0.0) { r1[5] -= m1 * s; r2[5] -= m2 * s; r3[5] -= m3 * s; }
+ s = r0[6];
+ if (s != 0.0) { r1[6] -= m1 * s; r2[6] -= m2 * s; r3[6] -= m3 * s; }
+ s = r0[7];
+ if (s != 0.0) { r1[7] -= m1 * s; r2[7] -= m2 * s; r3[7] -= m3 * s; }
+
+ /* choose pivot - or die */
+ if (fabs(r3[1])>fabs(r2[1])) SWAP_ROWS(r3, r2);
+ if (fabs(r2[1])>fabs(r1[1])) SWAP_ROWS(r2, r1);
+ if (0.0 == r1[1])  return GL_FALSE;
+
+ /* eliminate second variable */
+ m2 = r2[1]/r1[1]; m3 = r3[1]/r1[1];
+ r2[2] -= m2 * r1[2]; r3[2] -= m3 * r1[2];
+ r2[3] -= m2 * r1[3]; r3[3] -= m3 * r1[3];
+ s = r1[4]; if (0.0 != s) { r2[4] -= m2 * s; r3[4] -= m3 * s; }
+ s = r1[5]; if (0.0 != s) { r2[5] -= m2 * s; r3[5] -= m3 * s; }
+ s = r1[6]; if (0.0 != s) { r2[6] -= m2 * s; r3[6] -= m3 * s; }
+ s = r1[7]; if (0.0 != s) { r2[7] -= m2 * s; r3[7] -= m3 * s; }
+
+ /* choose pivot - or die */
+ if (fabs(r3[2])>fabs(r2[2])) SWAP_ROWS(r3, r2);
+ if (0.0 == r2[2])  return GL_FALSE;
+
+ /* eliminate third variable */
+ m3 = r3[2]/r2[2];
+ r3[3] -= m3 * r2[3], r3[4] -= m3 * r2[4],
+ r3[5] -= m3 * r2[5], r3[6] -= m3 * r2[6],
+ r3[7] -= m3 * r2[7];
+
+ /* last check */
+ if (0.0 == r3[3]) return GL_FALSE;
+
+ s = 1.0/r3[3];              /* now back substitute row 3 */
+ r3[4] *= s; r3[5] *= s; r3[6] *= s; r3[7] *= s;
+
+ m2 = r2[3];                 /* now back substitute row 2 */
+ s  = 1.0/r2[2];
+ r2[4] = s * (r2[4] - r3[4] * m2), r2[5] = s * (r2[5] - r3[5] * m2),
+ r2[6] = s * (r2[6] - r3[6] * m2), r2[7] = s * (r2[7] - r3[7] * m2);
+ m1 = r1[3];
+ r1[4] -= r3[4] * m1, r1[5] -= r3[5] * m1,
+ r1[6] -= r3[6] * m1, r1[7] -= r3[7] * m1;
+ m0 = r0[3];
+ r0[4] -= r3[4] * m0, r0[5] -= r3[5] * m0,
+ r0[6] -= r3[6] * m0, r0[7] -= r3[7] * m0;
+
+ m1 = r1[2];                 /* now back substitute row 1 */
+ s  = 1.0/r1[1];
+ r1[4] = s * (r1[4] - r2[4] * m1), r1[5] = s * (r1[5] - r2[5] * m1),
+ r1[6] = s * (r1[6] - r2[6] * m1), r1[7] = s * (r1[7] - r2[7] * m1);
+ m0 = r0[2];
+ r0[4] -= r2[4] * m0, r0[5] -= r2[5] * m0,
+ r0[6] -= r2[6] * m0, r0[7] -= r2[7] * m0;
+
+ m0 = r0[1];                 /* now back substitute row 0 */
+ s  = 1.0/r0[0];
+ r0[4] = s * (r0[4] - r1[4] * m0), r0[5] = s * (r0[5] - r1[5] * m0),
+ r0[6] = s * (r0[6] - r1[6] * m0), r0[7] = s * (r0[7] - r1[7] * m0);
+
+ MAT(out,0,0) = r0[4]; MAT(out,0,1) = r0[5],
+ MAT(out,0,2) = r0[6]; MAT(out,0,3) = r0[7],
+ MAT(out,1,0) = r1[4]; MAT(out,1,1) = r1[5],
+ MAT(out,1,2) = r1[6]; MAT(out,1,3) = r1[7],
+ MAT(out,2,0) = r2[4]; MAT(out,2,1) = r2[5],
+ MAT(out,2,2) = r2[6]; MAT(out,2,3) = r2[7],
+ MAT(out,3,0) = r3[4]; MAT(out,3,1) = r3[5],
+ MAT(out,3,2) = r3[6]; MAT(out,3,3) = r3[7]; 
+
+ return GL_TRUE;
+
+#undef MAT
+#undef SWAP_ROWS
+}
+
+
+
+/* projection du point (objx,objy,obz) sur l'ecran (winx,winy,winz) */
+GLint GLAPIENTRY gluProject(GLdouble objx,GLdouble objy,GLdouble objz,
+                          const GLdouble model[16],const GLdouble proj[16],
+                          const GLint viewport[4],
+                          GLdouble *winx,GLdouble *winy,GLdouble *winz)
+{
+    /* matrice de transformation */
+    GLdouble in[4],out[4];
+
+    /* initilise la matrice et le vecteur a transformer */
+    in[0]=objx; in[1]=objy; in[2]=objz; in[3]=1.0;
+    transform_point(out,model,in);
+    transform_point(in,proj,out);
+
+    /* d'ou le resultat normalise entre -1 et 1*/
+    if (in[3]==0.0)
+       return GL_FALSE;
+
+    in[0]/=in[3]; in[1]/=in[3]; in[2]/=in[3];
+
+    /* en coordonnees ecran */
+    *winx = viewport[0]+(1+in[0])*viewport[2]/2;
+    *winy = viewport[1]+(1+in[1])*viewport[3]/2;
+    /* entre 0 et 1 suivant z */
+    *winz = (1+in[2])/2;
+    return GL_TRUE;
+}
+
+
+
+/* transformation du point ecran (winx,winy,winz) en point objet */
+GLint GLAPIENTRY gluUnProject(GLdouble winx,GLdouble winy,GLdouble winz,
+                            const GLdouble model[16],const GLdouble proj[16],
+                            const GLint viewport[4],
+                            GLdouble *objx,GLdouble *objy,GLdouble *objz)
+{
+    /* matrice de transformation */
+    GLdouble m[16], A[16];
+    GLdouble in[4],out[4];
+
+    /* transformation coordonnees normalisees entre -1 et 1 */
+    in[0]=(winx-viewport[0])*2/viewport[2] - 1.0;
+    in[1]=(winy-viewport[1])*2/viewport[3] - 1.0;
+    in[2]=2*winz - 1.0;
+    in[3]=1.0;
+
+    /* calcul transformation inverse */
+    matmul(A,proj,model);
+    invert_matrix(A,m);
+
+    /* d'ou les coordonnees objets */
+    transform_point(out,m,in);
+    if (out[3]==0.0)
+       return GL_FALSE;
+    *objx=out[0]/out[3];
+    *objy=out[1]/out[3];
+    *objz=out[2]/out[3];
+    return GL_TRUE;
+}
+
diff --git a/src/glu/mesa/quadric.c b/src/glu/mesa/quadric.c
new file mode 100644 (file)
index 0000000..4698e79
--- /dev/null
@@ -0,0 +1,858 @@
+/* $Id: quadric.c,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * Copyright (C) 1995-1999  Brian Paul
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/*
+ * $Log: quadric.c,v $
+ * Revision 1.1  1999/08/19 00:55:42  jtg
+ * Initial revision
+ *
+ * Revision 1.19  1999/02/27 13:55:31  brianp
+ * fixed BeOS-related GLU typedef problems
+ *
+ * Revision 1.18  1999/01/03 03:23:15  brianp
+ * now using GLAPIENTRY and GLCALLBACK keywords (Ted Jump)
+ *
+ * Revision 1.17  1999/01/03 03:19:15  brianp
+ * rewrote some of gluCylinder
+ *
+ * Revision 1.16  1998/06/01 01:08:36  brianp
+ * small update for Next/OpenStep from Alexander Mai
+ *
+ * Revision 1.15  1998/03/15 18:28:54  brianp
+ * reimplemented gluDisk() point and line mode
+ *
+ * Revision 1.14  1998/03/15 18:14:17  brianp
+ * fixed a compiler cast warning
+ *
+ * Revision 1.13  1998/02/07 14:28:34  brianp
+ * another change to gluQuadricCallback(), this time for StormC compiler
+ *
+ * Revision 1.12  1998/02/05 00:43:19  brianp
+ * Yes, still another change to gluQuadricCallback()!
+ *
+ * Revision 1.11  1998/02/04 00:27:43  brianp
+ * yet another change to gluQuadricCallback()!
+ *
+ * Revision 1.10  1998/02/04 00:23:23  brianp
+ * fixed CALLBACK problem in gluQuadricCallback() (Stephane Rehel)
+ *
+ * Revision 1.9  1998/02/04 00:20:09  brianp
+ * added missing (int) in ErrorFunc cast
+ *
+ * Revision 1.8  1998/01/16 03:37:51  brianp
+ * fixed another assignment warning in gluQuadricCallback()
+ *
+ * Revision 1.7  1998/01/16 03:35:26  brianp
+ * fixed Windows compilation warnings (Theodore Jump)
+ *
+ * Revision 1.6  1997/10/29 02:02:20  brianp
+ * various MS Windows compiler changes (David Bucciarelli, v20 3dfx driver)
+ *
+ * Revision 1.5  1997/09/17 01:51:48  brianp
+ * changed glu*Callback() functions to match prototype in glu.h
+ *
+ * Revision 1.4  1997/07/24 01:28:44  brianp
+ * changed precompiled header symbol from PCH to PC_HEADER
+ *
+ * Revision 1.3  1997/05/28 02:29:38  brianp
+ * added support for precompiled headers (PCH), inserted APIENTRY keyword
+ *
+ * Revision 1.2  1997/03/12 02:15:38  brianp
+ * fixed problem in gluPartialDisk() reported by Kenneth H. Carpenter
+ *
+ * Revision 1.1  1996/09/27 01:19:39  brianp
+ * Initial revision
+ *
+ */
+
+
+/* TODO:
+ *   texture coordinate support
+ *   flip normals according to orientation
+ *   there's still some inside/outside orientation bugs in possibly all
+ *     but the sphere function
+ */
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "gluP.h"
+#endif
+
+
+
+#ifndef M_PI
+#  define M_PI (3.1415926)
+#endif
+
+
+/*
+ * Convert degrees to radians:
+ */
+#define DEG_TO_RAD(A)   ((A)*(M_PI/180.0))
+
+
+/*
+ * Sin and Cos for degree angles:
+ */
+#define SIND( A )   sin( (A)*(M_PI/180.0) )
+#define COSD( A)    cos( (A)*(M_PI/180.0) )
+
+
+/*
+ * Texture coordinates if texture flag is set
+ */
+#define TXTR_COORD(x,y)    if (qobj->TextureFlag) glTexCoord2f(x,y);
+
+
+
+struct GLUquadric {
+       GLenum  DrawStyle;              /* GLU_FILL, LINE, SILHOUETTE, or POINT */
+       GLenum Orientation;             /* GLU_INSIDE or GLU_OUTSIDE */
+       GLboolean TextureFlag;          /* Generate texture coords? */
+       GLenum Normals;         /* GLU_NONE, GLU_FLAT, or GLU_SMOOTH */
+       void (GLCALLBACK *ErrorFunc)(GLenum err);       /* Error handler callback function */
+};
+
+
+
+/*
+ * Process a GLU error.
+ */
+static void quadric_error( GLUquadricObj *qobj, GLenum error, const char *msg )
+{
+   /* Call the error call back function if any */
+   if (qobj->ErrorFunc) {
+      (*qobj->ErrorFunc)( error );
+   }
+   /* Print a message to stdout if MESA_DEBUG variable is defined */
+   if (getenv("MESA_DEBUG")) {
+      fprintf(stderr,"GLUError: %s: %s\n", (char*) gluErrorString(error), msg);
+   }
+}
+
+
+
+
+GLUquadricObj * GLAPIENTRY gluNewQuadric( void )
+{
+   GLUquadricObj *q;
+
+   q = (GLUquadricObj *) malloc( sizeof(struct GLUquadric) );
+   if (q) {
+      q->DrawStyle = GLU_FILL;
+      q->Orientation = GLU_OUTSIDE;
+      q->TextureFlag = GL_FALSE;
+      q->Normals = GLU_SMOOTH;
+      q->ErrorFunc = NULL;
+   }
+   return q;
+}
+
+
+
+void GLAPIENTRY gluDeleteQuadric( GLUquadricObj *state )
+{
+   if (state) {
+      free( (void *) state );
+   }
+}
+
+
+
+/*
+ * Set the drawing style to be GLU_FILL, GLU_LINE, GLU_SILHOUETTE,
+ * or GLU_POINT.
+ */
+void GLAPIENTRY gluQuadricDrawStyle( GLUquadricObj *quadObject, GLenum drawStyle )
+{
+   if (quadObject && (drawStyle==GLU_FILL || drawStyle==GLU_LINE
+                  || drawStyle==GLU_SILHOUETTE || drawStyle==GLU_POINT)) {
+      quadObject->DrawStyle = drawStyle;
+   }
+   else {
+      quadric_error( quadObject, GLU_INVALID_ENUM, "qluQuadricDrawStyle" );
+   }
+}
+
+
+
+/*
+ * Set the orientation to GLU_INSIDE or GLU_OUTSIDE.
+ */
+void GLAPIENTRY gluQuadricOrientation( GLUquadricObj *quadObject,
+                                     GLenum orientation )
+{
+   if (quadObject && (orientation==GLU_INSIDE || orientation==GLU_OUTSIDE)) {
+      quadObject->Orientation = orientation;
+   }
+   else {
+      quadric_error( quadObject, GLU_INVALID_ENUM, "qluQuadricOrientation" );
+   }
+}
+
+
+
+/*
+ * Set the error handler callback function.
+ */
+void GLAPIENTRY gluQuadricCallback( GLUquadricObj *qobj,
+                                  GLenum which, void (GLCALLBACK *fn)() )
+{
+   /*
+    * UGH, this is a mess!  I thought ANSI was a standard.
+    */
+   if (qobj && which==GLU_ERROR) {
+#ifdef __CYGWIN32__
+      qobj->ErrorFunc = (void(*)(int))fn;
+#elif defined(OPENSTEP)
+      qobj->ErrorFunc = (void(*)(GLenum))fn;
+#elif defined(_WIN32)
+      qobj->ErrorFunc = (void(GLCALLBACK*)(int))fn;
+#elif defined(__STORM__)
+      qobj->ErrorFunc = (void(GLCALLBACK*)(GLenum))fn;
+#elif defined(__BEOS__)
+      qobj->ErrorFunc = (void(*)(GLenum))fn;
+#else
+      qobj->ErrorFunc = (void(GLCALLBACK*)())fn;
+#endif
+   }
+}
+
+
+void GLAPIENTRY gluQuadricNormals( GLUquadricObj *quadObject, GLenum normals )
+{
+   if (quadObject
+         && (normals==GLU_NONE || normals==GLU_FLAT || normals==GLU_SMOOTH)) {
+      quadObject->Normals = normals;
+   }
+}
+
+
+void GLAPIENTRY gluQuadricTexture( GLUquadricObj *quadObject,
+                                 GLboolean textureCoords )
+{
+   if (quadObject) {
+      quadObject->TextureFlag = textureCoords;
+   }
+}
+
+
+
+
+/*
+ * Call glNormal3f after scaling normal to unit length.
+ */
+static void normal3f( GLfloat x, GLfloat y, GLfloat z )
+{
+   GLdouble mag;
+
+   mag = sqrt( x*x + y*y + z*z );
+   if (mag>0.00001F) {
+      x /= mag;
+      y /= mag;
+      z /= mag;
+   }
+   glNormal3f( x, y, z );
+}
+
+
+
+void GLAPIENTRY gluCylinder( GLUquadricObj *qobj,
+                           GLdouble baseRadius, GLdouble topRadius,
+                           GLdouble height, GLint slices, GLint stacks )
+{
+   GLdouble da, r, dr, dz;
+   GLfloat x, y, z, nz, nsign;
+   GLint i, j;
+
+   if (qobj->Orientation==GLU_INSIDE) {
+      nsign = -1.0;
+   }
+   else {
+      nsign = 1.0;
+   }
+
+   da = 2.0*M_PI / slices;
+   dr = (topRadius-baseRadius) / stacks;
+   dz = height / stacks;
+   nz = (baseRadius-topRadius) / height;  /* Z component of normal vectors */
+
+   if (qobj->DrawStyle==GLU_POINT) {
+      glBegin( GL_POINTS );
+      for (i=0;i<slices;i++) {
+        x = cos(i*da);
+        y = sin(i*da);
+        normal3f( x*nsign, y*nsign, nz*nsign );
+
+        z = 0.0;
+        r = baseRadius;
+        for (j=0;j<=stacks;j++) {
+           glVertex3f( x*r, y*r, z );
+           z += dz;
+           r += dr;
+        }
+      }
+      glEnd();
+   }
+   else if (qobj->DrawStyle==GLU_LINE || qobj->DrawStyle==GLU_SILHOUETTE) {
+      /* Draw rings */
+      if (qobj->DrawStyle==GLU_LINE) {
+        z = 0.0;
+        r = baseRadius;
+        for (j=0;j<=stacks;j++) {
+           glBegin( GL_LINE_LOOP );
+           for (i=0;i<slices;i++) {
+              x = cos(i*da);
+              y = sin(i*da);
+              normal3f( x*nsign, y*nsign, nz*nsign );
+              glVertex3f( x*r, y*r, z );
+           }
+           glEnd();
+           z += dz;
+           r += dr;
+        }
+      }
+      else {
+        /* draw one ring at each end */
+        if (baseRadius!=0.0) {
+           glBegin( GL_LINE_LOOP );
+           for (i=0;i<slices;i++) {
+              x = cos(i*da);
+              y = sin(i*da);
+              normal3f( x*nsign, y*nsign, nz*nsign );
+              glVertex3f( x*baseRadius, y*baseRadius, 0.0 );
+           }
+           glEnd();
+           glBegin( GL_LINE_LOOP );
+           for (i=0;i<slices;i++) {
+              x = cos(i*da);
+              y = sin(i*da);
+              normal3f( x*nsign, y*nsign, nz*nsign );
+              glVertex3f( x*topRadius, y*topRadius, height );
+           }
+           glEnd();
+        }
+      }
+      /* draw length lines */
+      glBegin( GL_LINES );
+      for (i=0;i<slices;i++) {
+        x = cos(i*da);
+        y = sin(i*da);
+        normal3f( x*nsign, y*nsign, nz*nsign );
+        glVertex3f( x*baseRadius, y*baseRadius, 0.0 );
+        glVertex3f( x*topRadius, y*topRadius, height );
+      }
+      glEnd();
+   }
+   else if (qobj->DrawStyle==GLU_FILL) {
+      GLfloat ds = 1.0 / slices;
+      GLfloat dt = 1.0 / stacks;
+      GLfloat t = 0.0;
+      z = 0.0;
+      r = baseRadius;
+      for (j=0;j<stacks;j++) {
+         GLfloat s = 0.0;
+         glBegin( GL_QUAD_STRIP );
+         for (i=0;i<=slices;i++) {
+            GLfloat x, y;
+            if (i == slices) {
+               x = sin(0);
+               y = cos(0);
+            }
+            else {
+               x = sin(i * da);
+               y = cos(i * da);
+            }
+            if (nsign==1.0) {
+               normal3f( x*nsign, y*nsign, nz*nsign );
+               TXTR_COORD(s, t);
+               glVertex3f( x * r, y * r, z );
+               normal3f( x*nsign, y*nsign, nz*nsign );
+               TXTR_COORD(s, t + dt);
+               glVertex3f( x * (r + dr), y * (r + dr), z + dz);
+            }
+            else {
+               normal3f( x*nsign, y*nsign, nz*nsign );
+               TXTR_COORD(s, t);
+               glVertex3f( x * r, y * r, z );
+               normal3f( x*nsign, y*nsign, nz*nsign );
+               TXTR_COORD(s, t + dt);
+               glVertex3f( x * (r + dr), y * (r + dr), z + dz);
+            }
+            s += ds;
+         } /* for slices */
+         glEnd();
+         r += dr;
+         t += dt;
+         z += dz;
+      } /* for stacks */
+   }
+}
+
+
+
+
+
+void GLAPIENTRY gluSphere( GLUquadricObj *qobj,
+                         GLdouble radius, GLint slices, GLint stacks )
+{
+   GLfloat rho, drho, theta, dtheta;
+   GLfloat x, y, z;
+   GLfloat s, t, ds, dt;
+   GLint i, j, imin, imax;
+   GLboolean normals;
+   GLfloat nsign;
+
+   if (qobj->Normals==GLU_NONE) {
+      normals = GL_FALSE;
+   }
+   else {
+      normals = GL_TRUE;
+   }
+   if (qobj->Orientation==GLU_INSIDE) {
+      nsign = -1.0;
+   }
+   else {
+      nsign = 1.0;
+   }
+
+   drho = M_PI / (GLfloat) stacks;
+   dtheta = 2.0 * M_PI / (GLfloat) slices;
+
+   /* texturing: s goes from 0.0/0.25/0.5/0.75/1.0 at +y/+x/-y/-x/+y axis */
+   /* t goes from -1.0/+1.0 at z = -radius/+radius (linear along longitudes) */
+   /* cannot use triangle fan on texturing (s coord. at top/bottom tip varies) */
+
+   if (qobj->DrawStyle==GLU_FILL) {
+     if (!qobj->TextureFlag) {
+      /* draw +Z end as a triangle fan */
+      glBegin( GL_TRIANGLE_FAN );
+      glNormal3f( 0.0, 0.0, 1.0 );
+      TXTR_COORD(0.5,1.0);
+      glVertex3f( 0.0, 0.0, nsign * radius );
+      for (j=0;j<=slices;j++) {
+        theta = (j==slices) ? 0.0 : j * dtheta;
+        x = -sin(theta) * sin(drho);
+        y = cos(theta) * sin(drho);
+        z = nsign * cos(drho);
+        if (normals)  glNormal3f( x*nsign, y*nsign, z*nsign );
+        glVertex3f( x*radius, y*radius, z*radius );
+      }
+      glEnd();
+     }
+
+      ds = 1.0 / slices;
+      dt = 1.0 / stacks;
+      t = 1.0;  /* because loop now runs from 0 */
+      if (qobj->TextureFlag) {
+        imin = 0;
+        imax = stacks;
+      }
+      else {
+        imin = 1;
+        imax = stacks-1;
+      }
+
+      /* draw intermediate stacks as quad strips */
+      for (i=imin;i<imax;i++) {
+        rho = i * drho;
+        glBegin( GL_QUAD_STRIP );
+         s = 0.0;
+        for (j=0;j<=slices;j++) {
+           theta = (j==slices) ? 0.0 : j * dtheta;
+           x = -sin(theta) * sin(rho);
+           y = cos(theta) * sin(rho);
+           z = nsign * cos(rho);
+           if (normals)  glNormal3f( x*nsign, y*nsign, z*nsign );
+           TXTR_COORD(s,t);
+           glVertex3f( x*radius, y*radius, z*radius );
+           x = -sin(theta) * sin(rho+drho);
+           y = cos(theta) * sin(rho+drho);
+           z = nsign * cos(rho+drho);
+           if (normals)  glNormal3f( x*nsign, y*nsign, z*nsign );
+           TXTR_COORD(s,t-dt);
+            s += ds;
+           glVertex3f( x*radius, y*radius, z*radius );
+        }
+        glEnd();
+        t -= dt;
+      }
+
+     if (!qobj->TextureFlag) {
+      /* draw -Z end as a triangle fan */
+      glBegin( GL_TRIANGLE_FAN );
+      glNormal3f( 0.0, 0.0, -1.0 );
+      TXTR_COORD(0.5,0.0);
+      glVertex3f( 0.0, 0.0, -radius*nsign );
+      rho = M_PI - drho;
+      s = 1.0;
+      t = dt;
+      for (j=slices;j>=0;j--) {
+        theta = (j==slices) ? 0.0 : j * dtheta;
+        x = -sin(theta) * sin(rho);
+        y = cos(theta) * sin(rho);
+        z = nsign * cos(rho);
+        if (normals)  glNormal3f( x*nsign, y*nsign, z*nsign );
+        TXTR_COORD(s,t);
+         s -= ds;
+        glVertex3f( x*radius, y*radius, z*radius );
+      }
+      glEnd();
+     }
+   }
+   else if (qobj->DrawStyle==GLU_LINE || qobj->DrawStyle==GLU_SILHOUETTE) {
+      /* draw stack lines */
+      for (i=1;i<stacks;i++) {  /* stack line at i==stacks-1 was missing here */
+        rho = i * drho;
+        glBegin( GL_LINE_LOOP );
+        for (j=0;j<slices;j++) {
+           theta = j * dtheta;
+           x = cos(theta) * sin(rho);
+           y = sin(theta) * sin(rho);
+           z = cos(rho);
+           if (normals)  glNormal3f( x*nsign, y*nsign, z*nsign );
+           glVertex3f( x*radius, y*radius, z*radius );
+        }
+        glEnd();
+      }
+      /* draw slice lines */
+      for (j=0;j<slices;j++) {
+        theta = j * dtheta;
+        glBegin( GL_LINE_STRIP );
+        for (i=0;i<=stacks;i++) {
+           rho = i * drho;
+           x = cos(theta) * sin(rho);
+           y = sin(theta) * sin(rho);
+           z = cos(rho);
+           if (normals)  glNormal3f( x*nsign, y*nsign, z*nsign );
+           glVertex3f( x*radius, y*radius, z*radius );
+        }
+        glEnd();
+      }
+   }
+   else if (qobj->DrawStyle==GLU_POINT) {
+      /* top and bottom-most points */
+      glBegin( GL_POINTS );
+      if (normals)  glNormal3f( 0.0, 0.0, nsign );
+      glVertex3d( 0.0, 0.0, radius );
+      if (normals)  glNormal3f( 0.0, 0.0, -nsign );
+      glVertex3d( 0.0, 0.0, -radius );
+
+      /* loop over stacks */
+      for (i=1;i<stacks-1;i++) {
+        rho = i * drho;
+        for (j=0;j<slices;j++) {
+           theta = j * dtheta;
+           x = cos(theta) * sin(rho);
+           y = sin(theta) * sin(rho);
+           z = cos(rho);
+           if (normals)  glNormal3f( x*nsign, y*nsign, z*nsign );
+           glVertex3f( x*radius, y*radius, z*radius );
+        }
+      }
+      glEnd();
+   }
+
+}
+
+
+
+void GLAPIENTRY gluDisk( GLUquadricObj *qobj,
+                       GLdouble innerRadius, GLdouble outerRadius,
+                       GLint slices, GLint loops )
+{
+   GLfloat da, dr;
+#if 0
+   GLdouble a, da;
+   GLfloat r, dr;
+   GLfloat x, y;
+   GLfloat r1, r2, dtc;
+   GLint s, l;
+#endif
+
+   /* Normal vectors */
+   if (qobj->Normals!=GLU_NONE) {
+      if (qobj->Orientation==GLU_OUTSIDE) {
+        glNormal3f( 0.0, 0.0, +1.0 );
+      }
+      else {
+        glNormal3f( 0.0, 0.0, -1.0 );
+      }
+   }
+
+   da = 2.0*M_PI / slices;
+   dr = (outerRadius-innerRadius) / (GLfloat) loops;
+
+   switch (qobj->DrawStyle) {
+      case GLU_FILL:
+      {
+         /* texture of a gluDisk is a cut out of the texture unit square
+          * x, y in [-outerRadius, +outerRadius]; s, t in [0, 1]
+          * (linear mapping)
+          */
+         GLfloat dtc = 2.0f * outerRadius;
+         GLfloat sa,ca;
+         GLfloat r1 = innerRadius;
+         GLint l;
+         for (l=0; l<loops; l++) {
+           GLfloat r2 = r1 + dr;
+           if (qobj->Orientation==GLU_OUTSIDE) {
+               GLint s;
+              glBegin( GL_QUAD_STRIP );
+              for (s=0;s<=slices;s++) {
+                  GLfloat a;
+                 if (s==slices) a = 0.0;
+                 else  a = s * da;
+                 sa = sin(a); ca = cos(a);
+                  TXTR_COORD(0.5+sa*r2/dtc,0.5+ca*r2/dtc);
+                  glVertex2f( r2*sa, r2*ca );
+                  TXTR_COORD(0.5+sa*r1/dtc,0.5+ca*r1/dtc);
+                  glVertex2f( r1*sa, r1*ca );
+              }
+              glEnd();
+           }
+           else {
+               GLint s;
+              glBegin( GL_QUAD_STRIP );
+              for (s=slices;s>=0;s--) {
+                  GLfloat a;
+                 if (s==slices) a = 0.0;
+                 else  a = s * da;
+                 sa = sin(a); ca = cos(a);
+                  TXTR_COORD(0.5-sa*r2/dtc,0.5+ca*r2/dtc);
+                  glVertex2f( r2*sa, r2*ca );
+                  TXTR_COORD(0.5-sa*r1/dtc,0.5+ca*r1/dtc);
+                  glVertex2f( r1*sa, r1*ca );
+              }
+              glEnd();
+           }
+           r1 = r2;
+        }
+         break;
+      }
+      case GLU_LINE:
+      {
+         GLint l, s;
+        /* draw loops */
+         for (l=0; l<=loops; l++) {
+            GLfloat r = innerRadius + l * dr;
+           glBegin( GL_LINE_LOOP );
+            for (s=0; s<slices; s++) {
+               GLfloat a = s * da;
+              glVertex2f( r*sin(a), r*cos(a) );
+            }
+           glEnd();
+        }
+        /* draw spokes */
+         for (s=0; s<slices; s++) {
+            GLfloat a = s * da;
+           GLfloat x = sin(a);
+           GLfloat y = cos(a);
+           glBegin( GL_LINE_STRIP );
+            for (l=0; l<=loops; l++) {
+               GLfloat r = innerRadius + l * dr;
+              glVertex2f( r*x, r*y );
+           }
+           glEnd();
+        }
+        break;
+      }
+      case GLU_POINT:
+      {
+         GLint s;
+        glBegin( GL_POINTS );
+         for (s=0; s<slices; s++) {
+            GLfloat a = s * da;
+           GLfloat x = sin(a);
+           GLfloat y = cos(a);
+            GLint l;
+            for (l=0; l<=loops; l++) {
+               GLfloat r = innerRadius * l * dr;
+              glVertex2f( r*x, r*y );
+           }
+        }
+        glEnd();
+        break;
+      }
+      case GLU_SILHOUETTE:
+      {
+        if (innerRadius!=0.0) {
+            GLfloat a;
+           glBegin( GL_LINE_LOOP );
+           for (a=0.0; a<2.0*M_PI; a+=da) {
+              GLfloat x = innerRadius * sin(a);
+              GLfloat y = innerRadius * cos(a);
+              glVertex2f( x, y );
+           }
+           glEnd();
+        }
+         {
+            GLfloat a;
+            glBegin( GL_LINE_LOOP );
+            for (a=0; a<2.0*M_PI; a+=da) {
+               GLfloat x = outerRadius * sin(a);
+               GLfloat y = outerRadius * cos(a);
+               glVertex2f( x, y );
+            }
+            glEnd();
+         }
+        break;
+      }
+      default:
+         abort();
+   }
+}
+
+
+
+void GLAPIENTRY gluPartialDisk( GLUquadricObj *qobj, GLdouble innerRadius,
+                              GLdouble outerRadius, GLint slices, GLint loops,
+                              GLdouble startAngle, GLdouble sweepAngle )
+{
+   if (qobj->Normals!=GLU_NONE) {
+      if (qobj->Orientation==GLU_OUTSIDE) {
+        glNormal3f( 0.0, 0.0, +1.0 );
+      }
+      else {
+        glNormal3f( 0.0, 0.0, -1.0 );
+      }
+   }
+
+   if (qobj->DrawStyle==GLU_POINT) {
+      GLint loop, slice;
+      GLdouble radius, delta_radius;
+      GLdouble angle, delta_angle;
+      delta_radius = (outerRadius - innerRadius) / (loops-1);
+      delta_angle = DEG_TO_RAD((sweepAngle) / (slices-1));
+      glBegin( GL_POINTS );
+      radius = innerRadius;
+      for (loop=0; loop<loops; loop++) {
+        angle = DEG_TO_RAD(startAngle);
+        for (slice=0; slice<slices; slice++) {
+           glVertex2d( radius * sin(angle), radius * cos(angle) );
+           angle += delta_angle;
+        }
+        radius += delta_radius;
+      }
+      glEnd();
+   }
+   else if (qobj->DrawStyle==GLU_LINE) {
+      GLint loop, slice;
+      GLdouble radius, delta_radius;
+      GLdouble angle, delta_angle;
+      delta_radius = (outerRadius - innerRadius) / loops;
+      delta_angle = DEG_TO_RAD(sweepAngle / slices);
+      /* draw rings */
+      radius = innerRadius;
+      for (loop=0; loop<loops; loop++) {
+        angle = DEG_TO_RAD(startAngle);
+        glBegin( GL_LINE_STRIP );
+        for (slice=0; slice<slices; slice++) {
+           glVertex2d( radius * sin(angle), radius * cos(angle) );
+           angle += delta_angle;
+        }
+        glEnd();
+        radius += delta_radius;
+      }
+      /* draw spokes */
+      angle = DEG_TO_RAD(startAngle);
+      for (slice=0; slice<slices; slice++) {
+        radius = innerRadius;
+        glBegin( GL_LINE_STRIP );
+        for (loop=0; loop<loops; loop++) {
+           glVertex2d( radius * sin(angle), radius * cos(angle) );
+           radius += delta_radius;
+        }
+        glEnd();
+        angle += delta_angle;
+      }
+   }
+   else if (qobj->DrawStyle==GLU_SILHOUETTE) {
+      GLint slice;
+      GLdouble angle, delta_angle;
+      delta_angle = DEG_TO_RAD(sweepAngle / slices);
+      /* draw outer ring */
+      glBegin( GL_LINE_STRIP );
+      angle = DEG_TO_RAD(startAngle);
+      for (slice=0; slice<=slices; slice++) {
+        glVertex2d( outerRadius * sin(angle), outerRadius * cos(angle) );
+        angle += delta_angle;
+      }
+      glEnd();
+      /* draw inner ring */
+      if (innerRadius>0.0) {
+        glBegin( GL_LINE_STRIP );
+        angle = DEG_TO_RAD(startAngle);
+        for (slice=0; slice<slices; slice++) {
+           glVertex2d( innerRadius * sin(angle), innerRadius * cos(angle) );
+           angle += delta_angle;
+        }
+        glEnd();
+      }
+      /* draw spokes */
+      if (sweepAngle<360.0) {
+        GLdouble stopAngle = startAngle + sweepAngle;
+        glBegin( GL_LINES );
+        glVertex2d( innerRadius*SIND(startAngle), innerRadius*COSD(startAngle) );
+        glVertex2d( outerRadius*SIND(startAngle), outerRadius*COSD(startAngle) );
+        glVertex2d( innerRadius*SIND(stopAngle), innerRadius*COSD(stopAngle) );
+        glVertex2d( outerRadius*SIND(stopAngle), outerRadius*COSD(stopAngle) );
+        glEnd();
+      }
+   }
+   else if (qobj->DrawStyle==GLU_FILL) {
+      GLint loop, slice;
+      GLdouble radius, delta_radius;
+      GLdouble angle, delta_angle;
+      delta_radius = (outerRadius - innerRadius) / loops;
+      delta_angle = DEG_TO_RAD(sweepAngle / slices);
+      radius = innerRadius;
+      for (loop=0; loop<loops; loop++) {
+        glBegin( GL_QUAD_STRIP );
+        angle = DEG_TO_RAD(startAngle);
+        for (slice=0; slice<slices; slice++) {
+           if (qobj->Orientation==GLU_OUTSIDE) {
+              glVertex2d( (radius+delta_radius)*sin(angle),
+                          (radius+delta_radius)*cos(angle) );
+              glVertex2d( radius * sin(angle), radius * cos(angle) );
+           }
+           else {
+              glVertex2d( radius * sin(angle), radius * cos(angle) );
+              glVertex2d( (radius+delta_radius)*sin(angle),
+                          (radius+delta_radius)*cos(angle) );
+           }
+           angle += delta_angle;
+        }
+        glEnd();
+        radius += delta_radius;
+      }
+   }
+}
+
+
+
diff --git a/src/glu/mesa/tess.c b/src/glu/mesa/tess.c
new file mode 100644 (file)
index 0000000..c773fba
--- /dev/null
@@ -0,0 +1,369 @@
+/* $Id: tess.c,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * Copyright (C) 1995-1999  Brian Paul
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/*
+ * $Log: tess.c,v $
+ * Revision 1.1  1999/08/19 00:55:42  jtg
+ * Initial revision
+ *
+ * Revision 1.11  1999/02/27 13:55:31  brianp
+ * fixed BeOS-related GLU typedef problems
+ *
+ * Revision 1.10  1999/01/03 03:23:15  brianp
+ * now using GLAPIENTRY and GLCALLBACK keywords (Ted Jump)
+ *
+ * Revision 1.9  1998/06/01 01:10:29  brianp
+ * small update for Next/OpenStep from Alexander Mai
+ *
+ * Revision 1.8  1998/02/04 00:27:58  brianp
+ * cygnus changes from Stephane Rehel
+ *
+ * Revision 1.7  1998/01/16 03:35:26  brianp
+ * fixed Windows compilation warnings (Theodore Jump)
+ *
+ * Revision 1.6  1997/09/17 01:51:48  brianp
+ * changed glu*Callback() functions to match prototype in glu.h
+ *
+ * Revision 1.5  1997/07/24 01:28:44  brianp
+ * changed precompiled header symbol from PCH to PC_HEADER
+ *
+ * Revision 1.4  1997/05/28 02:29:38  brianp
+ * added support for precompiled headers (PCH), inserted APIENTRY keyword
+ *
+ * Revision 1.3  1996/11/12 01:23:02  brianp
+ * added test to prevent free(vertex) when vertex==NULL in delete_contours()
+ *
+ * Revision 1.2  1996/10/22 22:57:19  brianp
+ * better error handling in gluBegin/EndPolygon() from Erich Eder
+ *
+ * Revision 1.1  1996/09/27 01:19:39  brianp
+ * Initial revision
+ *
+ */
+
+
+/*
+ * This file is part of the polygon tesselation code contributed by
+ * Bogdan Sikorski
+ */
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <math.h>
+#include <stdlib.h>
+#include "tess.h"
+#endif
+
+
+/*
+ * This is ugly, but seems the easiest way to do things to make the
+ * code work under YellowBox for Windows
+ */
+#if defined(OPENSTEP) && defined(GLCALLBACK)
+#undef GLCALLBACK
+#define GLCALLBACK
+#endif
+
+
+extern void tess_test_polygon(GLUtriangulatorObj *);
+extern void tess_find_contour_hierarchies(GLUtriangulatorObj *);
+extern void tess_handle_holes(GLUtriangulatorObj *);
+extern void tess_tesselate(GLUtriangulatorObj *);
+extern void tess_tesselate_with_edge_flag(GLUtriangulatorObj *);
+static void delete_contours(GLUtriangulatorObj *);
+
+#ifdef __CYGWIN32__
+#define _CALLBACK
+#else
+#define _CALLBACK GLCALLBACK
+#endif
+
+void init_callbacks(tess_callbacks *callbacks)
+{
+   callbacks->begin = ( void (_CALLBACK*)(GLenum) ) 0;
+   callbacks->edgeFlag = ( void (_CALLBACK*)(GLboolean) ) 0;
+   callbacks->vertex = ( void (_CALLBACK*)(void*) ) 0;
+   callbacks->end = ( void (_CALLBACK*)(void) ) 0;
+   callbacks->error = ( void (_CALLBACK*)(GLenum) ) 0;
+}
+
+void tess_call_user_error(GLUtriangulatorObj *tobj, GLenum gluerr)
+{
+   if(tobj->error==GLU_NO_ERROR)
+      tobj->error=gluerr;
+   if(tobj->callbacks.error!=NULL)
+      (tobj->callbacks.error)(gluerr);
+}
+
+GLUtriangulatorObj* GLAPIENTRY gluNewTess( void )
+{
+   GLUtriangulatorObj *tobj;
+   tobj = (GLUtriangulatorObj *) malloc(sizeof(struct GLUtesselator));
+   if (!tobj)
+      return NULL;
+   tobj->contours=tobj->last_contour=NULL;
+   init_callbacks(&tobj->callbacks);
+   tobj->error=GLU_NO_ERROR;
+   tobj->current_polygon=NULL;
+   tobj->contour_cnt=0;
+   return tobj;
+}
+
+
+void GLAPIENTRY gluTessCallback( GLUtriangulatorObj *tobj, GLenum which,
+                               void (GLCALLBACK *fn)() )
+{
+       switch(which)
+       {
+               case GLU_BEGIN:
+                       tobj->callbacks.begin = (void (_CALLBACK*)(GLenum)) fn;
+                       break;
+               case GLU_EDGE_FLAG:
+                       tobj->callbacks.edgeFlag = (void (_CALLBACK*)(GLboolean)) fn;
+                       break;
+               case GLU_VERTEX:
+                       tobj->callbacks.vertex = (void (_CALLBACK*)(void *)) fn;
+                       break;
+               case GLU_END:
+                       tobj->callbacks.end = (void (_CALLBACK*)(void)) fn;
+                       break;
+               case GLU_ERROR:
+                       tobj->callbacks.error = (void (_CALLBACK*)(GLenum)) fn;
+                       break;
+               default:
+                       tobj->error=GLU_INVALID_ENUM;
+                       break;
+       }
+}
+
+
+
+void GLAPIENTRY gluDeleteTess( GLUtriangulatorObj *tobj )
+{
+       if(tobj->error==GLU_NO_ERROR && tobj->contour_cnt)
+               /* was gluEndPolygon called? */
+               tess_call_user_error(tobj,GLU_TESS_ERROR1);
+       /* delete all internal structures */
+       delete_contours(tobj);
+       free(tobj);
+}
+
+
+void GLAPIENTRY gluBeginPolygon( GLUtriangulatorObj *tobj )
+{
+/*
+       if(tobj->error!=GLU_NO_ERROR)
+               return;
+*/
+        tobj->error = GLU_NO_ERROR;
+       if(tobj->current_polygon!=NULL)
+       {
+               /* gluEndPolygon was not called */
+               tess_call_user_error(tobj,GLU_TESS_ERROR1);
+               /* delete all internal structures */
+               delete_contours(tobj);
+       }
+       else
+       {
+               if((tobj->current_polygon=
+                       (tess_polygon *)malloc(sizeof(tess_polygon)))==NULL)
+               {
+                       tess_call_user_error(tobj,GLU_OUT_OF_MEMORY);
+                       return;
+               }
+               tobj->current_polygon->vertex_cnt=0;
+               tobj->current_polygon->vertices=
+                       tobj->current_polygon->last_vertex=NULL;
+       }
+}
+
+
+void GLAPIENTRY gluEndPolygon( GLUtriangulatorObj *tobj )
+{
+       /*tess_contour *contour_ptr;*/
+
+       /* there was an error */
+       if(tobj->error!=GLU_NO_ERROR) goto end;
+
+       /* check if gluBeginPolygon was called */
+       if(tobj->current_polygon==NULL)
+       {
+               tess_call_user_error(tobj,GLU_TESS_ERROR2);
+               return;
+       }
+       tess_test_polygon(tobj);
+       /* there was an error */
+       if(tobj->error!=GLU_NO_ERROR) goto end;
+
+       /* any real contours? */
+       if(tobj->contour_cnt==0)
+       {
+               /* delete all internal structures */
+               delete_contours(tobj);
+               return;
+       }
+       tess_find_contour_hierarchies(tobj);
+       /* there was an error */
+       if(tobj->error!=GLU_NO_ERROR) goto end;
+
+       tess_handle_holes(tobj);
+       /* there was an error */
+       if(tobj->error!=GLU_NO_ERROR) goto end;
+
+       /* if no callbacks, nothing to do */
+       if(tobj->callbacks.begin!=NULL && tobj->callbacks.vertex!=NULL &&
+               tobj->callbacks.end!=NULL)
+       {
+               if(tobj->callbacks.edgeFlag==NULL)
+                       tess_tesselate(tobj);
+               else
+                       tess_tesselate_with_edge_flag(tobj);
+       }
+
+end:
+       /* delete all internal structures */
+       delete_contours(tobj);
+}
+
+
+void GLAPIENTRY gluNextContour( GLUtriangulatorObj *tobj, GLenum type )
+{
+       if(tobj->error!=GLU_NO_ERROR)
+               return;
+       if(tobj->current_polygon==NULL)
+       {
+               tess_call_user_error(tobj,GLU_TESS_ERROR2);
+               return;
+       }
+       /* first contour? */
+       if(tobj->current_polygon->vertex_cnt)
+               tess_test_polygon(tobj);
+}
+
+
+void GLAPIENTRY gluTessVertex( GLUtriangulatorObj *tobj, GLdouble v[3], void *data )
+{
+       tess_polygon *polygon=tobj->current_polygon;
+       tess_vertex *last_vertex_ptr;
+
+       if(tobj->error!=GLU_NO_ERROR)
+               return;
+       if(polygon==NULL)
+       {
+               tess_call_user_error(tobj,GLU_TESS_ERROR2);
+               return;
+       }
+       last_vertex_ptr=polygon->last_vertex;
+       if(last_vertex_ptr==NULL)
+       {
+               if((last_vertex_ptr=(tess_vertex *)
+                       malloc(sizeof(tess_vertex)))==NULL)
+               {
+                       tess_call_user_error(tobj,GLU_OUT_OF_MEMORY);
+                       return;
+               }
+               polygon->vertices=last_vertex_ptr;
+               polygon->last_vertex=last_vertex_ptr;
+               last_vertex_ptr->data=data;
+               last_vertex_ptr->location[0]=v[0];
+               last_vertex_ptr->location[1]=v[1];
+               last_vertex_ptr->location[2]=v[2];
+               last_vertex_ptr->next=NULL;
+               last_vertex_ptr->previous=NULL;
+               ++(polygon->vertex_cnt);
+       }
+       else
+       {
+               tess_vertex *vertex_ptr;
+
+               /* same point twice? */
+               if(fabs(last_vertex_ptr->location[0]-v[0]) < EPSILON &&
+                       fabs(last_vertex_ptr->location[1]-v[1]) < EPSILON &&
+                       fabs(last_vertex_ptr->location[2]-v[2]) < EPSILON)
+               {
+                       tess_call_user_error(tobj,GLU_TESS_ERROR6);
+                       return;
+               }
+               if((vertex_ptr=(tess_vertex *)
+                       malloc(sizeof(tess_vertex)))==NULL)
+               {
+                       tess_call_user_error(tobj,GLU_OUT_OF_MEMORY);
+                       return;
+               }
+               vertex_ptr->data=data;
+               vertex_ptr->location[0]=v[0];
+               vertex_ptr->location[1]=v[1];
+               vertex_ptr->location[2]=v[2];
+               vertex_ptr->next=NULL;
+               vertex_ptr->previous=last_vertex_ptr;
+               ++(polygon->vertex_cnt);
+               last_vertex_ptr->next=vertex_ptr;
+               polygon->last_vertex=vertex_ptr;
+       }
+}
+
+
+static void delete_contours(GLUtriangulatorObj *tobj)
+{
+       tess_polygon *polygon=tobj->current_polygon;
+       tess_contour *contour,*contour_tmp;
+       tess_vertex *vertex,*vertex_tmp;
+
+       /* remove current_polygon list - if exists due to detected error */
+       if(polygon!=NULL)
+       {
+               if (polygon->vertices)
+               {
+                       for(vertex=polygon->vertices;vertex!=polygon->last_vertex;)
+                       {
+                               vertex_tmp=vertex->next;
+                               free(vertex);
+                               vertex=vertex_tmp;
+                       }
+                       free(vertex);
+               }
+               free(polygon);
+               tobj->current_polygon=NULL;
+       }
+       /* remove all contour data */
+       for(contour=tobj->contours;contour!=NULL;)
+       {
+               for(vertex=contour->vertices;vertex!=contour->last_vertex;)
+               {
+                       vertex_tmp=vertex->next;
+                       free(vertex);
+                       vertex=vertex_tmp;
+               }
+               free(vertex);
+               contour_tmp=contour->next;
+               free(contour);
+               contour=contour_tmp;
+       }
+       tobj->contours=tobj->last_contour=NULL;
+       tobj->contour_cnt=0;
+}
+
+
+
diff --git a/src/glu/mesa/tess.h b/src/glu/mesa/tess.h
new file mode 100644 (file)
index 0000000..53d673c
--- /dev/null
@@ -0,0 +1,121 @@
+/* $Id: tess.h,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * Copyright (C) 1995-1998  Brian Paul
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/*
+ * $Log: tess.h,v $
+ * Revision 1.1  1999/08/19 00:55:42  jtg
+ * Initial revision
+ *
+ * Revision 1.5  1999/02/27 13:55:31  brianp
+ * fixed BeOS-related GLU typedef problems
+ *
+ * Revision 1.4  1999/01/03 03:23:15  brianp
+ * now using GLAPIENTRY and GLCALLBACK keywords (Ted Jump)
+ *
+ * Revision 1.3  1997/10/29 02:02:20  brianp
+ * various MS Windows compiler changes (David Bucciarelli, v20 3dfx driver)
+ *
+ * Revision 1.2  1997/05/24 13:30:58  brianp
+ * added TESS_H multi-inclusion prevention test
+ *
+ * Revision 1.1  1996/09/27 01:19:39  brianp
+ * Initial revision
+ *
+ */
+
+
+/*
+ * This file is part of the polygon tesselation code contributed by
+ * Bogdan Sikorski
+ */
+
+
+#ifndef TESS_H
+#define TESS_H
+
+
+#include "gluP.h"
+
+#define EPSILON 1e-06 /* epsilon for double precision compares */
+
+typedef enum
+{
+       OXY,
+       OYZ,
+       OXZ
+} projection_type;
+
+typedef struct callbacks_str
+{
+       void (GLCALLBACK *begin)( GLenum mode );
+       void (GLCALLBACK *edgeFlag)( GLboolean flag );
+       void (GLCALLBACK *vertex)( GLvoid *v );
+       void (GLCALLBACK *end)( void );
+       void (GLCALLBACK *error)( GLenum err );
+} tess_callbacks;
+
+typedef struct vertex_str
+{
+       void                            *data;
+       GLdouble                        location[3];
+       GLdouble                        x,y;
+       GLboolean                       edge_flag;
+       struct vertex_str       *shadow_vertex;
+       struct vertex_str       *next,*previous;
+} tess_vertex;
+
+typedef struct contour_str
+{
+       GLenum                          type;
+       GLuint                          vertex_cnt;
+       GLdouble                        area;
+       GLenum                          orientation;
+       struct vertex_str       *vertices,*last_vertex;
+       struct contour_str      *next,*previous;
+} tess_contour;
+
+typedef struct polygon_str
+{
+       GLuint                          vertex_cnt;
+       GLdouble                        A,B,C,D;
+       GLdouble                        area;
+       GLenum                          orientation;
+       struct vertex_str       *vertices,*last_vertex;
+} tess_polygon;
+
+struct GLUtesselator
+{
+       tess_contour            *contours,*last_contour;
+       GLuint                          contour_cnt;
+       tess_callbacks          callbacks;
+       tess_polygon            *current_polygon;
+       GLenum                          error;
+       GLdouble                        A,B,C,D;
+       projection_type         projection;
+};
+
+
+extern void tess_call_user_error(GLUtriangulatorObj *,GLenum);
+
+
+#endif
diff --git a/src/glu/mesa/tesselat.c b/src/glu/mesa/tesselat.c
new file mode 100644 (file)
index 0000000..1e424c1
--- /dev/null
@@ -0,0 +1,456 @@
+/* $Id: tesselat.c,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  2.4
+ * Copyright (C) 1995-1997  Brian Paul
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/*
+ * $Log: tesselat.c,v $
+ * Revision 1.1  1999/08/19 00:55:42  jtg
+ * Initial revision
+ *
+ * Revision 1.5  1997/07/24 01:28:44  brianp
+ * changed precompiled header symbol from PCH to PC_HEADER
+ *
+ * Revision 1.4  1997/05/28 02:29:38  brianp
+ * added support for precompiled headers (PCH), inserted APIENTRY keyword
+ *
+ * Revision 1.3  1997/02/17 17:24:58  brianp
+ * more tesselation changes (Randy Frank)
+ *
+ * Revision 1.2  1997/02/13 18:31:57  brianp
+ * fixed some numerical precision problems (Randy Frank)
+ *
+ * Revision 1.1  1996/09/27 01:19:39  brianp
+ * Initial revision
+ *
+ */
+
+
+/*
+ * This file is part of the polygon tesselation code contributed by
+ * Bogdan Sikorski
+ */
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <stdlib.h>
+#include <math.h>
+#include "tess.h"
+#endif
+
+
+
+static GLboolean edge_flag;
+
+static void emit_triangle(GLUtriangulatorObj *, tess_vertex *,
+       tess_vertex *,tess_vertex *);
+
+static void emit_triangle_with_edge_flag(GLUtriangulatorObj *,
+        tess_vertex *,GLboolean,tess_vertex *,GLboolean,
+        tess_vertex *,GLboolean);
+
+static GLdouble twice_the_triangle_area(
+       tess_vertex *va,
+       tess_vertex *vb,
+       tess_vertex *vc)
+{
+       return   (vb->x - va->x)*(vc->y - va->y) - (vb->y - va->y)*(vc->x - va->x);
+}
+
+static GLboolean left(
+       GLdouble A,
+       GLdouble B,
+       GLdouble C,
+       GLdouble x,
+       GLdouble y)
+{
+       if(A*x+B*y+C > -EPSILON)
+               return GL_TRUE;
+       else
+               return GL_FALSE;
+}
+
+static GLboolean right(
+       GLdouble A,
+       GLdouble B,
+       GLdouble C,
+       GLdouble x,
+       GLdouble y)
+{
+       if(A*x+B*y+C < EPSILON)
+               return GL_TRUE;
+       else
+               return GL_FALSE;
+}
+
+static GLint convex_ccw(
+       tess_vertex *va,
+       tess_vertex *vb,
+       tess_vertex *vc,
+       GLUtriangulatorObj *tobj)
+{
+       GLdouble        d;
+
+       d = twice_the_triangle_area(va,vb,vc);
+
+       if (d > EPSILON ) {
+               return 1;
+       } else if (d < -EPSILON ) {
+               return 0;
+       } else {
+               return -1;
+       }
+}
+
+static GLint convex_cw(
+       tess_vertex *va,
+       tess_vertex *vb,
+       tess_vertex *vc,
+       GLUtriangulatorObj *tobj)
+{
+       GLdouble        d;
+
+       d = twice_the_triangle_area(va,vb,vc);
+
+       if (d < -EPSILON ) {
+               return 1;
+       } else if (d > EPSILON ) {
+               return 0;
+       } else {
+               return -1;
+       }
+}
+
+static GLboolean diagonal_ccw(
+       tess_vertex *va,
+       tess_vertex *vb,
+       GLUtriangulatorObj *tobj,
+       tess_contour *contour)
+{
+       tess_vertex *vc=va->next , *vertex , *shadow_vertex;
+       struct
+       {
+               GLdouble A,B,C;
+       } ac,cb,ba;
+       GLdouble x,y;
+
+       GLint    res = convex_ccw(va,vc,vb,tobj);
+       if (res == 0) return GL_FALSE;
+       if (res == -1) return GL_TRUE;
+
+       ba.A=vb->y - va->y;
+       ba.B=va->x - vb->x;
+       ba.C= -ba.A*va->x - ba.B*va->y;
+       ac.A=va->y - vc->y;
+       ac.B=vc->x - va->x;
+       ac.C= -ac.A*vc->x - ac.B*vc->y;
+       cb.A=vc->y - vb->y;
+       cb.B=vb->x - vc->x;
+       cb.C= -cb.A*vb->x - cb.B*vb->y;
+       for(vertex=vb->next;vertex!=va;vertex=vertex->next)
+       {
+               shadow_vertex=vertex->shadow_vertex;
+               if(shadow_vertex!=NULL && 
+                       (shadow_vertex==va || shadow_vertex==vb || shadow_vertex==vc))
+                       continue;
+               x=vertex->x;
+               y=vertex->y;
+               if(left(ba.A,ba.B,ba.C,x,y) &&
+                       left(ac.A,ac.B,ac.C,x,y) &&
+                       left(cb.A,cb.B,cb.C,x,y))
+                       return GL_FALSE;
+       }
+       return GL_TRUE;
+}
+
+static GLboolean diagonal_cw(
+       tess_vertex *va,
+       tess_vertex *vb,
+       GLUtriangulatorObj *tobj,
+       tess_contour *contour)
+{
+       tess_vertex *vc=va->next , *vertex , *shadow_vertex;
+       struct
+       {
+               GLdouble A,B,C;
+       } ac,cb,ba;
+       GLdouble x,y;
+
+       GLint    res = convex_cw(va,vc,vb,tobj);
+       if (res == 0) return GL_FALSE;
+       if (res == -1) return GL_TRUE;
+
+       ba.A=vb->y - va->y;
+       ba.B=va->x - vb->x;
+       ba.C= -ba.A*va->x - ba.B*va->y;
+       ac.A=va->y - vc->y;
+       ac.B=vc->x - va->x;
+       ac.C= -ac.A*vc->x - ac.B*vc->y;
+       cb.A=vc->y - vb->y;
+       cb.B=vb->x - vc->x;
+       cb.C= -cb.A*vb->x - cb.B*vb->y;
+       for(vertex=vb->next;vertex!=va;vertex=vertex->next)
+       {
+               shadow_vertex=vertex->shadow_vertex;
+               if(shadow_vertex!=NULL && 
+                       (shadow_vertex==va || shadow_vertex==vb || shadow_vertex==vc))
+                       continue;
+               x=vertex->x;
+               y=vertex->y;
+               if(right(ba.A,ba.B,ba.C,x,y) &&
+                       right(ac.A,ac.B,ac.C,x,y) &&
+                       right(cb.A,cb.B,cb.C,x,y))
+                       return GL_FALSE;
+       }
+       return GL_TRUE;
+}
+
+static void clip_ear(
+       GLUtriangulatorObj *tobj,
+       tess_vertex *v,
+       tess_contour *contour)
+{
+       emit_triangle(tobj,v->previous,v,v->next);
+       /* the first in the list */
+       if(contour->vertices==v)
+       {
+               contour->vertices=v->next;
+               contour->last_vertex->next=v->next;
+               v->next->previous=contour->last_vertex;
+       }
+       else
+       /* the last ? */
+       if(contour->last_vertex==v)
+       {
+               contour->vertices->previous=v->previous;
+               v->previous->next=v->next;
+               contour->last_vertex=v->previous;
+       }
+       else
+       {
+               v->next->previous=v->previous;
+               v->previous->next=v->next;
+       }
+       free(v);
+       --(contour->vertex_cnt);
+}
+
+static void clip_ear_with_edge_flag(
+       GLUtriangulatorObj *tobj,
+       tess_vertex *v,
+       tess_contour *contour)
+{
+       emit_triangle_with_edge_flag(tobj,v->previous,v->previous->edge_flag,
+               v,v->edge_flag,v->next,GL_FALSE);
+       v->previous->edge_flag=GL_FALSE;
+       /* the first in the list */
+       if(contour->vertices==v)
+       {
+               contour->vertices=v->next;
+               contour->last_vertex->next=v->next;
+               v->next->previous=contour->last_vertex;
+       }
+       else
+       /* the last ? */
+       if(contour->last_vertex==v)
+       {
+               contour->vertices->previous=v->previous;
+               v->previous->next=v->next;
+               contour->last_vertex=v->previous;
+       }
+       else
+       {
+               v->next->previous=v->previous;
+               v->previous->next=v->next;
+       }
+       free(v);
+       --(contour->vertex_cnt);
+}
+
+static void triangulate_ccw(
+       GLUtriangulatorObj *tobj,
+       tess_contour *contour)
+{
+       tess_vertex *vertex;
+       GLuint vertex_cnt=contour->vertex_cnt;
+
+       while(vertex_cnt > 3)
+       {
+               vertex=contour->vertices;
+               while(diagonal_ccw(vertex,vertex->next->next,tobj,contour)==GL_FALSE &&
+                       tobj->error==GLU_NO_ERROR)
+                       vertex=vertex->next;
+               if(tobj->error!=GLU_NO_ERROR)
+                       return;
+               clip_ear(tobj,vertex->next,contour);
+               --vertex_cnt;
+       }
+}
+
+static void triangulate_cw(
+       GLUtriangulatorObj *tobj,
+       tess_contour *contour)
+{
+       tess_vertex *vertex;
+       GLuint vertex_cnt=contour->vertex_cnt;
+
+       while(vertex_cnt > 3)
+       {
+               vertex=contour->vertices;
+               while(diagonal_cw(vertex,vertex->next->next,tobj,contour)==GL_FALSE &&
+                       tobj->error==GLU_NO_ERROR)
+                       vertex=vertex->next;
+               if(tobj->error!=GLU_NO_ERROR)
+                       return;
+               clip_ear(tobj,vertex->next,contour);
+               --vertex_cnt;
+       }
+}
+
+static void triangulate_ccw_with_edge_flag(
+       GLUtriangulatorObj *tobj,
+       tess_contour *contour)
+{
+       tess_vertex *vertex;
+       GLuint vertex_cnt=contour->vertex_cnt;
+
+       while(vertex_cnt > 3)
+       {
+               vertex=contour->vertices;
+               while(diagonal_ccw(vertex,vertex->next->next,tobj,contour)==GL_FALSE &&
+                       tobj->error==GLU_NO_ERROR)
+                       vertex=vertex->next;
+               if(tobj->error!=GLU_NO_ERROR)
+                       return;
+               clip_ear_with_edge_flag(tobj,vertex->next,contour);
+               --vertex_cnt;
+       }
+}
+
+static void triangulate_cw_with_edge_flag(
+       GLUtriangulatorObj *tobj,
+       tess_contour *contour)
+{
+       tess_vertex *vertex;
+       GLuint vertex_cnt=contour->vertex_cnt;
+
+       while(vertex_cnt > 3)
+       {
+               vertex=contour->vertices;
+               while(diagonal_cw(vertex,vertex->next->next,tobj,contour)==GL_FALSE &&
+                       tobj->error==GLU_NO_ERROR)
+                       vertex=vertex->next;
+               if(tobj->error!=GLU_NO_ERROR)
+                       return;
+               clip_ear_with_edge_flag(tobj,vertex->next,contour);
+               --vertex_cnt;
+       }
+}
+
+void tess_tesselate(GLUtriangulatorObj *tobj)
+{
+       tess_contour *contour;
+
+       for(contour=tobj->contours;contour!=NULL;contour=contour->next)
+       {
+               if(contour->orientation==GLU_CCW) {
+                       triangulate_ccw(tobj,contour);
+               } else {
+                       triangulate_cw(tobj,contour);
+               }
+               if(tobj->error!=GLU_NO_ERROR)
+                       return;
+
+               /* emit the last triangle */
+               emit_triangle(tobj,contour->vertices,contour->vertices->next,
+                       contour->vertices->next->next);
+       }
+}
+
+void tess_tesselate_with_edge_flag(GLUtriangulatorObj *tobj)
+{
+       tess_contour *contour;
+
+       edge_flag=GL_TRUE;
+       /* first callback with edgeFlag set to GL_TRUE */
+       (tobj->callbacks.edgeFlag)(GL_TRUE);
+
+       for(contour=tobj->contours;contour!=NULL;contour=contour->next)
+       {
+               if(contour->orientation==GLU_CCW)
+                       triangulate_ccw_with_edge_flag(tobj,contour);
+               else
+                       triangulate_cw_with_edge_flag(tobj,contour);
+               if(tobj->error!=GLU_NO_ERROR)
+                       return;
+               /* emit the last triangle */
+               emit_triangle_with_edge_flag(tobj,contour->vertices,
+                       contour->vertices->edge_flag,contour->vertices->next,
+                       contour->vertices->next->edge_flag,contour->vertices->next->next,
+                       contour->vertices->next->next->edge_flag);
+       }
+}
+
+static void emit_triangle(
+       GLUtriangulatorObj *tobj,
+       tess_vertex *v1,
+       tess_vertex *v2,
+       tess_vertex *v3)
+{
+       (tobj->callbacks.begin)(GL_TRIANGLES);
+       (tobj->callbacks.vertex)(v1->data);
+       (tobj->callbacks.vertex)(v2->data);
+       (tobj->callbacks.vertex)(v3->data);
+       (tobj->callbacks.end)();
+}
+
+static void emit_triangle_with_edge_flag(
+       GLUtriangulatorObj *tobj,
+       tess_vertex *v1,
+       GLboolean edge_flag1,
+       tess_vertex *v2,
+       GLboolean edge_flag2,
+       tess_vertex *v3,
+       GLboolean edge_flag3)
+{
+       (tobj->callbacks.begin)(GL_TRIANGLES);
+       if(edge_flag1!=edge_flag)
+       {
+               edge_flag = (edge_flag==GL_TRUE ? GL_FALSE : GL_TRUE);
+               (tobj->callbacks.edgeFlag)(edge_flag);
+       }
+       (tobj->callbacks.vertex)(v1->data);
+       if(edge_flag2!=edge_flag)
+       {
+               edge_flag = (edge_flag==GL_TRUE ? GL_FALSE : GL_TRUE);
+               (tobj->callbacks.edgeFlag)(edge_flag);
+       }
+       (tobj->callbacks.vertex)(v2->data);
+       if(edge_flag3!=edge_flag)
+       {
+               edge_flag = (edge_flag==GL_TRUE ? GL_FALSE : GL_TRUE);
+               (tobj->callbacks.edgeFlag)(edge_flag);
+       }
+       (tobj->callbacks.vertex)(v3->data);
+       (tobj->callbacks.end)();
+}
diff --git a/src/glw/GLwDrawA.c b/src/glw/GLwDrawA.c
new file mode 100644 (file)
index 0000000..670ddb1
--- /dev/null
@@ -0,0 +1,686 @@
+/*
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+ */
+
+/*
+ *
+ * This file has been slightly modified from the original for use with Mesa
+ *
+ *     Jeroen van der Zijp
+ *
+ *     jvz@cyberia.cfdrc.com
+ *
+ */
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <GL/glx.h>
+#include <GL/gl.h>
+#ifdef __GLX_MOTIF
+#include <Xm/PrimitiveP.h>
+#include "GLwMDrawAP.h"
+#else 
+#include "GLwDrawAP.h"
+#endif 
+#include <assert.h>
+#include <stdio.h>
+
+#ifdef __GLX_MOTIF
+#define GLwDrawingAreaWidget             GLwMDrawingAreaWidget
+#define GLwDrawingAreaClassRec           GLwMDrawingAreaClassRec
+#define glwDrawingAreaClassRec           glwMDrawingAreaClassRec
+#define glwDrawingAreaWidgetClass        glwMDrawingAreaWidgetClass
+#define GLwDrawingAreaRec                GLwMDrawingAreaRec
+#endif 
+
+#define ATTRIBLIST_SIZE 30
+
+#define offset(field) XtOffset(GLwDrawingAreaWidget,glwDrawingArea.field)
+
+
+/* forward definitions */
+static void createColormap(GLwDrawingAreaWidget w,int offset,XrmValue *value);
+static void Initialize(GLwDrawingAreaWidget req,GLwDrawingAreaWidget neww,ArgList args,Cardinal *num_args);
+static void Realize(Widget w,Mask *valueMask,XSetWindowAttributes *attributes);
+static void Redraw(GLwDrawingAreaWidget w,XEvent *event,Region region);
+static void Resize(GLwDrawingAreaWidget glw);
+static void Destroy(GLwDrawingAreaWidget glw);
+static void glwInput(GLwDrawingAreaWidget glw,XEvent *event,String *params,Cardinal *numParams);
+
+
+
+static char defaultTranslations[] =
+#ifdef __GLX_MOTIF
+     "<Key>osfHelp:PrimitiveHelp() \n"
+#endif
+    "<KeyDown>:   glwInput() \n\
+     <KeyUp>:     glwInput() \n\
+     <BtnDown>:   glwInput() \n\
+     <BtnUp>:     glwInput() \n\
+     <BtnMotion>: glwInput() ";
+
+
+static XtActionsRec actions[] = {
+  {"glwInput",(XtActionProc)glwInput},                /* key or mouse input */
+  };
+
+
+/*
+ * There is a bit of unusual handling of the resources here.
+ * Because Xt insists on allocating the colormap resource when it is
+ * processing the core resources (even if we redeclare the colormap
+ * resource here, we need to do a little trick.  When Xt first allocates
+ * the colormap, we allow it to allocate the default one, since we have
+ * not yet determined the appropriate visual (which is determined from
+ * resources parsed after the colormap).  We also let it allocate colors
+ * in that default colormap.
+ *
+ * In the initialize proc we calculate the actual visual.  Then, we
+ * reobtain the colormap resource using XtGetApplicationResources in
+ * the initialize proc.  If requested, we also reallocate colors in
+ * that colormap using the same method.
+ */
+
+static XtResource resources[] = {
+  /* The GLX attributes.  Add any new attributes here */
+
+  {GLwNbufferSize, GLwCBufferSize, XtRInt, sizeof (int),
+       offset(bufferSize), XtRImmediate, (XtPointer) 0},
+  
+  {GLwNlevel, GLwCLevel, XtRInt, sizeof (int),
+       offset(level), XtRImmediate, (XtPointer) 0},
+  
+  {GLwNrgba, GLwCRgba, XtRBoolean, sizeof (Boolean),
+       offset(rgba), XtRImmediate, (XtPointer) FALSE},
+  
+  {GLwNdoublebuffer, GLwCDoublebuffer, XtRBoolean, sizeof (Boolean),
+       offset(doublebuffer), XtRImmediate, (XtPointer) FALSE},
+  
+  {GLwNstereo, GLwCStereo, XtRBoolean, sizeof (Boolean),
+       offset(stereo), XtRImmediate, (XtPointer) FALSE},
+  
+  {GLwNauxBuffers, GLwCAuxBuffers, XtRInt, sizeof (int),
+       offset(auxBuffers), XtRImmediate, (XtPointer) 0},
+  
+  {GLwNredSize, GLwCColorSize, XtRInt, sizeof (int),
+       offset(redSize), XtRImmediate, (XtPointer) 1},
+  
+  {GLwNgreenSize, GLwCColorSize, XtRInt, sizeof (int),
+       offset(greenSize), XtRImmediate, (XtPointer) 1},
+  
+  {GLwNblueSize, GLwCColorSize, XtRInt, sizeof (int),
+       offset(blueSize), XtRImmediate, (XtPointer) 1},
+  
+  {GLwNalphaSize, GLwCAlphaSize, XtRInt, sizeof (int),
+       offset(alphaSize), XtRImmediate, (XtPointer) 0},
+  
+  {GLwNdepthSize, GLwCDepthSize, XtRInt, sizeof (int),
+       offset(depthSize), XtRImmediate, (XtPointer) 0},
+  
+  {GLwNstencilSize, GLwCStencilSize, XtRInt, sizeof (int),
+       offset(stencilSize), XtRImmediate, (XtPointer) 0},
+  
+  {GLwNaccumRedSize, GLwCAccumColorSize, XtRInt, sizeof (int),
+       offset(accumRedSize), XtRImmediate, (XtPointer) 0},
+  
+  {GLwNaccumGreenSize, GLwCAccumColorSize, XtRInt, sizeof (int),
+       offset(accumGreenSize), XtRImmediate, (XtPointer) 0},
+  
+  {GLwNaccumBlueSize, GLwCAccumColorSize, XtRInt, sizeof (int),
+       offset(accumBlueSize), XtRImmediate, (XtPointer) 0},
+  
+  {GLwNaccumAlphaSize, GLwCAccumAlphaSize, XtRInt, sizeof (int),
+       offset(accumAlphaSize), XtRImmediate, (XtPointer) 0},
+  
+  /* the attribute list */
+  {GLwNattribList, GLwCAttribList, XtRPointer, sizeof(int *),
+       offset(attribList), XtRImmediate, (XtPointer) NULL},
+
+  /* the visual info */
+  {GLwNvisualInfo, GLwCVisualInfo, GLwRVisualInfo, sizeof (XVisualInfo *),
+       offset(visualInfo), XtRImmediate, (XtPointer) NULL},
+
+  /* miscellaneous resources */
+  {GLwNinstallColormap, GLwCInstallColormap, XtRBoolean, sizeof (Boolean),
+       offset(installColormap), XtRImmediate, (XtPointer) TRUE},
+
+  {GLwNallocateBackground, GLwCAllocateColors, XtRBoolean, sizeof (Boolean),
+       offset(allocateBackground), XtRImmediate, (XtPointer) FALSE},
+
+  {GLwNallocateOtherColors, GLwCAllocateColors, XtRBoolean, sizeof (Boolean),
+       offset(allocateOtherColors), XtRImmediate, (XtPointer) FALSE},
+
+  {GLwNinstallBackground, GLwCInstallBackground, XtRBoolean, sizeof (Boolean),
+       offset(installBackground), XtRImmediate, (XtPointer) TRUE},
+
+  {GLwNginitCallback, GLwCCallback, XtRCallback, sizeof (XtCallbackList),
+       offset(ginitCallback), XtRImmediate, (XtPointer) NULL},
+
+  {GLwNinputCallback, GLwCCallback, XtRCallback, sizeof (XtCallbackList),
+       offset(inputCallback), XtRImmediate, (XtPointer) NULL},
+
+  {GLwNresizeCallback, GLwCCallback, XtRCallback, sizeof (XtCallbackList),
+       offset(resizeCallback), XtRImmediate, (XtPointer) NULL},
+
+  {GLwNexposeCallback, GLwCCallback, XtRCallback, sizeof (XtCallbackList),
+       offset(exposeCallback), XtRImmediate, (XtPointer) NULL},
+
+  /* Changes to Motif primitive resources */
+#ifdef __GLX_MOTIF
+  {XmNtraversalOn, XmCTraversalOn, XmRBoolean, sizeof (Boolean),
+   XtOffset (GLwDrawingAreaWidget, primitive.traversal_on), XmRImmediate,
+   (XtPointer)FALSE},
+  
+  /* highlighting is normally disabled, as when Motif tries to disable
+   * highlighting, it tries to reset the color back to the parent's
+   * background (usually Motif blue).  Unfortunately, that is in a
+   * different colormap, and doesn't work too well.
+   */
+  {XmNhighlightOnEnter, XmCHighlightOnEnter, XmRBoolean, sizeof (Boolean),
+   XtOffset (GLwDrawingAreaWidget, primitive.highlight_on_enter),
+   XmRImmediate, (XtPointer) FALSE},
+  
+  {XmNhighlightThickness, XmCHighlightThickness, XmRHorizontalDimension,
+   sizeof (Dimension),
+   XtOffset (GLwDrawingAreaWidget, primitive.highlight_thickness),
+   XmRImmediate, (XtPointer) 0},
+#endif 
+  };
+
+
+/*
+** The following resources are reobtained using XtGetApplicationResources
+** in the initialize proc.
+*/
+
+/* The colormap */
+static XtResource initializeResources[] = {
+  /* reobtain the colormap with the new visual */
+  {XtNcolormap, XtCColormap, XtRColormap, sizeof(Colormap),
+   XtOffset(GLwDrawingAreaWidget, core.colormap),
+   XtRCallProc,(XtPointer) createColormap},
+  };
+
+
+/* reallocate any colors we need in the new colormap */
+  
+/* The background is obtained only if the allocateBackground resource is TRUE*/
+static XtResource backgroundResources[] = {
+#ifdef __GLX_MOTIF
+  {XmNbackground, XmCBackground,XmRPixel, 
+   sizeof(Pixel),XtOffset(GLwDrawingAreaWidget,core.background_pixel),
+   XmRString,(XtPointer)"lightgrey"},
+   /*XmRCallProc,(XtPointer)_XmBackgroundColorDefault},*/
+
+  {XmNbackgroundPixmap,XmCPixmap,XmRXmBackgroundPixmap, 
+   sizeof(Pixmap),XtOffset(GLwDrawingAreaWidget,core.background_pixmap),
+   XmRImmediate,(XtPointer)XmUNSPECIFIED_PIXMAP},
+
+#else
+  {XtNbackground,XtCBackground,XtRPixel,sizeof(Pixel),
+   XtOffset(GLwDrawingAreaWidget,core.background_pixel),
+   XtRString,(XtPointer)"lightgrey"},
+   /*XtRString,(XtPointer)"XtDefaultBackground"},*/
+
+  {XtNbackgroundPixmap, XtCPixmap, XtRPixmap, sizeof(Pixmap),
+   XtOffset(GLwDrawingAreaWidget,core.background_pixmap),
+   XtRImmediate,(XtPointer)XtUnspecifiedPixmap},
+#endif  
+  };
+
+
+
+/* The other colors such as the foreground are allocated only if
+ * allocateOtherColors are set.  These resources only exist in Motif.
+ */
+#ifdef __GLX_MOTIF
+static XtResource otherColorResources[] = {
+  {XmNforeground,XmCForeground,XmRPixel, 
+   sizeof(Pixel),XtOffset(GLwDrawingAreaWidget,primitive.foreground),
+   XmRString,(XtPointer)"lighgrey"},
+   /*XmRCallProc, (XtPointer) _XmForegroundColorDefault},*/
+
+  {XmNhighlightColor,XmCHighlightColor,XmRPixel,sizeof(Pixel),
+   XtOffset(GLwDrawingAreaWidget,primitive.highlight_color),
+   XmRString,(XtPointer)"lightgrey"},
+   /*XmRCallProc,(XtPointer)_XmHighlightColorDefault},*/
+
+  {XmNhighlightPixmap,XmCHighlightPixmap,XmRPrimHighlightPixmap,
+   sizeof(Pixmap),
+   XtOffset(GLwDrawingAreaWidget,primitive.highlight_pixmap),
+   XmRImmediate,(XtPointer)XmUNSPECIFIED_PIXMAP},
+   /*XmRCallProc,(XtPointer)_XmPrimitiveHighlightPixmapDefault},*/
+  };
+#endif
+
+
+#undef offset
+
+
+GLwDrawingAreaClassRec glwDrawingAreaClassRec = {
+  { /* core fields */
+#ifdef __GLX_MOTIF
+    /* superclass                */        (WidgetClass) &xmPrimitiveClassRec,
+    /* class_name                */        "GLwMDrawingArea",
+#else /* not __GLX_MOTIF */
+    /* superclass                */        (WidgetClass) &widgetClassRec,
+    /* class_name                */        "GLwDrawingArea",
+#endif /* __GLX_MOTIF */
+    /* widget_size               */        sizeof(GLwDrawingAreaRec),
+    /* class_initialize          */        NULL,
+    /* class_part_initialize     */        NULL,
+    /* class_inited              */        FALSE,
+    /* initialize                */        (XtInitProc) Initialize,
+    /* initialize_hook           */        NULL,
+    /* realize                   */        Realize,
+    /* actions                   */        actions,
+    /* num_actions               */        XtNumber(actions),
+    /* resources                 */        resources,
+    /* num_resources             */        XtNumber(resources),
+    /* xrm_class                 */        NULLQUARK,
+    /* compress_motion           */        TRUE,
+    /* compress_exposure         */        TRUE,
+    /* compress_enterleave       */        TRUE,
+    /* visible_interest          */        TRUE,
+    /* destroy                   */        (XtWidgetProc) Destroy,
+    /* resize                    */        (XtWidgetProc) Resize,
+    /* expose                    */        (XtExposeProc) Redraw,
+    /* set_values                */        NULL,
+    /* set_values_hook           */        NULL,
+    /* set_values_almost         */        XtInheritSetValuesAlmost,
+    /* get_values_hook           */        NULL,
+    /* accept_focus              */        NULL,
+    /* version                   */        XtVersion,
+    /* callback_private          */        NULL,
+    /* tm_table                  */        defaultTranslations,
+    /* query_geometry            */        XtInheritQueryGeometry,
+    /* display_accelerator       */        XtInheritDisplayAccelerator,
+    /* extension                 */        NULL
+  },
+#ifdef __GLX_MOTIF /* primitive resources */
+  {
+    /* border_highlight          */        XmInheritBorderHighlight,
+    /* border_unhighlight        */        XmInheritBorderUnhighlight,
+    /* translations              */        XtInheritTranslations,
+    /* arm_and_activate          */        NULL,
+    /* get_resources             */        NULL,
+    /* num get_resources         */        0,
+    /* extension                 */        NULL,                                
+  }
+#endif 
+  };
+
+WidgetClass glwDrawingAreaWidgetClass=(WidgetClass)&glwDrawingAreaClassRec;
+
+
+
+static void error(Widget w,char* string){
+  char buf[100];
+#ifdef __GLX_MOTIF
+  sprintf(buf,"GLwMDrawingArea: %s\n",string);
+#else
+  sprintf(buf,"GLwDrawingArea: %s\n",string);
+#endif
+  XtAppError(XtWidgetToApplicationContext(w),buf);
+  }
+
+
+static void warning(Widget w,char* string){
+  char buf[100];
+#ifdef __GLX_MOTIF
+  sprintf (buf, "GLwMDraw: %s\n", string);
+#else
+  sprintf (buf, "GLwDraw: %s\n", string);
+#endif
+  XtAppWarning(XtWidgetToApplicationContext(w), buf);
+  }
+
+
+
+/* Initialize the attribList based on the attributes */
+static void createAttribList(GLwDrawingAreaWidget w){
+  int *ptr;
+  w->glwDrawingArea.attribList = (int*)XtMalloc(ATTRIBLIST_SIZE*sizeof(int));
+  if(!w->glwDrawingArea.attribList){
+    error((Widget)w,"Unable to allocate attribute list");
+    }
+  ptr = w->glwDrawingArea.attribList;
+  *ptr++ = GLX_BUFFER_SIZE;
+  *ptr++ = w->glwDrawingArea.bufferSize;
+  *ptr++ = GLX_LEVEL;
+  *ptr++ = w->glwDrawingArea.level;
+  if(w->glwDrawingArea.rgba) *ptr++ = GLX_RGBA;
+  if(w->glwDrawingArea.doublebuffer) *ptr++ = GLX_DOUBLEBUFFER;
+  if(w->glwDrawingArea.stereo) *ptr++ = GLX_STEREO;
+  *ptr++ = GLX_AUX_BUFFERS;
+  *ptr++ = w->glwDrawingArea.auxBuffers;
+  *ptr++ = GLX_RED_SIZE;
+  *ptr++ = w->glwDrawingArea.redSize;
+  *ptr++ = GLX_GREEN_SIZE;
+  *ptr++ = w->glwDrawingArea.greenSize;
+  *ptr++ = GLX_BLUE_SIZE;
+  *ptr++ = w->glwDrawingArea.blueSize;
+  *ptr++ = GLX_ALPHA_SIZE;
+  *ptr++ = w->glwDrawingArea.alphaSize;
+  *ptr++ = GLX_DEPTH_SIZE;
+  *ptr++ = w->glwDrawingArea.depthSize;
+  *ptr++ = GLX_STENCIL_SIZE;
+  *ptr++ = w->glwDrawingArea.stencilSize;
+  *ptr++ = GLX_ACCUM_RED_SIZE;
+  *ptr++ = w->glwDrawingArea.accumRedSize;
+  *ptr++ = GLX_ACCUM_GREEN_SIZE;
+  *ptr++ = w->glwDrawingArea.accumGreenSize;
+  *ptr++ = GLX_ACCUM_BLUE_SIZE;
+  *ptr++ = w->glwDrawingArea.accumBlueSize;
+  *ptr++ = GLX_ACCUM_ALPHA_SIZE;
+  *ptr++ = w->glwDrawingArea.accumAlphaSize;
+  *ptr++ = None;
+  assert((ptr-w->glwDrawingArea.attribList)<ATTRIBLIST_SIZE);
+  }
+
+
+
+/* Initialize the visualInfo based on the attribute list */
+static void createVisualInfo(GLwDrawingAreaWidget w){
+  static XVisualInfo *visualInfo;
+  assert(w->glwDrawingArea.attribList);
+  w->glwDrawingArea.visualInfo=glXChooseVisual(XtDisplay(w),XScreenNumberOfScreen(XtScreen(w)),w->glwDrawingArea.attribList);
+  if(!w->glwDrawingArea.visualInfo) error((Widget)w,"requested visual not supported");
+  }
+
+
+
+/* Initialize the colormap based on the visual info.
+ * This routine maintains a cache of visual-infos to colormaps.  If two
+ * widgets share the same visual info, they share the same colormap.
+ * This function is called by the callProc of the colormap resource entry.
+ */
+static void createColormap(GLwDrawingAreaWidget w,int offset,XrmValue *value){
+  static struct cmapCache { Visual *visual; Colormap cmap; } *cmapCache;
+  static int cacheEntries=0;
+  static int cacheMalloced=0;
+  register int i;
+    
+  assert(w->glwDrawingArea.visualInfo);
+
+  /* see if we can find it in the cache */
+  for(i=0; i<cacheEntries; i++){
+    if(cmapCache[i].visual==w->glwDrawingArea.visualInfo->visual){
+      value->addr=(XtPointer)(&cmapCache[i].cmap);
+      return;
+      }
+    }
+
+  /* not in the cache, create a new entry */
+  if(cacheEntries >= cacheMalloced){
+    /* need to malloc a new one.  Since we are likely to have only a
+     * few colormaps, we allocate one the first time, and double
+     * each subsequent time.
+     */
+    if(cacheMalloced==0){
+      cacheMalloced=1;
+      cmapCache=(struct cmapCache*)XtMalloc(sizeof(struct cmapCache));
+      }
+    else{
+      cacheMalloced<<=1;
+      cmapCache=(struct cmapCache*)XtRealloc((char*)cmapCache,sizeof(struct cmapCache)*cacheMalloced);
+      }
+    }
+       
+  cmapCache[cacheEntries].cmap=XCreateColormap(XtDisplay(w),
+                                               RootWindow(XtDisplay(w),
+                                               w->glwDrawingArea.visualInfo->screen),
+                                               w->glwDrawingArea.visualInfo->visual,
+                                               AllocNone);
+  cmapCache[cacheEntries].visual=w->glwDrawingArea.visualInfo->visual;
+  value->addr=(XtPointer)(&cmapCache[cacheEntries++].cmap);
+  }
+
+
+
+static void Initialize(GLwDrawingAreaWidget req,GLwDrawingAreaWidget neww,ArgList args,Cardinal *num_args){
+
+  /* fix size */
+  if(req->core.width==0) neww->core.width=100;
+  if(req->core.height==0) neww->core.width=100;
+
+  /* create the attribute list if needed */
+  neww->glwDrawingArea.myList=FALSE;
+  if(neww->glwDrawingArea.attribList==NULL){
+    neww->glwDrawingArea.myList=TRUE;
+    createAttribList(neww);
+    }
+
+  /* Gotta have it */
+  assert(neww->glwDrawingArea.attribList);
+
+  /* determine the visual info if needed */
+  neww->glwDrawingArea.myVisual=FALSE;
+  if(neww->glwDrawingArea.visualInfo==NULL){
+    neww->glwDrawingArea.myVisual=TRUE;
+    createVisualInfo(neww);
+    }
+
+  /* Gotta have that too */
+  assert(neww->glwDrawingArea.visualInfo);
+
+  neww->core.depth=neww->glwDrawingArea.visualInfo->depth;
+
+  /* Reobtain the colormap and colors in it using XtGetApplicationResources*/
+  XtGetApplicationResources((Widget)neww,neww,initializeResources,XtNumber(initializeResources),args,*num_args);
+
+  /* obtain the color resources if appropriate */
+  if(req->glwDrawingArea.allocateBackground){
+    XtGetApplicationResources((Widget)neww,neww,backgroundResources,XtNumber(backgroundResources),args,*num_args);
+    }
+
+#ifdef __GLX_MOTIF
+  if(req->glwDrawingArea.allocateOtherColors){
+    XtGetApplicationResources((Widget)neww,neww,otherColorResources,XtNumber(otherColorResources),args,*num_args);
+    }
+#endif 
+  }
+
+
+
+static void Realize(Widget w,Mask *valueMask,XSetWindowAttributes *attributes){
+  register GLwDrawingAreaWidget glw=(GLwDrawingAreaWidget)w;
+  GLwDrawingAreaCallbackStruct cb;
+  Widget parentShell;
+  Status status;
+  Window windows[2],*windowsReturn,*windowList;
+  int countReturn,i;
+   
+  /* if we haven't requested that the background be both installed and
+   * allocated, don't install it.
+   */
+  if(!(glw->glwDrawingArea.installBackground && glw->glwDrawingArea.allocateBackground)){
+    *valueMask&=~CWBackPixel;
+    }
+  XtCreateWindow(w,(unsigned int)InputOutput,glw->glwDrawingArea.visualInfo->visual,*valueMask,attributes);
+
+  /* if appropriate, call XSetWMColormapWindows to install the colormap */
+  if(glw->glwDrawingArea.installColormap){
+
+    /* Get parent shell */
+    for(parentShell=XtParent(w); parentShell&&!XtIsShell(parentShell); parentShell=XtParent(parentShell));
+
+    if(parentShell && XtWindow(parentShell)){
+
+      /* check to see if there is already a property */
+      status=XGetWMColormapWindows(XtDisplay(parentShell),XtWindow(parentShell),&windowsReturn,&countReturn);
+            
+      /* if no property, just create one */
+      if(!status){
+        windows[0]=XtWindow(w);
+        windows[1]=XtWindow(parentShell);
+        XSetWMColormapWindows(XtDisplay(parentShell),XtWindow(parentShell),windows,2);
+        }
+
+      /* there was a property, add myself to the beginning */
+      else{
+        windowList=(Window *)XtMalloc((sizeof(Window))*(countReturn+1));
+        windowList[0]=XtWindow(w);
+        for(i=0; i<countReturn; i++) windowList[i+1]=windowsReturn[i];
+        XSetWMColormapWindows(XtDisplay(parentShell),XtWindow(parentShell),windowList,countReturn+1);
+        XtFree((char*)windowList);
+        XtFree((char*)windowsReturn);
+        }
+      }
+    else{
+      warning(w,"Could not set colormap property on parent shell");
+      }
+    }
+
+  /* Invoke callbacks */
+  cb.reason=GLwCR_GINIT;
+  cb.event=NULL;
+  cb.width=glw->core.width;
+  cb.height=glw->core.height;
+  XtCallCallbackList((Widget)glw,glw->glwDrawingArea.ginitCallback,&cb);
+  }
+
+
+
+static void Redraw(GLwDrawingAreaWidget w,XEvent *event,Region region){
+  GLwDrawingAreaCallbackStruct cb;
+  XtCallbackList cblist;
+  if(!XtIsRealized((Widget)w)) return;
+  cb.reason=GLwCR_EXPOSE;
+  cb.event=event;
+  cb.width=w->core.width;
+  cb.height=w->core.height;
+  XtCallCallbackList((Widget)w,w->glwDrawingArea.exposeCallback,&cb);
+  }
+
+
+
+static void Resize(GLwDrawingAreaWidget glw){
+  GLwDrawingAreaCallbackStruct cb;
+  if(!XtIsRealized((Widget)glw)) return;
+  cb.reason=GLwCR_RESIZE;
+  cb.event=NULL;
+  cb.width=glw->core.width;
+  cb.height=glw->core.height;
+  XtCallCallbackList((Widget)glw,glw->glwDrawingArea.resizeCallback,&cb);
+  }
+
+
+
+static void Destroy(GLwDrawingAreaWidget glw){
+  Window *windowsReturn;
+  Widget parentShell;
+  Status status;
+  int countReturn;
+  register int i;
+
+  if(glw->glwDrawingArea.myList && glw->glwDrawingArea.attribList){
+    XtFree((XtPointer)glw->glwDrawingArea.attribList);
+    }
+
+  if(glw->glwDrawingArea.myVisual && glw->glwDrawingArea.visualInfo){
+    XtFree((XtPointer)glw->glwDrawingArea.visualInfo);
+    }
+
+  /* if my colormap was installed, remove it */
+  if(glw->glwDrawingArea.installColormap){
+
+    /* Get parent shell */
+    for(parentShell=XtParent(glw); parentShell&&!XtIsShell(parentShell); parentShell=XtParent(parentShell));
+
+    if(parentShell && XtWindow(parentShell)){
+
+      /* make sure there is a property */
+      status=XGetWMColormapWindows(XtDisplay(parentShell),XtWindow(parentShell),&windowsReturn,&countReturn);
+            
+      /* if no property, just return.  If there was a property, continue */
+      if(status){
+
+        /* search for a match */
+        for(i=0; i<countReturn; i++){
+          if(windowsReturn[i]==XtWindow(glw)){
+
+            /* we found a match, now copy the rest down */
+            for(i++; i<countReturn; i++){ windowsReturn[i-1]=windowsReturn[i]; }
+
+            XSetWMColormapWindows(XtDisplay(parentShell),XtWindow(parentShell),windowsReturn,countReturn-1);
+            break; 
+            }
+          }
+        XtFree((char *)windowsReturn);
+        }
+      }
+    }
+  }
+
+
+
+/* Action routine for keyboard and mouse events */
+static void glwInput(GLwDrawingAreaWidget glw,XEvent *event,String *params,Cardinal *numParams){
+  GLwDrawingAreaCallbackStruct cb;
+  cb.reason=GLwCR_INPUT;
+  cb.event=event;
+  cb.width=glw->core.width;
+  cb.height=glw->core.height;
+  XtCallCallbackList((Widget)glw,glw->glwDrawingArea.inputCallback,&cb);
+  }
+
+
+#ifdef __GLX_MOTIF
+
+/* Create routine */
+Widget GLwCreateMDrawingArea(Widget parent, char *name,ArgList arglist,Cardinal argcount){
+  return XtCreateWidget(name,glwMDrawingAreaWidgetClass, parent, arglist,argcount);
+  }
+
+#endif
+
+
+#ifndef __GLX_MOTIF
+
+/* Make context current */
+void GLwDrawingAreaMakeCurrent(Widget w,GLXContext ctx){
+  glXMakeCurrent(XtDisplay(w),XtWindow(w),ctx);
+  }
+
+
+/* Swap buffers convenience function */
+void GLwDrawingAreaSwapBuffers(Widget w){
+  glXSwapBuffers(XtDisplay(w),XtWindow(w));
+  }
+
+#endif
diff --git a/src/glw/GLwDrawA.h b/src/glw/GLwDrawA.h
new file mode 100644 (file)
index 0000000..a62852c
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+ */
+#ifndef _GLwDrawA_h
+#define _GLwDrawA_h
+
+#include <GL/glx.h>
+#include <GL/gl.h>
+
+/****************************************************************
+ *
+ * GLwDrawingArea widgets
+ *
+ ****************************************************************/
+
+/* Resources:
+
+ Name               Class              RepType         Default Value
+ ----               -----              -------         -------------
+ attribList         AttribList         int *           NULL
+ visualInfo         VisualInfo         VisualInfo      NULL
+ installColormap     InstallColormap   Boolean         TRUE
+ allocateBackground  AllocateColors    Boolean         FALSE
+ allocateOtherColors AllocateColors    Boolean         FALSE
+ installBackground   InstallBackground Boolean         TRUE
+ exposeCallback      Callback          Pointer         NULL
+ ginitCallback       Callback          Pointer         NULL
+ inputCallback       Callback          Pointer         NULL
+ resizeCallback      Callback          Pointer         NULL
+
+*** The following resources all correspond to the GLX configuration
+*** attributes and are used to create the attribList if it is NULL
+ bufferSize         BufferSize         int             0
+ level              Level              int             0
+ rgba               Rgba               Boolean         FALSE
+ doublebuffer       Doublebuffer       Boolean         FALSE
+ stereo                     Stereo             Boolean         FALSE
+ auxBuffers         AuxBuffers         int             0
+ redSize            ColorSize          int             1
+ greenSize          ColorSize          int             1
+ blueSize           ColorSize          int             1
+ alphaSize          AlphaSize          int             0
+ depthSize          DepthSize          int             0
+ stencilSize        StencilSize        int             0
+ accumRedSize       AccumColorSize     int             0
+ accumGreenSize             AccumColorSize     int             0
+ accumBlueSize      AccumColorSize     int             0
+ accumAlphaSize             AccumAlphaSize     int             0
+*/
+
+#define GLwNattribList         "attribList"
+#define GLwCAttribList         "AttribList"
+#define GLwNvisualInfo         "visualInfo"
+#define GLwCVisualInfo         "VisualInfo"
+#define GLwRVisualInfo         "VisualInfo"
+
+#define GLwNinstallColormap    "installColormap"
+#define GLwCInstallColormap    "InstallColormap"
+#define GLwNallocateBackground "allocateBackground"
+#define GLwNallocateOtherColors        "allocateOtherColors"
+#define GLwCAllocateColors     "AllocateColors"
+#define GLwNinstallBackground  "installBackground"
+#define GLwCInstallBackground  "InstallBackground"
+
+#define GLwCCallback           "Callback"
+#define GLwNexposeCallback     "exposeCallback"
+#define GLwNginitCallback      "ginitCallback"
+#define GLwNresizeCallback     "resizeCallback"
+#define GLwNinputCallback      "inputCallback"
+
+#define GLwNbufferSize         "bufferSize"
+#define GLwCBufferSize         "BufferSize"
+#define GLwNlevel              "level"
+#define GLwCLevel              "Level"
+#define GLwNrgba               "rgba"
+#define GLwCRgba               "Rgba"
+#define GLwNdoublebuffer       "doublebuffer"
+#define GLwCDoublebuffer       "Doublebuffer"
+#define GLwNstereo             "stereo"
+#define GLwCStereo             "Stereo"
+#define GLwNauxBuffers         "auxBuffers"
+#define GLwCAuxBuffers         "AuxBuffers"
+#define GLwNredSize            "redSize"
+#define GLwNgreenSize          "greenSize"
+#define GLwNblueSize           "blueSize"
+#define GLwCColorSize          "ColorSize"
+#define GLwNalphaSize          "alphaSize"
+#define GLwCAlphaSize          "AlphaSize"
+#define GLwNdepthSize          "depthSize"
+#define GLwCDepthSize          "DepthSize"
+#define GLwNstencilSize                "stencilSize"
+#define GLwCStencilSize                "StencilSize"
+#define GLwNaccumRedSize       "accumRedSize"
+#define GLwNaccumGreenSize     "accumGreenSize"
+#define GLwNaccumBlueSize      "accumBlueSize"
+#define GLwCAccumColorSize     "AccumColorSize"
+#define GLwNaccumAlphaSize     "accumAlphaSize"
+#define GLwCAccumAlphaSize     "AccumAlphaSize"
+
+#ifdef __GLX_MOTIF
+
+typedef struct _GLwMDrawingAreaClassRec        *GLwMDrawingAreaWidgetClass;
+typedef struct _GLwMDrawingAreaRec     *GLwMDrawingAreaWidget;
+
+extern WidgetClass glwMDrawingAreaWidgetClass;
+
+
+#else 
+
+typedef struct _GLwDrawingAreaClassRec *GLwDrawingAreaWidgetClass;
+typedef struct _GLwDrawingAreaRec      *GLwDrawingAreaWidget;
+
+extern WidgetClass glwDrawingAreaWidgetClass;
+
+
+#endif
+
+
+/* Callback reasons */
+#ifdef __GLX_MOTIF
+#define GLwCR_EXPOSE   XmCR_EXPOSE
+#define GLwCR_RESIZE   XmCR_RESIZE
+#define GLwCR_INPUT    XmCR_INPUT
+#else 
+/* The same values as Motif, but don't use Motif constants */
+#define GLwCR_EXPOSE   38
+#define GLwCR_RESIZE   39
+#define GLwCR_INPUT    40
+#endif
+
+#define GLwCR_GINIT    32135   /* Arbitrary number that should neverr clash */
+
+typedef struct 
+  {
+  int       reason;
+  XEvent   *event;
+  Dimension width,height;
+  } 
+  GLwDrawingAreaCallbackStruct;
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/* front ends to glXMakeCurrent and glXSwapBuffers */
+extern void GLwDrawingAreaMakeCurrent(Widget w,GLXContext ctx);
+extern void GLwDrawingAreaSwapBuffers(Widget w);
+
+#ifdef __GLX_MOTIF
+#ifdef _NO_PROTO
+extern Widget GLwCreateMDrawingArea();
+#else
+extern Widget GLwCreateMDrawingArea(Widget parent,char *name,ArgList arglist,Cardinal argcount);
+#endif
+#endif 
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif
diff --git a/src/glw/GLwDrawAP.h b/src/glw/GLwDrawAP.h
new file mode 100644 (file)
index 0000000..f121701
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+ */
+#ifndef _GLwDrawAP_h
+#define _GLwDrawAP_h
+
+
+/* MOTIF */
+#ifdef __GLX_MOTIF
+#include "GLwMDrawA.h"
+#else
+#include "GLwDrawA.h"
+#endif
+
+typedef struct _GLwDrawingAreaClassPart {
+  caddr_t extension;
+  } GLwDrawingAreaClassPart;
+
+
+#ifdef __GLX_MOTIF
+typedef struct _GLwMDrawingAreaClassRec {
+  CoreClassPart               core_class;
+  XmPrimitiveClassPart        primitive_class;
+  GLwDrawingAreaClassPart     glwDrawingArea_class;
+  } GLwMDrawingAreaClassRec;
+
+
+extern GLwMDrawingAreaClassRec glwMDrawingAreaClassRec;
+
+
+/* XT */
+#else 
+
+typedef struct _GLwDrawingAreaClassRec {
+  CoreClassPart               core_class;
+  GLwDrawingAreaClassPart     glwDrawingArea_class;
+  } GLwDrawingAreaClassRec;
+
+extern GLwDrawingAreaClassRec glwDrawingAreaClassRec;
+
+
+#endif 
+
+
+
+typedef struct {
+  /* resources */
+  int *                attribList;
+  XVisualInfo *        visualInfo;
+  Boolean              myList;                /* TRUE if we malloced the attribList*/
+  Boolean              myVisual;        /* TRUE if we created the visualInfo*/
+  Boolean              installColormap;
+  Boolean              allocateBackground;
+  Boolean              allocateOtherColors;
+  Boolean              installBackground;
+  XtCallbackList       ginitCallback;
+  XtCallbackList       resizeCallback;
+  XtCallbackList       exposeCallback;
+  XtCallbackList       inputCallback;
+  /* specific attributes; add as we get new attributes */
+  int                  bufferSize;
+  int                  level;
+  Boolean              rgba;
+  Boolean              doublebuffer;
+  Boolean              stereo;
+  int                  auxBuffers;
+  int                  redSize;
+  int                  greenSize;
+  int                  blueSize;
+  int                  alphaSize;
+  int                  depthSize;
+  int                  stencilSize;
+  int                  accumRedSize;
+  int                  accumGreenSize;
+  int                  accumBlueSize;
+  int                  accumAlphaSize;
+  } GLwDrawingAreaPart;
+
+#ifdef __GLX_MOTIF
+
+typedef struct _GLwMDrawingAreaRec {
+  CorePart             core;
+  XmPrimitivePart      primitive;
+  GLwDrawingAreaPart   glwDrawingArea;
+  } GLwMDrawingAreaRec;
+
+#else 
+
+typedef struct _GLwDrawingAreaRec {
+  CorePart             core;
+  GLwDrawingAreaPart   glwDrawingArea;
+  } GLwDrawingAreaRec;
+
+#endif 
+
+#endif
diff --git a/src/glw/GLwMDrawA.c b/src/glw/GLwMDrawA.c
new file mode 100644 (file)
index 0000000..bdefe92
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+ */
+#ifndef __GLX_MOTIF
+#define __GLX_MOTIF 1
+#endif
+#include "GLwDrawA.c"
diff --git a/src/glw/GLwMDrawA.h b/src/glw/GLwMDrawA.h
new file mode 100644 (file)
index 0000000..2e24589
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+ */
+#ifndef __GLX_MOTIF
+#define __GLX_MOTIF 1
+#endif
+#include "GLwDrawA.h"
diff --git a/src/glw/GLwMDrawAP.h b/src/glw/GLwMDrawAP.h
new file mode 100644 (file)
index 0000000..a0a689b
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+ */
+#ifndef __GLX_MOTIF
+#define __GLX_MOTIF 1
+#endif
+#include "GLwDrawAP.h"
diff --git a/src/glw/Makefile b/src/glw/Makefile
new file mode 100644 (file)
index 0000000..af55a1b
--- /dev/null
@@ -0,0 +1,59 @@
+# Makefile for OpenGL widgets
+
+# NOTE: widget code is from SGI.  See any of the .c or .h files for the
+# complete copyright.  Mesa's GNU copyright DOES NOT apply to this widget
+# code.
+
+
+##### MACROS #####
+
+VPATH = RCS
+
+INCDIRS = -I../include -I/usr/include/Motif1.2 -I/usr/X11R6/include
+LIBDIR = ../lib
+
+SOURCES = GLwDrawA.c GLwMDrawA.c
+
+
+OBJECTS = $(SOURCES:.c=.o)
+
+
+
+##### RULES #####
+
+.c.o:
+       $(CC) -c $(INCDIRS) $(CFLAGS) $<
+
+
+
+##### TARGETS #####
+
+default:
+       @echo "Specify a target configuration"
+
+clean:
+       -rm *.o *~
+
+# The name of the library file comes from Make-config
+#XXX GLW_LIB = libGLw.a
+
+targets: $(LIBDIR)/$(GLW_LIB)
+
+
+# Make the library
+$(LIBDIR)/$(GLW_LIB): $(OBJECTS)
+       $(MAKELIB) $(GLW_LIB) $(MAJOR) $(MINOR) $(OBJECTS)
+       mv $(GLW_LIB)* $(LIBDIR)
+
+include ../Make-config
+
+include depend
+
+
+
+#
+# Run 'make depend' to update the dependencies if you change what's included
+# by any source file.
+# 
+dep: $(SOURCES)
+       makedepend -fdepend -Y -I../include $(SOURCES)
diff --git a/src/glw/README b/src/glw/README
new file mode 100644 (file)
index 0000000..545f8b2
--- /dev/null
@@ -0,0 +1,56 @@
+
+
+                           widgets README file
+
+
+This directory contains the source code for SGI's OpenGL Xt/Motif widgets,
+slightly modified by Jeroen van der Zijp to work better with Mesa.
+
+To compile the widget code (producing lib/libGLw.a) cd to the widgets/
+directory and type 'make <config>' where <config> is the system configuration
+you used to compile Mesa.  This hasn't been tested on many systems so
+let us know if you have trouble.
+
+If you want to make a Linux ELF shared lib instead of the non-shared .a
+file see the notes in the Makefile.
+
+
+These files are NOT covered by Mesa's GNU copyright.  The real copyright
+is as follows.
+
+
+ * (c) Copyright 1993, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED 
+ * Permission to use, copy, modify, and distribute this software for 
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that 
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. 
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 
+ * 
+ * US Government Users Restricted Rights 
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States.  Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
diff --git a/src/glw/boilerplate.c b/src/glw/boilerplate.c
new file mode 100644 (file)
index 0000000..c53a3fa
--- /dev/null
@@ -0,0 +1,451 @@
+/*
+
+                                BOILERPLATE
+
+   To get started with mixed model programming with Motif and OpenGL, this
+   boilerplate `application' might help get you started.
+
+   This program honors two environment variables:
+
+      SETVISUAL <id>    Makes the application use the indicated visual,
+                        instead of the one chosen by glxChooseVisual.
+
+      SAMEVISUAL        Make the application use the same visual for the
+                        GUI as for the 3D GL Widget.
+
+   The basic idea is to minimize colormap `flash' on systems with only one
+   hardware colormap, especially when focus shifts between several
+   of the application's windows, e.g. the about box.
+
+   If you have suggestions for improvements, please mail to:
+
+
+      Jeroen van der Zijp  <jvz@cyberia.cfdrc.com>
+
+
+   Feel free to turn this into a useful program!!
+
+*/
+
+
+/*
+
+    This code is hereby placed under GNU GENERAL PUBLIC LICENSE.
+    Copyright (C) 1996 Jeroen van der Zijp <jvz@cyberia.cfdrc.com>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+/* Include the kitchen sink */
+#include <stdio.h>
+#include <stdlib.h>
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+#include <X11/cursorfont.h>
+#include <X11/keysym.h>
+#include <Xm/Xm.h>
+#include <Xm/MainW.h>
+#include <Xm/RowColumn.h>
+#include <Xm/PushB.h>
+#include <Xm/CascadeB.h>
+#include <Xm/BulletinB.h>
+#include <Xm/DialogS.h>
+#include <Xm/Frame.h>
+#include <Xm/MessageB.h>
+#include <Xm/Form.h>
+#include <Xm/Separator.h>
+#include <Xm/MwmUtil.h>
+
+/* Now some good stuff */
+#include <GLwMDrawA.h>
+#include <GL/gl.h>
+#include <GL/glu.h>
+#include <GL/glx.h>
+
+
+/* Stuff */
+Display      *display;
+Visual       *gui_visual;
+Colormap      gui_colormap;
+Colormap      gl_colormap;
+XVisualInfo  *gl_visualinfo;
+XtAppContext  app_context;
+Widget        toplevel;
+Widget        mainwindow;
+Widget        menubar;
+Widget        mainform;
+Widget        mainframe;
+Widget        glwidget;
+Widget        button;
+Widget        separator;
+GLXContext    glx_context;
+
+#ifndef __cplusplus
+#define c_class class
+#endif
+
+/* Requested attributes; fix as you see fit */
+static int glxConfig[]={
+  GLX_RGBA,
+  GLX_DOUBLEBUFFER,
+  GLX_DEPTH_SIZE,   16,
+  GLX_RED_SIZE,     1,
+  GLX_GREEN_SIZE,   1,
+  GLX_BLUE_SIZE,    1,
+  None
+  };
+
+
+/* Forwards */
+static void exposeCB(Widget w,XtPointer client_data,GLwDrawingAreaCallbackStruct *cbs);
+static void initCB(Widget w,XtPointer client_data,GLwDrawingAreaCallbackStruct *cbs);
+static void resizeCB(Widget w,XtPointer client_data,GLwDrawingAreaCallbackStruct *cbs);
+static void inputCB(Widget w,XtPointer client_data,GLwDrawingAreaCallbackStruct *cbs);
+static void byeCB(Widget w,XtPointer client_data,XtPointer call_data);
+static void aboutCB(Widget w,XtPointer client_data,XtPointer call_data);
+static char* showvisualclass(int cls);
+
+
+
+/* Sample application */
+int main(int argc, char *argv[]){
+  char *thevisual;
+  XVisualInfo vi;
+  int nvisinfos,visid,n;
+  Arg args[30];
+  Widget pane,cascade,but;
+
+  /*
+  ** Initialize toolkit
+  ** We do *not* use XtAppInitialize as we want to figure visual and
+  ** colormap BEFORE we create the top level shell!!!
+  */
+  XtToolkitInitialize();
+
+  /* Make application context */
+  app_context=XtCreateApplicationContext();
+
+  /* Try open display */
+  display=XtOpenDisplay(app_context,NULL,"boilerPlate","BoilerPlate",NULL,0,&argc,argv);
+
+  /* Report failure */
+  if(!display){
+    fprintf(stderr,"Unable to open the specified display.\n");
+    fprintf(stderr,"Set your `DISPLAY' environment variable properly or\n");
+    fprintf(stderr,"use the `xhost' command to authorize access to the display.\n");
+    exit(1);
+    }
+
+  /* Check for extension; for Mesa, this is always cool */
+  if(!glXQueryExtension(display,NULL,NULL)){
+    fprintf(stderr,"The specified display does not support the OpenGL extension\n");
+    exit(1);
+    }
+
+  /* Init with default visual and colormap */
+  gui_visual=DefaultVisual(display,0);
+  gui_colormap=DefaultColormap(display,0);
+  gl_colormap=DefaultColormap(display,0);
+
+  /* User insists on a specific visual */
+  if((thevisual=getenv("SETVISUAL"))!=NULL){
+    if(sscanf(thevisual,"%x",&visid)==1){
+      vi.visualid=visid;
+      gl_visualinfo=XGetVisualInfo(display,VisualIDMask,&vi,&nvisinfos);
+      }
+    else{
+      fprintf(stderr,"Please set the `SETVISUAL' variable in hexadecimal\n");
+      fprintf(stderr,"Use one of the Visual ID's reported by `xdpyinfo'\n");
+      exit(1);
+      }
+    }
+
+  /* Find visual the regular way */
+  else{
+    gl_visualinfo=glXChooseVisual(display,DefaultScreen(display),glxConfig);
+    }
+
+  /* Make sure we have a visual */
+  if(!gl_visualinfo){
+    fprintf(stderr,"Unable to obtain visual for graphics\n");
+    exit(1);
+    }
+
+  /* Show what visual is being used */
+  fprintf(stderr,"Using the following visual:\n");
+  fprintf(stderr,"  visualid: %lx\n",gl_visualinfo->visualid);
+  fprintf(stderr,"     depth: %d\n",gl_visualinfo->depth);
+  fprintf(stderr,"    screen: %d\n",gl_visualinfo->screen);
+  fprintf(stderr,"  bits/rgb: %d\n",gl_visualinfo->bits_per_rgb);
+  fprintf(stderr,"     class: %s\n",showvisualclass(gl_visualinfo->c_class));
+
+  /*
+  ** If not using default visual, we need a colormap for this visual.
+  ** Yes, the GL widget can allocate one itself, but we want to make
+  ** sure the GUI and the 3D have the same one (if hardware does not
+  ** allow more than one simultaneously).
+  ** This prevents nasty flashing when the window with the 3D widget
+  ** looses the focus.
+  */
+  if(gl_visualinfo->visual!=DefaultVisual(display,0)){
+    fprintf(stderr,"Making another colormap\n");
+    gl_colormap=XCreateColormap(display,
+                                RootWindow(display,0),
+                                gl_visualinfo->visual,
+                                AllocNone);
+    if(!gl_colormap){
+      fprintf(stderr,"Unable to create private colormap\n");
+      exit(1);
+      }
+    }
+
+  /*
+  ** Use common visual for GUI and GL?
+  ** Maybe you can invoke some hardware interrogation function and
+  ** see if more than one hardware map is supported.  For the purpose
+  ** of this demo, we'll use an environment variable instead.
+  */
+  if(getenv("SAMEVISUAL")!=NULL){
+    gui_visual=gl_visualinfo->visual;
+    gui_colormap=gl_colormap;
+    }
+
+  fprintf(stderr,"GUI uses visual: %lx\n",XVisualIDFromVisual(gui_visual));
+
+  /* Create application shell, finally */
+  n=0;
+  XtSetArg(args[n],XmNvisual,gui_visual); n++;         /* Plug in that visual */
+  XtSetArg(args[n],XmNcolormap,gui_colormap); n++;     /* And that colormap */
+  toplevel=XtAppCreateShell("boilerPlate","BoilerPlate",
+                            applicationShellWidgetClass,display,args,n);
+
+
+  /* Main window */
+  n=0;
+  mainwindow=XmCreateMainWindow(toplevel,"window",args,n);
+  XtManageChild(mainwindow);
+
+  /* Make a menu */
+  n=0;
+  XtSetArg(args[n],XmNmarginWidth,0); n++;
+  XtSetArg(args[n],XmNmarginHeight,0); n++;
+  menubar=XmCreateMenuBar(mainwindow,"menubar",args,2);
+  XtManageChild(menubar);
+
+  n=0;
+  pane=XmCreatePulldownMenu(menubar,"pane",args,n);
+  n=0;
+  but=XmCreatePushButton(pane,"Open",args,n);
+  XtManageChild(but);
+  but=XmCreatePushButton(pane,"Save",args,n);
+  XtManageChild(but);
+  but=XmCreatePushButton(pane,"Save As",args,n);
+  XtManageChild(but);
+  but=XmCreatePushButton(pane,"Quit",args,n);
+  XtAddCallback(but,XmNactivateCallback,byeCB,(XtPointer)NULL);
+  XtManageChild(but);
+  XtSetArg(args[0],XmNsubMenuId,pane);
+  cascade=XmCreateCascadeButton(menubar,"File",args,1);
+  XtManageChild(cascade);
+
+  n=0;
+  pane=XmCreatePulldownMenu(menubar,"pane",args,n);
+  n=0;
+  but=XmCreatePushButton(pane,"About",args,n);
+  XtAddCallback(but,XmNactivateCallback,aboutCB,(XtPointer)NULL);
+  XtManageChild(but);
+  XtSetArg(args[0],XmNsubMenuId,pane);
+  cascade=XmCreateCascadeButton(menubar,"Help",args,1);
+  XtManageChild(cascade);
+  XtVaSetValues(menubar,XmNmenuHelpWidget,cascade,NULL);
+
+  /* Main window form */
+  n=0;
+  XtSetArg(args[n],XmNmarginWidth,5); n++;
+  XtSetArg(args[n],XmNmarginHeight,5); n++;
+  mainform=XmCreateForm(mainwindow,"mainForm",args,n);
+  XtManageChild(mainform);
+
+  /* Some nice button */
+  n=0;
+  XtSetArg(args[n],XmNbottomAttachment,XmATTACH_FORM); n++;
+  XtSetArg(args[n],XmNrightAttachment,XmATTACH_FORM); n++;
+  button=XmCreatePushButton(mainform,"Bye",args,n);
+  XtAddCallback(button,XmNactivateCallback,byeCB,(XtPointer)NULL);
+  XtManageChild(button);
+
+  n=0;
+  XtSetArg(args[n],XmNleftAttachment,XmATTACH_FORM); n++;
+  XtSetArg(args[n],XmNrightAttachment,XmATTACH_FORM); n++;
+  XtSetArg(args[n],XmNbottomAttachment,XmATTACH_WIDGET); n++;
+  XtSetArg(args[n],XmNbottomWidget,button); n++;
+  XtSetArg(args[n],XmNshadowType,XmSHADOW_ETCHED_IN); n++;
+  separator=XmCreateSeparator(mainform,"separator",args,n);
+  XtManageChild(separator);
+
+  /* Main window frame */
+  n = 0;
+  XtSetArg(args[n],XmNleftAttachment,XmATTACH_FORM); n++;
+  XtSetArg(args[n],XmNrightAttachment,XmATTACH_FORM); n++;
+  XtSetArg(args[n],XmNtopAttachment,XmATTACH_FORM); n++;
+  XtSetArg(args[n],XmNbottomAttachment,XmATTACH_WIDGET); n++;
+  XtSetArg(args[n],XmNbottomWidget,separator); n++;
+  XtSetArg(args[n],XmNshadowType,XmSHADOW_IN); n++;
+  mainframe = XmCreateFrame(mainform,"mainFrame",args,n);
+  XtManageChild(mainframe);
+
+  /* GL drawing area */
+  n = 0;
+  XtSetArg(args[n],XmNcolormap,gl_colormap); n++;
+  XtSetArg(args[n],GLwNvisualInfo,gl_visualinfo); n++;
+  XtSetArg(args[n],GLwNinstallColormap,True); n++;
+  XtSetArg(args[n],XmNtraversalOn,True); n++;
+  XtSetArg(args[n],XmNwidth,400); n++;
+  XtSetArg(args[n],XmNheight,300); n++;
+  glwidget = GLwCreateMDrawingArea(mainframe,"glWidget",args,n);
+  XtAddCallback(glwidget,GLwNexposeCallback,(XtCallbackProc)exposeCB,(XtPointer)NULL);
+  XtAddCallback(glwidget,GLwNresizeCallback,(XtCallbackProc)resizeCB,(XtPointer)NULL);
+  XtAddCallback(glwidget,GLwNginitCallback,(XtCallbackProc)initCB,(XtPointer)NULL);
+  XtAddCallback(glwidget,GLwNinputCallback,(XtCallbackProc)inputCB,(XtPointer)NULL);
+  XtManageChild(glwidget);
+
+  /* Set into main window */
+  XmMainWindowSetAreas(mainwindow,menubar,NULL,NULL,NULL,mainform);
+  XtRealizeWidget(toplevel);
+
+  /* Loop until were done */
+  XtAppMainLoop(app_context);
+  return 0;
+  }
+
+
+/* Show visual class */
+static char* showvisualclass(int cls){
+  if(cls==TrueColor) return "TrueColor";
+  if(cls==DirectColor) return "DirectColor";
+  if(cls==PseudoColor) return "PseudoColor";
+  if(cls==StaticColor) return "StaticColor";
+  if(cls==GrayScale) return "GrayScale";
+  if(cls==StaticGray) return "StaticGray";
+  return "Unknown";
+  }
+
+
+static void exposeCB(Widget w,XtPointer client_data,GLwDrawingAreaCallbackStruct *cbs){
+  GLwDrawingAreaMakeCurrent(glwidget,glx_context);
+
+  glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
+  glMatrixMode(GL_PROJECTION);
+
+  glLoadIdentity();
+  glOrtho(-1.0,1.0,-1.0,1.0,0.0,1.0);
+
+  glMatrixMode(GL_MODELVIEW);
+
+  glLoadIdentity();
+
+  glColor3f(1.0,0.0,0.0);
+  glBegin(GL_LINE_STRIP);
+  glVertex3f(-1.0,-1.0,0.0);
+  glVertex3f( 1.0, 1.0,0.0);
+  glEnd();
+  glXSwapBuffers(display,XtWindow(glwidget));
+  }
+
+
+/* Initialize widget */
+static void initCB(Widget w,XtPointer client_data,GLwDrawingAreaCallbackStruct *cbs){
+
+  /* First, create context. We prefer direct rendering */
+  glx_context=glXCreateContext(display,gl_visualinfo,0,TRUE);
+  if(!glx_context){
+    fprintf(stderr,"Unable to create gl context\n");
+    exit(1);
+    }
+
+  /* Make it current */
+  GLwDrawingAreaMakeCurrent(glwidget,glx_context);
+
+  /* Set a viewport */
+  glViewport(0,0,cbs->width,cbs->height);
+
+  /* You might want to do a lot more here ... */
+  glEnable(GL_DEPTH_TEST);
+  glDepthFunc(GL_LEQUAL);
+  glClearColor(1.0,1.0,1.0,1.0);
+  glClearDepth(1.0);
+
+
+  }
+
+
+/* Widget changed size, so adjust txform */
+static void resizeCB(Widget w,XtPointer client_data,GLwDrawingAreaCallbackStruct *cbs){
+  GLwDrawingAreaMakeCurrent(glwidget,glx_context);
+  glViewport(0,0,cbs->width,cbs->height);
+
+  /* blablabla */
+  }
+
+
+/* Boilerplate event handling */
+static void inputCB(Widget w,XtPointer client_data,GLwDrawingAreaCallbackStruct *cbs){
+  switch(cbs->event->type){
+    case ButtonPress:
+      switch(cbs->event->xbutton.button){
+        case Button1: fprintf(stderr,"Pressed 1\n"); break;
+        case Button2: fprintf(stderr,"Pressed 2\n"); break;
+        case Button3: fprintf(stderr,"Pressed 3\n"); break;
+        }
+      break;
+    case ButtonRelease:
+      switch(cbs->event->xbutton.button){
+        case Button1: fprintf(stderr,"Released 1\n"); break;
+        case Button2: fprintf(stderr,"Released 2\n"); break;
+        case Button3: fprintf(stderr,"Released 3\n"); break;
+        }
+      break;
+    case MotionNotify:
+      fprintf(stderr,"Moved mouse to (%d %d)\n",
+              cbs->event->xbutton.x,
+              cbs->event->xbutton.y);
+      break;
+    }
+  }
+
+
+/* Hasta la vista, baby */
+static void byeCB(Widget w,XtPointer client_data,XtPointer call_data){
+  exit(0);
+  }
+
+
+/* Pop informative panel */
+static void aboutCB(Widget w,XtPointer client_data,XtPointer call_data){
+  Arg args[10];
+  XmString str;
+  Widget box;
+  str=XmStringCreateLtoR("Boilerplate Mixed Model Programming Example\n\n   (C) 1996 Jeroen van der Zijp \n\n    jvz@cyberia.cfdrc.com",XmSTRING_DEFAULT_CHARSET);
+  XtSetArg(args[0],XmNnoResize,True);
+  XtSetArg(args[1],XmNautoUnmanage,True);
+  XtSetArg(args[2],XmNmessageString,str);
+  XtSetArg(args[3],XmNdefaultPosition,False);
+  box=XmCreateInformationDialog(toplevel,"About Boilerplate",args,4);
+  XtManageChild(box);
+  XtUnmanageChild(XmMessageBoxGetChild(box,XmDIALOG_HELP_BUTTON));
+  XtUnmanageChild(XmMessageBoxGetChild(box,XmDIALOG_CANCEL_BUTTON));
+  XmStringFree(str);
+  }
diff --git a/src/glw/depend b/src/glw/depend
new file mode 100644 (file)
index 0000000..e0c23de
--- /dev/null
@@ -0,0 +1,6 @@
+# DO NOT DELETE
+
+GLwDrawA.o: ../include/GL/glx.h ../include/GL/gl.h ../include/GL/xmesa.h
+GLwDrawA.o: GLwDrawAP.h GLwDrawA.h
+GLwMDrawA.o: GLwDrawA.c ../include/GL/glx.h ../include/GL/gl.h
+GLwMDrawA.o: ../include/GL/xmesa.h GLwDrawAP.h GLwDrawA.h GLwMDrawAP.h
diff --git a/src/mesa/Makefile.X11 b/src/mesa/Makefile.X11
new file mode 100644 (file)
index 0000000..e6419b5
--- /dev/null
@@ -0,0 +1,243 @@
+# $Id: Makefile.X11,v 1.1 1999/08/19 00:55:41 jtg Exp $
+
+# Mesa 3-D graphics library
+# Version:  3.1
+# Copyright (C) 1995-1999  Brian Paul
+
+# Makefile for core library
+
+
+##### MACROS #####
+
+VPATH = RCS
+
+INCDIR = ../include
+LIBDIR = ../lib
+
+CORE_SOURCES = \
+       accum.c \
+       alpha.c \
+       alphabuf.c \
+       api1.c \
+       api2.c \
+       apiext.c \
+       attrib.c \
+       bbox.c \
+       bitmap.c \
+       blend.c \
+       clip.c \
+       colortab.c \
+       config.c \
+       context.c \
+       copypix.c \
+       cva.c \
+       debug_xform.c \
+       depth.c \
+       dlist.c \
+       drawpix.c \
+       enable.c \
+       enums.c \
+       eval.c \
+       extensions.c \
+       feedback.c \
+       fog.c \
+       get.c \
+       hash.c \
+       image.c \
+       light.c \
+       lines.c \
+       logic.c \
+       masking.c \
+       matrix.c \
+       misc.c \
+       mmath.c \
+       mthreads.c \
+       pb.c \
+       pixel.c \
+       pipeline.c \
+       points.c \
+       pointers.c \
+       polygon.c \
+       quads.c \
+       rastpos.c \
+       readpix.c \
+       rect.c \
+       scissor.c \
+       shade.c \
+       span.c \
+       stages.c \
+       stencil.c \
+       teximage.c \
+       texobj.c \
+       texstate.c \
+       texture.c \
+       translate.c \
+       triangle.c \
+       varray.c \
+       vb.c \
+       vbcull.c \
+       vbfill.c \
+       vbindirect.c \
+       vbrender.c \
+       vbxform.c \
+       vector.c \
+       winpos.c \
+       xform.c \
+       zoom.c \
+       X86/x86.c \
+       X86/common_x86.c \
+       X86/3dnow.c
+
+DRIVER_SOURCES = \
+       X/glxapi.c \
+       X/fakeglx.c \
+       X/realglx.c \
+       X/xfonts.c \
+       X/xmesa1.c \
+       X/xmesa2.c \
+       X/xmesa3.c \
+       X/xmesa4.c \
+       OSmesa/osmesa.c \
+       SVGA/svgamesa.c \
+       FX/fxapi.c \
+       FX/fxclip.c \
+       FX/fxcva.c \
+       FX/fxdd.c \
+       FX/fxddspan.c \
+       FX/fxddtex.c \
+       FX/fxfastpath.c \
+       FX/fxpipeline.c \
+       FX/fxrender.c \
+       FX/fxsanity.c \
+       FX/fxsetup.c \
+       FX/fxtexman.c \
+       FX/fxtrifuncs.c \
+       FX/fxvsetup.c \
+       FX/fxglidew.c 
+#      GGI/ggimesa.c
+
+ASM_SOURCES = 
+
+ADDITIONAL_OBJ = 
+
+OBJECTS = $(ASM_SOURCES:.S=.o) \
+       $(CORE_SOURCES:.c=.o) \
+       $(DRIVER_SOURCES:.c=.o) \
+       $(ADDITIONAL_OBJ)
+
+
+#who put these here!?!
+#GL_LIB = libMesaGL.so
+#GLU_LIB = libMesaGLU.so
+#GLUT_LIB = libglut.so
+#CC = gcc
+#INCLUDES=-I. -I../include -I/usr/X11R6/include -I/usr/include/glide -I/usr/local/glide/include
+
+
+##### RULES #####
+
+.c.o:
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+
+.S.o:
+       $(CC) -c $(CFLAGS) $< -o $@
+
+
+# UGH! These rules shouldn't be needed but IRIX's make (and others?) needs them
+X/glxapi.o: X/glxapi.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+X/fakeglx.o: X/fakeglx.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+X/realglx.o: X/realglx.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+X/xfonts.o: X/xfonts.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+X/xmesa1.o: X/xmesa1.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+X/xmesa2.o: X/xmesa2.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+X/xmesa3.o: X/xmesa3.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+X/xmesa4.o: X/xmesa4.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+SVGA/svgamesa.o: SVGA/svgamesa.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+OSmesa/osmesa.o: OSmesa/osmesa.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+FX/fxapi.o: FX/fxapi.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+FX/fxclip.o: FX/fxclip.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+FX/fxcva.o: FX/fxcva.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+FX/fxdd.o: FX/fxdd.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+FX/fxddspan.o: FX/fxddspan.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+FX/fxddtex.o: FX/fxddtex.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+FX/fxfastpath.o: FX/fxfastpath.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+FX/fxpipeline.o: FX/fxpipeline.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+FX/fxrender.o: FX/fxrender.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+FX/fxsanity.o: FX/fxsanity.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+FX/fxsetup.o: FX/fxsetup.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+FX/fxtrifuncs.o: FX/fxtrifuncs.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+FX/fxtexman.o: FX/fxtexman.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+FX/fxvsetup.o: FX/fxvsetup.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+FX/fxglidew.o: FX/fxglidew.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+FX/X86/fx_3dnow_fastpath.o: FX/X86/fx_3dnow_fastpath.S FX/X86/fx_regoff.h
+FX/X86/fx_regoff.h: FX/X86/fx_gen_regoff
+       $< > $@
+FX/X86/fx_gen_regoff : FX/X86/fx_gen_regoff.c
+       $(CC) -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+GGI/ggimesa.o: GGI/ggimesa.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+X86/x86.o: X86/x86.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+X86/common_x86.o: X86/common_x86.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+X86/3dnow.o: X86/3dnow.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+
+
+##### TARGETS #####
+
+#default:
+#      @echo "Specify a target configuration"
+
+clean:
+       -rm *.o *~ */*.o */*~
+
+targets: $(LIBDIR)/$(GL_LIB)
+
+# Make the library
+$(LIBDIR)/$(GL_LIB): $(OBJECTS)
+       $(MAKELIB) $(GL_LIB) $(MAJOR) $(MINOR) $(OBJECTS)
+       rm -f $(LIBDIR)/$(GL_LIB)*
+       mv $(GL_LIB)* $(LIBDIR)
+
+
+include ../Make-config
+
+include depend
+
+
+
+#
+# Run 'make dep' to update the dependencies if you change what's included
+# by any source file.
+# 
+dep: $(CORE_SOURCES) $(DRIVER_SOURCES)
+       makedepend -fdepend -Y -I../include -DGGI -DSVGA -DFX $(CORE_SOURCES) $(DRIVER_SOURCES)
+
+tags:
+       etags `find . -name \*.[ch]` `find ../include`
diff --git a/src/mesa/drivers/allegro/amesa.c b/src/mesa/drivers/allegro/amesa.c
new file mode 100644 (file)
index 0000000..6e0f21d
--- /dev/null
@@ -0,0 +1,395 @@
+/*\r
+ * Mesa 3-D graphics library\r
+ * Version:  3.0\r
+ * Copyright (C) 1995-1998  Brian Paul\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Library General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Library General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Library General Public\r
+ * License along with this library; if not, write to the Free\r
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
+ */\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <allegro.h>\r
+#include "context.h"\r
+#include "matrix.h"\r
+#include "types.h"\r
+#include "GL/amesa.h"\r
+\r
+\r
+struct amesa_visual\r
+    {\r
+    GLvisual   *GLVisual;       /* inherit from GLvisual      */\r
+    GLboolean   DBFlag;         /* double buffered?           */\r
+    GLuint      Depth;          /* bits per pixel ( >= 15 )   */\r
+    };\r
+\r
+\r
+struct amesa_buffer\r
+    {\r
+    GLframebuffer *GLBuffer;    /* inherit from GLframebuffer */\r
+    GLuint         Width, Height;\r
+    BITMAP        *Screen;\r
+       BITMAP        *Background;\r
+       BITMAP        *Active;\r
+    };\r
+\r
+\r
+struct amesa_context\r
+    {\r
+    GLcontext   *GLContext;     /* inherit from GLcontext     */\r
+    AMesaVisual  Visual;\r
+       AMesaBuffer  Buffer;\r
+    GLuint       ClearColor;\r
+    GLuint       CurrentColor;\r
+    };\r
+\r
+\r
+static void setup_dd_pointers(GLcontext *ctx);\r
+\r
+\r
+/**********************************************************************/\r
+/*****                   drawing functions                        *****/\r
+/**********************************************************************/\r
+\r
+#define FLIP(context, y)  (context->Buffer->Height - (y) - 1)\r
+\r
+#include "allegro/generic.h"\r
+#include "allegro/direct.h"\r
+\r
+\r
+/**********************************************************************/\r
+/*****            15-bit accelerated drawing funcs                *****/\r
+/**********************************************************************/\r
+\r
+IMPLEMENT_WRITE_RGBA_SPAN(15, unsigned short)\r
+IMPLEMENT_WRITE_RGB_SPAN(15, unsigned short)\r
+IMPLEMENT_WRITE_MONO_RGBA_SPAN(15, unsigned short)\r
+IMPLEMENT_READ_RGBA_SPAN(15, unsigned short)\r
+IMPLEMENT_WRITE_RGBA_PIXELS(15, unsigned short)\r
+IMPLEMENT_WRITE_MONO_RGBA_PIXELS(15, unsigned short)\r
+IMPLEMENT_READ_RGBA_PIXELS(15, unsigned short)\r
+\r
+\r
+/**********************************************************************/\r
+/*****            16-bit accelerated drawing funcs                *****/\r
+/**********************************************************************/\r
+\r
+IMPLEMENT_WRITE_RGBA_SPAN(16, unsigned short)\r
+IMPLEMENT_WRITE_RGB_SPAN(16, unsigned short)\r
+IMPLEMENT_WRITE_MONO_RGBA_SPAN(16, unsigned short)\r
+IMPLEMENT_READ_RGBA_SPAN(16, unsigned short)\r
+IMPLEMENT_WRITE_RGBA_PIXELS(16, unsigned short)\r
+IMPLEMENT_WRITE_MONO_RGBA_PIXELS(16, unsigned short)\r
+IMPLEMENT_READ_RGBA_PIXELS(16, unsigned short)\r
+\r
+\r
+/**********************************************************************/\r
+/*****            32-bit accelerated drawing funcs                *****/\r
+/**********************************************************************/\r
+\r
+IMPLEMENT_WRITE_RGBA_SPAN(32, unsigned long)\r
+IMPLEMENT_WRITE_RGB_SPAN(32, unsigned long)\r
+IMPLEMENT_WRITE_MONO_RGBA_SPAN(32, unsigned long)\r
+IMPLEMENT_READ_RGBA_SPAN(32, unsigned long)\r
+IMPLEMENT_WRITE_RGBA_PIXELS(32, unsigned long)\r
+IMPLEMENT_WRITE_MONO_RGBA_PIXELS(32, unsigned long)\r
+IMPLEMENT_READ_RGBA_PIXELS(32, unsigned long)\r
+\r
+\r
+/**********************************************************************/\r
+/*****              Miscellaneous device driver funcs             *****/\r
+/**********************************************************************/\r
+\r
+static GLboolean set_buffer(GLcontext *ctx, GLenum mode)\r
+    {\r
+    AMesaContext context = (AMesaContext)(ctx->DriverCtx);\r
+    GLboolean    ok      = GL_TRUE;\r
+\r
+    if (mode == GL_FRONT_LEFT)\r
+        context->Buffer->Active = context->Buffer->Screen;\r
+\r
+    else if (mode == GL_BACK_LEFT)\r
+        {\r
+        if (context->Buffer->Background)\r
+            context->Buffer->Active = context->Buffer->Background;\r
+        else\r
+            ok = GL_FALSE;\r
+        }\r
+\r
+    else\r
+        ok = GL_FALSE;\r
+\r
+    return ok;\r
+    }\r
+\r
+\r
+static void get_buffer_size(GLcontext *ctx, GLuint *width, GLuint *height)\r
+    {\r
+       AMesaContext context = (AMesaContext)(ctx->DriverCtx);\r
+\r
+    *width  = context->Buffer->Width;\r
+    *height = context->Buffer->Height;\r
+    }\r
+\r
+\r
+/**********************************************************************/\r
+/**********************************************************************/\r
+\r
+static void setup_dd_pointers(GLcontext *ctx)\r
+       {\r
+       AMesaContext context = (AMesaContext)(ctx->DriverCtx);\r
+\r
+       /* Initialize all the pointers in the driver struct. Do this whenever */\r
+       /* a new context is made current or we change buffers via set_buffer! */\r
+\r
+    ctx->Driver.UpdateState   = setup_dd_pointers;\r
+       ctx->Driver.SetBuffer     = set_buffer;\r
+       ctx->Driver.GetBufferSize = get_buffer_size;\r
+\r
+    ctx->Driver.Color               = set_color_generic;\r
+    ctx->Driver.ClearColor          = clear_color_generic;\r
+    ctx->Driver.Clear               = clear_generic;\r
+    ctx->Driver.WriteRGBASpan       = write_rgba_span_generic;\r
+    ctx->Driver.WriteRGBSpan        = write_rgb_span_generic;\r
+    ctx->Driver.WriteMonoRGBASpan   = write_mono_rgba_span_generic;\r
+    ctx->Driver.WriteRGBAPixels     = write_rgba_pixels_generic;\r
+    ctx->Driver.WriteMonoRGBAPixels = write_mono_rgba_pixels_generic;\r
+    ctx->Driver.ReadRGBASpan        = read_rgba_span_generic;\r
+    ctx->Driver.ReadRGBAPixels      = read_rgba_pixels_generic;\r
+\r
+    if (context->Buffer->Active != screen)\r
+        {\r
+        switch (context->Visual->Depth)\r
+            {\r
+            case 15:\r
+                ctx->Driver.WriteRGBASpan       = write_rgba_span_15;\r
+                ctx->Driver.WriteRGBSpan        = write_rgb_span_15;\r
+                ctx->Driver.WriteMonoRGBASpan   = write_mono_rgba_span_15;\r
+                ctx->Driver.WriteRGBAPixels     = write_rgba_pixels_15;\r
+                ctx->Driver.WriteMonoRGBAPixels = write_mono_rgba_pixels_15;\r
+                ctx->Driver.ReadRGBASpan        = read_rgba_span_15;\r
+                ctx->Driver.ReadRGBAPixels      = read_rgba_pixels_15;\r
+                break;\r
+\r
+            case 16:\r
+                ctx->Driver.WriteRGBASpan       = write_rgba_span_16;\r
+                ctx->Driver.WriteRGBSpan        = write_rgb_span_16;\r
+                ctx->Driver.WriteMonoRGBASpan   = write_mono_rgba_span_16;\r
+                ctx->Driver.WriteRGBAPixels     = write_rgba_pixels_16;\r
+                ctx->Driver.WriteMonoRGBAPixels = write_mono_rgba_pixels_16;\r
+                ctx->Driver.ReadRGBASpan        = read_rgba_span_16;\r
+                ctx->Driver.ReadRGBAPixels      = read_rgba_pixels_16;\r
+                break;\r
+\r
+            case 32:\r
+                ctx->Driver.WriteRGBASpan       = write_rgba_span_32;\r
+                ctx->Driver.WriteRGBSpan        = write_rgb_span_32;\r
+                ctx->Driver.WriteMonoRGBASpan   = write_mono_rgba_span_32;\r
+                ctx->Driver.WriteRGBAPixels     = write_rgba_pixels_32;\r
+                ctx->Driver.WriteMonoRGBAPixels = write_mono_rgba_pixels_32;\r
+                ctx->Driver.ReadRGBASpan        = read_rgba_span_32;\r
+                ctx->Driver.ReadRGBAPixels      = read_rgba_pixels_32;\r
+                break;\r
+            }\r
+        }\r
+       }\r
+\r
+\r
+/**********************************************************************/\r
+/*****                AMesa Public API Functions                  *****/\r
+/**********************************************************************/\r
+\r
+\r
+AMesaVisual AMesaCreateVisual(GLboolean dbFlag, GLint depth,\r
+                              GLint depthSize, GLint stencilSize, GLint accumSize)\r
+       {\r
+       AMesaVisual visual;\r
+    GLbyte      redBits, greenBits, blueBits;\r
+\r
+    visual = (AMesaVisual)calloc(1, sizeof(struct amesa_visual));\r
+       if (!visual)\r
+       return NULL;\r
+\r
+    switch (depth)\r
+        {\r
+        case 15:\r
+            redBits   = 5;\r
+            greenBits = 5;\r
+            blueBits  = 5;\r
+            break;\r
+\r
+        case 16:\r
+            redBits   = 5;\r
+            greenBits = 6;\r
+            blueBits  = 5;\r
+            break;\r
+\r
+        case 24: case 32:\r
+            redBits   = 8;\r
+            greenBits = 8;\r
+            blueBits  = 8;\r
+            break;\r
+\r
+        default:\r
+            free(visual);\r
+            return NULL;\r
+        }\r
+\r
+    visual->DBFlag   = dbFlag;\r
+    visual->Depth    = depth;\r
+    visual->GLVisual = gl_create_visual(GL_TRUE,    /* rgb mode       */\r
+                                        GL_TRUE,    /* software alpha */\r
+                                        dbFlag,     /* db_flag        */\r
+                                        GL_FALSE,   /* stereo         */\r
+                                        depthSize,  /* depth bits     */\r
+                                        stencilSize,/* stencil bits   */\r
+                                        accumSize,  /* accum bits     */\r
+                                        0,          /* index bits     */\r
+                                        redBits, greenBits, blueBits, 0);\r
+    if (!visual->GLVisual)\r
+        {\r
+        free(visual);\r
+        return NULL;\r
+        }\r
+\r
+       return visual;\r
+       }\r
+\r
+\r
+void AMesaDestroyVisual(AMesaVisual visual)\r
+       {\r
+    gl_destroy_visual(visual->GLVisual);\r
+       free(visual);\r
+       }\r
+\r
+\r
+AMesaBuffer AMesaCreateBuffer(AMesaVisual visual,\r
+                                                         GLint width, GLint height)\r
+       {\r
+       AMesaBuffer buffer;\r
+\r
+    buffer = (AMesaBuffer)calloc(1, sizeof(struct amesa_buffer));\r
+       if (!buffer)\r
+       return NULL;\r
+\r
+       buffer->Screen     = NULL;\r
+       buffer->Background = NULL;\r
+       buffer->Active     = NULL;\r
+       buffer->Width      = width;\r
+       buffer->Height     = height;\r
+\r
+       if (visual->DBFlag)\r
+               {\r
+               buffer->Background = create_bitmap_ex(visual->Depth, width, height);\r
+               if (!buffer->Background)\r
+                       {\r
+                       free(buffer);\r
+                       return NULL;\r
+                       }\r
+               }\r
+\r
+    buffer->GLBuffer = gl_create_framebuffer(visual->GLVisual);\r
+    if (!buffer->GLBuffer)\r
+        {\r
+        if (buffer->Background) destroy_bitmap(buffer->Background);\r
+        free(buffer);\r
+        return NULL;\r
+        }\r
+\r
+       return buffer;\r
+       }\r
+\r
+\r
+void AMesaDestroyBuffer(AMesaBuffer buffer)\r
+       {\r
+    if (buffer->Screen)     destroy_bitmap(buffer->Screen);\r
+       if (buffer->Background) destroy_bitmap(buffer->Background);\r
+    gl_destroy_framebuffer(buffer->GLBuffer);\r
+       free(buffer);\r
+       }\r
+\r
+\r
+AMesaContext AMesaCreateContext(AMesaVisual visual,\r
+                                AMesaContext share)\r
+       {\r
+       AMesaContext context;\r
+       GLboolean    direct = GL_FALSE;\r
+\r
+    context = (AMesaContext)calloc(1, sizeof(struct amesa_context));\r
+       if (!context)\r
+               return NULL;\r
+\r
+       context->Visual       = visual;\r
+       context->Buffer           = NULL;\r
+       context->ClearColor   = 0;\r
+       context->CurrentColor = 0;\r
+    context->GLContext    = gl_create_context(visual->GLVisual,\r
+                                              share ? share->GLContext : NULL,\r
+                                                     (void*)context,\r
+                                              direct);\r
+    if (!context->GLContext)\r
+        {\r
+        free(context);\r
+        return NULL;\r
+        }\r
+\r
+       return context;\r
+       }\r
+\r
+\r
+void AMesaDestroyContext(AMesaContext context)\r
+       {\r
+    gl_destroy_context(context->GLContext);\r
+       free(context);\r
+       }\r
+\r
+\r
+GLboolean AMesaMakeCurrent(AMesaContext context, AMesaBuffer buffer)\r
+       {\r
+       if (context && buffer)\r
+               {\r
+       set_color_depth(context->Visual->Depth);\r
+        if (set_gfx_mode(GFX_AUTODETECT, buffer->Width, buffer->Height, 0, 0) != 0)\r
+            return GL_FALSE;\r
+\r
+               context->Buffer = buffer;\r
+        buffer->Screen  = screen;\r
+        buffer->Active  = buffer->Background ? buffer->Background : screen;\r
+        \r
+        setup_dd_pointers(context->GLContext);\r
+        gl_make_current(context->GLContext, buffer->GLBuffer);\r
+        gl_Viewport(context->GLContext, 0, 0, buffer->Width, buffer->Height);\r
+       }\r
+       else\r
+               {\r
+        destroy_bitmap(context->Buffer->Screen);\r
+        context->Buffer->Screen = NULL;\r
+        context->Buffer->Active = NULL;\r
+        context->Buffer         = NULL;\r
+       gl_make_current(NULL, NULL);\r
+               }\r
+\r
+    return GL_TRUE;\r
+       }\r
+\r
+\r
+void AMesaSwapBuffers(AMesaBuffer buffer)\r
+       {\r
+       if (buffer->Background)\r
+               {\r
+               blit(buffer->Background, buffer->Screen,\r
+             0, 0, 0, 0,\r
+             buffer->Width, buffer->Height);\r
+               }\r
+       }\r
diff --git a/src/mesa/drivers/allegro/direct.h b/src/mesa/drivers/allegro/direct.h
new file mode 100644 (file)
index 0000000..3998fc1
--- /dev/null
@@ -0,0 +1,189 @@
+/*\r
+ * Mesa 3-D graphics library\r
+ * Version:  3.0\r
+ * Copyright (C) 1995-1998  Brian Paul\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Library General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Library General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Library General Public\r
+ * License along with this library; if not, write to the Free\r
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
+ */\r
+\r
+\r
+#define DESTINATION(BMP, X, Y, TYPE)                                \\r
+    ({                                                              \\r
+    BITMAP *_bmp = BMP;                                             \\r
+                                                                    \\r
+    (TYPE*)(_bmp->line[_bmp->h - (Y) - 1]) + (X);                   \\r
+    })\r
+\r
+\r
+#define IMPLEMENT_WRITE_RGBA_SPAN(DEPTH, TYPE)                                                   \\r
+static void write_rgba_span_##DEPTH (const GLcontext *ctx,                                       \\r
+                                     GLuint n, GLint x, GLint y,                                 \\r
+                                     const GLubyte rgba[][4],                                    \\r
+                                     const GLubyte mask[])                                       \\r
+    {                                                                                            \\r
+    AMesaContext context = (AMesaContext)(ctx->DriverCtx);                                       \\r
+    TYPE              *d = DESTINATION(context->Buffer->Active, x, y, TYPE);                     \\r
+                                                                                                 \\r
+    if (mask)                                                                                    \\r
+        {                                                                                        \\r
+        while (n--)                                                                              \\r
+            {                                                                                    \\r
+            if (mask[0]) d[0] = makecol##DEPTH(rgba[0][RCOMP], rgba[0][GCOMP], rgba[0][BCOMP]);  \\r
+            d++; rgba++; mask++;                                                                 \\r
+            }                                                                                    \\r
+        }                                                                                        \\r
+    else                                                                                         \\r
+        {                                                                                        \\r
+        while (n--)                                                                              \\r
+            {                                                                                    \\r
+            d[0] = makecol##DEPTH(rgba[0][RCOMP], rgba[0][GCOMP], rgba[0][BCOMP]);               \\r
+            d++; rgba++;                                                                         \\r
+            }                                                                                    \\r
+        }                                                                                        \\r
+    }\r
+\r
+\r
+#define IMPLEMENT_WRITE_RGB_SPAN(DEPTH, TYPE)                                                    \\r
+static void write_rgb_span_##DEPTH (const GLcontext *ctx,                                        \\r
+                                    GLuint n, GLint x, GLint y,                                  \\r
+                                    const GLubyte rgb[][3],                                      \\r
+                                    const GLubyte mask[])                                        \\r
+    {                                                                                            \\r
+    AMesaContext context = (AMesaContext)(ctx->DriverCtx);                                       \\r
+    TYPE              *d = DESTINATION(context->Buffer->Active, x, y, TYPE);                     \\r
+                                                                                                 \\r
+    if (mask)                                                                                    \\r
+        {                                                                                        \\r
+        while (n--)                                                                              \\r
+            {                                                                                    \\r
+            if (mask[0]) d[0] = makecol##DEPTH(rgb[0][RCOMP], rgb[0][GCOMP], rgb[0][BCOMP]);     \\r
+            d++; rgb++; mask++;                                                                  \\r
+            }                                                                                    \\r
+        }                                                                                        \\r
+    else                                                                                         \\r
+        {                                                                                        \\r
+        while (n--)                                                                              \\r
+            {                                                                                    \\r
+            d[0] = makecol##DEPTH(rgb[0][RCOMP], rgb[0][GCOMP], rgb[0][BCOMP]);                  \\r
+            d++; rgb++;                                                                          \\r
+            }                                                                                    \\r
+        }                                                                                        \\r
+    }\r
+\r
+\r
+#define IMPLEMENT_WRITE_MONO_RGBA_SPAN(DEPTH, TYPE)                                              \\r
+static void write_mono_rgba_span_##DEPTH (const GLcontext *ctx,                                  \\r
+                                          GLuint n, GLint x, GLint y,                            \\r
+                                          const GLubyte mask[])                                  \\r
+    {                                                                                            \\r
+    AMesaContext context = (AMesaContext)(ctx->DriverCtx);                                       \\r
+    TYPE           color = context->CurrentColor;                                                \\r
+    TYPE              *d = DESTINATION(context->Buffer->Active, x, y, TYPE);                     \\r
+                                                                                                 \\r
+    while (n--)                                                                                  \\r
+        {                                                                                        \\r
+        if (mask[0]) d[0] = color;                                                               \\r
+        d++; mask++;                                                                             \\r
+        }                                                                                        \\r
+    }\r
+\r
+\r
+#define IMPLEMENT_READ_RGBA_SPAN(DEPTH, TYPE)                           \\r
+static void read_rgba_span_##DEPTH (const GLcontext *ctx,                              \\r
+                                    GLuint n, GLint x, GLint y,                        \\r
+                                    GLubyte rgba[][4])                                 \\r
+    {                                                                                                                                  \\r
+    AMesaContext context = (AMesaContext)(ctx->DriverCtx);                             \\r
+    BITMAP          *bmp = context->Buffer->Active;                     \\r
+    TYPE              *d = DESTINATION(bmp, x, y, TYPE);                \\r
+                                                                        \\r
+    while (n--)                                                         \\r
+        {                                                               \\r
+        rgba[0][RCOMP] = getr##DEPTH(d[0]);                             \\r
+        rgba[0][GCOMP] = getg##DEPTH(d[0]);                             \\r
+        rgba[0][BCOMP] = getb##DEPTH(d[0]);                             \\r
+        rgba[0][ACOMP] = 255;                                           \\r
+                                                                        \\r
+        d++; rgba++;                                                    \\r
+        }                                                               \\r
+    }\r
+\r
+\r
+#define IMPLEMENT_WRITE_RGBA_PIXELS(DEPTH, TYPE)                                                                                 \\r
+static void write_rgba_pixels_##DEPTH (const GLcontext *ctx,                                                                     \\r
+                                       GLuint n,                                                                                 \\r
+                                       const GLint x[],                                                                          \\r
+                                       const GLint y[],                                                                          \\r
+                                       const GLubyte rgba[][4],                                                                  \\r
+                                       const GLubyte mask[])                                                                     \\r
+    {                                                                                                                            \\r
+    AMesaContext context = (AMesaContext)(ctx->DriverCtx);                                                                       \\r
+    BITMAP          *bmp = context->Buffer->Active;                                                                              \\r
+                                                                                                                                 \\r
+    while (n--)                                                                                                                  \\r
+        {                                                                                                                        \\r
+        if (mask[0]) *DESTINATION(bmp, x[0], y[0], TYPE) = makecol##DEPTH(rgba[0][RCOMP], rgba[0][GCOMP], rgba[0][BCOMP]);       \\r
+        rgba++; x++; y++; mask++;                                                                                                \\r
+        }                                                                                                                        \\r
+    }\r
+\r
+\r
+\r
+#define IMPLEMENT_WRITE_MONO_RGBA_PIXELS(DEPTH, TYPE)                                                                            \\r
+static void write_mono_rgba_pixels_##DEPTH (const GLcontext *ctx,                                                                \\r
+                                            GLuint n,                                                                            \\r
+                                            const GLint x[],                                                                     \\r
+                                            const GLint y[],                                                                     \\r
+                                            const GLubyte mask[])                                                                \\r
+    {                                                                                                                            \\r
+    AMesaContext context = (AMesaContext)(ctx->DriverCtx);                                                                       \\r
+    TYPE          color  = context->CurrentColor;                                                                                \\r
+    BITMAP          *bmp = context->Buffer->Active;                                                                              \\r
+                                                                                                                                 \\r
+    while (n--)                                                                                                                  \\r
+        {                                                                                                                        \\r
+        if (mask[0]) *DESTINATION(bmp, x[0], y[0], TYPE) = color;                                                                \\r
+        x++; y++; mask++;                                                                                                        \\r
+        }                                                                                                                        \\r
+    }\r
+\r
+\r
+#define IMPLEMENT_READ_RGBA_PIXELS(DEPTH, TYPE)                         \\r
+static void read_rgba_pixels_##DEPTH (const GLcontext *ctx,                            \\r
+                                         GLuint n,                                                     \\r
+                                         const GLint x[],                                      \\r
+                                         const GLint y[],                                      \\r
+                                         GLubyte rgba[][4],                            \\r
+                                         const GLubyte mask[])                         \\r
+    {                                                                                                                                  \\r
+    AMesaContext context = (AMesaContext)(ctx->DriverCtx);                             \\r
+    BITMAP          *bmp = context->Buffer->Active;                     \\r
+                                                                        \\r
+    while (n--)                                                         \\r
+        {                                                               \\r
+        if (mask[0])                                                    \\r
+            {                                                           \\r
+            int color = *DESTINATION(bmp, x[0], y[0], TYPE);            \\r
+                                                                        \\r
+            rgba[0][RCOMP] = getr##DEPTH(color);                        \\r
+            rgba[0][GCOMP] = getg##DEPTH(color);                        \\r
+            rgba[0][BCOMP] = getb##DEPTH(color);                        \\r
+            rgba[0][ACOMP] = 255;                                       \\r
+            }                                                           \\r
+                                                                        \\r
+        x++; y++; rgba++; mask++;                                       \\r
+        }                                                               \\r
+    }\r
+\r
diff --git a/src/mesa/drivers/allegro/generic.h b/src/mesa/drivers/allegro/generic.h
new file mode 100644 (file)
index 0000000..898a055
--- /dev/null
@@ -0,0 +1,233 @@
+/*\r
+ * Mesa 3-D graphics library\r
+ * Version:  3.0\r
+ * Copyright (C) 1995-1998  Brian Paul\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Library General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Library General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Library General Public\r
+ * License along with this library; if not, write to the Free\r
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
+ */\r
+\r
+static void clear_color_generic(GLcontext *ctx,\r
+                                GLubyte red,  GLubyte green,\r
+                                GLubyte blue, GLubyte alpha)\r
+    {\r
+    AMesaContext context = (AMesaContext)(ctx->DriverCtx);\r
+\r
+    context->ClearColor = makecol(red, green, blue);\r
+    }\r
+\r
+\r
+static void set_color_generic(GLcontext *ctx,\r
+                              GLubyte red,  GLubyte green,\r
+                              GLubyte blue, GLubyte alpha)\r
+    {\r
+    AMesaContext context = (AMesaContext)(ctx->DriverCtx);\r
+\r
+    context->CurrentColor = makecol(red, green, blue);\r
+    }\r
+\r
+\r
+static GLbitfield clear_generic(GLcontext *ctx,\r
+                                GLbitfield mask, GLboolean all,\r
+                                GLint x, GLint y,\r
+                                GLint width, GLint height)\r
+    {\r
+    AMesaContext context = (AMesaContext)(ctx->DriverCtx);\r
+\r
+    if (mask & GL_COLOR_BUFFER_BIT)\r
+        {\r
+        if (all)\r
+            clear_to_color(context->Buffer->Active, context->ClearColor);\r
+        else\r
+            rect(context->Buffer->Active,\r
+                 x, y, x+width-1, y+height-1,\r
+                 context->ClearColor);\r
+        }\r
+\r
+    return mask & (~GL_COLOR_BUFFER_BIT);\r
+    }\r
+\r
+\r
+static void write_rgba_span_generic(const GLcontext *ctx,\r
+                                    GLuint n, GLint x, GLint y,\r
+                                    const GLubyte rgba[][4],\r
+                                    const GLubyte mask[])\r
+    {\r
+    AMesaContext context = (AMesaContext)(ctx->DriverCtx);\r
+    BITMAP          *bmp = context->Buffer->Active;\r
+\r
+    y = FLIP(context, y);\r
+\r
+    if (mask)\r
+        {\r
+        while (n--)\r
+            {\r
+            if (mask[0]) putpixel(bmp, x, y, makecol(rgba[0][RCOMP], rgba[0][GCOMP], rgba[0][BCOMP]));\r
+            x++; mask++; rgba++;\r
+            }\r
+        }\r
+    else\r
+        {\r
+        while (n--)\r
+            {\r
+            putpixel(bmp, x, y, makecol(rgba[0][RCOMP], rgba[0][GCOMP], rgba[0][BCOMP]));\r
+            x++; rgba++;\r
+            }\r
+        }\r
+    }\r
+\r
+\r
+static void write_rgb_span_generic(const GLcontext *ctx,\r
+                                   GLuint n, GLint x, GLint y,\r
+                                   const GLubyte rgb[][3],\r
+                                   const GLubyte mask[])\r
+    {\r
+    AMesaContext context = (AMesaContext)(ctx->DriverCtx);\r
+    BITMAP          *bmp = context->Buffer->Active;\r
+\r
+    y = FLIP(context, y);\r
+\r
+    if (mask)\r
+        {\r
+        while(n--)\r
+            {\r
+            if (mask[0]) putpixel(bmp, x, y, makecol(rgb[0][RCOMP], rgb[0][GCOMP], rgb[0][BCOMP]));\r
+            x++; mask++; rgb++;\r
+            }\r
+        }\r
+    else\r
+        {\r
+        while (n--)\r
+            {\r
+            putpixel(bmp, x, y, makecol(rgb[0][RCOMP], rgb[0][GCOMP], rgb[0][BCOMP]));\r
+            x++; rgb++;\r
+            }\r
+        }\r
+    }\r
+\r
+\r
+static void write_mono_rgba_span_generic(const GLcontext *ctx,\r
+                                         GLuint n, GLint x, GLint y,\r
+                                         const GLubyte mask[])\r
+    {\r
+    AMesaContext context = (AMesaContext)(ctx->DriverCtx);\r
+    BITMAP          *bmp = context->Buffer->Active;\r
+    int            color = context->CurrentColor;\r
+\r
+    y = FLIP(context, y);\r
+\r
+    if (mask)\r
+        {\r
+        while(n--)\r
+            {\r
+            if (mask[0]) putpixel(bmp, x, y, color);\r
+            x++; mask++;\r
+            }\r
+        }\r
+    else\r
+        {\r
+        while(n--)\r
+            {\r
+            putpixel(bmp, x, y, color);\r
+            x++;\r
+            }\r
+        }\r
+    }\r
+\r
+\r
+static void read_rgba_span_generic(const GLcontext *ctx,\r
+                                   GLuint n, GLint x, GLint y,\r
+                                   GLubyte rgba[][4])\r
+    {\r
+    AMesaContext context = (AMesaContext)(ctx->DriverCtx);\r
+    BITMAP          *bmp = context->Buffer->Active;\r
+\r
+    y = FLIP(context, y);\r
+\r
+    while (n--)\r
+        {\r
+        int color = getpixel(bmp, x, y);\r
+\r
+        rgba[0][RCOMP] = getr(color);\r
+        rgba[0][GCOMP] = getg(color);\r
+        rgba[0][BCOMP] = getb(color);\r
+        rgba[0][ACOMP] = 255;\r
+\r
+        x++; rgba++;\r
+        }\r
+    }\r
+\r
+\r
+static void write_rgba_pixels_generic(const GLcontext *ctx,\r
+                                      GLuint n,\r
+                                      const GLint x[],\r
+                                      const GLint y[],\r
+                                      const GLubyte rgba[][4],\r
+                                      const GLubyte mask[])\r
+    {\r
+    AMesaContext context = (AMesaContext)(ctx->DriverCtx);\r
+    BITMAP          *bmp = context->Buffer->Active;\r
+\r
+    while (n--)\r
+        {\r
+        if (mask[0]) putpixel(bmp, x[0], FLIP(context, y[0]), makecol(rgba[0][RCOMP], rgba[0][GCOMP], rgba[0][BCOMP]));\r
+        x++; y++; mask++;\r
+        }\r
+    }\r
+\r
+\r
+static void write_mono_rgba_pixels_generic(const GLcontext *ctx,\r
+                                           GLuint n,\r
+                                           const GLint x[],\r
+                                           const GLint y[],\r
+                                           const GLubyte mask[])\r
+    {\r
+    AMesaContext context = (AMesaContext)(ctx->DriverCtx);\r
+    BITMAP          *bmp = context->Buffer->Active;\r
+    int            color = context->CurrentColor;\r
+\r
+    while (n--)\r
+        {\r
+        if (mask[0]) putpixel(bmp, x[0], FLIP(context, y[0]), color);\r
+        x++; y++; mask++;\r
+        }\r
+    }\r
+\r
+\r
+static void read_rgba_pixels_generic(const GLcontext *ctx,\r
+                                     GLuint n,\r
+                                     const GLint x[],\r
+                                     const GLint y[],\r
+                                     GLubyte rgba[][4],\r
+                                     const GLubyte mask[])\r
+    {\r
+    AMesaContext context = (AMesaContext)(ctx->DriverCtx);\r
+    BITMAP          *bmp = context->Buffer->Active;\r
+\r
+    while (n--)\r
+        {\r
+        if (mask[0])\r
+            {\r
+            int color = getpixel(bmp, x[0], FLIP(context, y[0]));\r
+\r
+            rgba[0][RCOMP] = getr(color);\r
+            rgba[0][GCOMP] = getg(color);\r
+            rgba[0][BCOMP] = getb(color);\r
+            rgba[0][ACOMP] = 255;\r
+            }\r
+\r
+        x++; y++; mask++; rgba++;\r
+        }\r
+    }\r
+\r
diff --git a/src/mesa/drivers/beos/GLView.cpp b/src/mesa/drivers/beos/GLView.cpp
new file mode 100644 (file)
index 0000000..4332f97
--- /dev/null
@@ -0,0 +1,1233 @@
+/* $Id: GLView.cpp,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/*
+ * $Log: GLView.cpp,v $
+ * Revision 1.1  1999/08/19 00:55:41  jtg
+ * Initial revision
+ *
+ * Revision 1.7  1999/03/28 21:08:17  brianp
+ * updated SetBuffer driver function
+ *
+ * Revision 1.6  1999/02/14 03:44:37  brianp
+ * new copyright
+ *
+ * Revision 1.5  1999/02/11 03:50:57  brianp
+ * added CopySubBufferMESA()
+ *
+ * Revision 1.4  1999/02/06 17:44:59  brianp
+ * code clean-up and bug fixes
+ *
+ * Revision 1.3  1999/02/04 04:13:15  brianp
+ * implemented double buffering
+ *
+ * Revision 1.2  1999/02/03 04:23:28  brianp
+ * basic device driver functions now work (yeah!)
+ *
+ * Revision 1.1  1999/02/02 04:40:46  brianp
+ * Initial revision
+ */
+
+
+
+#include <assert.h>
+#include <stdio.h>
+#include <GLView.h>
+#include "../src/context.h"
+
+
+// BeOS component ordering for B_RGBA32 bitmap format
+#define BE_RCOMP 2
+#define BE_GCOMP 1
+#define BE_BCOMP 0
+#define BE_ACOMP 3
+
+
+//
+// This object hangs off of the BGLView object.  We have to use
+// Be's BGLView class as-is to maintain binary compatibility (we
+// can't add new members to it).  Instead we just put all our data
+// in this class and use BGLVIew::m_gc to point to it.
+//
+class AuxInfo
+{
+public:
+   AuxInfo();
+   ~AuxInfo();
+   void Init(BGLView *bglView, GLcontext *c, GLvisual *v, GLframebuffer *b);
+
+   void MakeCurrent();
+   void SwapBuffers() const;
+   void CopySubBuffer(GLint x, GLint y, GLuint width, GLuint height) const;
+
+private:
+   AuxInfo(const AuxInfo &rhs);  // copy constructor illegal
+   AuxInfo &operator=(const AuxInfo &rhs);  // assignment oper. illegal
+
+   GLcontext *mContext;
+   GLvisual *mVisual;
+   GLframebuffer *mBuffer;
+
+   BGLView *mBGLView;
+   BBitmap *mBitmap;
+
+   GLubyte mColor[4];       // current color
+   GLuint mIndex;           // current color index
+   GLubyte mClearColor[4];  // buffer clear color
+   GLuint mClearIndex;      // buffer clear color index
+   GLint mBottom;           // used for flipping Y coords
+   GLint mWidth, mHeight;   // size of buffer
+
+   // Mesa device driver functions
+   static void UpdateState(GLcontext *ctx);
+   static void ClearIndex(GLcontext *ctx, GLuint index);
+   static void ClearColor(GLcontext *ctx, GLubyte r, GLubyte g,
+                          GLubyte b, GLubyte a);
+   static GLbitfield ClearFront(GLcontext *ctx, GLbitfield mask,
+                                GLboolean all, GLint x, GLint y,
+                                GLint width, GLint height);
+   static GLbitfield ClearBack(GLcontext *ctx, GLbitfield mask,
+                               GLboolean all, GLint x, GLint y,
+                               GLint width, GLint height);
+   static void Index(GLcontext *ctx, GLuint index);
+   static void Color(GLcontext *ctx, GLubyte r, GLubyte g,
+                     GLubyte b, GLubyte a);
+   static GLboolean SetBuffer(GLcontext *ctx, GLenum mode);
+   static void GetBufferSize(GLcontext *ctgx, GLuint *width,
+                             GLuint *height);
+   static const GLubyte *GetString(GLcontext *ctx, GLenum name);
+
+   // Front-buffer functions
+   static void WriteRGBASpanFront(const GLcontext *ctx, GLuint n,
+                                  GLint x, GLint y,
+                                  CONST GLubyte rgba[][4],
+                                  const GLubyte mask[]);
+   static void WriteRGBSpanFront(const GLcontext *ctx, GLuint n,
+                                 GLint x, GLint y,
+                                 CONST GLubyte rgba[][3],
+                                 const GLubyte mask[]);
+   static void WriteMonoRGBASpanFront(const GLcontext *ctx, GLuint n,
+                                      GLint x, GLint y, const GLubyte mask[]);
+   static void WriteRGBAPixelsFront(const GLcontext *ctx, GLuint n,
+                                    const GLint x[], const GLint y[],
+                                    CONST GLubyte rgba[][4],
+                                    const GLubyte mask[]);
+   static void WriteMonoRGBAPixelsFront(const GLcontext *ctx, GLuint n,
+                                        const GLint x[], const GLint y[],
+                                        const GLubyte mask[]);
+   static void WriteCI32SpanFront(const GLcontext *ctx, GLuint n,
+                                  GLint x, GLint y,
+                                  const GLuint index[], const GLubyte mask[]);
+   static void WriteCI8SpanFront(const GLcontext *ctx, GLuint n,
+                                 GLint x, GLint y,
+                                 const GLubyte index[], const GLubyte mask[]);
+   static void WriteMonoCISpanFront(const GLcontext *ctx, GLuint n,
+                                    GLint x, GLint y, const GLubyte mask[]);
+   static void WriteCI32PixelsFront(const GLcontext *ctx,
+                                    GLuint n, const GLint x[], const GLint y[],
+                                    const GLuint index[], const GLubyte mask[]);
+   static void WriteMonoCIPixelsFront(const GLcontext *ctx, GLuint n,
+                                      const GLint x[], const GLint y[],
+                                      const GLubyte mask[]);
+   static void ReadCI32SpanFront(const GLcontext *ctx,
+                                 GLuint n, GLint x, GLint y, GLuint index[]);
+   static void ReadRGBASpanFront(const GLcontext *ctx, GLuint n,
+                                 GLint x, GLint y,
+                                 GLubyte rgba[][4]);
+   static void ReadCI32PixelsFront(const GLcontext *ctx,
+                                   GLuint n, const GLint x[], const GLint y[],
+                                   GLuint indx[], const GLubyte mask[]);
+   static void ReadRGBAPixelsFront(const GLcontext *ctx,
+                                   GLuint n, const GLint x[], const GLint y[],
+                                   GLubyte rgba[][4], const GLubyte mask[]);
+
+   // Back buffer functions
+   static void WriteRGBASpanBack(const GLcontext *ctx, GLuint n,
+                                  GLint x, GLint y,
+                                  CONST GLubyte rgba[][4],
+                                  const GLubyte mask[]);
+   static void WriteRGBSpanBack(const GLcontext *ctx, GLuint n,
+                                 GLint x, GLint y,
+                                 CONST GLubyte rgba[][3],
+                                 const GLubyte mask[]);
+   static void WriteMonoRGBASpanBack(const GLcontext *ctx, GLuint n,
+                                      GLint x, GLint y, const GLubyte mask[]);
+   static void WriteRGBAPixelsBack(const GLcontext *ctx, GLuint n,
+                                    const GLint x[], const GLint y[],
+                                    CONST GLubyte rgba[][4],
+                                    const GLubyte mask[]);
+   static void WriteMonoRGBAPixelsBack(const GLcontext *ctx, GLuint n,
+                                        const GLint x[], const GLint y[],
+                                        const GLubyte mask[]);
+   static void WriteCI32SpanBack(const GLcontext *ctx, GLuint n,
+                                 GLint x, GLint y,
+                                 const GLuint index[], const GLubyte mask[]);
+   static void WriteCI8SpanBack(const GLcontext *ctx, GLuint n, GLint x, GLint y,
+                                const GLubyte index[], const GLubyte mask[]);
+   static void WriteMonoCISpanBack(const GLcontext *ctx, GLuint n,
+                                   GLint x, GLint y,
+                                   const GLubyte mask[]);
+   static void WriteCI32PixelsBack(const GLcontext *ctx,
+                                   GLuint n, const GLint x[], const GLint y[],
+                                   const GLuint index[], const GLubyte mask[]);
+   static void WriteMonoCIPixelsBack(const GLcontext *ctx,
+                                     GLuint n, const GLint x[], const GLint y[],
+                                     const GLubyte mask[]);
+   static void ReadCI32SpanBack(const GLcontext *ctx,
+                                GLuint n, GLint x, GLint y, GLuint index[]);
+   static void ReadRGBASpanBack(const GLcontext *ctx, GLuint n,
+                                GLint x, GLint y,
+                                GLubyte rgba[][4]);
+   static void ReadCI32PixelsBack(const GLcontext *ctx,
+                                  GLuint n, const GLint x[], const GLint y[],
+                                  GLuint indx[], const GLubyte mask[]);
+   static void ReadRGBAPixelsBack(const GLcontext *ctx,
+                                  GLuint n, const GLint x[], const GLint y[],
+                                  GLubyte rgba[][4], const GLubyte mask[]);
+
+};
+
+
+
+AuxInfo::AuxInfo()
+{
+   mContext = NULL;
+   mVisual = NULL;
+   mBuffer = NULL;
+   mBGLView = NULL;
+   mBitmap = NULL;
+   mClearColor[BE_RCOMP] = 0;
+   mClearColor[BE_GCOMP] = 0;
+   mClearColor[BE_BCOMP] = 0;
+   mClearColor[BE_ACOMP] = 0;
+   mClearIndex = 0;
+   mColor[BE_RCOMP] = 255;
+   mColor[BE_GCOMP] = 255;
+   mColor[BE_BCOMP] = 255;
+   mColor[BE_ACOMP] = 255;
+   mIndex = 1;
+}
+
+
+AuxInfo::~AuxInfo()
+{
+
+   gl_destroy_visual(mVisual);
+   gl_destroy_framebuffer(mBuffer);
+   gl_destroy_context(mContext);
+}
+
+
+void AuxInfo::Init(BGLView *bglView, GLcontext *c, GLvisual *v, GLframebuffer *b)
+{
+   mBGLView = bglView;
+   mContext = c;
+   mVisual = v;
+   mBuffer = b;
+}
+
+
+void AuxInfo::MakeCurrent()
+{
+   UpdateState(mContext);
+   gl_make_current(mContext, mBuffer);
+}
+
+
+void AuxInfo::SwapBuffers() const
+{
+   if (mBitmap) {
+      mBGLView->DrawBitmap(mBitmap, BPoint(0, 0));
+   }
+}
+
+
+void AuxInfo::CopySubBuffer(GLint x, GLint y, GLuint width, GLuint height) const
+{
+   if (mBitmap) {
+      // Source bitmap and view's bitmap are same size.
+      // Source and dest rectangle are the same.
+      // Note (x,y) = (0,0) is the lower-left corner, have to flip Y
+      BRect srcAndDest;
+      srcAndDest.left = x;
+      srcAndDest.right = x + width - 1;
+      srcAndDest.bottom = mBottom - y;
+      srcAndDest.top = srcAndDest.bottom - height + 1;
+      mBGLView->DrawBitmap(mBitmap, srcAndDest, srcAndDest);
+   }
+}
+
+
+void AuxInfo::UpdateState( GLcontext *ctx )
+{
+   AuxInfo *aux = (AuxInfo *) ctx->DriverCtx;
+
+   assert(aux->mContext == ctx );
+
+   ctx->Driver.UpdateState = AuxInfo::UpdateState;
+   ctx->Driver.SetBuffer = AuxInfo::SetBuffer;
+   ctx->Driver.Color = AuxInfo::Color;
+   ctx->Driver.Index = AuxInfo::Index;
+   ctx->Driver.ClearIndex = AuxInfo::ClearIndex;
+   ctx->Driver.ClearColor = AuxInfo::ClearColor;
+   ctx->Driver.GetBufferSize = AuxInfo::GetBufferSize;
+   ctx->Driver.GetString = AuxInfo::GetString;
+
+   if (ctx->Color.DrawBuffer == GL_FRONT) {
+      /* read/write front buffer */
+      ctx->Driver.Clear = AuxInfo::ClearFront;
+      ctx->Driver.WriteRGBASpan = AuxInfo::WriteRGBASpanFront;
+      ctx->Driver.WriteRGBSpan = AuxInfo::WriteRGBSpanFront;
+      ctx->Driver.WriteRGBAPixels = AuxInfo::WriteRGBAPixelsFront;
+      ctx->Driver.WriteMonoRGBASpan = AuxInfo::WriteMonoRGBASpanFront;
+      ctx->Driver.WriteMonoRGBAPixels = AuxInfo::WriteMonoRGBAPixelsFront;
+      ctx->Driver.WriteCI32Span = AuxInfo::WriteCI32SpanFront;
+      ctx->Driver.WriteCI8Span = AuxInfo::WriteCI8SpanFront;
+      ctx->Driver.WriteMonoCISpan = AuxInfo::WriteMonoCISpanFront;
+      ctx->Driver.WriteCI32Pixels = AuxInfo::WriteCI32PixelsFront;
+      ctx->Driver.WriteMonoCIPixels = AuxInfo::WriteMonoCIPixelsFront;
+      ctx->Driver.ReadRGBASpan = AuxInfo::ReadRGBASpanFront;
+      ctx->Driver.ReadRGBAPixels = AuxInfo::ReadRGBAPixelsFront;
+      ctx->Driver.ReadCI32Span = AuxInfo::ReadCI32SpanFront;
+      ctx->Driver.ReadCI32Pixels = AuxInfo::ReadCI32PixelsFront;
+   }
+   else {
+      /* read/write back buffer */
+      ctx->Driver.Clear = AuxInfo::ClearBack;
+      ctx->Driver.WriteRGBASpan = AuxInfo::WriteRGBASpanBack;
+      ctx->Driver.WriteRGBSpan = AuxInfo::WriteRGBSpanBack;
+      ctx->Driver.WriteRGBAPixels = AuxInfo::WriteRGBAPixelsBack;
+      ctx->Driver.WriteMonoRGBASpan = AuxInfo::WriteMonoRGBASpanBack;
+      ctx->Driver.WriteMonoRGBAPixels = AuxInfo::WriteMonoRGBAPixelsBack;
+      ctx->Driver.WriteCI32Span = AuxInfo::WriteCI32SpanBack;
+      ctx->Driver.WriteCI8Span = AuxInfo::WriteCI8SpanBack;
+      ctx->Driver.WriteMonoCISpan = AuxInfo::WriteMonoCISpanBack;
+      ctx->Driver.WriteCI32Pixels = AuxInfo::WriteCI32PixelsBack;
+      ctx->Driver.WriteMonoCIPixels = AuxInfo::WriteMonoCIPixelsBack;
+      ctx->Driver.ReadRGBASpan = AuxInfo::ReadRGBASpanBack;
+      ctx->Driver.ReadRGBAPixels = AuxInfo::ReadRGBAPixelsBack;
+      ctx->Driver.ReadCI32Span = AuxInfo::ReadCI32SpanBack;
+      ctx->Driver.ReadCI32Pixels = AuxInfo::ReadCI32PixelsBack;
+    }
+}
+
+
+void AuxInfo::ClearIndex(GLcontext *ctx, GLuint index)
+{
+   AuxInfo *aux = (AuxInfo *) ctx->DriverCtx;
+   aux->mClearIndex = index;
+}
+
+
+void AuxInfo::ClearColor(GLcontext *ctx, GLubyte r, GLubyte g,
+                         GLubyte b, GLubyte a)
+{
+   AuxInfo *aux = (AuxInfo *) ctx->DriverCtx;
+   aux->mClearColor[BE_RCOMP] = r;
+   aux->mClearColor[BE_GCOMP] = g;
+   aux->mClearColor[BE_BCOMP] = b;
+   aux->mClearColor[BE_ACOMP] = a;
+   assert(aux->mBGLView);
+}
+
+
+GLbitfield AuxInfo::ClearFront(GLcontext *ctx, GLbitfield mask,
+                               GLboolean all, GLint x, GLint y,
+                               GLint width, GLint height)
+{
+   AuxInfo *aux = (AuxInfo *) ctx->DriverCtx;
+   BGLView *bglview = aux->mBGLView;
+   assert(bglview);
+
+   bglview->SetHighColor(aux->mClearColor[BE_RCOMP],
+                         aux->mClearColor[BE_GCOMP],
+                         aux->mClearColor[BE_BCOMP],
+                         aux->mClearColor[BE_ACOMP]);
+   bglview->SetLowColor(aux->mClearColor[BE_RCOMP],
+                        aux->mClearColor[BE_GCOMP],
+                        aux->mClearColor[BE_BCOMP],
+                        aux->mClearColor[BE_ACOMP]);
+   if (all) {
+      BRect b = bglview->Bounds();
+      bglview->FillRect(b);
+   }
+   else {
+      // XXX untested
+      BRect b;
+      b.left = x;
+      b.right = x + width;
+      b.bottom = aux->mHeight - y - 1;
+      b.top = b.bottom - height;
+      bglview->FillRect(b);
+   }
+
+   // restore drawing color
+   bglview->SetHighColor(aux->mColor[BE_RCOMP],
+                         aux->mColor[BE_GCOMP],
+                         aux->mColor[BE_BCOMP],
+                         aux->mColor[BE_ACOMP]);
+   bglview->SetLowColor(aux->mColor[BE_RCOMP],
+                        aux->mColor[BE_GCOMP],
+                        aux->mColor[BE_BCOMP],
+                        aux->mColor[BE_ACOMP]);
+   
+   return mask & (~GL_COLOR_BUFFER_BIT);
+}
+
+
+GLbitfield AuxInfo::ClearBack(GLcontext *ctx, GLbitfield mask,
+                               GLboolean all, GLint x, GLint y,
+                               GLint width, GLint height)
+{
+   AuxInfo *aux = (AuxInfo *) ctx->DriverCtx;
+   BGLView *bglview = aux->mBGLView;
+   assert(bglview);
+   BBitmap *bitmap = aux->mBitmap;
+   assert(bitmap);
+   GLuint *start = (GLuint *) bitmap->Bits();
+   const GLuint *clearPixelPtr = (const GLuint *) aux->mClearColor;
+   const GLuint clearPixel = *clearPixelPtr;
+
+   if (all) {
+      const int numPixels = aux->mWidth * aux->mHeight;
+      if (clearPixel == 0) {
+         memset(start, 0, numPixels * 4);
+      }
+      else {
+         for (int i = 0; i < numPixels; i++) {
+             start[i] = clearPixel;
+         }
+      }
+   }
+   else {
+      // XXX untested
+      start += y * aux->mWidth + x;
+      for (int i = 0; i < height; i++) {
+         for (int j = 0; j < width; j++) {
+            start[j] = clearPixel;
+         }
+         start += aux->mWidth;
+      }
+   }
+
+   return mask & (~GL_COLOR_BUFFER_BIT);
+}
+
+
+void AuxInfo::Index(GLcontext *ctx, GLuint index)
+{
+   AuxInfo *aux = (AuxInfo *) ctx->DriverCtx;
+   BGLView *bglview = aux->mBGLView;
+   assert(bglview);
+   aux->mIndex = index;
+}
+
+
+void AuxInfo::Color(GLcontext *ctx, GLubyte r, GLubyte g,
+                                               GLubyte b, GLubyte a)
+{
+   AuxInfo *aux = (AuxInfo *) ctx->DriverCtx;
+   BGLView *bglview = aux->mBGLView;
+   assert(bglview);
+   aux->mColor[BE_RCOMP] = r;
+   aux->mColor[BE_GCOMP] = g;
+   aux->mColor[BE_BCOMP] = b;
+   aux->mColor[BE_ACOMP] = a;
+   bglview->SetHighColor(r, g, b, a);
+   bglview->SetLowColor(r, g, b, a);
+}
+
+GLboolean AuxInfo::SetBuffer(GLcontext *ctx, GLenum buffer)
+{
+   if (buffer == GL_FRONT_LEFT)
+      return GL_TRUE;
+   else if (buffer == GL_BACK_LEFT)
+      return GL_TRUE;
+   else
+      return GL_FALSE;
+}
+
+void AuxInfo::GetBufferSize(GLcontext *ctx, GLuint *width,
+                            GLuint *height)
+{
+   AuxInfo *aux = (AuxInfo *) ctx->DriverCtx;
+   BGLView *bglview = aux->mBGLView;
+   assert(bglview);
+   BRect b = bglview->Bounds();
+   *width = (GLuint) (b.right - b.left + 1);
+   *height = (GLuint) (b.bottom - b.top + 1);
+   aux->mBottom = (GLint) b.bottom;
+
+   if (ctx->Visual->DBflag) {
+      if (*width != aux->mWidth || *height != aux->mHeight) {
+         // allocate new size of back buffer bitmap
+         if (aux->mBitmap)
+            delete aux->mBitmap;
+         BRect rect(0.0, 0.0, *width - 1, *height - 1);
+         aux->mBitmap = new BBitmap(rect, B_RGBA32);
+      }
+   }
+   else
+   {
+      aux->mBitmap = NULL;
+   }
+
+   aux->mWidth = *width;
+   aux->mHeight = *height;
+}
+
+
+const GLubyte *AuxInfo::GetString(GLcontext *ctx, GLenum name)
+{
+   switch (name) {
+      case GL_RENDERER:
+         return (const GLubyte *) "Mesa BeOS";
+      default:
+         // Let core library handle all other cases
+         return NULL;
+   }
+}
+
+
+// Plot a pixel.  (0,0) is upper-left corner
+// This is only used when drawing to the front buffer.
+static void Plot(BGLView *bglview, int x, int y)
+{
+   // XXX There's got to be a better way!
+   BPoint p(x, y), q(x+1, y);
+   bglview->StrokeLine(p, q);
+}
+
+
+void AuxInfo::WriteRGBASpanFront(const GLcontext *ctx, GLuint n,
+                                 GLint x, GLint y,
+                                 CONST GLubyte rgba[][4],
+                                 const GLubyte mask[])
+{
+   AuxInfo *aux = (AuxInfo *) ctx->DriverCtx;
+   BGLView *bglview = aux->mBGLView;
+   assert(bglview);
+   int flippedY = aux->mBottom - y;
+   if (mask) {
+      for (GLuint i = 0; i < n; i++) {
+         if (mask[i]) {
+            bglview->SetHighColor(rgba[i][0], rgba[i][1], rgba[i][2], rgba[i][3]);
+            Plot(bglview, x++, flippedY);
+         }
+      }
+   }
+   else {
+      for (GLuint i = 0; i < n; i++) {
+         bglview->SetHighColor(rgba[i][0], rgba[i][1], rgba[i][2], rgba[i][3]);
+         Plot(bglview, x++, flippedY);
+      }
+   }
+}
+
+void AuxInfo::WriteRGBSpanFront(const GLcontext *ctx, GLuint n,
+                                GLint x, GLint y,
+                                CONST GLubyte rgba[][3],
+                                const GLubyte mask[])
+{
+   AuxInfo *aux = (AuxInfo *) ctx->DriverCtx;
+   BGLView *bglview = aux->mBGLView;
+   assert(bglview);
+   int flippedY = aux->mBottom - y;
+   if (mask) {
+      for (GLuint i = 0; i < n; i++) {
+         if (mask[i]) {
+            bglview->SetHighColor(rgba[i][0], rgba[i][1], rgba[i][2]);
+            Plot(bglview, x++, flippedY);
+         }
+      }
+   }
+   else {
+      for (GLuint i = 0; i < n; i++) {
+         bglview->SetHighColor(rgba[i][0], rgba[i][1], rgba[i][2]);
+         Plot(bglview, x++, flippedY);
+      }
+   }
+}
+
+void AuxInfo::WriteMonoRGBASpanFront(const GLcontext *ctx, GLuint n,
+                                     GLint x, GLint y, const GLubyte mask[])
+{
+   AuxInfo *aux = (AuxInfo *) ctx->DriverCtx;
+   BGLView *bglview = aux->mBGLView;
+   assert(bglview);
+   int flippedY = aux->mBottom - y;
+   if (mask) {
+      for (GLuint i = 0; i < n; i++) {
+         if (mask[i]) {
+            Plot(bglview, x++, flippedY);
+         }
+      }
+   }
+   else {
+      for (GLuint i = 0; i < n; i++) {
+         Plot(bglview, x++, flippedY);
+      }
+   }
+}
+
+void AuxInfo::WriteRGBAPixelsFront(const GLcontext *ctx,
+                                   GLuint n, const GLint x[], const GLint y[],
+                                   CONST GLubyte rgba[][4],
+                                   const GLubyte mask[] )
+{
+   AuxInfo *aux = (AuxInfo *) ctx->DriverCtx;
+   BGLView *bglview = aux->mBGLView;
+   assert(bglview);
+   if (mask) {
+      for (GLuint i = 0; i < n; i++) {
+         if (mask[i]) {
+            bglview->SetHighColor(rgba[i][0], rgba[i][1], rgba[i][2]);
+            Plot(bglview, x[i], aux->mBottom - y[i]);
+         }
+      }
+   }
+   else {
+      for (GLuint i = 0; i < n; i++) {
+         bglview->SetHighColor(rgba[i][0], rgba[i][1], rgba[i][2]);
+         Plot(bglview, x[i], aux->mBottom - y[i]);
+      }
+   }
+}
+
+
+void AuxInfo::WriteMonoRGBAPixelsFront(const GLcontext *ctx, GLuint n,
+                                       const GLint x[], const GLint y[],
+                                       const GLubyte mask[])
+{
+   AuxInfo *aux = (AuxInfo *) ctx->DriverCtx;
+   BGLView *bglview = aux->mBGLView;
+   assert(bglview);
+   // plot points using current color
+   if (mask) {
+      for (GLuint i = 0; i < n; i++) {
+         if (mask[i]) {
+            Plot(bglview, x[i], aux->mBottom - y[i]);
+         }
+      }
+   }
+   else {
+      for (GLuint i = 0; i < n; i++) {
+         Plot(bglview, x[i], aux->mBottom - y[i]);
+      }
+   }
+}
+
+
+void AuxInfo::WriteCI32SpanFront( const GLcontext *ctx, GLuint n, GLint x, GLint y,
+                             const GLuint index[], const GLubyte mask[] )
+{
+   // XXX to do
+}
+
+void AuxInfo::WriteCI8SpanFront( const GLcontext *ctx, GLuint n, GLint x, GLint y,
+                            const GLubyte index[], const GLubyte mask[] )
+{
+   // XXX to do
+}
+
+void AuxInfo::WriteMonoCISpanFront( const GLcontext *ctx, GLuint n,
+                               GLint x, GLint y, const GLubyte mask[] )
+{
+   // XXX to do
+}
+
+
+void AuxInfo::WriteCI32PixelsFront( const GLcontext *ctx, GLuint n,
+                                    const GLint x[], const GLint y[],
+                                    const GLuint index[], const GLubyte mask[] )
+{
+   // XXX to do
+}
+
+void AuxInfo::WriteMonoCIPixelsFront( const GLcontext *ctx, GLuint n,
+                                      const GLint x[], const GLint y[],
+                                      const GLubyte mask[] )
+{
+   // XXX to do
+}
+
+
+void AuxInfo::ReadCI32SpanFront( const GLcontext *ctx,
+                                 GLuint n, GLint x, GLint y, GLuint index[] )
+{
+   // XXX to do
+}
+
+
+void AuxInfo::ReadRGBASpanFront( const GLcontext *ctx, GLuint n,
+                                 GLint x, GLint y, GLubyte rgba[][4] )
+{
+   // XXX to do
+}
+
+
+void AuxInfo::ReadCI32PixelsFront( const GLcontext *ctx,
+                                   GLuint n, const GLint x[], const GLint y[],
+                                   GLuint indx[], const GLubyte mask[] )
+{
+   // XXX to do
+}
+
+
+void AuxInfo::ReadRGBAPixelsFront( const GLcontext *ctx,
+                                   GLuint n, const GLint x[], const GLint y[],
+                                   GLubyte rgba[][4], const GLubyte mask[] )
+{
+   // XXX to do
+}
+
+
+
+
+void AuxInfo::WriteRGBASpanBack(const GLcontext *ctx, GLuint n,
+                                 GLint x, GLint y,
+                                 CONST GLubyte rgba[][4],
+                                 const GLubyte mask[])
+{
+   AuxInfo *aux = (AuxInfo *) ctx->DriverCtx;
+   BBitmap *bitmap = aux->mBitmap;
+   assert(bitmap);
+   int row = aux->mBottom - y;
+   GLubyte *pixel = (GLubyte *) bitmap->Bits() + (row * aux->mWidth + x) * 4;
+   if (mask) {
+      for (GLuint i = 0; i < n; i++) {
+         if (mask[i]) {
+            pixel[BE_RCOMP] = rgba[i][RCOMP];
+            pixel[BE_GCOMP] = rgba[i][GCOMP];
+            pixel[BE_BCOMP] = rgba[i][BCOMP];
+            pixel[BE_ACOMP] = rgba[i][ACOMP];
+         }
+         pixel += 4;
+      }
+   }
+   else {
+      for (GLuint i = 0; i < n; i++) {
+         pixel[BE_RCOMP] = rgba[i][RCOMP];
+         pixel[BE_GCOMP] = rgba[i][GCOMP];
+         pixel[BE_BCOMP] = rgba[i][BCOMP];
+         pixel[BE_ACOMP] = rgba[i][ACOMP];
+         pixel += 4;
+      }
+   }
+}
+
+
+void AuxInfo::WriteRGBSpanBack(const GLcontext *ctx, GLuint n,
+                                GLint x, GLint y,
+                                CONST GLubyte rgb[][3],
+                                const GLubyte mask[])
+{
+   AuxInfo *aux = (AuxInfo *) ctx->DriverCtx;
+   BBitmap *bitmap = aux->mBitmap;
+   assert(bitmap);
+   int row = aux->mBottom - y;
+   GLubyte *pixel = (GLubyte *) bitmap->Bits() + (row * aux->mWidth + x) * 4;
+   if (mask) {
+      for (GLuint i = 0; i < n; i++) {
+         if (mask[i]) {
+            pixel[BE_RCOMP] = rgb[i][RCOMP];
+            pixel[BE_GCOMP] = rgb[i][GCOMP];
+            pixel[BE_BCOMP] = rgb[i][BCOMP];
+            pixel[BE_ACOMP] = 255;
+         }
+         pixel += 4;
+      }
+   }
+   else {
+      for (GLuint i = 0; i < n; i++) {
+         pixel[BE_RCOMP] = rgb[i][RCOMP];
+         pixel[BE_GCOMP] = rgb[i][GCOMP];
+         pixel[BE_BCOMP] = rgb[i][BCOMP];
+         pixel[BE_ACOMP] = 255;
+         pixel += 4;
+      }
+   }
+}
+
+
+void AuxInfo::WriteMonoRGBASpanBack(const GLcontext *ctx, GLuint n,
+                                     GLint x, GLint y, const GLubyte mask[])
+{
+   AuxInfo *aux = (AuxInfo *) ctx->DriverCtx;
+   BBitmap *bitmap = aux->mBitmap;
+   assert(bitmap);
+   int row = aux->mBottom - y;
+   GLuint *pixelPtr = (GLuint *) bitmap->Bits() + row * aux->mWidth + x;
+   const GLuint pixel = *((GLuint *) aux->mColor);
+   if (mask) {
+      for (GLuint i = 0; i < n; i++) {
+         if (mask[i])
+            *pixelPtr = pixel;
+         pixelPtr++;
+      }
+   }
+   else {
+      for (GLuint i = 0; i < n; i++) {
+         *pixelPtr++ = pixel;
+      }
+   }
+}
+
+
+void AuxInfo::WriteRGBAPixelsBack(const GLcontext *ctx,
+                                   GLuint n, const GLint x[], const GLint y[],
+                                   CONST GLubyte rgba[][4],
+                                   const GLubyte mask[] )
+{
+   AuxInfo *aux = (AuxInfo *) ctx->DriverCtx;
+   BBitmap *bitmap = aux->mBitmap;
+   assert(bitmap);
+   if (mask) {
+      for (GLuint i = 0; i < n; i++) {
+         if (mask[i]) {
+            GLubyte *pixel = (GLubyte *) bitmap->Bits()
+            + (aux->mBottom - y[i]) * bitmap->BytesPerRow() + x[i] * 4;
+            pixel[BE_RCOMP] = rgba[i][RCOMP];
+            pixel[BE_GCOMP] = rgba[i][GCOMP];
+            pixel[BE_BCOMP] = rgba[i][BCOMP];
+            pixel[BE_ACOMP] = rgba[i][ACOMP];
+         }
+      }
+   }
+   else {
+      for (GLuint i = 0; i < n; i++) {
+         GLubyte *pixel = (GLubyte *) bitmap->Bits()
+            + (aux->mBottom - y[i]) * bitmap->BytesPerRow() + x[i] * 4;
+         pixel[BE_RCOMP] = rgba[i][RCOMP];
+         pixel[BE_GCOMP] = rgba[i][GCOMP];
+         pixel[BE_BCOMP] = rgba[i][BCOMP];
+         pixel[BE_ACOMP] = rgba[i][ACOMP];
+      }
+   }
+}
+
+
+void AuxInfo::WriteMonoRGBAPixelsBack(const GLcontext *ctx, GLuint n,
+                                       const GLint x[], const GLint y[],
+                                       const GLubyte mask[])
+{
+   AuxInfo *aux = (AuxInfo *) ctx->DriverCtx;
+   BBitmap *bitmap = aux->mBitmap;
+   assert(bitmap);
+   const GLuint pixel = *((GLuint *) aux->mColor);
+   if (mask) {
+      for (GLuint i = 0; i < n; i++) {
+         if (mask[i]) {
+            GLuint *pixelPtr = (GLuint *) bitmap->Bits()
+                    + (aux->mBottom - y[i]) * aux->mWidth + x[i];
+            *pixelPtr = pixel;
+         }
+      }
+   }
+   else {
+      for (GLuint i = 0; i < n; i++) {
+         GLuint *pixelPtr = (GLuint *) bitmap->Bits()
+                 + (aux->mBottom - y[i]) * aux->mWidth + x[i];
+         *pixelPtr = pixel;
+      }
+   }
+}
+
+
+void AuxInfo::WriteCI32SpanBack( const GLcontext *ctx, GLuint n,
+                                 GLint x, GLint y,
+                                 const GLuint index[], const GLubyte mask[] )
+{
+   // XXX to do
+}
+
+void AuxInfo::WriteCI8SpanBack( const GLcontext *ctx, GLuint n,
+                                GLint x, GLint y,
+                                const GLubyte index[], const GLubyte mask[] )
+{
+   // XXX to do
+}
+
+void AuxInfo::WriteMonoCISpanBack( const GLcontext *ctx, GLuint n,
+                                   GLint x, GLint y, const GLubyte mask[] )
+{
+   // XXX to do
+}
+
+
+void AuxInfo::WriteCI32PixelsBack( const GLcontext *ctx, GLuint n,
+                                   const GLint x[], const GLint y[],
+                                   const GLuint index[], const GLubyte mask[] )
+{
+   // XXX to do
+}
+
+void AuxInfo::WriteMonoCIPixelsBack( const GLcontext *ctx, GLuint n,
+                                     const GLint x[], const GLint y[],
+                                     const GLubyte mask[] )
+{
+   // XXX to do
+}
+
+
+void AuxInfo::ReadCI32SpanBack( const GLcontext *ctx,
+                                GLuint n, GLint x, GLint y, GLuint index[] )
+{
+   // XXX to do
+}
+
+
+void AuxInfo::ReadRGBASpanBack( const GLcontext *ctx, GLuint n,
+                                GLint x, GLint y, GLubyte rgba[][4] )
+{
+   AuxInfo *aux = (AuxInfo *) ctx->DriverCtx;
+   const BBitmap *bitmap = aux->mBitmap;
+   assert(bitmap);
+   int row = aux->mBottom - y;
+   const GLubyte *pixel = (GLubyte *) bitmap->Bits()
+                        + row * bitmap->BytesPerRow() + x * 4;
+   for (GLuint i = 0; i < n; i++) {
+      rgba[i][RCOMP] = pixel[BE_RCOMP];
+      rgba[i][GCOMP] = pixel[BE_GCOMP];
+      rgba[i][BCOMP] = pixel[BE_BCOMP];
+      rgba[i][ACOMP] = pixel[BE_ACOMP];
+      pixel += 4;
+   }
+}
+
+
+void AuxInfo::ReadCI32PixelsBack( const GLcontext *ctx,
+                                   GLuint n, const GLint x[], const GLint y[],
+                                   GLuint indx[], const GLubyte mask[] )
+{
+   // XXX to do
+}
+
+
+void AuxInfo::ReadRGBAPixelsBack( const GLcontext *ctx,
+                                  GLuint n, const GLint x[], const GLint y[],
+                                  GLubyte rgba[][4], const GLubyte mask[] )
+{
+   AuxInfo *aux = (AuxInfo *) ctx->DriverCtx;
+   const BBitmap *bitmap = aux->mBitmap;
+   assert(bitmap);
+   for (GLuint i = 0; i < n; i++) {
+      if (y[i] < aux->mHeight) {
+         const GLubyte *pixel = (const GLubyte *) bitmap->Bits()
+            + ((aux->mBottom - y[i]) * aux->mWidth + x[i]) * 4;
+         rgba[i][RCOMP] = pixel[BE_RCOMP];
+         rgba[i][GCOMP] = pixel[BE_GCOMP];
+         rgba[i][BCOMP] = pixel[BE_BCOMP];
+         rgba[i][ACOMP] = pixel[BE_ACOMP];
+      }
+   }
+}
+
+
+
+
+//------------------------------------------------------------------
+// Public interface methods
+//------------------------------------------------------------------
+
+
+//
+// Input:  rect - initial rectangle
+//         name - window name
+//         resizingMode - example: B_FOLLOW_NONE
+//         mode - usually 0 ?
+//         options - Bitwise-OR of BGL_* tokens
+//
+BGLView::BGLView(BRect rect, char *name,
+                 ulong resizingMode, ulong mode,
+                 ulong options)
+   :BView(rect, name, resizingMode, mode)
+{
+   const GLboolean rgbFlag = (options & BGL_RGB) == BGL_RGB;
+   const GLboolean alphaFlag = (options & BGL_ALPHA) == BGL_ALPHA;
+   const GLboolean dblFlag = (options & BGL_DOUBLE) == BGL_DOUBLE;
+   const GLboolean stereoFlag = false;
+   const GLint depth = (options & BGL_DEPTH) ? 16 : 0;
+   const GLint stencil = (options & BGL_STENCIL) ? 8 : 0;
+   const GLint accum = (options & BGL_ACCUM) ? 16 : 0;
+   const GLint index = (options & BGL_INDEX) ? 32 : 0;
+   const GLint red = (options & BGL_RGB) ? 8 : 0;
+   const GLint green = (options & BGL_RGB) ? 8 : 0;
+   const GLint blue = (options & BGL_RGB) ? 8 : 0;
+   const GLint alpha = (options & BGL_RGB) ? 8 : 0;
+
+   if (!rgbFlag) {
+      fprintf(stderr, "Mesa Warning: color index mode not supported\n");
+   }
+
+   // Allocate auxiliary data object
+   AuxInfo *aux = new AuxInfo;
+
+   // examine option flags and create gl_context struct
+   GLvisual *visual = gl_create_visual( rgbFlag, alphaFlag,
+                                        dblFlag, stereoFlag,
+                                        depth, stencil, accum, index,
+                                        red, green, blue, alpha);
+
+   // create core framebuffer
+   GLframebuffer *buffer = gl_create_framebuffer(visual);
+
+   // create core context
+   const GLboolean direct = GL_TRUE;
+   GLcontext *ctx = gl_create_context( visual, NULL, aux, direct );
+
+   aux->Init(this, ctx, visual, buffer );
+
+   // Hook aux data into BGLView object
+   m_gc = aux;
+}
+
+
+BGLView::~BGLView()
+{
+   printf("BGLView destructor\n");
+   AuxInfo *aux = (AuxInfo *) m_gc;
+   assert(aux);
+   delete aux;
+}
+
+void BGLView::LockGL()
+{
+   AuxInfo *aux = (AuxInfo *) m_gc;
+   assert(aux);
+   aux->MakeCurrent();
+}
+
+void BGLView::UnlockGL()
+{
+   AuxInfo *aux = (AuxInfo *) m_gc;
+   assert(aux);
+   // Could call gl_make_current(NULL, NULL) but it would just
+   // hinder performance
+}
+
+void BGLView::SwapBuffers()
+{
+   AuxInfo *aux = (AuxInfo *) m_gc;
+   assert(aux);
+   aux->SwapBuffers();
+}
+
+
+void BGLView::CopySubBufferMESA(GLint x, GLint y, GLuint width, GLuint height)
+{
+   AuxInfo *aux = (AuxInfo *) m_gc;
+   assert(aux);
+   aux->CopySubBuffer(x, y, width, height);
+}
+
+
+BView *BGLView::EmbeddedView()
+{
+   // XXX to do
+
+}
+
+status_t BGLView::CopyPixelsOut(BPoint source, BBitmap *dest)
+{
+   // XXX to do
+}
+
+
+status_t BGLView::CopyPixelsIn(BBitmap *source, BPoint dest)
+{
+   // XXX to do
+}
+
+void BGLView::ErrorCallback(GLenum errorCode)
+{
+   // XXX to do
+}
+
+void BGLView::Draw(BRect updateRect)
+{
+//   printf("BGLView draw\n");
+   // XXX to do
+}
+
+void BGLView::AttachedToWindow()
+{
+   BView::AttachedToWindow();
+
+   // don't paint window background white when resized
+   SetViewColor(B_TRANSPARENT_32_BIT);
+}
+
+void BGLView::AllAttached()
+{
+   BView::AllAttached();
+//   printf("BGLView AllAttached\n");
+}
+
+void BGLView::DetachedFromWindow()
+{
+   BView::DetachedFromWindow();
+}
+
+void BGLView::AllDetached()
+{
+   BView::AllDetached();
+//   printf("BGLView AllDetached");
+}
+
+void BGLView::FrameResized(float width, float height)
+{
+   return BView::FrameResized(width, height);
+}
+
+status_t BGLView::Perform(perform_code d, void *arg)
+{
+   return BView::Perform(d, arg);
+}
+
+
+status_t BGLView::Archive(BMessage *data, bool deep) const
+{
+   return BView::Archive(data, deep);
+}
+
+void BGLView::MessageReceived(BMessage *msg)
+{
+   BView::MessageReceived(msg);
+}
+
+void BGLView::SetResizingMode(uint32 mode)
+{
+   BView::SetResizingMode(mode);
+}
+
+void BGLView::Show()
+{
+//   printf("BGLView Show\n");
+   BView::Show();
+}
+
+void BGLView::Hide()
+{
+//   printf("BGLView Hide\n");
+   BView::Hide();
+}
+
+BHandler *BGLView::ResolveSpecifier(BMessage *msg, int32 index,
+                                    BMessage *specifier, int32 form,
+                                    const char *property)
+{
+   return BView::ResolveSpecifier(msg, index, specifier, form, property);
+}
+
+status_t BGLView::GetSupportedSuites(BMessage *data)
+{
+   return BView::GetSupportedSuites(data);
+}
+
+void BGLView::DirectConnected( direct_buffer_info *info )
+{
+   // XXX to do
+}
+
+void BGLView::EnableDirectMode( bool enabled )
+{
+   // XXX to do
+}
+
+
+
+//---- private methods ----------
+
+void BGLView::_ReservedGLView1() {}
+void BGLView::_ReservedGLView2() {}
+void BGLView::_ReservedGLView3() {}
+void BGLView::_ReservedGLView4() {}
+void BGLView::_ReservedGLView5() {}
+void BGLView::_ReservedGLView6() {}
+void BGLView::_ReservedGLView7() {}
+void BGLView::_ReservedGLView8() {}
+
+#if 0
+BGLView::BGLView(const BGLView &v)
+       : BView(v)
+{
+   // XXX not sure how this should work
+   printf("Warning BGLView::copy constructor not implemented\n");
+}
+#endif
+
+
+BGLView &BGLView::operator=(const BGLView &v)
+{
+   printf("Warning BGLView::operator= not implemented\n");
+}
+
+void BGLView::dither_front()
+{
+   // no-op
+}
+
+bool BGLView::confirm_dither()
+{
+   // no-op
+   return false;
+}
+
+void BGLView::draw(BRect r)
+{
+   // XXX no-op ???
+}
+
+/* Direct Window stuff */
+void BGLView::drawScanline( int x1, int x2, int y, void *data )
+{
+   // no-op
+}
+
+void BGLView::scanlineHandler(struct rasStateRec *state,
+                              GLint x1, GLint x2)
+{
+   // no-op
+}
+
+void BGLView::lock_draw()
+{
+   // no-op
+}
+
+void BGLView::unlock_draw()
+{
+   // no-op
+}
+
+bool BGLView::validateView()
+{
+   // no-op
+   return true;
+}
+
diff --git a/src/mesa/drivers/d3d/D3DCAPS.CPP b/src/mesa/drivers/d3d/D3DCAPS.CPP
new file mode 100644 (file)
index 0000000..53595f0
--- /dev/null
@@ -0,0 +1,251 @@
+/*===========================================================================*/\r
+/*                                                                           */\r
+/* Mesa-3.0 DirectX 6 Driver                                       Build 5   */\r
+/*                                                                           */\r
+/* By Leigh McRae                                                            */\r
+/*                                                                           */\r
+/* http://www.altsoftware.com/                                               */\r
+/*                                                                           */\r
+/* Copyright (c) 1999-1998  alt.software inc.  All Rights Reserved           */\r
+/*===========================================================================*/\r
+#include "D3DHAL.h"\r
+/*===========================================================================*/\r
+/* Macros.                                                                   */\r
+/*===========================================================================*/\r
+#define SRCBLEND_MAP(gl,d3d,fall)      if ( pHAL->D3DHWDevDesc.dpcTriCaps.dwSrcBlendCaps & d3d ) \\r
+                                   { \\r
+                                                   sprintf( buffer, "SRC Blend: %s -> %s", # gl, # d3d ); \\r
+                                     DPF(( (DBG_CNTX_INFO|DBG_TXT_INFO), buffer )); \\r
+                                     pShared->dwSrcBlendCaps[index] = d3d; \\r
+                                                    } \\r
+                                                       else \\r
+                                   { \\r
+                                                   sprintf( buffer, "SRC Blend: %s -> %s", # gl, # fall ); \\r
+                                     DPF(( (DBG_CNTX_INFO|DBG_TXT_INFO), buffer )); \\r
+                                     pShared->dwSrcBlendCaps[index] = fall; \\r
+                                                       }\r
+#define DSTBLEND_MAP(gl,d3d,fall)      if ( pHAL->D3DHWDevDesc.dpcTriCaps.dwDestBlendCaps & d3d ) \\r
+                                   { \\r
+                                                   sprintf( buffer, "DST Blend: %s -> %s", # gl, # d3d ); \\r
+                                     DPF(( (DBG_CNTX_INFO|DBG_TXT_INFO), buffer )); \\r
+                                     pShared->dwDestBlendCaps[index] = d3d; \\r
+                                                    } \\r
+                                                       else \\r
+                                   { \\r
+                                                   sprintf( buffer, "DST Blend: %s -> %s", # gl, # fall ); \\r
+                                     DPF(( (DBG_CNTX_INFO|DBG_TXT_INFO), buffer )); \\r
+                                     pShared->dwDestBlendCaps[index] = fall; \\r
+                                                       }\r
+\r
+/*===========================================================================*/\r
+/*  I use this function to handle the fact that the D3D texture blending and */\r
+/* OpenGL texture blending functions don't map one to one.  Also there is the*/\r
+/* problem with cards not supporting all the D3D functions. So I use the CAPS*/\r
+/* of the card to make a table of functions that will have defaults for the  */\r
+/* unsupported functions.                                                    */\r
+/*  So first I fill the table with the fallback function then I check to see */\r
+/* if the card supports the requested function.  If it does I replace the    */\r
+/* default thats already in the array.  Now order does matter as I used an   */\r
+/* enum type in D3DShared.h so that the mapping would be a little easier.    */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+void AlphaBlendTableHAL( PMESAD3DHAL pHAL )\r
+{\r
+  PMESAD3DSHARED       pShared = &pHAL->shared;\r
+  int                  index;\r
+  char                 buffer[128];\r
+\r
+  DPF(( DBG_FUNC, "AlphaBlendTableHAL();" ));\r
+\r
+  /* Make the fallback for the Source blend. */\r
+  for( index = 0; index < 14; index++ )\r
+  {\r
+    switch( index )\r
+    {\r
+      case s_zero:\r
+        SRCBLEND_MAP( GL_ZERO, D3DBLEND_ZERO, D3DBLEND_ONE );\r
+          break;\r
+      case s_one:\r
+        SRCBLEND_MAP( GL_ONE, D3DBLEND_ONE, D3DBLEND_ONE );\r
+          break;\r
+      case s_dst_color:\r
+        SRCBLEND_MAP( GL_DST_COLOR, D3DBLEND_DESTCOLOR, D3DBLEND_ONE );\r
+          break;\r
+      case s_one_minus_dst_color:\r
+        SRCBLEND_MAP( GL_ONE_MINUS_DST_COLOR, D3DBLEND_INVDESTCOLOR, D3DBLEND_ONE );\r
+          break;\r
+      case s_src_alpha:\r
+        SRCBLEND_MAP( GL_SRC_ALPHA, D3DBLEND_SRCALPHA, D3DBLEND_ONE );\r
+          break;\r
+      case s_one_minus_src_alpha:\r
+        SRCBLEND_MAP( GL_ONE_MINUS_SRC_ALPHA, D3DBLEND_INVSRCALPHA, D3DBLEND_ONE );\r
+          break;\r
+      case s_dst_alpha:\r
+        SRCBLEND_MAP( GL_DST_ALPHA, D3DBLEND_DESTALPHA, D3DBLEND_ONE );\r
+          break;\r
+      case s_one_minus_dst_alpha:\r
+        SRCBLEND_MAP( GL_ONE_MINUS_DST_ALPHA, D3DBLEND_INVDESTALPHA, D3DBLEND_ONE );\r
+          break;\r
+      case s_src_alpha_saturate:\r
+        SRCBLEND_MAP( GL_SRC_ALPHA_SATURATE, D3DBLEND_SRCALPHASAT, D3DBLEND_ONE );\r
+          break;\r
+      case s_constant_color:\r
+        SRCBLEND_MAP( GL_CONSTANT_COLOR, D3DBLEND_SRCCOLOR, D3DBLEND_ONE );\r
+          break;\r
+      case s_one_minus_constant_color:\r
+        SRCBLEND_MAP( GL_ONE_MINUS_CONSTANT_COLOR, D3DBLEND_INVSRCCOLOR, D3DBLEND_ONE );\r
+          break;\r
+      case s_constant_alpha:\r
+        SRCBLEND_MAP( GL_CONSTANT_ALPHA, D3DBLEND_BOTHSRCALPHA, D3DBLEND_ONE );\r
+          break;\r
+      case s_one_minus_constant_alpha:\r
+        SRCBLEND_MAP( GL_ONE_MINUS_CONSTANT_ALPHA, D3DBLEND_BOTHINVSRCALPHA, D3DBLEND_ONE );\r
+          break;\r
+    }\r
+  }\r
+\r
+  /* Make the fallback for the Destination blend. */\r
+  for( index = 0; index < 14; index++ )\r
+  {\r
+    switch( index )\r
+    {\r
+      case d_zero:\r
+        DSTBLEND_MAP( GL_ZERO, D3DBLEND_ZERO, D3DBLEND_ONE );\r
+          break;\r
+      case d_one:\r
+        DSTBLEND_MAP( GL_ONE, D3DBLEND_ONE, D3DBLEND_ONE );\r
+          break;\r
+      case d_src_color:\r
+        DSTBLEND_MAP( GL_SRC_COLOR, D3DBLEND_SRCCOLOR, D3DBLEND_ONE );\r
+          break;\r
+      case d_one_minus_src_color:\r
+        DSTBLEND_MAP( GL_ONE_MINUS_SRC_COLOR, D3DBLEND_INVSRCCOLOR, D3DBLEND_ONE );\r
+          break;\r
+      case d_src_alpha:\r
+        DSTBLEND_MAP( GL_SRC_ALPHA, D3DBLEND_SRCALPHA, D3DBLEND_ONE );\r
+          break;\r
+      case d_one_minus_src_alpha:\r
+        DSTBLEND_MAP( GL_ONE_MINUS_SRC_ALPHA, D3DBLEND_INVSRCALPHA, D3DBLEND_ONE );\r
+          break;\r
+      case d_dst_alpha:\r
+        DSTBLEND_MAP( GL_DST_ALPHA, D3DBLEND_DESTALPHA, D3DBLEND_ONE );\r
+          break;\r
+      case d_one_minus_dst_alpha:\r
+        DSTBLEND_MAP( GL_ONE_MINUS_DST_ALPHA, D3DBLEND_INVDESTALPHA, D3DBLEND_ONE );\r
+          break;\r
+      case d_constant_color:\r
+        DSTBLEND_MAP( GL_CONSTANT_COLOR, D3DBLEND_DESTCOLOR, D3DBLEND_ONE );\r
+          break;\r
+      case d_one_minus_constant_color:\r
+        DSTBLEND_MAP( GL_ONE_MINUS_CONSTANT_COLOR, D3DBLEND_INVDESTCOLOR, D3DBLEND_ONE );\r
+          break;\r
+      case d_constant_alpha:\r
+        DSTBLEND_MAP( GL_CONSTANT_ALPHAR, D3DBLEND_BOTHSRCALPHA, D3DBLEND_ONE );\r
+          break;\r
+      case d_one_minus_constant_alpha:\r
+        DSTBLEND_MAP( GL_ONE_MINUS_CONSTANT_ALPHA, D3DBLEND_BOTHINVSRCALPHA, D3DBLEND_ONE );\r
+          break;\r
+    }\r
+  }\r
+\r
+  /* Make the fallbacks for the texture functions. */\r
+  for( index = 0; index < 4; index++ )\r
+  {\r
+    switch( index )\r
+    {\r
+      case d3dtblend_decal:\r
+          if ( pHAL->D3DHWDevDesc.dpcTriCaps.dwTextureBlendCaps & D3DTBLEND_DECAL )\r
+          {\r
+               DPF(( (DBG_CNTX_INFO|DBG_TXT_INFO), "D3DTBLEND_DECAL -> D3DTBLEND_DECAL" )); \r
+               pShared->dwTexFunc[index] = D3DTBLEND_DECAL; \r
+          }\r
+        else\r
+          {\r
+               if ( pHAL->D3DHWDevDesc.dpcTriCaps.dwTextureBlendCaps & D3DTBLEND_MODULATE )\r
+               {\r
+                 DPF(( (DBG_CNTX_INFO|DBG_TXT_INFO), "D3DTBLEND_DECAL -> D3DTBLEND_MODULATE" )); \r
+                 pShared->dwTexFunc[index] = D3DTBLEND_MODULATE; \r
+               }\r
+               else\r
+               {\r
+                 DPF(( (DBG_CNTX_INFO|DBG_TXT_INFO), "D3DTBLEND_DECAL -> D3DTBLEND_ADD" )); \r
+                 pShared->dwTexFunc[index] = D3DTBLEND_ADD; \r
+               }\r
+          }\r
+          break;\r
+      case d3dtblend_decalalpha:\r
+          if ( pHAL->D3DHWDevDesc.dpcTriCaps.dwTextureBlendCaps & D3DTBLEND_DECALALPHA )\r
+          {\r
+               DPF(( (DBG_CNTX_INFO|DBG_TXT_INFO), "D3DTBLEND_DECALALPHA -> D3DTBLEND_DECALALPHA" )); \r
+               pShared->dwTexFunc[index] = D3DTBLEND_DECALALPHA; \r
+          }\r
+        else\r
+          {\r
+               if ( pHAL->D3DHWDevDesc.dpcTriCaps.dwTextureBlendCaps & D3DTBLEND_DECAL )\r
+               {\r
+                 DPF(( (DBG_CNTX_INFO|DBG_TXT_INFO), "D3DTBLEND_DECALALPA -> D3DTBLEND_DECAL" )); \r
+                 pShared->dwTexFunc[index] = D3DTBLEND_DECAL; \r
+               }\r
+               else\r
+               {\r
+                 DPF(( (DBG_CNTX_INFO|DBG_TXT_INFO), "D3DTBLEND_DECALALPHA -> D3DTBLEND_ADD" )); \r
+                 pShared->dwTexFunc[index] = D3DTBLEND_ADD; \r
+               }\r
+          }\r
+          break;\r
+    case d3dtblend_modulate:\r
+          if ( pHAL->D3DHWDevDesc.dpcTriCaps.dwTextureBlendCaps & D3DTBLEND_MODULATE )\r
+          {\r
+               DPF(( (DBG_CNTX_INFO|DBG_TXT_INFO), "D3DTBLEND_MODULATE -> D3DTBLEND_MODULATE" )); \r
+               pShared->dwTexFunc[index] = D3DTBLEND_MODULATE; \r
+          }\r
+        else\r
+          {\r
+               if ( pHAL->D3DHWDevDesc.dpcTriCaps.dwTextureBlendCaps & D3DTBLEND_MODULATEALPHA )\r
+               {\r
+                 DPF(( (DBG_CNTX_INFO|DBG_TXT_INFO), "D3DTBLEND_MODULATE -> D3DTBLEND_MODULATEALPHA" )); \r
+                 pShared->dwTexFunc[index] = D3DTBLEND_MODULATEALPHA; \r
+               }\r
+               else    if ( pHAL->D3DHWDevDesc.dpcTriCaps.dwTextureBlendCaps & D3DTBLEND_DECAL )\r
+               {\r
+                 DPF(( (DBG_CNTX_INFO|DBG_TXT_INFO), "D3DTBLEND_MODULATE -> D3DTBLEND_DECAL" )); \r
+                 pShared->dwTexFunc[index] = D3DTBLEND_DECAL; \r
+               }\r
+               else\r
+               {\r
+                 DPF(( (DBG_CNTX_INFO|DBG_TXT_INFO), "D3DTBLEND_MODULATE -> D3DTBLEND_ADD" )); \r
+                 pShared->dwTexFunc[index] = D3DTBLEND_ADD; \r
+               }\r
+          }\r
+          break;\r
+    case d3dtblend_modulatealpha:\r
+          if ( pHAL->D3DHWDevDesc.dpcTriCaps.dwTextureBlendCaps & D3DTBLEND_MODULATEALPHA )\r
+          {\r
+               DPF(( (DBG_CNTX_INFO|DBG_TXT_INFO), "D3DTBLEND_MODULATEALPHA -> D3DTBLEND_MODULATEALPHA" )); \r
+               pShared->dwTexFunc[index] = D3DTBLEND_MODULATEALPHA; \r
+          }\r
+        else\r
+          {\r
+               if ( pHAL->D3DHWDevDesc.dpcTriCaps.dwTextureBlendCaps & D3DTBLEND_MODULATE )\r
+               {\r
+                 DPF(( (DBG_CNTX_INFO|DBG_TXT_INFO), "D3DTBLEND_MODULATEALPHA -> D3DTBLEND_MODULATE" )); \r
+                 pShared->dwTexFunc[index] = D3DTBLEND_MODULATE;\r
+               }\r
+               else    if ( pHAL->D3DHWDevDesc.dpcTriCaps.dwTextureBlendCaps & D3DTBLEND_DECAL )\r
+               {\r
+                 DPF(( (DBG_CNTX_INFO|DBG_TXT_INFO), "D3DTBLEND_MODULATEALPHA -> D3DTBLEND_DECALE" )); \r
+                 pShared->dwTexFunc[index] = D3DTBLEND_DECAL; \r
+               }\r
+               else\r
+               {\r
+                 DPF(( (DBG_CNTX_INFO|DBG_TXT_INFO), "D3DTBLEND_MODULATEALPHA -> D3DTBLEND_ADD" )); \r
+                 pShared->dwTexFunc[index] = D3DTBLEND_ADD; \r
+               }\r
+          }\r
+          break;\r
+    }\r
+  }\r
+}\r
+\r
+\1a
\ No newline at end of file
diff --git a/src/mesa/drivers/d3d/D3DHAL.H b/src/mesa/drivers/d3d/D3DHAL.H
new file mode 100644 (file)
index 0000000..12f4b4e
--- /dev/null
@@ -0,0 +1,69 @@
+/*===========================================================================*/\r
+/*                                                                           */\r
+/* Mesa-3.0 DirectX 6 Driver                                                 */\r
+/*                                                                           */\r
+/* By Leigh McRae                                                            */\r
+/*                                                                           */\r
+/* http://www.altsoftware.com/                                               */\r
+/*                                                                           */\r
+/* Copyright (c) 1999-1998  alt.software inc.  All Rights Reserved           */\r
+/*===========================================================================*/\r
+#ifndef _D3D_HAL_INC\r
+#define _D3D_HAL_INC\r
+   \r
+/*===========================================================================*/\r
+/* Includes.                                                                 */\r
+/*===========================================================================*/\r
+#include <windows.h>\r
+#include <ddraw.h>\r
+#include <d3d.h>\r
+#include <stdlib.h>\r
+#include <time.h>\r
+#include "D3DShared.h"\r
+#include "D3DTextureMgr.h"\r
+#include "Debug.h"\r
+/*===========================================================================*/\r
+/* Defines.                                                                  */\r
+/*===========================================================================*/\r
+#define        DX_RESTORE(ps)                  if ( (ps) && (ps)->IsLost() ) (ps)->Restore();\r
+/*===========================================================================*/\r
+/* Type defines.                                                             */\r
+/*===========================================================================*/\r
+typedef struct _d3d_hal_struct\r
+{\r
+  MESAD3DSHARED                shared;\r
+\r
+  GUID                         guid;\r
+  LPDIRECTDRAW                 lpDD;\r
+  LPDIRECTDRAW4                lpDD4;\r
+  LPDIRECT3D3                  lpD3D3;\r
+  LPDIRECT3DDEVICE3            lpD3DDevice;\r
+  D3DDEVICEDESC                D3DHWDevDesc;\r
+  LPDIRECTDRAWSURFACE4         lpDDSPrimary,\r
+                         lpDDSRender,\r
+                         lpDDSZbuffer;\r
+  LPDIRECT3DVIEWPORT3          lpViewport;\r
+  LPDIRECTDRAWCLIPPER  lpClipper;\r
+  DDPIXELFORMAT                ddpf,\r
+                         ddpfZBuffer;\r
+  PTM_OBJECT                   pTMList;\r
+\r
+} MESAD3DHAL, *PMESAD3DHAL;\r
+/*===========================================================================*/\r
+/* External function prototypes.                                             */\r
+/*===========================================================================*/\r
+extern BOOL InitTMgrHAL( PMESAD3DHAL pHAL );\r
+extern void TermTMgrHAL( PMESAD3DHAL pHAL );\r
+extern void AlphaBlendTableHAL( PMESAD3DHAL pHAL );\r
+\r
+extern void Solve8BitChannelPixelFormat( DDPIXELFORMAT *pddpf, PPIXELINFO pPixel );\r
+extern char *ErrorStringD3D( HRESULT hr );\r
+extern void  FatalShutDown( PMESAD3DHAL pHAL );\r
+/*===========================================================================*/\r
+/* Global variables.                                                         */\r
+/*===========================================================================*/\r
+extern char    *errorMsg;\r
+\r
+#endif\r
+\r
+\1a
\ No newline at end of file
diff --git a/src/mesa/drivers/d3d/D3DInit.cpp b/src/mesa/drivers/d3d/D3DInit.cpp
new file mode 100644 (file)
index 0000000..ba78916
--- /dev/null
@@ -0,0 +1,891 @@
+/*===========================================================================*/\r
+/*                                                                           */\r
+/* Mesa-3.0 DirectX 6 Driver                                       Build 5   */\r
+/*                                                                           */\r
+/* By Leigh McRae                                                            */\r
+/*                                                                           */\r
+/* http://www.altsoftware.com/                                               */\r
+/*                                                                           */\r
+/* Copyright (c) 1999-1998  alt.software inc.  All Rights Reserved           */\r
+/*===========================================================================*/\r
+#include "D3DHAL.h"\r
+/*===========================================================================*/\r
+/* Local function prototypes.                                                */\r
+/*===========================================================================*/\r
+static void    DestroyAllSurfaces( PMESAD3DHAL pHAL );\r
+static void    DestroyDevice( PMESAD3DHAL pHAL );\r
+static void    DestroyInterfaces( PMESAD3DHAL pHAL );\r
+\r
+HRESULT WINAPI   EnumSurfacesHook( LPDIRECTDRAWSURFACE4 lpDDS, LPDDSURFACEDESC2 lpDDSDesc, LPVOID pVoid );\r
+HRESULT CALLBACK EnumZBufferHook( DDPIXELFORMAT* pddpf, VOID *pVoid );\r
+HRESULT CALLBACK EnumDeviceHook( GUID FAR* lpGuid, LPSTR lpDesc, LPSTR lpName, LPD3DDEVICEDESC lpD3DHWDesc, LPD3DDEVICEDESC lpD3DHELDesc,  void *pVoid );\r
+/*===========================================================================*/\r
+/* Globals.                                                                  */\r
+/*===========================================================================*/\r
+//char         *errorMsg;\r
+/*===========================================================================*/\r
+/*  This function is responable for allocating the actual MESAD3DHAL struct. */\r
+/* Each Mesa context will have its own MESAD3DHAL struct so its like a mini  */\r
+/* context to some extent. All one time allocations/operations get done here.*/\r
+/*===========================================================================*/\r
+/* RETURN: TRUE, FALSE.                                                      */\r
+/*===========================================================================*/\r
+extern "C" PMESAD3DSHARED InitHAL( HWND hwnd )\r
+{\r
+  PMESAD3DHAL  pHAL;\r
+  ULONG        rc;\r
+\r
+  DPF(( DBG_FUNC, "InitHAL();" ));\r
+  DPF(( DBG_CNTX_INFO, "hwnd: %d", hwnd ));\r
+\r
+  /* Allocate the structure and zero it out. */   \r
+  pHAL = (PMESAD3DHAL)ALLOC( sizeof(MESAD3DHAL) );\r
+  if ( pHAL == NULL )\r
+  {   \r
+    RIP( pHAL, "InitHAL->", "Memory Allocation" );\r
+    return (PMESAD3DSHARED)NULL;\r
+  }\r
+  memset( pHAL, 0, sizeof(MESAD3DHAL) );\r
+\r
+  /* Get the texture manager going. */\r
+  rc = InitTMgrHAL( pHAL );\r
+  if ( rc == FALSE )\r
+  {   \r
+    RIP( pHAL, "InitTMgrHAL->", "Failed" );\r
+    return (PMESAD3DSHARED)NULL;\r
+  }\r
+\r
+  /* Fill in the window parameters if we can. */\r
+  pHAL->shared.hwnd = hwnd;\r
+\r
+  /* Parse the user's enviroment variables to generate a debug mask. */\r
+  ReadDBGEnv();\r
+  \r
+  return (PMESAD3DSHARED)pHAL;\r
+}\r
+/*===========================================================================*/\r
+/*  This function will unload all the resources that the MESAD3DHAL struct   */\r
+/* has bound to it.  The actual structure itself will be freed.              */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+extern "C" void TermHAL( PMESAD3DSHARED pShared )\r
+{\r
+  PMESAD3DHAL  pHAL = (PMESAD3DHAL)pShared;\r
+\r
+  DPF(( DBG_FUNC, "TermHAL();" ));\r
+\r
+  /* Check for an empty wrapper structure. */\r
+  if ( pHAL == NULL )\r
+    return;\r
+\r
+  /* Kill this texture manager. */\r
+  TermTMgrHAL( pHAL );\r
+\r
+  /* Kill any DDraw stuff if exists. */\r
+  DestroyDevice( pHAL );\r
+  DestroyAllSurfaces( pHAL );\r
+  DestroyInterfaces( pHAL );\r
+\r
+  FREE( pHAL );\r
+}\r
+/*===========================================================================*/\r
+/*  This function is used to init and resize the rendering surface as the two*/\r
+/* are almost the same.  First the device and all the surfaces are destoryed */\r
+/* if they already exist.  Next we create a OffScreen rendering surface and  */\r
+/* save some pixelformat info to do color convertions. Next we start to take */\r
+/* care of getting the most out of the hardware. I use bHardware to determine*/\r
+/* the state of the device we found in the device enumeration.  The enum proc*/\r
+/* will try for hardware first.  I next use a bForceSW to make the enum proc */\r
+/* choose a software device.  So I will try some combinations with HW first  */\r
+/* until I feel I have to set the bForceSW and call this function again.  If */\r
+/* this function is called with no width or height then use the internals.   */\r
+/*   NOTE:  The worst case is that all will be in SW (RGBDevice) and really  */\r
+/*         I should forget the whole thing and fall back to a DDraw span type*/\r
+/*         rendering but what is the point.  This way I always know I have a */\r
+/*         D3DDevice and that makes things easier.  I do impliment the span  */\r
+/*         rendering function for stuff that I haven't done support for such */\r
+/*         as points and lines.                                              */\r
+/*===========================================================================*/\r
+/* RETURN: TRUE, FALSE                                                       */\r
+/*===========================================================================*/\r
+extern "C" BOOL        CreateHAL( PMESAD3DSHARED pShared )\r
+{\r
+  PMESAD3DHAL          pHAL = (PMESAD3DHAL)pShared;\r
+  DDSURFACEDESC2       ddsd2;\r
+  D3DDEVICEDESC        D3DSWDevDesc;\r
+  DDSCAPS2             ddscaps;\r
+  DWORD                dwCoopFlags,\r
+                    dwWidth,\r
+                    dwHeight;\r
+  ULONG                rc;\r
+\r
+  DPF(( DBG_FUNC, "CreateHAL();" ));\r
+\r
+#define InitDDSD2(f)      memset( &ddsd2, 0, sizeof(DDSURFACEDESC2) ); \\r
+                          ddsd2.dwSize  = sizeof( DDSURFACEDESC2 ); \\r
+                          ddsd2.dwFlags = f;\r
+\r
+  if ( pHAL == NULL )\r
+    return FALSE;\r
+\r
+  /* Use the internal rectangle struct. */\r
+  dwWidth  = pShared->rectW.right - pShared->rectW.left;\r
+  dwHeight = pShared->rectW.bottom - pShared->rectW.top;\r
+\r
+  DPF(( DBG_CNTX_INFO, "Width: %d Height: %d", dwWidth, dwHeight ));\r
+\r
+  /* The dimensions might still be the same so just leave. */\r
+  if ( (dwWidth == pShared->dwWidth) && (dwHeight == pShared->dwHeight) )\r
+  {\r
+    DPF(( DBG_CNTX_WARN, "Context size hasn't changed" ));\r
+    return TRUE;\r
+  }\r
+\r
+  /* If one of the dimensions are zero then leave. WM_SIZE should get us back here. */\r
+  if ( (dwWidth == 0) || (dwHeight == 0) )\r
+    return TRUE;\r
+\r
+  /* Save the renders dimensions. */\r
+  pShared->dwWidth  = dwWidth;\r
+  pShared->dwHeight = dwHeight;\r
+\r
+  DPF(( DBG_CNTX_INFO, "Creating Context:\n cx:%d cy:%d", pShared->dwWidth, pShared->dwHeight ));\r
+\r
+  /*=================================*/\r
+  /* Create all required interfaces. */\r
+  /*=================================*/\r
+\r
+  /* Kill any DDraw stuff if exists. */\r
+  DestroyDevice( pHAL );\r
+  DestroyAllSurfaces( pHAL );\r
+  DestroyInterfaces( pHAL );\r
+\r
+  /* Create a instance of DDraw using the Primary display driver. */\r
+  rc = DirectDrawCreate( NULL, &pHAL->lpDD, NULL );\r
+  if( FAILED(rc) )\r
+  {\r
+    RIP( pHAL, "DirectDrawCreate->", ErrorStringD3D(rc) );\r
+    return FALSE;\r
+  }\r
+\r
+  /* Get the DDraw4 interface. */\r
+  rc = pHAL->lpDD->QueryInterface( IID_IDirectDraw4, (void **)&pHAL->lpDD4 );\r
+  if( FAILED(rc) )\r
+  {\r
+    RIP( pHAL, "QueryInterface (IID_IDirectDraw4) ->", ErrorStringD3D(rc) );\r
+    return FALSE;\r
+  }\r
+\r
+  /* Get the Direct3D3 interface. */\r
+  rc = pHAL->lpDD4->QueryInterface( IID_IDirect3D3, (void **)&pHAL->lpD3D3 );\r
+  if( FAILED(rc) )\r
+  {\r
+    RIP( pHAL, "QueryInterface (IID_IDirect3D3) ->", ErrorStringD3D(rc) );\r
+    return FALSE;\r
+  }\r
+\r
+  /* Set the Cooperative level. NOTE: we need to know if we are FS at this point.*/\r
+  dwCoopFlags = (pShared->bWindow == TRUE) ? DDSCL_NORMAL : (DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);\r
+  rc = pHAL->lpDD4->SetCooperativeLevel( pShared->hwnd, dwCoopFlags );\r
+  if ( FAILED(rc) )\r
+  {\r
+    RIP( pHAL, "SetCooperativeLevel->", ErrorStringD3D(rc) );\r
+    return FALSE;\r
+  }\r
+\r
+  /*==================================================================*/\r
+  /* Get the best device we can and note whether its hardware or not. */\r
+  /*==================================================================*/\r
+  pShared->bForceSW = FALSE;\r
+  pHAL->lpD3D3->EnumDevices( EnumDeviceHook, (void *)pHAL );\r
+  pShared->bHardware = IsEqualIID( pHAL->guid, IID_IDirect3DHALDevice );\r
+  DPF(( DBG_CNTX_INFO, "bHardware: %s", (pShared->bHardware) ? "TRUE" : "FALSE" ));\r
+  DPF(( DBG_CNTX_INFO, "bWindowed: %s", (pShared->bWindow) ? "TRUE" : "FALSE" ));\r
+\r
+  /*========================================================================*/\r
+  /* HARDWARE was found.                                                    */\r
+  /*========================================================================*/\r
+  if ( pShared->bHardware == TRUE )\r
+  {\r
+    /*===================================*/\r
+    /* HARDWARE -> Z-BUFFER.             */\r
+    /*===================================*/\r
+\r
+    /* Get a Z-Buffer pixelformat. */\r
+    memset( &ddsd2, 0, sizeof(DDSURFACEDESC2) );\r
+    ddsd2.dwSize = sizeof( DDSURFACEDESC2 );\r
+    rc = pHAL->lpD3D3->EnumZBufferFormats( pHAL->guid, EnumZBufferHook, (VOID*)&ddsd2.ddpfPixelFormat );\r
+    if ( FAILED(rc) )\r
+    {\r
+        RIP( pHAL, "EnumZBufferFormatsl->", ErrorStringD3D(rc) );\r
+        return FALSE;\r
+    }\r
+        \r
+    /* Setup our request structure for the Z-buffer surface. */\r
+    ddsd2.dwFlags        = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;\r
+    ddsd2.ddsCaps.dwCaps = DDSCAPS_ZBUFFER | DDSCAPS_VIDEOMEMORY;\r
+    ddsd2.dwWidth        = dwWidth;\r
+    ddsd2.dwHeight       = dwHeight;\r
+    rc = pHAL->lpDD4->CreateSurface( &ddsd2, &pHAL->lpDDSZbuffer, NULL );\r
+    if ( !FAILED(rc) )\r
+    {\r
+        DPF(( DBG_CNTX_INFO, "HW ZBuffer" ));\r
+\r
+        /*===================================*/\r
+        /* HARDWARE -> Z-BUFFER -> FLIPABLE  */\r
+        /*===================================*/\r
+        if ( pShared->bWindow == FALSE )\r
+        {\r
+          InitDDSD2( DDSD_CAPS | DDSD_BACKBUFFERCOUNT );\r
+          ddsd2.dwBackBufferCount = 1;\r
+          ddsd2.ddsCaps.dwCaps    = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;\r
+          rc = pHAL->lpDD4->CreateSurface( &ddsd2, &pHAL->lpDDSPrimary, NULL );\r
+          if ( FAILED(rc) )\r
+          {    \r
+               /* Make sure we try the next fall back. */\r
+               DPF(( DBG_CNTX_WARN, "HW Flip/Complex not available" ));\r
+               pHAL->lpDDSPrimary = NULL;\r
+          }\r
+          else\r
+          {\r
+               /* Get the back buffer that was created. */\r
+               ddscaps.dwCaps = DDSCAPS_BACKBUFFER;\r
+               rc = pHAL->lpDDSPrimary->GetAttachedSurface( &ddscaps, &pHAL->lpDDSRender );\r
+               if ( FAILED(rc) )\r
+               {       \r
+                 DPF(( DBG_CNTX_WARN, "GetAttachedSurface failed -> HW Flip/Complex" ));\r
+                 \r
+                 /* Make sure we try the next fall back. */\r
+                 pHAL->lpDDSPrimary->Release();\r
+                 pHAL->lpDDSPrimary = NULL;\r
+               }       \r
+               else\r
+               {\r
+                 /*  I have had problems when a complex surface comes back  */\r
+                 /* with the back buffer being created in SW.  Not sure why */\r
+                 /* or how this is possable but I'm checking for it here.   */\r
+                 memset( &ddsd2, 0, sizeof(DDSURFACEDESC2) ); \r
+                 ddsd2.dwSize = sizeof( DDSURFACEDESC2 );\r
+                 DX_RESTORE( pHAL->lpDDSRender );\r
+                 rc = pHAL->lpDDSRender->GetSurfaceDesc( &ddsd2 );\r
+                 if ( FAILED(rc) )\r
+                 {\r
+                   RIP( pHAL, "GetSurfaceDesc (RENDER) ->", ErrorStringD3D(rc) );\r
+                   return FALSE;\r
+                 }\r
+\r
+                 /* If the surface is in VID then we are happy with are Flipable. */\r
+                 if ( ddsd2.ddsCaps.dwCaps & DDSCAPS_LOCALVIDMEM )\r
+                 {\r
+                   pShared->bFlipable = TRUE;\r
+                   DPF(( DBG_CNTX_INFO, "HW Flip/Complex!" ));\r
+                 }\r
+                 else\r
+                 {\r
+                   /* Kill this setup. */\r
+                   pHAL->lpDDSPrimary->Release();\r
+                   pHAL->lpDDSPrimary = NULL;\r
+                 }\r
+               }\r
+          }\r
+        }\r
+\r
+        /*===================================*/\r
+        /* HARDWARE -> Z-BUFFER -> BLT       */\r
+        /*===================================*/\r
+        if ( pHAL->lpDDSPrimary == NULL )\r
+        {\r
+          pShared->bFlipable = FALSE;\r
+\r
+          /* Create the Primary (front buffer). */\r
+          InitDDSD2( DDSD_CAPS );\r
+          ddsd2.ddsCaps.dwCaps  = DDSCAPS_PRIMARYSURFACE;\r
+          rc = pHAL->lpDD4->CreateSurface( &ddsd2, &pHAL->lpDDSPrimary, NULL );\r
+          if ( FAILED(rc) )\r
+          {\r
+               /* This is an error as we should be able to do this at minimum. */\r
+               RIP( pHAL, "CreateSurface (PRIMARY) ->", ErrorStringD3D(rc) );\r
+               return FALSE;\r
+          }\r
+\r
+          /* Create the Render (back buffer). */\r
+          InitDDSD2( DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT );\r
+          ddsd2.dwWidth            = dwWidth;\r
+          ddsd2.dwHeight           = dwHeight;\r
+          ddsd2.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;\r
+          rc = pHAL->lpDD4->CreateSurface( &ddsd2, &pHAL->lpDDSRender, NULL );\r
+          if ( FAILED(rc) )\r
+          {\r
+               DPF(( DBG_CNTX_WARN, "Failed HW Offscreen surface" ));\r
+\r
+               /* Make sure we try the next fall back. */\r
+               pHAL->lpDDSPrimary->Release();\r
+               pHAL->lpDDSPrimary = NULL;\r
+          }\r
+          else\r
+          {\r
+               /*  Might as well check here too see if this surface is in */\r
+               /* hardware.  If nothing else just to be consistant.       */\r
+               memset( &ddsd2, 0, sizeof(DDSURFACEDESC2) ); \r
+               ddsd2.dwSize = sizeof( DDSURFACEDESC2 );\r
+               DX_RESTORE( pHAL->lpDDSRender );\r
+               rc = pHAL->lpDDSRender->GetSurfaceDesc( &ddsd2 );\r
+               if ( FAILED(rc) )\r
+               {\r
+                 RIP( pHAL, "GetSurfaceDesc (RENDER) ->", ErrorStringD3D(rc) );\r
+                 return FALSE;\r
+               }\r
+\r
+               /* If the surface is in VID then we are happy. */\r
+               if ( ddsd2.ddsCaps.dwCaps & DDSCAPS_LOCALVIDMEM )\r
+               {\r
+                 /*  Create a clipper object so that DDraw will be able to blt windows that */\r
+                 /* have been clipped by the screen or other windows.                       */\r
+                 pHAL->lpDD4->CreateClipper( 0, &pHAL->lpClipper, NULL );\r
+                 pHAL->lpClipper->SetHWnd( 0, pShared->hwnd );\r
+                 pHAL->lpDDSPrimary->SetClipper( pHAL->lpClipper );\r
+                 pHAL->lpClipper->Release();\r
+                 DPF(( DBG_CNTX_INFO, "HW RENDER surface" ));\r
+               }\r
+               else\r
+               {\r
+                 /* Kill this setup. */\r
+                 pHAL->lpDDSRender->Release();\r
+                 pHAL->lpDDSRender = NULL;\r
+                 pHAL->lpDDSPrimary->Release();\r
+                 pHAL->lpDDSPrimary = NULL;\r
+               }\r
+          }\r
+        }      \r
+\r
+        /*===================================*/\r
+        /* Create D3DDEVICE -> HARDWARE.     */\r
+        /*===================================*/\r
+        if ( pHAL->lpDDSZbuffer && pHAL->lpDDSPrimary && pHAL->lpDDSRender )\r
+        {\r
+          DX_RESTORE( pHAL->lpDDSRender );\r
+          DX_RESTORE( pHAL->lpDDSZbuffer );\r
+\r
+          rc = pHAL->lpDDSRender->AddAttachedSurface( pHAL->lpDDSZbuffer );\r
+          if ( FAILED(rc) )\r
+          {\r
+               RIP( pHAL, "AddAttachedSurface (ZBUFFER) ->", ErrorStringD3D(rc) );\r
+               return FALSE;\r
+          }\r
+\r
+          rc = pHAL->lpD3D3->CreateDevice( IID_IDirect3DHALDevice, pHAL->lpDDSRender, &pHAL->lpD3DDevice, NULL );\r
+          if ( rc != D3D_OK )\r
+          {\r
+               DPF(( DBG_CNTX_WARN, "Failed HW Device" ));\r
+               pHAL->lpD3DDevice = NULL;\r
+          }\r
+          else\r
+          {\r
+               DPF(( DBG_CNTX_INFO, "HW Device" ));\r
+          }\r
+        }\r
+    }  \r
+  }\r
+      \r
+  /*========================================================================*/\r
+  /* SOFTWARE fallback.                                                     */\r
+  /*========================================================================*/\r
+  if ( pHAL->lpD3DDevice == NULL )\r
+  {\r
+    DPF(( DBG_CNTX_INFO, "SW fallback :(" ));\r
+\r
+    /* Make sure we have no surfaces allocated.  Just incase. */\r
+    DestroyAllSurfaces( pHAL );\r
+\r
+    /* Get a software device. */\r
+    pShared->bFlipable = FALSE;\r
+    pShared->bForceSW = TRUE;\r
+    pHAL->lpD3D3->EnumDevices( EnumDeviceHook, (void *)pHAL );\r
+    pShared->bHardware = IsEqualIID( pHAL->guid, IID_IDirect3DHALDevice );\r
+\r
+     /*===================================*/\r
+    /* SOFTWARE -> Z-BUFFER.             */\r
+    /*===================================*/\r
+\r
+    /*===================================*/\r
+    /* SOFTWARE -> Z-BUFFER -> FLIPABLE  */\r
+    /*===================================*/\r
+    if ( pShared->bWindow == FALSE )\r
+    {\r
+        InitDDSD2( DDSD_CAPS | DDSD_BACKBUFFERCOUNT );\r
+        ddsd2.dwBackBufferCount = 1;\r
+        ddsd2.ddsCaps.dwCaps    = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;\r
+        ddsd2.ddpfPixelFormat.dwSize  = sizeof( DDPIXELFORMAT );\r
+        ddsd2.ddpfPixelFormat.dwFlags = (DDPF_RGB | DDPF_ALPHAPIXELS);\r
+        rc = pHAL->lpDD4->CreateSurface( &ddsd2, &pHAL->lpDDSPrimary, NULL );\r
+        if ( FAILED(rc) )\r
+        {      \r
+          DPF(( DBG_CNTX_WARN, "Failed SW Flip/Complex" ));\r
+\r
+          /* Make sure we try the next fall back. */\r
+          pHAL->lpDDSPrimary = NULL;\r
+        }\r
+        else\r
+        {\r
+          ddscaps.dwCaps = DDSCAPS_BACKBUFFER;\r
+          rc = pHAL->lpDDSPrimary->GetAttachedSurface( &ddscaps, &pHAL->lpDDSRender );\r
+          if ( FAILED(rc) )\r
+          {    \r
+               /* Make sure we try the next fall back. */\r
+               DPF(( DBG_CNTX_WARN, "GetAttachedSurface failed -> SW Flip/Complex" ));\r
+               pHAL->lpDDSPrimary->Release();\r
+               pHAL->lpDDSPrimary = NULL;\r
+          }    \r
+          else\r
+          {\r
+               DPF(( DBG_CNTX_INFO, "SW Flip/Complex" ));\r
+               pShared->bFlipable = TRUE;\r
+          }\r
+        }\r
+    }          \r
+\r
+    /*===================================*/\r
+    /* SOFTWARE -> Z-BUFFER -> BLT       */\r
+    /*===================================*/\r
+    if ( pHAL->lpDDSPrimary == NULL )\r
+    {\r
+        /* Create the Primary (front buffer). */\r
+        InitDDSD2( DDSD_CAPS );\r
+        ddsd2.ddsCaps.dwCaps  = DDSCAPS_PRIMARYSURFACE;\r
+        rc = pHAL->lpDD4->CreateSurface( &ddsd2, &pHAL->lpDDSPrimary, NULL );\r
+        if ( FAILED(rc) )\r
+        {\r
+          /* This is an error as we should be able to do this at minimum. */\r
+          RIP( pHAL, "CreateSurface (PRIMARY) ->", ErrorStringD3D(rc) );\r
+          return FALSE;\r
+        }\r
+\r
+        /* Create the Render (back buffer). */\r
+        InitDDSD2( DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT );\r
+        ddsd2.dwWidth                                  = dwWidth;\r
+        ddsd2.dwHeight                         = dwHeight;\r
+        ddsd2.ddsCaps.dwCaps                   = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;\r
+        ddsd2.ddpfPixelFormat.dwSize   = sizeof( DDPIXELFORMAT );\r
+        ddsd2.ddpfPixelFormat.dwFlags  = (DDPF_RGB | DDPF_ALPHAPIXELS);\r
+        rc = pHAL->lpDD4->CreateSurface( &ddsd2, &pHAL->lpDDSRender, NULL );\r
+        if ( FAILED(rc) )\r
+        {\r
+          /* That was our last hope. */\r
+          RIP( pHAL, "CreateSurface (RENDER) ->", ErrorStringD3D(rc) );\r
+          return FALSE;\r
+        }\r
+        else\r
+        {\r
+          DPF(( DBG_CNTX_INFO, "SW RENDER surface" ));\r
+\r
+          /*  Create a clipper object so that DDraw will be able to blt windows that */\r
+          /* have been clipped by the screen or other windows.                       */\r
+          pHAL->lpDD4->CreateClipper( 0, &pHAL->lpClipper, NULL );\r
+          pHAL->lpClipper->SetHWnd( 0, pShared->hwnd );\r
+          pHAL->lpDDSPrimary->SetClipper( pHAL->lpClipper );\r
+          pHAL->lpClipper->Release();\r
+        }\r
+    }          \r
+       \r
+    /*===================================*/\r
+    /* Create D3DDEVICE -> SOFTWARE.     */\r
+    /*===================================*/\r
+    if ( pHAL->lpDDSPrimary && pHAL->lpDDSRender )\r
+    {\r
+        DX_RESTORE( pHAL->lpDDSRender );\r
+        rc = pHAL->lpD3D3->CreateDevice( IID_IDirect3DRGBDevice, pHAL->lpDDSRender, &pHAL->lpD3DDevice, NULL );\r
+        if ( rc != D3D_OK )\r
+        {\r
+          /* That was our last hope. */\r
+          RIP( pHAL, "CreateDevice (IID_IDirect3DRGBDevice) ->", ErrorStringD3D(rc) );\r
+          return FALSE;\r
+        }\r
+        \r
+        DPF(( DBG_CNTX_INFO, "SW Device" ));\r
+    }  \r
+  }\r
+\r
+  /*==============================================================================*/\r
+  /* Get a copy of the render pixelformat so that wgl.c can call GetPixelInfoD3D. */\r
+  /*==============================================================================*/\r
+  memset( &pHAL->ddpf, 0, sizeof(DDPIXELFORMAT) );\r
+  pHAL->ddpf.dwSize = sizeof( DDPIXELFORMAT );\r
+  rc = pHAL->lpDDSRender->GetPixelFormat( &pHAL->ddpf );\r
+  if ( FAILED(rc) )\r
+  {\r
+    RIP( pHAL, "GetPixelFormat ->", ErrorStringD3D(rc) );\r
+    return FALSE;\r
+  }\r
+  DebugPixelFormat( "Using OFFSCREEN", &pHAL->ddpf );\r
+  DebugPixelFormat( "Using ZBUFFER", &ddsd2.ddpfPixelFormat );\r
+\r
+  /* Get a copy of what the D3DDevice supports for later use. */\r
+  memset( &D3DSWDevDesc, 0, sizeof(D3DDEVICEDESC) );\r
+  memset( &pHAL->D3DHWDevDesc, 0, sizeof(D3DDEVICEDESC) );\r
+  D3DSWDevDesc.dwSize       = sizeof( D3DDEVICEDESC );\r
+  pHAL->D3DHWDevDesc.dwSize = sizeof( D3DDEVICEDESC );\r
+  rc = pHAL->lpD3DDevice->GetCaps( &pHAL->D3DHWDevDesc, &D3DSWDevDesc );\r
+  if ( FAILED(rc) )\r
+  {\r
+    RIP( pHAL, "GetCaps ->", ErrorStringD3D(rc) );\r
+    return FALSE;\r
+  }\r
+\r
+  /* Get a copy of the pixel convertion stuff for direct buffer access. */\r
+  Solve8BitChannelPixelFormat( &pHAL->ddpf, &pShared->pixel );\r
+  AlphaBlendTableHAL( pHAL );\r
+\r
+  /* We must prime the Begin/End scene for SwapBuffers to work. */\r
+  rc = pHAL->lpD3DDevice->BeginScene();   \r
+  if ( FAILED(rc) )\r
+  {\r
+    RIP( pHAL, "BeginScene ->", ErrorStringD3D(rc) );\r
+    return FALSE;\r
+  }\r
+\r
+#undef InitDDSD2\r
+\r
+  return TRUE;\r
+}\r
+/*===========================================================================*/\r
+/*  This function will make sure a viewport is created and set for the device*/\r
+/* in the supplied structure.  If a rect is supplied then it will be used for*/\r
+/* the viewport otherwise the current setting in the strucute will be used.  */\r
+/* Note that the rect is relative to the window.  So left/top must be 0,0 to */\r
+/* use the whole window else there is scissoring going down.                 */\r
+/*===========================================================================*/\r
+/* RETURN: TRUE, FALSE.                                                      */\r
+/*===========================================================================*/\r
+extern "C" BOOL SetViewportHAL( PMESAD3DSHARED pShared, RECT *pRect, float minZ, float maxZ  )\r
+{\r
+  PMESAD3DHAL  pHAL = (PMESAD3DHAL)pShared;\r
+  D3DVIEWPORT2 vdData;\r
+  ULONG                rc;\r
+  POINT                pt;\r
+\r
+  DPF(( DBG_FUNC, "SetViewportHAL();" ));\r
+\r
+  /* Make sure we have enough info. */\r
+  if ( !pHAL || !pHAL->lpDDSPrimary || !pHAL->lpD3DDevice )\r
+  {\r
+    DPF(( DBG_CNTX_WARN, "SetViewport() -> NULL Pointer" ));\r
+    return FALSE;\r
+  }\r
+\r
+  /* TODO: this is just a temp fix to stop redundant changes. */\r
+  if ( pRect &&\r
+         (pShared->rectV.left   == pRect->left)    &&\r
+         (pShared->rectV.right  == pRect->right)   &&\r
+         (pShared->rectV.top    == pRect->top)     &&\r
+         (pShared->rectV.bottom == pRect->bottom) )\r
+  {\r
+    DPF(( DBG_CNTX_WARN, "Redundant viewport" ));\r
+    return TRUE;\r
+  }\r
+\r
+  DPF(( DBG_CNTX_INFO, "Current Viewport:" ));\r
+  DPF(( DBG_CNTX_INFO, "x: %d y: %d", pShared->rectV.left, pShared->rectV.top ));\r
+  DPF(( DBG_CNTX_INFO, "cx: %d cy: %d", (pShared->rectV.right-pShared->rectV.left), (pShared->rectV.bottom-pShared->rectV.top) ));\r
+  DPF(( DBG_CNTX_INFO, "New Viewport:" ));\r
+  DPF(( DBG_CNTX_INFO, "x: %d y: %d", pRect->left, pRect->top ));\r
+  DPF(( DBG_CNTX_INFO, "cx: %d cy: %d", (pRect->right-pRect->left), (pRect->bottom-pRect->top) ));\r
+\r
+  /* Update the current viewport rect if one is supplied. */\r
+  if ( pRect )      \r
+    memcpy( &pShared->rectV, pRect, sizeof(RECT) );\r
+        \r
+  /* Build the request structure. */\r
+  memset( &vdData, 0, sizeof(D3DVIEWPORT2) );\r
+  vdData.dwSize   = sizeof(D3DVIEWPORT2);  \r
+  vdData.dwX      = pShared->rectV.left;\r
+  vdData.dwY      = pShared->rectV.top;\r
+  vdData.dwWidth  = (pShared->rectV.right - pShared->rectV.left);\r
+  vdData.dwHeight = (pShared->rectV.bottom - pShared->rectV.top);\r
+\r
+  if ( !vdData.dwWidth || !vdData.dwHeight )\r
+  {\r
+    GetClientRect( pShared->hwnd, &pShared->rectW );\r
+    pt.x = pt.y = 0;\r
+    ClientToScreen( pShared->hwnd, &pt );\r
+    OffsetRect( &pShared->rectW, pt.x, pt.y);\r
+    vdData.dwX      = pShared->rectW.left;\r
+    vdData.dwY      = pShared->rectW.top;\r
+    vdData.dwWidth  = (pShared->rectW.right - pShared->rectW.left);\r
+    vdData.dwHeight = (pShared->rectW.bottom - pShared->rectW.top);\r
+    memcpy( &pShared->rectV, &pShared->rectW, sizeof(RECT) );\r
+  }\r
+\r
+  // The dvClipX, dvClipY, dvClipWidth, dvClipHeight, dvMinZ, \r
+  // and dvMaxZ members define the non-normalized post-perspective \r
+  // 3-D view volume which is visible to the viewer. In most cases, \r
+  // dvClipX is set to -1.0 and dvClipY is set to the inverse of \r
+  // the viewport's aspect ratio on the target surface, which can be \r
+  // calculated by dividing the dwHeight member by dwWidth. Similarly, \r
+  // the dvClipWidth member is typically 2.0 and dvClipHeight is set \r
+  // to twice the aspect ratio set in dwClipY. The dvMinZ and dvMaxZ \r
+  // are usually set to 0.0 and 1.0.\r
+  vdData.dvClipX      = -1.0f;\r
+  vdData.dvClipWidth  = 2.0f;\r
+  vdData.dvClipY      = 1.0f;\r
+  vdData.dvClipHeight = 2.0f;\r
+  vdData.dvMaxZ       = maxZ;\r
+  vdData.dvMinZ       = minZ;\r
+\r
+  DPF(( DBG_CNTX_INFO, "zMin: %f zMax: %f", minZ, maxZ ));\r
+\r
+  /*  I'm going to destroy the viewport everytime as when we size we will */\r
+  /* have a new D3DDevice.  As this area doesn't need to be fast...       */\r
+  if ( pHAL->lpViewport )\r
+  {\r
+    DPF(( DBG_CNTX_INFO, "DeleteViewport" ));\r
+\r
+    pHAL->lpD3DDevice->DeleteViewport( pHAL->lpViewport );\r
+    rc = pHAL->lpViewport->Release();\r
+    pHAL->lpViewport = NULL;\r
+  }\r
+\r
+  rc = pHAL->lpD3D3->CreateViewport( &pHAL->lpViewport, NULL );\r
+  if ( rc != D3D_OK )\r
+  {\r
+    DPF(( DBG_CNTX_ERROR, "CreateViewport Failed" ));\r
+    return FALSE;\r
+  }\r
+\r
+  /* Update the device with the new viewport. */\r
+  pHAL->lpD3DDevice->AddViewport( pHAL->lpViewport );\r
+  pHAL->lpViewport->SetViewport2( &vdData );\r
+  pHAL->lpD3DDevice->SetCurrentViewport( pHAL->lpViewport );\r
+\r
+  return TRUE; \r
+}\r
+/*===========================================================================*/\r
+/*                                                                           */\r
+/*                                                                           */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+HRESULT WINAPI EnumSurfacesHook( LPDIRECTDRAWSURFACE4 lpDDS, LPDDSURFACEDESC2 lpDDSDesc, LPVOID pVoid )\r
+{\r
+  DDSURFACEDESC2 *pddsd2 = (DDSURFACEDESC2 *)pVoid;\r
+\r
+  DPF(( DBG_FUNC, "EnumSurfacesHook();" ));\r
+\r
+  if ( (lpDDSDesc->ddpfPixelFormat.dwFlags == pddsd2->ddpfPixelFormat.dwFlags) && (lpDDSDesc->ddsCaps.dwCaps == pddsd2->ddsCaps.dwCaps) )\r
+  {\r
+    /* Save the pixelformat now so that we know we have one. */\r
+    memcpy( pddsd2, lpDDSDesc, sizeof(DDSURFACEDESC2) );\r
+\r
+    return D3DENUMRET_CANCEL;\r
+  }\r
+\r
+  return D3DENUMRET_OK;\r
+}\r
+/*===========================================================================*/\r
+/*  This is the callback proc to get a Z-Buffer.  Thats it.                  */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+HRESULT CALLBACK  EnumZBufferHook( DDPIXELFORMAT* pddpf, VOID *pVoid )\r
+{\r
+  DDPIXELFORMAT  *pddpfChoice = (DDPIXELFORMAT *)pVoid;\r
+\r
+  DPF(( DBG_FUNC, "EnumZBufferHook();" ));\r
+\r
+  /* If this is ANY type of depth-buffer, stop. */\r
+  if( pddpf->dwFlags == DDPF_ZBUFFER )\r
+  {\r
+    /* Save the pixelformat now so that we know we have one. */\r
+    memcpy( pddpfChoice, pddpf, sizeof(DDPIXELFORMAT) );\r
+\r
+    /* I feel if the hardware supports this low then lets use it.  Could get ugly. */\r
+    if( pddpf->dwZBufferBitDepth >= 8 )\r
+    {\r
+        return D3DENUMRET_CANCEL;\r
+    }\r
+  }\r
\r
+   return D3DENUMRET_OK;\r
+}\r
+/*===========================================================================*/\r
+/*  This function handles the callback for the D3DDevice enumeration.  Good  */\r
+/* god who's idea was this?  The D3D wrapper has two variable related to what*/\r
+/* kind of device we want and have.  First we have a Bool that is set if we  */\r
+/* have allocated a HW device.  We always look for the HW device first.  The */\r
+/* other variable is used to force SW.  If we have run into a case that we   */\r
+/* want to fallback to SW then we set this.  We will fallback if we cannot   */\r
+/* texture in video memory (among others).                                   */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+HRESULT CALLBACK  EnumDeviceHook( GUID FAR* lpGuid, LPSTR lpDesc, LPSTR lpName, LPD3DDEVICEDESC lpD3DHWDesc, LPD3DDEVICEDESC lpD3DHELDesc,  void *pVoid )\r
+{\r
+  PMESAD3DHAL          pHAL = (PMESAD3DHAL)pVoid;\r
+  LPD3DDEVICEDESC   pChoice = lpD3DHWDesc;\r
+\r
+  DPF(( DBG_FUNC, "EnumDeviceHook();" ));\r
+\r
+  /* Determine if which device description is valid. */\r
+  if ( pChoice->dcmColorModel == 0 )\r
+    pChoice = lpD3DHELDesc;\r
+\r
+  /* Make sure we always have a GUID. */\r
+  memcpy( &pHAL->guid, lpGuid, sizeof(GUID) );\r
+\r
+  /* This controls whether we will except HW or not. */\r
+  if ( pHAL->shared.bForceSW == TRUE )\r
+  {\r
+    return (pChoice == lpD3DHELDesc) ? D3DENUMRET_CANCEL : D3DENUMRET_OK;\r
+  }\r
+\r
+  /* Always try for hardware. */\r
+  if ( pChoice == lpD3DHWDesc )\r
+  {\r
+    return D3DENUMRET_CANCEL;\r
+  }\r
+\r
+  return D3DENUMRET_OK;\r
+}\r
+/*===========================================================================*/\r
+/*  This function will destroy any and all surfaces that this context has    */\r
+/* allocated.  If there is a clipper object then it will also be destoryed as*/\r
+/* it is part of the Primary Surface.                                        */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+static void DestroyAllSurfaces( PMESAD3DHAL pHAL )\r
+{\r
+  LONG refCount;\r
+\r
+  DPF(( DBG_FUNC, "DestroyAllSurfaces();" ));\r
+\r
+  DX_RESTORE( pHAL->lpDDSPrimary );\r
+  DX_RESTORE( pHAL->lpDDSRender );\r
+  DX_RESTORE( pHAL->lpDDSZbuffer);\r
+\r
+  if ( pHAL->lpDDSRender )\r
+  {\r
+    pHAL->lpDDSRender->Unlock( NULL );\r
+\r
+    /* If this isn't a Flipable surface then we must clean up the render. */\r
+    if ( pHAL->shared.bFlipable == FALSE)\r
+    {\r
+        if ( pHAL->lpDDSZbuffer )\r
+        {\r
+          DPF(( DBG_CNTX_INFO, "Remove attached surfaces from RENDER" ));\r
+          pHAL->lpDDSRender->DeleteAttachedSurface( 0, NULL );\r
+        }\r
+\r
+        DPF(( DBG_CNTX_INFO, "Release RENDER" ));\r
+        refCount = pHAL->lpDDSRender->Release();\r
+        pHAL->lpDDSRender = NULL;\r
+    }\r
+  }\r
+\r
+  if ( pHAL->lpDDSZbuffer )\r
+  {\r
+    DPF(( DBG_CNTX_INFO, "Release ZBuffer" ));\r
+    pHAL->lpDDSZbuffer->Unlock( NULL );\r
+    refCount = pHAL->lpDDSZbuffer->Release();\r
+    pHAL->lpDDSZbuffer = NULL;\r
+  }\r
+\r
+  if ( pHAL->lpClipper )\r
+  {\r
+    DPF(( DBG_CNTX_INFO, "Release Clipper" ));\r
+    refCount = pHAL->lpClipper->Release();\r
+    pHAL->lpClipper = NULL;\r
+  }\r
+\r
+  if ( pHAL->lpDDSPrimary )\r
+  {\r
+    pHAL->lpDDSPrimary->Unlock( NULL );\r
+\r
+    DPF(( DBG_CNTX_INFO, "Release PRIMARY" ));\r
+    refCount = pHAL->lpDDSPrimary->Release();\r
+    pHAL->lpDDSPrimary = NULL;\r
+  }\r
+}\r
+/*===========================================================================*/\r
+/*  This function will destroy the current D3DDevice and any resources that  */\r
+/* belong to it.                                                             */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+static void DestroyDevice( PMESAD3DHAL pHAL )\r
+{\r
+  LONG refCount;\r
+\r
+  DPF(( DBG_FUNC, "DestroyDevice();" ));\r
+\r
+  /* Kill the D3D stuff if exists. */\r
+  if ( pHAL->lpViewport )\r
+  {\r
+    DPF(( DBG_CNTX_INFO, "Delete Viewport" ));\r
+    pHAL->lpD3DDevice->DeleteViewport( pHAL->lpViewport );\r
+\r
+    DPF(( DBG_CNTX_INFO, "Release Viewport" ));\r
+    refCount = pHAL->lpViewport->Release();\r
+    pHAL->lpViewport = NULL;\r
+  }\r
+\r
+  if ( pHAL->lpD3DDevice != NULL )\r
+  {\r
+    DPF(( DBG_CNTX_INFO, "Release D3DDevice" ));\r
+    refCount = pHAL->lpD3DDevice->EndScene();  \r
+    refCount = pHAL->lpD3DDevice->Release();\r
+    pHAL->lpD3DDevice = NULL;\r
+  }\r
+}\r
+/*===========================================================================*/\r
+/*  This function will destroy the current D3DDevice and any resources that  */\r
+/* belong to it.                                                             */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+static void DestroyInterfaces( PMESAD3DHAL pHAL )\r
+{\r
+  LONG refCount;\r
+\r
+  DPF(( DBG_FUNC, "DestroyInterfaces();" ));\r
+\r
+  if ( pHAL->lpD3D3 != NULL )\r
+  {\r
+    DPF(( DBG_CNTX_INFO, "Release Direct3D3" ));\r
+    refCount = pHAL->lpD3D3->Release();\r
+    pHAL->lpD3D3 = NULL;\r
+  }\r
+\r
+  if ( pHAL->lpDD4 != NULL )\r
+  {\r
+    DPF(( DBG_CNTX_INFO, "Release DDraw4" ));\r
+    refCount = pHAL->lpDD4->Release();\r
+    pHAL->lpDD4 = NULL;\r
+  }\r
+\r
+  if ( pHAL->lpDD != NULL )\r
+  {\r
+    DPF(( DBG_CNTX_INFO, "Release DDraw" ));\r
+    refCount = pHAL->lpDD->Release();\r
+    pHAL->lpDD = NULL;\r
+  }\r
+}\r
+/*===========================================================================*/\r
+/*  This function will first send (not post) a message to the client window  */\r
+/* that this context is using.  The client will respond by unbinding itself  */\r
+/* and binding the 'default' context.  This allows the API to be supported   */\r
+/* until the window can be destroyed.  Finally we post the quit message to   */\r
+/* the client in hopes to end the application.                               */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+void  FatalShutDown( PMESAD3DHAL pHAL )\r
+{\r
+  /* Whip this baby in too try and support the API until we die... */\r
+  if ( pHAL )\r
+    SendMessage( pHAL->shared.hwnd, UM_FATALSHUTDOWN, 0L, 0L );\r
+\r
+  /* Close the client application down. */\r
+  PostQuitMessage( 0 );\r
+}\r
+\r
diff --git a/src/mesa/drivers/d3d/D3DMESA.H b/src/mesa/drivers/d3d/D3DMESA.H
new file mode 100644 (file)
index 0000000..907f69f
--- /dev/null
@@ -0,0 +1,85 @@
+/*===========================================================================*/\r
+/*                                                                           */\r
+/* Mesa-3.0 DirectX 6 Driver                                                 */\r
+/*                                                                           */\r
+/* By Leigh McRae                                                            */\r
+/*                                                                           */\r
+/* http://www.altsoftware.com/                                               */\r
+/*                                                                           */\r
+/* Copyright (c) 1999-1998  alt.software inc.  All Rights Reserved           */\r
+/*===========================================================================*/\r
+#ifndef D3D_MESA_H\r
+#define D3D_MESA_H\r
+/*===========================================================================*/\r
+/* Includes.                                                                 */\r
+/*===========================================================================*/\r
+#include <windows.h>\r
+#include <ddraw.h>\r
+#include <d3d.h>\r
+#include "matrix.h"\r
+#include "context.h"\r
+#include "types.h"\r
+#include "vb.h"\r
+#include "D3DShared.h"\r
+#include "Debug.h"\r
+#include "NULLProcs.h"\r
+/*===========================================================================*/\r
+/* Macros.                                                                   */\r
+/*===========================================================================*/\r
+#define FLIP(h,y)                       (h-y)\r
+/*===========================================================================*/\r
+/* Magic numbers.                                                            */\r
+/*===========================================================================*/\r
+/*===========================================================================*/\r
+/* Type defines.                                                             */\r
+/*===========================================================================*/\r
+struct __extensions__\r
+{\r
+   PROC  proc;\r
+   char  *name;\r
+};\r
+\r
+typedef GLbitfield   (*ClearPROC)( GLcontext *ctx, GLbitfield mask, GLboolean all, GLint x, GLint y, GLint width, GLint height );\r
+typedef void         (*WSpanRGBPROC)( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte rgb[][3], const GLubyte mask[] );\r
+typedef void         (*WSpanRGBAPROC)( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte rgba[][4], const GLubyte mask[] );\r
+typedef void         (*WSpanRGBAMonoPROC)( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte mask[] );\r
+typedef void         (*WPixelsRGBAPROC)( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], const GLubyte rgba[][4], const GLubyte mask[] );\r
+typedef void         (*WPixelsRGBAMonoPROC)( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], const GLubyte mask[] );\r
+typedef void         (*RSpanRGBAPROC)( const GLcontext* ctx, GLuint n, GLint x, GLint y, GLubyte rgba[][4] );\r
+typedef void         (*RPixelsRGBAPROC)( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], GLubyte rgba[][4], const GLubyte mask[] );\r
+\r
+typedef struct D3D_mesa_context \r
+{\r
+  PMESAD3DSHARED        pShared;\r
+\r
+  GLcontext             *gl_ctx;       /* The core GL/Mesa context */\r
+  GLvisual              *gl_visual;    /* Describes the buffers */\r
+  GLframebuffer *gl_buffer;    /* Depth, stencil, accum, etc buffers */\r
+\r
+  HDC                   hdc;\r
+  WNDPROC               hOldProc;\r
+\r
+  UCHAR                 rClear,         /* Current clear colors. */\r
+                   gClear,\r
+                   bClear,\r
+                   aClear,\r
+                   rCurrent,           /* Current rendering colors. */\r
+                   gCurrent,\r
+                   bCurrent,\r
+                   aCurrent;\r
+\r
+   struct D3D_mesa_context *next;\r
+\r
+} D3DMESACONTEXT, *PD3DMESACONTEXT;\r
+/*===========================================================================*/\r
+/* Extern function prototypes.                                               */\r
+/*===========================================================================*/\r
+extern void gl_Viewport( GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height );\r
+/*===========================================================================*/\r
+/* Global variables.                                                         */\r
+/*===========================================================================*/\r
+extern D3DTLVERTEX   D3DTLVertices[(VB_MAX*6)];\r
+\r
+#endif\r
+\r
+\1a
\ No newline at end of file
diff --git a/src/mesa/drivers/d3d/D3DRaster.cpp b/src/mesa/drivers/d3d/D3DRaster.cpp
new file mode 100644 (file)
index 0000000..b87b3ab
--- /dev/null
@@ -0,0 +1,214 @@
+/*===========================================================================*/\r
+/*                                                                           */\r
+/* Mesa-3.0 DirectX 6 Driver                                                 */\r
+/*                                                                           */\r
+/* By Leigh McRae                                                            */\r
+/*                                                                           */\r
+/* http://www.altsoftware.com/                                               */\r
+/*                                                                           */\r
+/* Copyright (c) 1999-1998  alt.software inc.  All Rights Reserved           */\r
+/*===========================================================================*/\r
+#include "D3DHAL.h"\r
+/*===========================================================================*/\r
+/*  This function clears the context bound to the supplied shared context.   */\r
+/* The function takes the D3D flags D3DCLEAR_TARGET, D3DCLEAR_STENCIL and    */\r
+/* D3DCLEAR_ZBUFFER.  Set bAll to TRUE for a full clear else supply the coord*/\r
+/* of the rect to be cleared relative to the window.  The color is always a  */\r
+/* 32bit value (RGBA).  Fill in the z-value and stencil if needed.           */\r
+/*                                                                           */\r
+/*  TODO: this can be redone to be called by Mesa directly.                  */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+extern "C" void ClearHAL( PMESAD3DSHARED pShared, DWORD dwFlags, BOOL bAll, int x, int y, int cx, int cy, DWORD dwColor, float zv, DWORD dwStencil )\r
+{\r
+  PMESAD3DHAL  pHAL = (PMESAD3DHAL)pShared;\r
+  D3DRECT              d3dRect;\r
+\r
+#ifdef D3D_DEBUG\r
+  HRESULT              rc;\r
+\r
+  DPF(( DBG_FUNC, "CleaHAL();" ));\r
+\r
+  /* Make sure we have enough info. */\r
+  if ( (pHAL == NULL) || (pHAL->lpViewport == NULL) )\r
+    return;\r
+#endif\r
+\r
+  if ( bAll )\r
+  {\r
+    /* I assume my viewport is valid. */\r
+    d3dRect.lX1 = pShared->rectV.left;\r
+    d3dRect.lY1 = pShared->rectV.top;\r
+    d3dRect.lX2 = pShared->rectV.right;\r
+    d3dRect.lY2 = pShared->rectV.bottom;\r
+  }\r
+  else\r
+  {\r
+    d3dRect.lX1 = pShared->rectV.left + x;\r
+    d3dRect.lY1 = pShared->rectV.top  + y;\r
+    d3dRect.lX2 = d3dRect.lX1 + cx;\r
+    d3dRect.lY2 = d3dRect.lY1 + cy;\r
+  }\r
+\r
+#ifdef D3D_DEBUG\r
+  rc = pHAL->lpViewport->Clear2( 1, &d3dRect, dwFlags, dwColor, zv, dwStencil );\r
+  if ( FAILED(rc) )\r
+  {\r
+    RIP( pHAL, "Clear2 ->", ErrorStringD3D(rc) );\r
+  }\r
+#else\r
+  pHAL->lpViewport->Clear2( 1, &d3dRect, dwFlags, dwColor, zv, dwStencil );\r
+#endif\r
+}\r
+/*===========================================================================*/\r
+/*  Well this is the guts of it all.  Here we rasterize the primitives that  */\r
+/* are in their final form.  OpenGL has done all the lighting, transfomations*/\r
+/* and clipping at this point.                                               */\r
+/*                                                                           */\r
+/* TODO:  I'm not sure if I want to bother to check for errors on this call. */\r
+/*       The overhead kills me...                                            */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+extern "C" void DrawPrimitiveHAL( PMESAD3DSHARED pShared, D3DPRIMITIVETYPE dptPrimitiveType, D3DTLVERTEX *pVertices, DWORD dwCount )\r
+{\r
+  PMESAD3DHAL  pHAL = (PMESAD3DHAL)pShared;\r
+\r
+#ifdef D3D_DEBUG\r
+  HRESULT              rc;      \r
+\r
+  DPF(( DBG_FUNC, "DrawPrimitveHAL();" ));\r
+\r
+  /* Make sure we have enough info. */\r
+  if ( (pHAL == NULL) || (pHAL->lpD3DDevice == NULL) )\r
+    return;\r
+\r
+  DPF(( DBG_PRIM_INFO, "DP( %d )", dwCount ));\r
+\r
+  rc = pHAL->lpD3DDevice->DrawPrimitive( dptPrimitiveType,\r
+                                                                D3DFVF_TLVERTEX,\r
+                                                                (LPVOID)pVertices,\r
+                                                                dwCount, \r
+                                                                (D3DDP_DONOTCLIP | D3DDP_DONOTLIGHT) );\r
+  if ( FAILED(rc) )\r
+  {\r
+    RIP( pHAL, "DrawPrimitive ->", ErrorStringD3D(rc) );\r
+  }\r
+#else\r
+  pHAL->lpD3DDevice->DrawPrimitive( dptPrimitiveType,\r
+                                                        D3DFVF_TLVERTEX,\r
+                                                        (LPVOID)pVertices,\r
+                                                        dwCount, \r
+                                                        (D3DDP_DONOTCLIP | D3DDP_DONOTLIGHT) );\r
+#endif\r
+}\r
+/*===========================================================================*/\r
+/*  This call will handle the swapping of the buffers.  Now I didn't bother  */\r
+/* to support single buffered so this will be used for glFlush() as its all  */\r
+/* the same.  So first we do an EndScene as we are always considered to be in*/\r
+/* a BeginScene because when we leave we do a BeginScene.  Now note that when*/\r
+/* the context is created in the first place we do a BeginScene also just to */\r
+/* get things going.  The call will use either Flip/blt based on the type of */\r
+/* surface was created for rendering.                                        */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+extern "C" void SwapBuffersHAL( PMESAD3DSHARED pShared )\r
+{\r
+  PMESAD3DHAL  pHAL = (PMESAD3DHAL)pShared;\r
+\r
+#ifdef D3D_DEBUG\r
+  HRESULT              rc;      \r
+\r
+  DPF(( DBG_FUNC, "SwapBuffersHAL();" ));\r
+  DPF(( DBG_ALL_PROFILE, "=================SWAP===================" ));\r
+\r
+  /* Make sure we have enough info. */\r
+  if ( (pHAL == NULL) || (pHAL->lpD3DDevice == NULL) )\r
+    return;\r
+\r
+  /* Make sure we have enough info. */\r
+  if ( pHAL->lpDDSPrimary != NULL )\r
+  {\r
+    rc = pHAL->lpD3DDevice->EndScene();   \r
+    if ( FAILED(rc) )\r
+    {\r
+        RIP( pHAL, "EndScene ->", ErrorStringD3D(rc) );\r
+    }\r
\r
+    if ( pShared->bFlipable )\r
+    {\r
+        DPF(( DBG_CNTX_PROFILE, "Swap->FLIP" ));\r
+        rc = pHAL->lpDDSPrimary->Flip( NULL, DDFLIP_WAIT );\r
+    }\r
+    else\r
+    {\r
+        DPF(( DBG_CNTX_PROFILE, "Swap->Blt" ));\r
+        rc = pHAL->lpDDSPrimary->Blt( &pShared->rectW, pHAL->lpDDSRender, NULL, DDBLT_WAIT, NULL );\r
+    }\r
+    if ( FAILED(rc) )\r
+    {\r
+        RIP( pHAL, "Blt (RENDER/PRIMARY) ->", ErrorStringD3D(rc) );\r
+    }\r
+\r
+    rc = pHAL->lpD3DDevice->BeginScene(); \r
+    if ( FAILED(rc) )\r
+    {\r
+        RIP( pHAL, "BeginScene ->", ErrorStringD3D(rc) );\r
+    }\r
+  }\r
+#else\r
+  pHAL->lpD3DDevice->EndScene();   \r
+\r
+  if ( pShared->bFlipable )\r
+    pHAL->lpDDSPrimary->Flip( NULL, DDFLIP_WAIT );\r
+  else\r
+    pHAL->lpDDSPrimary->Blt( &pShared->rectW, pHAL->lpDDSRender, NULL, DDBLT_WAIT, NULL );\r
+\r
+  pHAL->lpD3DDevice->BeginScene(); \r
+\r
+#endif\r
+}\r
+/*===========================================================================*/\r
+/*  This function is a very thin wrapper for the D3D call 'SetRenderState'.  */\r
+/* Using this function requires all the types to be defined by including the */\r
+/* D3D header file.                                                          */\r
+/*                                                                           */\r
+/*  TODO:  would be much better to get ride of all these calls per VBRender. */\r
+/*        I feel I should get this call into SetRenderStates() the RenderVB. */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+extern "C" void SetStateHAL( PMESAD3DSHARED pShared, DWORD dwType, DWORD dwState )\r
+{\r
+  PMESAD3DHAL  pHAL = (PMESAD3DHAL)pShared;\r
+\r
+#ifdef D3D_DEBUG   \r
+  HRESULT              rc;\r
+\r
+  DPF(( DBG_FUNC, "SetStateHAL();" ));\r
+\r
+  /* Make sure we have enough info. */\r
+  if ( (pHAL == NULL) || (pHAL->lpD3DDevice == NULL) )\r
+    return;\r
+\r
+  rc = pHAL->lpD3DDevice->SetRenderState( (D3DRENDERSTATETYPE)dwType, dwState );\r
+  if ( FAILED(rc) )\r
+  {\r
+    RIP( pHAL, "SetRenderState ->", ErrorStringD3D(rc) );\r
+  }\r
+\r
+#else\r
+  pHAL->lpD3DDevice->SetRenderState( (D3DRENDERSTATETYPE)dwType, dwState );\r
+#endif\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\1a
\ No newline at end of file
diff --git a/src/mesa/drivers/d3d/D3DShared.h b/src/mesa/drivers/d3d/D3DShared.h
new file mode 100644 (file)
index 0000000..cc629e2
--- /dev/null
@@ -0,0 +1,154 @@
+/*===========================================================================*/
+/*                                                                           */
+/* Mesa-3.0 DirectX 6 Driver                                                 */
+/*                                                                           */
+/* By Leigh McRae                                                            */
+/*                                                                           */
+/* http://www.altsoftware.com/                                               */
+/*                                                                           */
+/* Copyright (c) 1999-1998  alt.software inc.  All Rights Reserved           */
+/*===========================================================================*/
+#ifndef D3D_MESA_ALL_H
+#define D3D_MESA_ALL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*===========================================================================*/
+/* Includes.                                                                 */
+/*===========================================================================*/
+#include <stdio.h>
+#include <string.h>
+/*===========================================================================*/
+/* Magic numbers.                                                            */
+/*===========================================================================*/
+#define        TM_ACTION_LOAD      0x01
+#define        TM_ACTION_BIND      0x02
+#define        TM_ACTION_UPDATE        0x04
+
+#define        UM_FATALSHUTDOWN        (WM_USER+42)
+/*===========================================================================*/
+/* Macros defines.                                                           */
+/*===========================================================================*/
+#define  ALLOC(cb)            malloc( (cb) )
+#define  FREE(p)              { free( (p) ); (p) = NULL; }
+/*===========================================================================*/
+/* Type defines.                                                             */
+/*===========================================================================*/
+typedef struct _pixel_convert
+{
+  int  cb,                     /* Count in bytes of one pixel. */
+          rShift,              /* Shift count that postions each componet. */
+            gShift,            
+            bShift,            
+          aShift;              
+  float   rScale,              /* Value that scales a color that ranges 0.0 -> 1.0 */
+          gScale,              /* to this pixel format.                            */
+          bScale,
+          aScale;
+  DWORD   dwRMask,             /* Color mask per component. */
+            dwGMask,
+          dwBMask,
+          dwAMask;
+
+} PIXELINFO, *PPIXELINFO;
+
+
+typedef struct _d3d_shared_info
+{
+  HWND         hwnd;
+  BOOL         bWindow,
+               bFlipable,
+               bForceSW,
+               bHardware;
+  RECT         rectW,                  /* Window size and postion in screen space. */
+               rectV;                  /* Viewport size and postion. */
+  DWORD                dwWidth,                        /* Current render size for quick checks. */
+               dwHeight;
+
+  PIXELINFO    pixel;                  
+  DWORD                dwSrcBlendCaps[14],     /* See D3DCAPS.CPP */
+               dwDestBlendCaps[14],
+               dwTexFunc[4];
+
+} MESAD3DSHARED, *PMESAD3DSHARED;
+
+typedef struct _render_options
+{
+  BOOL bForceSoftware,         /* TODO: Add user switches. */
+            bStretchtoPrimary;
+
+} USER_CTRL, *PUSER_CRTL;
+
+enum { s_zero = 0,                             
+         s_one, 
+         s_dst_color, 
+         s_one_minus_dst_color, 
+         s_src_alpha, 
+         s_one_minus_src_alpha, 
+         s_dst_alpha,
+         s_one_minus_dst_alpha,
+         s_src_alpha_saturate, 
+         s_constant_color, 
+         s_one_minus_constant_color, 
+         s_constant_alpha, 
+         s_one_minus_constant_alpha };
+
+enum { d_zero = 0, 
+         d_one, 
+         d_src_color, 
+         d_one_minus_src_color, 
+         d_src_alpha, 
+         d_one_minus_src_alpha, 
+         d_dst_alpha,
+         d_one_minus_dst_alpha,
+         d_constant_color,
+         d_one_minus_constant_color,
+         d_constant_alpha,
+         d_one_minus_constant_alpha };
+
+enum { d3dtblend_decal = 0,
+         d3dtblend_decalalpha,
+         d3dtblend_modulate,
+         d3dtblend_modulatealpha };
+
+/*===========================================================================*/
+/* Function prototypes.                                                      */
+/*===========================================================================*/
+PMESAD3DSHARED InitHAL( HWND hwnd );
+void           TermHAL( PMESAD3DSHARED pShared );
+BOOL           CreateHAL( PMESAD3DSHARED pShared );
+BOOL           SetViewportHAL( PMESAD3DSHARED pShared, RECT *pRect, float minZ, float maxZ  );
+
+void ClearHAL( PMESAD3DSHARED pShared, DWORD dwFlags, BOOL bAll, int x, int y, int cx, int cy, DWORD dwColor, float zv, DWORD dwStencil );
+void SetStateHAL( PMESAD3DSHARED pShared, DWORD dwType, DWORD dwState );
+void DrawPrimitiveHAL( PMESAD3DSHARED pShared, D3DPRIMITIVETYPE dptPrimitiveType, D3DTLVERTEX *pVertices, DWORD dwCount );
+
+void           SwapBuffersHAL( PMESAD3DSHARED pShared );
+DDSURFACEDESC2 *LockHAL( PMESAD3DSHARED pShared, BOOL bBack );
+void           UnlockHAL( PMESAD3DSHARED pShared, BOOL bBack );
+void           UpdateScreenPosHAL( PMESAD3DSHARED pShared );
+void                   GetPixelInfoHAL( PMESAD3DSHARED pShared, PPIXELINFO pPixel );
+BOOL CreateTMgrHAL( PMESAD3DSHARED pShared, DWORD dwName, int level, DWORD dwRequestFlags, RECT *rectDirty, DWORD dwWidth, DWORD dwHeight, DWORD dwAction, void *pPixels );
+void DisableTMgrHAL( PMESAD3DSHARED pShared );
+
+
+int  SaveDIBitmap( char *filename, BITMAPINFO *info, void *bits );
+int    ARGB_SaveBitmap( char *filename, int width, int height, unsigned char *pARGB );
+int  BGRA_SaveBitmap( char *filename, int width, int height, unsigned char *pBGRA );
+int  BGR_SaveBitmap( char *filename, int width, int height, unsigned char *pBGR );
+/*===========================================================================*/
+/* Global variables.                                                         */
+/*===========================================================================*/
+extern float   g_DepthScale,   /* Mesa needs to scale Z in SW.  The HAL */
+               g_MaxDepth;    /* doesn't but I wanted SW still to work.*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
diff --git a/src/mesa/drivers/d3d/D3DTEXT.CPP b/src/mesa/drivers/d3d/D3DTEXT.CPP
new file mode 100644 (file)
index 0000000..7321eeb
--- /dev/null
@@ -0,0 +1,577 @@
+/*===========================================================================*/\r
+/*                                                                           */\r
+/* Mesa-3.0 DirectX 6 Driver                                                 */\r
+/*                                                                           */\r
+/* By Leigh McRae                                                            */\r
+/*                                                                           */\r
+/* http://www.altsoftware.com/                                               */\r
+/*                                                                           */\r
+/* Copyright (c) 1999-1998  alt.software inc.  All Rights Reserved           */\r
+/*===========================================================================*/\r
+#include "d3dText.h"\r
+\r
+/*=============================================================================\r
+\r
+       1     \r
+     ------\r
+    |      | \r
+  6 |      | 2\r
+    |  7   |\r
+     ------  \r
+    |      |\r
+  5 |      | 3\r
+    |      |\r
+     ------ \r
+       4 \r
+\r
+           TL_0                TR_0\r
+TLL            TL_1            TR_1    TRR\r
+\r
+MLL_0   ML_0           MR_0    MRR_0\r
+MLL_1   ML_1           MR_1    MRR_1\r
+\r
+BLL            BL_0            BR_0    BRR\r
+        BL_1           BR_1\r
+\r
+=============================================================================*/\r
+\r
+#define TLL            0\r
+#define TRR            1\r
+#define TL_0   2\r
+#define TL_1   3\r
+#define TR_0   4\r
+#define TR_1   5\r
+\r
+#define        MLL_0   6\r
+#define        MLL_1   7\r
+#define        MRR_0   8\r
+#define        MRR_1   9\r
+\r
+#define        ML_0    10\r
+#define        ML_1    11\r
+#define        MR_0    12\r
+#define        MR_1    13\r
+\r
+#define        BL_0    14\r
+#define        BL_1    15\r
+#define        BR_0    16\r
+#define        BR_1    17\r
+#define        BLL             18\r
+#define        BRR             19\r
+\r
+#define        BIT1    0x00000001\r
+#define        BIT2    0x00000002\r
+#define        BIT3    0x00000004\r
+#define        BIT4    0x00000008\r
+#define        BIT5    0x00000010\r
+#define        BIT6    0x00000020\r
+#define        BIT7    0x00000040\r
+\r
+#define TOP            BIT4\r
+#define MIDDLE         BIT7\r
+#define BOTTOM         BIT1\r
+#define TLEFT          BIT5\r
+#define BLEFT          BIT6\r
+#define LEFT           (TLEFT|BLEFT)\r
+#define TRIGHT         BIT3\r
+#define BRIGHT         BIT2\r
+#define RIGHT          (TRIGHT|BRIGHT)\r
+#define ALL            0xFFFFFFFF\r
+\r
+/*===========================================================================*/\r
+/*  This is the static array that will map the ASCII value of the character  */\r
+/* being draw to the bit mask that will be scan converted to the LED display.*/\r
+/*===========================================================================*/\r
+DWORD  textBitMasks[] = \r
+{\r
+  0xFFFFFFFF, // 000\r
+  0xFFFFFFFF, // 001\r
+  0xFFFFFFFF, // 002\r
+  0xFFFFFFFF, // 003  \r
+  0xFFFFFFFF, // 004\r
+  0xFFFFFFFF, // 005\r
+  0xFFFFFFFF, // 006\r
+  0xFFFFFFFF, // 007  \r
+  0xFFFFFFFF, // 008\r
+  0xFFFFFFFF, // 009\r
+  0xFFFFFFFF, // 010\r
+  0xFFFFFFFF, // 011\r
+  0xFFFFFFFF, // 012\r
+  0xFFFFFFFF, // 013\r
+  0xFFFFFFFF, // 014\r
+  0xFFFFFFFF, // 015\r
+  0xFFFFFFFF, // 016\r
+  0xFFFFFFFF, // 017\r
+  0xFFFFFFFF, // 018\r
+  0xFFFFFFFF, // 019\r
+  0xFFFFFFFF, // 020\r
+  0xFFFFFFFF, // 021\r
+  0xFFFFFFFF, // 022\r
+  0xFFFFFFFF, // 023 \r
+  0xFFFFFFFF, // 024\r
+  0xFFFFFFFF, // 025\r
+  0xFFFFFFFF, // 026\r
+  0xFFFFFFFF, // 027\r
+  0xFFFFFFFF, // 028\r
+  0xFFFFFFFF, // 029\r
+  0xFFFFFFFF, // 030\r
+  0XFFFFFFFF, // 031 \r
+  0x00000000, // 032 'SPC'\r
+  0xFFFFFFFF, // 033\r
+  0xFFFFFFFF, // 034\r
+  0xFFFFFFFF, // 035\r
+  0xFFFFFFFF, // 036\r
+  0xFFFFFFFF, // 037\r
+  0xFFFFFFFF, // 038\r
+  0xFFFFFFFF, // 039\r
+  0xFFFFFFFF, // 040\r
+  0xFFFFFFFF, // 041\r
+  0xFFFFFFFF, // 042\r
+  0xFFFFFFFF, // 043\r
+  0xFFFFFFFF, // 044\r
+  0xFFFFFFFF, // 045\r
+  0xFFFFFFFF, // 046\r
+  0xFFFFFFFF, // 047 \r
+  (ALL &~ MIDDLE),                     // 048  '0'\r
+  (RIGHT),                                     // 049  '1'\r
+  (ALL &~ TLEFT &~ BRIGHT), // 050     '2'\r
+  (ALL &~ LEFT),                       // 051  '3'\r
+  (TLEFT | MIDDLE | RIGHT), // 052     '4'\r
+  (ALL &~ TRIGHT &~ BLEFT), // 053     '5'\r
+  (ALL &~ TRIGHT),                     // 054  '6'\r
+  (TOP | RIGHT),                       // 055  '7'\r
+  (ALL),                                       // 056  '8'\r
+  (ALL &~ BOTTOM &~ BLEFT), // 057     '9'\r
+  0xFFFFFFFF, // 058\r
+  0xFFFFFFFF, // 059\r
+  0xFFFFFFFF, // 060\r
+  0XFFFFFFFF, // 061\r
+  0xFFFFFFFF, // 062\r
+  0xFFFFFFFF, // 063\r
+  0xFFFFFFFF, // 064\r
+  (ALL &~ BOTTOM),                     // 065  'A'\r
+  (ALL),                                       // 066  'B'\r
+  (TOP | LEFT | BOTTOM),       // 067  'C'\r
+  (ALL &~ MIDDLE),                     // 068  'D'\r
+  (ALL &~ RIGHT),                      // 069  'E'\r
+  (LEFT | TOP | MIDDLE),       // 070  'F'\r
+  0x00000000,                                  // 071  'G'\r
+  (ALL &~ TOP &~ BOTTOM),      // 072  'H'\r
+  (RIGHT),                                     // 073  'I'\r
+  (RIGHT | BOTTOM),                    // 074  'J'\r
+  0x00000000,                                  // 075  'K'\r
+  (LEFT | BOTTOM),                     // 076  'L'\r
+  0x00000000,                          // 088  'M'\r
+  0x00000000,                          // 089  'N'\r
+  (ALL &~ MIDDLE),             // 090  'O'\r
+  (ALL &~ BRIGHT &~ BOTTOM),// 091     'P'\r
+  0x00000000,                          // 092  'Q'\r
+  0x00000000,                          // 093  'R'\r
+  (ALL &~ TRIGHT &~ BLEFT),    // 094  'S'\r
+  0X00000000,                          // 095  'T'\r
+  (LEFT | RIGHT | BOTTOM),  // 096     'U'\r
+  0x00000000,                          // 097  'V'\r
+  0x00000000,                          // 098  'W'\r
+  0x00000000,                          // 099  'X'\r
+  0x00000000,                                  // 1000 'Z'\r
+  0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,  // 100 \r
+  0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,  // 104 \r
+  0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,  // 108 \r
+  0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,  // 112 \r
+  0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,  // 116 \r
+  0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,  // 120 \r
+  0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF   // 124 \r
+};\r
+\r
+#define        CT      1.0f\r
+#define        CX      7.0f\r
+#define        CY      13.0f\r
+#define CM     ((CY-(CT*3.0f))/2.0f)\r
+\r
+float lCoords[][2] = \r
+{\r
+  /* Top outsides. */\r
+  { 0,                 (CY-CT) },              \r
+  { CX,                (CY-CT) },\r
+\r
+  /* Top Line. */\r
+  { CT,                CY },\r
+  { CT,                (CY-CT) },\r
+  { (CX-CT),   CY },\r
+  { (CX-CT),   (CY-CT) },\r
+\r
+  /* Middle outsides. */\r
+  { 0.0f,              (CT+CM+CT) },\r
+  { 0.0f,              (CT+CM) },\r
+  { CX,                        (CT+CM+CT) },\r
+  { CX,                        (CT+CM) },\r
+\r
+  /* Middle Line. */\r
+  { CT,                        (CT+CM+CT) },   \r
+  { CT,                        (CT+CM) },      \r
+  { (CX-CT),   (CT+CM+CT) },\r
+  { (CX-CT),   (CT+CM) },\r
+\r
+  /* Bottom line. */\r
+  { CT,                        CT },\r
+  { CT,                        0.0f },\r
+  { (CX-CT),   CT },\r
+  { (CX-CT),   0.0f },\r
+\r
+  /* Bottom outsides. */\r
+  { 0.0f,              CT},\r
+  { CX,                        CT }\r
+};\r
+\r
+static int     ConvertCharacter( char *c, int cIndex,  PD3DFONTMETRICS pfntMetrics );\r
+\r
+D3DTLVERTEX TextVertices[MAX_VERTICES];\r
+/*===========================================================================*/\r
+/*  When we attach I will zero out the whole D3D vertex buffer I'm using for */\r
+/* the text.  This way I don't need to set all the redundant values.  I also */\r
+/* set all the oow values to 1 as I will be doing direct rendering.          */\r
+/*===========================================================================*/\r
+/* RETURN: TRUE, FALSE.                                                      */\r
+/*===========================================================================*/\r
+extern "C" BOOL InitD3DText( void )\r
+{\r
+  int  index;\r
+\r
+  /* Set the D3D Vertex Buffer up once so we don't do redundant changes. */\r
+  memset( &TextVertices[0], 0, sizeof(TextVertices) );\r
+  for( index = 0; index < MAX_VERTICES; index++ )\r
+       TextVertices[index].rhw = D3DVAL( 1.0 );\r
+\r
+  return TRUE;\r
+}\r
+/*===========================================================================*/\r
+/*  This function takes a single character and draw it using the supplied    */\r
+/* fontmetrics structure.                                                    */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+extern "C" void d3dTextDrawString( char *pszString, int x, int y, PD3DFONTMETRICS pfntMetrics )\r
+{\r
+  int  cIndex,\r
+            nIndex,\r
+            index;\r
+  float        cWidth = CX,\r
+            cHeight = CY;\r
+\r
+  /*  Find the max width/height of a character and add the spacing so */\r
+  /* that we can use this value to calculate the x,y of the character.*/\r
+  cWidth  = (cWidth  * pfntMetrics->fntXScale)  + pfntMetrics->fntXSpacing;\r
+  cHeight = (cHeight * pfntMetrics->fntYScale) + pfntMetrics->fntYSpacing;\r
+\r
+  /* Walk the string.  This must be NULL terminated. */\r
+  for( cIndex = 0, nIndex = 0; *pszString; pszString++, cIndex = nIndex, x++ )\r
+  {\r
+       /* Convert the character and get the index into the text vertex buffer. */\r
+       nIndex = ConvertCharacter( &pszString[0], cIndex, pfntMetrics );\r
+       if ( (nIndex - cIndex) > 2 )\r
+    {\r
+         /* Modify the text vertex buffer based on the fntMetrics structure. */\r
+         for( index = cIndex; index < nIndex; index++ )\r
+         {\r
+               /* Scale the character. */\r
+               TextVertices[index].sx  *= pfntMetrics->fntXScale;\r
+               TextVertices[index].sy   *= pfntMetrics->fntYScale;\r
+               \r
+               /* Move the character. */\r
+               TextVertices[index].sx  += (cWidth*x);\r
+               TextVertices[index].sy   += (cHeight*y);\r
+\r
+               /* Set the color. */\r
+               TextVertices[index].color = pfntMetrics->dwColor;\r
+         }\r
+       }\r
+  }\r
+\r
+  if ( nIndex < 3 )\r
+       return;\r
+\r
+  /* Set the states that slim things down. */\r
+  pfntMetrics->lpD3DDevice->SetRenderState( D3DRENDERSTATE_CULLMODE,                   D3DCULL_NONE );\r
+  pfntMetrics->lpD3DDevice->SetRenderState( D3DRENDERSTATE_FILLMODE,                   D3DFILL_SOLID );\r
+  pfntMetrics->lpD3DDevice->SetRenderState( D3DRENDERSTATE_ZENABLE,                    FALSE );\r
+  pfntMetrics->lpD3DDevice->SetRenderState( D3DRENDERSTATE_ZWRITEENABLE ,              FALSE );\r
+  pfntMetrics->lpD3DDevice->SetRenderState( D3DRENDERSTATE_ALPHATESTENABLE,    FALSE );\r
+  pfntMetrics->lpD3DDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE,   FALSE );\r
+\r
+  /* Blast them baby... */\r
+  pfntMetrics->lpD3DDevice->DrawPrimitive( D3DPT_TRIANGLELIST,\r
+                                                                                  D3DFVF_TLVERTEX,\r
+                                                                                  (LPVOID)&TextVertices[0],\r
+                                                                                  nIndex, \r
+                                                                                  (D3DDP_DONOTCLIP | D3DDP_DONOTLIGHT) );\r
+}\r
+/*===========================================================================*/\r
+/*  This function takes a single character and draw it directly to the screen*/\r
+/* unsing the supplied fntMetrics structure.  The character will be drawn at */\r
+/* the supplied x,y.  The x,y position is relative to the top left and uses  */\r
+/* the spacing in the fntMetrics structure.                                  */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+extern "C" void d3dTextDrawCharacter( char *c, int x, int y, PD3DFONTMETRICS pfntMetrics )\r
+{\r
+  int  cIndex = 0,\r
+           index;\r
+  float        cWidth = CX,\r
+           cHeight = CY;\r
+\r
+  /* Convert the character and get the index into the text vertex buffer. */\r
+  cIndex = ConvertCharacter( c, 0, pfntMetrics );\r
+  if ( cIndex < 3 )\r
+       return;\r
+\r
+  /*  Find the max width/height of a character and add the spacing so */\r
+  /* that we can use this value to calculate the x,y of the character.*/\r
+  cWidth  = (cWidth  * pfntMetrics->fntXScale)  + pfntMetrics->fntXSpacing;\r
+  cHeight = (cHeight * pfntMetrics->fntYScale) + pfntMetrics->fntYSpacing;\r
+\r
+  /* Modify the text vertex buffer based on the fntMetrics structure. */\r
+  for( index = 0; index < cIndex; index++ )\r
+  {\r
+       /* Scale the character. */\r
+       TextVertices[index].sx  *= pfntMetrics->fntXScale;\r
+       TextVertices[index].sy   *= pfntMetrics->fntYScale;\r
+\r
+       /* Move the character. */\r
+       TextVertices[index].sx  += (cWidth*x);\r
+       TextVertices[index].sy   += (cHeight*y);\r
+\r
+       /* Set the color. */\r
+       TextVertices[index].color = pfntMetrics->dwColor;\r
+  }\r
\r
+\r
+  /* Set the states that slim things down. */\r
+  pfntMetrics->lpD3DDevice->SetRenderState( D3DRENDERSTATE_CULLMODE,                   D3DCULL_NONE );\r
+  pfntMetrics->lpD3DDevice->SetRenderState( D3DRENDERSTATE_FILLMODE,                   D3DFILL_SOLID );\r
+  pfntMetrics->lpD3DDevice->SetRenderState( D3DRENDERSTATE_ZENABLE,                    FALSE );\r
+  pfntMetrics->lpD3DDevice->SetRenderState( D3DRENDERSTATE_ZWRITEENABLE ,              FALSE );\r
+  pfntMetrics->lpD3DDevice->SetRenderState( D3DRENDERSTATE_ALPHATESTENABLE,    FALSE );\r
+  pfntMetrics->lpD3DDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE,   FALSE );\r
+\r
+  /* Blast them baby... */\r
+  pfntMetrics->lpD3DDevice->DrawPrimitive( D3DPT_TRIANGLELIST,\r
+                                                                                  D3DFVF_TLVERTEX,\r
+                                                                                  (LPVOID)&TextVertices[0],\r
+                                                                                  cIndex, \r
+                                                                                  (D3DDP_DONOTCLIP | D3DDP_DONOTLIGHT) );\r
+}\r
+/*===========================================================================*/\r
+/*  This function takes a single character and draw it using the supplied    */\r
+/* fontmetrics structure.                                                    */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+static int     ConvertCharacter( char *c, int cIndex,  PD3DFONTMETRICS pfntMetrics )\r
+{\r
+  DWORD        asciiChar = (int)(*c);\r
+\r
+  /* Handle the TOP line. */\r
+  if ( textBitMasks[asciiChar] & BIT1 )\r
+  { \r
+    TextVertices[cIndex].sx    = D3DVAL( lCoords[TL_0][0] );\r
+    TextVertices[cIndex++].sy= D3DVAL( lCoords[TL_0][1] );\r
+    TextVertices[cIndex].sx    = D3DVAL( lCoords[TR_0][0] );\r
+    TextVertices[cIndex++].sy= D3DVAL( lCoords[TR_0][1] );\r
+    TextVertices[cIndex].sx    = D3DVAL( lCoords[TR_1][0] );\r
+    TextVertices[cIndex++].sy= D3DVAL( lCoords[TR_1][1] );\r
+    TextVertices[cIndex].sx    = D3DVAL( lCoords[TR_1][0] );\r
+    TextVertices[cIndex++].sy= D3DVAL( lCoords[TR_1][1] );\r
+    TextVertices[cIndex].sx    = D3DVAL( lCoords[TL_1][0] );\r
+    TextVertices[cIndex++].sy= D3DVAL( lCoords[TL_1][1] );\r
+    TextVertices[cIndex].sx    = D3DVAL( lCoords[TL_0][0] );\r
+    TextVertices[cIndex++].sy= D3DVAL( lCoords[TL_0][1] );\r
+  }\r
+\r
+  /* Handle the TOP/BOTTOM RIGHT lines. */\r
+  //  if ( textBitMasks[index] & (BIT2|BIT3) )\r
+  if ( 1 == 0 )\r
+  {\r
+    TextVertices[cIndex].sx    = D3DVAL( lCoords[TR_1][0] );\r
+    TextVertices[cIndex++].sy= D3DVAL( lCoords[TR_1][1] );\r
+    TextVertices[cIndex].sx    = D3DVAL( lCoords[TRR][0] );\r
+    TextVertices[cIndex++].sy= D3DVAL( lCoords[TRR][1] );\r
+    TextVertices[cIndex].sx    = D3DVAL( lCoords[BRR][0] );\r
+    TextVertices[cIndex++].sy= D3DVAL( lCoords[BRR][1] );\r
+    TextVertices[cIndex].sx    = D3DVAL( lCoords[BRR][0] );\r
+    TextVertices[cIndex++].sy= D3DVAL( lCoords[BRR][1] );\r
+    TextVertices[cIndex].sx    = D3DVAL( lCoords[BR_0][0] );\r
+    TextVertices[cIndex++].sy= D3DVAL( lCoords[BR_0][1] );\r
+    TextVertices[cIndex].sx    = D3DVAL( lCoords[TR_1][0] );\r
+    TextVertices[cIndex++].sy= D3DVAL( lCoords[TR_1][1] );\r
+  }\r
+  else \r
+  {\r
+       if ( textBitMasks[asciiChar] & BIT2 )\r
+       {\r
+         TextVertices[cIndex].sx       = D3DVAL( lCoords[TR_1][0] );\r
+         TextVertices[cIndex++].sy     = D3DVAL( lCoords[TR_1][1] );\r
+         TextVertices[cIndex].sx       = D3DVAL( lCoords[TRR][0] );\r
+         TextVertices[cIndex++].sy     = D3DVAL( lCoords[TRR][1] );\r
+         TextVertices[cIndex].sx       = D3DVAL( lCoords[MRR_0][0] );\r
+         TextVertices[cIndex++].sy     = D3DVAL( lCoords[MRR_0][1] );\r
+         TextVertices[cIndex].sx       = D3DVAL( lCoords[MRR_0][0] );\r
+         TextVertices[cIndex++].sy     = D3DVAL( lCoords[MRR_0][1] );\r
+         TextVertices[cIndex].sx       = D3DVAL( lCoords[MR_0][0] );\r
+         TextVertices[cIndex++].sy     = D3DVAL( lCoords[MR_0][1] );\r
+         TextVertices[cIndex].sx       = D3DVAL( lCoords[TR_1][0] );\r
+         TextVertices[cIndex++].sy     = D3DVAL( lCoords[TR_1][1] );\r
+       }\r
+       if ( textBitMasks[asciiChar] & BIT3 )\r
+       {\r
+         TextVertices[cIndex].sx       = D3DVAL( lCoords[MR_1][0] );\r
+         TextVertices[cIndex++].sy     = D3DVAL( lCoords[MR_1][1] );\r
+         TextVertices[cIndex].sx       = D3DVAL( lCoords[MRR_1][0] );\r
+         TextVertices[cIndex++].sy     = D3DVAL( lCoords[MRR_1][1] );\r
+         TextVertices[cIndex].sx       = D3DVAL( lCoords[BRR][0] );\r
+         TextVertices[cIndex++].sy     = D3DVAL( lCoords[BRR][1] );\r
+         TextVertices[cIndex].sx       = D3DVAL( lCoords[BRR][0] );\r
+         TextVertices[cIndex++].sy     = D3DVAL( lCoords[BRR][1] );\r
+         TextVertices[cIndex].sx       = D3DVAL( lCoords[BR_0][0] );\r
+         TextVertices[cIndex++].sy     = D3DVAL( lCoords[BR_0][1] );\r
+         TextVertices[cIndex].sx       = D3DVAL( lCoords[MR_1][0] );\r
+         TextVertices[cIndex++].sy     = D3DVAL( lCoords[MR_1][1] );\r
+       }\r
+  }\r
+\r
+  /* Handle the TOP/BOTTOM LEFT lines. */\r
+  //  if ( textBitMasks[asciiChar] & (BIT5|BIT6) )\r
+  if ( 1 == 0 )\r
+  {\r
+       TextVertices[cIndex].sx = D3DVAL( lCoords[TLL][0] );\r
+       TextVertices[cIndex++].sy= D3DVAL( lCoords[TLL][1] );\r
+       TextVertices[cIndex].sx = D3DVAL( lCoords[TL_1][0] );\r
+       TextVertices[cIndex++].sy= D3DVAL( lCoords[TL_1][1] );\r
+       TextVertices[cIndex].sx = D3DVAL( lCoords[BL_0][0] );\r
+       TextVertices[cIndex++].sy= D3DVAL( lCoords[BL_0][1] );\r
+       TextVertices[cIndex].sx = D3DVAL( lCoords[BL_0][0] );\r
+       TextVertices[cIndex++].sy= D3DVAL( lCoords[BL_0][1] );\r
+       TextVertices[cIndex].sx = D3DVAL( lCoords[BLL][0] );\r
+       TextVertices[cIndex++].sy= D3DVAL( lCoords[BLL][1] );\r
+       TextVertices[cIndex].sx = D3DVAL( lCoords[TLL][0] );\r
+       TextVertices[cIndex++].sy= D3DVAL( lCoords[TLL][1] );\r
+  }\r
+  else \r
+  {\r
+       if ( textBitMasks[asciiChar] & BIT5 )\r
+       {\r
+         TextVertices[cIndex].sx       = D3DVAL( lCoords[MLL_1][0] );\r
+         TextVertices[cIndex++].sy     = D3DVAL( lCoords[MLL_1][1] );\r
+         TextVertices[cIndex].sx       = D3DVAL( lCoords[ML_1][0] );\r
+         TextVertices[cIndex++].sy     = D3DVAL( lCoords[ML_1][1] );\r
+         TextVertices[cIndex].sx       = D3DVAL( lCoords[BL_0][0] );\r
+         TextVertices[cIndex++].sy     = D3DVAL( lCoords[BL_0][1] );\r
+         TextVertices[cIndex].sx       = D3DVAL( lCoords[BL_0][0] );\r
+         TextVertices[cIndex++].sy     = D3DVAL( lCoords[BL_0][1] );\r
+         TextVertices[cIndex].sx       = D3DVAL( lCoords[BLL][0] );\r
+         TextVertices[cIndex++].sy     = D3DVAL( lCoords[BLL][1] );\r
+         TextVertices[cIndex].sx       = D3DVAL( lCoords[MLL_1][0] );\r
+         TextVertices[cIndex++].sy     = D3DVAL( lCoords[MLL_1][1] );\r
+       }\r
+       if ( textBitMasks[asciiChar] & BIT6 )\r
+       {\r
+         TextVertices[cIndex].sx       = D3DVAL( lCoords[TLL][0] );\r
+         TextVertices[cIndex++].sy     = D3DVAL( lCoords[TLL][1] );\r
+         TextVertices[cIndex].sx       = D3DVAL( lCoords[TL_1][0] );\r
+         TextVertices[cIndex++].sy     = D3DVAL( lCoords[TL_1][1] );\r
+         TextVertices[cIndex].sx       = D3DVAL( lCoords[ML_0][0] );\r
+         TextVertices[cIndex++].sy     = D3DVAL( lCoords[ML_0][1] );\r
+         TextVertices[cIndex].sx       = D3DVAL( lCoords[ML_0][0] );\r
+         TextVertices[cIndex++].sy     = D3DVAL( lCoords[ML_0][1] );\r
+         TextVertices[cIndex].sx       = D3DVAL( lCoords[MLL_0][0] );\r
+         TextVertices[cIndex++].sy     = D3DVAL( lCoords[MLL_0][1] );\r
+         TextVertices[cIndex].sx       = D3DVAL( lCoords[TLL][0] );\r
+         TextVertices[cIndex++].sy     = D3DVAL( lCoords[TLL][1] );\r
+       }\r
+  }\r
+\r
+  /* Handle the MIDDLE line. */\r
+  if ( textBitMasks[asciiChar] & BIT7 )\r
+  {\r
+       TextVertices[cIndex].sx = D3DVAL( lCoords[ML_0][0] );\r
+       TextVertices[cIndex++].sy= D3DVAL( lCoords[ML_0][1] );\r
+       TextVertices[cIndex].sx = D3DVAL( lCoords[MR_0][0] );\r
+       TextVertices[cIndex++].sy= D3DVAL( lCoords[MR_0][1] );\r
+       TextVertices[cIndex].sx = D3DVAL( lCoords[MR_1][0] );\r
+       TextVertices[cIndex++].sy= D3DVAL( lCoords[MR_1][1] );\r
+       TextVertices[cIndex].sx = D3DVAL( lCoords[MR_1][0] );\r
+       TextVertices[cIndex++].sy= D3DVAL( lCoords[MR_1][1] );\r
+       TextVertices[cIndex].sx = D3DVAL( lCoords[ML_1][0] );\r
+       TextVertices[cIndex++].sy= D3DVAL( lCoords[ML_1][1] );\r
+       TextVertices[cIndex].sx = D3DVAL( lCoords[ML_0][0] );\r
+       TextVertices[cIndex++].sy= D3DVAL( lCoords[ML_0][1] );\r
+  }\r
+\r
+  /* Handle the BOTTOM line. */\r
+  if ( textBitMasks[asciiChar] & BIT4 )\r
+  {\r
+       TextVertices[cIndex].sx = D3DVAL( lCoords[BL_0][0] );\r
+       TextVertices[cIndex++].sy= D3DVAL( lCoords[BL_0][1] );\r
+       TextVertices[cIndex].sx = D3DVAL( lCoords[BR_0][0] );\r
+       TextVertices[cIndex++].sy= D3DVAL( lCoords[BR_0][1] );\r
+       TextVertices[cIndex].sx = D3DVAL( lCoords[BR_1][0] );\r
+       TextVertices[cIndex++].sy= D3DVAL( lCoords[BR_1][1] );\r
+       TextVertices[cIndex].sx = D3DVAL( lCoords[BR_1][0] );\r
+       TextVertices[cIndex++].sy= D3DVAL( lCoords[BR_1][1] );\r
+       TextVertices[cIndex].sx = D3DVAL( lCoords[BL_1][0] );\r
+       TextVertices[cIndex++].sy= D3DVAL( lCoords[BL_1][1] );\r
+       TextVertices[cIndex].sx = D3DVAL( lCoords[BL_0][0] );\r
+       TextVertices[cIndex++].sy= D3DVAL( lCoords[BL_0][1] );\r
+  }\r
+  \r
+  return cIndex;\r
+}\r
+\r
+#undef CM\r
+#undef CY\r
+#undef CX\r
+#undef CT\r
+\r
+#undef TLL\r
+#undef TRR\r
+#undef TL_0\r
+#undef TL_1\r
+#undef TR_0\r
+#undef TR_1\r
+\r
+#undef MLL_0\r
+#undef MLL_1\r
+#undef MRR_0\r
+#undef MRR_1\r
+\r
+#undef ML_0\r
+#undef ML_1\r
+#undef MR_0\r
+#undef MR_1\r
+\r
+#undef BL_0\r
+#undef BL_1\r
+#undef BR_0\r
+#undef BR_1\r
+#undef BLL\r
+#undef BRR\r
+\r
+#undef BIT1\r
+#undef BIT2\r
+#undef BIT3\r
+#undef BIT4\r
+#undef BIT5\r
+#undef BIT6\r
+#undef BIT7\r
+\r
+#undef TOP\r
+#undef MIDDLE\r
+#undef BOTTOM\r
+#undef TLEFT\r
+#undef BLEFT\r
+#undef LEFT\r
+#undef TRIGHT\r
+#undef BRIGHT\r
+#undef RIGHT\r
+#undef ALL\r
+\1a
\ No newline at end of file
diff --git a/src/mesa/drivers/d3d/D3DTextureMgr.cpp b/src/mesa/drivers/d3d/D3DTextureMgr.cpp
new file mode 100644 (file)
index 0000000..9375e51
--- /dev/null
@@ -0,0 +1,948 @@
+/*===========================================================================*/\r
+/*                                                                           */\r
+/* Mesa-3.0 DirectX 6 Driver                                                 */\r
+/*                                                                           */\r
+/* By Leigh McRae                                                            */\r
+/*                                                                           */\r
+/* http://www.altsoftware.com/                                               */\r
+/*                                                                           */\r
+/* Copyright (c) 1999-1998  alt.software inc.  All Rights Reserved           */\r
+/*===========================================================================*/\r
+#include "D3DHAL.h"\r
+/*===========================================================================*/\r
+/* Local function prototypes.                                                */\r
+/*===========================================================================*/\r
+static void UpdateTexture( PTM_OBJECT pTMObj, BOOL bVideo, RECT *pRect, UCHAR *pixels );\r
+static BOOL LoadTextureInVideo( PMESAD3DHAL pHAL, PTM_OBJECT pTMObj );\r
+static BOOL FreeTextureMemory( PMESAD3DHAL pHAL, PTM_OBJECT pTMObject );\r
+static BOOL DestroyTextureObject( PMESAD3DHAL pHAL, PTM_OBJECT pTMObject );\r
+HRESULT CALLBACK EnumPFHook( LPDDPIXELFORMAT lpDDPixFmt, LPVOID lpContext );\r
+/*===========================================================================*/\r
+/*  This function will simply set the top of stack to NULL.  I only used it  */\r
+/* just incase I want to add something later.                                */\r
+/*===========================================================================*/\r
+/* RETURN: TRUE.                                                             */\r
+/*===========================================================================*/\r
+BOOL InitTMgrHAL( PMESAD3DHAL pHAL )\r
+{\r
+  DPF(( DBG_FUNC, "InitTMgrHAL();" ));\r
+\r
+  /* Be clean my friend. */\r
+  pHAL->pTMList = NULL;\r
+\r
+  return TRUE;\r
+}\r
+/*===========================================================================*/\r
+/*  This function will walk the Texture Managers linked list and destroy all */\r
+/* surfaces (SYSTEM/VIDEO).  The texture objects themselves also will be     */\r
+/* freed.                                                                    */\r
+/*  NOTE: this is per/context.                                               */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+void TermTMgrHAL( PMESAD3DHAL pHAL )\r
+{\r
+  DPF(( DBG_FUNC, "TermTMgrHAL();" ));\r
+\r
+  if ( pHAL && pHAL->pTMList )\r
+  {\r
+    /* Destroy the surface and remove the TMO from the stack. */\r
+    while( DestroyTextureObject(pHAL,NULL) );\r
+\r
+    /* Be clean my friend. */\r
+    pHAL->pTMList = NULL;\r
+  }\r
+}\r
+/*===========================================================================*/\r
+/*  This function is a HACK as I don't know how I can disable a texture with-*/\r
+/* out booting it out.  Is there know state change?                          */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+extern "C" void DisableTMgrHAL( PMESAD3DSHARED pShared )\r
+{\r
+  PMESAD3DHAL  pHAL = (PMESAD3DHAL)pShared;\r
+\r
+  DPF(( DBG_FUNC, "DisableTMgrHAL();" ));\r
+\r
+  /* Check too see that we have a valid context. */\r
+  if ( (pHAL == NULL) && (pHAL->lpD3DDevice != NULL)  ) \r
+  {\r
+    DPF(( DBG_TXT_WARN, "Null HAL/Direct3D Device!" ));\r
+    return;\r
+  }\r
+\r
+  // TODO: This is a hack to shut off textures.\r
+  pHAL->lpD3DDevice->SetTexture( 0, NULL );\r
+}\r
+/*===========================================================================*/\r
+/*  This function is the only entry into the TextureManager that Mesa/wgl    */\r
+/* will see.  It uses a dwAction to specify what we are doing.  I did this as*/\r
+/* depending on the cards resources the action taken can change.             */\r
+/*  When this function is called we will always search the Texture Managers  */\r
+/* linked list (per context remember) and try and find a structure that has  */\r
+/* the same dwName.  If we have a match we pull it out of the list and put it*/\r
+/* at the top of the list (TOL).  If we don't find one then we create a struc*/\r
+/* and put it a TOL.  This TOL idea makes for some caching as we will always */\r
+/* destroy Texture Surfaces from the bottom up...                            */\r
+/*  All texture objects at this point will create a texture surface in System*/\r
+/* memory (SMEM).  Then we will copy the Mesa texture into the surface using */\r
+/* the 'pixel' struc to get the translation info.  So now this means that all*/\r
+/* textures that Mesa gives me I will have a Surface with a copy.  If Mesa   */\r
+/* changes the texture the I update the surface in (SMEM).                   */\r
+/*  Now we have a texture struc and a Texture Surface in SMEM.  At this point*/\r
+/* we create another surface on the card (VMEM).  Finally we blt from the    */\r
+/* SMEM to the VMEM and set the texture as current.  Why do I need two? First*/\r
+/* this solves square textures.  If the cards CAPS is square textures only   */\r
+/* then I change the dimensions of the VMEM surface and the blt solves it for*/\r
+/* me.  Second it saves me from filling D3D textures over and over if the    */\r
+/* card needs to be creating and destroying surfaces because of low memory.  */\r
+/*  The surface in SMEM is expected to work always.  When a surface has to be*/\r
+/* created in VMEM then we put it in a loop that tries to create the surface.*/\r
+/* If we create the surface ok then we brake from the loop.  If we fail then */\r
+/* we will call 'FreeTextureMemory' that will return TRUE/FALSE as to whether*/\r
+/* memory was freed.  If memory was freed then we can try again. If no memory*/\r
+/* was freed then it just can't fit.                                         */\r
+/*  'FreeTextureMemory' will find the end of the list and start freeing VMEM */\r
+/* (never SMEM) surfaces that are not locked.                                */\r
+/*  BIND - when we bind and there is a texture struct with a texture surface */\r
+/* in VMEM then we just make it current.  If we have a struct and a surface  */\r
+/* in SMEM but no VMEM surface then we create the surface in VMEM and blt    */\r
+/* from the SMEM surface.  If we have nothing its just like a creation...    */\r
+/*===========================================================================*/\r
+/* RETURN: TRUE, FALSE.                                                      */\r
+/*===========================================================================*/\r
+extern "C" BOOL CreateTMgrHAL( PMESAD3DSHARED pShared, DWORD dwName, int level, DWORD dwRequestFlags, \r
+                                                RECT *rectDirty, DWORD dwWidth, DWORD dwHeight, DWORD dwAction, void *pPixels )\r
+{\r
+  PMESAD3DHAL          pHAL = (PMESAD3DHAL)pShared;\r
+  PTM_OBJECT           pTMObj,\r
+                    pTemp;\r
+  DDSURFACEDESC2       ddsd2;\r
+  HRESULT              rc;\r
+\r
+\r
+  DPF(( DBG_FUNC, "CreateTMgrHAL();" ));\r
+\r
+  DPF(( DBG_TXT_INFO, "Texture:" ));\r
+  DPF(( DBG_TXT_INFO, "cx: %d cy: %d", dwWidth, dwHeight ));\r
+  DPF(( DBG_TXT_INFO, "Rect:" ));\r
+  if ( rectDirty )\r
+  {\r
+    DPF(( DBG_TXT_INFO, "x0: %d y0: %d", rectDirty->left, rectDirty->top ));\r
+    DPF(( DBG_TXT_INFO, "x1: %d y1: %d", rectDirty->right, rectDirty->bottom ));\r
+  }\r
+\r
+  /* Check too see that we have a valid context. */\r
+  if ( (pHAL == NULL) && (pHAL->lpD3DDevice != NULL)  ) \r
+  {\r
+    DPF(( DBG_TXT_WARN, "Null HAL/Direct3D Device!" ));\r
+    return FALSE;\r
+  }\r
+\r
+  /*=================================================*/\r
+  /* See if we can find this texture object by name. */\r
+  /*=================================================*/\r
+  for( pTMObj = pHAL->pTMList; pTMObj && (pTMObj->dwName != dwName); pTMObj = pTMObj->next );\r
+\r
+  /*=========================================================*/\r
+  /* Allocate a new object if we didn't get a matching name. */\r
+  /*=========================================================*/\r
+  if ( pTMObj == NULL )\r
+  {\r
+    pTMObj = (PTM_OBJECT)ALLOC( sizeof(TM_OBJECT) );\r
+    if ( pTMObj == NULL )\r
+        return FALSE;\r
+    memset( pTMObj, 0, sizeof(TM_OBJECT) );\r
+\r
+    /* Put the object at the beginning of the list. */\r
+    pTMObj->next = pHAL->pTMList;\r
+    if ( pTMObj->next )\r
+    {\r
+        pTemp = pTMObj->next;\r
+        pTemp->prev = pTMObj;\r
+    }\r
+    pHAL->pTMList = pTMObj;\r
+  }\r
+  else\r
+  {\r
+    /*===============================================================*/\r
+    /* Make some caching happen by pulling this object to the front. */ \r
+    /*===============================================================*/\r
+    if ( pHAL->pTMList != pTMObj )\r
+    {\r
+        /* Pull the object out of the list. */\r
+        if ( pTMObj->prev )\r
+        {\r
+          pTemp = pTMObj->prev;\r
+          pTemp->next = pTMObj->next;\r
+        }\r
+        if ( pTMObj->next )\r
+      {\r
+          pTemp = pTMObj->next;\r
+          pTemp->prev = pTMObj->prev;\r
+        }\r
+\r
+        pTMObj->prev = NULL;\r
+        pTMObj->next = NULL;\r
+\r
+        /* Put the object at the front of the list. */\r
+        pTMObj->next = pHAL->pTMList;\r
+        if ( pTMObj->next )\r
+      {\r
+          pTemp = pTMObj->next;\r
+          pTemp->prev = pTMObj;\r
+        }\r
+        pHAL->pTMList = pTMObj;\r
+    }\r
+  }\r
+\r
+  /*========================================================*/\r
+  /* If we are doing BIND and the texture is in VID memory. */\r
+  /*========================================================*/\r
+  if ( (dwAction == TM_ACTION_BIND) && pTMObj->lpDDS_Video  )\r
+  {\r
+    DPF(( DBG_TXT_PROFILE, "Cache HIT (%d)", dwName ));\r
+          \r
+    /* Make this the current texture. */\r
+    rc = pHAL->lpD3DDevice->SetTexture( 0, pTMObj->lpD3DTexture2 );\r
+    if ( FAILED(rc) )\r
+    {\r
+        DPF(( DBG_TXT_WARN, "Failed SetTexture() (%s)", ErrorStringD3D(rc) ));\r
+        pHAL->lpD3DDevice->SetTexture( 0, NULL );\r
+        return FALSE;\r
+    }  \r
+\r
+    return TRUE;\r
+  }    \r
+\r
+  /*=================================================================*/\r
+  /* If we are doing BIND and the texture is at least in SYS memory. */\r
+  /*=================================================================*/\r
+  if ( (dwAction == TM_ACTION_BIND) && pTMObj->lpDDS_System  )\r
+  {\r
+    DPF(( DBG_TXT_PROFILE, "Cache MISS (%d)", dwName ));\r
+\r
+    /* Create the texture on the card. */\r
+    rc = LoadTextureInVideo( pHAL, pTMObj );\r
+    if ( rc == FALSE )\r
+        return FALSE;\r
+          \r
+    /* Make this the current texture. */\r
+    rc = pHAL->lpD3DDevice->SetTexture( 0, pTMObj->lpD3DTexture2 );\r
+    if ( FAILED(rc) )\r
+    {\r
+        DPF(( DBG_TXT_WARN, "Failed SetTexture() (%s)", ErrorStringD3D(rc) ));\r
+        pHAL->lpD3DDevice->SetTexture( 0, NULL );\r
+        return FALSE;\r
+    }  \r
+\r
+    return TRUE;\r
+  }    \r
+\r
+  /*=========================================================*/\r
+  /* If we are doing UPDATE then try in VID first for speed. */\r
+  /*=========================================================*/\r
+  if ( (dwAction == TM_ACTION_UPDATE) && pTMObj->lpDDS_Video &&\r
+         !(pHAL->D3DHWDevDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_SQUAREONLY) )\r
+  {\r
+    DPF(( DBG_TXT_INFO, "Fix the SubTexture update Leigh!" ));\r
+\r
+    /* Update the texture on the card. */\r
+    UpdateTexture( pTMObj, TRUE, rectDirty, (UCHAR *)pPixels );\r
+\r
+    /* We updated the texture in VID so kill the SYS so we know its dirty. */\r
+    if ( pTMObj->lpDDS_System )\r
+    {\r
+        DPF(( DBG_TXT_INFO, "Release texture (SYS)" ));\r
+        DX_RESTORE( pTMObj->lpDDS_System );\r
+        pTMObj->lpDDS_System->Release();\r
+        pTMObj->lpDDS_System = NULL;\r
+    }\r
+\r
+    /* Make this the current texture. */\r
+    rc = pHAL->lpD3DDevice->SetTexture( 0, pTMObj->lpD3DTexture2 );\r
+    if ( FAILED(rc) )\r
+    {\r
+        DPF(( DBG_TXT_WARN, "Failed SetTexture() (%s)", ErrorStringD3D(rc) ));\r
+        pHAL->lpD3DDevice->SetTexture( 0, NULL );\r
+        return FALSE;\r
+    }  \r
+\r
+    return TRUE;\r
+  }\r
+\r
+  /*===========================================================*/\r
+  /* If we are doing UPDATE then try in SYS still gives speed. */\r
+  /*===========================================================*/\r
+  if ( (dwAction == TM_ACTION_UPDATE) && pTMObj->lpDDS_System )\r
+  {\r
+    DPF(( DBG_TXT_INFO, "Fix the SubTexture update Leigh!" ));\r
+\r
+    /* Update the texture in SYS. */\r
+    UpdateTexture( pTMObj, FALSE, NULL, (UCHAR *)pPixels );\r
+\r
+    /* We updated the SYS texture only so now blt to the VID. */\r
+    rc = LoadTextureInVideo( pHAL, pTMObj );\r
+    if ( rc == FALSE )\r
+        return FALSE;\r
+\r
+    /* Make this the current texture. */\r
+    rc = pHAL->lpD3DDevice->SetTexture( 0, pTMObj->lpD3DTexture2 );\r
+    if ( FAILED(rc) )\r
+    {\r
+        DPF(( DBG_TXT_WARN, "Failed SetTexture() (%s)", ErrorStringD3D(rc) ));\r
+        pHAL->lpD3DDevice->SetTexture( 0, NULL );\r
+        return FALSE;\r
+    }  \r
+\r
+    return TRUE;\r
+  }\r
+\r
+  /*  At this point we have a valid Texture Manager Object with updated */\r
+  /* links.  We now need to create or update a texture surface that is  */\r
+  /* in system memory.  Every texture has a copy in system so we can use*/\r
+  /* blt to solve problems with textures allocated on the card (square  */\r
+  /* only textures, pixelformats...).                                   */\r
+  \r
+  // TODO: make support for update also.  Dirty rectangle basicly...\r
+\r
+  /* Kill the interface if we have one no matter what. */\r
+  if ( pTMObj->lpD3DTexture2 )\r
+  {\r
+    DPF(( DBG_TXT_INFO, "Release Texture2" ));\r
+    pTMObj->lpD3DTexture2->Release();\r
+    pTMObj->lpD3DTexture2 = NULL;\r
+  }    \r
+\r
+  /* Kill the system surface. TODO: should try to get the SubIMage going again */\r
+  if ( pTMObj->lpDDS_System )\r
+  {\r
+    DPF(( DBG_TXT_INFO, "Release texture (SYS)" ));\r
+    DX_RESTORE( pTMObj->lpDDS_System );\r
+    pTMObj->lpDDS_System->Release();\r
+    pTMObj->lpDDS_System = NULL;\r
+  }\r
+\r
+  /* Kill the Video surface. TODO: need some reuse system... */\r
+  if ( pTMObj->lpDDS_Video )\r
+  {\r
+    DPF(( DBG_TXT_INFO, "Release texture (VID)" ));\r
+    DX_RESTORE( pTMObj->lpDDS_Video );\r
+    pTMObj->lpDDS_Video->Release();\r
+    pTMObj->lpDDS_Video = NULL;\r
+  }\r
+\r
+  /*================================================================*/\r
+  /* Translate the the Mesa/OpenGL pixel channels to the D3D flags. */\r
+  /*================================================================*/\r
+  switch( dwRequestFlags )\r
+  {\r
+    case GL_ALPHA:\r
+        dwRequestFlags = DDPF_ALPHA; \r
+        DPF(( DBG_TXT_WARN, "GL_ALPHA not supported!)" ));\r
+        return FALSE;\r
+        \r
+    case GL_INTENSITY:\r
+    case GL_LUMINANCE:\r
+        DPF(( DBG_TXT_WARN, "GL_INTENSITY/GL_LUMINANCE not supported!)" ));\r
+        dwRequestFlags = DDPF_LUMINANCE; \r
+        return FALSE;\r
+        \r
+    case GL_LUMINANCE_ALPHA:\r
+        DPF(( DBG_TXT_WARN, "GL_LUMINANCE_ALPHA not supported!)" ));\r
+        dwRequestFlags = DDPF_LUMINANCE | DDPF_ALPHAPIXELS; \r
+        return FALSE;\r
+        \r
+    case GL_RGB:\r
+        DPF(( DBG_TXT_INFO, "Texture -> GL_RGB" ));\r
+        dwRequestFlags = DDPF_RGB; \r
+        break;\r
+\r
+    case GL_RGBA:\r
+        DPF(( DBG_TXT_INFO, "Texture -> GL_RGBA" ));\r
+        dwRequestFlags = DDPF_RGB | DDPF_ALPHAPIXELS; \r
+        break;\r
+  }\r
+\r
+  /*==============================*/\r
+  /* Populate the texture object. */\r
+  /*==============================*/\r
+  pTMObj->dwName      = dwName;\r
+  pTMObj->lpD3DDevice = pHAL->lpD3DDevice;\r
+  pTMObj->dwFlags     = dwRequestFlags;\r
+  if ( pHAL->D3DHWDevDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_SQUAREONLY )\r
+  {\r
+    DPF(( DBG_TXT_INFO, "Convert to Square..." ));\r
+    pTMObj->dwSHeight  = dwHeight;\r
+    pTMObj->dwSWidth   = dwWidth;\r
+\r
+    /* Shrink non-square textures. */\r
+    pTMObj->dwVHeight  = (dwHeight > dwWidth) ? dwWidth : dwHeight;\r
+    pTMObj->dwVWidth   = (dwHeight > dwWidth) ? dwWidth : dwHeight;\r
+  }\r
+  else\r
+  {\r
+    pTMObj->dwSHeight  = dwHeight;\r
+    pTMObj->dwSWidth   = dwWidth;\r
+    pTMObj->dwVHeight  = dwHeight;\r
+    pTMObj->dwVWidth   = dwWidth;\r
+  }\r
+\r
+  /*========================*/  \r
+  /* Create SYSTEM surface. */\r
+  /*========================*/\r
+\r
+  /*  Request a surface in system memory. */\r
+  memset( &ddsd2, 0, sizeof(DDSURFACEDESC2) );\r
+  ddsd2.dwSize          = sizeof( DDSURFACEDESC2 );\r
+  ddsd2.dwWidth         = pTMObj->dwSWidth;\r
+  ddsd2.dwHeight        = pTMObj->dwSHeight;\r
+  ddsd2.dwFlags         = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;\r
+  ddsd2.ddsCaps.dwCaps  = DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY;\r
+  ddsd2.ddsCaps.dwCaps2 = 0L;\r
+  memset( &ddsd2.ddpfPixelFormat, 0, sizeof(DDPIXELFORMAT) );\r
+  ddsd2.ddpfPixelFormat.dwSize  = sizeof( DDPIXELFORMAT );\r
+  ddsd2.ddpfPixelFormat.dwFlags = dwRequestFlags;\r
+  rc = pHAL->lpD3DDevice->EnumTextureFormats( EnumPFHook, &ddsd2.ddpfPixelFormat );\r
+  if ( FAILED(rc) )\r
+  {\r
+    RIP( pHAL, "EnumerTextureFormats (SYSTEM)->", ErrorStringD3D(rc) );\r
+    return FALSE;\r
+  }\r
+\r
+  /* Create the surface using the enumerated pixelformat. */\r
+  rc = pHAL->lpDD4->CreateSurface( &ddsd2, &pTMObj->lpDDS_System, NULL );\r
+  if ( FAILED(rc) )\r
+  {\r
+    RIP( pHAL, "CreateSurface (TEXTURE/SYSTEM)->", ErrorStringD3D(rc) );\r
+    return FALSE;\r
+  }\r
+\r
+  /* Solve the pixel mapping info using the surface pixelformat. */\r
+  Solve8BitChannelPixelFormat( &ddsd2.ddpfPixelFormat, &pTMObj->pixel );\r
+\r
+  /*===================================================================*/\r
+  /* Fill the texture using the PixelInfo structure to do the mapping. */\r
+  /*===================================================================*/\r
+  UpdateTexture( pTMObj, FALSE, NULL, (UCHAR *)pPixels );\r
+\r
+  /*=======================*/\r
+  /* Create VIDEO surface. */\r
+  /*=======================*/\r
+  rc = LoadTextureInVideo( pHAL, pTMObj );\r
+  if ( rc == FALSE )\r
+    return FALSE;\r
+\r
+  /* Make this the current texture. */\r
+  rc = pHAL->lpD3DDevice->SetTexture( 0, pTMObj->lpD3DTexture2 );\r
+  if ( FAILED(rc) )\r
+  {\r
+    DPF(( DBG_TXT_WARN, "Failed SetTexture() (%s)", ErrorStringD3D(rc) ));\r
+    pHAL->lpD3DDevice->SetTexture( 0, NULL );\r
+    return FALSE;\r
+  }\r
+\r
+  return TRUE;\r
+}\r
+/*===========================================================================*/\r
+/*  This function will handle the creation and destruction of the texture    */\r
+/* surfaces on the card.  Using the dw'V'Width/Height dimensions the call    */\r
+/* try and create the texture on the card and keep using FreeTextureMemory   */\r
+/* until the surace can be created.  Once the surface is created we get the  */\r
+/* interface that we will use to make it the current texture.  I didn't put  */\r
+/* the code to make the texture current in this function as BIND needs to    */\r
+/* use the same code and this function doesn't always get called when we do a*/\r
+/* bind.                                                                     */\r
+/*===========================================================================*/\r
+/* RETURN: TRUE, FALSE.                                                      */\r
+/*===========================================================================*/\r
+static BOOL    LoadTextureInVideo( PMESAD3DHAL pHAL, PTM_OBJECT pTMObj )\r
+{\r
+  DDSURFACEDESC2       ddsd2;\r
+  HRESULT              rc;\r
+\r
+  DPF(( DBG_FUNC, "LoadTextureInVideo();" ));\r
+\r
+  /* Kill the interface if we have one no matter what. */\r
+  if ( pTMObj->lpD3DTexture2 )\r
+  {\r
+    DPF(( DBG_TXT_INFO, "Release Texture2" ));\r
+    pTMObj->lpD3DTexture2->Release();\r
+    pTMObj->lpD3DTexture2 = NULL;\r
+  }    \r
+\r
+  /* Kill the Video surface. TODO: need some reuse system... */\r
+  if ( pTMObj->lpDDS_Video )\r
+  {\r
+    DPF(( DBG_TXT_INFO, "Release texture (VID)" ));\r
+    DX_RESTORE( pTMObj->lpDDS_Video );\r
+    pTMObj->lpDDS_Video->Release();\r
+    pTMObj->lpDDS_Video = NULL;\r
+  }\r
+\r
+  /*  Request a surface in Video memory. */\r
+  memset( &ddsd2, 0, sizeof(DDSURFACEDESC2) );\r
+  ddsd2.dwSize          = sizeof( DDSURFACEDESC2 );\r
+  ddsd2.dwWidth         = pTMObj->dwVWidth;\r
+  ddsd2.dwHeight        = pTMObj->dwVHeight;\r
+  ddsd2.dwFlags         = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;\r
+  ddsd2.ddsCaps.dwCaps  = DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY;\r
+  ddsd2.ddsCaps.dwCaps2 = 0L;\r
+  memset( &ddsd2.ddpfPixelFormat, 0, sizeof(DDPIXELFORMAT) );\r
+  ddsd2.ddpfPixelFormat.dwSize  = sizeof( DDPIXELFORMAT );\r
+  ddsd2.ddpfPixelFormat.dwFlags = pTMObj->dwFlags;\r
+  rc = pHAL->lpD3DDevice->EnumTextureFormats( EnumPFHook, &ddsd2.ddpfPixelFormat );\r
+  if ( FAILED(rc) )\r
+  {\r
+    RIP( pHAL, "EnumerTextureFormats ->", ErrorStringD3D(rc) );\r
+    return FALSE;\r
+  }\r
+\r
+  /* Make sure we lock so we don't nuke this texture trying to free memory for it. */\r
+  pTMObj->bLock = TRUE;\r
+\r
+  /*  Start a loop that will free all textures until we have created the texture */\r
+  /* surface or we can't free up more memory.                                    */\r
+  do\r
+  {\r
+    /* Try to create the texture surface. */\r
+    rc = pHAL->lpDD4->CreateSurface( &ddsd2, &pTMObj->lpDDS_Video, NULL );\r
+    if ( !FAILED(rc) )\r
+        break;\r
+\r
+    DPF(( DBG_TXT_INFO, "Free Texture Memory" ));\r
+\r
+    /* DestroyTexture will return TRUE if a surface was freed. */\r
+  } while( FreeTextureMemory(pHAL,NULL) );\r
+\r
+  /* Make sure we unlock or we won't be able to nuke the TMO later. */\r
+  pTMObj->bLock = FALSE;\r
+\r
+  /* Did we create a valid texture surface? */\r
+  if ( FAILED(rc) )\r
+  {\r
+    DPF(( DBG_TXT_WARN, "Failed to load texture" ));\r
+    pHAL->lpD3DDevice->SetTexture( 0, NULL );\r
+    return FALSE;\r
+  }\r
+\r
+  DX_RESTORE( pTMObj->lpDDS_System );\r
+  DX_RESTORE( pTMObj->lpDDS_Video );\r
+\r
+  DPF(( DBG_TXT_INFO, "Texture Blt SYSTEM -> VID" ));\r
+\r
+  /* Now blt the texture in system memory to the card. */\r
+  rc = pTMObj->lpDDS_Video->Blt( NULL, pTMObj->lpDDS_System, NULL, DDBLT_WAIT, NULL );\r
+  if ( FAILED(rc) )\r
+  {\r
+    RIP( pHAL, "Blt (TEXTURE) ->", ErrorStringD3D(rc) );\r
+    return FALSE;\r
+  }\r
+\r
+  /* Get the Texture interface that is used to render with. */\r
+  pTMObj->lpDDS_Video->QueryInterface( IID_IDirect3DTexture2, (void **)&pTMObj->lpD3DTexture2 ); \r
+  if ( pTMObj->lpD3DTexture2 == NULL )\r
+  {\r
+    DPF(( DBG_TXT_WARN, "Failed QueryTextureInterface" ));\r
+    pHAL->lpD3DDevice->SetTexture( 0, NULL );\r
+    return FALSE;\r
+  }\r
+\r
+  return TRUE;\r
+}\r
+/*===========================================================================*/\r
+/*  If this function gets a texture object struc then we will try and free   */\r
+/* it.  If we get a NULL then we will search from the bottom up and free one */\r
+/* VMEM surface.  I can only free when the surface isn't locked and of course*/\r
+/* there must be a VMEM surface.  We never free SMEM surfaces as that isn't  */\r
+/* the point.                                                                */\r
+/* TODO: should have a pointer to the bottom of the stack really.            */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+static BOOL FreeTextureMemory( PMESAD3DHAL pHAL, PTM_OBJECT pTMObject )\r
+{\r
+  PTM_OBJECT   pCurrent;\r
+  BOOL         bFreed = FALSE;\r
+\r
+  DPF(( DBG_FUNC, "FreeTextureMemory();" ));\r
+  DPF(( DBG_TXT_WARN, "FREE TEXTURE!" ));\r
+\r
+  /* Just to be safe. */\r
+  if ( !pHAL || !pHAL->pTMList )\r
+  {\r
+    DPF(( DBG_TXT_WARN, "FreeTextureMemory() -> NULL pHAL/pHAL->pTMList" ));\r
+    return FALSE;\r
+  }\r
+\r
+  /* Free the last texture in the list. */\r
+  if ( pTMObject == NULL )\r
+  {\r
+    DPF(( DBG_TXT_INFO, "Free Last texture in cache" ));\r
+\r
+    /* Find the last texture object. */\r
+    for( pCurrent = pHAL->pTMList; pCurrent->next; pCurrent = pCurrent->next );\r
+\r
+    /* Now backup until we find a texture on the card. */\r
+    while( pCurrent && (pCurrent->lpDDS_Video == NULL) && (pCurrent->bLock == FALSE) )\r
+        pCurrent = pCurrent->prev;\r
+\r
+    /* Didn't find anything. */\r
+    if ( pCurrent == NULL )\r
+    {\r
+        DPF(( DBG_TXT_INFO, "No texture memory freed" ));\r
+        return FALSE;\r
+    }\r
+  }\r
+  else\r
+  {\r
+    /* See if we can find this texture object. */\r
+    for( pCurrent = pHAL->pTMList; pCurrent && (pCurrent != pTMObject); pCurrent = pCurrent->next );\r
+\r
+    /* Didn't find anything. */\r
+    if ( pCurrent == NULL )\r
+    {\r
+        DPF(( DBG_TXT_INFO, "Requested texture to be freed NOT FOUND" ));\r
+        return FALSE;\r
+    }\r
+  }\r
+\r
+  /* Can't free this baby. */\r
+  if ( pCurrent->bLock == TRUE )\r
+  {\r
+    DPF(( DBG_TXT_WARN, "Requested texture LOCKED" ));\r
+    return FALSE;\r
+  }\r
+\r
+  /* Free the texture memory. */\r
+  if ( pCurrent->lpD3DTexture2 )\r
+  {\r
+    DPF(( DBG_TXT_INFO, "Release Texture2" ));\r
+    pCurrent->lpD3DTexture2->Release();\r
+    pCurrent->lpD3DTexture2 = NULL;\r
+    bFreed = TRUE;\r
+  }\r
+  if ( pCurrent->lpDDS_Video )\r
+  {\r
+    DPF(( DBG_TXT_INFO, "Release texture (VID):" ));\r
+    DPF(( DBG_TXT_INFO, "dwName: %d", pCurrent->dwName ));\r
+    DPF(( DBG_TXT_INFO, "cx: %d, cy: %d", pCurrent->dwVWidth, pCurrent->dwVHeight ));\r
+    pCurrent->lpDDS_Video->Release();\r
+    pCurrent->lpDDS_Video = NULL;\r
+    bFreed = TRUE;\r
+  }\r
+  \r
+  return bFreed;\r
+}\r
+/*===========================================================================*/\r
+/*  This function searches the linked list of texture objects in the supplied*/\r
+/* D3Dwrapper structure.  If it finds a match it will free it and pull it out*/\r
+/* of the linked list.  The function works on the bases of a matching pointer*/\r
+/* to the object (not matching content).                                     */\r
+/*  If the function gets passed a NULL then we want to free the last texture */\r
+/* object in the list.  Used in a loop to destory all.                       */\r
+/*===========================================================================*/\r
+/* RETURN: TRUE, FALSE.                                                      */\r
+/*===========================================================================*/\r
+static BOOL DestroyTextureObject( PMESAD3DHAL pHAL, PTM_OBJECT pTMObject )\r
+{\r
+  PTM_OBJECT   pCurrent;\r
+\r
+  DPF(( DBG_FUNC, "DestoryTextureObject();" ));\r
+\r
+  /* Just to be safe. */\r
+  if ( !pHAL || !pHAL->pTMList )\r
+  {\r
+    DPF(( DBG_TXT_WARN, "DestroyTextureObject() -> NULL pHAL/pHAL->pTMList" ));\r
+    return FALSE;\r
+  }\r
+\r
+  /* Free the last texture in the list. */\r
+  if ( pTMObject == NULL )\r
+  {\r
+    /* Find the last texture object. */\r
+    for( pCurrent = pHAL->pTMList; pCurrent->next; pCurrent = pCurrent->next );\r
+  }\r
+  else\r
+  {\r
+    /* See if we can find this texture object. */\r
+    for( pCurrent = pHAL->pTMList; pCurrent && (pCurrent != pTMObject); pCurrent = pCurrent->next );\r
+\r
+    /* Didn't find anything. */\r
+    if ( pCurrent == NULL )\r
+    {\r
+        DPF(( DBG_TXT_WARN, "No textures to be freed" ));\r
+        return FALSE;\r
+    }\r
+  }\r
+\r
+  /* Can't free this baby. */\r
+  if ( pCurrent->bLock == TRUE )\r
+  {\r
+    DPF(( DBG_TXT_WARN, "Requested texture to be freed LOCKED" ));\r
+    return FALSE;\r
+  }\r
+\r
+  /* Free the texture memory. */\r
+  if ( pCurrent->lpD3DTexture2 )\r
+  { \r
+    DPF(( DBG_TXT_INFO, "Release Texture2" ));\r
+    pCurrent->lpD3DTexture2->Release();\r
+    pCurrent->lpD3DTexture2 = NULL;\r
+  }\r
+  if ( pCurrent->lpDDS_Video )\r
+  {\r
+    DPF(( DBG_TXT_INFO, "Release texture (VID):" ));\r
+    pCurrent->lpDDS_Video->Release();\r
+    pCurrent->lpDDS_Video = NULL;\r
+  }\r
+  if ( pCurrent->lpDDS_System )\r
+  {\r
+    DPF(( DBG_TXT_INFO, "Release texture (SYS):" ));\r
+    pCurrent->lpDDS_System->Release();\r
+    pCurrent->lpDDS_System = NULL;\r
+  }\r
+\r
+  /* Pull this texture out of the list. */\r
+  if ( pCurrent == pHAL->pTMList )\r
+    pHAL->pTMList = NULL;\r
+  if ( pCurrent->prev )\r
+    (pCurrent->prev)->next = pCurrent->next;\r
+  if ( pCurrent->next )\r
+    (pCurrent->next)->prev = pCurrent->prev;\r
+  FREE( pCurrent );\r
+\r
+  return TRUE;\r
+}\r
+/*===========================================================================*/\r
+/*  This function is the callback function that gets called when we are doing*/\r
+/* an enumeration of the texture formats supported by this device. The choice*/\r
+/* is made by checking to see if we have a match with the supplied D3D pixel-*/\r
+/* format.  So the enumeration has to pass a desired D3D PF as the user var. */\r
+/*===========================================================================*/\r
+/* RETURN: D3DENUMRET_OK, D3DENUMRET_CANCEL.                                 */\r
+/*===========================================================================*/\r
+static void UpdateTexture( PTM_OBJECT pTMObj, BOOL bVideo, RECT *pRect, UCHAR *pixels )\r
+{\r
+  LPDIRECTDRAWSURFACE4 lpDDS;\r
+  DDSURFACEDESC2               ddsd2;\r
+  DWORD                        srcPitch,\r
+                         dwHeight, \r
+                         dwWidth,\r
+                         dwCol,\r
+                         dwColor;\r
+  UCHAR                        *pSrc,\r
+                         *pSrcRow,\r
+                         *pDest,\r
+                         *pDestRow;\r
+  int                          rc;\r
+\r
+  // TODO:  Do I need to pass the h/w when its in the object!\r
+  DPF(( DBG_FUNC, "UpdateTexture();" ));\r
+\r
+  /* Get the surface pointer we are looking for. */\r
+  lpDDS = (bVideo) ? pTMObj->lpDDS_Video : pTMObj->lpDDS_System;\r
+\r
+  /*===================================================================*/\r
+  /* Fill the texture using the PixelInfo structure to do the mapping. */\r
+  /*===================================================================*/\r
+        \r
+  /* Get the surface pointer. */\r
+  memset( &ddsd2, 0, sizeof(DDSURFACEDESC2) );\r
+  ddsd2.dwSize = sizeof(DDSURFACEDESC2);\r
+  rc = lpDDS->Lock( NULL, &ddsd2, DDLOCK_WAIT, NULL );\r
+  if ( FAILED(rc) )\r
+  {\r
+    RIP( NULL, "Lock (TEXTURE/SYSTEM)->", ErrorStringD3D(rc) );\r
+    return;\r
+  }\r
+\r
+  /* For now we are only updating the system surface so use its dimensions. */\r
+  dwWidth  = (bVideo) ? pTMObj->dwVWidth : pTMObj->dwSWidth;\r
+  dwHeight = (bVideo) ? pTMObj->dwVHeight : pTMObj->dwSHeight;\r
+\r
+  /*  If we are updating the whole surface then the pDest/pSrc will */\r
+  /* always be the same.                                            */\r
+  if ( pRect == NULL )\r
+  {\r
+    pDest = (UCHAR *)ddsd2.lpSurface;\r
+    pSrc  = pixels;\r
+  }\r
+\r
+  /* Fill the texture surface based on the pixelformat flags. */\r
+  if ( pTMObj->dwFlags == (DDPF_RGB | DDPF_ALPHAPIXELS) )\r
+  {\r
+    srcPitch = dwWidth * 4;\r
+    if ( pRect )\r
+    {\r
+        pDest = ((UCHAR *)ddsd2.lpSurface) + (pRect->top * ddsd2.lPitch) + (pRect->left * pTMObj->pixel.cb);\r
+        pSrc  = pixels + (pRect->top * dwWidth * 4) + (pRect->left * 4);\r
+        dwHeight = (pRect->bottom - pRect->top);\r
+        dwWidth = (pRect->right - pRect->left);\r
+    }\r
+\r
+    for( pDestRow = pDest, pSrcRow = pSrc; dwHeight > 0; dwHeight--, pDestRow += ddsd2.lPitch, pSrcRow += srcPitch )\r
+    {\r
+        for( dwCol = 0, pDest = pDestRow, pSrc = pSrcRow; dwCol < dwWidth; dwCol++ )\r
+      {\r
+          dwColor =  ( ((DWORD)(*(pSrc  ) * pTMObj->pixel.rScale)) << pTMObj->pixel.rShift );\r
+          dwColor |= ( ((DWORD)(*(pSrc+1) * pTMObj->pixel.gScale)) << pTMObj->pixel.gShift );\r
+          dwColor |= ( ((DWORD)(*(pSrc+2) * pTMObj->pixel.bScale)) << pTMObj->pixel.bShift );\r
+          if ( pTMObj->pixel.aScale == -1.0 )\r
+               dwColor |= ( (*(pSrc+3) & 0x80) ? (1 << pTMObj->pixel.aShift) : 0 );\r
+          else\r
+               dwColor |= ( ((DWORD)(*(pSrc+3) * pTMObj->pixel.aScale)) << pTMObj->pixel.aShift );\r
+          memcpy( pDest, &dwColor, pTMObj->pixel.cb );\r
+          pDest += pTMObj->pixel.cb;\r
+          pSrc  += 4;\r
+        }\r
+    }\r
+  }\r
+  else if ( pTMObj->dwFlags == DDPF_RGB )\r
+  {\r
+    srcPitch = dwWidth * 3;\r
+    if ( pRect )\r
+    {\r
+        pDest = ((UCHAR *)ddsd2.lpSurface) + (pRect->top * ddsd2.lPitch) + (pRect->left * pTMObj->pixel.cb);\r
+        pSrc  = pixels + (pRect->top * dwWidth * 3) + (pRect->left * 3);\r
+        dwHeight = (pRect->bottom - pRect->top);\r
+        dwWidth  = (pRect->right - pRect->left);\r
+    }\r
+\r
+    for( pDestRow = pDest, pSrcRow = pSrc; dwHeight > 0; dwHeight--, pDestRow += ddsd2.lPitch, pSrcRow += srcPitch )\r
+    {\r
+        for( dwCol = 0, pDest = pDestRow, pSrc = pSrcRow; dwCol < dwWidth; dwCol++ )\r
+      {\r
+          dwColor =  ( ((DWORD)(*(pSrc  ) * pTMObj->pixel.rScale)) << pTMObj->pixel.rShift );\r
+          dwColor |= ( ((DWORD)(*(pSrc+1) * pTMObj->pixel.gScale)) << pTMObj->pixel.gShift );\r
+          dwColor |= ( ((DWORD)(*(pSrc+2) * pTMObj->pixel.bScale)) << pTMObj->pixel.bShift );\r
+          memcpy( pDest, &dwColor, pTMObj->pixel.cb );\r
+          pDest += pTMObj->pixel.cb;\r
+          pSrc  += 3;\r
+        }\r
+    }\r
+  }\r
+  else if ( pTMObj->dwFlags == (DDPF_LUMINANCE | DDPF_ALPHAPIXELS) )\r
+  {\r
+    srcPitch = dwWidth * 2;\r
+    if ( pRect )\r
+    {\r
+        pDest = ((UCHAR *)ddsd2.lpSurface) + (pRect->top * ddsd2.lPitch) + (pRect->left * pTMObj->pixel.cb);\r
+        pSrc  = pixels + (pRect->top * dwWidth * 2) + (pRect->left * 2);\r
+        dwHeight = (pRect->bottom - pRect->top);\r
+        dwWidth  = (pRect->right - pRect->left);\r
+    }\r
+\r
+    for( pDestRow = pDest, pSrcRow = pSrc; dwHeight > 0; dwHeight--, pDestRow += ddsd2.lPitch, pSrcRow += srcPitch )\r
+    {\r
+        for( dwCol = 0, pDest = pDestRow, pSrc = pSrcRow; dwCol < dwWidth; dwCol++ )\r
+      {\r
+          dwColor =  ( ((DWORD)(*(pSrc  ) * pTMObj->pixel.rScale)) << pTMObj->pixel.rShift );\r
+          if ( pTMObj->pixel.aScale == -1.0 )\r
+               dwColor |= ( (*(pSrc+1) & 0x80) ? (1 << pTMObj->pixel.aShift) : 0 );\r
+          else\r
+               dwColor |= ( ((DWORD)(*(pSrc+1) * pTMObj->pixel.aScale)) << pTMObj->pixel.aShift );\r
+          memcpy( pDest, &dwColor, pTMObj->pixel.cb );\r
+          pDest += pTMObj->pixel.cb;\r
+          pSrc  += 2;\r
+        }\r
+    }\r
+  }\r
+  else if ( pTMObj->dwFlags == DDPF_LUMINANCE )\r
+  {\r
+    srcPitch = dwWidth;\r
+    if ( pRect )\r
+    {\r
+        pDest = ((UCHAR *)ddsd2.lpSurface) + (pRect->top * ddsd2.lPitch) + (pRect->left * pTMObj->pixel.cb);\r
+        pSrc  = pixels + (pRect->top * dwWidth) + (pRect->left);\r
+        dwHeight = (pRect->bottom - pRect->top);\r
+        dwWidth  = (pRect->right - pRect->left);\r
+    }\r
+\r
+    for( pDestRow = pDest, pSrcRow = pSrc; dwHeight > 0; dwHeight--, pDestRow += ddsd2.lPitch, pSrcRow += srcPitch )\r
+    {\r
+        for( dwCol = 0, pDest = pDestRow, pSrc = pSrcRow; dwCol < dwWidth; dwCol++ )\r
+      {\r
+          dwColor =  ( ((DWORD)(*pSrc * pTMObj->pixel.rScale)) << pTMObj->pixel.rShift );\r
+          memcpy( pDest, &dwColor, pTMObj->pixel.cb );\r
+          pDest += pTMObj->pixel.cb;\r
+          pSrc++;\r
+        }\r
+    }\r
+  }\r
+  else if ( pTMObj->dwFlags == DDPF_ALPHAPIXELS )\r
+  {\r
+    srcPitch = dwWidth;\r
+    if ( pRect )\r
+    {\r
+        pDest = ((UCHAR *)ddsd2.lpSurface) + (pRect->top * ddsd2.lPitch) + (pRect->left * pTMObj->pixel.cb);\r
+        pSrc  = pixels + (pRect->top * dwWidth) + (pRect->left);\r
+        dwHeight = (pRect->bottom - pRect->top);\r
+        dwWidth  = (pRect->right - pRect->left);\r
+    }\r
+\r
+    for( pDestRow = pDest, pSrcRow = pSrc; dwHeight > 0; dwHeight--, pDestRow += ddsd2.lPitch, pSrcRow += srcPitch )\r
+    {\r
+        for( dwCol = 0, pDest = pDestRow, pSrc = pSrcRow; dwCol < dwWidth; dwCol++ )\r
+      {\r
+          if ( pTMObj->pixel.aScale == -1.0 )\r
+               dwColor = ( (*pSrc & 0x80) ? (1 << pTMObj->pixel.aShift) : 0 );\r
+          else\r
+               dwColor = ( ((DWORD)(*pSrc * pTMObj->pixel.aScale)) << pTMObj->pixel.aShift );\r
+          memcpy( pDest, &dwColor, pTMObj->pixel.cb );\r
+          pDest += pTMObj->pixel.cb;\r
+          pSrc++;\r
+        }\r
+    }\r
+  }\r
+\r
+  /* Unlock the surface. */\r
+  rc = lpDDS->Unlock( NULL );\r
+  if ( FAILED(rc) )\r
+  {\r
+    RIP( NULL, "Unlock (TEXTURE/SYSTEM)->", ErrorStringD3D(rc) );\r
+  }\r
+}\r
+/*===========================================================================*/\r
+/*  This function is the callback function that gets called when we are doing*/\r
+/* an enumeration of the texture formats supported by this device. The choice*/\r
+/* is made by checking to see if we have a match with the supplied D3D pixel-*/\r
+/* format.  So the enumeration has to pass a desired D3D PF as the user var. */\r
+/*===========================================================================*/\r
+/* RETURN: D3DENUMRET_OK, D3DENUMRET_CANCEL.                                 */\r
+/*===========================================================================*/\r
+HRESULT CALLBACK EnumPFHook( LPDDPIXELFORMAT lpDDPixFmt, LPVOID lpContext )\r
+{\r
+  LPDDPIXELFORMAT   lpDDPixFmtRequest = (LPDDPIXELFORMAT)lpContext;\r
+  PIXELINFO            pixel;\r
+\r
+  DPF(( DBG_FUNC, "EnumPFHook();" ));\r
+\r
+  if ( lpDDPixFmt->dwFlags == lpDDPixFmtRequest->dwFlags )\r
+  {\r
+    /* Are we looking for an alpha channel? */\r
+    if ( lpDDPixFmtRequest->dwFlags & DDPF_ALPHAPIXELS )\r
+    {\r
+        /* Try for something that has more then 1bits of Alpha. */\r
+        Solve8BitChannelPixelFormat( lpDDPixFmt, &pixel );\r
+        if ( pixel.aScale == -1.0 )\r
+        {\r
+          /* Save this format no matter what as its a match of sorts. */\r
+          memcpy( lpDDPixFmtRequest, lpDDPixFmt, sizeof(DDPIXELFORMAT) );\r
+          return D3DENUMRET_OK;\r
+        }\r
+    }\r
+\r
+    /* Save this format as its a good match. */\r
+    memcpy( lpDDPixFmtRequest, lpDDPixFmt, sizeof(DDPIXELFORMAT) );\r
+\r
+    /* We are happy at this point so lets leave. */\r
+    return D3DENUMRET_CANCEL;\r
+  }\r
+  \r
+  return D3DENUMRET_OK;\r
+}\r
+\r
+\r
+\1a
\ No newline at end of file
diff --git a/src/mesa/drivers/d3d/D3DTextureMgr.h b/src/mesa/drivers/d3d/D3DTextureMgr.h
new file mode 100644 (file)
index 0000000..6b3ac78
--- /dev/null
@@ -0,0 +1,63 @@
+/*===========================================================================*/\r
+/*                                                                           */\r
+/* Mesa-3.0 DirectX 6 Driver                                                 */\r
+/*                                                                           */\r
+/* By Leigh McRae                                                            */\r
+/*                                                                           */\r
+/* http://www.altsoftware.com/                                               */\r
+/*                                                                           */\r
+/* Copyright (c) 1999-1998  alt.software inc.  All Rights Reserved           */\r
+/*===========================================================================*/\r
+#ifndef _TEXTURE_MGR_INC\r
+#define _TEXTURE_MGR_INC\r
+   \r
+/*===========================================================================*/\r
+/* Includes.                                                                 */\r
+/*===========================================================================*/\r
+#include <windows.h>\r
+#include <ddraw.h>\r
+#include <d3d.h>\r
+#include <stdlib.h>\r
+#include <stdlib.h>\r
+#include "GL/gl.h"\r
+/*========================================================================*/\r
+/* Defines.                                                               */\r
+/*========================================================================*/\r
+/*========================================================================*/\r
+/* Type defines.                                                          */\r
+/*========================================================================*/\r
+typedef struct _local_texture_object\r
+{\r
+   DWORD                dwName,\r
+                        dwPriority,\r
+                        dwFlags,\r
+                        dwSWidth,\r
+                        dwSHeight,\r
+                        dwVWidth,\r
+                        dwVHeight;\r
+   BOOL                 bLock,\r
+                          bDirty;              /*  I only update VID on SubImage calls so the system */\r
+                                        /* texture can get invalid.                           */\r
+\r
+   LPDIRECT3DDEVICE3    lpD3DDevice;   /* If the device changes we must get new handles... */\r
+   LPDIRECTDRAWSURFACE4 lpDDS_System,\r
+                          lpDDS_Video;\r
+   LPDIRECT3DTEXTURE2   lpD3DTexture2;\r
+\r
+   PIXELINFO            pixel;\r
+\r
+   struct _local_texture_object *next;\r
+   struct _local_texture_object *prev;\r
+\r
+} TM_OBJECT, *PTM_OBJECT;\r
+/*========================================================================*/\r
+/* Function prototypes.                                                   */\r
+/*========================================================================*/\r
+void APIENTRY  InitTMD3D( void *pVoid );\r
+void APIENTRY  TermTMD3D( void *pVoid );\r
+/*========================================================================*/\r
+/* Global variables declaration.                                          */\r
+/*========================================================================*/\r
+\r
+#endif \r
+\1a
\ No newline at end of file
diff --git a/src/mesa/drivers/d3d/D3DUTILS.CPP b/src/mesa/drivers/d3d/D3DUTILS.CPP
new file mode 100644 (file)
index 0000000..381e09f
--- /dev/null
@@ -0,0 +1,639 @@
+/*===========================================================================*/\r
+/*                                                                           */\r
+/* Mesa-3.0 DirectX 6 Driver                                                 */\r
+/*                                                                           */\r
+/* By Leigh McRae                                                            */\r
+/*                                                                           */\r
+/* http://www.altsoftware.com/                                               */\r
+/*                                                                           */\r
+/* Copyright (c) 1999-1998  alt.software inc.  All Rights Reserved           */\r
+/*===========================================================================*/\r
+#include "D3DHAL.h"\r
+/*===========================================================================*/\r
+/* Local only functions.                                                     */\r
+/*===========================================================================*/\r
+static int  CountTrailingZeros( DWORD dwMask );\r
+/*===========================================================================*/\r
+/*  This function is used to get the pointer to the surface and the pitch for*/\r
+/* the scanline rendering functions.                                         */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+extern "C" DDSURFACEDESC2 *LockHAL( PMESAD3DSHARED pShared, BOOL bBack )\r
+{\r
+  PMESAD3DHAL                  pHAL = (PMESAD3DHAL)pShared;\r
+  static DDSURFACEDESC2        ddsd2;\r
+  HRESULT                      rc;      \r
+\r
+  DPF(( DBG_FUNC, "LockHAL();" ));\r
+\r
+  /* Set the request structure up first. */\r
+  memset( &ddsd2, 0, sizeof(DDSURFACEDESC2) );\r
+  ddsd2.dwSize = sizeof(DDSURFACEDESC2);\r
+\r
+  /* Make sure we have enough info. */\r
+  if ( pHAL )\r
+  {\r
+    rc = pHAL->lpDDSRender->Lock( NULL, &ddsd2, DDLOCK_WAIT, NULL );\r
+    if ( FAILED(rc) )\r
+    {\r
+        RIP( pHAL, "Lock (RENDER) ->", ErrorStringD3D(rc) );\r
+    }\r
+  }\r
+\r
+  return &ddsd2;\r
+}\r
+/*===========================================================================*/\r
+/*  This is just a simple wrapper.  I probably don't need to do any error    */\r
+/* checking as the Lock must have worked inorder to get here...              */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+extern "C" void UnlockHAL( PMESAD3DSHARED pShared, BOOL bBack )\r
+{\r
+  PMESAD3DHAL  pHAL = (PMESAD3DHAL)pShared;\r
+  HRESULT              rc;\r
+\r
+  DPF(( DBG_FUNC, "UnlockHAL();" ));\r
+\r
+  /* Make sure we have enough info. */\r
+  if ( pHAL )\r
+  {\r
+    rc = pHAL->lpDDSRender->Unlock( NULL );\r
+    if ( FAILED(rc) )\r
+    {\r
+        RIP( pHAL, "Unlock (RENDER) ->", ErrorStringD3D(rc) );\r
+    }\r
+  }\r
+}\r
+/*===========================================================================*/\r
+/*  This function will track the main/Primary window that will be used as the*/\r
+/* target for the Blt in SwapBuffers.  As a side effect the call will check  */\r
+/* to see if the primary surface is the same size and position as the screen.*/\r
+/* If they are the same size we will call it fullscreen...                   */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+extern "C" void UpdateScreenPosHAL( PMESAD3DSHARED pShared )\r
+{\r
+  PMESAD3DHAL  pHAL = (PMESAD3DHAL)pShared;\r
+  POINT                pt;\r
+  DWORD                dwWidth, dwHeight;\r
+\r
+  DPF(( DBG_FUNC, "UpdateScreenPosHAL();" ));\r
+\r
+  /* Make sure we have enough info. */\r
+  if ( pHAL != NULL )\r
+  {\r
+    /* Update the windows screen position. */\r
+    GetClientRect( pShared->hwnd, &pShared->rectW );\r
+    pt.x = pt.y = 0;\r
+    ClientToScreen( pShared->hwnd, &pt );\r
+    OffsetRect( &pShared->rectW, pt.x, pt.y);\r
+\r
+    /* Compare the primary to the screen. */\r
+    dwWidth = GetSystemMetrics( SM_CXSCREEN );\r
+    dwHeight =  GetSystemMetrics( SM_CYSCREEN );\r
+    if ( (pShared->rectW.left > 0) ||  (pShared->rectW.top > 0)  ||\r
+           (pShared->rectW.right > dwWidth) || (pShared->rectW.bottom > dwHeight) )\r
+        pShared->bWindow = TRUE;\r
+    else\r
+        pShared->bWindow = FALSE;\r
+  }\r
+}\r
+/*===========================================================================*/\r
+/*  This function will fill in the pixel info structure defined in D3Dshared.*/\r
+/* Basicly it will take a DirectDraw pixelformat structure and make scaling  */\r
+/* values that will convert from 8bit channels to whatever the supplied ddpf */\r
+/* uses.  Also we will generate shift values that will be used to get move   */\r
+/* each component of the pixel into place.                                   */\r
+/*  I have now added a special case for a 1bit alpha channel.  If I find a 1b*/\r
+/* alpha then I will set the scale to -1.0 which should be unique.  Later I  */\r
+/* can check the alpha scale value too see if its -1.0 and thus handle it.  I*/\r
+/* was finding that the case was not working tom my advantage so this is my  */\r
+/* HACK for the day.  As a TODO I should work on this...                     */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+void   Solve8BitChannelPixelFormat( DDPIXELFORMAT *pddpf, PPIXELINFO pPixel )\r
+{\r
+  DPF(( DBG_FUNC, "Solve8BitChannelPixelFromat();" ));\r
+\r
+  memset( pPixel, 0, sizeof(PPIXELINFO) );\r
+\r
+  /* Check too see if the color space is valid in the PF. */\r
+  if ( pddpf->dwFlags & DDPF_RGB )\r
+  {\r
+    /* Solve the red stuff. */\r
+    pPixel->dwRMask = pddpf->dwRBitMask;\r
+    pPixel->rShift = CountTrailingZeros( pPixel->dwRMask );\r
+    pPixel->rScale = (float)0.00392156 * (float)(pPixel->dwRMask >> pPixel->rShift);\r
+\r
+    /* Solve the green thingy's. */\r
+    pPixel->dwGMask = pddpf->dwGBitMask;\r
+    pPixel->gShift = CountTrailingZeros( pPixel->dwGMask );\r
+    pPixel->gScale = (float)0.00392156 * (float)(pPixel->dwGMask >> pPixel->gShift);\r
+\r
+    /* Solve the blues. */\r
+    pPixel->dwBMask = pddpf->dwBBitMask;\r
+    pPixel->bShift = CountTrailingZeros( pddpf->dwBBitMask );\r
+    pPixel->bScale = (float)0.00392156 * (float)(pddpf->dwBBitMask >> pPixel->bShift);\r
+  }\r
+\r
+  /* Do the alpha channel if there is one. */\r
+  if ( pddpf->dwFlags & DDPF_ALPHAPIXELS )\r
+  {\r
+    pPixel->dwAMask = pddpf->dwRGBAlphaBitMask;\r
+    pPixel->aShift = CountTrailingZeros( pPixel->dwAMask );\r
+\r
+    /* Special case a 1bit alpha. */\r
+    if ( (pPixel->dwAMask >> pPixel->aShift) == 1 )\r
+        pPixel->aScale = -1.0;\r
+    else\r
+        pPixel->aScale = (float)0.00392156 * (float)(pPixel->dwAMask >> pPixel->aShift);\r
+  }\r
+\r
+  /* Get the size of the pixel in bytes. Should work as dwRGBBitCount is in a union. */\r
+  pPixel->cb = pddpf->dwRGBBitCount / 8;\r
+}\r
+/*===========================================================================*/\r
+/*  See RETURN :)                                                            */\r
+/*===========================================================================*/\r
+/* RETURN: number of contiguous zeros starting from the right.               */\r
+/*===========================================================================*/\r
+static int  CountTrailingZeros( DWORD dwMask )\r
+{\r
+  DWORD Mask;\r
+\r
+  if ( dwMask == 0 ) \r
+    return 32;\r
+\r
+  /* Can't take credit for this one! */\r
+  Mask = dwMask & -(int)dwMask;\r
+  return ((Mask & 0xFFFF0000)!=0) << 4\r
+         | ((Mask & 0xFF00FF00)!=0) << 3\r
+         | ((Mask & 0xF0F0F0F0)!=0) << 2\r
+         | ((Mask & 0xCCCCCCCC)!=0) << 1\r
+         | ((Mask & 0xAAAAAAAA)!=0);\r
+}\r
+/*===========================================================================*/\r
+/*  This function will convert the DDraw error code to its macro string.  The*/\r
+/* returned pointer is static so you need not worry about memory managemnet  */\r
+/* but the error message gets written over from call to call...              */\r
+/*===========================================================================*/\r
+/* RETURN: pointer to the single static buffer that hold the error message.  */\r
+/*===========================================================================*/\r
+char *ErrorStringD3D( HRESULT hr )\r
+{\r
+  static   char  errorString[128];\r
+\r
+  switch( hr )\r
+    {\r
+    case DDERR_ALREADYINITIALIZED:\r
+        strcpy( errorString, "DDERR_ALREADYINITIALIZED" );\r
+        break;\r
+        \r
+    case DDERR_CANNOTATTACHSURFACE:\r
+        strcpy( errorString, "DDERR_CANNOTATTACHSURFACE" );\r
+        break;\r
+        \r
+    case DDERR_CANNOTDETACHSURFACE:\r
+        strcpy( errorString, "DDERR_CANNOTDETACHSURFACE" );\r
+        break;\r
+        \r
+    case DDERR_CURRENTLYNOTAVAIL:\r
+        strcpy( errorString, "DDERR_CURRENTLYNOTAVAIL" );\r
+        break;\r
+        \r
+    case DDERR_EXCEPTION:\r
+        strcpy( errorString, "DDERR_EXCEPTION" );\r
+        break;\r
+        \r
+    case DDERR_GENERIC:\r
+        strcpy( errorString, "DDERR_GENERIC" );\r
+        break;\r
+        \r
+    case DDERR_HEIGHTALIGN:\r
+        strcpy( errorString, "DDERR_HEIGHTALIGN" );\r
+        break;\r
+        \r
+    case DDERR_INCOMPATIBLEPRIMARY:\r
+        strcpy( errorString, "DDERR_INCOMPATIBLEPRIMARY" );\r
+        break;\r
+        \r
+    case DDERR_INVALIDCAPS:\r
+        strcpy( errorString, "DDERR_INVALIDCAPS" );\r
+        break;\r
+        \r
+    case DDERR_INVALIDCLIPLIST:\r
+        strcpy( errorString, "DDERR_INVALIDCLIPLIST" );\r
+        break;\r
+        \r
+    case DDERR_INVALIDMODE:\r
+        strcpy( errorString, "DDERR_INVALIDMODE" );\r
+        break;\r
+        \r
+    case DDERR_INVALIDOBJECT:\r
+        strcpy( errorString, "DDERR_INVALIDOBJECT" );\r
+        break;\r
+        \r
+    case DDERR_INVALIDPARAMS:\r
+        strcpy( errorString, "DDERR_INVALIDPARAMS" );\r
+        break;\r
+        \r
+    case DDERR_INVALIDPIXELFORMAT:\r
+        strcpy( errorString, "DDERR_INVALIDPIXELFORMAT" );\r
+        break;\r
+        \r
+    case DDERR_INVALIDRECT:\r
+        strcpy( errorString, "DDERR_INVALIDRECT" );\r
+        break;\r
+        \r
+    case DDERR_LOCKEDSURFACES:\r
+        strcpy( errorString, "DDERR_LOCKEDSURFACES" );\r
+        break;\r
+        \r
+    case DDERR_NO3D:\r
+        strcpy( errorString, "DDERR_NO3D" );\r
+        break;\r
+        \r
+    case DDERR_NOALPHAHW:\r
+        strcpy( errorString, "DDERR_NOALPHAHW" );\r
+        break;\r
+        \r
+    case DDERR_NOCLIPLIST:\r
+        strcpy( errorString, "DDERR_NOCLIPLIST" );\r
+        break;\r
+        \r
+    case DDERR_NOCOLORCONVHW:\r
+        strcpy( errorString, "DDERR_NOCOLORCONVHW" );\r
+        break;\r
+        \r
+    case DDERR_NOCOOPERATIVELEVELSET:\r
+        strcpy( errorString, "DDERR_NOCOOPERATIVELEVELSET" );\r
+        break;\r
+        \r
+    case DDERR_NOCOLORKEY:\r
+        strcpy( errorString, "DDERR_NOCOLORKEY" );\r
+        break;\r
+        \r
+    case DDERR_NOCOLORKEYHW:\r
+        strcpy( errorString, "DDERR_NOCOLORKEYHW" );\r
+        break;\r
+        \r
+    case DDERR_NODIRECTDRAWSUPPORT:\r
+        strcpy( errorString, "DDERR_NODIRECTDRAWSUPPORT" );\r
+        break;\r
+        \r
+    case DDERR_NOEXCLUSIVEMODE:\r
+        strcpy( errorString, "DDERR_NOEXCLUSIVEMODE" );\r
+        break;\r
+        \r
+    case DDERR_NOFLIPHW:\r
+        strcpy( errorString, "DDERR_NOFLIPHW" );\r
+        break;\r
+        \r
+    case DDERR_NOGDI:\r
+        strcpy( errorString, "DDERR_NOGDI" );\r
+        break;\r
+        \r
+    case DDERR_NOMIRRORHW:\r
+        strcpy( errorString, "DDERR_NOMIRRORHW" );\r
+        break;\r
+        \r
+    case DDERR_NOTFOUND:\r
+        strcpy( errorString, "DDERR_NOTFOUND" );\r
+        break;\r
+        \r
+    case DDERR_NOOVERLAYHW:\r
+        strcpy( errorString, "DDERR_NOOVERLAYHW" );\r
+        break;\r
+        \r
+    case DDERR_OVERLAPPINGRECTS:\r
+        strcpy( errorString, "DDERR_OVERLAPPINGRECTS" );\r
+        break;\r
+        \r
+    case DDERR_NORASTEROPHW:\r
+        strcpy( errorString, "DDERR_NORASTEROPHW" );\r
+        break;\r
+        \r
+    case DDERR_NOROTATIONHW:\r
+        strcpy( errorString, "DDERR_NOROTATIONHW" );\r
+        break;\r
+        \r
+    case DDERR_NOSTRETCHHW:\r
+        strcpy( errorString, "DDERR_NOSTRETCHHW" );\r
+        break;\r
+        \r
+    case DDERR_NOT4BITCOLOR:\r
+        strcpy( errorString, "DDERR_NOT4BITCOLOR" );\r
+        break;\r
+        \r
+    case DDERR_NOT4BITCOLORINDEX:\r
+        strcpy( errorString, "DDERR_NOT4BITCOLORINDEX" );\r
+        break;\r
+        \r
+    case DDERR_NOT8BITCOLOR:\r
+        strcpy( errorString, "DDERR_NOT8BITCOLOR" );\r
+        break;\r
+        \r
+    case DDERR_NOTEXTUREHW:\r
+        strcpy( errorString, "DDERR_NOTEXTUREHW" );\r
+        break;\r
+        \r
+    case DDERR_NOVSYNCHW:\r
+        strcpy( errorString, "DDERR_NOVSYNCHW" );\r
+        break;\r
+        \r
+    case DDERR_NOZBUFFERHW:\r
+        strcpy( errorString, "DDERR_NOZBUFFERHW" );\r
+        break;\r
+\r
+    case DDERR_NOZOVERLAYHW:\r
+        strcpy( errorString, "DDERR_NOZOVERLAYHW" );\r
+        break;\r
+        \r
+    case DDERR_OUTOFCAPS:\r
+        strcpy( errorString, "DDERR_OUTOFCAPS" );\r
+        break;\r
+        \r
+    case DDERR_OUTOFMEMORY:\r
+        strcpy( errorString, "DDERR_OUTOFMEMORY" );\r
+        break;\r
+        \r
+    case DDERR_OUTOFVIDEOMEMORY:\r
+        strcpy( errorString, "DDERR_OUTOFVIDEOMEMORY" );\r
+        break;\r
+        \r
+    case DDERR_OVERLAYCANTCLIP:\r
+        strcpy( errorString, "DDERR_OVERLAYCANTCLIP" );\r
+        break;\r
+        \r
+    case DDERR_OVERLAYCOLORKEYONLYONEACTIVE:\r
+        strcpy( errorString, "DDERR_OVERLAYCOLORKEYONLYONEACTIVE" );\r
+        break;\r
+        \r
+    case DDERR_PALETTEBUSY:\r
+        strcpy( errorString, "DDERR_PALETTEBUSY" );\r
+        break;\r
+        \r
+    case DDERR_COLORKEYNOTSET:\r
+        strcpy( errorString, "DDERR_COLORKEYNOTSET" );\r
+        break;\r
+        \r
+    case DDERR_SURFACEALREADYATTACHED:\r
+        strcpy( errorString, "DDERR_SURFACEALREADYATTACHED" );\r
+        break;\r
+        \r
+    case DDERR_SURFACEALREADYDEPENDENT:\r
+        strcpy( errorString, "DDERR_SURFACEALREADYDEPENDENT" );\r
+        break;\r
+        \r
+    case DDERR_SURFACEBUSY:\r
+        strcpy( errorString, "DDERR_SURFACEBUSY" );\r
+        break;\r
+        \r
+    case DDERR_CANTLOCKSURFACE:\r
+        strcpy( errorString, "DDERR_CANTLOCKSURFACE" );\r
+        break;\r
+\r
+    case DDERR_SURFACEISOBSCURED:\r
+        strcpy( errorString, "DDERR_SURFACEISOBSCURED" );\r
+        break;\r
+\r
+    case DDERR_SURFACELOST:\r
+        strcpy( errorString, "DDERR_SURFACELOST" );\r
+        break;\r
+        \r
+    case DDERR_SURFACENOTATTACHED:\r
+        strcpy( errorString, "DDERR_SURFACENOTATTACHED" );\r
+        break;\r
+        \r
+    case DDERR_TOOBIGHEIGHT:\r
+        strcpy( errorString, "DDERR_TOOBIGHEIGHT" );\r
+        break;\r
+        \r
+    case DDERR_TOOBIGSIZE:\r
+        strcpy( errorString, "DDERR_TOOBIGSIZE" );\r
+        break;\r
+        \r
+    case DDERR_TOOBIGWIDTH:\r
+        strcpy( errorString, "DDERR_TOOBIGWIDTH" );\r
+        break;\r
+        \r
+    case DDERR_UNSUPPORTED:\r
+        strcpy( errorString, "DDERR_UNSUPPORTED" );\r
+        break;\r
+        \r
+    case DDERR_UNSUPPORTEDFORMAT:\r
+        strcpy( errorString, "DDERR_UNSUPPORTEDFORMAT" );\r
+        break;\r
+        \r
+    case DDERR_UNSUPPORTEDMASK:\r
+        strcpy( errorString, "DDERR_UNSUPPORTEDMASK" );\r
+        break;\r
+        \r
+    case DDERR_INVALIDSTREAM:\r
+        strcpy( errorString, "DDERR_INVALIDSTREAM" );\r
+        break;\r
+        \r
+    case DDERR_VERTICALBLANKINPROGRESS:\r
+        strcpy( errorString, "DDERR_VERTICALBLANKINPROGRESS" );\r
+        break;\r
+        \r
+    case DDERR_WASSTILLDRAWING:\r
+        strcpy( errorString, "DDERR_WASSTILLDRAWING" );\r
+        break;\r
+        \r
+    case DDERR_XALIGN:\r
+        strcpy( errorString, "DDERR_XALIGN" );\r
+        break;\r
+        \r
+    case DDERR_INVALIDDIRECTDRAWGUID:\r
+        strcpy( errorString, "DDERR_INVALIDDIRECTDRAWGUID" );\r
+        break;\r
+        \r
+    case DDERR_DIRECTDRAWALREADYCREATED:\r
+        strcpy( errorString, "DDERR_DIRECTDRAWALREADYCREATED" );\r
+        break;\r
+        \r
+    case DDERR_NODIRECTDRAWHW:\r
+        strcpy( errorString, "DDERR_NODIRECTDRAWHW" );\r
+        break;\r
+        \r
+    case DDERR_PRIMARYSURFACEALREADYEXISTS:\r
+        strcpy( errorString, "DDERR_PRIMARYSURFACEALREADYEXISTS" );\r
+        break;\r
+        \r
+    case DDERR_NOEMULATION:\r
+        strcpy( errorString, "DDERR_NOEMULATION" );\r
+        break;\r
+        \r
+    case DDERR_REGIONTOOSMALL:\r
+        strcpy( errorString, "DDERR_REGIONTOOSMALL" );\r
+        break;\r
+        \r
+    case DDERR_CLIPPERISUSINGHWND:\r
+        strcpy( errorString, "DDERR_CLIPPERISUSINGHWND" );\r
+        break;\r
+        \r
+    case DDERR_NOCLIPPERATTACHED:\r
+        strcpy( errorString, "DDERR_NOCLIPPERATTACHED" );\r
+        break;\r
+        \r
+    case DDERR_NOHWND:\r
+        strcpy( errorString, "DDERR_NOHWND" );\r
+        break;\r
+        \r
+    case DDERR_HWNDSUBCLASSED:\r
+        strcpy( errorString, "DDERR_HWNDSUBCLASSED" );\r
+        break;\r
+        \r
+    case DDERR_HWNDALREADYSET:\r
+        strcpy( errorString, "DDERR_HWNDALREADYSET" );\r
+        break;\r
+        \r
+    case DDERR_NOPALETTEATTACHED:\r
+        strcpy( errorString, "DDERR_NOPALETTEATTACHED" );\r
+        break;\r
+        \r
+    case DDERR_NOPALETTEHW:\r
+        strcpy( errorString, "DDERR_NOPALETTEHW" );\r
+        break;\r
+        \r
+    case DDERR_BLTFASTCANTCLIP:\r
+         strcpy( errorString, "DDERR_BLTFASTCANTCLIP" );\r
+         break;\r
+\r
+      case DDERR_NOBLTHW:\r
+         strcpy( errorString, "DDERR_NOBLTHW" );\r
+         break;\r
+\r
+      case DDERR_NODDROPSHW:\r
+         strcpy( errorString, "DDERR_NODDROPSHW" );\r
+         break;\r
+\r
+      case DDERR_OVERLAYNOTVISIBLE:\r
+         strcpy( errorString, "DDERR_OVERLAYNOTVISIBLE" );\r
+         break;\r
+\r
+      case DDERR_NOOVERLAYDEST:\r
+         strcpy( errorString, "DDERR_NOOVERLAYDEST" );\r
+         break;\r
+\r
+      case DDERR_INVALIDPOSITION:\r
+         strcpy( errorString, "DDERR_INVALIDPOSITION" );\r
+         break;\r
+\r
+      case DDERR_NOTAOVERLAYSURFACE:\r
+         strcpy( errorString, "DDERR_NOTAOVERLAYSURFACE" );\r
+         break;\r
+\r
+      case DDERR_EXCLUSIVEMODEALREADYSET:\r
+         strcpy( errorString, "DDERR_EXCLUSIVEMODEALREADYSET" );\r
+         break;\r
+\r
+      case DDERR_NOTFLIPPABLE:\r
+         strcpy( errorString, "DDERR_NOTFLIPPABLE" );\r
+         break;\r
+\r
+      case DDERR_CANTDUPLICATE:\r
+         strcpy( errorString, "DDERR_CANTDUPLICATE" );\r
+         break;\r
+\r
+      case DDERR_NOTLOCKED:\r
+         strcpy( errorString, "DDERR_NOTLOCKED" );\r
+         break;\r
+\r
+      case DDERR_CANTCREATEDC:\r
+         strcpy( errorString, "DDERR_CANTCREATEDC" );\r
+         break;\r
+\r
+      case DDERR_NODC:\r
+         strcpy( errorString, "DDERR_NODC" );\r
+         break;\r
+\r
+      case DDERR_WRONGMODE:\r
+         strcpy( errorString, "DDERR_WRONGMODE" );\r
+         break;\r
+\r
+      case DDERR_IMPLICITLYCREATED:\r
+         strcpy( errorString, "DDERR_IMPLICITLYCREATED" );\r
+         break;\r
+\r
+      case DDERR_NOTPALETTIZED:\r
+         strcpy( errorString, "DDERR_NOTPALETTIZED" );\r
+         break;\r
+\r
+      case DDERR_UNSUPPORTEDMODE:\r
+         strcpy( errorString, "DDERR_UNSUPPORTEDMODE" );\r
+         break;\r
+\r
+      case DDERR_NOMIPMAPHW:\r
+         strcpy( errorString, "DDERR_NOMIPMAPHW" );\r
+         break;\r
+\r
+      case DDERR_INVALIDSURFACETYPE:\r
+         strcpy( errorString, "DDERR_INVALIDSURFACETYPE" );\r
+         break;\r
+\r
+      case DDERR_NOOPTIMIZEHW:\r
+         strcpy( errorString, "DDERR_NOOPTIMIZEHW" );\r
+         break;\r
+\r
+      case DDERR_NOTLOADED:\r
+         strcpy( errorString, "DDERR_NOTLOADED" );\r
+         break;\r
+\r
+      case DDERR_NOFOCUSWINDOW:\r
+         strcpy( errorString, "DDERR_NOFOCUSWINDOW" );\r
+         break;\r
+\r
+      case DDERR_DCALREADYCREATED:\r
+         strcpy( errorString, "DDERR_DCALREADYCREATED" );\r
+         break;\r
+\r
+      case DDERR_NONONLOCALVIDMEM:\r
+         strcpy( errorString, "DDERR_NONONLOCALVIDMEM" );\r
+         break;\r
+\r
+      case DDERR_CANTPAGELOCK:\r
+         strcpy( errorString, "DDERR_CANTPAGELOCK" );\r
+         break;\r
+\r
+      case DDERR_CANTPAGEUNLOCK:\r
+         strcpy( errorString, "DDERR_CANTPAGEUNLOCK" );\r
+         break;\r
+\r
+      case DDERR_NOTPAGELOCKED:\r
+         strcpy( errorString, "DDERR_NOTPAGELOCKED" );\r
+         break;\r
+\r
+      case DDERR_MOREDATA:\r
+         strcpy( errorString, "DDERR_MOREDATA" );\r
+         break;\r
+\r
+      case DDERR_EXPIRED:\r
+         strcpy( errorString, "DDERR_EXPIRED" );\r
+         break;\r
+\r
+      case DDERR_VIDEONOTACTIVE:\r
+         strcpy( errorString, "DDERR_VIDEONOTACTIVE" );\r
+         break;\r
+\r
+      case DDERR_DEVICEDOESNTOWNSURFACE:\r
+         strcpy( errorString, "DDERR_DEVICEDOESNTOWNSURFACE" );\r
+         break;\r
+\r
+      case DDERR_NOTINITIALIZED:\r
+         strcpy( errorString, "DDERR_NOTINITIALIZED" );\r
+         break;\r
+\r
+      default:\r
+         strcpy( errorString, "<unknown error code>" );\r
+         break;\r
+   }\r
+\r
+   return &errorString[0];\r
+} \r
+\1a
\ No newline at end of file
diff --git a/src/mesa/drivers/d3d/D3Dvbrender.c b/src/mesa/drivers/d3d/D3Dvbrender.c
new file mode 100644 (file)
index 0000000..57c1306
--- /dev/null
@@ -0,0 +1,2150 @@
+/*===========================================================================*/
+/*                                                                           */
+/* Mesa-3.0 DirectX 6 Driver                                                 */
+/*                                                                           */
+/* By Leigh McRae                                                            */
+/*                                                                           */
+/* http://www.altsoftware.com/                                               */
+/*                                                                           */
+/* Copyright (c) 1999-1998  alt.software inc.  All Rights Reserved           */
+/*===========================================================================*/
+#include <stdio.h>
+#include "clip.h"
+#include "context.h"
+#include "light.h"
+#include "lines.h"
+#include "macros.h"
+#include "matrix.h"
+#include "pb.h"
+#include "points.h"
+#include "types.h"
+#include "vb.h"
+#include "vbrender.h"
+#include "xform.h"
+#include "D3DMesa.h"
+
+static void SetRenderStates( GLcontext *ctx );
+static void DebugRenderStates( GLcontext *ctx, BOOL bForce );
+
+static void RenderPointsVB( GLcontext *ctx, GLuint start, GLuint end );
+static void RenderTriangleVB( GLcontext *ctx, GLuint start, GLuint end );
+static void RenderTriangleFanVB( GLcontext *ctx, GLuint start, GLuint end );
+static void RenderTriangleStripVB( GLcontext *ctx, GLuint start, GLuint end );
+static void RenderQuadVB( GLcontext *ctx, GLuint start, GLuint end );
+static void RenderQuad( GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3, GLuint v4, GLuint pv );
+void           RenderOneTriangle( GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3, GLuint pv );
+void   RenderOneLine( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv );
+
+/*  I went with a D3D vertex buffer that is 6 times that of the Mesa one */
+/* instead of having the D3D one flush when its full.  This way Mesa will*/
+/* handle all the flushing.  I need x6 as points can use 4 vertex each.  */
+D3DTLVERTEX    D3DTLVertices[ (VB_MAX*6) ];    
+GLuint                 VList[VB_SIZE];
+/*===========================================================================*/
+/* Compute Z offsets for a polygon with plane defined by (A,B,C,D)           */
+/* D is not needed. TODO: Currently we are calculating this but not using it.*/
+/*===========================================================================*/
+/* RETURN:                                                                   */
+/*===========================================================================*/
+static void OffsetPolygon( GLcontext *ctx, GLfloat a, GLfloat b, GLfloat c )
+{
+  GLfloat      ac, 
+          bc, 
+          m,
+          offset;
+
+  DPF(( DBG_FUNC, "OffsetPolygon();" ));
+
+  if ( (c < 0.001F) && (c > - 0.001F) ) 
+  {
+    /* Prevents underflow problems. */
+    ctx->PointZoffset   = 0.0F;
+    ctx->LineZoffset    = 0.0F;
+    ctx->PolygonZoffset = 0.0F;
+  }
+  else 
+  {
+    ac = a / c;
+    bc = b / c;
+    if ( ac < 0.0F )  
+        ac = -ac;
+    if ( bc<0.0F )  
+        bc = -bc;
+    m = MAX2( ac, bc );     /* m = sqrt( ac*ac + bc*bc ); */
+
+    offset = (m * ctx->Polygon.OffsetFactor + ctx->Polygon.OffsetUnits);
+    ctx->PointZoffset   = ctx->Polygon.OffsetPoint ? offset : 0.0F;
+    ctx->LineZoffset    = ctx->Polygon.OffsetLine  ? offset : 0.0F;
+    ctx->PolygonZoffset = ctx->Polygon.OffsetFill  ? offset : 0.0F;
+  }
+
+  DPF(( DBG_PRIM_INFO, "OffsetPolygon: %f", offset ));
+}
+/*===========================================================================*/
+/*  Compute signed area of the n-sided polgyon specified by vertices         */
+/* vb->Win[] and vertex list vlist[].                                        */
+/*  A clockwise polygon will return a negative area.  A counter-clockwise    */
+/* polygon will return a positive area.  I have changed this function to     */
+/* actually calculate twice the area as its faster and still gives the sign. */
+/*===========================================================================*/
+/* RETURN: signed area of the polgon.                                        */
+/*===========================================================================*/
+static GLfloat PolygonArea( const struct vertex_buffer *vb, GLuint n, const GLuint vlist[] )
+{
+  GLfloat      area;
+  GLuint  i;
+
+  DPF(( DBG_FUNC, "PolygonArea();" ));
+
+#define  j0    vlist[i]
+#define  j1    vlist[(i+1)%n]
+#define  x0    vb->Win[j0][0]
+#define  y0    vb->Win[j0][1]
+#define  x1    vb->Win[j1][0]
+#define  y1    vb->Win[j1][1]
+
+  /* area = sum of trapezoids */
+  for( i = 0, area = 0.0; i < n; i++ ) 
+    area += ((x0 - x1) * (y0 + y1));  /* Note: no divide by two here! */
+
+#undef x0
+#undef y0
+#undef x1
+#undef y1
+#undef j1
+#undef j0
+
+  // TODO: I don't see the point or * 0.5 as we just want the sign...
+  return area;
+}
+/*===========================================================================*/
+/*  Render a polygon that needs clipping on at least one vertex. The function*/
+/* will first clip the polygon to any user clipping planes then clip to the  */
+/* viewing volume.  The final polygon will be draw as single triangles that  */
+/* first need minor proccessing (culling, offset, etc) before we draw the    */
+/* polygon as a fan.  NOTE: the fan is draw as single triangles as its not   */
+/* formed sequentaly in the VB but is in the vlist[].                        */
+/*===========================================================================*/
+/* RETURN:                                                                   */
+/*===========================================================================*/
+static void RenderClippedPolygon( GLcontext *ctx, GLuint n, GLuint vlist[] )
+{
+  struct vertex_buffer *VB = ctx->VB;
+  GLfloat                      (*win)[3] = VB->Win,
+                         *proj = ctx->ProjectionMatrix,
+                         ex, ey, 
+                         fx, fy, c,
+                           wInv; 
+  GLuint                               index,
+                           pv,
+                         facing;
+
+  DPF(( DBG_FUNC, "RenderClippedPolygon();" ));
+
+  DPF(( DBG_PRIM_INFO, "RenderClippedtPolygon( %d )", n ));
+
+  /* Which vertex dictates the color when flat shading. */
+  pv = (ctx->Primitive==GL_POLYGON) ? vlist[0] : vlist[n-1];
+
+  /*  Clipping may introduce new vertices.  New vertices will be stored in */
+  /* the vertex buffer arrays starting with location VB->Free.  After we've*/
+  /* rendered the polygon, these extra vertices can be overwritten.        */
+  VB->Free = VB_MAX;
+
+  /* Clip against user clipping planes in eye coord space. */
+  if ( ctx->Transform.AnyClip ) 
+  {
+    n = gl_userclip_polygon( ctx, n, vlist );
+    if ( n < 3 )
+        return;
+
+    /* Transform vertices from eye to clip coordinates:  clip = Proj * eye */
+    for( index = 0; index < n; index++ ) 
+    {
+        TRANSFORM_POINT( VB->Clip[vlist[index]], proj, VB->Eye[vlist[index]] );
+    }
+  }
+
+  /* Clip against view volume in clip coord space */
+  n = gl_viewclip_polygon( ctx, n, vlist );
+  if ( n < 3 )
+    return;
+
+  /* Transform new vertices from clip to ndc to window coords.    */
+  /* ndc = clip / W    window = viewport_mapping(ndc)             */
+  /* Note that window Z values are scaled to the range of integer */
+  /* depth buffer values.                                         */
+
+  /* Only need to compute window coords for new vertices */
+  for( index = VB_MAX; index < VB->Free; index++ ) 
+  {
+    if ( VB->Clip[index][3] != 0.0F ) 
+    {
+        wInv = 1.0F / VB->Clip[index][3];
+
+        win[index][0] = VB->Clip[index][0] * wInv * ctx->Viewport.Sx + ctx->Viewport.Tx;
+        win[index][1] = VB->Clip[index][1] * wInv * ctx->Viewport.Sy + ctx->Viewport.Ty;
+        win[index][2] = VB->Clip[index][2] * wInv * ctx->Viewport.Sz + ctx->Viewport.Tz;
+    }
+    else 
+    {
+        /* Can't divide by zero, so... */
+        win[index][0] = win[index][1] = win[index][2] = 0.0F;
+    }
+  }
+
+  /* Draw filled polygon as a triangle fan */
+  for( index = 2; index < n; index++ ) 
+  {
+    /* Compute orientation of triangle */
+    ex = win[vlist[index-1]][0] - win[vlist[0]][0];
+    ey = win[vlist[index-1]][1] - win[vlist[0]][1];
+    fx = win[vlist[index]][0]   - win[vlist[0]][0];
+    fy = win[vlist[index]][1]   - win[vlist[0]][1];
+    c = (ex * fy) - (ey * fx);
+
+    /* polygon is perpindicular to view plane, don't draw it */
+    if ( (c == 0.0F) && !ctx->Polygon.Unfilled )
+        continue;
+
+    /* Backface culling. */
+    facing = (c < 0.0F) ^ ctx->Polygon.FrontBit;
+    if ( (facing + 1) & ctx->Polygon.CullBits )  
+        continue;
+        
+    if ( ctx->IndirectTriangles & DD_TRI_LIGHT_TWOSIDE ) 
+    {
+        if ( facing == 1 ) 
+        {
+          /* use back color */
+          VB->Color   = VB->Bcolor;
+          VB->Specular= VB->Bspec;
+        }
+        else 
+        {
+          /* use front color */
+          VB->Color   = VB->Fcolor;
+          VB->Specular= VB->Fspec;
+        }
+    }
+
+    if ( ctx->IndirectTriangles & DD_TRI_OFFSET ) 
+    {
+        /* finish computing plane equation of polygon, compute offset */
+        GLfloat fz = win[vlist[index]][2]   - win[vlist[0]][2];  
+        GLfloat ez = win[vlist[index-1]][2] - win[vlist[0]][2];
+        GLfloat a = (ey * fz) - (ez * fy);
+        GLfloat b = (ez * fx) - (ex * fz);
+        OffsetPolygon( ctx, a, b, c );
+    }
+    RenderOneTriangle( ctx, vlist[0], vlist[index-1], vlist[index], pv );
+  }
+}
+/*===========================================================================*/
+/*  This function gets called when either the vertex buffer is full or glEnd */
+/* has been called.  If the we aren't in rendering mode (FEEDBACK) then I    */
+/* pass the vertex buffer back to Mesa to deal with by returning FALSE.      */
+/*  If I can render the primitive types in the buffer directly then I will   */
+/* return TRUE after I render the vertex buffer and reset the vertex buffer. */
+/*                                                                           */
+/* TODO: I don't handle the special case of when the vertex buffer is full   */
+/*      and we have a primitive that bounds this buffer and the next one to  */
+/*      come.  I'm not sure right now if Mesa handles this for me...         */
+/*===========================================================================*/
+/* RETURN: TRUE, FALSE.                                                      */
+/*===========================================================================*/
+GLboolean RenderVertexBuffer( GLcontext *ctx, GLboolean allDone )
+{
+  struct vertex_buffer *VB = ctx->VB;
+  GLuint                               index,
+                           vlist[VB_SIZE];
+
+  DPF(( DBG_FUNC, "RenderVertexBuffer();" ));
+
+  /* We only need to hook actual tri's that need rendering. */
+  if ( ctx->RenderMode != GL_RENDER )
+  {
+          //      (ctx->Visual->AccumBits > 0) )
+          //      (ctx->Visual->StencilBits > 0) )
+    DPF(( DBG_PRIM_INFO, "Passing VB back to Mesa" ));
+    return FALSE;
+  }
+
+  /*  I'm going to set the states here so that all functions will  */
+  /* be assured to have the right states.  If Mesa's vertex bufefr */
+  /* function calls one of my primitive functions (TRI,POINT,LINE) */
+  /* it will need the right states.  So instead of doing it in the */
+  /* primitive function I will always do it here at risk of some   */
+  /* slow down to some cases...                                    */
+  SetRenderStates( ctx );
+
+  switch( ctx->Primitive ) 
+  {
+    case GL_POINTS:
+        DPF(( DBG_PRIM_INFO, "GL_POINTS( %d )", VB->Count ));
+        RenderPointsVB( ctx, 0, VB->Count );
+        break;
+
+    case GL_LINES:
+    case GL_LINE_STRIP:
+    case GL_LINE_LOOP:
+        /*  Not supported functions yet so pass back that we failed to */
+        /* render the vertex buffer and Mesa will have to do it.       */
+        DPF(( DBG_PRIM_INFO, "GL_LINE_?( %d )", VB->Count ));
+        return FALSE;
+
+    case GL_TRIANGLES:
+        if ( VB->Count < 3 )
+        {
+          DPF(( DBG_PRIM_WARN, "GL_TRIANGLES( %d )", VB->Count ));
+          return FALSE;
+        }
+
+        DPF(( DBG_PRIM_INFO, "GL_TRIANGLES( %d )", VB->Count ));
+      RenderTriangleVB( ctx, 0, VB->Count );
+        break;
+
+    case GL_TRIANGLE_STRIP:
+        if ( VB->Count < 3 )
+        {
+          DPF(( DBG_PRIM_WARN, "GL_TRIANGLE_STRIP( %d )", VB->Count ));
+          return FALSE;
+        }
+
+        DPF(( DBG_PRIM_INFO, "GL_TRIANGLE_STRIP( %d )", VB->Count ));
+        RenderTriangleStripVB( ctx, 0, VB->Count );
+        break;
+
+    case GL_TRIANGLE_FAN:
+        if ( VB->Count < 3 )
+        {
+          DPF(( DBG_PRIM_WARN, "GL_TRIANGLE_FAN( %d )", VB->Count ));
+          return FALSE;
+        }
+
+        DPF(( DBG_PRIM_INFO, "GL_TRIANGLE_FAN( %d )", VB->Count ));
+        RenderTriangleFanVB( ctx, 0, VB->Count );
+        break;
+
+    case GL_QUADS:
+        if ( VB->Count < 4 )
+        {
+          DPF(( DBG_PRIM_WARN, "GL_QUADS( %d )", VB->Count ));
+          return FALSE;
+        }
+
+         DPF(( DBG_PRIM_INFO, "GL_QUADS( %d )", VB->Count ));
+         RenderQuadVB( ctx, 0, VB->Count );
+         break;
+
+    case GL_QUAD_STRIP:
+        if ( VB->Count < 4 )
+        {
+          DPF(( DBG_PRIM_WARN, "GL_QUAD_STRIP( %d )", VB->Count ));
+          return FALSE;
+        }
+
+        DPF(( DBG_PRIM_INFO, "GL_QUAD_STRIP( %d )", VB->Count ));
+
+        if ( VB->ClipOrMask ) 
+        {
+          for( index = 3; index < VB->Count; index += 2 ) 
+          {
+               if ( VB->ClipMask[index-3] & VB->ClipMask[index-2] & VB->ClipMask[index-1] & VB->ClipMask[index] & CLIP_ALL_BITS ) 
+               {
+                  /* All points clipped by common plane */
+                 DPF(( DBG_PRIM_WARN, "GL_QUAD_STRIP( %d )", VB->Count ));
+                 continue;
+               }
+               else if ( VB->ClipMask[index-3] | VB->ClipMask[index-2] | VB->ClipMask[index-1] | VB->ClipMask[index] ) 
+               {
+                 vlist[0] = index - 3;
+                 vlist[1] = index - 2;
+                 vlist[2] = index;
+                 vlist[3] = index - 1;
+                 RenderClippedPolygon( ctx, 4, vlist );
+               }
+               else 
+               {
+                 RenderQuad( ctx, (index-3), (index-2), index, (index-1), index );
+               }       
+          }
+        }
+        else 
+        {
+          /* No clipping needed */
+          for( index = 3; index < VB->Count; index += 2 ) 
+               RenderQuad( ctx, (index-3), (index-2), index, (index-1), index );
+        }      
+        break;
+          
+    case GL_POLYGON:
+        if ( VB->Count < 3 ) 
+        {
+          DPF(( DBG_PRIM_WARN, "GL_POLYGON( %d )", VB->Count ));
+          return FALSE;
+        }
+
+        DPF(( DBG_PRIM_INFO, "GL_POLYGON( %d )", VB->Count ));
+
+        /* All points clipped by common plane, draw nothing */
+        if ( !(VB->ClipAndMask & CLIP_ALL_BITS) ) 
+          RenderTriangleFanVB( ctx, 0, VB->Count );
+        break;
+
+    default:
+        /* should never get here */
+        gl_problem( ctx, "invalid mode in gl_render_vb" );
+   }
+  DPF(( DBG_PRIM_INFO, "ResetVB" ));
+
+  /* We return TRUE to indicate we rendered the VB. */
+  gl_reset_vb( ctx, allDone );
+  return TRUE;
+}
+/*===========================================================================*/
+/*  This function will render the current vertex buffer as triangles.  The   */
+/* buffer has to be able to be rendered directly.  This means that we are    */
+/* filled, no offsets, no culling and one sided rendering.  Also we must be  */
+/* in render mode of course.                                                 */
+/*  First I will fill the global D3D vertice buffer.  Next I will set all the*/
+/* states for D3D based on the current OGL state.  Finally I pass the D3D VB */
+/* to the wrapper that call DrawPrimitives.                                  */
+/*===========================================================================*/
+/* RETURN:                                                                   */
+/*===========================================================================*/
+static void RenderTriangleVB( GLcontext *ctx, GLuint start, GLuint end )
+{
+  D3DMESACONTEXT       *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
+  struct vertex_buffer         *VB = ctx->VB;
+  int                    index,
+                         cVertex,
+                         height = (pContext->pShared->rectW.bottom - pContext->pShared->rectW.top);
+   DWORD                       dwPVColor;
+   GLfloat                     ex, ey, 
+                         fx, fy, c;
+   GLuint                      facing;
+
+   DPF(( DBG_FUNC, "RenderTriangleVB" ));
+
+   if ( (!(ctx->IndirectTriangles & DD_SW_SETUP)) && !VB->ClipOrMask )
+   {
+       DPF(( DBG_PRIM_INFO, "DirectTriangles( %d )", (end-start) ));
+       for( index = start, cVertex = 0; index < end; )
+       {
+         dwPVColor = (VB->Color[(index+2)][3]<<24) | (VB->Color[(index+2)][0]<<16) | (VB->Color[(index+2)][1]<<8) | VB->Color[(index+2)][2];
+   
+         /*=====================================*/
+         /* Populate the the triangle vertices. */
+         /*=====================================*/
+         D3DTLVertices[cVertex].sx     = D3DVAL( VB->Win[index][0] );
+         D3DTLVertices[cVertex].sy     = D3DVAL( (height - VB->Win[index][1]) );
+         D3DTLVertices[cVertex].sz     = D3DVAL( VB->Win[index][2] );
+         D3DTLVertices[cVertex].tu     = D3DVAL( VB->TexCoord[index][0] );
+         D3DTLVertices[cVertex].tv     = D3DVAL( VB->TexCoord[index][1] );
+         D3DTLVertices[cVertex].rhw    = D3DVAL( (1.0 / VB->Clip[index][3]) );
+         D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
+                                         dwPVColor :
+                                       (VB->Color[index][3]<<24) | (VB->Color[index][0]<<16) | (VB->Color[index][1]<<8) | VB->Color[index][2];
+         index++;
+   
+         D3DTLVertices[cVertex].sx     = D3DVAL( VB->Win[index][0] );
+         D3DTLVertices[cVertex].sy     = D3DVAL( (height - VB->Win[index][1]) );
+         D3DTLVertices[cVertex].sz     = D3DVAL( VB->Win[index][2] );
+         D3DTLVertices[cVertex].tu     = D3DVAL( VB->TexCoord[index][0] );
+         D3DTLVertices[cVertex].tv     = D3DVAL( VB->TexCoord[index][1] );
+         D3DTLVertices[cVertex].rhw    = D3DVAL( (1.0 / VB->Clip[index][3]) );
+         D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
+                                       dwPVColor :
+                                       (VB->Color[index][3]<<24) | (VB->Color[index][0]<<16) | (VB->Color[index][1]<<8) | VB->Color[index][2];
+         index++;
+      
+         D3DTLVertices[cVertex].sx     = D3DVAL( VB->Win[index][0] );
+         D3DTLVertices[cVertex].sy     = D3DVAL( (height - VB->Win[index][1]) );
+         D3DTLVertices[cVertex].sz     = D3DVAL( VB->Win[index][2] );
+         D3DTLVertices[cVertex].tu     = D3DVAL( VB->TexCoord[index][0] );
+         D3DTLVertices[cVertex].tv     = D3DVAL( VB->TexCoord[index][1] );
+         D3DTLVertices[cVertex].rhw    = D3DVAL( (1.0 / VB->Clip[index][3]) );
+         D3DTLVertices[cVertex++].color= dwPVColor;
+         index++;
+       }
+   }
+   else
+   {
+#define v1     index
+#define v2     (index+1)
+#define v3     (index+2)
+
+       for( index = start, cVertex = 0; index < end; index += 3 )
+       {
+         if ( VB->ClipMask[v1] & VB->ClipMask[v2] & VB->ClipMask[v3] & CLIP_ALL_BITS ) 
+         {
+           continue;
+         }
+         else if ( VB->ClipMask[v1] | VB->ClipMask[v2] | VB->ClipMask[v3] ) 
+         {
+           VList[0] = v1;
+           VList[1] = v2;
+           VList[2] = v3;
+           RenderClippedPolygon( ctx, 3, VList );
+           continue;
+         }
+
+         /* Compute orientation of triangle */
+         ex = VB->Win[v2][0] - VB->Win[v1][0];
+         ey = VB->Win[v2][1] - VB->Win[v1][1];
+         fx = VB->Win[v3][0] - VB->Win[v1][0];
+         fy = VB->Win[v3][1] - VB->Win[v1][1];
+         c = (ex * fy) - (ey * fx);
+
+         /* polygon is perpindicular to view plane, don't draw it */
+         if ( (c == 0.0F) && !ctx->Polygon.Unfilled )
+           continue;
+
+         /* Backface culling. */
+         facing = (c < 0.0F) ^ ctx->Polygon.FrontBit;
+         if ( (facing + 1) & ctx->Polygon.CullBits )  
+           continue;
+
+         if ( ctx->IndirectTriangles & DD_TRI_LIGHT_TWOSIDE ) 
+         {
+           if ( facing == 1 ) 
+           {
+                /* use back color */
+                VB->Color   = VB->Bcolor;
+                VB->Specular= VB->Bspec;
+           }
+           else 
+           {
+                /* use front color */
+                VB->Color   = VB->Fcolor;
+                VB->Specular= VB->Fspec;
+           }
+         }
+
+         if ( ctx->IndirectTriangles & DD_TRI_OFFSET ) 
+         {
+           /* Finish computing plane equation of polygon, compute offset */
+           GLfloat fz = VB->Win[v3][2] - VB->Win[v1][2];  
+           GLfloat ez = VB->Win[v2][2] - VB->Win[v1][2];
+           GLfloat a = (ey * fz) - (ez * fy);
+           GLfloat b = (ez * fx) - (ex * fz);
+           OffsetPolygon( ctx, a, b, c );
+         }
+
+         /*=====================================*/
+         /* Populate the the triangle vertices. */
+         /*=====================================*/
+         /* Solve the prevoking vertex color as we need it for the 3rd triangle and flat shading. */
+         dwPVColor = (VB->Color[v3][3]<<24) | (VB->Color[v3][0]<<16) | (VB->Color[v3][1]<<8) | VB->Color[v3][2];
+   
+         D3DTLVertices[cVertex].sx     = D3DVAL( VB->Win[v1][0] );
+         D3DTLVertices[cVertex].sy     = D3DVAL( (height - VB->Win[v1][1]) );
+         D3DTLVertices[cVertex].sz     = D3DVAL( (VB->Win[v1][2] + ctx->PolygonZoffset) );
+         D3DTLVertices[cVertex].tu     = D3DVAL( VB->TexCoord[v1][0] );
+         D3DTLVertices[cVertex].tv     = D3DVAL( VB->TexCoord[v1][1] );
+         D3DTLVertices[cVertex].rhw    = D3DVAL( (1.0 / VB->Clip[v1][3]) );
+         D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
+                                       dwPVColor :
+                                       (VB->Color[v1][3]<<24) | (VB->Color[v1][0]<<16) | (VB->Color[v1][1]<<8) | VB->Color[v1][2];
+   
+         D3DTLVertices[cVertex].sx     = D3DVAL( VB->Win[v2][0] );
+         D3DTLVertices[cVertex].sy     = D3DVAL( (height - VB->Win[v2][1]) );
+         D3DTLVertices[cVertex].sz     = D3DVAL( (VB->Win[v2][2] + ctx->PolygonZoffset) );
+         D3DTLVertices[cVertex].tu     = D3DVAL( VB->TexCoord[v2][0] );
+         D3DTLVertices[cVertex].tv     = D3DVAL( VB->TexCoord[v2][1] );
+         D3DTLVertices[cVertex].rhw    = D3DVAL( (1.0 / VB->Clip[v2][3]) );
+         D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
+                                       dwPVColor :
+                                       (VB->Color[v2][3]<<24) | (VB->Color[v2][0]<<16) | (VB->Color[v2][1]<<8) | VB->Color[v2][2];
+      
+         D3DTLVertices[cVertex].sx     = D3DVAL( VB->Win[v3][0] );
+         D3DTLVertices[cVertex].sy     = D3DVAL( (height - VB->Win[v3][1]) );
+         D3DTLVertices[cVertex].sz     = D3DVAL( (VB->Win[v3][2] + ctx->PolygonZoffset) );
+         D3DTLVertices[cVertex].tu     = D3DVAL( VB->TexCoord[v3][0] );
+         D3DTLVertices[cVertex].tv     = D3DVAL( VB->TexCoord[v3][1] );
+         D3DTLVertices[cVertex].rhw    = D3DVAL( (1.0 / VB->Clip[v3][3]) );
+         D3DTLVertices[cVertex++].color= dwPVColor;
+       }
+#undef v1
+#undef v2
+#undef v3
+   }    
+
+   /* Render the converted vertex buffer. */  
+   if ( cVertex > 2 )
+       DrawPrimitiveHAL( pContext->pShared, D3DPT_TRIANGLELIST, &D3DTLVertices[0], cVertex );
+}
+/*===========================================================================*/
+/*  This function will render the current vertex buffer as a triangle fan.   */
+/* The buffer has to be able to be rendered directly.  This means that we are*/
+/* filled, no offsets, no culling and one sided rendering.  Also we must be  */
+/* in render mode of course.                                                 */
+/*  First I will fill the global D3D vertice buffer.  Next I will set all the*/
+/* states for D3D based on the current OGL state.  Finally I pass the D3D VB */
+/* to the wrapper that call DrawPrimitives.                                  */
+/*===========================================================================*/
+/* RETURN:                                                                   */
+/*===========================================================================*/
+static void RenderTriangleFanVB( GLcontext *ctx, GLuint start, GLuint end )
+{
+  D3DMESACONTEXT       *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
+  struct vertex_buffer         *VB = ctx->VB;
+  int                          index,
+                         cVertex,
+                         height = (pContext->pShared->rectW.bottom - pContext->pShared->rectW.top);
+   GLfloat                     ex, ey, 
+                         fx, fy, c;
+   GLuint                      facing;
+   DWORD                       dwPVColor;
+
+   DPF(( DBG_FUNC, "RenderTriangleFanVB();" ));
+
+   /* Special case that we can blast the fan without culling, offset, etc... */
+   if ( (!(ctx->IndirectTriangles & DD_SW_SETUP)) && !VB->ClipOrMask && (ctx->Light.ShadeModel != GL_FLAT) )
+   {
+       DPF(( DBG_PRIM_INFO, "DirectTriangles( %d )", (end-start) ));
+
+       /* Seed the the fan. */
+       D3DTLVertices[0].sx   = D3DVAL( VB->Win[start][0] );
+       D3DTLVertices[0].sy   = D3DVAL( (height - VB->Win[start][1]) );
+       D3DTLVertices[0].sz   = D3DVAL( VB->Win[start][2] );
+       D3DTLVertices[0].tu   = D3DVAL( VB->TexCoord[start][0] );
+       D3DTLVertices[0].tv   = D3DVAL( VB->TexCoord[start][1] );
+       D3DTLVertices[0].rhw  = D3DVAL( (1.0 / VB->Clip[start][3]) );
+       D3DTLVertices[0].color= (VB->Color[start][3]<<24) | (VB->Color[start][0]<<16) | (VB->Color[start][1]<<8) | VB->Color[start][2];
+   
+       /* Seed the the fan. */
+       D3DTLVertices[1].sx   = D3DVAL( VB->Win[(start+1)][0] );
+       D3DTLVertices[1].sy   = D3DVAL( (height - VB->Win[(start+1)][1]) );
+       D3DTLVertices[1].sz   = D3DVAL( VB->Win[(start+1)][2] );
+       D3DTLVertices[1].tu   = D3DVAL( VB->TexCoord[(start+1)][0] );
+       D3DTLVertices[1].tv   = D3DVAL( VB->TexCoord[(start+1)][1] );
+       D3DTLVertices[1].rhw  = D3DVAL( (1.0 / VB->Clip[(start+1)][3]) );
+       D3DTLVertices[1].color= (VB->Color[(start+1)][3]<<24) | (VB->Color[(start+1)][0]<<16) | (VB->Color[(start+1)][1]<<8) | VB->Color[(start+1)][2];
+   
+       for( index = (start+2), cVertex = 2; index < end; index++, cVertex++ )
+       {
+         /*=================================*/
+         /* Add the next vertex to the fan. */
+         /*=================================*/
+         D3DTLVertices[cVertex].sx     = D3DVAL( VB->Win[index][0] );
+         D3DTLVertices[cVertex].sy     = D3DVAL( (height - VB->Win[index][1]) );
+         D3DTLVertices[cVertex].sz     = D3DVAL( VB->Win[index][2] );
+         D3DTLVertices[cVertex].tu     = D3DVAL( VB->TexCoord[index][0] );
+         D3DTLVertices[cVertex].tv     = D3DVAL( VB->TexCoord[index][1] );
+         D3DTLVertices[cVertex].rhw    = D3DVAL( (1.0 / VB->Clip[index][3]) );
+         D3DTLVertices[cVertex].color  = (VB->Color[index][3]<<24) | (VB->Color[index][0]<<16) | (VB->Color[index][1]<<8) | VB->Color[index][2];
+      }
+
+       /* Render the converted vertex buffer. */  
+       if ( cVertex )
+         DrawPrimitiveHAL( pContext->pShared, D3DPT_TRIANGLEFAN, &D3DTLVertices[0], cVertex );
+   }
+   else
+   {
+#define v1     start
+#define v2     (index-1)
+#define v3     index
+
+       for( index = (start+2), cVertex = 0; index < end; index++ )
+       {
+         if ( VB->ClipOrMask ) 
+         {
+           /* All points clipped by common plane */
+           if ( VB->ClipMask[v1] & VB->ClipMask[v2] & VB->ClipMask[v3] & CLIP_ALL_BITS ) 
+           {
+                continue;
+           }
+           else if ( VB->ClipMask[v1] | VB->ClipMask[v2] | VB->ClipMask[v3] ) 
+           {
+                VList[0] = v1;
+                VList[1] = v2;
+                VList[2] = v3;
+                RenderClippedPolygon( ctx, 3, VList );
+                continue;
+           }
+         }
+
+         /* Compute orientation of triangle */
+         ex = VB->Win[v2][0] - VB->Win[v1][0];
+         ey = VB->Win[v2][1] - VB->Win[v1][1];
+         fx = VB->Win[v3][0] - VB->Win[v1][0];
+         fy = VB->Win[v3][1] - VB->Win[v1][1];
+         c = (ex * fy) - (ey * fx);
+   
+         /* polygon is perpindicular to view plane, don't draw it */
+         if ( (c == 0.0F) && !ctx->Polygon.Unfilled )
+           continue;
+
+         /* Backface culling. */
+         facing = (c < 0.0F) ^ ctx->Polygon.FrontBit;
+         if ( (facing + 1) & ctx->Polygon.CullBits )  
+           continue;
+   
+         if ( ctx->IndirectTriangles & DD_TRI_OFFSET ) 
+         {
+           /* Finish computing plane equation of polygon, compute offset */
+           GLfloat fz = VB->Win[v3][2] - VB->Win[v1][2];  
+           GLfloat ez = VB->Win[v2][2] - VB->Win[v1][2];
+           GLfloat a = (ey * fz) - (ez * fy);
+           GLfloat b = (ez * fx) - (ex * fz);
+           OffsetPolygon( ctx, a, b, c );
+         }
+
+         /*=====================================*/
+         /* Populate the the triangle vertices. */
+         /*=====================================*/
+         dwPVColor = (VB->Color[v3][3]<<24) | (VB->Color[v3][0]<<16) | (VB->Color[v3][1]<<8) | VB->Color[v3][2];
+
+         D3DTLVertices[cVertex].sx     = D3DVAL( VB->Win[v1][0] );
+         D3DTLVertices[cVertex].sy     = D3DVAL( (height - VB->Win[v1][1]) );
+         D3DTLVertices[cVertex].sz     = D3DVAL( (VB->Win[v1][2] + ctx->PolygonZoffset) );
+         D3DTLVertices[cVertex].tu     = D3DVAL( VB->TexCoord[v1][0] );
+         D3DTLVertices[cVertex].tv     = D3DVAL( VB->TexCoord[v1][1] );
+         D3DTLVertices[cVertex].rhw    = D3DVAL( (1.0 / VB->Clip[v1][3]) );
+         D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ? dwPVColor :
+                                         (VB->Color[v1][3]<<24) | (VB->Color[v1][0]<<16) | (VB->Color[v1][1]<<8) | VB->Color[v1][2];
+      
+         D3DTLVertices[cVertex].sx     = D3DVAL( VB->Win[v2][0] );
+         D3DTLVertices[cVertex].sy     = D3DVAL( (height - VB->Win[v2][1]) );
+         D3DTLVertices[cVertex].sz     = D3DVAL( (VB->Win[v2][2] + ctx->PolygonZoffset)  );
+         D3DTLVertices[cVertex].tu     = D3DVAL( VB->TexCoord[v2][0] );
+         D3DTLVertices[cVertex].tv     = D3DVAL( VB->TexCoord[v2][1] );
+         D3DTLVertices[cVertex].rhw    = D3DVAL( (1.0 / VB->Clip[v2][3]) );
+         D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ? dwPVColor :
+                                         (VB->Color[v2][3]<<24) | (VB->Color[v2][0]<<16) | (VB->Color[v2][1]<<8) | VB->Color[v2][2];
+         
+         D3DTLVertices[cVertex].sx     = D3DVAL( VB->Win[v3][0] );
+         D3DTLVertices[cVertex].sy     = D3DVAL( (height - VB->Win[v3][1]) );
+         D3DTLVertices[cVertex].sz     = D3DVAL( (VB->Win[v3][2] + ctx->PolygonZoffset) );
+         D3DTLVertices[cVertex].tu     = D3DVAL( VB->TexCoord[v3][0] );
+         D3DTLVertices[cVertex].tv     = D3DVAL( VB->TexCoord[v3][1] );
+         D3DTLVertices[cVertex].rhw    = D3DVAL( (1.0 / VB->Clip[v3][3]) );
+         D3DTLVertices[cVertex++].color= dwPVColor;
+       }
+
+       /* Render the converted vertex buffer. */  
+       if ( cVertex )
+         DrawPrimitiveHAL( pContext->pShared, D3DPT_TRIANGLELIST, &D3DTLVertices[0], cVertex );
+#undef v1
+#undef v2
+#undef v3
+   }
+}
+/*===========================================================================*/
+/*  This function will render the current vertex buffer as a triangle strip. */
+/* The buffer has to be able to be rendered directly.  This means that we are*/
+/* filled, no offsets, no culling and one sided rendering.  Also we must be  */
+/* in render mode of course.                                                 */
+/*  First I will fill the global D3D vertice buffer.  Next I will set all the*/
+/* states for D3D based on the current OGL state.  Finally I pass the D3D VB */
+/* to the wrapper that call DrawPrimitives.                                  */
+/*===========================================================================*/
+/* RETURN:                                                                   */
+/*===========================================================================*/
+static void RenderTriangleStripVB( GLcontext *ctx, GLuint start, GLuint end )
+{
+  D3DMESACONTEXT       *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
+  struct vertex_buffer         *VB = ctx->VB;
+  int                    index,
+                         cVertex = 0,
+                           v1, v2, v3,
+                         height = (pContext->pShared->rectW.bottom - pContext->pShared->rectW.top);
+  GLfloat                      ex, ey, 
+                         fx, fy, c;
+  GLuint                       facing;
+  DWORD                        dwPVColor;
+
+  DPF(( DBG_FUNC, "RenderTriangleStripVB();" ));
+
+  /* Special case that we can blast the fan without culling, offset, etc... */
+  if ( (!(ctx->IndirectTriangles & DD_SW_SETUP)) && !VB->ClipOrMask && (ctx->Light.ShadeModel != GL_FLAT) )
+  {
+    DPF(( DBG_PRIM_PROFILE, "DirectTriangles" ));
+
+    /* Seed the the strip. */
+    D3DTLVertices[0].sx   = D3DVAL( VB->Win[start][0] );
+    D3DTLVertices[0].sy   = D3DVAL( (height - VB->Win[start][1]) );
+    D3DTLVertices[0].sz   = D3DVAL( VB->Win[start][2] );
+    D3DTLVertices[0].tu   = D3DVAL( VB->TexCoord[start][0] );
+    D3DTLVertices[0].tv   = D3DVAL( VB->TexCoord[start][1] );
+    D3DTLVertices[0].rhw  = D3DVAL( (1.0 / VB->Clip[start][3]) );
+    D3DTLVertices[0].color= (VB->Color[start][3]<<24) | (VB->Color[start][0]<<16) | (VB->Color[start][1]<<8) | VB->Color[start][2];
+
+    /* Seed the the strip. */
+    D3DTLVertices[1].sx   = D3DVAL( VB->Win[(start+1)][0] );
+    D3DTLVertices[1].sy   = D3DVAL( (height - VB->Win[(start+1)][1]) );
+    D3DTLVertices[1].sz   = D3DVAL( VB->Win[(start+1)][2] );
+    D3DTLVertices[1].tu   = D3DVAL( VB->TexCoord[(start+1)][0] );
+    D3DTLVertices[1].tv   = D3DVAL( VB->TexCoord[(start+1)][1] );
+    D3DTLVertices[1].rhw  = D3DVAL( (1.0 / VB->Clip[(start+1)][3]) );
+    D3DTLVertices[1].color= (VB->Color[(start+1)][3]<<24) | (VB->Color[(start+1)][0]<<16) | (VB->Color[(start+1)][1]<<8) | VB->Color[(start+1)][2];
+   
+    for( index = (start+2), cVertex = 2; index < end; index++, cVertex++ )
+    {
+        /*===================================*/
+        /* Add the next vertex to the strip. */
+        /*===================================*/
+        D3DTLVertices[cVertex].sx     = D3DVAL( VB->Win[index][0] );
+        D3DTLVertices[cVertex].sy     = D3DVAL( (height - VB->Win[index][1]) );
+        D3DTLVertices[cVertex].sz     = D3DVAL( VB->Win[index][2] );
+        D3DTLVertices[cVertex].tu     = D3DVAL( VB->TexCoord[index][0] );
+        D3DTLVertices[cVertex].tv     = D3DVAL( VB->TexCoord[index][1] );
+        D3DTLVertices[cVertex].rhw    = D3DVAL( (1.0 / VB->Clip[index][3]) );
+        D3DTLVertices[cVertex].color  = (VB->Color[index][3]<<24) | (VB->Color[index][0]<<16) | (VB->Color[index][1]<<8) | VB->Color[index][2];
+    }
+
+    /* Render the converted vertex buffer. */  
+    if ( cVertex )
+        DrawPrimitiveHAL( pContext->pShared, D3DPT_TRIANGLESTRIP, &D3DTLVertices[0], cVertex );
+  }
+  else
+  {
+    for( index = (start+2); index < end; index++ ) 
+    {
+        /* We need to switch order so that winding won't be a problem. */
+        if ( index & 1 )
+        {
+          v1 = index - 1;
+          v2 = index - 2;
+          v3 = index - 0;
+        }
+        else
+        {
+          v1 = index - 2;
+          v2 = index - 1;
+          v3 = index - 0;
+        }
+
+        /* All vertices clipped by common plane */
+        if ( VB->ClipMask[v1] & VB->ClipMask[v2] & VB->ClipMask[v3] & CLIP_ALL_BITS ) 
+          continue;
+
+        /* Check if any vertices need clipping. */
+        if ( VB->ClipMask[v1] | VB->ClipMask[v2] | VB->ClipMask[v3] ) 
+        {
+          VList[0] = v1;
+          VList[1] = v2;
+          VList[2] = v3;
+          RenderClippedPolygon( ctx, 3, VList );
+        }
+        else 
+        {
+          /* Compute orientation of triangle */
+          ex = VB->Win[v2][0] - VB->Win[v1][0];
+          ey = VB->Win[v2][1] - VB->Win[v1][1];
+          fx = VB->Win[v3][0] - VB->Win[v1][0];
+          fy = VB->Win[v3][1] - VB->Win[v1][1];
+          c = (ex * fy) - (ey * fx);
+
+          /* Polygon is perpindicular to view plane, don't draw it */
+          if ( (c == 0.0F) && !ctx->Polygon.Unfilled )
+               continue;
+
+          /* Backface culling. */
+          facing = (c < 0.0F) ^ ctx->Polygon.FrontBit;
+          if ( (facing + 1) & ctx->Polygon.CullBits )  
+               continue;
+
+          /* Need right color if we have two sided lighting. */
+          if ( ctx->IndirectTriangles & DD_TRI_LIGHT_TWOSIDE ) 
+          {
+               if ( facing == 1 ) 
+               {
+                 /* use back color */
+                 VB->Color   = VB->Bcolor;
+                 VB->Specular= VB->Bspec;
+               }
+               else 
+               {
+                 /* use front color */
+                 VB->Color   = VB->Fcolor;
+                 VB->Specular= VB->Fspec;
+               }
+          }
+
+          if ( ctx->IndirectTriangles & DD_TRI_OFFSET ) 
+          {
+               /* Finish computing plane equation of polygon, compute offset */
+               GLfloat fz = VB->Win[v3][2] - VB->Win[v1][2];  
+               GLfloat ez = VB->Win[v2][2] - VB->Win[v1][2];
+               GLfloat a = (ey * fz) - (ez * fy);
+               GLfloat b = (ez * fx) - (ex * fz);
+               OffsetPolygon( ctx, a, b, c );
+          }
+          /*=====================================*/
+          /* Populate the the triangle vertices. */
+          /*=====================================*/
+
+          /* Solve the prevoking vertex color as we need it for the 3rd triangle and flat shading. */
+          dwPVColor = (VB->Color[v3][3]<<24) | (VB->Color[v3][0]<<16) | (VB->Color[v3][1]<<8) | VB->Color[v3][2];
+   
+          D3DTLVertices[cVertex].sx     = D3DVAL( VB->Win[v1][0] );
+          D3DTLVertices[cVertex].sy     = D3DVAL( (height - VB->Win[v1][1]) );
+          D3DTLVertices[cVertex].sz     = D3DVAL( (VB->Win[v1][2] + ctx->PolygonZoffset) );
+          D3DTLVertices[cVertex].tu     = D3DVAL( VB->TexCoord[v1][0] );
+          D3DTLVertices[cVertex].tv     = D3DVAL( VB->TexCoord[v1][1] );
+          D3DTLVertices[cVertex].rhw    = D3DVAL( (1.0 / VB->Clip[v1][3]) );
+          D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
+                                        dwPVColor :
+                                        (VB->Color[v1][3]<<24) | (VB->Color[v1][0]<<16) | (VB->Color[v1][1]<<8) | VB->Color[v1][2];
+   
+          D3DTLVertices[cVertex].sx     = D3DVAL( VB->Win[v2][0] );
+          D3DTLVertices[cVertex].sy     = D3DVAL( (height - VB->Win[v2][1]) );
+          D3DTLVertices[cVertex].sz     = D3DVAL( (VB->Win[v2][2] + ctx->PolygonZoffset) );
+          D3DTLVertices[cVertex].tu     = D3DVAL( VB->TexCoord[v2][0] );
+          D3DTLVertices[cVertex].tv     = D3DVAL( VB->TexCoord[v2][1] );
+          D3DTLVertices[cVertex].rhw    = D3DVAL( (1.0 / VB->Clip[v2][3]) );
+          D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
+                                          dwPVColor :
+                                          (VB->Color[v2][3]<<24) | (VB->Color[v2][0]<<16) | (VB->Color[v2][1]<<8) | VB->Color[v2][2];
+      
+          D3DTLVertices[cVertex].sx     = D3DVAL( VB->Win[v3][0] );
+          D3DTLVertices[cVertex].sy     = D3DVAL( (height - VB->Win[v3][1]) );
+          D3DTLVertices[cVertex].sz     = D3DVAL( (VB->Win[v3][2] + ctx->PolygonZoffset) );
+          D3DTLVertices[cVertex].tu     = D3DVAL( VB->TexCoord[v3][0] );
+          D3DTLVertices[cVertex].tv     = D3DVAL( VB->TexCoord[v3][1] );
+          D3DTLVertices[cVertex].rhw    = D3DVAL( (1.0 / VB->Clip[v3][3]) );
+          D3DTLVertices[cVertex++].color= dwPVColor;
+        }
+    }
+
+    /* Render the converted vertex buffer. */  
+    if ( cVertex )     
+        DrawPrimitiveHAL( pContext->pShared, D3DPT_TRIANGLELIST, &D3DTLVertices[0], cVertex );
+  }    
+}
+/*===========================================================================*/
+/*  This function will render the current vertex buffer as Quads.  The buffer*/
+/* has to be able to be rendered directly.  This means that we are filled, no*/
+/* offsets, no culling and one sided rendering.  Also we must be in render   */
+/* mode of cource.                                                           */
+/*  First I will fill the global D3D vertice buffer.  Next I will set all the*/
+/* states for D3D based on the current OGL state.  Finally I pass the D3D VB */
+/* to the wrapper that call DrawPrimitives.                                  */
+/*===========================================================================*/
+/* RETURN:                                                                   */
+/*===========================================================================*/
+static void RenderQuadVB( GLcontext *ctx, GLuint start, GLuint end )
+{
+  D3DMESACONTEXT               *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
+  struct vertex_buffer *VB = ctx->VB;
+  int                          index,
+                         cVertex,
+                         height = (pContext->pShared->rectW.bottom - pContext->pShared->rectW.top);
+  DWORD                        dwPVColor;
+  GLfloat              ex, ey, 
+                         fx, fy, c;
+  GLuint                               facing;  /* 0=front, 1=back */
+
+  DPF(( DBG_FUNC, "RenderQuadVB();" ));
+
+#define  v1 (index)
+#define  v2 (index+1)
+#define  v3 (index+2)
+#define  v4 (index+3)
+
+  if ( (!(ctx->IndirectTriangles & DD_SW_SETUP)) && !VB->ClipOrMask )
+  {
+    DPF(( DBG_PRIM_PROFILE, "DirectTriangles" ));
+
+    for( cVertex = 0, index = start; index < end; index += 4 )
+    {
+        if ( ctx->Light.ShadeModel == GL_FLAT )
+          dwPVColor = (VB->Color[v4][3]<<24) | (VB->Color[v4][0]<<16) | (VB->Color[v4][1]<<8) | VB->Color[v4][2];
+   
+        /*=====================================*/
+        /* Populate the the triangle vertices. */
+        /*=====================================*/
+        D3DTLVertices[cVertex].sx     = D3DVAL( VB->Win[v1][0] );
+        D3DTLVertices[cVertex].sy     = D3DVAL( (height - VB->Win[v1][1]) );
+        D3DTLVertices[cVertex].sz     = D3DVAL( VB->Win[v1][2] );
+        D3DTLVertices[cVertex].tu     = D3DVAL( VB->TexCoord[v1][0] );
+        D3DTLVertices[cVertex].tv     = D3DVAL( VB->TexCoord[v1][1] );
+        D3DTLVertices[cVertex].rhw    = D3DVAL( (1.0 / VB->Clip[v1][3]) );
+        D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ? 
+                                      dwPVColor :
+                                        (VB->Color[v1][3]<<24) | (VB->Color[v1][0]<<16) | (VB->Color[v1][1]<<8) | VB->Color[v1][2];
+   
+        D3DTLVertices[cVertex].sx     = D3DVAL( VB->Win[v2][0] );
+        D3DTLVertices[cVertex].sy     = D3DVAL( (height - VB->Win[v2][1]) );
+        D3DTLVertices[cVertex].sz     = D3DVAL( VB->Win[v2][2] );
+        D3DTLVertices[cVertex].tu     = D3DVAL( VB->TexCoord[v2][0] );
+        D3DTLVertices[cVertex].tv     = D3DVAL( VB->TexCoord[v2][1] );
+        D3DTLVertices[cVertex].rhw    = D3DVAL( (1.0 / VB->Clip[v2][3]) );
+        D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ? 
+                                      dwPVColor :
+                                      (VB->Color[v2][3]<<24) | (VB->Color[v2][0]<<16) | (VB->Color[v2][1]<<8) | VB->Color[v2][2];
+      
+        D3DTLVertices[cVertex].sx     = D3DVAL( VB->Win[v3][0] );
+        D3DTLVertices[cVertex].sy     = D3DVAL( (height - VB->Win[v3][1]) );
+        D3DTLVertices[cVertex].sz     = D3DVAL( VB->Win[v3][2] );
+        D3DTLVertices[cVertex].tu     = D3DVAL( VB->TexCoord[v3][0] );
+        D3DTLVertices[cVertex].tv     = D3DVAL( VB->TexCoord[v3][1] );
+        D3DTLVertices[cVertex].rhw    = D3DVAL( (1.0 / VB->Clip[v3][3]) );
+        D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ? 
+                                        dwPVColor :
+                                      (VB->Color[v3][3]<<24) | (VB->Color[v3][0]<<16) | (VB->Color[v3][1]<<8) | VB->Color[v3][2];
+   
+        D3DTLVertices[cVertex].sx     = D3DVAL( VB->Win[v1][0] );
+        D3DTLVertices[cVertex].sy     = D3DVAL( (height - VB->Win[v1][1]) );
+        D3DTLVertices[cVertex].sz     = D3DVAL( VB->Win[v1][2] );
+        D3DTLVertices[cVertex].tu     = D3DVAL( VB->TexCoord[v1][0] );
+        D3DTLVertices[cVertex].tv     = D3DVAL( VB->TexCoord[v1][1] );
+        D3DTLVertices[cVertex].rhw    = D3DVAL( (1.0 / VB->Clip[v1][3]) );
+        D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ? 
+                                        dwPVColor :
+                                      (VB->Color[v1][3]<<24) | (VB->Color[v1][0]<<16) | (VB->Color[v1][1]<<8) | VB->Color[v1][2];
+   
+        D3DTLVertices[cVertex].sx     = D3DVAL( VB->Win[v3][0] );
+        D3DTLVertices[cVertex].sy     = D3DVAL( (height - VB->Win[v3][1]) );
+        D3DTLVertices[cVertex].sz     = D3DVAL( VB->Win[v3][2] );
+        D3DTLVertices[cVertex].tu     = D3DVAL( VB->TexCoord[v3][0] );
+        D3DTLVertices[cVertex].tv     = D3DVAL( VB->TexCoord[v3][1] );
+        D3DTLVertices[cVertex].rhw    = D3DVAL( (1.0 / VB->Clip[v3][3]) );
+        D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ? 
+                                      dwPVColor :
+                                      (VB->Color[v3][3]<<24) | (VB->Color[v3][0]<<16) | (VB->Color[v3][1]<<8) | VB->Color[v3][2];
+   
+        D3DTLVertices[cVertex].sx     = D3DVAL( VB->Win[v4][0] );
+        D3DTLVertices[cVertex].sy     = D3DVAL( (height - VB->Win[v4][1]) );
+        D3DTLVertices[cVertex].sz     = D3DVAL( VB->Win[v4][2] );
+        D3DTLVertices[cVertex].tu     = D3DVAL( VB->TexCoord[v4][0] );
+        D3DTLVertices[cVertex].tv     = D3DVAL( VB->TexCoord[v4][1] );
+        D3DTLVertices[cVertex].rhw    = D3DVAL( (1.0 / VB->Clip[v4][3]) );
+        D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ? 
+                                      dwPVColor :
+                                      (VB->Color[v4][3]<<24) | (VB->Color[v4][0]<<16) | (VB->Color[v4][1]<<8) | VB->Color[v4][2];
+    }
+  }
+  else
+  {
+    for( cVertex = 0, index = start; index < end; index += 4 )
+    {
+        if ( VB->ClipMask[v1] & VB->ClipMask[v2] & VB->ClipMask[v3]  & VB->ClipMask[v4] & CLIP_ALL_BITS ) 
+        {
+          continue;
+        }      
+        else if ( VB->ClipMask[v1] | VB->ClipMask[v2] | VB->ClipMask[v3] | VB->ClipMask[v4] ) 
+        {
+          VList[0] = v1;
+          VList[1] = v2;
+          VList[2] = v3;
+          VList[3] = v4;
+          RenderClippedPolygon( ctx, 4, VList );
+          continue;
+        }
+
+        /* Compute orientation of triangle */
+        ex = VB->Win[v2][0] - VB->Win[v1][0];
+        ey = VB->Win[v2][1] - VB->Win[v1][1];
+        fx = VB->Win[v3][0] - VB->Win[v1][0];
+        fy = VB->Win[v3][1] - VB->Win[v1][1];
+        c = (ex * fy) - (ey * fx);
+
+        /* polygon is perpindicular to view plane, don't draw it */
+        if ( (c == 0.0F) && !ctx->Polygon.Unfilled )
+          continue;
+
+        /* Backface culling. */
+        facing = (c < 0.0F) ^ ctx->Polygon.FrontBit;
+        if ( (facing + 1) & ctx->Polygon.CullBits ) 
+          continue;
+
+        if ( ctx->IndirectTriangles & DD_TRI_LIGHT_TWOSIDE ) 
+        {
+          if ( facing == 1 ) 
+          {
+               /* use back color */
+               VB->Color   = VB->Bcolor;
+               VB->Specular= VB->Bspec;
+          }
+          else 
+          {
+               /* use front color */
+               VB->Color   = VB->Fcolor;
+               VB->Specular= VB->Fspec;
+          }    
+        }      
+
+        if ( ctx->IndirectTriangles & DD_TRI_OFFSET ) 
+        {
+          /* Finish computing plane equation of polygon, compute offset */
+          GLfloat fz = VB->Win[v3][2] - VB->Win[v1][2];  
+          GLfloat ez = VB->Win[v2][2] - VB->Win[v1][2];
+          GLfloat a = (ey * fz) - (ez * fy);
+          GLfloat b = (ez * fx) - (ex * fz);
+          OffsetPolygon( ctx, a, b, c );
+        }
+
+        if ( ctx->Light.ShadeModel == GL_FLAT )
+          dwPVColor = (VB->Color[v4][3]<<24) | (VB->Color[v4][0]<<16) | (VB->Color[v4][1]<<8) | VB->Color[v4][2];
+   
+        /*=====================================*/
+        /* Populate the the triangle vertices. */
+        /*=====================================*/
+        D3DTLVertices[cVertex].sx     = D3DVAL( VB->Win[v1][0] );
+        D3DTLVertices[cVertex].sy     = D3DVAL( (height - VB->Win[v1][1]) );
+        D3DTLVertices[cVertex].sz     = D3DVAL( (VB->Win[v1][2] + ctx->PolygonZoffset) );
+        D3DTLVertices[cVertex].tu     = D3DVAL( VB->TexCoord[v1][0] );
+        D3DTLVertices[cVertex].tv     = D3DVAL( VB->TexCoord[v1][1] );
+        D3DTLVertices[cVertex].rhw    = D3DVAL( (1.0 / VB->Clip[v1][3]) );
+        D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ? 
+                                       dwPVColor :
+                                       (VB->Color[v1][3]<<24) | (VB->Color[v1][0]<<16) | (VB->Color[v1][1]<<8) | VB->Color[v1][2];
+   
+        D3DTLVertices[cVertex].sx     = D3DVAL( VB->Win[v2][0] );
+        D3DTLVertices[cVertex].sy     = D3DVAL( (height - VB->Win[v2][1]) );
+        D3DTLVertices[cVertex].sz     = D3DVAL( (VB->Win[v2][2] + ctx->PolygonZoffset) );
+        D3DTLVertices[cVertex].tu     = D3DVAL( VB->TexCoord[v2][0] );
+        D3DTLVertices[cVertex].tv     = D3DVAL( VB->TexCoord[v2][1] );
+        D3DTLVertices[cVertex].rhw    = D3DVAL( (1.0 / VB->Clip[v2][3]) );
+        D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ? 
+                                       dwPVColor :
+                                       (VB->Color[v2][3]<<24) | (VB->Color[v2][0]<<16) | (VB->Color[v2][1]<<8) | VB->Color[v2][2];
+      
+        D3DTLVertices[cVertex].sx     = D3DVAL( VB->Win[v3][0] );
+        D3DTLVertices[cVertex].sy     = D3DVAL( (height - VB->Win[v3][1]) );
+        D3DTLVertices[cVertex].sz     = D3DVAL( (VB->Win[v3][2] + ctx->PolygonZoffset) );
+        D3DTLVertices[cVertex].tu     = D3DVAL( VB->TexCoord[v3][0] );
+        D3DTLVertices[cVertex].tv     = D3DVAL( VB->TexCoord[v3][1] );
+        D3DTLVertices[cVertex].rhw    = D3DVAL( (1.0 / VB->Clip[v3][3]) );
+        D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ? 
+                                       dwPVColor :
+                                       (VB->Color[v3][3]<<24) | (VB->Color[v3][0]<<16) | (VB->Color[v3][1]<<8) | VB->Color[v3][2];
+   
+        D3DTLVertices[cVertex].sx     = D3DVAL( VB->Win[v1][0] );
+        D3DTLVertices[cVertex].sy     = D3DVAL( (height - VB->Win[v1][1]) );
+        D3DTLVertices[cVertex].sz     = D3DVAL( (VB->Win[v1][2] + ctx->PolygonZoffset) );
+        D3DTLVertices[cVertex].tu     = D3DVAL( VB->TexCoord[v1][0] );
+        D3DTLVertices[cVertex].tv     = D3DVAL( VB->TexCoord[v1][1] );
+        D3DTLVertices[cVertex].rhw    = D3DVAL( (1.0 / VB->Clip[v1][3]) );
+        D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ? 
+                                         dwPVColor :
+                                       (VB->Color[v1][3]<<24) | (VB->Color[v1][0]<<16) | (VB->Color[v1][1]<<8) | VB->Color[v1][2];
+   
+        D3DTLVertices[cVertex].sx     = D3DVAL( VB->Win[v3][0] );
+        D3DTLVertices[cVertex].sy     = D3DVAL( (height - VB->Win[v3][1]) );
+        D3DTLVertices[cVertex].sz     = D3DVAL( (VB->Win[v3][2] + ctx->PolygonZoffset) );
+        D3DTLVertices[cVertex].tu     = D3DVAL( VB->TexCoord[v3][0] );
+        D3DTLVertices[cVertex].tv     = D3DVAL( VB->TexCoord[v3][1] );
+        D3DTLVertices[cVertex].rhw    = D3DVAL( (1.0 / VB->Clip[v3][3]) );
+        D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ? 
+                                       dwPVColor :
+                                       (VB->Color[v3][3]<<24) | (VB->Color[v3][0]<<16) | (VB->Color[v3][1]<<8) | VB->Color[v3][2];
+   
+        D3DTLVertices[cVertex].sx     = D3DVAL( VB->Win[v4][0] );
+        D3DTLVertices[cVertex].sy     = D3DVAL( (height - VB->Win[v4][1]) );
+        D3DTLVertices[cVertex].sz     = D3DVAL( (VB->Win[v4][2] + ctx->PolygonZoffset) );
+        D3DTLVertices[cVertex].tu     = D3DVAL( VB->TexCoord[v4][0] );
+        D3DTLVertices[cVertex].tv     = D3DVAL( VB->TexCoord[v4][1] );
+        D3DTLVertices[cVertex].rhw    = D3DVAL( (1.0 / VB->Clip[v4][3]) );
+        D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ? 
+                                       dwPVColor :
+                                       (VB->Color[v4][3]<<24) | (VB->Color[v4][0]<<16) | (VB->Color[v4][1]<<8) | VB->Color[v4][2];
+    }
+  }
+
+#undef   v4
+#undef   v3
+#undef   v2
+#undef   v1
+
+  /* Render the converted vertex buffer. */  
+  if ( cVertex )
+    DrawPrimitiveHAL( pContext->pShared, D3DPT_TRIANGLELIST, &D3DTLVertices[0], cVertex );
+}
+/*===========================================================================*/
+/*                                                                           */
+/*===========================================================================*/
+/* RETURN: TRUE, FALSE.                                                      */
+/*===========================================================================*/
+static void RenderQuad( GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3, GLuint v4, GLuint pv )
+{
+  D3DMESACONTEXT       *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
+  struct vertex_buffer         *VB = ctx->VB;
+  int                          height = (pContext->pShared->rectW.bottom - pContext->pShared->rectW.top);
+  DWORD                        dwPVColor;
+  GLfloat                      ex, ey, 
+                         fx, fy, c;
+  GLuint                       facing;  /* 0=front, 1=back */
+  static D3DTLVERTEX           TLVertices[6];
+
+  DPF(( DBG_FUNC, "RenderQuad" ));
+  DPF(( DBG_PRIM_INFO, "RenderQuad( 1 )" ));
+
+  /* Compute orientation of triangle */
+  ex = VB->Win[v2][0] - VB->Win[v1][0];
+  ey = VB->Win[v2][1] - VB->Win[v1][1];
+  fx = VB->Win[v3][0] - VB->Win[v1][0];
+  fy = VB->Win[v3][1] - VB->Win[v1][1];
+  c = (ex * fy) - (ey * fx);
+
+  /* polygon is perpindicular to view plane, don't draw it */
+  if ( (c == 0.0F) && !ctx->Polygon.Unfilled )
+    return;
+
+  /* Backface culling. */
+  facing = (c < 0.0F) ^ ctx->Polygon.FrontBit;
+  if ( (facing + 1) & ctx->Polygon.CullBits )  
+    return;
+
+  if ( ctx->IndirectTriangles & DD_TRI_LIGHT_TWOSIDE ) 
+  {
+    if ( facing == 1 ) 
+    {
+        /* use back color */
+        VB->Color   = VB->Bcolor;
+        VB->Specular= VB->Bspec;
+    }
+    else 
+    {
+        /* use front color */
+        VB->Color   = VB->Fcolor;
+        VB->Specular= VB->Fspec;
+    }
+  }
+
+  if ( ctx->IndirectTriangles & DD_TRI_OFFSET ) 
+  {
+    /* Finish computing plane equation of polygon, compute offset */
+    GLfloat fz = VB->Win[v3][2] - VB->Win[v1][2];  
+    GLfloat ez = VB->Win[v2][2] - VB->Win[v1][2];
+    GLfloat a = (ey * fz) - (ez * fy);
+    GLfloat b = (ez * fx) - (ex * fz);
+    OffsetPolygon( ctx, a, b, c );
+  }
+  
+  if ( ctx->Light.ShadeModel == GL_FLAT )
+    dwPVColor = (VB->Color[pv][3]<<24) | (VB->Color[pv][0]<<16) | (VB->Color[pv][1]<<8) | VB->Color[pv][2];
+
+  /*=====================================*/
+  /* Populate the the triangle vertices. */
+  /*=====================================*/
+  TLVertices[0].sx      = D3DVAL( VB->Win[v1][0] );
+  TLVertices[0].sy      = D3DVAL( (height - VB->Win[v1][1]) );
+  TLVertices[0].sz      = D3DVAL( (VB->Win[v1][2] + ctx->PolygonZoffset) );
+  TLVertices[0].tu      = D3DVAL( VB->TexCoord[v1][0] );
+  TLVertices[0].tv      = D3DVAL( VB->TexCoord[v1][1] );
+  TLVertices[0].rhw     = D3DVAL( (1.0 / VB->Clip[v1][3]) );
+  TLVertices[0].color   = (ctx->Light.ShadeModel == GL_FLAT) ? dwPVColor :
+                           (VB->Color[v1][3]<<24) | (VB->Color[v1][0]<<16) | (VB->Color[v1][1]<<8) | VB->Color[v1][2];
+
+   TLVertices[1].sx      = D3DVAL( VB->Win[v2][0] );
+   TLVertices[1].sy      = D3DVAL( (height - VB->Win[v2][1]) );
+   TLVertices[1].sz      = D3DVAL( (VB->Win[v2][2] + ctx->PolygonZoffset) );
+   TLVertices[1].tu      = D3DVAL( VB->TexCoord[v2][0] );
+   TLVertices[1].tv      = D3DVAL( VB->TexCoord[v2][1] );
+   TLVertices[1].rhw     = D3DVAL( (1.0 / VB->Clip[v2][3]) );
+   TLVertices[1].color   = (ctx->Light.ShadeModel == GL_FLAT) ? dwPVColor :
+                           (VB->Color[v2][3]<<24) | (VB->Color[v2][0]<<16) | (VB->Color[v2][1]<<8) | VB->Color[v2][2];
+   
+   TLVertices[2].sx      = D3DVAL( VB->Win[v3][0] );
+   TLVertices[2].sy      = D3DVAL( (height - VB->Win[v3][1]) );
+   TLVertices[2].sz      = D3DVAL( (VB->Win[v3][2] + ctx->PolygonZoffset) );
+   TLVertices[2].tu      = D3DVAL( VB->TexCoord[v3][0] );
+   TLVertices[2].tv      = D3DVAL( VB->TexCoord[v3][1] );
+   TLVertices[2].rhw     = D3DVAL( (1.0 / VB->Clip[v3][3]) );
+   TLVertices[2].color   = (ctx->Light.ShadeModel == GL_FLAT) ? dwPVColor :
+                           (VB->Color[v3][3]<<24) | (VB->Color[v3][0]<<16) | (VB->Color[v3][1]<<8) | VB->Color[v3][2];
+
+   TLVertices[3].sx      = D3DVAL( VB->Win[v3][0] );
+   TLVertices[3].sy      = D3DVAL( (height - VB->Win[v3][1]) );
+   TLVertices[3].sz      = D3DVAL( (VB->Win[v3][2] + ctx->PolygonZoffset) );
+   TLVertices[3].tu      = D3DVAL( VB->TexCoord[v3][0] );
+   TLVertices[3].tv      = D3DVAL( VB->TexCoord[v3][1] );
+   TLVertices[3].rhw     = D3DVAL( (1.0 / VB->Clip[v3][3]) );
+   TLVertices[3].color   = (ctx->Light.ShadeModel == GL_FLAT) ? dwPVColor :
+                           (VB->Color[v3][3]<<24) | (VB->Color[v3][0]<<16) | (VB->Color[v3][1]<<8) | VB->Color[v3][2];
+
+   TLVertices[4].sx      = D3DVAL( VB->Win[v4][0] );
+   TLVertices[4].sy      = D3DVAL( (height - VB->Win[v4][1]) );
+   TLVertices[4].sz      = D3DVAL( (VB->Win[v4][2] + ctx->PolygonZoffset) );
+   TLVertices[4].tu      = D3DVAL( VB->TexCoord[v4][0] );
+   TLVertices[4].tv      = D3DVAL( VB->TexCoord[v4][1] );
+   TLVertices[4].rhw     = D3DVAL( (1.0 / VB->Clip[v4][3]) );
+   TLVertices[4].color   = (ctx->Light.ShadeModel == GL_FLAT) ? dwPVColor :
+                           (VB->Color[v4][3]<<24) | (VB->Color[v4][0]<<16) | (VB->Color[v4][1]<<8) | VB->Color[v4][2];
+
+   TLVertices[5].sx      = D3DVAL( VB->Win[v1][0] );
+   TLVertices[5].sy      = D3DVAL( (height - VB->Win[v1][1]) );
+   TLVertices[5].sz      = D3DVAL( (VB->Win[v1][2] + ctx->PolygonZoffset) );
+   TLVertices[5].tu      = D3DVAL( VB->TexCoord[v1][0] );
+   TLVertices[5].tv      = D3DVAL( VB->TexCoord[v1][1] );
+   TLVertices[5].rhw     = D3DVAL( (1.0 / VB->Clip[v1][3]) );
+   TLVertices[5].color   = (ctx->Light.ShadeModel == GL_FLAT) ? dwPVColor :
+                           (VB->Color[v1][3]<<24) | (VB->Color[v1][0]<<16) | (VB->Color[v1][1]<<8) | VB->Color[v1][2];
+
+   /* Draw the two triangles. */  
+   DrawPrimitiveHAL( pContext->pShared, D3DPT_TRIANGLELIST, &TLVertices[0], 6 );
+}
+/*===========================================================================*/
+/*                                                                           */
+/*===========================================================================*/
+/* RETURN: TRUE, FALSE.                                                      */
+/*===========================================================================*/
+void   RenderOneTriangle( GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3, GLuint pv )
+{
+  D3DMESACONTEXT               *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
+  struct vertex_buffer         *VB = ctx->VB;
+  int                          height = (pContext->pShared->rectW.bottom - pContext->pShared->rectW.top);
+  DWORD                        dwPVColor;
+  static D3DTLVERTEX           TLVertices[3];
+
+  DPF(( DBG_FUNC, "RenderOneTriangle" ));
+  DPF(( DBG_PRIM_INFO, "RenderTriangle( 1 )" ));
+
+  /*=====================================*/
+  /* Populate the the triangle vertices. */
+  /*=====================================*/
+  if ( ctx->Light.ShadeModel == GL_FLAT )
+    dwPVColor = (VB->Color[pv][3]<<24) | (VB->Color[pv][0]<<16) | (VB->Color[pv][1]<<8) | VB->Color[pv][2];
+
+  TLVertices[0].sx      = D3DVAL( VB->Win[v1][0] );
+  TLVertices[0].sy      = D3DVAL( (height - VB->Win[v1][1]) );
+  TLVertices[0].sz      = D3DVAL( (VB->Win[v1][2] + ctx->PolygonZoffset) );
+  TLVertices[0].tu      = D3DVAL( VB->TexCoord[v1][0] );
+  TLVertices[0].tv      = D3DVAL( VB->TexCoord[v1][1] );
+  TLVertices[0].rhw     = D3DVAL( (1.0 / VB->Clip[v1][3]) );
+  TLVertices[0].color   = (ctx->Light.ShadeModel == GL_FLAT) ? dwPVColor :
+                          (VB->Color[v1][3]<<24) | (VB->Color[v1][0]<<16) | (VB->Color[v1][1]<<8) | VB->Color[v1][2];
+  DPF(( DBG_PRIM_INFO, "V1 -> x:%f y:%f z:%f c:%x",
+          TLVertices[0].sx,
+          TLVertices[0].sy,
+          TLVertices[0].sz,
+          TLVertices[0].color ));
+
+  TLVertices[1].sx      = D3DVAL( VB->Win[v2][0] );
+  TLVertices[1].sy      = D3DVAL( (height - VB->Win[v2][1]) );
+  TLVertices[1].sz      = D3DVAL( (VB->Win[v2][2] + ctx->PolygonZoffset) );
+  TLVertices[1].tu      = D3DVAL( VB->TexCoord[v2][0] );
+  TLVertices[1].tv      = D3DVAL( VB->TexCoord[v2][1] );
+  TLVertices[1].rhw     = D3DVAL( (1.0 / VB->Clip[v2][3]) );
+  TLVertices[1].color   = (ctx->Light.ShadeModel == GL_FLAT) ? dwPVColor :
+                          (VB->Color[v2][3]<<24) | (VB->Color[v2][0]<<16) | (VB->Color[v2][1]<<8) | VB->Color[v2][2];
+  DPF(( DBG_PRIM_INFO, "V2 -> x:%f y:%f z:%f c:%x",
+          TLVertices[1].sx,
+          TLVertices[1].sy,
+          TLVertices[1].sz,
+          TLVertices[1].color ));
+   
+  TLVertices[2].sx      = D3DVAL( VB->Win[v3][0] );
+  TLVertices[2].sy      = D3DVAL( (height - VB->Win[v3][1]) );
+  TLVertices[2].sz      = D3DVAL( (VB->Win[v3][2] + ctx->PolygonZoffset) );
+  TLVertices[2].tu      = D3DVAL( VB->TexCoord[v3][0] );
+  TLVertices[2].tv      = D3DVAL( VB->TexCoord[v3][1] );
+  TLVertices[2].rhw     = D3DVAL( (1.0 / VB->Clip[v3][3]) );
+  TLVertices[2].color   = (ctx->Light.ShadeModel == GL_FLAT) ? dwPVColor :
+                          (VB->Color[v3][3]<<24) | (VB->Color[v3][0]<<16) | (VB->Color[v3][1]<<8) | VB->Color[v3][2];
+  DPF(( DBG_PRIM_INFO, "V3 -> x:%f y:%f z:%f c:%x",
+          TLVertices[2].sx,
+          TLVertices[2].sy,
+          TLVertices[2].sz,
+          TLVertices[2].color ));
+
+  /* Draw the triangle. */  
+  DrawPrimitiveHAL( pContext->pShared, D3DPT_TRIANGLELIST, &TLVertices[0], 3 );
+}
+/*===========================================================================*/
+/*                                                                           */
+/*===========================================================================*/
+/* RETURN: TRUE, FALSE.                                                      */
+/*===========================================================================*/
+void RenderOneLine( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv )
+{
+  D3DMESACONTEXT       *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
+  struct vertex_buffer         *VB = ctx->VB;
+  int                          height = (pContext->pShared->rectW.bottom - pContext->pShared->rectW.top);
+  DWORD                        dwPVColor;
+  static D3DTLVERTEX   TLVertices[2];
+
+  DPF(( DBG_FUNC, "RenderOneLine" ));
+  DPF(( DBG_PRIM_INFO, "RenderLine( 1 )" ));
+
+  if ( VB->MonoColor ) 
+    dwPVColor = (pContext->aCurrent<<24) | (pContext->rCurrent<<16) | (pContext->gCurrent<<8) | pContext->bCurrent;
+  else         
+    dwPVColor = (VB->Color[pv][3]<<24) | (VB->Color[pv][0]<<16) | (VB->Color[pv][1]<<8) | VB->Color[pv][2];
+
+   TLVertices[0].sx      = D3DVAL( VB->Win[v1][0] );
+   TLVertices[0].sy      = D3DVAL( (height - VB->Win[v1][1]) );
+   TLVertices[0].sz      = D3DVAL( (VB->Win[v1][2] + ctx->LineZoffset) );
+   TLVertices[0].tu      = D3DVAL( VB->TexCoord[v1][0] );
+   TLVertices[0].tv      = D3DVAL( VB->TexCoord[v1][1] );
+   TLVertices[0].rhw     = D3DVAL( (1.0 / VB->Clip[v1][3]) );
+   TLVertices[0].color   = (ctx->Light.ShadeModel == GL_FLAT) ? dwPVColor :
+                           (VB->Color[v1][3]<<24) | (VB->Color[v1][0]<<16) | (VB->Color[v1][1]<<8) | VB->Color[v1][2];
+
+   TLVertices[1].sx      = D3DVAL( VB->Win[v2][0] );
+   TLVertices[1].sy      = D3DVAL( (height - VB->Win[v2][1]) );
+   TLVertices[1].sz      = D3DVAL( (VB->Win[v2][2] + ctx->LineZoffset) );
+   TLVertices[1].tu      = D3DVAL( VB->TexCoord[v2][0] );
+   TLVertices[1].tv      = D3DVAL( VB->TexCoord[v2][1] );
+   TLVertices[1].rhw     = D3DVAL( (1.0 / VB->Clip[v2][3]) );
+   TLVertices[1].color   = (ctx->Light.ShadeModel == GL_FLAT) ? dwPVColor :
+                           (VB->Color[v2][3]<<24) | (VB->Color[v2][0]<<16) | (VB->Color[v2][1]<<8) | VB->Color[v2][2];
+
+   /* Draw line from (x0,y0) to (x1,y1) with current pixel color/index */
+   DrawPrimitiveHAL( pContext->pShared, D3DPT_LINELIST, &TLVertices[0], 2 );
+}
+/*===========================================================================*/
+/*  This function was written to convert points into triangles.  I did this  */
+/* as all card accelerate triangles and most drivers do this anyway.  In hind*/
+/* thought this might be a bad idea as some cards do better.                 */
+/*===========================================================================*/
+/* RETURN:                                                                   */
+/*===========================================================================*/
+static void RenderPointsVB( GLcontext *ctx, GLuint start, GLuint end )
+{
+  D3DMESACONTEXT               *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
+  struct vertex_buffer         *VB = ctx->VB;
+  struct pixel_buffer  *PB = ctx->PB;
+  GLuint                               index;
+  GLfloat                radius, z,
+                         xmin, ymin, 
+                         xmax, ymax;
+  GLint                                cVertex,
+                         height = (pContext->pShared->rectW.bottom - pContext->pShared->rectW.top);
+  DWORD                                dwPVColor;
+  
+  DPF(( DBG_FUNC, "RenderPointsVB();" ));
+
+  radius = CLAMP( ctx->Point.Size, MIN_POINT_SIZE, MAX_POINT_SIZE ) * 0.5F;
+
+  for( index = start, cVertex = 0; index <= end; index++ ) 
+  {
+    if ( VB->ClipMask[index] == 0 ) 
+    {
+        xmin = D3DVAL( VB->Win[index][0] - radius );
+        xmax = D3DVAL( VB->Win[index][0] + radius );
+        ymin = D3DVAL( height - VB->Win[index][1] - radius );
+        ymax = D3DVAL( height - VB->Win[index][1] + radius );
+        z    = D3DVAL( (VB->Win[index][2] + ctx->PointZoffset) );
+
+        dwPVColor = (VB->Color[index][3]<<24) | 
+                    (VB->Color[index][0]<<16) | 
+                    (VB->Color[index][1]<<8) | 
+                  VB->Color[index][2];
+
+        D3DTLVertices[cVertex].sx        = xmin;
+        D3DTLVertices[cVertex].sy      = ymax;
+        D3DTLVertices[cVertex].sz      = z;
+        D3DTLVertices[cVertex].tu      = 0.0;
+        D3DTLVertices[cVertex].tv      = 0.0;
+        D3DTLVertices[cVertex].rhw     = D3DVAL( (1.0 / VB->Clip[index][3]) );
+        D3DTLVertices[cVertex++].color = dwPVColor;
+
+        D3DTLVertices[cVertex].sx      = xmin;
+        D3DTLVertices[cVertex].sy      = ymin;
+        D3DTLVertices[cVertex].sz      = z;
+        D3DTLVertices[cVertex].tu      = 0.0;
+        D3DTLVertices[cVertex].tv      = 0.0;
+        D3DTLVertices[cVertex].rhw     = D3DVAL( (1.0 / VB->Clip[index][3]) );
+        D3DTLVertices[cVertex++].color = dwPVColor;
+   
+        D3DTLVertices[cVertex].sx      = xmax;
+        D3DTLVertices[cVertex].sy      = ymin;
+        D3DTLVertices[cVertex].sz      = z;
+        D3DTLVertices[cVertex].tu      = 0.0;
+        D3DTLVertices[cVertex].tv      = 0.0;
+        D3DTLVertices[cVertex].rhw     = D3DVAL( (1.0 / VB->Clip[index][3]) );
+        D3DTLVertices[cVertex++].color = dwPVColor;
+   
+        D3DTLVertices[cVertex].sx      = xmax;
+        D3DTLVertices[cVertex].sy      = ymin;
+        D3DTLVertices[cVertex].sz      = z;
+        D3DTLVertices[cVertex].tu      = 0.0;
+        D3DTLVertices[cVertex].tv      = 0.0;
+        D3DTLVertices[cVertex].rhw     = D3DVAL( (1.0 / VB->Clip[index][3]) );
+        D3DTLVertices[cVertex++].color = dwPVColor;
+
+        D3DTLVertices[cVertex].sx        = xmax;
+        D3DTLVertices[cVertex].sy      = ymax;
+        D3DTLVertices[cVertex].sz      = z;
+        D3DTLVertices[cVertex].tu      = 0.0;
+        D3DTLVertices[cVertex].tv      = 0.0;
+        D3DTLVertices[cVertex].rhw     = D3DVAL( (1.0 / VB->Clip[index][3]) );
+        D3DTLVertices[cVertex++].color = dwPVColor;
+
+        D3DTLVertices[cVertex].sx        = xmin;
+        D3DTLVertices[cVertex].sy      = ymax;
+        D3DTLVertices[cVertex].sz      = z;
+        D3DTLVertices[cVertex].tu      = 0.0;
+        D3DTLVertices[cVertex].tv      = 0.0;
+        D3DTLVertices[cVertex].rhw     = D3DVAL( (1.0 / VB->Clip[index][3]) );
+        D3DTLVertices[cVertex++].color = dwPVColor;
+    }
+  }
+
+  /* Render the converted vertex buffer. */  
+  if ( cVertex )
+    DrawPrimitiveHAL( pContext->pShared, D3DPT_TRIANGLELIST, &D3DTLVertices[0], cVertex );
+}
+/*===========================================================================*/
+/*  This gets call before we render any primitives so that the current OGL   */
+/* states will be mapped the D3D context.  I'm still not sure how D3D works  */
+/* but I'm finding that it doesn't act like a state machine as OGL is.  It   */
+/* looks like the state gets set back to the defaults after a DrawPrimitives */
+/* or an EndScene.  Also I set states that are the default even though this  */
+/* is redundant as the defaults seem screwed up.                             */
+/* TODO: make a batch call.                                                  */
+/*===========================================================================*/
+/* RETURN:                                                                   */
+/*===========================================================================*/
+static void SetRenderStates( GLcontext *ctx )
+{
+   D3DMESACONTEXT      *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
+   DWORD               dwFunc;
+   static      BOOL            bTexture = FALSE;
+   static int          texName = -1;
+
+   DPF(( DBG_FUNC, "SetRenderStates();" ));
+
+   if ( g_DBGMask & DBG_STATES )
+       DebugRenderStates( ctx, FALSE );
+
+   SetStateHAL( pContext->pShared, D3DRENDERSTATE_CULLMODE, D3DCULL_NONE );
+   SetStateHAL( pContext->pShared, D3DRENDERSTATE_DITHERENABLE, (ctx->Color.DitherFlag) ? TRUE : FALSE );
+
+   /*================================================*/
+   /* Check too see if there are new TEXTURE states. */
+   /*================================================*/
+   if ( ctx->Texture.Enabled )
+   {
+      switch( ctx->Texture.Set[ctx->Texture.CurrentSet].EnvMode )
+      {
+        case GL_MODULATE:
+               if ( ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0]->Format == GL_RGBA )
+                 dwFunc = pContext->pShared->dwTexFunc[d3dtblend_modulatealpha];
+               else
+                 dwFunc = pContext->pShared->dwTexFunc[d3dtblend_modulate];
+               break;
+
+          case GL_BLEND:
+               dwFunc = pContext->pShared->dwTexFunc[d3dtblend_decalalpha];
+               break;
+  
+        case GL_REPLACE:
+               dwFunc = pContext->pShared->dwTexFunc[d3dtblend_decal];
+               break;
+
+        case GL_DECAL:
+               if ( ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0]->Format == GL_RGBA )
+                 dwFunc = pContext->pShared->dwTexFunc[d3dtblend_decalalpha];
+               else
+                 dwFunc = pContext->pShared->dwTexFunc[d3dtblend_decal];
+               break;
+      }
+      SetStateHAL( pContext->pShared, D3DRENDERSTATE_TEXTUREMAPBLEND, dwFunc );
+      
+      switch( ctx->Texture.Set[ctx->Texture.CurrentSet].Current->MagFilter )
+      {
+          case GL_NEAREST:
+               dwFunc = D3DFILTER_NEAREST;
+               break;
+        case GL_LINEAR:
+               dwFunc = D3DFILTER_LINEAR;
+               break;
+        case GL_NEAREST_MIPMAP_NEAREST:
+               dwFunc = D3DFILTER_MIPNEAREST;
+               break;
+        case GL_LINEAR_MIPMAP_NEAREST:
+               dwFunc = D3DFILTER_LINEARMIPNEAREST;
+               break;
+        case GL_NEAREST_MIPMAP_LINEAR:
+               dwFunc = D3DFILTER_MIPLINEAR;
+               break;
+        case GL_LINEAR_MIPMAP_LINEAR:
+               dwFunc = D3DFILTER_LINEARMIPLINEAR;
+               break;
+      }
+      SetStateHAL( pContext->pShared, D3DRENDERSTATE_TEXTUREMAG, dwFunc );
+
+      switch( ctx->Texture.Set[ctx->Texture.CurrentSet].Current->MinFilter )
+      {
+          case GL_NEAREST:
+               dwFunc = D3DFILTER_NEAREST;
+               break;
+        case GL_LINEAR:
+               dwFunc = D3DFILTER_LINEAR;
+               break;
+        case GL_NEAREST_MIPMAP_NEAREST:
+               dwFunc = D3DFILTER_MIPNEAREST;
+               break;
+        case GL_LINEAR_MIPMAP_NEAREST:
+               dwFunc = D3DFILTER_LINEARMIPNEAREST;
+               break;
+        case GL_NEAREST_MIPMAP_LINEAR:
+               dwFunc = D3DFILTER_MIPLINEAR;
+               break;
+        case GL_LINEAR_MIPMAP_LINEAR:
+               dwFunc = D3DFILTER_LINEARMIPLINEAR;
+               break;
+      }
+      SetStateHAL( pContext->pShared, D3DRENDERSTATE_TEXTUREMIN, dwFunc  );
+
+        /* Another hack to cut down on redundant texture binding. */
+        //      if ( texName != ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Name )
+        //      {
+          texName = ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Name;
+          CreateTMgrHAL( pContext->pShared, 
+                                  texName,
+                                  0,
+                                  ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0]->Format,
+                                  (RECT *)NULL,
+                                  ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0]->Width, 
+                                  ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0]->Height,
+                                  TM_ACTION_BIND,
+                                  (void *)ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0]->Data );
+          //    }
+        bTexture = TRUE;
+   }
+   else
+   {
+       /* This is nasty but should cut down on the number of redundant calls. */
+       if ( bTexture == TRUE )
+       {
+         DisableTMgrHAL( pContext->pShared );
+         bTexture = FALSE;
+       }
+   }
+
+   /*===============================================*/
+   /* Check too see if there are new RASTER states. */
+   /*===============================================*/
+
+   // TODO: no concept of front & back.
+   switch( ctx->Polygon.FrontMode )
+   {
+     case GL_POINT:
+         SetStateHAL( pContext->pShared, D3DRENDERSTATE_FILLMODE, D3DFILL_POINT );
+         break;
+     case GL_LINE:
+         SetStateHAL( pContext->pShared, D3DRENDERSTATE_FILLMODE, D3DFILL_WIREFRAME );
+         break;
+     case GL_FILL:
+         SetStateHAL( pContext->pShared, D3DRENDERSTATE_FILLMODE, D3DFILL_SOLID );
+         break;
+   }
+
+   /*************/
+   /* Z-Buffer. */
+   /*************/
+   if ( ctx->Depth.Test == GL_TRUE )
+   {
+       switch( ctx->Depth.Func )
+       {  
+         case GL_NEVER:    
+           dwFunc = D3DCMP_NEVER;        
+           break;
+         case GL_LESS:     
+           dwFunc = D3DCMP_LESS;         
+           break;
+         case GL_GEQUAL:   
+           dwFunc = D3DCMP_GREATEREQUAL; 
+           break;
+         case GL_LEQUAL:   
+           dwFunc = D3DCMP_LESSEQUAL;    
+           break;
+         case GL_GREATER:  
+           dwFunc = D3DCMP_GREATER;      
+           break;
+         case GL_NOTEQUAL: 
+           dwFunc = D3DCMP_NOTEQUAL;     
+           break;
+         case GL_EQUAL:    
+           dwFunc = D3DCMP_EQUAL;        
+           break;
+         case GL_ALWAYS:   
+           dwFunc = D3DCMP_ALWAYS;       
+           break;
+       }
+       SetStateHAL( pContext->pShared, D3DRENDERSTATE_ZFUNC, dwFunc );
+       SetStateHAL( pContext->pShared, D3DRENDERSTATE_ZENABLE, TRUE );
+   }   
+   else
+   {
+       SetStateHAL( pContext->pShared, D3DRENDERSTATE_ZENABLE, FALSE );
+   }
+
+   /*******************/
+   /* Z-Write Enable. */
+   /*******************/
+   SetStateHAL( pContext->pShared, D3DRENDERSTATE_ZWRITEENABLE , (ctx->Depth.Mask == GL_TRUE) ? TRUE : FALSE );
+
+   /***************/
+   /* Alpha test. */
+   /***************/
+   if ( ctx->Color.AlphaEnabled == GL_TRUE )
+   {
+       switch( ctx->Color.AlphaFunc )
+     {  
+         case GL_NEVER:    
+           dwFunc = D3DCMP_NEVER;        
+           break;
+         case GL_LESS:     
+           dwFunc = D3DCMP_LESS;         
+           break;
+         case GL_GEQUAL:   
+           dwFunc = D3DCMP_GREATEREQUAL; 
+           break;
+         case GL_LEQUAL:   
+           dwFunc = D3DCMP_LESSEQUAL;    
+           break;
+         case GL_GREATER:  
+           dwFunc = D3DCMP_GREATER;      
+           break;
+         case GL_NOTEQUAL: 
+           dwFunc = D3DCMP_NOTEQUAL;     
+           break;
+         case GL_EQUAL:    
+           dwFunc = D3DCMP_EQUAL;        
+           break;
+         case GL_ALWAYS:   
+           dwFunc = D3DCMP_ALWAYS;       
+           break;
+       }
+       SetStateHAL( pContext->pShared, D3DRENDERSTATE_ALPHAFUNC , dwFunc );
+       SetStateHAL( pContext->pShared, D3DRENDERSTATE_ALPHATESTENABLE, TRUE );
+   }
+   else
+   {
+       SetStateHAL( pContext->pShared, D3DRENDERSTATE_ALPHATESTENABLE, FALSE );
+   }
+
+   /****************/
+   /* Alpha blend. */
+   /****************/
+   if ( ctx->Color.BlendEnabled == GL_TRUE )
+   {
+       switch( ctx->Color.BlendSrc ) 
+       {
+         case GL_ZERO:                         
+           dwFunc = pContext->pShared->dwSrcBlendCaps[s_zero];
+           break;
+       case GL_ONE:                     
+           dwFunc = pContext->pShared->dwSrcBlendCaps[s_one];
+           break;
+       case GL_DST_COLOR:               
+           dwFunc = pContext->pShared->dwSrcBlendCaps[s_dst_color];
+           break;
+       case GL_ONE_MINUS_DST_COLOR:     
+           dwFunc = pContext->pShared->dwSrcBlendCaps[s_one_minus_dst_color];
+           break;
+       case GL_SRC_ALPHA:               
+           dwFunc = pContext->pShared->dwSrcBlendCaps[s_src_alpha];
+           break;
+       case GL_ONE_MINUS_SRC_ALPHA:     
+           dwFunc = pContext->pShared->dwSrcBlendCaps[s_one_minus_src_alpha];
+           break;
+       case GL_DST_ALPHA:               
+           dwFunc = pContext->pShared->dwSrcBlendCaps[s_dst_alpha];
+           break;
+       case GL_ONE_MINUS_DST_ALPHA:     
+           dwFunc = pContext->pShared->dwSrcBlendCaps[s_one_minus_dst_alpha];
+           break;
+       case GL_SRC_ALPHA_SATURATE:      
+           dwFunc = pContext->pShared->dwSrcBlendCaps[s_src_alpha_saturate];
+           break;
+       case GL_CONSTANT_COLOR:          
+           dwFunc = pContext->pShared->dwSrcBlendCaps[s_constant_color];
+           break;
+       case GL_ONE_MINUS_CONSTANT_COLOR:
+           dwFunc = pContext->pShared->dwSrcBlendCaps[s_one_minus_constant_color];
+           break;
+       case GL_CONSTANT_ALPHA:          
+           dwFunc = pContext->pShared->dwSrcBlendCaps[s_constant_alpha];
+           break;
+       case GL_ONE_MINUS_CONSTANT_ALPHA:
+           dwFunc = pContext->pShared->dwSrcBlendCaps[s_one_minus_constant_alpha];
+           break;
+       }
+       SetStateHAL( pContext->pShared, D3DRENDERSTATE_SRCBLEND, dwFunc );
+
+       switch( ctx->Color.BlendDst ) 
+       {
+       case GL_ZERO:                   
+           dwFunc = pContext->pShared->dwDestBlendCaps[d_zero];
+           break;
+       case GL_ONE:                     
+           dwFunc = pContext->pShared->dwDestBlendCaps[d_one];
+           break;
+       case GL_SRC_COLOR:               
+           dwFunc = pContext->pShared->dwDestBlendCaps[d_src_color];
+           break;
+       case GL_ONE_MINUS_SRC_COLOR:     
+           dwFunc = pContext->pShared->dwDestBlendCaps[d_one_minus_src_color];
+           break;
+       case GL_SRC_ALPHA:               
+           dwFunc = pContext->pShared->dwDestBlendCaps[d_src_alpha];
+           break;
+       case GL_ONE_MINUS_SRC_ALPHA:     
+           dwFunc = pContext->pShared->dwDestBlendCaps[d_one_minus_src_alpha];
+           break;
+       case GL_DST_ALPHA:               
+           dwFunc = pContext->pShared->dwDestBlendCaps[d_dst_alpha];
+           break;
+       case GL_ONE_MINUS_DST_ALPHA:     
+           dwFunc = pContext->pShared->dwDestBlendCaps[d_one_minus_dst_alpha];
+           break;
+       case GL_CONSTANT_COLOR:          
+           dwFunc = pContext->pShared->dwDestBlendCaps[d_constant_color];
+           break;
+       case GL_ONE_MINUS_CONSTANT_COLOR:
+           dwFunc = pContext->pShared->dwDestBlendCaps[d_one_minus_constant_color];
+           break;
+       case GL_CONSTANT_ALPHA:          
+           dwFunc = pContext->pShared->dwDestBlendCaps[d_constant_alpha];
+           break;
+       case GL_ONE_MINUS_CONSTANT_ALPHA:
+           dwFunc = pContext->pShared->dwDestBlendCaps[d_one_minus_constant_alpha];
+           break;
+       }
+       SetStateHAL( pContext->pShared, D3DRENDERSTATE_DESTBLEND, dwFunc );
+       SetStateHAL( pContext->pShared, D3DRENDERSTATE_ALPHABLENDENABLE, TRUE );
+   }
+   else
+   {
+       SetStateHAL( pContext->pShared, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE );
+   }
+}
+/*===========================================================================*/
+/*  If this function is called it will track the changes to the current      */
+/* states that I'm setting in Direct3D.  I did this so that the DPF's would  */
+/* be under control!                                                         */
+/*===========================================================================*/
+/* RETURN:                                                                   */
+/*===========================================================================*/
+static void DebugRenderStates( GLcontext *ctx, BOOL bForce )
+{
+   D3DMESACONTEXT      *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
+   DWORD                       dwFunc;
+   static int          dither = -1,
+                      texture = -1,
+                    textName = -1,
+                      textEnv = -1,
+                    textMin = -1,
+                    textMag = -1,
+                    polyMode = -1,
+                      depthTest = -1,
+                      depthFunc = -1,
+                      depthMask = -1,
+                      alphaTest = -1,
+                    alphaFunc = -1,
+                      blend = -1,
+                    blendSrc = -1,
+                    blendDest = -1;
+
+   /* Force a displayed update of all current states. */
+   if ( bForce )
+   {
+       dither = texture = textName = textEnv = textMin = textMag = -1;
+       polyMode = depthTest = depthFunc = depthMask = -1;
+       alphaTest = alphaFunc = blend = blendSrc = blendDest = -1;
+   }
+
+   if ( dither != ctx->Color.DitherFlag )
+   {
+       dither = ctx->Color.DitherFlag;
+       DPF(( 0, "\tDither\t\t%s", (dither) ? "ENABLED" : "--------" ));
+   }
+   if ( depthTest != ctx->Depth.Test )
+   {
+       depthTest = ctx->Depth.Test;
+       DPF(( 0, "\tDepth Test\t%s", (depthTest) ? "ENABLED" : "--------" ));
+   }
+   if ( alphaTest != ctx->Color.AlphaEnabled )
+   {   
+       alphaTest = ctx->Color.AlphaEnabled;
+       
+       DPF(( 0, "\tAlpha Test\t%s", (alphaTest) ? "ENABLED" : "--------" ));
+   }
+   if ( blend != ctx->Color.BlendEnabled )
+   {   
+       blend = ctx->Color.BlendEnabled;
+       
+       DPF(( 0, "\tBlending\t%s", (blend) ? "ENABLED" : "--------" ));
+   }
+
+   /*================================================*/
+   /* Check too see if there are new TEXTURE states. */
+   /*================================================*/
+   if ( texture != ctx->Texture.Enabled )
+   {
+       texture = ctx->Texture.Enabled;
+       DPF(( 0, "\tTexture\t\t%s", (texture) ? "ENABLED" : "--------" ));
+   }   
+
+   if ( ctx->Texture.Set[ctx->Texture.CurrentSet].Current )
+   {
+       if ( ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Name != textName )
+       {
+         textName = ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Name;
+         DPF(( 0, "\tTexture Name:\t%d", textName ));
+         DPF(( 0, "\tTexture Format:\t%s", 
+                  (ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0]->Format == GL_RGBA) ? 
+                  "GL_RGBA" : "GLRGB" ));
+       }
+
+       if ( textEnv != ctx->Texture.Set[ctx->Texture.CurrentSet].EnvMode )
+       {
+         textEnv = ctx->Texture.Set[ctx->Texture.CurrentSet].EnvMode;
+
+         switch( textEnv )
+         {
+       case GL_MODULATE:
+           DPF(( 0, "\tTexture\tMode\tGL_MODULATE" ));
+           break;
+       case GL_BLEND:
+           DPF(( 0, "\tTexture\tMode\tGL_BLEND" ));
+           break;
+       case GL_REPLACE:
+           DPF(( 0, "\tTexture\tMode\tGL_REPLACE" ));
+           break;
+       case GL_DECAL:
+           DPF(( 0, "\tTexture\tMode\tGL_DECAL" ));
+           break;
+         }
+       }
+
+       if ( textMag != ctx->Texture.Set[ctx->Texture.CurrentSet].Current->MagFilter )
+       {
+         textMag = ctx->Texture.Set[ctx->Texture.CurrentSet].Current->MagFilter;
+         
+         switch( textMag )
+         {
+       case GL_NEAREST:
+           DPF(( 0, "\tTexture MAG\tGL_NEAREST" ));
+           break;
+       case GL_LINEAR:
+           DPF(( 0, "\tTexture MAG\tGL_LINEAR" ));
+           break;
+       case GL_NEAREST_MIPMAP_NEAREST:
+           DPF(( 0, "\tTexture MAG\tGL_NEAREST_MIPMAP_NEAREST" ));
+           break;
+       case GL_LINEAR_MIPMAP_NEAREST:
+           DPF(( 0, "\tTexture MAG\tGL_LINEAR_MIPMAP_NEAREST" ));
+           break;
+       case GL_NEAREST_MIPMAP_LINEAR:
+           DPF(( 0, "\tTexture MAG\tGL_NEAREST_MIPMAP_LINEAR" ));
+           break;
+       case GL_LINEAR_MIPMAP_LINEAR:
+           DPF(( 0, "\tTexture MAG\tGL_LINEAR_MIPMAP_LINEAR" ));
+           break;
+         }
+       }
+
+       if ( textMin != ctx->Texture.Set[ctx->Texture.CurrentSet].Current->MinFilter )
+       {
+         textMin = ctx->Texture.Set[ctx->Texture.CurrentSet].Current->MinFilter;
+
+         switch( textMin )
+         {
+       case GL_NEAREST:
+           DPF(( 0, "\tTexture MIN\tGL_NEAREST" ));
+           break;
+       case GL_LINEAR:
+           DPF(( 0, "\tTexture MIN\tGL_LINEAR" ));
+           break;
+       case GL_NEAREST_MIPMAP_NEAREST:
+           DPF(( 0, "\tTexture MIN\tGL_NEAREST_MIPMAP_NEAREST" ));
+           break;
+       case GL_LINEAR_MIPMAP_NEAREST:
+           DPF(( 0, "\tTexture MIN\tGL_LINEAR_MIPMAP_NEAREST" ));
+           break;
+       case GL_NEAREST_MIPMAP_LINEAR:
+           DPF(( 0, "\tTexture MIN\tGL_LINEAR_MIPMAP_LINEAR" ));
+           break;
+       case GL_LINEAR_MIPMAP_LINEAR:
+           DPF(( 0, "\tTexture MIN\tGL_LINEAR_MIPMAP_LINEAR" ));
+           break;
+         }
+       }       
+   }
+
+   if ( ctx->Polygon.FrontMode != polyMode )
+   {
+       polyMode = ctx->Polygon.FrontMode;
+
+       switch( polyMode )
+       {
+       case GL_POINT:
+           DPF(( 0, "\tMode\t\tGL_POINT" ));
+           break;
+       case GL_LINE:
+           DPF(( 0, "\tMode\t\tGL_LINE" ));
+           break;
+       case GL_FILL:
+           DPF(( 0, "\tMode\t\tGL_FILL" ));
+           break;
+       }
+   }
+
+   if ( depthFunc != ctx->Depth.Func )
+   {
+       depthFunc = ctx->Depth.Func;
+
+       switch( depthFunc )
+       {  
+       case GL_NEVER:    
+           DPF(( 0, "\tDepth Func\tGL_NEVER" ));
+           break;
+       case GL_LESS:     
+           DPF(( 0, "\tDepth Func\tGL_LESS" ));
+           break;
+       case GL_GEQUAL:   
+           DPF(( 0, "\tDepth Func\tGL_GEQUAL" ));
+           break;
+       case GL_LEQUAL:   
+           DPF(( 0, "\tDepth Func\tGL_LEQUAL" ));
+           break;
+       case GL_GREATER:  
+           DPF(( 0, "\tDepth Func\tGL_GREATER" ));
+           break;
+       case GL_NOTEQUAL: 
+           DPF(( 0, "\tDepth Func\tGL_NOTEQUAL" ));
+           break;
+       case GL_EQUAL:    
+           DPF(( 0, "\tDepth Func\tGL_EQUAL" ));
+           break;
+       case GL_ALWAYS:   
+           DPF(( 0, "\tDepth Func\tGL_ALWAYS" ));
+           break;
+       }
+   }   
+
+   if ( depthMask != ctx->Depth.Mask )
+   {
+       depthMask = ctx->Depth.Mask;
+       DPF(( 0, "\tZWrite\t\t%s", (depthMask) ? "ENABLED" : "--------" ));
+   }
+
+   if ( alphaFunc != ctx->Color.AlphaFunc )
+   {
+       alphaFunc = ctx->Color.AlphaFunc;
+
+       switch( alphaFunc )
+     {  
+         case GL_NEVER:    
+           DPF(( 0, "\tAlpha Func\tGL_NEVER" ));
+           break;
+         case GL_LESS:     
+           DPF(( 0, "\tAlpha Func\tGL_LESS" ));
+           break;
+         case GL_GEQUAL:   
+           DPF(( 0, "\tAlpha Func\tGL_GEQUAL" ));
+           break;
+         case GL_LEQUAL:   
+           DPF(( 0, "\tAlpha Func\tGL_LEQUAL" ));
+           break;
+         case GL_GREATER:  
+           DPF(( 0, "\tAlpha Func\tGL_GREATER" ));
+           break;
+         case GL_NOTEQUAL: 
+           DPF(( 0, "\tAlpha Func\tGL_NOTEQUAL" ));
+           break;
+         case GL_EQUAL:    
+           DPF(( 0, "\tAlpha Func\tGL_EQUAL" ));
+           break;
+         case GL_ALWAYS:   
+           DPF(( 0, "\tAlpha Func\tGL_ALWAYS" ));
+           break;
+       }
+   }
+
+   if ( blendSrc != ctx->Color.BlendSrc ) 
+   {
+       blendSrc = ctx->Color.BlendSrc;
+
+       switch( blendSrc ) 
+       {
+         case GL_ZERO:                         
+           DPF(( 0, "\tSRC Blend\tGL_ZERO" ));
+           break;
+       case GL_ONE:                     
+           DPF(( 0, "\tSRC Blend\tGL_ONE" ));
+           break;
+       case GL_DST_COLOR:               
+           DPF(( 0, "\tSRC Blend\tGL_DST_COLOR" ));
+           break;
+       case GL_ONE_MINUS_DST_COLOR:     
+           DPF(( 0, "\tSRC Blend\tGL_ONE_MINUS_DST_COLOR" ));
+           break;
+       case GL_SRC_ALPHA:               
+           DPF(( 0, "\tSRC Blend\tGL_SRC_ALPHA" ));
+           break;
+       case GL_ONE_MINUS_SRC_ALPHA:     
+           DPF(( 0, "\tSRC Blend\tGL_MINUS_SRC_ALPHA" ));
+           break;
+       case GL_DST_ALPHA:               
+           DPF(( 0, "\tSRC Blend\tGL_DST_ALPHA" ));
+           break;
+       case GL_ONE_MINUS_DST_ALPHA:     
+           DPF(( 0, "\tSRC Blend\tGL_ONE_MINUS_DST_ALPHA" ));
+           break;
+       case GL_SRC_ALPHA_SATURATE:      
+           DPF(( 0, "\tSRC Blend\tGL_SRC_ALPHA_SATURATE" ));
+           break;
+       case GL_CONSTANT_COLOR:          
+           DPF(( 0, "\tSRC Blend\tGL_CONSTANT_COLOR" ));
+           break;
+       case GL_ONE_MINUS_CONSTANT_COLOR:
+           DPF(( 0, "\tSRC Blend\tGL_ONE_MINUS_CONSTANT_COLOR" ));
+           break;
+       case GL_CONSTANT_ALPHA:          
+           DPF(( 0, "\tSRC Blend\tGL_CONSTANT_ALPHA" ));
+           break;
+       case GL_ONE_MINUS_CONSTANT_ALPHA:
+           DPF(( 0, "\tSRC Blend\tGL_ONE_MINUS_CONSTANT_ALPHA" ));
+           break;
+       }
+   }
+
+   if ( blendDest != ctx->Color.BlendDst ) 
+   {
+       blendDest = ctx->Color.BlendDst;
+
+       switch( blendDest ) 
+       {
+       case GL_ZERO:                   
+           DPF(( 0, "\tDST Blend\tGL_ZERO" ));
+           break;
+       case GL_ONE:                     
+           DPF(( 0, "\tDST Blend\tGL_ONE" ));
+           break;
+       case GL_SRC_COLOR:               
+           DPF(( 0, "\tDST Blend\tGL_SRC_COLOR" ));
+           break;
+       case GL_ONE_MINUS_SRC_COLOR:     
+           DPF(( 0, "\tDST Blend\tGL_ONE_MINUS_SRC_COLOR" ));
+           break;
+       case GL_SRC_ALPHA:               
+           DPF(( 0, "\tDST Blend\tGL_SRC_ALPHA" ));
+           break;
+       case GL_ONE_MINUS_SRC_ALPHA:     
+           DPF(( 0, "\tDST Blend\tGL_ONE_MINUS_SRC_ALPHA" ));
+           break;
+       case GL_DST_ALPHA:               
+           DPF(( 0, "\tDST Blend\tGL_DST_ALPHA" ));
+           break;
+       case GL_ONE_MINUS_DST_ALPHA:     
+           DPF(( 0, "\tDST Blend\tGL_ONE_MINUS_DST_ALPHA" ));
+           break;
+       case GL_CONSTANT_COLOR:          
+           DPF(( 0, "\tDST Blend\tGL_CONSTANT_COLOR" ));
+           break;
+       case GL_ONE_MINUS_CONSTANT_COLOR:
+           DPF(( 0, "\tDST Blend\tGL_ONE_MINUS_CONSTANT_COLOR" ));
+           break;
+       case GL_CONSTANT_ALPHA:          
+           DPF(( 0, "\tDST Blend\tGL_CONSTANT_ALPHA" ));
+           break;
+       case GL_ONE_MINUS_CONSTANT_ALPHA:
+           DPF(( 0, "\tDST Blend\tGL_ONE_MINUS_CONSTANT_ALPHA" ));
+           break;
+       }
+   }   
+}
+\1a
diff --git a/src/mesa/drivers/d3d/DDrawPROCS.c b/src/mesa/drivers/d3d/DDrawPROCS.c
new file mode 100644 (file)
index 0000000..33a1e47
--- /dev/null
@@ -0,0 +1,400 @@
+/*===========================================================================*/\r
+/*                                                                           */\r
+/* Mesa-3.0 DirectX 6 Driver                                                */\r
+/*                                                                           */\r
+/* By Leigh McRae                                                            */\r
+/*                                                                           */\r
+/* http://www.altsoftware.com/                                               */\r
+/*                                                                           */\r
+/* Copyright (c) 1999-1998  alt.software inc.  All Rights Reserved           */\r
+/*===========================================================================*/\r
+#include "D3DMesa.h"\r
+/*===========================================================================*/\r
+/*  This call will clear the render surface using the pixel info built from  */\r
+/* the surface at creation time.  The call uses Lock/Unlock to access the    */\r
+/* surface.  The call also special cases a full clear or a dirty rectangle.  */\r
+/*  Finally the call returns the new clear mask that reflects that the color */\r
+/* buffer was cleared.                                                       */\r
+/*===========================================================================*/\r
+/* RETURN: the original mask with the bits cleared that represents the buffer*/\r
+/* or buffers we just cleared.                                               */\r
+/*===========================================================================*/\r
+GLbitfield ClearBuffers( GLcontext *ctx, GLbitfield mask, GLboolean all, GLint x, GLint y, GLint width, GLint height )\r
+{\r
+   D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;\r
+   DDSURFACEDESC2 *pddsd2;\r
+   UCHAR          *pBuffer,\r
+                  *pScanLine;\r
+   int            index,\r
+                     index2;\r
+   DWORD          dwColor;\r
+\r
+   if ( mask & GL_COLOR_BUFFER_BIT )\r
+   {\r
+       /* Lock the surface to get the surface pointer. */\r
+       pddsd2 = LockHAL( pContext->pShared, TRUE );\r
+   \r
+       /* Solve the color once only. */\r
+       dwColor =  ( ((DWORD)((float)pContext->rClear * pContext->pShared->pixel.rScale)) << pContext->pShared->pixel.rShift );\r
+       dwColor |= ( ((DWORD)((float)pContext->gClear * pContext->pShared->pixel.gScale)) << pContext->pShared->pixel.gShift );\r
+       dwColor |= ( ((DWORD)((float)pContext->bClear * pContext->pShared->pixel.bScale)) << pContext->pShared->pixel.bShift );\r
+   \r
+       if ( all ) \r
+       {\r
+         for( index = 0, pScanLine = (UCHAR *)pddsd2->lpSurface; index < pContext->pShared->dwHeight; index++, pScanLine += pddsd2->lPitch )\r
+           for( pBuffer = pScanLine, index2 = 0; index2 < pContext->pShared->dwWidth; index2++, pBuffer += pContext->pShared->pixel.cb )\r
+               memcpy( pBuffer, &dwColor, pContext->pShared->pixel.cb );\r
+       }\r
+       else\r
+       {\r
+         pScanLine = ((UCHAR *)pddsd2->lpSurface) +\r
+                   ( (FLIP( pContext->pShared->dwHeight, (y+height)) * pddsd2->lPitch) + (x * pContext->pShared->pixel.cb) );\r
+\r
+         for( index = 0; index < height; index++, pScanLine += pddsd2->lPitch )\r
+         {\r
+           for( index2 = 0, pBuffer = pScanLine; index2 < width; index2++, pBuffer += pContext->pShared->pixel.cb )\r
+                memcpy( pBuffer, &dwColor, pContext->pShared->pixel.cb );\r
+         }\r
+       }\r
+   \r
+       UnlockHAL( pContext->pShared, TRUE );\r
+   }\r
+   \r
+   return (mask & ~GL_COLOR_BUFFER_BIT);\r
+}\r
+/*===========================================================================*/\r
+/*  This proc (as all others) has been written for the general case. I use   */\r
+/* the PIXELINFO structure to pack the pixel from RGB24 to whatever the Off- */\r
+/* Screen render surface uses.  The alpha is ignored as Mesa does it in SW.  */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */ \r
+/*===========================================================================*/\r
+void WSpanRGB( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte rgb[][3], const GLubyte mask[] )\r
+{\r
+   D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;\r
+   DDSURFACEDESC2 *pddsd2;\r
+   UCHAR          *pBuffer;\r
+   int            index;\r
+   DWORD          dwColor;\r
+\r
+   /* Get the surface pointer and the pitch. */\r
+   pddsd2 = LockHAL( pContext->pShared, TRUE );\r
+\r
+   /* Find the start of the span. Invert y for Windows. */\r
+   pBuffer = (UCHAR *)pddsd2->lpSurface + (FLIP(pContext->pShared->dwHeight,y) * pddsd2->lPitch) + (x*pContext->pShared->pixel.cb);\r
+\r
+   if ( mask ) \r
+   {\r
+       for( index = 0; index < n; index++, pBuffer += pContext->pShared->pixel.cb )\r
+       {\r
+         if ( mask[index] )\r
+         {\r
+           /* Pack the color components. */\r
+           dwColor =  ( ((DWORD)((float)rgb[index][RCOMP] * pContext->pShared->pixel.rScale)) << pContext->pShared->pixel.rShift );\r
+           dwColor |= ( ((DWORD)((float)rgb[index][GCOMP] * pContext->pShared->pixel.gScale)) << pContext->pShared->pixel.gShift );\r
+           dwColor |= ( ((DWORD)((float)rgb[index][BCOMP] * pContext->pShared->pixel.bScale)) << pContext->pShared->pixel.bShift );\r
+           memcpy( pBuffer, &dwColor, pContext->pShared->pixel.cb );\r
+         }\r
+       }       \r
+   }\r
+   else\r
+   {\r
+       for( index = 0; index < n; index++, pBuffer += pContext->pShared->pixel.cb )\r
+       {\r
+         /* Pack the color components. */\r
+         dwColor =  ( ((DWORD)((float)rgb[index][RCOMP] * pContext->pShared->pixel.rScale)) << pContext->pShared->pixel.rShift );\r
+         dwColor |= ( ((DWORD)((float)rgb[index][GCOMP] * pContext->pShared->pixel.gScale)) << pContext->pShared->pixel.gShift );\r
+         dwColor |= ( ((DWORD)((float)rgb[index][BCOMP] * pContext->pShared->pixel.bScale)) << pContext->pShared->pixel.bShift );\r
+         memcpy( pBuffer, &dwColor, pContext->pShared->pixel.cb );\r
+       }\r
+   }\r
+\r
+   /* Giver back. */\r
+   UnlockHAL( pContext->pShared, TRUE );\r
+}\r
+/*===========================================================================*/\r
+/*  This proc (as all others) has been written for the general case. I use   */\r
+/* the PIXELINFO structure to pack the pixel from RGB24 to whatever the Off- */\r
+/* Screen render surface uses.  The alpha is ignored as Mesa does it in SW.  */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */ \r
+/*===========================================================================*/\r
+void WSpanRGBA( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte rgba[][4], const GLubyte mask[] )\r
+{\r
+   D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;\r
+   DDSURFACEDESC2 *pddsd2;\r
+   UCHAR          *pBuffer;\r
+   int            index;\r
+   DWORD          dwColor;\r
+\r
+   /* Get the surface pointer and the pitch. */\r
+   pddsd2 = LockHAL( pContext->pShared, TRUE );\r
+\r
+   /* Find the start of the span. Invert y for Windows. */\r
+   pBuffer = (UCHAR *)pddsd2->lpSurface + (FLIP(pContext->pShared->dwHeight,y) * pddsd2->lPitch) + (x*pContext->pShared->pixel.cb);\r
+\r
+   if ( mask ) \r
+   {\r
+       for( index = 0; index < n; index++, pBuffer += pContext->pShared->pixel.cb )\r
+       {\r
+         if ( mask[index] )\r
+         {\r
+         /* Pack the color components. */\r
+           dwColor =  ( ((DWORD)((float)rgba[index][RCOMP] * pContext->pShared->pixel.rScale)) << pContext->pShared->pixel.rShift );\r
+           dwColor |= ( ((DWORD)((float)rgba[index][GCOMP] * pContext->pShared->pixel.gScale)) << pContext->pShared->pixel.gShift );\r
+           dwColor |= ( ((DWORD)((float)rgba[index][BCOMP] * pContext->pShared->pixel.bScale)) << pContext->pShared->pixel.bShift );\r
+           memcpy( pBuffer, &dwColor, pContext->pShared->pixel.cb );\r
+         }\r
+       }       \r
+   }\r
+   else\r
+   {\r
+       for( index = 0; index < n; index++, pBuffer += pContext->pShared->pixel.cb )\r
+       {\r
+         /* Pack the color components. */\r
+         dwColor =  ( ((DWORD)((float)rgba[index][RCOMP] * pContext->pShared->pixel.rScale)) << pContext->pShared->pixel.rShift );\r
+         dwColor |= ( ((DWORD)((float)rgba[index][GCOMP] * pContext->pShared->pixel.gScale)) << pContext->pShared->pixel.gShift );\r
+         dwColor |= ( ((DWORD)((float)rgba[index][BCOMP] * pContext->pShared->pixel.bScale)) << pContext->pShared->pixel.bShift );\r
+         memcpy( pBuffer, &dwColor, pContext->pShared->pixel.cb );\r
+       }\r
+   }\r
+\r
+   /* Giver back. */\r
+   UnlockHAL( pContext->pShared, TRUE );\r
+}\r
+/*===========================================================================*/\r
+/*  This proc (as all others) has been written for the general case. I use   */\r
+/* the PIXELINFO structure to pack the pixel from RGB24 to whatever the Off- */\r
+/* Screen render surface uses.  The color is solved once from the current    */\r
+/* color components.  The alpha is ignored as Mesa is doing it in SW.        */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */ \r
+/*===========================================================================*/\r
+void WSpanRGBAMono( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte mask[] )\r
+{\r
+   D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;\r
+   DDSURFACEDESC2 *pddsd2;\r
+   UCHAR          *pBuffer;\r
+   int            index;\r
+   DWORD          dwColor;\r
+\r
+   /* Lock the surface to get the surface pointer and the pitch. */\r
+   pddsd2 = LockHAL( pContext->pShared, TRUE );\r
+\r
+   /* Solve the color once only. (no alpha) */\r
+   dwColor =  ( ((DWORD)((float)pContext->rCurrent * pContext->pShared->pixel.rScale)) << pContext->pShared->pixel.rShift );\r
+   dwColor |= ( ((DWORD)((float)pContext->gCurrent * pContext->pShared->pixel.gScale)) << pContext->pShared->pixel.gShift );\r
+   dwColor |= ( ((DWORD)((float)pContext->bCurrent * pContext->pShared->pixel.bScale)) << pContext->pShared->pixel.bShift );\r
+\r
+   /* Find the start of the span. Invert y for Windows. */\r
+   pBuffer = (UCHAR *)pddsd2->lpSurface + (FLIP(pContext->pShared->dwHeight,y) * pddsd2->lPitch) + (x*pContext->pShared->pixel.cb);\r
+\r
+   if ( mask ) \r
+   {\r
+       for( index = 0; index < n; index++, pBuffer += pContext->pShared->pixel.cb )\r
+         if ( mask[index] )\r
+           memcpy( pBuffer, &dwColor, pContext->pShared->pixel.cb );\r
+   }\r
+   else\r
+   {\r
+       for( index = 0; index < n; index++, pBuffer += pContext->pShared->pixel.cb )\r
+         memcpy( pBuffer, &dwColor, pContext->pShared->pixel.cb );\r
+   }\r
+\r
+   /* Giver back. */\r
+   UnlockHAL( pContext->pShared, TRUE );\r
+}\r
+/*===========================================================================*/\r
+/*  This proc (as all others) has been written for the general case. I use   */\r
+/* the PIXELINFO structure to pack the pixel from RGB24 to whatever the Off- */\r
+/* Screen render surface uses.  The alpha is ignored as Mesa does it in SW.  */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */ \r
+/*===========================================================================*/\r
+void WPixelsRGBA( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], const GLubyte rgba[][4], const GLubyte mask[] )\r
+{\r
+   D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;\r
+   DDSURFACEDESC2 *pddsd2;\r
+   UCHAR          *pBuffer;\r
+   int            index;\r
+   DWORD          dwColor;\r
+\r
+   /* Get the surface pointer and the pitch. */\r
+   pddsd2 = LockHAL( pContext->pShared, TRUE );\r
+\r
+   if ( mask ) \r
+   {\r
+       for( index = 0; index < n; index++ )\r
+       {\r
+         if ( mask[index] )\r
+         {\r
+           /* Pack the color components. */\r
+           dwColor =  ( ((DWORD)((float)rgba[index][RCOMP] * pContext->pShared->pixel.rScale)) << pContext->pShared->pixel.rShift );\r
+           dwColor |= ( ((DWORD)((float)rgba[index][GCOMP] * pContext->pShared->pixel.gScale)) << pContext->pShared->pixel.gShift );\r
+           dwColor |= ( ((DWORD)((float)rgba[index][BCOMP] * pContext->pShared->pixel.bScale)) << pContext->pShared->pixel.bShift );\r
+\r
+           /* Find the pixel. Invert y for Windows. */\r
+           pBuffer = (UCHAR *)pddsd2->lpSurface + (FLIP(pContext->pShared->dwHeight,y[index]) * pddsd2->lPitch) + (x[index]*pContext->pShared->pixel.cb);\r
+           memcpy( pBuffer, &dwColor, pContext->pShared->pixel.cb );\r
+         }\r
+       }\r
+   }\r
+   else\r
+   {\r
+       for( index = 0; index < n; index++ )\r
+       {\r
+         /* Pack the color components. */\r
+         dwColor =  ( ((DWORD)((float)rgba[index][RCOMP] * pContext->pShared->pixel.rScale)) << pContext->pShared->pixel.rShift );\r
+         dwColor |= ( ((DWORD)((float)rgba[index][GCOMP] * pContext->pShared->pixel.gScale)) << pContext->pShared->pixel.gShift );\r
+         dwColor |= ( ((DWORD)((float)rgba[index][BCOMP] * pContext->pShared->pixel.bScale)) << pContext->pShared->pixel.bShift );\r
+\r
+         /* Find the pixel. Invert y for Windows. */\r
+         pBuffer = (UCHAR *)pddsd2->lpSurface + (FLIP(pContext->pShared->dwHeight,y[index]) * pddsd2->lPitch) + (x[index]*pContext->pShared->pixel.cb);\r
+         memcpy( pBuffer, &dwColor, pContext->pShared->pixel.cb );\r
+       }\r
+   }\r
+\r
+   /* Giver back. */\r
+   UnlockHAL( pContext->pShared, TRUE );\r
+}\r
+/*===========================================================================*/\r
+/*  This proc (as all others) has been written for the general case. I use   */\r
+/* the PIXELINFO structure to pack the pixel from RGB24 to whatever the Off- */\r
+/* Screen render surface uses.  The color is solved once from the current    */\r
+/* color components.  The alpha is ignored as Mesa is doing it in SW.        */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */ \r
+/*===========================================================================*/\r
+void WPixelsRGBAMono( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], const GLubyte mask[] )\r
+{\r
+   D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;\r
+   DDSURFACEDESC2 *pddsd2;\r
+   UCHAR          *pBuffer;\r
+   int            index;\r
+   DWORD          dwColor;\r
+\r
+   /* Get the surface pointer and the pitch. */\r
+   pddsd2 = LockHAL( pContext->pShared, TRUE );\r
+\r
+   /* Solve the color once only. I don't uses the alpha. */\r
+   dwColor =  ( ((DWORD)((float)pContext->rCurrent * pContext->pShared->pixel.rScale)) << pContext->pShared->pixel.rShift );\r
+   dwColor |= ( ((DWORD)((float)pContext->gCurrent * pContext->pShared->pixel.gScale)) << pContext->pShared->pixel.gShift );\r
+   dwColor |= ( ((DWORD)((float)pContext->bCurrent * pContext->pShared->pixel.bScale)) << pContext->pShared->pixel.bShift );\r
+\r
+   if ( mask ) \r
+   {\r
+       /* We store the surface pointer as a UCHAR so that pixel.cb (count in btyles) will work for all. */\r
+       for( index = 0; index < n; index++ )\r
+       {\r
+         if ( mask[index] )\r
+         {\r
+           /* Find the pixel. Invert y for Windows. */\r
+           pBuffer = (UCHAR *)pddsd2->lpSurface + (FLIP(pContext->pShared->dwHeight,y[index]) * pddsd2->lPitch) + (x[index]*pContext->pShared->pixel.cb);\r
+           memcpy( pBuffer, &dwColor, pContext->pShared->pixel.cb );\r
+         }\r
+       }\r
+   }\r
+   else\r
+   {\r
+       /* We store the surface pointer as a UCHAR so that pixel.cb (count in btyles) will work for all. */\r
+       for( index = 0; index < n; index++ )\r
+       {\r
+         /* Find the pixel. Invert y for Windows. */\r
+         pBuffer = (UCHAR *)pddsd2->lpSurface + (FLIP(pContext->pShared->dwHeight,y[index]) * pddsd2->lPitch) + (x[index]*pContext->pShared->pixel.cb);\r
+         memcpy( pBuffer, &dwColor, pContext->pShared->pixel.cb );\r
+       }\r
+   }\r
+\r
+   /* Giver back. */\r
+   UnlockHAL( pContext->pShared, TRUE );\r
+}\r
+/*===========================================================================*/\r
+/*  This proc isn't written for speed rather its to handle the general case. */\r
+/* I grab each pixel from the surface and unpack the info using the PIXELINFO*/\r
+/* structure that was generated from the OffScreen surface pixelformat.  The */\r
+/* function will not fill in the alpha value as Mesa I have Mesa allocate its*/\r
+/* own alpha channel when the context was created.  I did this as I didn't   */\r
+/* feel that it was worth the effort to try and get HW to work (bus bound).  */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+void RSpanRGBA( const GLcontext* ctx, GLuint n, GLint x, GLint y, GLubyte rgba[][4] )\r
+{\r
+   D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;\r
+   DDSURFACEDESC2 *pddsd2;\r
+   UCHAR          *pBuffer;\r
+   int            index;\r
+   DWORD          *pdwColor;\r
+\r
+   /* Get the surface pointer and the pitch. */\r
+   pddsd2 = LockHAL( pContext->pShared, TRUE );\r
+\r
+   /* Find the start of the span. Invert y for Windows. */\r
+   pBuffer = (UCHAR *)pddsd2->lpSurface + \r
+                        (FLIP(pContext->pShared->dwHeight,y) * pddsd2->lPitch) + \r
+                        (x*pContext->pShared->pixel.cb);\r
+\r
+   /* We store the surface pointer as a UCHAR so that pixel.cb (count in btyles) will work for all. */\r
+   for( index = 0; index < n; index++, pBuffer += pContext->pShared->pixel.cb )\r
+   {\r
+       pdwColor = (DWORD *)pBuffer;\r
+       rgba[index][RCOMP] = (GLubyte)((float)((*pdwColor & pContext->pShared->pixel.dwRMask) >> pContext->pShared->pixel.rShift) / pContext->pShared->pixel.rScale);\r
+       rgba[index][GCOMP] = (GLubyte)((float)((*pdwColor & pContext->pShared->pixel.dwGMask) >> pContext->pShared->pixel.gShift) / pContext->pShared->pixel.gScale);\r
+       rgba[index][BCOMP] = (GLubyte)((float)((*pdwColor & pContext->pShared->pixel.dwBMask) >> pContext->pShared->pixel.bShift) / pContext->pShared->pixel.bScale);\r
+   }\r
+\r
+   /* Giver back. */\r
+   UnlockHAL( pContext->pShared, TRUE );\r
+}\r
+/*===========================================================================*/\r
+/*  This proc isn't written for speed rather its to handle the general case. */\r
+/* I grab each pixel from the surface and unpack the info using the PIXELINFO*/\r
+/* structure that was generated from the OffScreen surface pixelformat.  The */\r
+/* function will not fill in the alpha value as Mesa I have Mesa allocate its*/\r
+/* own alpha channel when the context was created.  I did this as I didn't   */\r
+/* feel that it was worth the effort to try and get HW to work (bus bound).  */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+void RPixelsRGBA( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], GLubyte rgba[][4], const GLubyte mask[] )\r
+{\r
+   D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;\r
+   DDSURFACEDESC2 *pddsd2;\r
+   int            index;\r
+   DWORD          *pdwColor;\r
+\r
+   /* Get the surface pointer and the pitch. */\r
+   pddsd2 = LockHAL( pContext->pShared, TRUE );\r
+\r
+   if ( mask )\r
+   {\r
+       /* We store the surface pointer as a UCHAR so that pixel.cb (count in btyles) will work for all. */\r
+       for( index = 0; index < n; index++ )\r
+       {\r
+         if ( mask[index] )\r
+         {\r
+           /* Find the start of the pixel. Invert y for Windows. */\r
+           pdwColor = (DWORD *)((UCHAR *)pddsd2->lpSurface + (FLIP(pContext->pShared->dwHeight,y[index]) * pddsd2->lPitch) + (x[index]*pContext->pShared->pixel.cb));\r
+           rgba[index][RCOMP] = (GLubyte)((float)((*pdwColor & pContext->pShared->pixel.dwRMask) >> pContext->pShared->pixel.rShift) / pContext->pShared->pixel.rScale);\r
+           rgba[index][GCOMP] = (GLubyte)((float)((*pdwColor & pContext->pShared->pixel.dwGMask) >> pContext->pShared->pixel.gShift) / pContext->pShared->pixel.gScale);\r
+           rgba[index][BCOMP] = (GLubyte)((float)((*pdwColor & pContext->pShared->pixel.dwBMask) >> pContext->pShared->pixel.bShift) / pContext->pShared->pixel.bScale);\r
+         }\r
+       }\r
+   }\r
+   else\r
+   {\r
+       /* We store the surface pointer as a UCHAR so that pixel.cb (count in btyles) will work for all. */\r
+       for( index = 0; index < n; index++ )\r
+       {\r
+         /* Find the start of the pixel. Invert y for Windows. */\r
+         pdwColor = (DWORD *)((UCHAR *)pddsd2->lpSurface + (FLIP(pContext->pShared->dwHeight,y[index]) * pddsd2->lPitch) + (x[index]*pContext->pShared->pixel.cb));\r
+         rgba[index][RCOMP] = (GLubyte)((float)((*pdwColor & pContext->pShared->pixel.dwRMask) >> pContext->pShared->pixel.rShift) / pContext->pShared->pixel.rScale);\r
+         rgba[index][GCOMP] = (GLubyte)((float)((*pdwColor & pContext->pShared->pixel.dwGMask) >> pContext->pShared->pixel.gShift) / pContext->pShared->pixel.gScale);\r
+         rgba[index][BCOMP] = (GLubyte)((float)((*pdwColor & pContext->pShared->pixel.dwBMask) >> pContext->pShared->pixel.bShift) / pContext->pShared->pixel.bScale);\r
+       }\r
+   }\r
+\r
+   /* Giver back. */\r
+   UnlockHAL( pContext->pShared, TRUE );\r
+}\r
+\1a
\ No newline at end of file
diff --git a/src/mesa/drivers/d3d/DEBUG.C b/src/mesa/drivers/d3d/DEBUG.C
new file mode 100644 (file)
index 0000000..26c2c25
--- /dev/null
@@ -0,0 +1,144 @@
+/*===========================================================================*/\r
+/*                                                                           */\r
+/* Mesa-3.0 DirectX 6 Driver                                                 */\r
+/*                                                                           */\r
+/* By Leigh McRae                                                            */\r
+/*                                                                           */\r
+/* http://www.altsoftware.com/                                               */\r
+/*                                                                           */\r
+/* Copyright (c) 1999-1998  alt.software inc.  All Rights Reserved           */\r
+/*===========================================================================*/\r
+#include "Debug.h"\r
+/*===========================================================================*/\r
+/* Global variables.                                                         */\r
+/*===========================================================================*/\r
+DWORD  g_DBGMask = DBG_ALL_ERROR;\r
+/*===========================================================================*/\r
+/*  This is your basic DPF function with printf like support.  The function  */\r
+/* also works with a global debug mask variable.  I have written support that*/\r
+/* allows for the user's enviroment variable space to be read and set the    */\r
+/* masks.  This is done when the dll starts and is only in the debug version.*/\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+void _cdecl DebugPrint( int mask, char *pszFormat, ... )\r
+{\r
+  char buffer[512];\r
+  va_list      args;\r
+\r
+  /* A mask of 0 will always pass. Easy to remeber. */\r
+  if ( (mask == 0) || (mask & g_DBGMask) ) \r
+  {\r
+    va_start( args, pszFormat );\r
+\r
+    if ( mask & DBG_ALL_ERROR ) \r
+        OutputDebugString( "MesaD3D: (ERROR)" ); \r
+    else\r
+        OutputDebugString( "MesaD3D: " ); \r
+\r
+    vsprintf( buffer, pszFormat, args );\r
+    strcat( buffer, "\n" );\r
+    OutputDebugString( buffer );\r
+\r
+    va_end( args );\r
+  }\r
+}\r
+/*===========================================================================*/\r
+/*  This call reads the users enviroment variables and sets any debug mask   */\r
+/* that they have set to TRUE.  Now the value must be "TRUE".                */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+void   ReadDBGEnv( void )\r
+{\r
+  g_DBGMask = DBG_ALL_ERROR;\r
+\r
+#define IS_VAR_SET(v)  if ( getenv( # v ) && !strcmp(getenv( # v ),"TRUE") ) g_DBGMask |= v;\r
+  \r
+  IS_VAR_SET( DBG_FUNC );\r
+  IS_VAR_SET( DBG_STATES );\r
+\r
+  IS_VAR_SET( DBG_CNTX_INFO );\r
+  IS_VAR_SET( DBG_CNTX_WARN );\r
+  IS_VAR_SET( DBG_CNTX_PROFILE );\r
+  IS_VAR_SET( DBG_CNTX_ERROR );\r
+  IS_VAR_SET( DBG_CNTX_ALL );\r
+\r
+  IS_VAR_SET( DBG_PRIM_INFO );\r
+  IS_VAR_SET( DBG_PRIM_WARN );\r
+  IS_VAR_SET( DBG_PRIM_PROFILE );\r
+  IS_VAR_SET( DBG_PRIM_ERROR );\r
+  IS_VAR_SET( DBG_PRIM_ALL );\r
+\r
+  IS_VAR_SET( DBG_TXT_INFO );\r
+  IS_VAR_SET( DBG_TXT_WARN );\r
+  IS_VAR_SET( DBG_TXT_PROFILE );\r
+  IS_VAR_SET( DBG_TXT_ERROR );\r
+  IS_VAR_SET( DBG_TXT_ALL );\r
+\r
+  IS_VAR_SET( DBG_ALL_INFO );\r
+  IS_VAR_SET( DBG_ALL_WARN );\r
+  IS_VAR_SET( DBG_ALL_PROFILE );\r
+  IS_VAR_SET( DBG_ALL_ERROR );\r
+  IS_VAR_SET( DBG_ALL );\r
+\r
+#undef IS_VAR_SET\r
+}\r
+/*===========================================================================*/\r
+/*  This function will take a pointer to a DDSURFACEDESC2 structure & display*/\r
+/* the parsed information using a DPF call.                                  */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+void   DebugPixelFormat( char *pszSurfaceName, DDPIXELFORMAT *pddpf )\r
+{\r
+  char buffer[256];\r
+\r
+  /* Parse the flag type and write the string equivalent. */\r
+  if ( pddpf->dwFlags & DDPF_ALPHA )\r
+       strcat( buffer, "DDPF_ALPHA " );\r
+  if ( pddpf->dwFlags & DDPF_ALPHAPIXELS )\r
+       strcat( buffer, "DDPF_ALPHAPIXELS " );\r
+  if ( pddpf->dwFlags & DDPF_ALPHAPREMULT )\r
+       strcat( buffer, "DDPF_ALPHAPREMULT " );\r
+  if ( pddpf->dwFlags & DDPF_BUMPLUMINANCE )\r
+       strcat( buffer, "DDPF_BUMPLUMINANCE " );\r
+  if ( pddpf->dwFlags & DDPF_BUMPDUDV )\r
+       strcat( buffer, "DDPF_BUMPDUDV " );\r
+  if ( pddpf->dwFlags & DDPF_COMPRESSED )\r
+       strcat( buffer, "DDPF_COMPRESSED " );\r
+  if ( pddpf->dwFlags & DDPF_FOURCC )\r
+       strcat( buffer, "DDPF_FOURCC " );\r
+  if ( pddpf->dwFlags & DDPF_LUMINANCE )\r
+       strcat( buffer, "DDPF_LUMINANCE " );\r
+  if ( pddpf->dwFlags & DDPF_PALETTEINDEXED1 )\r
+       strcat( buffer, "DDPF_PALETTEINDEXED1 " );\r
+  if ( pddpf->dwFlags & DDPF_PALETTEINDEXED2 )\r
+       strcat( buffer, "DDPF_PALETTEINDEXED2 " );\r
+  if ( pddpf->dwFlags & DDPF_PALETTEINDEXED4 )\r
+       strcat( buffer, "DDPF_PALETTEINDEXED4 " );\r
+  if ( pddpf->dwFlags & DDPF_PALETTEINDEXED8 )\r
+       strcat( buffer, "DDPF_PALETTEINDEXED8 " );\r
+  if ( pddpf->dwFlags & DDPF_PALETTEINDEXEDTO8 )\r
+       strcat( buffer, "DDPF_PALETTEINDEXEDTO8 " );\r
+  if ( pddpf->dwFlags & DDPF_RGB )\r
+       strcat( buffer, "DDPF_RGB  " );\r
+  if ( pddpf->dwFlags & DDPF_RGBTOYUV )\r
+       strcat( buffer, "DDPF_RGBTOYUV  " );\r
+  if ( pddpf->dwFlags & DDPF_STENCILBUFFER )\r
+       strcat( buffer, "DDPF_STENCILBUFFER  " );\r
+  if ( pddpf->dwFlags & DDPF_YUV )\r
+       strcat( buffer, "DDPF_YUV  " );\r
+  if ( pddpf->dwFlags & DDPF_ZBUFFER )\r
+       strcat( buffer, "DDPF_ZBUFFER  " );\r
+  if ( pddpf->dwFlags & DDPF_ZPIXELS )\r
+       strcat( buffer, "DDPF_ZPIXELS  " );\r
+\r
+  DPF(( (DBG_TXT_INFO|DBG_CNTX_INFO),"%s", buffer ));\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\1a
\ No newline at end of file
diff --git a/src/mesa/drivers/d3d/DEBUG.H b/src/mesa/drivers/d3d/DEBUG.H
new file mode 100644 (file)
index 0000000..e63d6c5
--- /dev/null
@@ -0,0 +1,91 @@
+/*===========================================================================*/\r
+/*                                                                           */\r
+/* Mesa-3.0 DirectX 6 Driver                                                 */\r
+/*                                                                           */\r
+/* By Leigh McRae                                                            */\r
+/*                                                                           */\r
+/* http://www.altsoftware.com/                                               */\r
+/*                                                                           */\r
+/* Copyright (c) 1999-1998  alt.software inc.  All Rights Reserved           */\r
+/*===========================================================================*/\r
+#ifndef _DEBUG_H\r
+#define _DEBUG_H\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+/*===========================================================================*/\r
+/* Includes.                                                                 */\r
+/*===========================================================================*/\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <ddraw.h>\r
+#include <d3d.h>\r
+#include "D3DShared.h"\r
+/*===========================================================================*/\r
+/* Magic numbers.                                                            */\r
+/*===========================================================================*/\r
+/*===========================================================================*/\r
+/* Macros defines.                                                           */\r
+/*===========================================================================*/\r
+#define DBG_FUNC                        0x00000001\r
+#define DBG_STATES              0x00000002\r
+\r
+#define DBG_CNTX_INFO           0x00000010\r
+#define DBG_CNTX_WARN           0x00000020\r
+#define DBG_CNTX_PROFILE        0x00000040\r
+#define DBG_CNTX_ERROR          0x00000080\r
+#define DBG_CNTX_ALL            0x000000F0\r
+\r
+#define DBG_PRIM_INFO           0x00000100\r
+#define DBG_PRIM_WARN           0x00000200\r
+#define DBG_PRIM_PROFILE        0x00000400\r
+#define DBG_PRIM_ERROR          0x00000800\r
+#define DBG_PRIM_ALL            0x00000F00\r
+\r
+#define DBG_TXT_INFO            0x00001000\r
+#define DBG_TXT_WARN            0x00002000\r
+#define DBG_TXT_PROFILE 0x00004000\r
+#define DBG_TXT_ERROR           0x00008000\r
+#define DBG_TXT_ALL             0x0000F000\r
+\r
+#define DBG_ALL_INFO            0x11111110\r
+#define DBG_ALL_WARN            0x22222220\r
+#define DBG_ALL_PROFILE 0x44444440\r
+#define DBG_ALL_ERROR           0x88888880\r
+#define DBG_ALL                 0xFFFFFFFF\r
+\r
+#ifdef D3D_DEBUG\r
+#       define  DPF(arg)                        DebugPrint arg \r
+#       define  RIP(pH,msg,err) OutputDebugString(msg); \\r
+                                                       OutputDebugString(err); \\r
+                                                       OutputDebugString("\n"); \\r
+                                                       FatalShutDown(pH)\r
+#else\r
+#       define  DPF(arg)\r
+#       define  RIP(pH,msg,err) FatalShutDown(pH)\r
+#endif\r
+/*===========================================================================*/\r
+/* Type defines.                                                             */\r
+/*===========================================================================*/\r
+/*===========================================================================*/\r
+/* Function prototypes.                                                      */\r
+/*===========================================================================*/\r
+extern void ReadDBGEnv( void );\r
+extern void _cdecl DebugPrint( int mask, char *pszFormat, ... );\r
+extern void DebugPixelFormat( char *pszSurfaceName, DDPIXELFORMAT *pddpf );\r
+/*===========================================================================*/\r
+/* Global variables.                                                         */\r
+/*===========================================================================*/\r
+extern DWORD    g_DBGMask;\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
+\r
+\r
+\r
+\1a
\ No newline at end of file
diff --git a/src/mesa/drivers/d3d/DbgEnv.bat b/src/mesa/drivers/d3d/DbgEnv.bat
new file mode 100644 (file)
index 0000000..40858e6
--- /dev/null
@@ -0,0 +1,25 @@
+SET DBG_FUNC=FALSE\r
+\r
+SET DBG_CNTX_INFO=TRUE\r
+SET DBG_CNTX_WARN=TRUE\r
+SET DBG_CNTX_PROFILE=FALSE\r
+SET DBG_CNTX_ERROR=TRUE\r
+SET DBG_CNTX_ALL=TRUE\r
+\r
+SET DBG_PRIM_INFO=FALSE\r
+SET DBG_PRIM_WARN=FALSE\r
+SET DBG_PRIM_PROFILE=FALSE\r
+SET DBG_PRIM_ERROR=TRUE\r
+SET DBG_PRIM_ALL=FALSE\r
+\r
+SET DBG_TXT_INFO=FALSE\r
+SET DBG_TXT_WARN=TRUE\r
+SET DBG_TXT_PROFILE=FALSE\r
+SET DBG_TXT_ERROR=TRUE\r
+SET DBG_TXT_ALL=FALSE\r
+\r
+SET DBG_ALL_INFO=FALSE\r
+SET DBG_ALL_WARN=TRUE\r
+SET DBG_ALL_PROFILE=FALSE\r
+SET DBG_ALL_ERROR=TRUE\r
+SET DBG_ALL=FALSE\r
diff --git a/src/mesa/drivers/d3d/MAKEFILE b/src/mesa/drivers/d3d/MAKEFILE
new file mode 100644 (file)
index 0000000..59734cf
--- /dev/null
@@ -0,0 +1,102 @@
+##############################################################################\r
+# \r
+# Mesa-3.0 Makefile for DirectX 6 Driver                             \r
+#\r
+# By Leigh McRae\r
+#\r
+# http://www.altsoftware.com/\r
+#\r
+# Copyright (c) 1999-1998  alt.software inc.  All Rights Reserved     \r
+##############################################################################\r
+NAME=\r
+TARGET= WGL Driver (D3DHAL)\r
+\r
+D3D_DIR=$(MAKEDIR)\D3D\r
+TARGET_DIR=e:\WinNT\System32\r
+TEMP_DIR=c:\Temp\r
+\r
+SPACE=-\r
+LINKER=link.exe\r
+\r
+INCLUDE=$(SDKROOT)\include;$(INCLUDE)\r
+LIB=$(SDKROOT)\lib;$(LIB)\r
+##############################################################################\r
+CFLAGS  = /c /nologo /W1 /G5 /I..\ /I..\..\Include \\r
+               /D "_WIN32" /D "WIN32" /D "_WINDOWS" /D "__WIN32__" /D "__MSC__"  /D "MESAD3D"\r
+CPPFLAGS= /c /nologo /W1 /G5 /I..\ /I..\..\Include \\r
+               /D "_WIN32" /D "WIN32" /D "_WINDOWS" /D "__WIN32__" /D "__MSC__"  /D "MESAD3D"\r
+\r
+!IF "$(DEBUG)" == "1"\r
+\r
+CFLAGS   = /MTd /Od /Z7 /Yd /D "_DEBUG" /D "D3D_DEBUG" $(CFLAGS)\r
+CPPFLAGS = /MTd /Od /Z7 /Yd /D "_DEBUG" /D "D3D_DEBUG" $(CPPFLAGS)\r
+BUILD_TYPE=debug\r
+\r
+!ELSE\r
+\r
+CFLAGS   = /MT /Ox /D "NDEBUG" $(CFLAGS)\r
+CPPFLAGS = /MT /Ox /D "NDEBUG" $(CPPFLAGS)\r
+BUILD_TYPE=release\r
+\r
+!ENDIF\r
+##############################################################################\r
+SRCS_WGL = wgl.c D3Dvbrender.c DDrawPROCS.c NULLProcs.c Debug.c\r
+SRCS_HAL = D3DInit.cpp D3DRaster.cpp D3DTextureMgr.cpp D3DUtils.cpp D3DCaps.cpp\r
+OBJS_WGL = $(SRCS_WGL:.c=.obj)\r
+OBJS_HAL = $(SRCS_HAL:.cpp=.obj)\r
+\r
+WINLIBS = kernel32.lib user32.lib gdi32.lib oldnames.lib \r
+DXLIBS = \r
+LIBS = $(WINLIBS) $(DXLIBS) \r
+###############################################################################\r
+# Primary Targets                                                             #\r
+###############################################################################\r
+\r
+default: header WGL HAL footer\r
+\r
+all: default \r
+\r
+WGL : $(OBJS_WGL) \r
+        \r
+HAL : $(OBJS_HAL)\r
+\r
+install : forceit\r
+       @echo $(SPACE)\r
+       @echo ========================================\r
+       @echo Install files created.\r
+       @echo ========================================\r
+\r
+        \r
+###############################################################################\r
+# Secondary Targets                                                           #\r
+###############################################################################\r
+\r
+clean:\r
+       @echo ========================================\r
+       @echo Cleaning $(TARGET)\r
+       @del *.obj \r
+       @del *.dep \r
+       @del *.exp \r
+       @del *.ncb\r
+       @del *.plg\r
+       @del *.lib\r
+       @echo ========================================\r
+\r
+header:\r
+       @echo ============================================================\r
+       @echo Building $(TARGET)  ($(BUILD_TYPE) version)\r
+       @echo ============================================================\r
+       @echo $(SPACE)\r
+\r
+footer:\r
+       @echo $(SPACE)\r
+       @echo ============================================================\r
+       @echo DONE building $(TARGET)  ($(BUILD_TYPE) version)\r
+       @echo ============================================================\r
+\r
+forceit:\r
+\r
+\r
+\r
+\r
+\1a
\ No newline at end of file
diff --git a/src/mesa/drivers/d3d/NULLProcs.h b/src/mesa/drivers/d3d/NULLProcs.h
new file mode 100644 (file)
index 0000000..f0bbd21
--- /dev/null
@@ -0,0 +1,49 @@
+/*===========================================================================*/
+/*                                                                           */
+/* Mesa-3.0 DirectX 6 Driver                                                 */
+/*                                                                           */
+/* By Leigh McRae                                                            */
+/*                                                                           */
+/* http://www.altsoftware.com/                                               */
+/*                                                                           */
+/* Copyright (c) 1999-1998  alt.software inc.  All Rights Reserved           */
+/*===========================================================================*/
+#ifndef NULL_MESA_PROCS_INC
+#define NULL_MESA_PROCS_INC
+/*===========================================================================*/
+/* Includes.                                                                 */
+/*===========================================================================*/
+#include "matrix.h"
+#include "context.h"
+#include "types.h"
+#include "vb.h"
+/*===========================================================================*/
+/* Macros.                                                                   */
+/*===========================================================================*/
+/*===========================================================================*/
+/* Magic numbers.                                                            */
+/*===========================================================================*/
+/*===========================================================================*/
+/* Type defines.                                                             */
+/*===========================================================================*/
+void NULLSetColor( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a );
+void NULLClearColor( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a );
+GLboolean NULLSetBuffer( GLcontext *ctx, GLenum mode );
+void NULLGetBufferSize( GLcontext *ctx, GLuint *width, GLuint *height );
+GLbitfield NULLClearBuffers( GLcontext *ctx, GLbitfield m, GLboolean a, GLint x, GLint y, GLint w, GLint h );
+void NULLWrSpRGB( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte r[][3], const GLubyte m[] );
+void NULLWrSpRGBA( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte r[][4], const GLubyte m[] );
+void NULLWrSpRGBAMono( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte m[] );
+void NULLWrPiRGBA( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], const GLubyte r[][4], const GLubyte m[] );
+void NULLWrPiRGBAMono( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], const GLubyte m[] );
+void NULLReSpRGBA( const GLcontext* ctx, GLuint n, GLint x, GLint y, GLubyte r[][4] );
+void NULLRePiRGBA( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], GLubyte r[][4], const GLubyte m[] );
+/*===========================================================================*/
+/* Extern function prototypes.                                               */
+/*===========================================================================*/
+/*===========================================================================*/
+/* Global variables.                                                         */
+/*===========================================================================*/
+
+#endif
+
diff --git a/src/mesa/drivers/d3d/NullProcs.c b/src/mesa/drivers/d3d/NullProcs.c
new file mode 100644 (file)
index 0000000..e8f1854
--- /dev/null
@@ -0,0 +1,130 @@
+/*===========================================================================*/\r
+/*                                                                           */\r
+/* Mesa-3.0 DirectX 6 Driver                                                 */\r
+/*                                                                           */\r
+/* By Leigh McRae                                                            */\r
+/*                                                                           */\r
+/* http://www.altsoftware.com/                                               */\r
+/*                                                                           */\r
+/* Copyright (c) 1999-1998  alt.software inc.  All Rights Reserved           */\r
+/*===========================================================================*/\r
+#include "NULLProcs.h"\r
+/*===========================================================================*/\r
+/*                                                                           */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+void NULLSetColor( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )\r
+{\r
+\r
+}\r
+/*===========================================================================*/\r
+/*                                                                           */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+void NULLClearColor( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )\r
+{\r
+}\r
+/*===========================================================================*/\r
+/*                                                                           */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+GLboolean NULLSetBuffer( GLcontext *ctx, GLenum mode )\r
+{\r
+   return TRUE;\r
+}\r
+/*===========================================================================*/\r
+/*                                                                           */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+void NULLGetBufferSize( GLcontext *ctx, GLuint *width, GLuint *height )\r
+{\r
+  *width = 1;\r
+  *height = 1;\r
+}\r
+/*===========================================================================*/\r
+/*                                                                           */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+GLbitfield NULLClearBuffers( GLcontext *ctx, GLbitfield m, GLboolean a, GLint x, GLint y, GLint w, GLint h )\r
+{\r
+   return m;\r
+}\r
+/*===========================================================================*/\r
+/*                                                                           */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+void NULLWrSpRGB( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte r[][3], const GLubyte m[] )\r
+{\r
+\r
+}\r
+/*===========================================================================*/\r
+/*                                                                           */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+void NULLWrSpRGBA( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte r[][4], const GLubyte m[] )\r
+{\r
+\r
+}\r
+/*===========================================================================*/\r
+/*                                                                           */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+void NULLWrSpRGBAMono( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte m[] )\r
+{\r
+\r
+}\r
+/*===========================================================================*/\r
+/*                                                                           */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+void NULLWrPiRGBA( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], const GLubyte r[][4], const GLubyte m[] )\r
+{\r
+\r
+}\r
+/*===========================================================================*/\r
+/*                                                                           */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+void NULLWrPiRGBAMono( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], const GLubyte m[] )\r
+{\r
+\r
+}\r
+/*===========================================================================*/\r
+/*                                                                           */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+void NULLReSpRGBA( const GLcontext* ctx, GLuint n, GLint x, GLint y, GLubyte r[][4] )\r
+{\r
+\r
+}\r
+/*===========================================================================*/\r
+/*                                                                           */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+void NULLRePiRGBA( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], GLubyte r[][4], const GLubyte m[] )\r
+{\r
+\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\1a
\ No newline at end of file
diff --git a/src/mesa/drivers/d3d/OPENGL32.DEF b/src/mesa/drivers/d3d/OPENGL32.DEF
new file mode 100644 (file)
index 0000000..19762bb
--- /dev/null
@@ -0,0 +1,443 @@
+;===========================================================================\r
+;                                                                           \r
+; Mesa-3.0 DirectX 6 Driver                                       \r
+;                                                                           \r
+; By Leigh McRae                                                            \r
+;                                                                           \r
+; http://www.altsoftware.com/                                               \r
+;                                                                           \r
+; Copyright (c) 1999-1998  alt.software inc.  All Rights Reserved           \r
+;===========================================================================\r
+NAME OpenGL32.DLL\r
+DESCRIPTION "Mesa-3.0 DX6 Driver Version 0.5"\r
+\r
+EXPORTS\r
+       DllMain\r
+       glAccum\r
+       glAlphaFunc\r
+       glAreTexturesResident\r
+       glAreTexturesResidentEXT\r
+       glArrayElement\r
+       glArrayElementEXT\r
+       glBegin\r
+       glBindTexture\r
+       glBindTextureEXT\r
+       glBitmap\r
+       glBlendColorEXT\r
+       glBlendEquationEXT\r
+       glBlendFunc\r
+       glCallList\r
+       glCallLists\r
+       glClear\r
+       glClearAccum\r
+       glClearColor\r
+       glClearDepth\r
+       glClearIndex\r
+       glClearStencil\r
+       glClipPlane\r
+       glColor3b\r
+       glColor3bv\r
+       glColor3d\r
+       glColor3dv\r
+       glColor3f\r
+       glColor3fv\r
+       glColor3i\r
+       glColor3iv\r
+       glColor3s\r
+       glColor3sv\r
+       glColor3ub\r
+       glColor3ubv\r
+       glColor3ui\r
+       glColor3uiv\r
+       glColor3us\r
+       glColor3usv\r
+       glColor4b\r
+       glColor4bv\r
+       glColor4d\r
+       glColor4dv\r
+       glColor4f\r
+       glColor4fv\r
+       glColor4i\r
+       glColor4iv\r
+       glColor4s\r
+       glColor4sv\r
+       glColor4ub\r
+       glColor4ubv\r
+       glColor4ui\r
+       glColor4uiv\r
+       glColor4us\r
+       glColor4usv\r
+       glColorMask\r
+       glColorMaterial\r
+       glColorPointer\r
+       glColorPointerEXT\r
+       glColorSubTableEXT\r
+       glColorTableEXT\r
+       glCopyPixels\r
+       glCopyTexImage1D\r
+       glCopyTexImage2D\r
+       glCopyTexSubImage1D\r
+       glCopyTexSubImage2D\r
+       glCopyTexSubImage3DEXT\r
+       glCullFace\r
+       glDeleteLists\r
+       glDeleteTextures\r
+       glDeleteTexturesEXT\r
+       glDepthFunc\r
+       glDepthMask\r
+       glDepthRange\r
+       glDisable\r
+       glDisableClientState\r
+       glDrawArrays\r
+       glDrawArraysEXT\r
+       glDrawBuffer\r
+       glDrawElements\r
+       glDrawPixels\r
+       glEdgeFlag\r
+       glEdgeFlagPointer\r
+       glEdgeFlagPointerEXT\r
+       glEdgeFlagv\r
+       glEnable\r
+       glEnableClientState\r
+       glEnd\r
+       glEndList\r
+       glEvalCoord1d\r
+       glEvalCoord1dv\r
+       glEvalCoord1f\r
+       glEvalCoord1fv\r
+       glEvalCoord2d\r
+       glEvalCoord2dv\r
+       glEvalCoord2f\r
+       glEvalCoord2fv\r
+       glEvalMesh1\r
+       glEvalMesh2\r
+       glEvalPoint1\r
+       glEvalPoint2\r
+       glFeedbackBuffer\r
+       glFinish\r
+       glFlush\r
+       glFogf\r
+       glFogfv\r
+       glFogi\r
+       glFogiv\r
+       glFrontFace\r
+       glFrustum\r
+       glGenLists\r
+       glGenTextures\r
+       glGenTexturesEXT\r
+       glGetBooleanv\r
+       glGetClipPlane\r
+       glGetColorTableEXT\r
+       glGetColorTableParameterfvEXT\r
+       glGetColorTableParameterivEXT\r
+       glGetDoublev\r
+       glGetError\r
+       glGetFloatv\r
+       glGetIntegerv\r
+       glGetLightfv\r
+       glGetLightiv\r
+       glGetMapdv\r
+       glGetMapfv\r
+       glGetMapiv\r
+       glGetMaterialfv\r
+       glGetMaterialiv\r
+       glGetPixelMapfv\r
+       glGetPixelMapuiv\r
+       glGetPixelMapusv\r
+       glGetPointerv\r
+       glGetPointervEXT\r
+       glGetPolygonStipple\r
+       glGetString\r
+       glGetTexEnvfv\r
+       glGetTexEnviv\r
+       glGetTexGendv\r
+       glGetTexGenfv\r
+       glGetTexGeniv\r
+       glGetTexImage\r
+       glGetTexLevelParameterfv\r
+       glGetTexLevelParameteriv\r
+       glGetTexParameterfv\r
+       glGetTexParameteriv\r
+       glHint\r
+       glIndexd\r
+       glIndexdv\r
+       glIndexf\r
+       glIndexfv\r
+       glIndexi\r
+       glIndexiv\r
+       glIndexMask\r
+       glIndexPointer\r
+       glIndexPointerEXT\r
+       glIndexs\r
+       glIndexsv\r
+       glIndexub\r
+       glIndexubv\r
+       glInitNames\r
+       glInterleavedArrays\r
+       glIsEnabled\r
+       glIsList\r
+       glIsTexture\r
+       glIsTextureEXT\r
+       glLightf\r
+       glLightfv\r
+       glLighti\r
+       glLightiv\r
+       glLightModelf\r
+       glLightModelfv\r
+       glLightModeli\r
+       glLightModeliv\r
+       glLineStipple\r
+       glLineWidth\r
+       glListBase\r
+       glLoadIdentity\r
+       glLoadMatrixd\r
+       glLoadMatrixf\r
+       glLoadName\r
+       glLogicOp\r
+       glMap1d\r
+       glMap1f\r
+       glMap2d\r
+       glMap2f\r
+       glMapGrid1d\r
+       glMapGrid1f\r
+       glMapGrid2d\r
+       glMapGrid2f\r
+       glMaterialf\r
+       glMaterialfv\r
+       glMateriali\r
+       glMaterialiv\r
+       glMatrixMode\r
+       glMultMatrixd\r
+       glMultMatrixf\r
+       glNewList\r
+       glNormal3b\r
+       glNormal3bv\r
+       glNormal3d\r
+       glNormal3dv\r
+       glNormal3f\r
+       glNormal3fv\r
+       glNormal3i\r
+       glNormal3iv\r
+       glNormal3s\r
+       glNormal3sv\r
+       glNormalPointer\r
+       glNormalPointerEXT\r
+       glOrtho\r
+       glPassThrough\r
+       glPixelMapfv\r
+       glPixelMapuiv\r
+       glPixelMapusv\r
+       glPixelStoref\r
+       glPixelStorei\r
+       glPixelTransferf\r
+       glPixelTransferi\r
+       glPixelZoom\r
+       glPointParameterfEXT\r
+       glPointParameterfvEXT\r
+       glPointSize\r
+       glPolygonMode\r
+       glPolygonOffset\r
+       glPolygonOffsetEXT\r
+       glPolygonStipple\r
+       glPopAttrib\r
+       glPopClientAttrib\r
+       glPopMatrix\r
+       glPopName\r
+       glPrioritizeTextures\r
+       glPrioritizeTexturesEXT\r
+       glPushAttrib\r
+       glPushClientAttrib\r
+       glPushMatrix\r
+       glPushName\r
+       glRasterPos2d\r
+       glRasterPos2dv\r
+       glRasterPos2f\r
+       glRasterPos2fv\r
+       glRasterPos2i\r
+       glRasterPos2iv\r
+       glRasterPos2s\r
+       glRasterPos2sv\r
+       glRasterPos3d\r
+       glRasterPos3dv\r
+       glRasterPos3f\r
+       glRasterPos3fv\r
+       glRasterPos3i\r
+       glRasterPos3iv\r
+       glRasterPos3s\r
+       glRasterPos3sv\r
+       glRasterPos4d\r
+       glRasterPos4dv\r
+       glRasterPos4f\r
+       glRasterPos4fv\r
+       glRasterPos4i\r
+       glRasterPos4iv\r
+       glRasterPos4s\r
+       glRasterPos4sv\r
+       glReadBuffer\r
+       glReadPixels\r
+       glRectd\r
+       glRectdv\r
+       glRectf\r
+       glRectfv\r
+       glRecti\r
+       glRectiv\r
+       glRects\r
+       glRectsv\r
+       glRenderMode\r
+       glResizeBuffersMESA\r
+       glRotated\r
+       glRotatef\r
+       glScaled\r
+       glScalef\r
+       glScissor\r
+       glSelectBuffer\r
+       glShadeModel\r
+       glStencilFunc\r
+       glStencilMask\r
+       glStencilOp\r
+       glTexCoord1d\r
+       glTexCoord1dv\r
+       glTexCoord1f\r
+       glTexCoord1fv\r
+       glTexCoord1i\r
+       glTexCoord1iv\r
+       glTexCoord1s\r
+       glTexCoord1sv\r
+       glTexCoord2d\r
+       glTexCoord2dv\r
+       glTexCoord2f\r
+       glTexCoord2fv\r
+       glTexCoord2i\r
+       glTexCoord2iv\r
+       glTexCoord2s\r
+       glTexCoord2sv\r
+       glTexCoord3d\r
+       glTexCoord3dv\r
+       glTexCoord3f\r
+       glTexCoord3fv\r
+       glTexCoord3i\r
+       glTexCoord3iv\r
+       glTexCoord3s\r
+       glTexCoord3sv\r
+       glTexCoord4d\r
+       glTexCoord4dv\r
+       glTexCoord4f\r
+       glTexCoord4fv\r
+       glTexCoord4i\r
+       glTexCoord4iv\r
+       glTexCoord4s\r
+       glTexCoord4sv\r
+       glTexCoordPointer\r
+       glTexCoordPointerEXT\r
+       glTexEnvf\r
+       glTexEnvfv\r
+       glTexEnvi\r
+       glTexEnviv\r
+       glTexGend\r
+       glTexGendv\r
+       glTexGenf\r
+       glTexGenfv\r
+       glTexGeni\r
+       glTexGeniv\r
+       glTexImage1D\r
+       glTexImage2D\r
+       glTexImage3DEXT\r
+       glTexParameterf\r
+       glTexParameterfv\r
+       glTexParameteri\r
+       glTexParameteriv\r
+       glTexSubImage1D\r
+       glTexSubImage2D\r
+       glTexSubImage3DEXT\r
+       glTranslated\r
+       glTranslatef\r
+       glVertex2d\r
+       glVertex2dv\r
+       glVertex2f\r
+       glVertex2fv\r
+       glVertex2i\r
+       glVertex2iv\r
+       glVertex2s\r
+       glVertex2sv\r
+       glVertex3d\r
+       glVertex3dv\r
+       glVertex3f\r
+       glVertex3fv\r
+       glVertex3i\r
+       glVertex3iv\r
+       glVertex3s\r
+       glVertex3sv\r
+       glVertex4d\r
+       glVertex4dv\r
+       glVertex4f\r
+       glVertex4fv\r
+       glVertex4i\r
+       glVertex4iv\r
+       glVertex4s\r
+       glVertex4sv\r
+       glVertexPointer\r
+       glVertexPointerEXT\r
+       glViewport\r
+       glWindowPos2dMESA\r
+       glWindowPos2dvMESA\r
+       glWindowPos2fMESA\r
+       glWindowPos2fvMESA\r
+       glWindowPos2iMESA\r
+       glWindowPos2ivMESA\r
+       glWindowPos2sMESA\r
+       glWindowPos2svMESA\r
+       glWindowPos3dMESA\r
+       glWindowPos3dvMESA\r
+       glWindowPos3fMESA\r
+       glWindowPos3fvMESA\r
+       glWindowPos3iMESA\r
+       glWindowPos3ivMESA\r
+       glWindowPos3sMESA\r
+       glWindowPos3svMESA\r
+       glWindowPos4dMESA\r
+       glWindowPos4dvMESA\r
+       glWindowPos4fMESA\r
+       glWindowPos4fvMESA\r
+       glWindowPos4iMESA\r
+       glWindowPos4ivMESA\r
+       glWindowPos4sMESA\r
+       glWindowPos4svMESA\r
+;    WMesaCreateContext\r
+;    WMesaDestroyContext\r
+;    WMesaMakeCurrent\r
+;    WMesaPaletteChange\r
+;    WMesaSwapBuffers\r
+;    OSMesaCreateContext\r
+;    OSMesaDestroyContext\r
+;    OSMesaMakeCurrent\r
+;    OSMesaGetCurrentContext\r
+;    OSMesaPixelStore\r
+;    OSMesaGetIntegerv\r
+;    OSMesaGetDepthBuffer\r
+       wglCopyContext\r
+       wglCreateContext\r
+       wglCreateLayerContext\r
+       wglDeleteContext\r
+;      wglDescribeLayerPlane\r
+       wglGetCurrentContext\r
+       wglGetCurrentDC\r
+;      wglGetLayerPaletteEntries\r
+       wglGetProcAddress\r
+       wglMakeCurrent\r
+;      wglRealizeLayerPalette\r
+;      wglSetLayerPaletteEntries\r
+       wglShareLists\r
+       wglSwapLayerBuffers\r
+       wglUseFontBitmapsA\r
+       wglUseFontBitmapsW\r
+       wglUseFontOutlinesA\r
+       wglUseFontOutlinesW\r
+       wglChoosePixelFormat\r
+       wglDescribePixelFormat\r
+       wglGetPixelFormat\r
+       wglSetPixelFormat\r
+       wglSwapBuffers\r
+    \r
+\r
+\r
+\1a
\ No newline at end of file
diff --git a/src/mesa/drivers/d3d/WGL.C b/src/mesa/drivers/d3d/WGL.C
new file mode 100644 (file)
index 0000000..2d1a6a0
--- /dev/null
@@ -0,0 +1,1262 @@
+/*===========================================================================*/\r
+/*                                                                           */\r
+/* Mesa-3.0 Makefile for DirectX 6                                           */\r
+/*                                                                           */\r
+/* By Leigh McRae                                                            */\r
+/*                                                                           */\r
+/* http://www.altsoftware.com/                                               */\r
+/*                                                                           */\r
+/* Copyright (c) 1998-1997  alt.software inc.  All Rights Reserved           */\r
+/*===========================================================================*/\r
+#include "D3DMesa.h"\r
+/*===========================================================================*/\r
+/* Window managment.                                                         */\r
+/*===========================================================================*/\r
+static BOOL    InitOpenGL( HINSTANCE hInst );\r
+static BOOL    TermOpenGL( HINSTANCE hInst );\r
+static BOOL     ResizeContext( GLcontext *ctx );\r
+static BOOL    MakeCurrent( D3DMESACONTEXT *pContext );\r
+static void    DestroyContext( D3DMESACONTEXT *pContext );\r
+static BOOL    UnBindWindow( D3DMESACONTEXT *pContext );\r
+LONG APIENTRY  wglMonitorProc( HWND hwnd, UINT message, UINT wParam, LONG lParam );\r
+/*===========================================================================*/\r
+/* Mesa hooks.                                                               */\r
+/*===========================================================================*/\r
+static void SetupDDPointers( GLcontext *ctx );\r
+static void SetupSWDDPointers( GLcontext *ctx );\r
+static void SetupHWDDPointers( GLcontext *ctx );\r
+static void SetupNULLDDPointers( GLcontext *ctx );\r
+static const char *RendererString( void );\r
+\r
+/* State Management hooks. */\r
+static void       SetColor( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a );\r
+static void       ClearColor( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a );\r
+static GLboolean SetBuffer( GLcontext *ctx, GLenum buffer );\r
+\r
+/* Window Management hooks. */\r
+static void GetBufferSize( GLcontext *ctx, GLuint *width, GLuint *height );\r
+static void SetViewport( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h );\r
+static void Flush( GLcontext *ctx );\r
+\r
+/* Span rendering hooks. */\r
+void WSpanRGB( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte rgb[][3], const GLubyte mask[] );\r
+void WSpanRGBA( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte rgba[][4], const GLubyte mask[] );\r
+void WSpanRGBAMono( const GLcontext* ctx, GLuint n, GLint x, GLint y, const GLubyte mask[] );\r
+void WPixelsRGBA( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], const GLubyte rgba[][4], const GLubyte mask[] );\r
+void WPixelsRGBAMono( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], const GLubyte mask[] );\r
+void RSpanRGBA( const GLcontext* ctx, GLuint n, GLint x, GLint y, GLubyte rgba[][4] );\r
+void RPixelsRGBA( const GLcontext* ctx, GLuint n, const GLint x[], const GLint y[], GLubyte rgba[][4], const GLubyte mask[] );\r
+GLbitfield ClearBuffers( GLcontext *ctx, GLbitfield mask, GLboolean all, GLint x, GLint y, GLint width, GLint height );\r
+\r
+/* Primitve rendering hooks. */\r
+GLboolean  RenderVertexBuffer( GLcontext *ctx, GLboolean allDone );\r
+void             RenderOneTriangle( GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3, GLuint pv );\r
+void     RenderOneLine( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv );\r
+GLbitfield ClearBuffersD3D( GLcontext *ctx, GLbitfield mask, GLboolean all, GLint x, GLint y, GLint width, GLint height );\r
+\r
+/* Texture Management hooks. */\r
+static void TextureBind( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj );\r
+static void TextureLoad( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj, GLint level, GLint internalFormat, const struct gl_texture_image *image );\r
+static void TextureSubImage( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLint internalFormat, const struct gl_texture_image *image );\r
+/*===========================================================================*/\r
+/* Global variables.                                                         */\r
+/*===========================================================================*/\r
+D3DMESACONTEXT *pD3DCurrent,     \r
+              *pD3DDefault;     /* Thin support context. */\r
+\r
+struct __extensions__   ext[] = {\r
+\r
+    { (PROC)glPolygonOffsetEXT,        "glPolygonOffsetEXT"       },\r
+    { (PROC)glBlendEquationEXT,        "glBlendEquationEXT"       },\r
+    { (PROC)glBlendColorEXT,           "glBlendColorExt"          },\r
+    { (PROC)glVertexPointerEXT,        "glVertexPointerEXT"       },\r
+    { (PROC)glNormalPointerEXT,        "glNormalPointerEXT"       },\r
+    { (PROC)glColorPointerEXT,         "glColorPointerEXT"        },\r
+    { (PROC)glIndexPointerEXT,         "glIndexPointerEXT"        },\r
+    { (PROC)glTexCoordPointerEXT,      "glTexCoordPointer"        },\r
+    { (PROC)glEdgeFlagPointerEXT,      "glEdgeFlagPointerEXT"     },\r
+    { (PROC)glGetPointervEXT,          "glGetPointervEXT"         },\r
+    { (PROC)glArrayElementEXT,         "glArrayElementEXT"        },\r
+    { (PROC)glDrawArraysEXT,           "glDrawArrayEXT"           },\r
+    { (PROC)glAreTexturesResidentEXT,  "glAreTexturesResidentEXT" },\r
+    { (PROC)glBindTextureEXT,          "glBindTextureEXT"         },\r
+    { (PROC)glDeleteTexturesEXT,       "glDeleteTexturesEXT"      },\r
+    { (PROC)glGenTexturesEXT,          "glGenTexturesEXT"         },\r
+    { (PROC)glIsTextureEXT,            "glIsTextureEXT"           },\r
+    { (PROC)glPrioritizeTexturesEXT,   "glPrioritizeTexturesEXT"  },\r
+    { (PROC)glCopyTexSubImage3DEXT,    "glCopyTexSubImage3DEXT"   },\r
+    { (PROC)glTexImage3DEXT,           "glTexImage3DEXT"          },\r
+    { (PROC)glTexSubImage3DEXT,        "glTexSubImage3DEXT"       },\r
+};\r
+\r
+int             qt_ext = sizeof(ext) / sizeof(ext[0]);\r
+float   g_DepthScale,\r
+         g_MaxDepth;\r
+/*===========================================================================*/\r
+/*  When a process loads this DLL we will setup the linked list for context  */\r
+/* management and create a default context that will support the API until   */\r
+/* the user creates and binds thier own.  This THIN default context is useful*/\r
+/* to have around.                                                           */\r
+/*  When the process terminates we will clean up all resources here.         */\r
+/*===========================================================================*/\r
+/* RETURN: TRUE, FALSE.                                                      */\r
+/*===========================================================================*/\r
+BOOL APIENTRY   DllMain( HINSTANCE hInst, DWORD reason, LPVOID reserved )\r
+{\r
+  switch( reason ) \r
+  {\r
+    case DLL_PROCESS_ATTACH:\r
+        return InitOpenGL( hInst );\r
+\r
+    case DLL_PROCESS_DETACH:\r
+        return TermOpenGL( hInst );\r
+  }     \r
+\r
+  return TRUE;\r
+}\r
+/*===========================================================================*/\r
+/*  The first thing we do when this dll is hit is connect to the dll that has*/\r
+/* handles all the DirectX 6 rendering.  I decided to use another dll as DX6 */\r
+/* is all C++ and Mesa-3.0 is C (thats a good thing).  This way I can write  */\r
+/* the DX6 in C++ and Mesa-3.0 in C without having to worry about linkage.   */\r
+/* I feel this is easy and better then using static wrappers as it is likely */\r
+/* faster and it allows me to just develope the one without compiling the    */\r
+/* other.                                                                    */\r
+/*  NOTE that at this point we don't have much other than a very thin context*/\r
+/* that will support the API calls only to the point of not causing the app  */\r
+/* to crash from the API table being empty.                                  */\r
+/*===========================================================================*/\r
+/* RETURN: TRUE, FALSE.                                                      */\r
+/*===========================================================================*/\r
+static BOOL  InitOpenGL( HINSTANCE hInst )\r
+{\r
+  /* Allocate and clear the default context. */\r
+  pD3DDefault = (PD3DMESACONTEXT)ALLOC( sizeof(D3DMESACONTEXT) );\r
+  if ( pD3DDefault == NULL )\r
+    return FALSE;\r
+  memset( pD3DDefault, 0, sizeof(D3DMESACONTEXT) );\r
+\r
+  /*  Clear the D3D vertex buffer so that values not used will be zero.  This */\r
+  /* save me from some redundant work.                                        */\r
+  memset( &D3DTLVertices, 0, sizeof(D3DTLVertices) );\r
+\r
+  /*  Update the link.  We uses a circular list so that it is easy to  */\r
+  /* add and search.  This context will also be used for head and tail.*/\r
+  pD3DDefault->next = pD3DDefault;\r
+\r
+  /*========================================================================*/\r
+  /* Do all core Mesa stuff.                                                */\r
+  /*========================================================================*/\r
+  pD3DDefault->gl_visual = gl_create_visual( TRUE,\r
+                                                                       GL_FALSE,   /* software alpha */\r
+                                                                       FALSE,      /* db_flag */\r
+                                                                       GL_FALSE,   /* stereo */\r
+                                                                       16,         /* depth_bits */\r
+                                                                       8,          /* stencil_bits */\r
+                                                                       8,          /* accum_bits */\r
+                                                                       0,          /* index bits */\r
+                                                                       8,8,8,8 );  /* r, g, b, a bits */\r
+\r
+  if ( pD3DDefault->gl_visual == NULL)  \r
+  {\r
+    FREE( pD3DDefault );\r
+    return FALSE;\r
+  }\r
+\r
+  /* Allocate a new Mesa context */\r
+  pD3DDefault->gl_ctx = gl_create_context( pD3DDefault->gl_visual, NULL, pD3DDefault, GL_TRUE );\r
+  if ( pD3DDefault->gl_ctx == NULL ) \r
+  {\r
+    gl_destroy_visual( pD3DDefault->gl_visual );\r
+    FREE( pD3DDefault );\r
+    return FALSE;\r
+  }\r
+\r
+  /* Allocate a new Mesa frame buffer */\r
+  pD3DDefault->gl_buffer = gl_create_framebuffer( pD3DDefault->gl_visual );\r
+  if ( pD3DDefault->gl_buffer == NULL )\r
+  {\r
+    gl_destroy_visual( pD3DDefault->gl_visual );\r
+    gl_destroy_context( pD3DDefault->gl_ctx );\r
+    FREE( pD3DDefault );\r
+    return FALSE;\r
+  }\r
+  SetupDDPointers( pD3DDefault->gl_ctx );\r
+  gl_make_current( pD3DDefault->gl_ctx, pD3DDefault->gl_buffer );\r
+\r
+  return TRUE;\r
+}\r
+/*===========================================================================*/\r
+/*  This function will create a new D3D context but will not create the D3D  */\r
+/* surfaces or even an instance of D3D (see at GetBufferSize). The only stuff*/\r
+/* done here is the internal Mesa stuff and some Win32 handles.              */\r
+/*===========================================================================*/\r
+/* RETURN: casted pointer to the context, NULL.                              */\r
+/*===========================================================================*/\r
+HGLRC APIENTRY wglCreateContext( HDC hdc )\r
+{\r
+  D3DMESACONTEXT        *pNewContext;\r
+  DWORD                 dwCoopFlags = DDSCL_NORMAL;\r
+  RECT                  rectClient;\r
+  POINT                 pt;\r
+\r
+  /* ALLOC and clear the new context. */\r
+  pNewContext = (PD3DMESACONTEXT)ALLOC( sizeof(D3DMESACONTEXT) );\r
+  if ( pNewContext == NULL )\r
+  {\r
+    SetLastError( 0 );\r
+    return (HGLRC)NULL;\r
+  }\r
+  memset( pNewContext, 0, sizeof(D3DMESACONTEXT) );\r
+\r
+  /*========================================================================*/\r
+  /* Do all core Mesa stuff.                                                */\r
+  /*========================================================================*/\r
+\r
+  /* TODO: support more then one visual. */\r
+  pNewContext->gl_visual = gl_create_visual( TRUE,\r
+                                                                       GL_TRUE,   /* software alpha */\r
+                                                                       TRUE,       /* db_flag */\r
+                                                                       GL_FALSE,   /* stereo */\r
+                                                                       16,         /* depth_bits */\r
+                                                                       8,          /* stencil_bits */\r
+                                                                       8,          /* accum_bits */\r
+                                                                       0,          /* index bits */\r
+                                                                       8,8,8,8 );  /* r, g, b, a bits */\r
+  if ( pNewContext->gl_visual == NULL) \r
+  {\r
+    FREE( pNewContext );\r
+    SetLastError( 0 );\r
+    return (HGLRC)NULL;\r
+  }\r
+\r
+  /* Allocate a new Mesa context */\r
+  pNewContext->gl_ctx = gl_create_context( pNewContext->gl_visual, NULL, pNewContext, GL_TRUE );\r
+  if ( pNewContext->gl_ctx == NULL ) \r
+  {\r
+    gl_destroy_visual( pNewContext->gl_visual );\r
+    FREE( pNewContext );\r
+    SetLastError( 0 );\r
+    return (HGLRC)NULL;\r
+  }\r
+\r
+  /* Allocate a new Mesa frame buffer */\r
+  pNewContext->gl_buffer = gl_create_framebuffer( pNewContext->gl_visual );\r
+  if ( pNewContext->gl_buffer == NULL )\r
+  {\r
+    gl_destroy_visual( pNewContext->gl_visual );\r
+    gl_destroy_context( pNewContext->gl_ctx );\r
+    FREE( pNewContext );\r
+    SetLastError( 0 );\r
+    return (HGLRC)NULL;\r
+  }\r
+\r
+  /*========================================================================*/\r
+  /* Do all the driver stuff.                                               */\r
+  /*========================================================================*/\r
+  pNewContext->hdc  = hdc;\r
+  pNewContext->next = pD3DDefault->next;\r
+  pD3DDefault->next = pNewContext; /* Add to circular list. */\r
+\r
+  /* Create the HAL for the new context. */\r
+  pNewContext->pShared = InitHAL( WindowFromDC(hdc) );\r
+\r
+  return (HGLRC)pNewContext;\r
+}\r
+/*===========================================================================*/\r
+/*  This is a wrapper function that is supported by MakeCurrent.             */\r
+/*===========================================================================*/\r
+/* RETURN: TRUE, FALSE.                                                      */\r
+/*===========================================================================*/\r
+BOOL APIENTRY  wglMakeCurrent( HDC hdc, HGLRC hglrc )\r
+{\r
+   return MakeCurrent((D3DMESACONTEXT *)hglrc);\r
+}\r
+/*===========================================================================*/\r
+/*  MakeCurrent will unbind whatever context is current (if any) & then bind */\r
+/* the supplied context.  A context that is bound has it's window proc hooked*/\r
+/* with the wglMonitorProc and the context pointer is saved in pD3DCurrent.    */\r
+/* Once the context is bound we update the Mesa-3.0 hooks (SetDDPointers) and*/\r
+/* the viewport (Mesa-.30 and DX6).                                          */\r
+/*                                                                           */\r
+/* TODO: this function can't fail.                                           */\r
+/*===========================================================================*/\r
+/* RETURN: TRUE                                                              */\r
+/*===========================================================================*/\r
+static BOOL MakeCurrent( D3DMESACONTEXT *pContext )\r
+{\r
+   D3DMESACONTEXT *pNext;\r
+\r
+   /*====================================================================*/\r
+   /* This is a special case that is a request to have no context bound. */\r
+   /*====================================================================*/\r
+   if ( pContext == NULL )\r
+   {\r
+       /* Walk the whole list. We start and end at the Default context. */\r
+       for( pNext = pD3DDefault->next; pNext != pD3DDefault; pNext = pNext->next )\r
+         UnBindWindow( pNext );\r
+      \r
+       return TRUE;\r
+   }\r
+\r
+   /*=================================================*/\r
+   /* Make for a fast redundant use of this function. */\r
+   /*=================================================*/\r
+   if ( pD3DCurrent == pContext )\r
+      return TRUE;\r
+\r
+   /*=============================*/\r
+   /* Unbind the current context. */\r
+   /*=============================*/\r
+   UnBindWindow( pD3DCurrent );\r
+\r
+   /*=====================================*/\r
+   /* Let Mesa-3.0 we have a new context. */\r
+   /*=====================================*/\r
+   SetupDDPointers( pContext->gl_ctx );\r
+   gl_make_current( pContext->gl_ctx, pContext->gl_buffer );\r
+\r
+   /*  We are done so set the internal current context. */\r
+   if ( pContext != pD3DDefault )\r
+   {\r
+       ResizeContext( pContext->gl_ctx );\r
+       pContext->hOldProc = (WNDPROC)GetWindowLong( pContext->pShared->hwnd, GWL_WNDPROC );\r
+       SetWindowLong( pContext->pShared->hwnd, GWL_WNDPROC, (LONG)wglMonitorProc );\r
+   }\r
+   pD3DCurrent = pContext;\r
+\r
+   return TRUE;\r
+}\r
+/*===========================================================================*/\r
+/*  This function will only return the current window size.  I have re-done  */   \r
+/* this function so that it doesn't check the current size and react to it as*/   \r
+/* I should be able to have all the react code in the WM_SIZE message.  The  */   \r
+/* old version would check the current window size and create/resize the HAL */   \r
+/* surfaces if they have changed.  I needed to delay the creation if the     */   \r
+/* surfaces because sometimes I wouldn't have a window size so this is where */   \r
+/* I delayed it.  If you are reading this then all went ok!                  */   \r
+/*  The default context will return a zero sized window and I'm not sure if  */\r
+/* this is ok at this point (TODO).                                          */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+static void GetBufferSize( GLcontext *ctx, GLuint *width, GLuint *height )\r
+{\r
+  D3DMESACONTEXT        *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;\r
+\r
+  /* Fall through for the default because that is one of the uses for it. */\r
+  if ( pContext == pD3DDefault )\r
+  {\r
+    *width  = 0;\r
+    *height = 0;\r
+  }\r
+  else\r
+  {\r
+    *width  = pContext->pShared->dwWidth;\r
+    *height = pContext->pShared->dwHeight;\r
+  }\r
+}\r
+/*===========================================================================*/\r
+/*                                                                           */\r
+/*                                                                           */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+static BOOL ResizeContext( GLcontext *ctx )\r
+{\r
+  D3DMESACONTEXT        *pContext = (D3DMESACONTEXT *)ctx->DriverCtx,\r
+                   *pCurrentTemp;\r
+  RECT                  rectClient;\r
+  POINT                 pt;\r
+  DWORD                 dwWidth,\r
+                   dwHeight;\r
+  static BOOL           bDDrawLock = FALSE;\r
+\r
+  /* Make sure we have some values. */\r
+  if ( (pContext->hdc == NULL ) || \r
+         (pContext->pShared->hwnd != WindowFromDC(pContext->hdc)) ||\r
+       (pContext == pD3DDefault) )\r
+    return FALSE;\r
+\r
+  /* Having problems with DDraw sending resize messages before I was done. */\r
+  if( bDDrawLock == TRUE )\r
+    return FALSE;\r
+\r
+  // TODO: don't think I need this anymore.\r
+  pCurrentTemp = pD3DCurrent;\r
+  pD3DCurrent = pD3DDefault;\r
+  bDDrawLock = TRUE;\r
+\r
+  /* Get the current window dimentions. */\r
+  UpdateScreenPosHAL( pContext->pShared );\r
+  dwWidth  = pContext->pShared->rectW.right - pContext->pShared->rectW.left;\r
+  dwHeight = pContext->pShared->rectW.bottom - pContext->pShared->rectW.top;\r
+\r
+  /* Is the size of the OffScreen Render different? */\r
+  if ( (dwWidth != pContext->pShared->dwWidth) || (dwHeight != pContext->pShared->dwHeight) )\r
+  {\r
+    /* Create all the D3D surfaces and device. */\r
+    CreateHAL( pContext->pShared );\r
+\r
+    /*  I did this so that software rendering would still work as */\r
+    /* I don't need to scale the z values twice.                  */\r
+    g_DepthScale        = (pContext->pShared->bHardware) ? 1.0 : ((float)0x00FFFFFF);\r
+    g_MaxDepth          = (pContext->pShared->bHardware) ? 1.0 : ((float)0x00FFFFFF);\r
+    gl_DepthRange( pContext->gl_ctx, ctx->Viewport.Near, ctx->Viewport.Far );\r
+\r
+    /* Make sure we have a viewport. */\r
+    gl_Viewport( pContext->gl_ctx, 0, 0, dwWidth, dwHeight );\r
+\r
+    /* Update Mesa as we might have changed from SW <-> HW. */\r
+    SetupDDPointers( pContext->gl_ctx );\r
+    gl_make_current( pContext->gl_ctx, pContext->gl_buffer );\r
+\r
+    /*  If we are in HW we need to load the current texture if there is one already. */\r
+    //    if ( (ctx->Texture.Set[ctx->Texture.CurrentSet].Current != NULL) &&\r
+    //      (pContext->pShared->bHardware == TRUE) )\r
+    //    {\r
+    //   CreateTMgrHAL( pContext->pShared,\r
+    //                           ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Name,\r
+    //                           0,     \r
+    //                           ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0]->Format,\r
+    //                           (RECT *)NULL,\r
+    //                           ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0]->Width,\r
+    //                           ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0]->Height,\r
+    //                           TM_ACTION_BIND,\r
+    //                           (void *)ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0]->Data );\r
+    //    }\r
+  }\r
+\r
+  // TODO: don't think I need this anymore.\r
+  pD3DCurrent = pCurrentTemp;\r
+  bDDrawLock = FALSE;\r
+\r
+  return TRUE;\r
+}\r
+\r
+/*===========================================================================*\r
+/*  This function will Blt the render buffer to the PRIMARY surface. I repeat*/\r
+/* this code for the other SwapBuffer like functions and the flush (didn't   */\r
+/* want the function calling overhead).  Thsi could have been a macro...     */\r
+/*                                                                           */\r
+/* TODO: there are some problems with viewport/scissoring.                   */\r
+/*===========================================================================*/\r
+/* RETURN: TRUE, FALSE.                                                      */\r
+/*===========================================================================*/\r
+BOOL APIENTRY  wglSwapBuffers( HDC hdc )\r
+{\r
+  /* Fall through for the default because that is one of the uses for it. */\r
+  if ( pD3DCurrent == pD3DDefault )\r
+    return FALSE;\r
+\r
+  SwapBuffersHAL( pD3DCurrent->pShared );\r
+\r
+  return TRUE;\r
+}\r
+/*===========================================================================*/\r
+/*  Same as wglSwapBuffers.                                                  */\r
+/*===========================================================================*/\r
+/* RETURN: TRUE, FALSE.                                                      */\r
+/*===========================================================================*/\r
+BOOL APIENTRY  SwapBuffers( HDC hdc )\r
+{\r
+  /* Fall through for the default because that is one of the uses for it. */\r
+  if ( pD3DCurrent == pD3DDefault )\r
+    return FALSE;\r
+\r
+  SwapBuffersHAL( pD3DCurrent->pShared );\r
+\r
+  return TRUE;\r
+}\r
+/*===========================================================================*/\r
+/*  This should be ok as none of the SwapBuffers will cause a redundant Blt  */\r
+/* as none of my Swap functions will call flush.  This should also allow     */\r
+/* sinlge buffered applications to work (not really worried though).  Some   */\r
+/* applications may flush then swap but then this is there fault IMHO.       */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+static void Flush( GLcontext *ctx )\r
+{\r
+  /* Fall through for the default because that is one of the uses for it. */\r
+  if ( pD3DCurrent == pD3DDefault )\r
+    return;\r
+\r
+  SwapBuffersHAL( pD3DCurrent->pShared );\r
+}\r
+/*===========================================================================*/\r
+/*  For now this function will ignore the supplied PF. If I'm going to allow */\r
+/* the user to choice the mode and device at startup I'm going to have to do */\r
+/* something different.                                                      */\r
+/*                                                                           */\r
+/* TODO: use the linked list of modes to build a pixel format to be returned */\r
+/*      to the caller.                                                       */\r
+/*===========================================================================*/\r
+/* RETURN: 1.                                                                */\r
+/*===========================================================================*/\r
+int APIENTRY   wglChoosePixelFormat( HDC hdc, CONST PIXELFORMATDESCRIPTOR *ppfd )\r
+{\r
+   return 1;\r
+}\r
+/*===========================================================================*/\r
+/*  See wglChoosePixelFormat.                                                */\r
+/*===========================================================================*/\r
+/* RETURN: 1.                                                                */\r
+/*===========================================================================*/\r
+int APIENTRY   ChoosePixelFormat( HDC hdc, CONST PIXELFORMATDESCRIPTOR *ppfd )\r
+{\r
+  return wglChoosePixelFormat(hdc,ppfd);\r
+}\r
+/*===========================================================================*/\r
+/*  This function (for now) returns a static PF everytime.  This is just to  */\r
+/* allow things to continue.                                                 */\r
+/*===========================================================================*/\r
+/* RETURN: 1.                                                                */\r
+/*===========================================================================*/\r
+int APIENTRY   wglDescribePixelFormat( HDC hdc, int iPixelFormat, UINT nBytes, LPPIXELFORMATDESCRIPTOR ppfd )\r
+{\r
+   static PIXELFORMATDESCRIPTOR  pfd = \r
+   {\r
+      sizeof(PIXELFORMATDESCRIPTOR),   /* size */\r
+      1,                               /* version */\r
+      PFD_SUPPORT_OPENGL |\r
+      PFD_DRAW_TO_WINDOW |\r
+      PFD_DOUBLEBUFFER,                /* support double-buffering */\r
+      PFD_TYPE_RGBA,                   /* color type */\r
+      16,                              /* prefered color depth */\r
+      0, 0, 0, 0, 0, 0,                /* color bits (ignored) */\r
+      0,                               /* no alpha buffer */\r
+      0,                               /* alpha bits (ignored) */\r
+      0,                               /* no accumulation buffer */\r
+      0, 0, 0, 0,                      /* accum bits (ignored) */\r
+      16,                              /* depth buffer */\r
+      0,                               /* no stencil buffer */\r
+      0,                               /* no auxiliary buffers */\r
+      PFD_MAIN_PLANE,                  /* main layer */\r
+      0,                               /* reserved */\r
+      0, 0, 0,                         /* no layer, visible, damage masks */\r
+   };\r
+\r
+   /* Return the address of this static PF if one was requested. */\r
+   if ( ppfd != NULL )\r
+      memcpy( ppfd, &pfd, sizeof(PIXELFORMATDESCRIPTOR) );\r
+\r
+  return 1;\r
+}\r
+/*===========================================================================*/\r
+/*  See wglDescribePixelFormat.                                              */\r
+/*===========================================================================*/\r
+/* RETURN: 1.                                                                */\r
+/*===========================================================================*/\r
+int APIENTRY   DescribePixelFormat( HDC hdc, int iPixelFormat, UINT nBytes, LPPIXELFORMATDESCRIPTOR ppfd )\r
+{\r
+  return wglDescribePixelFormat(hdc,iPixelFormat,nBytes,ppfd);\r
+}\r
+/*===========================================================================*/\r
+/*  This function will always return 1 for now.  Just to allow for support.  */\r
+/*===========================================================================*/\r
+/* RETURN: 1.                                                                */\r
+/*===========================================================================*/\r
+int APIENTRY   wglGetPixelFormat( HDC hdc )\r
+{\r
+   return 1;\r
+}\r
+/*===========================================================================*/\r
+/*  See wglGetPixelFormat.                                                   */\r
+/*===========================================================================*/\r
+/* RETURN: 1.                                                                */\r
+/*===========================================================================*/\r
+int APIENTRY   GetPixelFormat( HDC hdc )\r
+{\r
+   return wglGetPixelFormat(hdc);\r
+}\r
+/*===========================================================================*/\r
+/*  This will aways work for now.                                            */\r
+/*===========================================================================*/\r
+/* RETURN: TRUE.                                                             */\r
+/*===========================================================================*/\r
+BOOL APIENTRY  wglSetPixelFormat( HDC hdc, int iPixelFormat, CONST PIXELFORMATDESCRIPTOR *ppfd )\r
+{\r
+   return TRUE;\r
+}\r
+/*===========================================================================*/\r
+/*  See wglSetPixelFormat.                                                   */\r
+/*===========================================================================*/\r
+/* RETURN: TRUE, FALSE.                                                      */\r
+/*===========================================================================*/\r
+BOOL APIENTRY  SetPixelFormat( HDC hdc, int iPixelFormat, CONST PIXELFORMATDESCRIPTOR *ppfd )\r
+{\r
+   return wglSetPixelFormat(hdc,iPixelFormat,ppfd);\r
+}\r
+/*===========================================================================*/\r
+/*  This is a wrapper function that is supported by my own internal function.*/\r
+/* that takes my own D3D Mesa context structure.  This so I can reuse the    */\r
+/* function (no need for speed).                                             */\r
+/*===========================================================================*/\r
+/* RETURN: TRUE.                                                             */\r
+/*===========================================================================*/\r
+BOOL APIENTRY  wglDeleteContext( HGLRC hglrc )\r
+{\r
+   DestroyContext( (D3DMESACONTEXT *)hglrc );\r
+\r
+   return TRUE;\r
+}\r
+/*===========================================================================*/\r
+/*  Simple getter function that uses a cast.                                 */\r
+/*===========================================================================*/\r
+/* RETURN: casted pointer to the context, NULL.                              */\r
+/*===========================================================================*/\r
+HGLRC APIENTRY wglGetCurrentContext( VOID )\r
+{\r
+   return (pD3DCurrent) ? (HGLRC)pD3DCurrent : (HGLRC)NULL;\r
+}\r
+/*===========================================================================*/\r
+/* No support.                                                               */\r
+/*===========================================================================*/\r
+/* RETURN: FALSE.                                                            */\r
+/*===========================================================================*/\r
+BOOL APIENTRY  wglCopyContext( HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask )\r
+{\r
+   SetLastError( 0 );\r
+   return FALSE;\r
+}\r
+/*===========================================================================*/\r
+/* No support.                                                               */\r
+/*===========================================================================*/\r
+/* RETURN: NULL.                                                             */\r
+/*===========================================================================*/\r
+HGLRC APIENTRY wglCreateLayerContext( HDC hdc,int iLayerPlane )\r
+{\r
+   SetLastError( 0 );\r
+   return (HGLRC)NULL;\r
+}\r
+/*===========================================================================*/\r
+/*  Simple getter function.                                                  */\r
+/*===========================================================================*/\r
+/* RETURN: FALSE.                                                            */\r
+/*===========================================================================*/\r
+HDC APIENTRY   wglGetCurrentDC( VOID )\r
+{\r
+   return (pD3DCurrent) ? pD3DCurrent->hdc : (HDC)NULL;\r
+}\r
+/*===========================================================================*/\r
+/*  Simply call that searches the supported extensions for a match & returns */\r
+/* the pointer to the function that lends support.                           */\r
+/*===========================================================================*/\r
+/* RETURN: pointer to API call, NULL.                                        */\r
+/*===========================================================================*/\r
+PROC APIENTRY  wglGetProcAddress( LPCSTR lpszProc )\r
+{\r
+   int   index;\r
+\r
+   for( index = 0; index < qt_ext; index++ )\r
+      if( !strcmp(lpszProc,ext[index].name) )\r
+        return ext[index].proc;\r
+\r
+   SetLastError( 0 );\r
+   return NULL;\r
+}\r
+/*===========================================================================*/\r
+/*  No support.                                                              */\r
+/*===========================================================================*/\r
+/* RETURN: FALSE.                                                            */\r
+/*===========================================================================*/\r
+BOOL APIENTRY  wglShareLists( HGLRC hglrc1, HGLRC hglrc2 )\r
+{\r
+   SetLastError( 0 );\r
+   return FALSE;\r
+}\r
+/*===========================================================================*/\r
+/*  No support.                                                              */\r
+/*===========================================================================*/\r
+/* RETURN: FALSE.                                                            */\r
+/*===========================================================================*/\r
+BOOL APIENTRY  wglUseFontBitmaps( HDC fontDevice, DWORD firstChar, DWORD numChars, DWORD listBase )\r
+{\r
+   SetLastError( 0 );\r
+   return FALSE;\r
+}\r
+/*===========================================================================*/\r
+/*  No support.                                                              */\r
+/*===========================================================================*/\r
+/* RETURN: FALSE.                                                            */\r
+/*===========================================================================*/\r
+BOOL APIENTRY  wglUseFontBitmapsW( HDC hdc,DWORD first,DWORD count,DWORD listBase )\r
+{\r
+   SetLastError( 0 );\r
+   return FALSE;\r
+}\r
+/*===========================================================================*/\r
+/*  No support.                                                              */\r
+/*===========================================================================*/\r
+/* RETURN: FALSE.                                                            */\r
+/*===========================================================================*/\r
+BOOL APIENTRY  wglUseFontOutlinesA( HDC hdc, DWORD first, DWORD count, DWORD listBase, FLOAT deviation, FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf )\r
+{\r
+   SetLastError( 0 );\r
+   return FALSE;\r
+}\r
+/*===========================================================================*/\r
+/*  No support.                                                              */\r
+/*===========================================================================*/\r
+/* RETURN: FALSE.                                                            */\r
+/*===========================================================================*/\r
+BOOL APIENTRY  wglUseFontOutlinesW( HDC hdc,DWORD first,DWORD count, DWORD listBase,FLOAT deviation, FLOAT extrusion,int format, LPGLYPHMETRICSFLOAT lpgmf )\r
+{\r
+   SetLastError( 0 );\r
+   return FALSE ;\r
+}\r
+/*===========================================================================*/\r
+/*  No support.                                                              */\r
+/*===========================================================================*/\r
+/* RETURN: FALSE.                                                            */\r
+/*===========================================================================*/\r
+BOOL APIENTRY  wglSwapLayerBuffers( HDC hdc, UINT fuPlanes )\r
+{\r
+   SetLastError( 0 );\r
+   return FALSE;\r
+}\r
+/*===========================================================================*/\r
+/*  This function will be hooked into the window that has been bound.  Right */\r
+/* now it is used to track the window size and position.  Also the we clean  */\r
+/* up the currrent context when the window is close/destroyed.               */\r
+/*                                                                           */\r
+/* TODO: there might be something wrong here as some games (Heretic II) don't*/\r
+/*      track the window quit right.                                         */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+LONG APIENTRY  wglMonitorProc( HWND hwnd, UINT message, UINT wParam, LONG lParam )\r
+{\r
+  WNDPROC       hOldProc;\r
+  GLint width,\r
+         height;\r
+\r
+  switch( message ) \r
+  {\r
+//      case WM_PAINT:\r
+//        break;\r
+//      case WM_ACTIVATE:\r
+//         break;\r
+//      case WM_SHOWWINDOW:\r
+//         break;\r
+\r
+    case UM_FATALSHUTDOWN:\r
+        /* Support the API until we die... */\r
+        MakeCurrent( pD3DDefault );\r
+        break;\r
+\r
+    case WM_MOVE:\r
+    case WM_DISPLAYCHANGE:\r
+    case WM_SIZE:\r
+        ResizeContext( pD3DCurrent->gl_ctx );\r
+        break;\r
+\r
+    case WM_CLOSE:\r
+    case WM_DESTROY:\r
+        /* Support the API until we die... */\r
+        hOldProc = pD3DCurrent->hOldProc;\r
+        DestroyContext( pD3DCurrent );\r
+        return (hOldProc)(hwnd,message,wParam,lParam);\r
+  }\r
+\r
+  return (pD3DCurrent->hOldProc)(hwnd,message,wParam,lParam);\r
+}\r
+\r
+/**********************************************************************/\r
+/*****              Miscellaneous device driver funcs             *****/\r
+/**********************************************************************/\r
+\r
+/*===========================================================================*/\r
+/*  Not reacting to this as I'm only supporting drawing to the back buffer   */\r
+/* right now.                                                                */\r
+/*===========================================================================*/\r
+/* RETURN: TRUE.                                                             */\r
+/*===========================================================================*/\r
+static GLboolean SetBuffer( GLcontext *ctx, GLenum buffer )\r
+{\r
+   if (buffer == GL_BACK_LEFT)\r
+      return GL_TRUE;\r
+   else\r
+      return GL_FALSE;\r
+}\r
+/*===========================================================================*/\r
+/*  This proc will be called by Mesa when the viewport has been set.  So if  */\r
+/* we have a context and it isn't the default then we should let D3D know of */\r
+/* the change.                                                               */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+static void SetViewport( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h )\r
+{\r
+   D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;\r
+   RECT           rect;\r
+\r
+   /* Make sure we can set a viewport. */\r
+   if ( pContext->pShared && (pContext != pD3DDefault) )\r
+   {\r
+        // TODO: might be needed.\r
+     UpdateScreenPosHAL( pContext->pShared );\r
+       rect.left   = x;\r
+       rect.right  = x + w;\r
+       rect.top    = y;\r
+       rect.bottom = y + h;\r
+\r
+       // TODO: shared struct should make this call smaller\r
+     SetViewportHAL( pContext->pShared, &rect, 0.0F, 1.0F );\r
+   }\r
+}\r
+/*===========================================================================*/\r
+/*  This function could be better I guess but I decided just to grab the four*/\r
+/* components and store then seperately.  Makes it easier to use IMHO.       */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+static void ClearColor( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )\r
+{\r
+   D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;\r
+\r
+   pContext->aClear = a;\r
+   pContext->bClear = b;\r
+   pContext->gClear = g;\r
+   pContext->rClear = r;\r
+}\r
+/*===========================================================================*/\r
+/*  This function could be better I guess but I decided just to grab the four*/\r
+/* components and store then seperately.  Makes it easier to use IMHO.       */\r
+/* (is there an echo in here?)                                               */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+static void SetColor( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )\r
+{\r
+   D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;\r
+\r
+   pContext->aCurrent = a;\r
+   pContext->bCurrent = b;\r
+   pContext->gCurrent = g;\r
+   pContext->rCurrent = r;\r
+}\r
+/*===========================================================================*/\r
+/*                                                                           */\r
+/*                                                                           */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+static const char *RendererString( void )\r
+{\r
+  static char pszRender[64];\r
+\r
+  strcpy( pszRender, "altD3D " );\r
+\r
+  if ( pD3DCurrent->pShared->bHardware )\r
+    strcat( pszRender, "(HW)");\r
+  else\r
+    strcat( pszRender, "(SW)");\r
+\r
+  return (const char *)pszRender;\r
+}\r
+/*===========================================================================*/\r
+/*  This function will choose which set of pointers Mesa will use based on   */\r
+/* whether we hard using hardware or software.  I have added another set of  */\r
+/* pointers that will do nothing but stop the API from crashing.             */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+static void SetupDDPointers( GLcontext *ctx )\r
+{\r
+   D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;\r
+\r
+   // TODO: write a generic NULL support for the span render. \r
+   if ( pContext->pShared && pContext->pShared->bHardware )\r
+   {\r
+       ctx->Driver.UpdateState = SetupHWDDPointers;\r
+   }\r
+   else if ( pContext == pD3DDefault )\r
+   {\r
+       ctx->Driver.UpdateState = SetupNULLDDPointers;\r
+   }\r
+   else\r
+   {\r
+       ctx->Driver.UpdateState = SetupSWDDPointers;\r
+   }\r
+}\r
+/*===========================================================================*/\r
+/*  This function will populate all the Mesa driver hooks. This version of   */\r
+/* hooks will do nothing but support the API when we don't have a valid      */\r
+/* context bound.  This is mostly for applications that don't behave right   */\r
+/* and also to help exit as clean as possable when we have a FatalError.     */\r
+/*===========================================================================*/\r
+/* RETURN: pointer to the specific function.                                 */\r
+/*===========================================================================*/\r
+static void SetupNULLDDPointers( GLcontext *ctx )\r
+{\r
+   D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;\r
+\r
+   /* Initialize all the pointers in the DD struct.  Do this whenever */\r
+   /* a new context is made current or we change buffers via set_buffer! */\r
+   ctx->Driver.UpdateState          = SetupNULLDDPointers;\r
+\r
+   /* State management hooks. */\r
+   ctx->Driver.Color                = NULLSetColor;\r
+   ctx->Driver.ClearColor           = NULLClearColor;\r
+   ctx->Driver.Clear                = NULLClearBuffers;\r
+   ctx->Driver.SetBuffer            = NULLSetBuffer;\r
+\r
+   /* Window management hooks. */\r
+   ctx->Driver.GetBufferSize        = NULLGetBufferSize;\r
+\r
+   /* Primitive rendering hooks. */\r
+   ctx->Driver.TriangleFunc         = NULL;\r
+   ctx->Driver.RenderVB             = NULL;\r
+\r
+   /* Pixel/span writing functions: */\r
+   ctx->Driver.WriteRGBASpan        = NULLWrSpRGBA;\r
+   ctx->Driver.WriteRGBSpan         = NULLWrSpRGB;\r
+   ctx->Driver.WriteMonoRGBASpan    = NULLWrSpRGBAMono;\r
+   ctx->Driver.WriteRGBAPixels      = NULLWrPiRGBA;\r
+   ctx->Driver.WriteMonoRGBAPixels  = NULLWrPiRGBAMono;\r
+\r
+   /* Pixel/span reading functions: */\r
+   ctx->Driver.ReadRGBASpan         = NULLReSpRGBA;\r
+   ctx->Driver.ReadRGBAPixels       = NULLRePiRGBA;\r
+\r
+   /* Misc. hooks. */\r
+   ctx->Driver.RendererString    = RendererString;\r
+}\r
+/*===========================================================================*/\r
+/*  This function will populate all the Mesa driver hooks. There are two of  */\r
+/* these functions.  One if we have hardware support and one is there is only*/\r
+/* software.  These functions will be called by Mesa and by the wgl.c when we*/\r
+/* have resized (or created) the buffers.  The thing is that if a window gets*/\r
+/* resized we may loose hardware support or gain it...                       */\r
+/*===========================================================================*/\r
+/* RETURN: pointer to the specific function.                                 */\r
+/*===========================================================================*/\r
+static void SetupSWDDPointers( GLcontext *ctx )\r
+{\r
+   D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;\r
+\r
+   /* Initialize all the pointers in the DD struct.  Do this whenever */\r
+   /* a new context is made current or we change buffers via set_buffer! */\r
+   ctx->Driver.UpdateState          = SetupSWDDPointers;\r
+\r
+   /* State management hooks. */\r
+   ctx->Driver.Color                = SetColor;\r
+   ctx->Driver.ClearColor           = ClearColor;\r
+   ctx->Driver.Clear                = ClearBuffers;\r
+   ctx->Driver.SetBuffer            = SetBuffer;\r
+\r
+   /* Window management hooks. */\r
+   ctx->Driver.GetBufferSize        = GetBufferSize;\r
+   ctx->Driver.Viewport             = SetViewport;\r
+\r
+   /* Primitive rendering hooks. */\r
+   ctx->Driver.TriangleFunc         = NULL;\r
+   ctx->Driver.RenderVB             = NULL;\r
+\r
+   /* Texture management hooks. */\r
+\r
+   /* Pixel/span writing functions: */\r
+   ctx->Driver.WriteRGBASpan        = WSpanRGBA;\r
+   ctx->Driver.WriteRGBSpan         = WSpanRGB;\r
+   ctx->Driver.WriteMonoRGBASpan    = WSpanRGBAMono;\r
+   ctx->Driver.WriteRGBAPixels      = WPixelsRGBA;\r
+   ctx->Driver.WriteMonoRGBAPixels  = WPixelsRGBAMono;\r
+\r
+   /* Pixel/span reading functions: */\r
+   ctx->Driver.ReadRGBASpan         = RSpanRGBA;\r
+   ctx->Driver.ReadRGBAPixels       = RPixelsRGBA;\r
+\r
+   /* Misc. hooks. */\r
+   ctx->Driver.Flush                = Flush;\r
+   ctx->Driver.RendererString    = RendererString;\r
+}\r
+/*===========================================================================*/\r
+/*  This function will populate all the Mesa driver hooks. There are two of  */\r
+/* these functions.  One if we have hardware support and one is there is only*/\r
+/* software.  These functions will be called by Mesa and by the wgl.c when we*/\r
+/* have resized (or created) the buffers.  The thing is that if a window gets*/\r
+/* resized we may loose hardware support or gain it...                       */\r
+/*===========================================================================*/\r
+/* RETURN: pointer to the specific function.                                 */\r
+/*===========================================================================*/\r
+static void SetupHWDDPointers( GLcontext *ctx )\r
+{\r
+   D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;\r
+\r
+   /* Initialize all the pointers in the DD struct.  Do this whenever */\r
+   /* a new context is made current or we change buffers via set_buffer! */\r
+   ctx->Driver.UpdateState          = SetupHWDDPointers;\r
+\r
+   /* State management hooks. */\r
+   ctx->Driver.Color                = SetColor;\r
+   ctx->Driver.ClearColor           = ClearColor;\r
+   ctx->Driver.Clear                = ClearBuffersD3D;\r
+   ctx->Driver.SetBuffer            = SetBuffer;\r
+\r
+   /* Window management hooks. */\r
+   ctx->Driver.GetBufferSize        = GetBufferSize;\r
+   ctx->Driver.Viewport             = SetViewport;\r
+\r
+   /* Primitive rendering hooks. */\r
+   ctx->Driver.TriangleFunc         = RenderOneTriangle;\r
+   ctx->Driver.LineFunc                          = RenderOneLine;\r
+   ctx->Driver.RenderVB             = RenderVertexBuffer;\r
+\r
+   /* Pixel/span writing functions: */\r
+   ctx->Driver.WriteRGBASpan        = WSpanRGBA;\r
+   ctx->Driver.WriteRGBSpan         = WSpanRGB;\r
+   ctx->Driver.WriteMonoRGBASpan    = WSpanRGBAMono;\r
+   ctx->Driver.WriteRGBAPixels      = WPixelsRGBA;\r
+   ctx->Driver.WriteMonoRGBAPixels  = WPixelsRGBAMono;\r
+\r
+   /* Pixel/span reading functions: */\r
+   ctx->Driver.ReadRGBASpan         = RSpanRGBA;\r
+   ctx->Driver.ReadRGBAPixels       = RPixelsRGBA;\r
+\r
+   /* Texture management hooks. */\r
+   //   ctx->Driver.BindTexture          = TextureBind;\r
+   ctx->Driver.TexImage             = TextureLoad;\r
+   ctx->Driver.TexSubImage          = TextureSubImage;\r
+\r
+   /* Misc. hooks. */\r
+   ctx->Driver.Flush                = Flush;\r
+   ctx->Driver.RendererString    = RendererString;\r
+}\r
+/*===========================================================================*/\r
+/*  This function will release all resources used by the DLL.  Every context */\r
+/* will be clobbered by releaseing all driver desources and then freeing the */\r
+/* context memory.  Most all the work is done in DestroyContext.             */\r
+/*===========================================================================*/\r
+/* RETURN: TRUE.                                                             */\r
+/*===========================================================================*/\r
+static BOOL  TermOpenGL( HINSTANCE hInst )\r
+{\r
+  D3DMESACONTEXT *pTmp,\r
+                *pNext;\r
+\r
+  /* Just incase we are still getting paint msg. */\r
+  MakeCurrent( pD3DDefault );\r
+\r
+  /* Walk the list until we get back to the default context. */\r
+  for( pTmp = pD3DDefault->next; pTmp != pD3DDefault; pTmp = pNext )\r
+  {\r
+    pNext = pTmp->next;\r
+    DestroyContext( pTmp );\r
+  }\r
+  DestroyContext( pD3DDefault );\r
+\r
+  return TRUE;\r
+}\r
+/*===========================================================================*/\r
+/*  This function is an internal function that will clean up all the Mesa    */\r
+/* context bound to this D3D context.  Also any D3D stuff that this context  */\r
+/* uses will be unloaded.                                                    */\r
+/*===========================================================================*/\r
+/* RETURN: TRUE, FALSE.                                                      */\r
+/*===========================================================================*/\r
+static void DestroyContext( D3DMESACONTEXT *pContext )\r
+{\r
+  D3DMESACONTEXT        *pTmp;\r
+\r
+  /* Walk the list until we find the context before this one. */\r
+  for( pTmp = pD3DDefault; pTmp && (pTmp->next != pContext); pTmp = pTmp->next )\r
+    if ( pTmp == pTmp->next )\r
+        break;\r
+\r
+  /* If we never found it it must already be deleted. */\r
+  if ( pTmp->next != pContext )\r
+    return;\r
+\r
+  /* Make sure we are not using this context. */\r
+  if ( pContext == pD3DCurrent )\r
+    MakeCurrent( pD3DDefault );\r
+\r
+   /* Free the Mesa stuff. */\r
+   if ( pContext->gl_visual ) \r
+   {\r
+      gl_destroy_visual( pContext->gl_visual );\r
+      pContext->gl_visual = NULL;\r
+   }\r
+   if ( pContext->gl_buffer ) \r
+   {\r
+      gl_destroy_framebuffer( pContext->gl_buffer );\r
+      pContext->gl_buffer = NULL;\r
+   }\r
+   if ( pContext->gl_ctx )    \r
+   {\r
+      gl_destroy_context( pContext->gl_ctx );\r
+      pContext->gl_ctx = NULL;\r
+   }\r
+\r
+   /* Now dump the D3D. */\r
+   if ( pContext->pShared )\r
+       TermHAL( pContext->pShared );\r
+\r
+   /* Update the previous context's link. */\r
+   pTmp->next = pContext->next;\r
+\r
+   /* Gonzo. */\r
+   FREE( pContext );\r
+}\r
+/*===========================================================================*/\r
+/*  This function will pull the supplied context away from Win32.  Basicly it*/\r
+/* will remove the hook from the window Proc.                                */\r
+/*                                                                           */\r
+/* TODO: might want to serialize this stuff...                               */\r
+/*===========================================================================*/\r
+/* RETURN: TRUE, FALSE.                                                      */\r
+/*===========================================================================*/\r
+static BOOL UnBindWindow( D3DMESACONTEXT *pContext )\r
+{\r
+  if ( pContext == NULL )\r
+    return FALSE;\r
+\r
+  if ( pContext == pD3DDefault )\r
+    return TRUE;\r
+\r
+  /* Make sure we always have a context bound. */\r
+  if ( pContext == pD3DCurrent )\r
+    pD3DCurrent = pD3DDefault;\r
+\r
+  SetWindowLong( pContext->pShared->hwnd, GWL_WNDPROC, (LONG)pContext->hOldProc );\r
+  pContext->hOldProc   = NULL;\r
+\r
+  return TRUE;\r
+}\r
+/*===========================================================================*/\r
+/*  There are two cases that allow for a faster clear when we know that the  */\r
+/* whole buffer is cleared and that there is no clipping.                    */\r
+/*===========================================================================*/\r
+/* RETURN: the original mask with the bits cleared that represents the buffer*\r
+/* or buffers we just cleared.                                               */\r
+/*===========================================================================*/\r
+GLbitfield ClearBuffersD3D( GLcontext *ctx, GLbitfield mask, GLboolean all, GLint x, GLint y, GLint width, GLint height )\r
+{\r
+  D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;\r
+  DWORD          dwFlags = 0;\r
+\r
+  if ( mask & GL_COLOR_BUFFER_BIT )\r
+  {\r
+    dwFlags |= D3DCLEAR_TARGET;\r
+    mask &= ~GL_COLOR_BUFFER_BIT;\r
+  }\r
+  if ( mask & GL_DEPTH_BUFFER_BIT )\r
+  {\r
+    dwFlags |= D3DCLEAR_ZBUFFER;\r
+    mask &= ~GL_DEPTH_BUFFER_BIT;\r
+  }\r
+  if ( dwFlags == 0 )\r
+    return mask;\r
+\r
+  ClearHAL( pContext->pShared, \r
+                 dwFlags, \r
+                 all, \r
+                 x, y, \r
+                 width, height, \r
+                 ((pContext->aClear<<24) | (pContext->rClear<<16) | (pContext->gClear<<8) | (pContext->bClear)), \r
+                 ctx->Depth.Clear, \r
+                 0 );\r
+\r
+  return mask;\r
+}\r
+\r
+\r
+\r
+/*===========================================================================*/\r
+/*  TEXTURE MANAGER: ok here is how I did textures.  Mesa-3.0 will keep track*/\r
+/* of all the textures for us.  So this means that at anytime we can go to   */\r
+/* the Mesa context and get the current texture.  With this in mind this is  */\r
+/* what I did.  I really don't care about what textures get or are loaded    */\r
+/* until I actually have to draw a tri that is textured.  At this point I    */\r
+/* must have the texture so I demand the texture by destorying all other     */\r
+/* texture surfaces if need be and load the current one.  This allows for the*/\r
+/* best preformance on low memory cards as time is not wasted loading and    */\r
+/* unload textures.                                                          */\r
+/*===========================================================================*/\r
+\r
+\r
+\r
+\r
+\r
+/*===========================================================================*/\r
+/*  TextureLoad will try and create a D3D surface from the supplied texture  */\r
+/* object if its level 0 (first).  The surface will be fully filled with the */\r
+/* texture.                                                                  */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+static void TextureLoad( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj, GLint level, GLint internalFormat, const struct gl_texture_image *image )\r
+{\r
+  D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;\r
+\r
+  /* TODO: only doing first LOD. */\r
+  if ( (ctx->DriverCtx == NULL) || (level != 0) )\r
+    return;\r
+\r
+  CreateTMgrHAL( pContext->pShared, \r
+                         tObj->Name, \r
+                         level,\r
+                         tObj->Image[level]->Format,\r
+                         (RECT *)NULL,\r
+                         tObj->Image[level]->Width, \r
+                         tObj->Image[level]->Height,\r
+                         TM_ACTION_LOAD,\r
+                         (void *)tObj->Image[level]->Data );\r
+}\r
+/*===========================================================================*/\r
+/*  TextureBind make sure that the texture is on the card.  Thats it.        */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+static void TextureBind( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj )\r
+{\r
+  D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;\r
+\r
+  /* TODO: only doing first LOD. */\r
+  if ( (tObj->Image[0] == NULL) || (ctx->DriverCtx == NULL) )\r
+    return;\r
+\r
+  CreateTMgrHAL( pContext->pShared, \r
+                         tObj->Name, \r
+                         0,\r
+                         tObj->Image[0]->Format,\r
+                         (RECT *)NULL,\r
+                         tObj->Image[0]->Width, \r
+                         tObj->Image[0]->Height,\r
+                         TM_ACTION_BIND,\r
+                         (void *)tObj->Image[0]->Data );\r
+}\r
+/*===========================================================================*/\r
+/*  TextureSubImage will make sure that the texture being updated is updated */\r
+/* if its on the card.                                                       */\r
+/*===========================================================================*/\r
+/* RETURN:                                                                   */\r
+/*===========================================================================*/\r
+static void TextureSubImage( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLint internalFormat, const struct gl_texture_image *image )\r
+{\r
+  D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;\r
+  RECT           rect;\r
+\r
+  /* TODO: only doing first LOD. */\r
+  if ( (ctx->DriverCtx == NULL) || (level > 0) )\r
+    return;\r
+\r
+  /* Create a dirty rectangle structure. */\r
+  rect.left   = xoffset;\r
+  rect.right  = xoffset + width;\r
+  rect.top    = yoffset;\r
+  rect.bottom = yoffset + height;\r
+  \r
+  CreateTMgrHAL( pContext->pShared, \r
+                         tObj->Name, \r
+                         0,\r
+                         tObj->Image[0]->Format, \r
+                         &rect,\r
+                         tObj->Image[0]->Width, \r
+                         tObj->Image[0]->Height,\r
+                         TM_ACTION_UPDATE,\r
+                         (void *)tObj->Image[0]->Data );\r
+}\r
+\r
diff --git a/src/mesa/drivers/d3d/d3dText.h b/src/mesa/drivers/d3d/d3dText.h
new file mode 100644 (file)
index 0000000..9ff0650
--- /dev/null
@@ -0,0 +1,53 @@
+#ifndef D3D_TEXT_H
+#define D3D_TEXT_H
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*===========================================================================*/
+/* Includes.                                                                 */
+/*===========================================================================*/
+#include <windows.h>
+#include <ddraw.h>
+#include <d3d.h>
+/*===========================================================================*/
+/* Magic numbers.                                                            */
+/*===========================================================================*/
+#define        D3DLTEXT_BITSUSED               0xFFFFFFFF
+#define        MAX_VERTICES                    700  // (14*40) 14 per character, 40 characters
+/*===========================================================================*/
+/* Macros defines.                                                           */
+/*===========================================================================*/
+/*===========================================================================*/
+/* Type defines.                                                             */
+/*===========================================================================*/
+typedef struct _d3dText_metrics
+{
+  float                        fntYScale,
+                    fntXScale;
+
+  int                  fntXSpacing,
+                      fntYSpacing;
+
+  DWORD                        dwColor;
+  LPDIRECT3DDEVICE3 lpD3DDevice;
+
+} D3DFONTMETRICS, *PD3DFONTMETRICS;
+/*===========================================================================*/
+/* Function prototypes.                                                      */
+/*===========================================================================*/
+extern BOOL InitD3DText( void );
+extern void d3dTextDrawCharacter( char *c, int x, int y, PD3DFONTMETRICS pfntMetrics );
+extern void d3dTextDrawString( char *pszString, int x, int y, PD3DFONTMETRICS pfntMetrics );
+/*===========================================================================*/
+/* Global variables.                                                         */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/src/mesa/drivers/dos/DEPEND.DOS b/src/mesa/drivers/dos/DEPEND.DOS
new file mode 100644 (file)
index 0000000..60a0fdc
--- /dev/null
@@ -0,0 +1,119 @@
+# DO NOT DELETE\r
+\r
+accum.obj: accum.h types.h ..\include\GL\gl.h config.h fixed.h dd.h context.h\r
+accum.obj: dlist.h macros.h\r
+alpha.obj: alpha.h types.h ..\include\GL\gl.h config.h fixed.h dd.h context.h\r
+alpha.obj: dlist.h macros.h\r
+alphabuf.obj: alphabuf.h types.h ..\include\GL\gl.h config.h fixed.h dd.h\r
+alphabuf.obj: context.h macros.h\r
+api1.obj: api.h bitmap.h types.h ..\include\GL\gl.h config.h fixed.h dd.h context.h\r
+api1.obj: eval.h image.h macros.h matrix.h teximage.h\r
+api2.obj: api.h bitmap.h types.h ..\include\GL\gl.h config.h fixed.h dd.h context.h\r
+api2.obj: eval.h image.h macros.h matrix.h teximage.h\r
+attrib.obj: attrib.h types.h ..\include\GL\gl.h config.h fixed.h dd.h context.h\r
+attrib.obj: draw.h dlist.h macros.h\r
+bitmap.obj: bitmap.h types.h ..\include\GL\gl.h config.h fixed.h dd.h context.h\r
+bitmap.obj: feedback.h image.h macros.h pb.h\r
+blend.obj: alphabuf.h types.h ..\include\GL\gl.h config.h fixed.h dd.h blend.h\r
+blend.obj: context.h dlist.h macros.h pb.h span.h\r
+bresenhm.obj: bresenhm.h types.h ..\include\GL\gl.h config.h fixed.h dd.h\r
+clip.obj: clip.h types.h ..\include\GL\gl.h config.h fixed.h dd.h context.h\r
+clip.obj: dlist.h macros.h matrix.h vb.h xform.h\r
+context.obj: context.h types.h ..\include\GL\gl.h config.h fixed.h dd.h depth.h\r
+context.obj: draw.h eval.h light.h lines.h dlist.h macros.h pb.h points.h\r
+context.obj: pointers.h triangle.h teximage.h texobj.h texture.h vb.h vertex.h\r
+copypix.obj: context.h types.h ..\include\GL\gl.h config.h fixed.h dd.h\r
+copypix.obj: copypix.h depth.h feedback.h dlist.h macros.h pixel.h span.h\r
+copypix.obj: stencil.h\r
+depth.obj: context.h types.h ..\include\GL\gl.h config.h fixed.h dd.h depth.h\r
+depth.obj: dlist.h macros.h\r
+dlist.obj: accum.h types.h ..\include\GL\gl.h config.h fixed.h dd.h alpha.h\r
+dlist.obj: attrib.h bitmap.h blend.h clip.h context.h copypix.h depth.h draw.h\r
+dlist.obj: drawpix.h enable.h eval.h feedback.h fog.h image.h light.h lines.h\r
+dlist.obj: dlist.h logic.h macros.h masking.h matrix.h misc.h pixel.h points.h\r
+dlist.obj: polygon.h scissor.h stencil.h texobj.h teximage.h texture.h vb.h\r
+dlist.obj: vertex.h winpos.h\r
+draw.obj: clip.h types.h ..\include\GL\gl.h config.h fixed.h dd.h context.h\r
+draw.obj: draw.h feedback.h fog.h light.h lines.h dlist.h macros.h matrix.h\r
+draw.obj: pb.h points.h texture.h vb.h xform.h\r
+drawpix.obj: context.h types.h ..\include\GL\gl.h config.h fixed.h dd.h\r
+drawpix.obj: drawpix.h feedback.h dlist.h macros.h pixel.h span.h stencil.h\r
+enable.obj: context.h types.h ..\include\GL\gl.h config.h fixed.h dd.h depth.h\r
+enable.obj: draw.h enable.h light.h dlist.h macros.h stencil.h\r
+eval.obj: context.h types.h ..\include\GL\gl.h config.h fixed.h dd.h draw.h\r
+eval.obj: eval.h dlist.h macros.h\r
+feedback.obj: context.h types.h ..\include\GL\gl.h config.h fixed.h dd.h\r
+feedback.obj: feedback.h dlist.h macros.h\r
+fog.obj: context.h types.h ..\include\GL\gl.h config.h fixed.h dd.h fog.h\r
+fog.obj: dlist.h macros.h\r
+get.obj: context.h types.h ..\include\GL\gl.h config.h fixed.h dd.h get.h\r
+get.obj: dlist.h macros.h\r
+hash.obj: hash.h\r
+interp.obj: interp.h types.h ..\include\GL\gl.h config.h fixed.h dd.h macros.h\r
+image.obj: image.h types.h ..\include\GL\gl.h config.h fixed.h dd.h macros.h\r
+image.obj: pixel.h\r
+light.obj: context.h types.h ..\include\GL\gl.h config.h fixed.h dd.h light.h\r
+light.obj: dlist.h macros.h matrix.h vb.h xform.h\r
+lines.obj: bresenhm.h types.h ..\include\GL\gl.h config.h fixed.h dd.h\r
+lines.obj: context.h feedback.h interp.h lines.h dlist.h macros.h pb.h vb.h\r
+logic.obj: context.h types.h ..\include\GL\gl.h config.h fixed.h dd.h dlist.h\r
+logic.obj: logic.h macros.h pb.h\r
+masking.obj: alphabuf.h types.h ..\include\GL\gl.h config.h fixed.h dd.h\r
+masking.obj: context.h macros.h masking.h pb.h\r
+matrix.obj: accum.h types.h ..\include\GL\gl.h config.h fixed.h dd.h alphabuf.h\r
+matrix.obj: context.h depth.h dlist.h macros.h matrix.h stencil.h\r
+misc.obj: accum.h types.h ..\include\GL\gl.h config.h fixed.h dd.h alphabuf.h\r
+misc.obj: context.h depth.h macros.h masking.h misc.h stencil.h\r
+pb.obj: alpha.h types.h ..\include\GL\gl.h config.h fixed.h dd.h alphabuf.h\r
+pb.obj: blend.h depth.h fog.h logic.h macros.h masking.h pb.h scissor.h\r
+pb.obj: stencil.h texture.h\r
+pixel.obj: context.h types.h ..\include\GL\gl.h config.h fixed.h dd.h dlist.h\r
+pixel.obj: macros.h pixel.h image.h span.h stencil.h\r
+points.obj: context.h types.h ..\include\GL\gl.h config.h fixed.h dd.h\r
+points.obj: feedback.h dlist.h macros.h pb.h span.h vb.h\r
+pointers.obj: accum.h types.h ..\include\GL\gl.h config.h fixed.h dd.h alpha.h\r
+pointers.obj: attrib.h bitmap.h blend.h clip.h context.h copypix.h depth.h\r
+pointers.obj: draw.h drawpix.h enable.h eval.h feedback.h fog.h get.h light.h\r
+pointers.obj: lines.h dlist.h logic.h macros.h masking.h matrix.h misc.h\r
+pointers.obj: pixel.h points.h polygon.h readpix.h scissor.h stencil.h\r
+pointers.obj: teximage.h texobj.h texture.h varray.h vb.h vertex.h winpos.h\r
+polygon.obj: context.h types.h ..\include\GL\gl.h config.h fixed.h dd.h\r
+polygon.obj: macros.h polygon.h\r
+readpix.obj: alphabuf.h types.h ..\include\GL\gl.h config.h fixed.h dd.h\r
+readpix.obj: context.h depth.h feedback.h dlist.h macros.h image.h readpix.h\r
+readpix.obj: span.h stencil.h\r
+scissor.obj: context.h types.h ..\include\GL\gl.h config.h fixed.h dd.h\r
+scissor.obj: macros.h dlist.h scissor.h\r
+span.obj: alpha.h types.h ..\include\GL\gl.h config.h fixed.h dd.h alphabuf.h\r
+span.obj: blend.h depth.h fog.h logic.h macros.h masking.h scissor.h span.h\r
+span.obj: stencil.h texture.h\r
+stencil.obj: context.h types.h ..\include\GL\gl.h config.h fixed.h dd.h dlist.h\r
+stencil.obj: macros.h pb.h stencil.h\r
+teximage.obj: context.h types.h ..\include\GL\gl.h config.h fixed.h dd.h\r
+teximage.obj: image.h macros.h pixel.h span.h teximage.h\r
+texobj.obj: context.h types.h ..\include\GL\gl.h config.h fixed.h dd.h macros.h\r
+texobj.obj: teximage.h texobj.h\r
+texture.obj: context.h types.h ..\include\GL\gl.h config.h fixed.h dd.h dlist.h\r
+texture.obj: macros.h pb.h teximage.h texture.h\r
+triangle.obj: depth.h types.h ..\include\GL\gl.h config.h fixed.h dd.h\r
+triangle.obj: feedback.h macros.h span.h triangle.h vb.h tritemp.h\r
+varray.obj: draw.h types.h ..\include\GL\gl.h config.h fixed.h dd.h context.h\r
+varray.obj: enable.h dlist.h macros.h varray.h vb.h xform.h\r
+vb.obj: types.h ..\include\GL\gl.h config.h fixed.h dd.h vb.h\r
+vertex.obj: draw.h types.h ..\include\GL\gl.h config.h fixed.h dd.h light.h\r
+vertex.obj: dlist.h macros.h vb.h vertex.h\r
+winpos.obj: ..\include\GL\gl.h draw.h types.h config.h fixed.h dd.h dlist.h\r
+winpos.obj: macros.h winpos.h\r
+xform.obj: types.h ..\include\GL\gl.h config.h fixed.h dd.h xform.h\r
+glx.obj: ..\include\GL\gl.h ..\include\GL\glx.h ..\include\GL\xmesa.h context.h\r
+glx.obj: types.h config.h fixed.h dd.h macros.h xmesaP.h\r
+osmesa.obj: ..\include\GL\osmesa.h ..\include\GL\gl.h context.h types.h\r
+osmesa.obj: config.h fixed.h dd.h depth.h macros.h matrix.h vb.h tritemp.h\r
+xfonts.obj: ..\include\GL\gl.h ..\include\GL\xmesa.h macros.h xmesaP.h types.h\r
+xfonts.obj: config.h fixed.h dd.h context.h\r
+xmesa1.obj: ..\include\GL\xmesa.h ..\include\GL\gl.h xmesaP.h types.h config.h\r
+xmesa1.obj: fixed.h dd.h context.h macros.h matrix.h\r
+xmesa2.obj: ..\include\GL\xmesa.h ..\include\GL\gl.h macros.h types.h config.h\r
+xmesa2.obj: fixed.h dd.h xmesaP.h\r
+xmesa3.obj: bresenhm.h types.h ..\include\GL\gl.h config.h fixed.h dd.h depth.h\r
+xmesa3.obj: interp.h macros.h vb.h xmesaP.h ..\include\GL\xmesa.h tritemp.h\r
diff --git a/src/mesa/drivers/dos/dosmesa.c b/src/mesa/drivers/dos/dosmesa.c
new file mode 100644 (file)
index 0000000..2f39732
--- /dev/null
@@ -0,0 +1,1513 @@
+/* $Id: dosmesa.c,v 1.1 1999/08/19 00:55:41 jtg Exp $ */\r
+\r
+/*\r
+ * Mesa 3-D graphics library\r
+ * Version:  2.3\r
+ * Copyright (C) 1995-1997  Brian Paul\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Library General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Library General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Library General Public\r
+ * License along with this library; if not, write to the Free\r
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
+ */\r
+\r
+\r
+/*\r
+ * $Log: dosmesa.c,v $
+ * Revision 1.1  1999/08/19 00:55:41  jtg
+ * Initial revision
+ *
+ * Revision 1.2  1999/03/28 21:11:57  brianp
+ * updated SetBuffer driver function
+ *
+ * Revision 1.1  1999/02/24 03:56:31  brianp
+ * initial check-in
+ *\r
+ *
+ * Revision 1.5  1997/06/19  22:00:00  Brian Paul\r
+ * Removed all ColorShift stuff
+ *\r
+ * Revision 1.4  1997/06/03  19:00:00  Brian Paul\r
+ * Replaced VB->Unclipped[] with VB->ClipMask[]\r
+ *\r
+ * Revision 1.3  1997/05/28  07:00:00  Phil Frisbie, Jr.\r
+ * Now pass red/green/blue/alpha bits to gl_create_visual()\r
+ * Fixed DJGPP mode 13 support.\r
+ *\r
+ * Revision 1.2  1996/12/08  16:13:45  Charlie\r
+ * Added VESA support via Scitechs SVGA kit.\r
+ *\r
+ * Revision 1.1  1996/12/08  16:09:52  Charlie\r
+ * Initial revision\r
+ *\r
+ */\r
+\r
+\r
+/*\r
+ * DOS VGA/VESA/MGL/Mesa interface.\r
+ *\r
+ */\r
+\r
+/*\r
+ *\r
+ * TODO: (cw)\r
+ *      Improve the colour matcher for rgb non vesa modes, its pretty bad and incorrect\r
+ *      Keyboard interrupt.\r
+ *  Comments and tidy up.\r
+ *  Add support for VESA without SVGAKIT.\r
+ *  DirectX Support.\r
+ *  Better GLIDE Support.\r
+ *  Clear up the #ifdef madness.\r
+ */\r
+\r
+#ifdef DOSVGA\r
+\r
+#if defined(DOSVGA) && !defined(GLIDE) && defined(DJGPP) && !defined(UNIVBE) && !defined(MGL)\r
+\r
+/* Should help cut down on the crazy #if`s */\r
+#define MODE13 1\r
+\r
+#else\r
+#undef MODE13\r
+#endif\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <string.h>\r
+#include <dos.h>\r
+\r
+#ifdef DJGPP\r
+#include <go32.h>\r
+#endif\r
+\r
+#ifdef MGL\r
+#include <mgraph.h>\r
+#endif\r
+\r
+#include "GL/DOSmesa.h"\r
+#include "context.h"\r
+#include "matrix.h"\r
+#include "types.h"\r
+\r
+#ifdef GLIDE\r
+\r
+static void glideshutdown( void );\r
+#include "vb.h"\r
+#include "glide.h"\r
+\r
+/* the glide modes available, set one */\r
+\r
+//#define GLIDE_MODE GR_RESOLUTION_\r
+#define GLIDE_MODE GR_RESOLUTION_800x600\r
+//#define GLIDE_MODE GR_RESOLUTION_640x480\r
+\r
+static GrVertex gr_vtx,gr_vtx1,gr_vtx2;\r
+\r
+#endif\r
+\r
+#ifdef UNIVBE\r
+/* You get this file from Scitechs VESA development kit */\r
+#include "svga.h"\r
+\r
+/*\r
+   Set these to the VESA mode you require, the first is for 256 colour modes,\r
+   the other is High colour modes, they must both be the same XRes and YRes.\r
+ */\r
+\r
+#define VESA_256COLOUR_MODE 0x11c\r
+#define VESA_HICOLOUR_MODE 0x11f\r
+\r
+#endif\r
+\r
+struct DOSmesa_context {\r
+   GLcontext *gl_ctx;                  /* the core Mesa context */\r
+   GLvisual *gl_vis;                           /* describes the color buffer */\r
+   GLframebuffer *gl_buffer;   /* the ancillary buffers */\r
+   GLuint index;                                       /* current color index */\r
+   GLint red, green, blue;             /* current rgb color */\r
+   GLint width, height;                        /* size of color buffer */\r
+   GLint depth;                                        /* bits per pixel (8,16,24 or 32) */\r
+};\r
+\r
+static DOSMesaContext DOSMesa = NULL;    /* the current context */\r
+\r
+#ifdef UNIVBE\r
+SV_devCtx *DC=NULL;\r
+int useLinear = TRUE;\r
+SV_modeInfo *mi=NULL;\r
+unsigned long modeNumber = 0;\r
+\r
+int activePage = 0;\r
+int visualPage = 1;\r
+\r
+#endif\r
+\r
+#if defined(MODE13)\r
+\r
+/* DOSVGA With no UniVBE support */\r
+\r
+unsigned char *video_buffer;\r
+\r
+#define VID_BUF(x,y) *(video_buffer+x+(y*320))\r
+\r
+#if defined(__WATCOMC__) && defined(__386__) && defined(__DOS__)\r
+\r
+void setupcopy(void);\r
+void copyscr(void);\r
+\r
+/* Watcom C specfic, screen copy and clear */\r
+\r
+#pragma aux setupcopy = \\r
+       ".386P"\\r
+       "push ebp" \\r
+       "mov esi,video_buffer" \\r
+       "mov edi,0xa0000" \\r
+       "mov ecx,2000" \\r
+       "xor ebp,ebp";\r
+\r
+#pragma aux copyscr = \\r
+       ".386P" \\r
+       "lop1: mov eax,[esi]"\\r
+       "mov ebx,[esi+4]"\\r
+       "mov edx,[esi+8]"\\r
+       "mov [edi],eax"\\r
+       "mov eax,[esi+12]"\\r
+       "mov dword ptr [esi],ebp"\\r
+       "mov dword ptr [esi+4],ebp"\\r
+       "mov dword ptr [esi+8],ebp"\\r
+       "mov dword ptr [esi+12],ebp"\\r
+       "mov [edi+4],ebx"\\r
+       "mov [edi+8],edx"\\r
+       "mov [edi+12],eax"\\r
+       "mov eax,[esi+16]"\\r
+       "mov ebx,[esi+4+16]"\\r
+       "mov edx,[esi+8+16]"\\r
+       "mov [edi+16],eax"\\r
+       "mov eax,[esi+12+16]"\\r
+       "mov dword ptr [esi+16],ebp"\\r
+       "mov dword ptr [esi+4+16],ebp"\\r
+       "mov dword ptr [esi+8+16],ebp"\\r
+       "mov dword ptr [esi+12+16],ebp"\\r
+       "mov [edi+4+16],ebx"\\r
+       "mov [edi+8+16],edx"\\r
+       "mov [edi+12+16],eax"\\r
+       "add esi,32"\\r
+       "add edi,32"\\r
+       "dec ecx"\\r
+       "jnz lop1"\\r
+       "pop ebp"\\r
+       modify exact [edi esi eax ebx ecx] ;\r
+\r
+#endif // WATCOM\r
+\r
+#endif // MODE13\r
+\r
+/*\r
+ * Convert Mesa window Y coordinate to VGA screen Y coordinate:\r
+ */\r
+#define FLIP(Y)  (DOSMesa->height-(Y)-1)\r
+\r
+unsigned short vga_cindex = 32768 ;\r
+\r
+static points_func choose_points_function( void );\r
+static line_func choose_line_function( void );\r
+static triangle_func choose_polygon_function( void );\r
+static void fast_tri(GLcontext *ctx,GLuint v0, GLuint v1, GLuint v2, GLuint pv );\r
+\r
+static points_func choose_points_function( void )\r
+{\r
+       return NULL;\r
+}\r
+\r
+static line_func choose_line_function( void )\r
+{\r
+       return NULL;\r
+}\r
+\r
+static triangle_func choose_triangle_function( void )\r
+{\r
+       #if defined(MODE13)\r
+               return  NULL;\r
+       #endif\r
+\r
+       #if defined(GLIDE)\r
+               return fast_tri;\r
+       #endif\r
+\r
+       return  NULL;\r
+}\r
+\r
+\r
+#if defined(MODE13)\r
+\r
+void setgfxmode(void);\r
+void settextmode(void);\r
+\r
+#ifndef DJGPP\r
+#pragma aux setgfxmode = \\r
+       "mov    ax,13h" \\r
+       "int    10h" \\r
+       modify [eax];\r
+\r
+#pragma aux settextmode = \\r
+       "mov    ax,3h" \\r
+       "int    10h" \\r
+       modify [eax];\r
+#else\r
+void setgfxmode(void)\r
+{\r
+       union REGS in_regs,out_regs;\r
+\r
+       in_regs.x.ax = 0x13;\r
+       int386(0x10,&in_regs,&out_regs);\r
+}\r
+\r
+void settextmode(void)\r
+{\r
+       union REGS in_regs,out_regs;\r
+\r
+       in_regs.x.ax = 0x3;\r
+       int386(0x10,&in_regs,&out_regs);\r
+}\r
+\r
+#endif\r
+\r
+int set_video_mode(unsigned short x,unsigned short y,char mode)\r
+{\r
+       setgfxmode();\r
+       return 1;       /* likelyhood of this failing is very small */\r
+}\r
+\r
+void restore_video_mode(void)\r
+{\r
+       settextmode();\r
+}\r
+\r
+int vga_getcolors(void)\r
+{\r
+       return vga_cindex;\r
+}\r
+\r
+int vga_getxdim(void)\r
+{\r
+       return 320;\r
+}\r
+\r
+int vga_getydim(void)\r
+{\r
+       return 200;\r
+}\r
+\r
+static unsigned short num_rgb_alloc = 1; /* start from 1, zero is black */\r
+\r
+/* an unlikely colour */\r
+static unsigned char last_r=1,last_g=255,last_b=99;\r
+\r
+extern void set_onecolor(int index,int R,int G,int B);\r
+\r
+static unsigned char rgbtable[64][64][64];\r
+\r
+void vga_setrgbcolor(int r,int g,int b)\r
+{\r
+\r
+/*\r
+ * make this into a translation table\r
+ */\r
+\r
+       DOSMesa->red = r;\r
+       DOSMesa->green = g ;\r
+       DOSMesa->blue = b ;\r
+\r
+       r/=4; g/=4; b/=4;\r
+\r
+       if( (r == last_r) && (g == last_g) && (b == last_b) ) return;\r
+\r
+       last_r = r ;\r
+       last_g = g ;\r
+       last_b = b ;\r
+\r
+       if(r+g+b == 0 ) {\r
+               DOSMesa->index = 0 ;\r
+               return ;\r
+       }\r
+\r
+       if( rgbtable[r][g][b] == 0 ) {\r
+               /* not allocated yet */\r
+               if(num_rgb_alloc<256) {\r
+                       DOSMesa->index = num_rgb_alloc;\r
+                       set_onecolor(num_rgb_alloc,r,g,b);\r
+                       rgbtable[r][g][b] = num_rgb_alloc;\r
+                       num_rgb_alloc++;\r
+                       return;\r
+\r
+               } else {\r
+                       /* need to search for a close colour */\r
+                       {\r
+                               unsigned short pass ;\r
+\r
+                               for(pass=0;pass<64;pass++) {\r
+                                       if(r-pass>0) {\r
+                                               if( rgbtable[r-pass][g][b] !=0 ) {\r
+                                                       rgbtable[r][g][b] = rgbtable[r-pass][g][b];\r
+                                                       DOSMesa->index = rgbtable[r-pass][g][b];\r
+                                                       return;\r
+                                               }\r
+                                       }\r
+                                       if(r+pass<64) {\r
+                                               if( rgbtable[r+pass][g][b] !=0 ) {\r
+                                                       rgbtable[r][g][b] = rgbtable[r+pass][g][b];\r
+                                                       DOSMesa->index = rgbtable[r+pass][g][b];\r
+                                                       return;\r
+                                               }\r
+                                       }\r
+                               }\r
+                       }\r
+                       rgbtable[r][g][b] = rand()%255;\r
+               }\r
+       }\r
+       DOSMesa->index = rgbtable[r][g][b];\r
+}\r
+\r
+#if defined(DJGPP)\r
+static int dos_seg;\r
+#endif\r
+\r
+void vga_clear(void)\r
+{\r
+\r
+/* Check if we`re using watcom and DOS */\r
+#if defined(__WATCOMC__) && defined(__386__) && defined(__DOS__)\r
+       setupcopy();\r
+       copyscr();\r
+#else\r
+\r
+#if defined (DJGPP)\r
+\r
+\r
+       asm ("\r
+               pusha\r
+               pushw   %es\r
+\r
+               movw    _dos_seg, %es\r
+\r
+               movl    _video_buffer, %esi\r
+               movl    $0xa0000, %edi\r
+\r
+               movl    $64000, %ecx\r
+\r
+               rep     ; movsb\r
+\r
+               popw    %es\r
+               popa\r
+       ");\r
+\r
+#else\r
+\r
+       /* copy the RAM buffer to the Video memory */\r
+       memcpy((unsigned char *)0xa0000,video_buffer, vga_getxdim()*vga_getydim() );\r
+\r
+#endif //DJGPP\r
+\r
+       /* clear the RAM buffer */\r
+       memset(video_buffer,0, vga_getxdim()*vga_getydim() );\r
+\r
+#endif //WATCOMC\r
+\r
+}\r
+\r
+#ifndef DEBUG\r
+#define vga_drawpixel(x,y) { VID_BUF(x,y) = DOSMesa->index; }\r
+#else\r
+void vga_drawpixel(x,y)\r
+{\r
+       VID_BUF(x,y) = DOSMesa->index;\r
+}\r
+#endif\r
+\r
+int vga_getpixel(int x,int y)\r
+{\r
+       return 1;\r
+}\r
+\r
+void vga_flip(void)\r
+{\r
+\r
+}\r
+\r
+void vga_setcolor(int index)\r
+{\r
+       /* does something, what i`ve no idea */\r
+       DOSMesa->index = index;\r
+\r
+}\r
+\r
+#endif\r
+\r
+#if defined(UNIVBE)\r
+\r
+/* UniVBE VESA support */\r
+\r
+void set_video_mode(unsigned short x,unsigned short y,char mode)\r
+{\r
+       if( setup_vesa_mode(x,y,mode) == FALSE ) {\r
+               fprintf(stderr,"VESA: Set mode failed\n");\r
+               exit(1);\r
+       }\r
+}\r
+\r
+/*\r
+   This is problematic as we don`t know what resolution the user program\r
+   wants when we reach here. This is why the 256 colour and HiColour modes\r
+       should be the same resolution, perhaps i`ll make this an environment\r
+       variable\r
+ */\r
+\r
+\r
+void check_mi(void)\r
+{\r
+       if(mi!=0) return;\r
+\r
+       if(DC==NULL) {\r
+               DC = SV_init( TRUE );\r
+       }\r
+\r
+       if(modeNumber == 0 ) {\r
+               modeNumber = VESA_HICOLOUR_MODE;\r
+       }\r
+\r
+       SV_getModeInfo(modeNumber,mi);\r
+\r
+       return;\r
+}\r
+\r
+int setup_vesa_mode(short height,short width,short depth)\r
+{\r
+       if(DC==NULL) {\r
+               DC = SV_init( TRUE );\r
+               /* how many bits per pixel */\r
+               if( depth == 0)\r
+                       modeNumber = VESA_256COLOUR_MODE;\r
+               else\r
+                       modeNumber = VESA_HICOLOUR_MODE;\r
+       }\r
+\r
+       /* Check if correct VESA Version is available */\r
+       if( !DC || DC->VBEVersion < 0x0102) {\r
+               fprintf(stderr,"Require a VESA VBE version 1.2 or higher\n");\r
+               return FALSE;\r
+       }\r
+\r
+       /* Check for LFB Supprt */\r
+       if(DC->VBEVersion < 0x0200 ) {\r
+               useLinear = FALSE;\r
+       } else {\r
+               useLinear = TRUE ;\r
+       }\r
+\r
+       /* Get desired mode info */\r
+   if(!SV_getModeInfo( modeNumber, mi))\r
+               return FALSE;\r
+\r
+       /* Set VESA mode */\r
+       if(!SV_setMode(modeNumber | svMultiBuffer, FALSE, TRUE, mi->NumberOfPages) )\r
+               return FALSE;\r
+\r
+       return TRUE;\r
+}\r
+\r
+void restore_video_mode(void)\r
+{\r
+       SV_restoreMode();\r
+}\r
+\r
+void vga_clear(void)\r
+{\r
+       SV_clear(0);\r
+}\r
+\r
+void vga_flip(void)\r
+{\r
+       activePage = 1-activePage;\r
+       visualPage = 1-activePage;\r
+\r
+       SV_setActivePage(activePage);\r
+\r
+       /*\r
+          Change false to true if you`re getting flickering\r
+          even in double buffer mode, ( sets wait for Vertical retrace  )\r
+       */\r
+       SV_setVisualPage(visualPage,false);\r
+}\r
+\r
+int vga_getcolors(void)\r
+{\r
+       check_mi();\r
+       switch ( mi->BitsPerPixel ) {\r
+               case 8:\r
+                       return 256;\r
+               case 15:\r
+               case 16:\r
+                       return 32768;\r
+               default:\r
+                       return 64000;\r
+        }\r
+}\r
+\r
+int vga_getxdim(void)\r
+{\r
+       check_mi();\r
+       return mi->XResolution;\r
+}\r
+\r
+int vga_getydim(void)\r
+{\r
+       check_mi();\r
+       return mi->YResolution;\r
+}\r
+\r
+unsigned long current_color = 255;\r
+\r
+void vga_setrgbcolor(int r,int g,int b)\r
+{\r
+       DOSMesa->red = r;\r
+       DOSMesa->green = g ;\r
+       DOSMesa->blue = b ;\r
+       current_color = SV_rgbColor(r,g,b);\r
+}\r
+\r
+void vga_setcolor(int index)\r
+{\r
+       DOSMesa->index = index;\r
+       current_color = index;\r
+}\r
+\r
+void vga_drawpixel(x,y)\r
+{\r
+       SV_putPixel(x,y,current_color);\r
+}\r
+\r
+/* TODO: */\r
+int vga_getpixel(x,y)\r
+{\r
+/*     return (int)SV_getPixel(x,y); */\r
+       fprintf(stderr,"vga_getpixel: Not implemented yet\n");\r
+       return 1;\r
+}\r
+\r
+/* End of UNIVBE section */\r
+#endif\r
+\r
+/* Scitechs MegaGraphicsLibrary http://www.scitechsoft.com/ */\r
+\r
+#if defined(MGL)\r
+\r
+/* MGL support */\r
+struct MI {\r
+       unsigned short BitsPerPixel;\r
+       unsigned long XResolution;\r
+       unsigned long YResolution;\r
+};\r
+\r
+struct MI*mi;\r
+\r
+static MGLDC*DC;\r
+static int activePage = 0;\r
+static int visualPage = 1;\r
+static int modeNumber = 0;\r
+\r
+void set_video_mode(unsigned short xres,unsigned short yres,char mode)\r
+{\r
+    int     i,driver = grDETECT,dmode = grDETECT;\r
+    event_t evt;\r
+\r
+       /* Start the MGL with only the SVGA 16m driver active */\r
+       MGL_registerDriver(MGL_SVGA16NAME,SVGA16_driver);\r
+       if (!MGL_init(&driver,&dmode,"..\\..\\"))\r
+               MGL_fatalError(MGL_errorMsg(MGL_result()));\r
+       if ((DC = MGL_createDisplayDC(false)) == NULL)\r
+               MGL_fatalError(MGL_errorMsg(MGL_result()));\r
+       MGL_makeCurrentDC(DC);\r
+}\r
+\r
+/*\r
+   This is problematic as we don`t know what resolution the user program\r
+   wants when we reach here. This is why the 256 colour and HiColour modes\r
+       should be the same resolution, perhaps i`ll make this an environment\r
+       variable\r
+ */\r
+\r
+#define MGL_HICOLOUR_MODE 0\r
+\r
+\r
+void check_mi(void)\r
+{\r
+       if(mi!=0) return;\r
+\r
+       if(DC==NULL) {\r
+//             DC = SV_init( TRUE );\r
+       }\r
+\r
+       if(modeNumber == 0 ) {\r
+               modeNumber = MGL_HICOLOUR_MODE;\r
+       }\r
+\r
+//     SV_getModeInfo(modeNumber,mi);\r
+\r
+       return;\r
+}\r
+\r
+void restore_video_mode(void)\r
+{\r
+       MGL_exit();\r
+}\r
+\r
+void vga_clear(void)\r
+{\r
+       MGL_clearDevice();\r
+}\r
+\r
+void vga_flip(void)\r
+{\r
+       activePage = 1-activePage;\r
+       visualPage = 1-activePage;\r
+\r
+//     SV_setActivePage(activePage);\r
+\r
+       /*\r
+          Change false to true if you`re getting flickering\r
+          even in double buffer mode, ( sets wait for Vertical retrace  )\r
+       */\r
+//     SV_setVisualPage(visualPage,false);\r
+}\r
+\r
+int vga_getcolors(void)\r
+{\r
+       check_mi();\r
+       switch ( mi->BitsPerPixel ) {\r
+               case 8:\r
+                       return 256;\r
+               case 15:\r
+               case 16:\r
+                       return 32768;\r
+               default:\r
+                       return 64000;\r
+        }\r
+}\r
+\r
+int vga_getxdim(void)\r
+{\r
+       check_mi();\r
+       return mi->XResolution;\r
+}\r
+\r
+int vga_getydim(void)\r
+{\r
+       check_mi();\r
+       return mi->YResolution;\r
+}\r
+\r
+unsigned long current_color = 255;\r
+\r
+void vga_setrgbcolor(int r,int g,int b)\r
+{\r
+       DOSMesa->red = r;\r
+       DOSMesa->green = g ;\r
+       DOSMesa->blue = b ;\r
+       current_color = MGL_rgbColor(DC,r,g,b);\r
+}\r
+\r
+void vga_setcolor(int index)\r
+{\r
+       DOSMesa->index = index;\r
+       current_color = index;\r
+}\r
+\r
+void vga_drawpixel(x,y)\r
+{\r
+       MGL_pixelCoord(x,y);\r
+}\r
+\r
+/* TODO: */\r
+int vga_getpixel(x,y)\r
+{\r
+/*     return (int)SV_getPixel(x,y); */\r
+       fprintf(stderr,"vga_getpixel: Not implemented yet\n");\r
+       return 1;\r
+}\r
+\r
+/* End of UNIVBE section */\r
+#endif\r
+\r
+#ifdef GLIDE\r
+\r
+/* GLIDE support */\r
+\r
+static GrHwConfiguration hwconfig;\r
+\r
+void set_video_mode(unsigned short x,unsigned short y,char mode)\r
+{\r
+       grGlideInit();\r
+       if( grSstQueryHardware( &hwconfig ) ) {\r
+               grSstSelect( 0 ) ;\r
+               if( !grSstOpen( GLIDE_MODE,\r
+                                                       GR_REFRESH_60Hz,\r
+                                                       GR_COLORFORMAT_ABGR,\r
+                                                       GR_ORIGIN_UPPER_LEFT,\r
+                                                       GR_SMOOTHING_ENABLE,\r
+                                                       2 ) ) {\r
+                       fprintf(stderr,"Detected 3DFX board, but couldn`t initialize!");\r
+                       exit(1);\r
+               }\r
+\r
+               grBufferClear( 0, 0, GR_WDEPTHVALUE_FARTHEST);\r
+\r
+               grDisableAllEffects();\r
+               atexit( glideshutdown );\r
+\r
+//             guColorCombineFunction( GR_COLORCOMBINE_ITRGB );\r
+//             grTexCombineFunction( GR_TMU0, GR_TEXTURECOMBINE_ZERO);\r
+       }\r
+}\r
+\r
+void restore_video_mode(void)\r
+{\r
+}\r
+\r
+static void glideshutdown( void )\r
+{\r
+       grGlideShutdown() ;\r
+}\r
+\r
+void vga_clear(void)\r
+{\r
+       grBufferSwap(0);\r
+       grBufferClear( 0, 0, GR_WDEPTHVALUE_FARTHEST);\r
+}\r
+\r
+void vga_flip(void)\r
+{\r
+}\r
+\r
+int vga_getcolors(void)\r
+{\r
+       return 32768;\r
+}\r
+\r
+int vga_getxdim(void)\r
+{\r
+#if GLIDE_MODE == GR_RESOLUTION_800x600\r
+               return 800;\r
+#else\r
+               return 640;\r
+#endif\r
+}\r
+\r
+int vga_getydim(void)\r
+{\r
+#if GLIDE_MODE == GR_RESOLUTION_800x600\r
+               return 600;\r
+#else\r
+               return 480;\r
+#endif\r
+}\r
+\r
+unsigned long current_color = 255;\r
+\r
+void vga_setrgbcolor(int r,int g,int b)\r
+{\r
+       DOSMesa->red = r;\r
+       DOSMesa->green = g ;\r
+       DOSMesa->blue = b ;\r
+}\r
+\r
+void vga_setcolor(int index)\r
+{\r
+       DOSMesa->index = index;\r
+}\r
+\r
+void vga_drawpixel(x,y)\r
+{\r
+\r
+       gr_vtx.x = x;\r
+       gr_vtx.y = y;\r
+       gr_vtx.z = 0;\r
+       gr_vtx.r        = DOSMesa->red;\r
+       gr_vtx.g        = DOSMesa->green;\r
+       gr_vtx.b        = DOSMesa->blue;\r
+\r
+       grDrawPoint( &gr_vtx );\r
+}\r
+\r
+static void fast_tri(GLcontext *ctx,GLuint v0, GLuint v1, GLuint v2, GLuint pv )\r
+{\r
+   struct vertex_buffer *VB = ctx->VB;\r
+\r
+       gr_vtx.z = 0;\r
+       gr_vtx1.z = 0;\r
+       gr_vtx2.z = 0;\r
+\r
+   if (VB->MonoColor) {\r
+               gr_vtx.r = DOSMesa->red;\r
+       gr_vtx.g = DOSMesa->green;\r
+       gr_vtx.b = DOSMesa->blue;\r
+       gr_vtx1.r = DOSMesa->red;\r
+       gr_vtx1.g = DOSMesa->green;\r
+       gr_vtx1.b = DOSMesa->blue;\r
+       gr_vtx2.r = DOSMesa->red;\r
+       gr_vtx2.g = DOSMesa->green;\r
+       gr_vtx2.b = DOSMesa->blue;\r
+   } else {\r
+               if(ctx->Light.ShadeModel == GL_SMOOTH ) {\r
+                       gr_vtx.r  = FixedToInt( VB->Color[v0][0] );\r
+                       gr_vtx.g  = FixedToInt( VB->Color[v0][1] );\r
+                       gr_vtx.b  = FixedToInt( VB->Color[v0][2] );\r
+\r
+                       gr_vtx1.r = FixedToInt( VB->Color[v1][0] );\r
+                       gr_vtx1.g = FixedToInt( VB->Color[v1][1] );\r
+                       gr_vtx1.b = FixedToInt( VB->Color[v1][2] );\r
+\r
+                       gr_vtx2.r = FixedToInt( VB->Color[v2][0] );\r
+                       gr_vtx2.g = FixedToInt( VB->Color[v2][1] );\r
+                       gr_vtx2.b = FixedToInt( VB->Color[v2][2] );\r
+               } else {\r
+                       gr_vtx.r  = VB->Color[pv][0];\r
+                       gr_vtx.g  = VB->Color[pv][1];\r
+                       gr_vtx.b  = VB->Color[pv][2];\r
+\r
+                       gr_vtx1.r = VB->Color[pv][0];\r
+                       gr_vtx1.g = VB->Color[pv][1];\r
+                       gr_vtx1.b = VB->Color[pv][2];\r
+\r
+                       gr_vtx2.r = VB->Color[pv][0];\r
+                       gr_vtx2.g = VB->Color[pv][1];\r
+                       gr_vtx2.b = VB->Color[pv][2];\r
+               }\r
+       }\r
+\r
+   gr_vtx.x  =       (VB->Win[v0][0] );\r
+   gr_vtx.y  = FLIP( (VB->Win[v0][1] ) );\r
+   gr_vtx1.x =       (VB->Win[v1][0] );\r
+   gr_vtx1.y = FLIP( (VB->Win[v1][1] ) );\r
+   gr_vtx2.x =       (VB->Win[v2][0] );\r
+   gr_vtx2.y = FLIP( (VB->Win[v2][1] ) );\r
+\r
+       if(gr_vtx.x <0 || gr_vtx.x > 639 )\r
+               return;\r
+       if(gr_vtx1.x <0 || gr_vtx1.x > 639 )\r
+               return;\r
+       if(gr_vtx2.x <0 || gr_vtx2.x > 639 )\r
+               return;\r
+\r
+       if(gr_vtx.y <0 || gr_vtx.y > 479 )\r
+               return;\r
+       if(gr_vtx1.y <0 || gr_vtx1.y > 479 )\r
+               return;\r
+       if(gr_vtx2.y <0 || gr_vtx2.y > 479 )\r
+               return;\r
+\r
+       grDrawTriangle( &gr_vtx,&gr_vtx1,&gr_vtx2);\r
+}\r
+\r
+void fast_plot(GLcontext *ctx,GLuint first,GLuint last )\r
+{\r
+       struct vertex_buffer *VB = ctx->VB;\r
+       register GLuint i;\r
+\r
+       if(VB->MonoColor) {\r
+               /* all same color */\r
+\r
+               gr_vtx.r = DOSMesa->red;\r
+               gr_vtx.g = DOSMesa->green;\r
+               gr_vtx.b = DOSMesa->blue;\r
+\r
+               for(i=first;i<last;i++) {\r
+                       if(VB->ClipMask[i]==0) {\r
+                               gr_vtx.x = VB->Win[i][0];\r
+                               gr_vtx.y = FLIP(VB->Win[i][1]);\r
+                       }\r
+               }\r
+       }\r
+}\r
+\r
+/* TODO: */\r
+int vga_getpixel(x,y)\r
+{\r
+/*     return (int)SV_getPixel(x,y); */\r
+       fprintf(stderr,"vga_getpixel: Not implemented yet\n");\r
+       return 1;\r
+}\r
+\r
+/* End of GLIDE section */\r
+\r
+#endif // GLIDE\r
+/**********************************************************************/\r
+/*****                 Miscellaneous functions                    *****/\r
+/**********************************************************************/\r
+\r
+\r
+static void get_buffer_size( GLcontext *ctx, GLuint *width, GLuint *height )\r
+{\r
+   *width = DOSMesa->width = vga_getxdim();\r
+   *height = DOSMesa->height = vga_getydim();\r
+}\r
+\r
+\r
+/* Set current color index */\r
+static void set_index( GLcontext *ctx, GLuint index )\r
+{\r
+   DOSMesa->index = index;\r
+   /*vga_setcolor( index );*/\r
+}\r
+\r
+\r
+/* Set current drawing color */\r
+static void set_color( GLcontext *ctx,\r
+                       GLubyte red, GLubyte green,\r
+                       GLubyte blue, GLubyte alpha )\r
+{\r
+   DOSMesa->red = red;\r
+   DOSMesa->green = green;\r
+   DOSMesa->blue = blue;\r
+   vga_setrgbcolor( red, green, blue );\r
+}\r
+\r
+\r
+static void clear_index( GLcontext *ctx, GLuint index )\r
+{\r
+   /* TODO: Implements glClearIndex() */\r
+}\r
+\r
+\r
+static void clear_color( GLcontext *ctx,\r
+                         GLubyte red, GLubyte green,\r
+                         GLubyte blue, GLubyte alpha )\r
+{\r
+   /* TODO: Implements glClearColor() */\r
+}\r
+\r
+\r
+static void clear( GLcontext *ctx,\r
+                   GLboolean all,\r
+                   GLint x, GLint y, GLint width, GLint height )\r
+{\r
+   vga_clear();\r
+}\r
+\r
+\r
+static GLboolean set_buffer( GLcontext *ctx,\r
+                             GLenum mode )\r
+{\r
+   /* TODO: implement double buffering and use this function to select */\r
+   /* between front and back buffers. */\r
+   if (buffer == GL_FRONT_LEFT)\r
+      return GL_TRUE;\r
+   else if (buffer == GL_BACK_LEFT)\r
+      return GL_TRUE;\r
+   else\r
+      return GL_FALSE;\r
+}\r
+\r
+\r
+\r
+\r
+/**********************************************************************/\r
+/*****            Write spans of pixels                           *****/\r
+/**********************************************************************/\r
+\r
+\r
+static void write_index_span( GLcontext *ctx,\r
+                              GLuint n, GLint x, GLint y,\r
+                              const GLuint index[],\r
+                              const GLubyte mask[] )\r
+{\r
+   int i;\r
+   y = FLIP(y);\r
+#ifdef UNIVBE\r
+       SV_beginPixel();\r
+#endif\r
+   for (i=0;i<n;i++,x++) {\r
+      if (mask[i]) {\r
+#ifdef UNIVBE\r
+               SV_putPixelFast(x,y,current_color);\r
+#else\r
+         vga_setcolor( index[i] );\r
+         vga_drawpixel( x, y );\r
+#endif\r
+      }\r
+   }\r
+\r
+#ifdef UNIVBE\r
+       SV_endPixel();\r
+#endif\r
+\r
+}\r
+\r
+\r
+\r
+static void write_monoindex_span( GLcontext *ctx,\r
+                                  GLuint n, GLint x, GLint y,\r
+                                  const GLubyte mask[] )\r
+{\r
+   int i;\r
+   y = FLIP(y);\r
+   /* use current color index */\r
+   vga_setcolor( DOSMesa->index );\r
+#ifdef UNIVBE\r
+       SV_beginPixel();\r
+#endif\r
+   for (i=0;i<n;i++,x++) {\r
+      if (mask[i]) {\r
+#ifdef UNIVBE\r
+                       SV_putPixelFast(x,y,current_color);\r
+#else\r
+         vga_drawpixel( x, y );\r
+#endif\r
+      }\r
+   }\r
+#ifdef UNIVBE\r
+       SV_endPixel();\r
+#endif\r
+}\r
+\r
+\r
+\r
+static void write_color_span( GLcontext *ctx,\r
+                              GLuint n, GLint x, GLint y,\r
+                              const GLubyte red[], const GLubyte green[],\r
+                              const GLubyte blue[], const GLubyte alpha[],\r
+                              const GLubyte mask[] )\r
+{\r
+   int i;\r
+   y=FLIP(y);\r
+#ifdef UNIVBE\r
+       SV_beginPixel();\r
+#endif\r
+   if (mask) {\r
+      /* draw some pixels */\r
+      for (i=0; i<n; i++, x++) {\r
+         if (mask[i]) {\r
+#ifdef UNIVBE\r
+                               SV_putPixelFast(x,y,SV_rgbColor(red[i], green[i], blue[i]) );\r
+#else\r
+            vga_setrgbcolor( red[i], green[i], blue[i] );\r
+            vga_drawpixel( x, y );\r
+#endif\r
+         }\r
+      }\r
+   }\r
+   else {\r
+      /* draw all pixels */\r
+      for (i=0; i<n; i++, x++) {\r
+#ifdef UNIVBE\r
+                       SV_putPixelFast(x,y,SV_rgbColor(red[i], green[i], blue[i]) );\r
+#else\r
+         vga_setrgbcolor( red[i], green[i], blue[i] );\r
+         vga_drawpixel( x, y );\r
+#endif\r
+      }\r
+   }\r
+#ifdef UNIVBE\r
+       SV_endPixel();\r
+#endif\r
+}\r
+\r
+\r
+\r
+static void write_monocolor_span( GLcontext *ctx,\r
+                                  GLuint n, GLint x, GLint y,\r
+                                  const GLubyte mask[])\r
+{\r
+   int i;\r
+   y=FLIP(y);\r
+#ifdef UNIVBE\r
+       SV_beginPixel();\r
+#endif\r
+   /* use current rgb color */\r
+   vga_setrgbcolor( DOSMesa->red, DOSMesa->green, DOSMesa->blue );\r
+   for (i=0; i<n; i++, x++) {\r
+      if (mask[i]) {\r
+#ifdef UNIVBE\r
+                       SV_putPixelFast(x,y,current_color);\r
+#else\r
+         vga_drawpixel( x, y );\r
+#endif\r
+      }\r
+   }\r
+#ifdef UNIVBE\r
+       SV_endPixel();\r
+#endif\r
+}\r
+\r
+\r
+\r
+/**********************************************************************/\r
+/*****                 Read spans of pixels                       *****/\r
+/**********************************************************************/\r
+\r
+\r
+static void read_index_span( GLcontext *ctx,\r
+                             GLuint n, GLint x, GLint y, GLuint index[])\r
+{\r
+   int i;\r
+   y = FLIP(y);\r
+   for (i=0; i<n; i++,x++) {\r
+      index[i] = vga_getpixel( x, y );\r
+   }\r
+}\r
+\r
+\r
+\r
+static void read_color_span( GLcontext *ctx,\r
+                             GLuint n, GLint x, GLint y,\r
+                             GLubyte red[], GLubyte green[],\r
+                             GLubyte blue[], GLubyte alpha[] )\r
+{\r
+   int i;\r
+   for (i=0; i<n; i++, x++) {\r
+      /* TODO */\r
+   }\r
+}\r
+\r
+\r
+\r
+/**********************************************************************/\r
+/*****                  Write arrays of pixels                    *****/\r
+/**********************************************************************/\r
+\r
+\r
+static void write_index_pixels( GLcontext *ctx,\r
+                                GLuint n, const GLint x[], const GLint y[],\r
+                                const GLuint index[], const GLubyte mask[] )\r
+{\r
+   int i;\r
+#ifdef UNIVBE\r
+       SV_beginPixel();\r
+#endif\r
+   for (i=0; i<n; i++) {\r
+      if (mask[i]) {\r
+#ifdef UNIVBE\r
+                       SV_putPixelFast(x[i], FLIP(y[i]), index[i] );\r
+#else\r
+         vga_setcolor( index[i] );\r
+         vga_drawpixel( x[i], FLIP(y[i]) );\r
+#endif\r
+      }\r
+   }\r
+#ifdef UNIVBE\r
+       SV_endPixel();\r
+#endif\r
+}\r
+\r
+\r
+\r
+static void write_monoindex_pixels( GLcontext *ctx,\r
+                                    GLuint n,\r
+                                    const GLint x[], const GLint y[],\r
+                                    const GLubyte mask[] )\r
+{\r
+   int i;\r
+   /* use current color index */\r
+   vga_setcolor( DOSMesa->index );\r
+#ifdef UNIVBE\r
+       SV_beginPixel();\r
+#endif\r
+   for (i=0; i<n; i++) {\r
+      if (mask[i]) {\r
+#ifdef UNIVBE\r
+                       SV_putPixelFast(x[i], FLIP(y[i]), DOSMesa->index);\r
+#else\r
+         vga_drawpixel( x[i], FLIP(y[i]) );\r
+#endif\r
+      }\r
+   }\r
+#ifdef UNIVBE\r
+       SV_endPixel();\r
+#endif\r
+}\r
+\r
+\r
+\r
+static void write_color_pixels( GLcontext *ctx,\r
+                                GLuint n, const GLint x[], const GLint y[],\r
+                                const GLubyte r[], const GLubyte g[],\r
+                                const GLubyte b[], const GLubyte a[],\r
+                                const GLubyte mask[] )\r
+{\r
+   int i;\r
+#ifdef UNIVBE\r
+       SV_beginPixel();\r
+#endif\r
+   for (i=0; i<n; i++) {\r
+      if (mask[i]) {\r
+#ifdef UNIVBE\r
+                       SV_putPixelFast(x[i], FLIP(y[i]), SV_rgbColor(r[i], g[i], b[i]) );\r
+#else\r
+         vga_setrgbcolor( r[i], g[i], b[i] );\r
+         vga_drawpixel( x[i], FLIP(y[i]) );\r
+#endif\r
+      }\r
+   }\r
+#ifdef UNIVBE\r
+       SV_endPixel();\r
+#endif\r
+}\r
+\r
+static void write_monocolor_pixels( GLcontext *ctx,\r
+                                    GLuint n,\r
+                                    const GLint x[], const GLint y[],\r
+                                    const GLubyte mask[] )\r
+{\r
+   int i;\r
+   /* use current rgb color */\r
+   vga_setrgbcolor( DOSMesa->red, DOSMesa->green, DOSMesa->blue );\r
+#ifdef UNIVBE\r
+       SV_beginPixel();\r
+#endif\r
+   for (i=0; i<n; i++) {\r
+      if (mask[i]) {\r
+#ifdef UNIVBE\r
+                       SV_putPixelFast(x[i], FLIP(y[i]), current_color );\r
+#else\r
+         vga_drawpixel( x[i], FLIP(y[i]) );\r
+#endif\r
+      }\r
+   }\r
+#ifdef UNIVBE\r
+       SV_endPixel();\r
+#endif\r
+}\r
+\r
+/**********************************************************************/\r
+/*****                   Read arrays of pixels                    *****/\r
+/**********************************************************************/\r
+\r
+/* Read an array of color index pixels. */\r
+static void read_index_pixels( GLcontext *ctx,\r
+                               GLuint n, const GLint x[], const GLint y[],\r
+                               GLuint index[], const GLubyte mask[] )\r
+{\r
+   int i;\r
+   for (i=0; i<n; i++) {\r
+      index[i] = vga_getpixel( x[i], FLIP(y[i]) );\r
+   }\r
+}\r
+\r
+\r
+\r
+static void read_color_pixels( GLcontext *ctx,\r
+                               GLuint n, const GLint x[], const GLint y[],\r
+                               GLubyte red[], GLubyte green[],\r
+                               GLubyte blue[], GLubyte alpha[],\r
+                               const GLubyte mask[] )\r
+{\r
+   /* TODO */\r
+}\r
+\r
+static void DOSmesa_setup_DD_pointers( GLcontext *ctx )\r
+{\r
+   /* Initialize all the pointers in the DD struct.  Do this whenever */\r
+   /* a new context is made current or we change buffers via set_buffer! */\r
+\r
+   ctx->Driver.UpdateState = DOSmesa_setup_DD_pointers;\r
+\r
+   ctx->Driver.ClearIndex = clear_index;\r
+   ctx->Driver.ClearColor = clear_color;\r
+   ctx->Driver.Clear = clear;\r
+\r
+   ctx->Driver.Index = set_index;\r
+   ctx->Driver.Color = set_color;\r
+\r
+   ctx->Driver.SetBuffer = set_buffer;\r
+   ctx->Driver.GetBufferSize = get_buffer_size;\r
+\r
+   ctx->Driver.PointsFunc = choose_points_function();\r
+   ctx->Driver.LineFunc = choose_line_function();\r
+   ctx->Driver.TriangleFunc = choose_triangle_function();\r
+\r
+\r
+   /* Pixel/span writing functions: */\r
+   /* TODO: use different funcs for 8, 16, 32-bit depths */\r
+   ctx->Driver.WriteColorSpan       = write_color_span;\r
+   ctx->Driver.WriteMonocolorSpan   = write_monocolor_span;\r
+   ctx->Driver.WriteColorPixels     = write_color_pixels;\r
+   ctx->Driver.WriteMonocolorPixels = write_monocolor_pixels;\r
+   ctx->Driver.WriteIndexSpan       = write_index_span;\r
+   ctx->Driver.WriteMonoindexSpan   = write_monoindex_span;\r
+   ctx->Driver.WriteIndexPixels     = write_index_pixels;\r
+   ctx->Driver.WriteMonoindexPixels = write_monoindex_pixels;\r
+\r
+   /* Pixel/span reading functions: */\r
+   /* TODO: use different funcs for 8, 16, 32-bit depths */\r
+   ctx->Driver.ReadIndexSpan = read_index_span;\r
+   ctx->Driver.ReadColorSpan = read_color_span;\r
+   ctx->Driver.ReadIndexPixels = read_index_pixels;\r
+   ctx->Driver.ReadColorPixels = read_color_pixels;\r
+}\r
+\r
+/*\r
+ * Create a new VGA/Mesa context and return a handle to it.\r
+ */\r
+DOSMesaContext DOSMesaCreateContext( void )\r
+{\r
+   DOSMesaContext ctx;\r
+   GLboolean rgb_flag;\r
+   GLfloat redscale, greenscale, bluescale, alphascale;\r
+   GLboolean db_flag = GL_FALSE;\r
+   GLboolean alpha_flag = GL_FALSE;\r
+   int colors;\r
+   GLint index_bits;\r
+   GLint redbits, greenbits, bluebits, alphabits;\r
+\r
+#if !defined(UNIVBE) && !defined(GLIDE) && !defined(MGL)\r
+       video_buffer = (unsigned char *) malloc( vga_getxdim() * vga_getydim() );\r
+\r
+       memset(video_buffer,0, vga_getxdim() * vga_getydim() );\r
+\r
+       memset(rgbtable,0,sizeof( rgbtable ) );\r
+#endif\r
+\r
+#if defined( DJGPP ) && !defined(UNIVBE) && !defined(GLIDE)\r
+       dos_seg = _go32_conventional_mem_selector();\r
+#endif\r
+\r
+   /* determine if we're in RGB or color index mode */\r
+   colors = vga_getcolors();\r
+   if (colors==32768) {\r
+      rgb_flag = GL_TRUE;\r
+      redscale = greenscale = bluescale = alphascale = 255.0;\r
+      redbits = greenbits = bluebits = 8;\r
+      alphabits = 0;\r
+      index_bits = 0;\r
+   }\r
+   else if (colors==256) {\r
+      rgb_flag = GL_FALSE;\r
+      redscale = greenscale = bluescale = alphascale = 0.0;\r
+      redbits = greenbits = bluebits = alphabits = 0;\r
+      index_bits = 8;\r
+   }\r
+   else {\r
+               restore_video_mode();\r
+      fprintf(stderr,"[%d] >16 bit color not implemented yet!\n",colors);\r
+      return NULL;\r
+   }\r
+\r
+   ctx = (DOSMesaContext) calloc( 1, sizeof(struct DOSmesa_context) );\r
+   if (!ctx) {\r
+      return NULL;\r
+   }\r
+\r
+   ctx->gl_vis = gl_create_visual( rgb_flag,\r
+                                   alpha_flag,\r
+                                   db_flag,\r
+                                   16,   /* depth_size */\r
+                                   8,    /* stencil_size */\r
+                                   16,   /* accum_size */\r
+                                   index_bits,\r
+                                   redscale,\r
+                                   greenscale,\r
+                                   bluescale,\r
+                                   alphascale,\r
+                                   redbits, greenbits,\r
+                                   bluebits, alphabits);\r
+\r
+   ctx->gl_ctx = gl_create_context( ctx->gl_vis,\r
+                                    NULL,  /* share list context */\r
+                                    (void *) ctx\r
+                                  );\r
+\r
+   ctx->gl_buffer = gl_create_framebuffer( ctx->gl_vis );\r
+\r
+   ctx->index = 1;\r
+   ctx->red = ctx->green = ctx->blue = 255;\r
+\r
+   ctx->width = ctx->height = 0;  /* temporary until first "make-current" */\r
+\r
+   return ctx;\r
+}\r
+\r
+/*\r
+ * Destroy the given VGA/Mesa context.\r
+ */\r
+void DOSMesaDestroyContext( DOSMesaContext ctx )\r
+{\r
+   if (ctx) {\r
+      gl_destroy_visual( ctx->gl_vis );\r
+      gl_destroy_context( ctx->gl_ctx );\r
+      gl_destroy_framebuffer( ctx->gl_buffer );\r
+      free( ctx );\r
+      if (ctx==DOSMesa) {\r
+         DOSMesa = NULL;\r
+      }\r
+   }\r
+}\r
+\r
+\r
+\r
+/*\r
+ * Make the specified VGA/Mesa context the current one.\r
+ */\r
+void DOSMesaMakeCurrent( DOSMesaContext ctx )\r
+{\r
+   DOSMesa = ctx;\r
+   gl_make_current( ctx->gl_ctx, ctx->gl_buffer );\r
+   DOSmesa_setup_DD_pointers( ctx->gl_ctx );\r
+\r
+   if (ctx->width==0 || ctx->height==0) {\r
+      /* setup initial viewport */\r
+      ctx->width = vga_getxdim();\r
+      ctx->height = vga_getydim();\r
+      gl_Viewport( ctx->gl_ctx, 0, 0, ctx->width, ctx->height );\r
+   }\r
+}\r
+\r
+\r
+\r
+/*\r
+ * Return a handle to the current VGA/Mesa context.\r
+ */\r
+DOSMesaContext DOSMesaGetCurrentContext( void )\r
+{\r
+   return DOSMesa;\r
+}\r
+\r
+\r
+/*\r
+ * Swap front/back buffers for current context if double buffered.\r
+ */\r
+void DOSMesaSwapBuffers( void )\r
+{\r
+#if !defined(UNIVBE)\r
+/* Assume double buffering is available if in UNIVBE,\r
+   if it isn`t its taken care of anyway */\r
+//   if (DOSMesa->gl_vis->DBflag)\r
+#endif\r
+       {\r
+      vga_flip();\r
+   }\r
+}\r
+\r
+\r
+#else\r
+\r
+/*\r
+ * Need this to provide at least one external definition when DOS is\r
+ * not defined on the compiler command line.\r
+ */\r
+\r
+int gl_DOS_dummy_function(void)\r
+{\r
+   return 0;\r
+}\r
+\r
+#endif  /*DOS*/\r
+\r
diff --git a/src/mesa/drivers/ggi/ggimesa.conf.in b/src/mesa/drivers/ggi/ggimesa.conf.in
new file mode 100644 (file)
index 0000000..7213233
--- /dev/null
@@ -0,0 +1,13 @@
+# GGIMesa global configuration
+.root: @ggi_libdir@/ggi/mesa
+
+generic-stubs-mesa             default/stubs.so
+generic-linear-8-mesa          default/linear_8.so
+generic-linear-15-mesa         default/linear_15.so
+generic-linear-16-mesa         default/linear_16.so
+generic-linear-24-mesa         default/linear_24.so
+generic-linear-32-mesa         default/linear_32.so
+
+display-fbdev-mesa             display/fbdev.so
+
+# .include @ggi_confdir@/ggi/mesa/targets/fbdev.conf
diff --git a/src/mesa/drivers/glide/fxapi.c b/src/mesa/drivers/glide/fxapi.c
new file mode 100644 (file)
index 0000000..fbc586e
--- /dev/null
@@ -0,0 +1,1411 @@
+/* -*- mode: C; tab-width:8;  -*-
+
+             fxapi.c - 3Dfx VooDoo/Mesa interface
+*/
+
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ********************************************************************
+ *
+ * Function names:
+ *  fxMesa....     (The driver API)
+ *  fxDD....       (Mesa device driver functions)
+ *  fxTM....       (Texture manager functions)
+ *  fxSetup....    (Voodoo units setup functions)
+ *  fx....         (Internal driver functions)
+ *
+ * Data type names:
+ *  fxMesa....     (Public driver data types)
+ *  tfx....        (Private driver data types)
+ *
+ ********************************************************************
+ *
+ * V0.30 - David Bucciarelli (davibu@tin.it) Humanware s.r.l.
+ *         - introduced a new MESA_GLX_FX related behavior
+ *         - the Glide fog table was built in a wrong way (using
+ *           gu* Glide function). Added the code for building the
+ *           table following the OpenGL specs. Thanks to Steve Baker
+ *           for highlighting the problem.
+ *         - fixed few problems in my and Keith's fxDDClear code
+ *         - merged my code with the Keith's one
+ *         - used the new BlendFunc Mesa device driver function 
+ *         - used the new AlphaFunc Mesa device driver function 
+ *         - used the new Enable Mesa device driver function 
+ *         - fixed a bug related to fog in the Mesa core. Fog
+ *           were applied two times: at vertex level and at fragment
+ *           level (thanks to Steve Baker for reporting the problem)
+ *         - glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE) now works
+ *           (thanks to Jiri Pop for reporting the problem)
+ *         - the driver works fine with OpenGL Unreal
+ *         - fixed a bug in the Mesa core clipping code (related
+ *           to the q texture coordinate)
+ *         - introduced the support for the q texture coordinate
+ *
+ *         Keith Whitwell (keithw@cableinet.co.uk)
+ *         - optimized the driver and written all the new code
+ *           required by the new Mesa-3.1 device driver API
+ *           and by the new Mesa-3.1 core changes
+ *         - written the cva support and many other stuff
+ *
+ *         Brian Paul (brian_paul@avid.com) Avid Technology
+ *         - fixed display list share bug for MESA_GLX_FX = window/fullscreen
+ *         - fixed glClear/gl...Mask related problem
+ *
+ *         Bert Schoenwaelder (bert@prinz-atm.CS.Uni-Magdeburg.De)
+ *         - the driver is now able to sleep when waiting for the completation
+ *           of multiple swapbuffer operations instead of wasting
+ *           CPU time (NOTE: you must uncomment the lines in the
+ *           fxMesaSwapBuffers function in order to enable this option)
+ *
+ *         Eero Pajarre (epajarre@koti.tpo.fi)
+ *         - enabled the macro FLOAT_COLOR_TO_UBYTE_COLOR under
+ *           windows
+ *         - written an asm x86 optimized float->integer conversions
+ *           for windows
+ *
+ *         Theodore Jump (tjump@cais.com)
+ *         - fixed a small problem in the __wglMonitor function of the
+ *           wgl emulator
+ *         - written the in-window-rendering hack support for windows
+ *           and Vooodoo1/2 cards
+ *
+ * V0.29 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
+ *         - included in Mesa-3.0
+ *         - now glGetString(GL_RENDERER) returns more information
+ *           about the hardware configuration: "Mesa Glide <version>
+ *           <Voodoo_Graphics|Voodoo_Rush|UNKNOWN> <num> CARD/<num> FB/
+ *           <num> TM/<num> TMU/<NOSLI|SLI>"
+ *           where: <num> CARD is the card used for the current context,
+ *           <num> FB is the number of MB for the framebuffer,
+ *           <num> TM is the number of MB for the texture memory,
+ *           <num> TMU is the number of TMU. You can try to run
+ *           Mesa/demos/glinfo in order to have an example of the
+ *           output
+ *         - fixed a problem of the WGL emulator with the
+ *           OpenGL Optimizer 1.1 (thanks to Erwin Coumans for
+ *           the bug report)
+ *         - fixed some bug in the fxwgl.c code (thanks to  
+ *           Peter Pettersson for a patch and a bug report)
+ *
+ *         Theodore Jump (tjump@cais.com)
+ *         - written the SST_DUALHEAD support in the WGL emulator
+ *
+ *         Daryll Strauss (daryll@harlot.rb.ca.us)
+ *         - fixed the Voodoo Rush support for the in window rendering
+ *
+ * V0.28 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
+ *         - the only supported multitexture functions are GL_MODULATE
+ *           for texture set 0 and GL_MODULATE for texture set 1. In
+ *           all other cases, the driver falls back to pure software
+ *           rendering
+ *         - written the support for the new  GL_EXT_multitexture
+ *         - written the DD_MAX_TEXTURE_COORD_SETS support in the
+ *           fxDDGetParameteri() function
+ *         - the driver falls back to pure software rendering when
+ *           texture mapping function is GL_BLEND
+ *
+ * V0.27 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
+ *         - inluded in the Mesa-3.0beta5
+ *         - written a smal extension (GL_FXMESA_global_texture_lod_bias) in
+ *           order to expose the LOD bias related Glide function
+ *         - fixed a bug fxDDWriteMonoRGBAPixels()
+ *         - the driver is now able to fallback to software rendering in
+ *           any case not directly supported by the hardware
+ *         - written the support for enabling/disabling dithering
+ *         - the in-window-rendering hack now works with any X11 screen
+ *           depth
+ *         - fixed a problem related to color/depth/alpha buffer clears
+ *         - fixed a problem when clearing buffer for a context with the
+ *           alpha buffer
+ *         - fixed a problem in the fxTMReloadSubMipMapLevel() function,
+ *           I have forget a "break;" (thanks to Joe Waters for the bug report)
+ *         - fixed a problem in the color format for the in window
+ *           rendering hack
+ *         - written the fxDDReadRGBAPixels function
+ *         - written the fxDDDepthTestPixelsGeneric function
+ *         - written the fxDDDepthTestSpanGeneric function
+ *         - written the fxDDWriteMonoRGBAPixels function
+ *         - written the fxDDWriteRGBAPixels function
+ *         - removed the multitexture emulation code for Voodoo board
+ *         with only one TMU
+ *
+ *         Chris Prince <cprince@cs.washington.edu>
+ *         - fixed a new bug in the wglUseFontBitmaps code
+ *
+ *         Ralf Knoesel (rknoesel@Stormfront.com)
+ *         - fixed a bug in the wglUseFontBitmaps code
+ *
+ *         Rune Hasvold (runeh@ifi.uio.no)
+ *         - fixed a problem related to the aux usage in the fxBestResolution
+ *           function
+ *         - fixed the order of pixel formats in the WGL emulator
+ *
+ *         Fredrik Hubinette (hubbe@hubbe.net)
+ *         - the driver shutdown the Glide for most common signals
+ *
+ * V0.26 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
+ *         - included in the Mesa-3.0beta4
+ *         - fixed a problem related to a my optimization for the Rune's
+ *           pixel-span optimization
+ *         - fixed a problem related to fxDDSetNearFar() and ctx->ProjectionMatrixType
+ *           (thanks to Ben "Ctrl-Alt-Delete" and the Raul Alonso's ssystem)
+ *         - fixed a small bug in the Rune's pixel-span optimization
+ *         - fixed a problem with GL_CCW (thanks to Curt Olson for and example
+ *           of the problem)
+ *         - grVertex setup code is now ready for the internal thread support
+ *         - fixed a no used optimization with clipped vertices in
+ *           grVertex setup code
+ *         - fixed a problem in the GL_LIGHT_MODEL_TWO_SIDE support (thanks
+ *           to Patrick H. Madden for a complete example of the bug)
+ *
+ *         Rune Hasvold (runeh@ifi.uio.no)
+ *         - highly optimized the driver functions for writing pixel
+ *           span (2-3 times faster !)
+ *
+ *         Axel W. Volley (volley@acm.org) Krauss-Maffei Wehrtechnik
+ *         - written the fxDDReadDepthSpanFloat() and fxDDReadDepthSpanInt()
+ *           functions
+ *
+ * V0.25 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
+ *         - fixed a problem with Voodoo boards with only one TMU
+ *         - fixed a bug in the fxMesaCreateContext()
+ *         - now the GL_FRONT_AND_BACK works fine also with
+ *           the alpha buffer and/or antialiasing
+ *         - written the support for GL_FRONT_AND_BACK drawing but
+ *           it doesn't works with the alpha buffer and/or antialiasing
+ *         - fixed some bug in the Mesa core for glCopyTexSubImage
+ *           and glCopyTexImage functions (thanks to Mike Connell
+ *           for an example of the problem)
+ *         - make some small optimizations in the Mesa core in order
+ *           to save same driver call and state change for not very
+ *           well written applications
+ *         - introduced the NEW_DRVSTATE and make other optimizations
+ *           for minimizing state changes
+ *         - made a lot of optimizations in order to minimize state
+ *           changes
+ *         - it isn't more possible to create a context with the
+ *           depth buffer and the stancil buffer (it isn't yet supported)
+ *         - now the partial support for the Multitexture extension
+ *           works with Quake2 for windows
+ *         - vertex snap is not longer used for the Voodoo2 (FX_V2
+ *           must be defined)
+ *         - done a lot of cleanup in the fxsetup.c file
+ *         - now the partial support for the Multitexture extension
+ *           works with GLQuake for windows
+ *
+ *         Dieter Nuetzel (nuetzel@kogs.informatik.uni-hamburg.de) University of Hamburg
+ *         - fixed a problem in the asm code for Linux of the fxvsetup.c file
+ *           highlighted by the binutils-2.8.1.0.29. 'fildw' asm instruction
+ *           changed in 'fild'
+ *
+ *         Kevin Hester (kevinh@glassworks.net)
+ *         - written the wglUseFontBitmaps() function in the WGL emulator
+ *
+ * V0.24 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
+ *         - now the drive always uses per fragment fog
+ *         - written a small optimization in the points drawing function
+ *         - written the support for trilinear filtering with 2 TMUs
+ *         - written the first partial support for the Multitexture extension.
+ *           This task is quite hard because the color combine units work after
+ *           the two texture combine units and not before as required by the 
+ *           Multitexture extension
+ *         - written a workaround in fxBestResolution() in order to solve a
+ *           problem with bzflag (it asks for 1x1 window !)
+ *         - changed the fxBestResolution() behavior. It now returns the larger
+ *           screen resolution supported by the hardware (instead of 640x480)
+ *           when it is unable to find an appropriate resolution that is large
+ *           enough for the requested size 
+ *         - the driver is now able to use also the texture memory attached to
+ *           second TMU
+ *         - the texture memory manager is now able to work with two TMUs and
+ *           store texture maps in the memory attached to TMU0, TMU1 or to split
+ *           the mimpmap levels across TMUs in order to support trilinear filtering
+ *         - I have bought a Voodoo2 board !
+ *         - the amount of frambuffer ram is now doubled when an SLI configuration
+ *           is detected
+ *         - solved a problem related to the fxDDTexParam() and fxTexInvalidate()
+ *           functions (thanks to Rune Hasvold for highlighting the problem)
+ *         - done some cleanup in the fxvsetup.c file, written
+ *           the FXVSETUP_FUNC macro
+ *         - done a lot of cleanup in data types and field names
+ *
+ *         Rune Hasvold (runeh@ifi.uio.no)
+ *         - written the support for a right management of the auxiliary buffer.
+ *           You can now use an 800x600 screen without the depth and alpha
+ *           buffer
+ *         - written the support for a new pixel format (without the depth
+ *           and alpha buffer) in the WGL emulator
+ *         - fixed a bug in the window version of the GLUT (it was ever asking
+ *           for depth buffer)
+ *
+ * V0.23 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
+ *         - included in the Mesa-3.0beta2 release
+ *         - written the support for the OpenGL 1.2 GL_TEXTURE_BASE_LEVEL
+ *           and GL_TEXTURE_MAX_LEVEL
+ *         - rewritten several functions for a more clean support of texture
+ *           mapping and in order to solve some bug
+ *         - the accumulation buffer works (it is  bit slow beacuase it requires
+ *           to read/write from/to the Voodoo frame buffer but it works)
+ *         - fixed a bug in the fxDDReadRGBASpan driver function (the R and
+ *           B channels were read in the wrong order). Thanks to Jason Heym
+ *           for highlighting the problem
+ *         - written the support for multiple contexts on multiple boards.
+ *           you can now use the Mesa/Voodoo with multiple Voodoo Graphics
+ *           boards (for example with multiple screens or an HMD)
+ *         - the fxBestResolution() now check all available resolutions
+ *           and it is able to check the amount of framebuffer memory
+ *           before return a resolution
+ *         - modified the GLX/X11 driver in order to support all the
+ *           resolution available
+ *         - changed all function names. They should be now a bit more
+ *           readable
+ *         - written the Glide grVertex setup code for two TMU or
+ *           for Multitexture support with emulationa dn one TMU
+ *         - written the support for the new Mesa driver
+ *           function GetParametri
+ *         - small optimization/clean up in the texbind() function
+ *         - fixed a FPU precision problem for glOrtho and texture
+ *           mapping (thanks to Antti Juhani Huovilainen for an example
+ *           of the problem)
+ *         - written some small SGI OpenGL emulation code for the wgl,
+ *           the OpenGL Optimizer and Cosmo3D work fine under windows !
+ *         - moved the point/line/triangle/quad support in the fxmesa7.c
+ *         - fixed a bug in the clear_color_depth() (thanks to Henk Kok
+ *           for an example of the problem)
+ *         - written a small workaround for Linux GLQuake, it asks
+ *           for the alpha buffer and the depth buffer at the some time
+ *           (but it never uses the alpha buffer)
+ *         - checked the antialiasing points, lines and polygons support.
+ *           It works fine
+ *         - written the support for standard OpenGL antialiasing using
+ *           blending. Lines support works fine (tested with BZflag)
+ *           while I have still to check the polygons and points support
+ *         - written the support for the alpha buffer. The driver is now
+ *           able to use the Voodoo auxiliary buffer as an alpha buffer
+ *           instead of a depth buffer. Also all the OpenGL blending
+ *           modes are now supported. But you can't request a context
+ *           with an alpha buffer AND a depth buffer at the some time
+ *           (this is an hardware limitation)
+ *         - written the support for switching between the fullscreen
+ *           rendering and the in-window-rendering hack on the fly
+ *
+ *         Rune Hasvold (runeh@ifi.uio.no)
+ *         - fixed a bug in the texparam() function
+ *
+ *         Brian Paul (brianp@elastic.avid.com) Avid Technology
+ *         - sources accomodated for the new Mesa 3.0beta1
+ *
+ * V0.22 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
+ *         - included with some v0.23 bug fix in the final release
+ *           of the Mesa-2.6
+ *         - written the support for the MESA_WGL_FX env. var. but
+ *           not tested because I have only Voodoo Graphics boards
+ *         - fixed a bug in the backface culling code
+ *           (thanks to David Farrell for an example of the problem)
+ *         - fixed the "Quake2 elevator" bug
+ *         - GL_POLYGONS with 3/4 vertices are now drawn as
+ *           GL_TRIANLGES/GL_QUADS (a small optimization for GLQuake)
+ *         - fixed a bug in fxmesa6.h for GL_LINE_LOOP
+ *         - fixed a NearFarStack bug in the Mesa when applications
+ *           directly call glLoadMatrix to load a projection matrix 
+ *         - done some cleanup in the fxmesa2.c file
+ *         - the driver no longer translates the texture maps
+ *           when the Mesa internal format and the Voodoo
+ *           format are the some (usefull for 1 byte texture maps
+ *           where the driver can directly use the Mesa texture
+ *           map). Also the amount of used memory is halfed
+ *         - fixed a bug for GL_DECAL and GL_RGBA
+ *         - fixed a bug in the clear_color_depth()
+ *         - tested the v0.22 with the Mesa-2.6beta2. Impressive
+ *           performances improvement thanks to the new Josh's
+ *           asm code (+10fps in the isosurf demo, +5fps in GLQuake
+ *           TIMEREFRESH)
+ *         - written a optimized version of the RenderVB Mesa driver
+ *           function. The Voodoo driver is now able to upload polygons
+ *           in the most common cases at a very good speed. Good
+ *           performance improvement for large set of small polygons
+ *         - optimized the asm code for setting up the color information
+ *           in the Glide grVertex structure
+ *         - fixed a bug in the fxmesa2.c asm code (the ClipMask[]
+ *           wasn't working)
+ *
+ *         Josh Vanderhoof (joshv@planet.net)
+ *         - removed the flush() function because it isn't required
+ *         - limited the maximum number of swapbuffers in the Voodoo
+ *           commands FIFO (controlled by the env. var. MESA_FX_SWAP_PENDING)
+ *
+ *         Holger Kleemiss (holger.kleemiss@metronet.de) STN Atlas Elektronik GmbH
+ *         - applied some patch for the Voodoo Rush
+ *
+ * V0.21 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
+ *         - the driver is now able to take advantage of the ClipMask[],
+ *           ClipOrMask and ClipAndMask information also under Windows
+ *         - introduced a new function in the Mesa driver interface
+ *           ClearColorAndDepth(). Now the glClear() function is
+ *           2 times faster (!) when you have to clear the color buffer
+ *           and the depth buffer at some time
+ *         - written the first version of the fxRenderVB() driver
+ *           function
+ *         - optimized the glTexImage() path
+ *         - removed the fxMesaTextureUsePalette() support
+ *         - fixed a bug in the points support (thanks to David Farrell
+ *           for an example of the problem)
+ *         - written the optimized path for glSubTexImage(),
+ *           introduced a new function in the Mesa driver interface
+ *           TexSubImage(...)
+ *         - fixed a bug for glColorMask and glDepthMask
+ *         - the wbuffer is not more used. The Voodoo driver uses
+ *           a standard 16bit zbuffer in all cases. It is more consistent
+ *           and now GLQuake and GLQuake2test work also with a GL_ZTRICK 0
+ *         - the driver is now able to take advantage of the ClipMask[],
+ *           ClipOrMask and ClipAndMask information (under Linux);
+ *         - rewritten the setup_fx_units() function, now the texture
+ *           mapping support is compliant to the OpenGL specs (GL_BLEND
+ *           support is still missing). The LinuxGLQuake console correctly
+ *           fade in/out and transparent water of GLQuake2test works fine
+ *         - written the support for the env. var. FX_GLIDE_SWAPINTERVAL
+ *         - found a bug in the Mesa core. There is a roundup problem for
+ *           color values out of the [0.0,1.0] range
+ *
+ *         Wonko <matt@khm.de>
+ *         - fixed a Voodoo Rush related problem in the fxwgl.c
+ *
+ *         Daryll Strauss <daryll@harlot.rb.ca.us>
+ *         - written the scissor test support
+ *
+ * V0.20 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
+ *         - written the closetmmanger() function in order to free all the memory
+ *           allocated by the Texture Memory Manager (it will be useful
+ *           when the support for multiple contexts/boards will be ready)
+ *         - now the Voodoo driver runs without printing any information,
+ *           define the env. var. MESA_FX_INFO if you want to read some
+ *           information about the hardware and some statistic
+ *         - written a small workaround for the "GLQuake multiplayer white box bug"
+ *           in the setup_fx_units() funxtions. I'm already rewriting
+ *           this function because it is the source of nearly all the current
+ *           Voodoo driver problems
+ *         - fixed the GLQuake texture misalignment problem (the texture
+ *           coordinates must be scaled between 0.0 and 256.0 and not
+ *           between 0.0 and 255.0)
+ *         - written the support for the GL_EXT_shared_texture_palette
+ *         - some small change for supporting the automatic building of the
+ *           OpenGL32.dll under the Windows platform
+ *         - the redefinition of a mipmap level is now a LOT faster. This path
+ *           is used by GLQuake for dynamic lighting with some call to glTexSubImage2D()
+ *         - the texture memory is now managed a set of 2MB blocks so
+ *           texture maps can't be allocated on a 2MB boundary. The new Pure3D
+ *           needs this kind of support (and probably any other Voodoo Graphics
+ *           board with more than 2MB of texture memory)
+ *
+ *         Brian Paul (brianp@elastic.avid.com) Avid Technology
+ *         - added write_monocolor_span(), fixed bug in write_color_span()
+ *         - added test for stenciling in choosepoint/line/triangle functions
+ *
+ *         Joe Waters (falc@attila.aegistech.com) Aegis
+ *         - written the support for the env. var. SST_SCREENREFRESH
+ *
+ * V0.19 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
+ *         - written the 3Dfx Global Palette extension for GLQuake
+ *         - written the support for the GL_EXT_paletted_texture (it works only with GL_RGBA
+ *           palettes and the alpha value is ignored ... this is a limitation of the
+ *           the current Glide version and Voodoo hardware)
+ *         - fixed the amount of memory allocated for 8bit textures
+ *         - merged the under construction v0.19 driver with the Mesa 2.5
+ *         - finally written the support for deleting textures
+ *         - introduced a new powerful texture memory manager: the texture memory
+ *           is used as a cache of the set of all defined texture maps. You can
+ *           now define several MB of texture maps also with a 2MB of texture memory
+ *           (the texture memory manager will do automatically all the swap out/swap in
+ *           work). The new texture memory manager has also
+ *           solved a lot of other bugs/no specs compliance/problems
+ *           related to the texture memory usage. The texture
+ *           manager code is inside the new fxmesa3.c file
+ *         - broken the fxmesa.c file in two files (fxmesa1.c and fxmesa2.c)
+ *           and done some code cleanup
+ *         - now is possible to redefine texture mipmap levels already defined
+ *         - fixed a problem with the amount of texture memory allocated for textures
+ *           with not all mipmap levels defined
+ *         - fixed a small problem with single buffer rendering
+ *
+ *         Brian Paul (brianp@elastic.avid.com) Avid Technology
+ *         - read/write_color_span() now use front/back buffer correctly
+ *         - create GLvisual with 5,6,5 bits per pixel, not 8,8,8
+ *         - removed a few ^M characters from fxmesa2.c file
+ *
+ * V0.18 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
+ *         - the Mesa-2.4beta3 is finally using the driver quads support (the
+ *           previous Mesa versions have never taken any advantage from the quads support !)
+ *         - tested with the Glide 2.4 for Win
+ *         - ported all asm code to Linux
+ *         - ported the v0.18 to Linux (without asm code)
+ *         - back to Linux !!!
+ *         - optimized the SETUP macro (no more vertex snap for points and lines)
+ *         - optimized the SETUP macro (added one argument)
+ *         - the Mesa/Voodoo is now 20/30% for points, lines and small triangles !
+ *         - performance improvement setting VBSIZE to 72 
+ *         - the GrVertex texture code is now written in asm
+ *         - the GrVertex zbuffer code is now written in asm
+ *         - the GrVertex wbuffer code is now written in asm
+ *         - the GrVertex gouraud code is now written in asm
+ *         - the GrVertex snap code is now written in asm
+ *         - changed the 8bit compressed texture maps in 8bit palette texture maps
+ *           support (it has the some advantage of compressed texture maps without the
+ *           problem of a fixed NCC table for all mipmap levels)
+ *         - written the support for 8bit compressed texture maps (but texture maps with
+ *           more than one mipmap level aren't working fine)
+ *         - finnaly everthing is working fine in MesaQuake !
+ *         - fixed a bug in the computation of texture mapping coordinates (I have found
+ *           the bug thanks to MesaQuake !)
+ *         - written the GL_REPLACE support (mainly for MesaQuake)
+ *         - written the support for textures with not all mipmap levels defined
+ *         - rewritten all the Texture memory stuff
+ *         - written the MesaQuake support (define MESAQUAKE)
+ *         - working with a ZBuffer if glOrtho or not int the default glDepthRange,
+ *           otherwise working with the WBuffer
+ *         written the glDepthRange support
+ *
+ *         Diego Picciani (d.picciani@novacomp.it) Nova Computer s.r.l.
+ *         - written the fxCloseHardware() and the fxQuaryHardware() (mainly
+ *           for the VoodooWGL emulator)
+ *
+ *         Brian Paul (brianp@elastic.avid.com) Avid Technology
+ *         - implemented read/write_color_span() so glRead/DrawPixels() works
+ *         - now needs Glide 2.3 or later.  Removed GLIDE_FULL_SCREEN and call to grSstOpen()
+ *
+ * V0.17 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
+ *         - optimized the bitmap support (66% faster)
+ *         - tested with the Mesa 2.3beta2
+ *
+ *         Diego Picciani (d.picciani@novacomp.it) Nova Computer s.r.l.
+ *         - solved a problem with the drawbitmap() and the Voodoo Rush
+ *           (GR_ORIGIN_LOWER_LEFT did not work with the Stingray)
+ *
+ *         Brian Paul (brianp@elastic.avid.com) Avid Technology
+ *         - linux stuff
+ *         - general code clean-up
+ *         - added attribList parameter to fxMesaCreateContext()
+ *         - single buffering works now
+ *         - VB colors are now GLubytes, removed ColorShift stuff
+ *
+ *         Paul Metzger
+ *         - linux stuff
+ *
+ * V0.16 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
+ *         - written the quadfunc support (no performance improvement)
+ *         - written the support for the new Mesa 2.3beta1 driver interface (Wow ! It is faaaster)
+ *         - rewritten the glBitmap support for the Glide 2.3 (~35% slower !)
+ *         - written the glBitmap support for the most common case (fonts)
+ *
+ *         Jack Palevich
+ *         - Glide 2.3 porting
+ *
+ *         Diego Picciani (d.picciani@novacomp.it) Nova Computer s.r.l.
+ *         - extended the fxMesaCreateContext() and fxMesaCreateBestContext()
+ *           functions in order to support also the Voodoo Rush
+ *         - tested with the Hercules Stingray 128/3D (The rendering in a window works !)
+ *
+ * V0.15 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
+ *         - written the GL_LUMINANCE_ALPHA support
+ *         - written the GL_ALPHA support
+ *         - written the GL_LUMINANCE support
+ *         - now SETUP correctly set color for mono color sequences
+ *         - written the 9x1,10x1,...,1x9,1x10,... texture map ratio support
+ *         - written the no square texture map support
+ *         - the fog table is no more rebuilt inside setup_fx_units() each time
+ *
+ *         Henri Fousse (arnaud@pobox.oleane.com) Thomson Training & Simulation
+ *         - written (not yet finished: no texture mapping) support for glOrtho
+ *         - some change to setup functions
+ *         - the fog support is now fully compatible with the standard OpenGL
+ *         - rewritten several parts of the driver in order to take
+ *           advantage of meshes (40% faster !!!)
+ *
+ * V0.14 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
+ *         - now glAlphaFunc() works
+ *         - now glDepthMask() works
+ *         - solved a mipmap problem when using more than one texture
+ *         - moved ti, texid and wscale inside the fxMesaContext (now we can
+ *           easy support more ctx and more boards)
+ *         - the management of the fxMesaContext was completly broken !
+ *         - solved several problems about Alpha and texture Alpha
+ *         - 4 (RGBA) texture channels supported
+ *         - setting the default color to white
+ *
+ *         Henri Fousse (arnaud@pobox.oleane.com) Thomson Training & Simulation
+ *         - small change to fxMesaCreateContext() and fxMesaMakeCurrent()
+ *         - written the fog support
+ *         - setting the default clear color to black
+ *         - written cleangraphics() for the onexit() function
+ *         - written fxMesaCreateBestContext()
+ *
+ * V0.13 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
+ *         - now glBlendFunc() works for all glBlendFunc without DST_ALPHA
+ *           (because the alpha buffer is not yet implemented) 
+ *         - now fxMesaCreateContext() accept resolution and refresh rate
+ *         - fixed a bug for texture mapping: the w (alias z) must be set
+ *           also without depth buffer
+ *         - fixed a bug for texture image with width!=256
+ *         - written texparam()
+ *         - written all point, line and triangle functions for all possible supported
+ *           contexts and the driver is slight faster with points, lines and small triangles
+ *         - fixed a small bug in fx/fxmesa.h (glOrtho)
+ *
+ * V0.12 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
+ *         - glDepthFunc supported
+ *         - introduced a trick to discover the far plane distance
+ *           (see fxMesaSetFar and fx/fxmesa.h)
+ *         - now the wbuffer works with homogeneous coordinate (and it
+ *           doesn't work with a glOrtho projection :)
+ *         - solved several problems with homogeneous coordinate and texture mapping
+ *         - fixed a bug in all line functions
+ *         - fixed a clear framebuffer bug
+ *         - solved a display list/teximg problem (but use
+ *           glBindTexture: it is several times faster)
+ *
+ * V0.11 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
+ *         - introduced texture mapping support (not yet finished !)
+ *         - tested with Mesa2.2b6
+ *         - the driver is faster 
+ *         - written glFlush/glFinish
+ *         - the driver print a lot of info about the Glide lib
+ *
+ * v0.1  - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
+ *         - Initial revision
+ *
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "conf.h"
+#endif
+
+#if defined(FX)
+#include "fxdrv.h"
+
+fxMesaContext fxMesaCurrentCtx=NULL;
+
+/*
+ * Status of 3Dfx hardware initialization
+ */
+
+static int glbGlideInitialized=0;
+static int glb3DfxPresent=0;
+static int glbTotNumCtx=0;
+
+GrHwConfiguration glbHWConfig;
+int glbCurrentBoard=0;
+
+
+#if defined(__WIN32__)
+static int cleangraphics(void)
+{
+  glbTotNumCtx=1;
+  fxMesaDestroyContext(fxMesaCurrentCtx);
+
+  return 0;
+}
+#elif defined(__linux__)
+static void cleangraphics(void)
+{
+  glbTotNumCtx=1;
+  fxMesaDestroyContext(fxMesaCurrentCtx);
+}
+
+static void cleangraphics_handler(int s)
+{
+  fprintf(stderr,"fxmesa: Received a not handled signal %d\n",s);
+
+  cleangraphics();
+/*    abort(); */
+  exit(1);
+}
+#endif
+
+
+/*
+ * Select the Voodoo board to use when creating
+ * a new context.
+ */
+GLboolean GLAPIENTRY fxMesaSelectCurrentBoard(int n)
+{
+  fxQueryHardware();
+
+  if((n<0) || (n>=glbHWConfig.num_sst))
+    return GL_FALSE;
+
+  glbCurrentBoard=n;
+
+  return GL_TRUE;
+}
+
+
+fxMesaContext GLAPIENTRY fxMesaGetCurrentContext(void)
+{
+  return fxMesaCurrentCtx;
+}
+
+
+void GLAPIENTRY fxMesaSetNearFar(GLfloat n, GLfloat f)
+{
+  if(fxMesaCurrentCtx)
+    fxDDSetNearFar(fxMesaCurrentCtx->glCtx,n,f);
+}
+
+
+/*
+ * The extension GL_FXMESA_global_texture_lod_bias
+ */
+void GLAPIENTRY glGlobalTextureLODBiasFXMESA(GLfloat biasVal)
+{
+  grTexLodBiasValue(GR_TMU0,biasVal);
+
+  if(fxMesaCurrentCtx->haveTwoTMUs)
+    grTexLodBiasValue(GR_TMU1,biasVal);
+}
+
+
+/*
+ * The 3Dfx Global Palette extension for GLQuake.
+ * More a trick than a real extesion, use the shared global
+ * palette extension. 
+ */
+void GLAPIENTRY gl3DfxSetPaletteEXT(GLuint *pal)
+{
+  fxMesaContext fxMesa =fxMesaCurrentCtx;
+  
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+    int i;
+
+    fprintf(stderr,"fxmesa: gl3DfxSetPaletteEXT()\n");
+
+    for(i=0;i<256;i++)
+      fprintf(stderr,"%x\n",pal[i]);
+  }
+  
+  if(fxMesa) {
+    fxMesa->haveGlobalPaletteTexture=1;
+    
+    FX_grTexDownloadTable(GR_TMU0,GR_TEXTABLE_PALETTE,(GuTexPalette *)pal);
+    if (fxMesa->haveTwoTMUs)
+        FX_grTexDownloadTable(GR_TMU1,GR_TEXTABLE_PALETTE,(GuTexPalette *)pal);
+  }
+}
+
+
+static GrScreenResolution_t fxBestResolution(int width, int height, int aux)
+{
+  static int resolutions[][5]={ 
+    { 512, 384, GR_RESOLUTION_512x384, 2, 2 },
+    { 640, 400, GR_RESOLUTION_640x400, 2, 2 },
+    { 640, 480, GR_RESOLUTION_640x480, 2, 2 },
+    { 800, 600, GR_RESOLUTION_800x600, 4, 2 },
+    { 960, 720, GR_RESOLUTION_960x720, 6, 4 }
+#ifdef GR_RESOLUTION_1024x768
+    ,{ 1024, 768, GR_RESOLUTION_1024x768, 8, 4 }
+#endif
+#ifdef GR_RESOLUTION_1280x1024
+    ,{ 1024, 768, GR_RESOLUTION_1280x1024, 8, 8 }
+#endif
+#ifdef GR_RESOLUTION_1600x1200
+    ,{ 1024, 768, GR_RESOLUTION_1600x1200, 16, 8 }
+#endif
+  };
+  int NUM_RESOLUTIONS = sizeof(resolutions) / (sizeof(int)*5);
+  int i,fbmem;
+  GrScreenResolution_t lastvalidres=resolutions[1][2];
+
+  fxQueryHardware();
+
+  if(glbHWConfig.SSTs[glbCurrentBoard].type==GR_SSTTYPE_VOODOO) {
+    fbmem=glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig.fbRam;
+
+    if(glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig.sliDetect)
+      fbmem*=2;
+  } else if(glbHWConfig.SSTs[glbCurrentBoard].type==GR_SSTTYPE_SST96)
+    fbmem=glbHWConfig.SSTs[glbCurrentBoard].sstBoard.SST96Config.fbRam;
+  else
+    fbmem=2;
+
+  /* A work around for BZFlag */
+
+  if((width==1) && (height==1)) {
+    width=640;
+    height=480;
+  }
+
+  for(i=0;i<NUM_RESOLUTIONS;i++)
+    if(resolutions[i][4-aux]<=fbmem) {
+      if((width<=resolutions[i][0]) && (height<=resolutions[i][1]))
+        return resolutions[i][2];
+
+      lastvalidres=resolutions[i][2];
+    }
+
+  return lastvalidres;
+}
+
+
+fxMesaContext GLAPIENTRY fxMesaCreateBestContext(GLuint win,GLint width, GLint height,
+                                              const GLint attribList[])
+{
+  GrScreenRefresh_t refresh;
+  int i;
+  int res,aux;
+  refresh=GR_REFRESH_75Hz;
+
+  if(getenv("SST_SCREENREFRESH")) {
+    if(!strcmp(getenv("SST_SCREENREFRESH"),"60"))
+      refresh=GR_REFRESH_60Hz;
+    if(!strcmp(getenv("SST_SCREENREFRESH"),"70"))
+      refresh=GR_REFRESH_70Hz;
+    if(!strcmp(getenv("SST_SCREENREFRESH"),"72"))
+      refresh=GR_REFRESH_72Hz;
+    if(!strcmp(getenv("SST_SCREENREFRESH"),"75"))
+      refresh=GR_REFRESH_75Hz;
+    if(!strcmp(getenv("SST_SCREENREFRESH"),"80"))
+      refresh=GR_REFRESH_80Hz;
+    if(!strcmp(getenv("SST_SCREENREFRESH"),"85"))
+      refresh=GR_REFRESH_85Hz;
+    if(!strcmp(getenv("SST_SCREENREFRESH"),"90"))
+      refresh=GR_REFRESH_90Hz;
+    if(!strcmp(getenv("SST_SCREENREFRESH"),"100"))
+      refresh=GR_REFRESH_100Hz;
+    if(!strcmp(getenv("SST_SCREENREFRESH"),"120"))
+      refresh=GR_REFRESH_120Hz;
+  }
+
+  aux=0;
+  for(i=0;attribList[i]!=FXMESA_NONE;i++)
+    if((attribList[i]==FXMESA_ALPHA_SIZE) ||
+       (attribList[i]==FXMESA_DEPTH_SIZE)) {
+      if(attribList[++i]>0) {
+        aux=1;
+        break;
+      }
+    }
+
+  res=fxBestResolution(width,height,aux);
+
+  return fxMesaCreateContext(win,res,refresh,attribList);
+}
+
+
+#if 0
+void fxsignals()
+{
+   signal(SIGINT,SIG_IGN);
+   signal(SIGHUP,SIG_IGN);
+   signal(SIGPIPE,SIG_IGN);
+   signal(SIGFPE,SIG_IGN);
+   signal(SIGBUS,SIG_IGN);
+   signal(SIGILL,SIG_IGN);
+   signal(SIGSEGV,SIG_IGN);
+   signal(SIGTERM,SIG_IGN);
+}
+#endif
+
+/*
+ * Create a new FX/Mesa context and return a handle to it.
+ */
+fxMesaContext GLAPIENTRY fxMesaCreateContext(GLuint win,GrScreenResolution_t res,
+                                          GrScreenRefresh_t ref,
+                                          const GLint attribList[])
+{
+  fxMesaContext fxMesa;
+  int i,type;
+  int aux;
+  GLboolean doubleBuffer=GL_FALSE;
+  GLboolean alphaBuffer=GL_FALSE;
+  GLboolean verbose=GL_FALSE;
+  GLint depthSize=0;
+  GLint stencilSize=0;
+  GLint accumSize=0;
+  GLcontext *shareCtx = NULL;
+  GLcontext *ctx = 0;
+  FX_GrContext_t glideContext = 0;
+  char *errorstr;
+
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+    fprintf(stderr,"fxmesa: fxMesaCreateContext() Start\n");
+  }
+
+  if(getenv("MESA_FX_INFO"))
+    verbose=GL_TRUE;
+
+  aux=0;
+  i=0;
+  while(attribList[i]!=FXMESA_NONE) {
+    switch (attribList[i]) {
+    case FXMESA_DOUBLEBUFFER:
+      doubleBuffer=GL_TRUE;
+      break;
+    case FXMESA_ALPHA_SIZE:
+      i++;
+      alphaBuffer=attribList[i]>0;
+      if(alphaBuffer)
+        aux=1;
+      break;
+    case FXMESA_DEPTH_SIZE:
+      i++;
+      depthSize=attribList[i];
+      if(depthSize)
+        aux=1;
+      break;
+    case FXMESA_STENCIL_SIZE:
+      i++;
+      stencilSize=attribList[i];
+      break;
+    case FXMESA_ACCUM_SIZE:
+      i++;
+      accumSize=attribList[i];
+      break;
+      /* XXX ugly hack here for sharing display lists */
+#define FXMESA_SHARE_CONTEXT 990099  /* keep in sync with xmesa1.c! */
+    case FXMESA_SHARE_CONTEXT:
+      i++;
+      {
+        const void *vPtr = &attribList[i];
+        GLcontext **ctx = (GLcontext **) vPtr;
+        shareCtx = *ctx;
+      }
+      break;
+    default:
+      if (MESA_VERBOSE&VERBOSE_DRIVER) {
+       fprintf(stderr,"fxmesa: fxMesaCreateContext() End (defualt)\n");
+      }
+      return NULL;
+    }
+    i++;
+  }
+
+  /* A workaround for Linux GLQuake */
+  if(depthSize && alphaBuffer)
+    alphaBuffer=0;
+
+  if(verbose)
+    fprintf(stderr,"Mesa fx Voodoo Device Driver v0.30\nWritten by David Bucciarelli (davibu@tin.it.it)\n");
+
+  if((type=fxQueryHardware()) >= 0) {
+    if(type==GR_SSTTYPE_VOODOO)
+      win=0;
+
+    grSstSelect(glbCurrentBoard);
+
+#if  FXMESA_USE_ARGB
+    glideContext = FX_grSstWinOpen((FxU32)win,res,ref,
+                     GR_COLORFORMAT_ARGB,GR_ORIGIN_LOWER_LEFT,2,aux);
+
+#else
+    glideContext = FX_grSstWinOpen((FxU32)win,res,ref,
+                     GR_COLORFORMAT_ABGR,GR_ORIGIN_LOWER_LEFT,2,aux);
+#endif
+   if (!glideContext){
+      errorstr = "grSstWinOpen"; 
+      goto errorhandler;
+    }
+
+    if(verbose)
+      fprintf(stderr,"Glide screen size: %dx%d\n",
+              (int)FX_grSstScreenWidth(),(int)FX_grSstScreenHeight());
+  } else {
+    fprintf(stderr,"fx Driver: ERROR no Voodoo1/2 Graphics or Voodoo Rush !\n");
+    return NULL;
+  }
+
+  fxMesa=(fxMesaContext)calloc(1,sizeof(struct tfxMesaContext));
+  if(!fxMesa) {
+    errorstr = "malloc";
+    goto errorhandler;
+  }
+  
+  FX_setupGrVertexLayout();
+  
+  fxMesa->glideContext = glideContext;
+  fxMesa->board=glbCurrentBoard;
+  fxMesa->width=FX_grSstScreenWidth();
+  fxMesa->height=FX_grSstScreenHeight();
+
+  fxMesa->verbose=verbose;
+
+  if(glbHWConfig.SSTs[glbCurrentBoard].type==GR_SSTTYPE_VOODOO)
+    fxMesa->haveTwoTMUs=(glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig.nTexelfx > 1);
+  else if(glbHWConfig.SSTs[glbCurrentBoard].type==GR_SSTTYPE_SST96)
+    fxMesa->haveTwoTMUs=(glbHWConfig.SSTs[glbCurrentBoard].sstBoard.SST96Config.nTexelfx > 1);
+  else
+    fxMesa->haveTwoTMUs=GL_FALSE;
+
+  if (getenv("FX_EMULATE_SINGLE_TMU")) {
+     if (MESA_VERBOSE&VERBOSE_DRIVER) 
+       fprintf(stderr, "\n\nEmulating single tmu\n\n");
+     fxMesa->haveTwoTMUs = GL_FALSE;
+  }
+
+  fxMesa->emulateTwoTMUs = fxMesa->haveTwoTMUs;
+  
+  if (!getenv("FX_DONT_FAKE_MULTITEX")) {
+     if (MESA_VERBOSE&VERBOSE_DRIVER) {
+         if (!fxMesa->haveTwoTMUs)
+           fprintf(stderr, "\n\nEmulating multitexture\n\n");
+     }
+     fxMesa->emulateTwoTMUs = GL_TRUE;
+  }
+
+
+  fxMesa->haveDoubleBuffer=doubleBuffer;
+  fxMesa->haveAlphaBuffer=alphaBuffer;
+  fxMesa->haveGlobalPaletteTexture=GL_FALSE;
+
+  if(getenv("FX_GLIDE_SWAPINTERVAL"))
+    fxMesa->swapInterval=atoi(getenv("FX_GLIDE_SWAPINTERVAL"));
+  else
+    fxMesa->swapInterval=1;
+
+  if(getenv("MESA_FX_SWAP_PENDING"))
+    fxMesa->maxPendingSwapBuffers=atoi(getenv("MESA_FX_SWAP_PENDING"));
+  else
+    fxMesa->maxPendingSwapBuffers=2;
+
+  fxMesa->color=0xffffffff;
+  fxMesa->clearC=0;
+  fxMesa->clearA=0;
+
+  fxMesa->stats.swapBuffer=0;
+  fxMesa->stats.reqTexUpload=0;
+  fxMesa->stats.texUpload=0;
+  fxMesa->stats.memTexUpload=0;
+
+  fxMesa->tmuSrc=FX_TMU_NONE;
+  fxMesa->lastUnitsMode=FX_UM_NONE;
+  fxTMInit(fxMesa);
+
+  /* FX units setup */
+
+  fxMesa->unitsState.alphaTestEnabled=GL_FALSE;
+  fxMesa->unitsState.alphaTestFunc=GR_CMP_ALWAYS;
+  fxMesa->unitsState.alphaTestRefValue=0;
+
+  fxMesa->unitsState.blendEnabled=GL_FALSE;
+  fxMesa->unitsState.blendSrcFuncRGB=GR_BLEND_ONE;
+  fxMesa->unitsState.blendDstFuncRGB=GR_BLEND_ZERO;
+  fxMesa->unitsState.blendSrcFuncAlpha=GR_BLEND_ONE;
+  fxMesa->unitsState.blendDstFuncAlpha=GR_BLEND_ZERO;
+
+  fxMesa->unitsState.depthTestEnabled  =GL_FALSE;
+  fxMesa->unitsState.depthMask         =GL_TRUE;
+  fxMesa->unitsState.depthTestFunc     =GR_CMP_LESS;
+
+  grColorMask(FXTRUE,alphaBuffer ? FXTRUE : FXFALSE);
+  if(doubleBuffer) {
+    fxMesa->currentFB=GR_BUFFER_BACKBUFFER;
+    grRenderBuffer(GR_BUFFER_BACKBUFFER);
+  } else {
+    fxMesa->currentFB=GR_BUFFER_FRONTBUFFER;
+    grRenderBuffer(GR_BUFFER_FRONTBUFFER);
+  }
+  
+  fxMesa->state        = NULL;
+  fxMesa->fogTable     = NULL;
+  
+  fxMesa->state        = malloc(FX_grGetInteger(FX_GLIDE_STATE_SIZE));
+  fxMesa->fogTable     = malloc(FX_grGetInteger(FX_FOG_TABLE_ENTRIES)*sizeof(GrFog_t));
+  
+  if (!fxMesa->state || !fxMesa->fogTable) {
+     errorstr = "malloc";
+     goto errorhandler;
+  }
+
+  if(depthSize)
+    grDepthBufferMode(GR_DEPTHBUFFER_ZBUFFER);
+    
+#if (!FXMESA_USE_ARGB)
+  grLfbWriteColorFormat(GR_COLORFORMAT_ABGR); /* Not every Glide supports this  */
+#endif
+
+  fxMesa->glVis=gl_create_visual(GL_TRUE,     /* RGB mode */
+                                 alphaBuffer,
+                                 doubleBuffer,
+                                 GL_FALSE,    /* stereo */
+                                 depthSize,   /* depth_size */
+                                 stencilSize, /* stencil_size */
+                                 accumSize,   /* accum_size */
+                                 0,           /* index bits */
+                                 5,6,5,0);    /* RGBA bits */
+  if (!fxMesa->glVis) {
+     errorstr = "gl_create_visual";
+     goto errorhandler;
+  }
+
+  ctx = fxMesa->glCtx=gl_create_context(fxMesa->glVis,
+                                       shareCtx,  /* share list context */
+                                       (void *) fxMesa, GL_TRUE);
+  if (!ctx) {
+     errorstr = "gl_create_context";
+     goto errorhandler;
+  }
+
+  fxMesa->glBuffer=gl_create_framebuffer(fxMesa->glVis);
+  if (!fxMesa->glBuffer) {
+    errorstr = "gl_create_framebuffer";
+    goto errorhandler;
+  }
+
+  fxMesa->glCtx->Const.MaxTextureLevels=9;
+  fxMesa->glCtx->Const.MaxTextureSize=256;
+  fxMesa->glCtx->Const.MaxTextureUnits=fxMesa->emulateTwoTMUs ? 2 : 1;
+
+  fxMesa->glCtx->NewState|=NEW_DRVSTATE1;
+  fxMesa->new_state = NEW_ALL;
+  
+  fxDDSetupInit();
+  fxDDCvaInit();
+  fxDDClipInit();
+  fxDDTrifuncInit();
+  fxDDFastPathInit();
+
+  fxSetupDDPointers(fxMesa->glCtx);
+  fxDDRenderInit(fxMesa->glCtx);
+  fxDDInitExtensions(fxMesa->glCtx);  
+
+  fxDDSetNearFar(fxMesa->glCtx,1.0,100.0);
+  
+  grGlideGetState((GrState*)fxMesa->state);
+
+  /* XXX Fix me: callback not registered when main VB is created.
+   */
+  if (fxMesa->glCtx->VB) 
+     fxDDRegisterVB( fxMesa->glCtx->VB );
+  
+  /* XXX Fix me too: need to have the 'struct dd' prepared prior to
+   * creating the context... The below is broken if you try to insert
+   * new stages.  
+   */
+  if (ctx->NrPipelineStages)
+     ctx->NrPipelineStages = fxDDRegisterPipelineStages( ctx->PipelineStage,
+                                                        ctx->PipelineStage,
+                                                        ctx->NrPipelineStages);
+
+  
+  glbTotNumCtx++;
+
+  /* Run the config file */
+  gl_context_initialize( fxMesa->glCtx );
+
+  /* install signal handlers */
+#if defined(__linux__)
+  if (fxMesa->glCtx->CatchSignals) {
+     signal(SIGINT,cleangraphics_handler);
+     signal(SIGHUP,cleangraphics_handler);
+     signal(SIGPIPE,cleangraphics_handler);
+     signal(SIGFPE,cleangraphics_handler);
+     signal(SIGBUS,cleangraphics_handler);
+     signal(SIGILL,cleangraphics_handler);
+     signal(SIGSEGV,cleangraphics_handler);
+     signal(SIGTERM,cleangraphics_handler);
+  }
+#endif
+
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+    fprintf(stderr,"fxmesa: fxMesaCreateContext() End\n");
+  }
+
+  return fxMesa;
+
+errorhandler:
+   if (fxMesa) {
+      if (fxMesa->glideContext)
+       FX_grSstWinClose(fxMesa->glideContext);
+      fxMesa->glideContext = 0;
+      
+      if (fxMesa->state)  
+       free(fxMesa->state);
+      if (fxMesa && fxMesa->fogTable)
+       free(fxMesa->fogTable);
+      if (fxMesa->glBuffer)
+       gl_destroy_framebuffer(fxMesa->glBuffer);
+      if (fxMesa->glVis)
+       gl_destroy_visual(fxMesa->glVis);
+      if (fxMesa->glCtx)
+       gl_destroy_context(fxMesa->glCtx);
+      free(fxMesa);
+   }
+
+
+
+     
+
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+      fprintf(stderr,"fxmesa: fxMesaCreateContext() End (%s)\n",errorstr);
+  }
+  return NULL;
+}
+
+
+/*
+ * Function to set the new window size in the context (mainly for the Voodoo Rush)
+ */
+void GLAPIENTRY fxMesaUpdateScreenSize(fxMesaContext fxMesa)
+{
+  fxMesa->width=FX_grSstScreenWidth();
+  fxMesa->height=FX_grSstScreenHeight();
+}
+
+
+/*
+ * Destroy the given FX/Mesa context.
+ */
+void GLAPIENTRY fxMesaDestroyContext(fxMesaContext fxMesa)
+{
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+    fprintf(stderr,"fxmesa: fxMesaDestroyContext()\n");
+  }
+
+  if(fxMesa) {
+    gl_destroy_visual(fxMesa->glVis);
+    gl_destroy_context(fxMesa->glCtx);
+    gl_destroy_framebuffer(fxMesa->glBuffer);
+
+    glbTotNumCtx--;
+
+    fxCloseHardware();
+    FX_grSstWinClose(fxMesa->glideContext);
+
+    if(fxMesa->verbose) {
+      fprintf(stderr,"Misc Stats:\n");
+      fprintf(stderr,"  # swap buffer: %u\n",fxMesa->stats.swapBuffer);
+
+      if(!fxMesa->stats.swapBuffer)
+        fxMesa->stats.swapBuffer=1;
+
+      fprintf(stderr,"Textures Stats:\n");
+      fprintf(stderr,"  Free texture memory on TMU0: %d:\n",fxMesa->freeTexMem[FX_TMU0]);
+      if(fxMesa->haveTwoTMUs)
+        fprintf(stderr,"  Free texture memory on TMU1: %d:\n",fxMesa->freeTexMem[FX_TMU1]);
+      fprintf(stderr,"  # request to TMM to upload a texture objects: %u\n",
+              fxMesa->stats.reqTexUpload);
+      fprintf(stderr,"  # request to TMM to upload a texture objects per swapbuffer: %.2f\n",
+              fxMesa->stats.reqTexUpload/(float)fxMesa->stats.swapBuffer);
+      fprintf(stderr,"  # texture objects uploaded: %u\n",
+              fxMesa->stats.texUpload);
+      fprintf(stderr,"  # texture objects uploaded per swapbuffer: %.2f\n",
+              fxMesa->stats.texUpload/(float)fxMesa->stats.swapBuffer);
+      fprintf(stderr,"  # MBs uploaded to texture memory: %.2f\n",
+              fxMesa->stats.memTexUpload/(float)(1<<20));
+      fprintf(stderr,"  # MBs uploaded to texture memory per swapbuffer: %.2f\n",
+              (fxMesa->stats.memTexUpload/(float)fxMesa->stats.swapBuffer)/(float)(1<<20));
+    }
+    if (fxMesa->state)  
+       free(fxMesa->state);
+    if (fxMesa->fogTable)
+       free(fxMesa->fogTable);
+    fxTMClose(fxMesa);
+    
+    free(fxMesa);
+  }
+
+  if(fxMesa==fxMesaCurrentCtx)
+    fxMesaCurrentCtx=NULL;
+}
+
+
+/*
+ * Make the specified FX/Mesa context the current one.
+ */
+void GLAPIENTRY fxMesaMakeCurrent(fxMesaContext fxMesa)
+{
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+    fprintf(stderr,"fxmesa: fxMesaMakeCurrent(...) Start\n");
+  }
+
+  if(!fxMesa) {
+    gl_make_current(NULL,NULL);
+    fxMesaCurrentCtx=NULL;
+
+    if (MESA_VERBOSE&VERBOSE_DRIVER) {
+      fprintf(stderr,"fxmesa: fxMesaMakeCurrent(NULL) End\n");
+    }
+
+    return;
+  }
+
+  /* if this context is already the current one, we can return early */
+  if (fxMesaCurrentCtx == fxMesa
+      && fxMesaCurrentCtx->glCtx == gl_get_current_context()) {
+     if (MESA_VERBOSE&VERBOSE_DRIVER) {
+        fprintf(stderr,"fxmesa: fxMesaMakeCurrent(fxMesaCurrentCtx==fxMesa) End\n");
+    }
+
+    return;
+  }
+
+  if(fxMesaCurrentCtx)
+    grGlideGetState((GrState*)fxMesaCurrentCtx->state);
+
+  fxMesaCurrentCtx=fxMesa;
+
+  grSstSelect(fxMesa->board);
+  grGlideSetState((GrState*)fxMesa->state);
+
+  gl_make_current(fxMesa->glCtx,fxMesa->glBuffer);
+
+  fxSetupDDPointers(fxMesa->glCtx);
+
+  /* The first time we call MakeCurrent we set the initial viewport size */
+  if(fxMesa->glCtx->Viewport.Width==0)
+    gl_Viewport(fxMesa->glCtx,0,0,fxMesa->width,fxMesa->height);
+
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+    fprintf(stderr,"fxmesa: fxMesaMakeCurrent(...) End\n");
+  }
+}
+
+
+/*
+ * Swap front/back buffers for current context if double buffered.
+ */
+void GLAPIENTRY fxMesaSwapBuffers(void)
+{
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+    fprintf(stderr,"fxmesa: ------------------------------- fxMesaSwapBuffers() -------------------------------\n");
+  }
+
+  if(fxMesaCurrentCtx) {
+   FLUSH_VB( fxMesaCurrentCtx->glCtx, "swap buffers" );
+
+    if(fxMesaCurrentCtx->haveDoubleBuffer) {
+
+      grBufferSwap(fxMesaCurrentCtx->swapInterval);
+
+      /*
+       * Don't allow swap buffer commands to build up!
+       */
+      while(FX_grGetInteger(FX_PENDING_BUFFERSWAPS)>fxMesaCurrentCtx->maxPendingSwapBuffers)
+        /* The driver is able to sleep when waiting for the completation
+           of multiple swapbuffer operations instead of wasting
+           CPU time (NOTE: you must uncomment the following line in the
+           in order to enable this option) */
+        /* usleep(10000); */
+        ;
+
+      fxMesaCurrentCtx->stats.swapBuffer++;
+    }
+  }
+}
+
+
+/*
+ * Query 3Dfx hardware presence/kind
+ */
+int GLAPIENTRY fxQueryHardware(void)
+{
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+    fprintf(stderr,"fxmesa: fxQueryHardware() Start\n");
+  }
+
+  if(!glbGlideInitialized) {
+    grGlideInit();
+    if(FX_grSstQueryHardware(&glbHWConfig)) {
+      grSstSelect(glbCurrentBoard);
+      glb3DfxPresent=1;
+
+      if(getenv("MESA_FX_INFO")) {
+        char buf[80];
+                        
+        FX_grGlideGetVersion(buf);
+        fprintf(stderr,"Using Glide V%s\n",0);
+        fprintf(stderr,"Number of boards: %d\n",glbHWConfig.num_sst);
+
+        if(glbHWConfig.SSTs[glbCurrentBoard].type==GR_SSTTYPE_VOODOO) {
+          fprintf(stderr,"Framebuffer RAM: %d\n",
+                  glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig.sliDetect ?
+                  (glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig.fbRam*2) :
+                  glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig.fbRam);
+          fprintf(stderr,"Number of TMUs: %d\n",
+                  glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig.nTexelfx);
+          fprintf(stderr,"SLI detected: %d\n",
+                  glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig.sliDetect);
+        } else if(glbHWConfig.SSTs[glbCurrentBoard].type==GR_SSTTYPE_SST96) {
+          fprintf(stderr,"Framebuffer RAM: %d\n",
+                  glbHWConfig.SSTs[glbCurrentBoard].sstBoard.SST96Config.fbRam);
+          fprintf(stderr,"Number of TMUs: %d\n",
+                  glbHWConfig.SSTs[glbCurrentBoard].sstBoard.SST96Config.nTexelfx);
+        }
+
+      }
+    } else
+      glb3DfxPresent=0;
+
+    glbGlideInitialized=1;
+
+#if defined(__WIN32__)
+    onexit((_onexit_t)cleangraphics);
+#elif defined(__linux__)
+    atexit(cleangraphics);
+#endif
+  }
+
+  if(!glb3DfxPresent) {
+    if (MESA_VERBOSE&VERBOSE_DRIVER) {
+      fprintf(stderr,"fxmesa: fxQueryHardware() End (-1)\n");
+    }
+    return(-1);
+  }
+
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+    fprintf(stderr,"fxmesa: fxQueryHardware() End (voodooo)\n");
+  }
+  return(glbHWConfig.SSTs[glbCurrentBoard].type);
+}
+
+
+/*
+ * Shutdown Glide library
+ */
+void GLAPIENTRY fxCloseHardware(void)
+{
+  if(glbGlideInitialized) {
+    if(getenv("MESA_FX_INFO")) {
+      GrSstPerfStats_t          st;
+
+      FX_grSstPerfStats(&st);
+      fprintf(stderr,"Pixels Stats:\n");
+      fprintf(stderr,"  # pixels processed (minus buffer clears): %u\n",(unsigned)st.pixelsIn);
+      fprintf(stderr,"  # pixels not drawn due to chroma key test failure: %u\n",(unsigned)st.chromaFail);
+      fprintf(stderr,"  # pixels not drawn due to depth test failure: %u\n",(unsigned)st.zFuncFail);
+      fprintf(stderr,"  # pixels not drawn due to alpha test failure: %u\n",(unsigned)st.aFuncFail);
+      fprintf(stderr,"  # pixels drawn (including buffer clears and LFB writes): %u\n",(unsigned)st.pixelsOut);
+    }
+
+    if(glbTotNumCtx==0) {
+      grGlideShutdown();
+      glbGlideInitialized=0;
+    }
+  }
+}
+
+
+#else
+
+
+/*
+ * Need this to provide at least one external definition.
+ */
+
+int gl_fx_dummy_function_api(void)
+{
+  return 0;
+}
+
+#endif  /* FX */
diff --git a/src/mesa/drivers/glide/fxdd.c b/src/mesa/drivers/glide/fxdd.c
new file mode 100644 (file)
index 0000000..b2f3a7a
--- /dev/null
@@ -0,0 +1,632 @@
+/* -*- mode: C; tab-width:8;  -*-
+
+             fxdd.c - 3Dfx VooDoo Mesa device driver functions
+*/
+
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * See the file fxapi.c for more informations about authors
+ *
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "conf.h"
+#endif
+
+#if defined(FX)
+
+#include "fxdrv.h"
+#include "enums.h"
+
+/**********************************************************************/
+/*****                 Miscellaneous functions                    *****/
+/**********************************************************************/
+
+/* Enalbe/Disable dithering */
+void fxDDDither(GLcontext *ctx, GLboolean enable)
+{
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+    fprintf(stderr,"fxmesa: fxDDDither()\n");
+  }
+
+  if(enable)
+    grDitherMode(GR_DITHER_4x4);
+  else
+    grDitherMode(GR_DITHER_DISABLE);
+}
+
+
+/* Return buffer size information */
+void fxDDBufferSize(GLcontext *ctx, GLuint *width, GLuint *height)
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+    fprintf(stderr,"fxmesa: fxDDBufferSize(...) Start\n");
+  }
+
+  *width=fxMesa->width;
+  *height=fxMesa->height;
+
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+    fprintf(stderr,"fxmesa: fxDDBufferSize(...) End\n");
+  }
+}
+
+
+/* Set current drawing color */
+static void fxDDSetColor(GLcontext *ctx, GLubyte red, GLubyte green,
+                         GLubyte blue, GLubyte alpha )
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+  GLubyte col[4];
+  ASSIGN_4V( col, red, green, blue, alpha );
+  
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+    fprintf(stderr,"fxmesa: fxDDSetColor(%d,%d,%d,%d)\n",red,green,blue,alpha);
+  }
+
+  fxMesa->color=FXCOLOR4(col);
+}
+
+
+/* Implements glClearColor() */
+static void fxDDClearColor(GLcontext *ctx, GLubyte red, GLubyte green,
+                           GLubyte blue, GLubyte alpha )
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+  GLubyte col[4];
+
+
+
+  ASSIGN_4V( col, red, green, blue, 255 );
+
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+    fprintf(stderr,"fxmesa: fxDDClearColor(%d,%d,%d,%d)\n",red,green,blue,alpha);
+  }
+  fxMesa->clearC=FXCOLOR4( col );
+  fxMesa->clearA=alpha;
+}
+
+/* Clear the color and/or depth buffers */
+static GLbitfield fxDDClear(GLcontext *ctx, GLbitfield mask, GLboolean all,
+                            GLint x, GLint y, GLint width, GLint height )
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+  GLbitfield newmask;
+
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+    fprintf(stderr,"fxmesa: fxDDClear(%d,%d,%d,%d)\n",x,y,width,height);
+  }
+
+  switch(mask & (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)) {
+  case (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT):
+    /* clear color and depth buffer */
+
+    if (ctx->Color.DrawDestMask & BACK_LEFT_BIT) {
+      grRenderBuffer(GR_BUFFER_BACKBUFFER);
+      grBufferClear(fxMesa->clearC, fxMesa->clearA,
+                    (FxU16)(ctx->Depth.Clear*0xffff));
+    }
+    if (ctx->Color.DrawDestMask & FRONT_LEFT_BIT) {
+       grRenderBuffer(GR_BUFFER_FRONTBUFFER);
+       grBufferClear(fxMesa->clearC, fxMesa->clearA,
+                     (FxU16)(ctx->Depth.Clear*0xffff));
+    }
+
+    newmask=mask & (~(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT));
+    break;
+  case (GL_COLOR_BUFFER_BIT):
+    /* clear color buffer */
+
+    if(ctx->Color.ColorMask) {
+      grDepthMask(FXFALSE);
+
+      if (ctx->Color.DrawDestMask & BACK_LEFT_BIT) {
+        grRenderBuffer(GR_BUFFER_BACKBUFFER);
+        grBufferClear(fxMesa->clearC, fxMesa->clearA, 0);
+      }
+      if (ctx->Color.DrawDestMask & FRONT_LEFT_BIT) {
+        grRenderBuffer(GR_BUFFER_FRONTBUFFER);
+        grBufferClear(fxMesa->clearC, fxMesa->clearA, 0);
+      }
+
+      if(ctx->Depth.Mask)
+        grDepthMask(FXTRUE);
+    }
+
+    newmask=mask & (~(GL_COLOR_BUFFER_BIT));
+    break;
+  case (GL_DEPTH_BUFFER_BIT):
+    /* clear depth buffer */
+
+    if(ctx->Depth.Mask) {
+      grColorMask(FXFALSE,FXFALSE);
+      grBufferClear(fxMesa->clearC, fxMesa->clearA,
+                    (FxU16)(ctx->Depth.Clear*0xffff));
+
+      grColorMask(ctx->Color.ColorMask[RCOMP] ||
+                  ctx->Color.ColorMask[GCOMP] ||
+                  ctx->Color.ColorMask[BCOMP],
+                  ctx->Color.ColorMask[ACOMP] && fxMesa->haveAlphaBuffer);
+    }
+
+    newmask=mask & (~(GL_DEPTH_BUFFER_BIT));
+    break;
+  default:
+    newmask=mask;
+    break;
+  }
+   
+  return newmask;
+}
+
+
+/*  Set the buffer used in double buffering */
+static GLboolean fxDDSetBuffer(GLcontext *ctx, GLenum mode )
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+    fprintf(stderr,"fxmesa: fxDDSetBuffer(%x)\n",mode);
+  }
+
+  if (mode == GL_FRONT_LEFT) {
+    fxMesa->currentFB = GR_BUFFER_FRONTBUFFER;
+    grRenderBuffer(fxMesa->currentFB);
+    return GL_TRUE;
+  }
+  else if (mode == GL_BACK_LEFT) {
+    fxMesa->currentFB = GR_BUFFER_BACKBUFFER;
+    grRenderBuffer(fxMesa->currentFB);
+    return GL_TRUE;
+  }
+  else {
+    return GL_FALSE;
+  }
+}
+
+
+static GLboolean fxDDDrawBitMap(GLcontext *ctx, GLint px, GLint py,
+                                GLsizei width, GLsizei height,
+                                const struct gl_pixelstore_attrib *unpack,
+                                const GLubyte *bitmap)
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+  FxU16 *p;
+  GrLfbInfo_t info;
+  const GLubyte *pb;
+  int x,y;
+  GLint r,g,b,a,scrwidth,scrheight,stride;
+  FxU16 color;
+
+  /* TODO: with a little work, these bitmap unpacking parameter restrictions
+   * could be removed.
+   */
+  if((unpack->Alignment!=1) ||
+     (unpack->RowLength!=0) ||
+     (unpack->SkipPixels!=0) ||
+     (unpack->SkipRows!=0) ||
+     (unpack->SwapBytes) ||
+     (unpack->LsbFirst))
+    return GL_FALSE;
+
+#define ISCLIPPED(rx) ( ((rx)<0) || ((rx)>=scrwidth) )
+#define DRAWBIT(i) {      \
+  if(!ISCLIPPED(x+px))    \
+    if( (*pb) & (1<<(i)) ) \
+      (*p)=color;         \
+  p++;                     \
+  x++;                    \
+  if(x>=width) {           \
+    pb++;                  \
+    break;                 \
+  }                        \
+}
+
+  scrwidth=fxMesa->width;
+  scrheight=fxMesa->height;
+
+  if((px>=scrwidth) || (px+width<=0) || (py>=scrheight) || (py+height<=0))
+    return GL_TRUE;
+
+  pb=bitmap;
+
+  if(py<0) {
+    pb+=(height*(-py)) >> (3+1);
+    height+=py;
+    py=0;
+  }
+
+  if(py+height>=scrheight)
+    height-=(py+height)-scrheight;
+
+  info.size=sizeof(info);
+  if(!grLfbLock(GR_LFB_WRITE_ONLY,
+                fxMesa->currentFB,
+                GR_LFBWRITEMODE_565,
+                GR_ORIGIN_UPPER_LEFT,
+                FXFALSE,
+                &info)) {
+#ifndef FX_SILENT
+    fprintf(stderr,"fx Driver: error locking the linear frame buffer\n");
+#endif
+    return GL_TRUE;
+  }
+
+  r=(GLint)(ctx->Current.RasterColor[0]*255.0f);
+  g=(GLint)(ctx->Current.RasterColor[1]*255.0f);
+  b=(GLint)(ctx->Current.RasterColor[2]*255.0f);
+  a=(GLint)(ctx->Current.RasterColor[3]*255.0f);
+  color=(FxU16)
+    ( ((FxU16)0xf8 & b) <<(11-3))  |
+    ( ((FxU16)0xfc & g) <<(5-3+1)) |
+    ( ((FxU16)0xf8 & r) >> 3);
+
+  stride=info.strideInBytes>>1;
+
+  /* This code is a bit slow... */
+
+  for(y=0;y<height;y++) {
+    p=((FxU16 *)info.lfbPtr)+px+((scrheight-(y+py))*stride);
+
+    for(x=0;;) {
+      DRAWBIT(7);       DRAWBIT(6);     DRAWBIT(5);     DRAWBIT(4);
+      DRAWBIT(3);       DRAWBIT(2);     DRAWBIT(1);     DRAWBIT(0);
+      pb++;
+    }
+  }
+
+  grLfbUnlock(GR_LFB_WRITE_ONLY,fxMesa->currentFB);
+
+#undef ISCLIPPED
+#undef DRAWBIT
+
+  return GL_TRUE;
+}
+
+static void fxDDFinish(GLcontext *ctx)
+{
+  FX_grFlush();
+}
+
+
+static GLint fxDDGetParameteri(const GLcontext *ctx, GLint param)
+{
+  switch(param) {
+  case DD_HAVE_HARDWARE_FOG:
+    return 1;
+  default:
+    fprintf(stderr,"fx Driver: internal error in fxDDGetParameteri(): %x\n",param);
+    fxCloseHardware();
+    exit(-1);
+  }
+}
+
+
+void fxDDSetNearFar(GLcontext *ctx, GLfloat n, GLfloat f)
+{
+   FX_CONTEXT(ctx)->new_state |= FX_NEW_FOG;
+   ctx->Driver.RenderStart = fxSetupFXUnits;
+}
+
+/* KW: Put the word Mesa in the render string because quakeworld
+ * checks for this rather than doing a glGet(GL_MAX_TEXTURE_SIZE).
+ * Why?
+ */
+static const GLubyte *fxDDGetString(GLcontext *ctx, GLenum name)
+{
+  static char *extensions="GL_EXT_blend_color GL_EXT_blend_minmax GL_EXT_blend_logic_op GL_EXT_blend_subtract GL_EXT_paletted_texture GL_EXT_point_parameters GL_EXT_polygon_offset GL_EXT_vertex_array GL_EXT_texture_object GL_EXT_texture3D GL_MESA_window_pos GL_MESA_resize_buffers GL_EXT_shared_texture_palette GL_EXT_rescale_normal GL_EXT_abgr GL_SGIS_texture_edge_clamp 3DFX_set_global_palette GL_FXMESA_global_texture_lod_bias";
+
+  static char buf[MAX_NUM_SST][64];
+
+  fxQueryHardware();
+
+  switch (name) {
+    case GL_RENDERER:
+      if(glbHWConfig.SSTs[glbCurrentBoard].type==GR_SSTTYPE_VOODOO) {
+        sprintf(buf[glbCurrentBoard],"Mesa Glide v0.30 Voodoo_Graphics %d CARD/%d FB/%d TM/%d TMU/%s",
+                glbCurrentBoard,
+
+                (glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig.sliDetect ?
+                 (glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig.fbRam*2) :
+                 glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig.fbRam),
+
+                glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig.tmuConfig[GR_TMU0].tmuRam+
+                ((glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig.nTexelfx>1) ?
+                 glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig.tmuConfig[GR_TMU1].tmuRam :
+                 0),
+
+                glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig.nTexelfx,
+
+                (glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig.sliDetect ? "SLI" : "NOSLI")
+                );
+      }
+      else {
+        if(glbHWConfig.SSTs[glbCurrentBoard].type==GR_SSTTYPE_SST96)
+          sprintf(buf[glbCurrentBoard],"Glide v0.30 Voodoo_Rush %d CARD/%d FB/%d TM/%d TMU/NOSLI",
+                  glbCurrentBoard,
+
+                  glbHWConfig.SSTs[glbCurrentBoard].sstBoard.SST96Config.fbRam,
+
+                  glbHWConfig.SSTs[glbCurrentBoard].sstBoard.SST96Config.tmuConfig.tmuRam,
+
+                  glbHWConfig.SSTs[glbCurrentBoard].sstBoard.SST96Config.nTexelfx            
+                  );
+        else
+          strcpy(buf[glbCurrentBoard],"Glide v0.30 UNKNOWN");
+      }
+      return (GLubyte *) buf[glbCurrentBoard];
+    case GL_EXTENSIONS:
+      return (GLubyte *) extensions;
+    default:
+      return NULL;
+  }
+}
+
+
+void fxDDInitExtensions( GLcontext *ctx )
+{
+   fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+
+   gl_extensions_add( ctx, DEFAULT_ON, "3DFX_set_global_palette", 0 );
+   gl_extensions_add( ctx, DEFAULT_ON, "GL_FXMESA_global_texture_lod_bias", 0);
+   
+   if (!fxMesa->emulateTwoTMUs) 
+      gl_extensions_disable( ctx, "GL_ARB_multitexture" );
+}
+
+/************************************************************************/
+/************************************************************************/
+/************************************************************************/
+
+/* This is a no-op, since the z-buffer is in hardware */
+static void fxAllocDepthBuffer(GLcontext *ctx)
+{
+   if (MESA_VERBOSE&VERBOSE_DRIVER) {
+     fprintf(stderr,"fxmesa: fxAllocDepthBuffer()\n");
+   }
+}
+
+/************************************************************************/
+/************************************************************************/
+/************************************************************************/
+
+/* Check if the hardware supports the current context 
+ *
+ * Performs similar work to fxDDChooseRenderState() - should be merged.
+ */
+static GLboolean fxIsInHardware(GLcontext *ctx)
+{
+   fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+
+  if (!ctx->Hint.AllowDrawMem)
+     return GL_TRUE;           /* you'll take it and like it */
+
+  if((ctx->RasterMask & STENCIL_BIT) ||
+     ((ctx->Color.BlendEnabled) && (ctx->Color.BlendEquation!=GL_FUNC_ADD_EXT)) ||
+     ((ctx->Color.ColorLogicOpEnabled) && (ctx->Color.LogicOp!=GL_COPY)) ||
+     (ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR) ||
+     (!((ctx->Color.ColorMask[RCOMP]==ctx->Color.ColorMask[GCOMP]) &&
+        (ctx->Color.ColorMask[GCOMP]==ctx->Color.ColorMask[BCOMP]) &&
+        (ctx->Color.ColorMask[ACOMP]==ctx->Color.ColorMask[ACOMP])))
+     )
+    return GL_FALSE;
+
+  /* Unsupported texture/multitexture cases */
+
+  if(fxMesa->emulateTwoTMUs) {
+    if((ctx->Enabled & (TEXTURE0_3D | TEXTURE1_3D)) ||
+       /* Not very well written ... */
+       ((ctx->Enabled & (TEXTURE0_1D | TEXTURE1_1D)) && 
+        ((ctx->Enabled & (TEXTURE0_2D | TEXTURE1_2D))!=(TEXTURE0_2D | TEXTURE1_2D)))
+       )
+      return GL_FALSE;
+
+    if((ctx->Texture.ReallyEnabled & TEXTURE0_2D) &&
+       (ctx->Texture.Unit[0].EnvMode==GL_BLEND))
+      return GL_FALSE;
+
+    if((ctx->Texture.ReallyEnabled & TEXTURE1_2D) &&
+       (ctx->Texture.Unit[1].EnvMode==GL_BLEND))
+      return GL_FALSE;
+
+
+    if (MESA_VERBOSE & (VERBOSE_DRIVER|VERBOSE_TEXTURE))
+       fprintf(stderr, "fxMesa: fxIsInHardware, envmode is %s/%s\n",
+              gl_lookup_enum_by_nr(ctx->Texture.Unit[0].EnvMode),
+              gl_lookup_enum_by_nr(ctx->Texture.Unit[1].EnvMode));
+
+    /* KW: This was wrong (I think) and I changed it... which doesn't mean
+     * it is now correct...
+     */
+    if((ctx->Enabled & (TEXTURE0_1D | TEXTURE0_2D | TEXTURE0_3D)) &&
+       (ctx->Enabled & (TEXTURE1_1D | TEXTURE1_2D | TEXTURE1_3D)))
+    {
+       /* Can't use multipass to blend a multitextured triangle - fall
+       * back to software.
+       */
+       if (!fxMesa->haveTwoTMUs && ctx->Color.BlendEnabled) 
+         return GL_FALSE;
+         
+       if ((ctx->Texture.Unit[0].EnvMode!=ctx->Texture.Unit[1].EnvMode) &&
+          (ctx->Texture.Unit[0].EnvMode!=GL_MODULATE) &&
+          (ctx->Texture.Unit[0].EnvMode!=GL_REPLACE)) /* q2, seems ok... */
+       {
+         if (MESA_VERBOSE&VERBOSE_DRIVER)
+           fprintf(stderr, "fxMesa: unsupported multitex env mode\n");
+
+         return GL_FALSE;
+       }
+    }
+  } else {
+    if((ctx->Enabled & (TEXTURE1_1D | TEXTURE1_2D | TEXTURE1_3D)) ||
+       /* Not very well written ... */
+       ((ctx->Enabled & TEXTURE0_1D) && 
+        (!(ctx->Enabled & TEXTURE0_2D)))
+       )
+      return GL_FALSE;
+
+    
+    if((ctx->Texture.ReallyEnabled & TEXTURE0_2D) &&
+       (ctx->Texture.Unit[0].EnvMode==GL_BLEND))
+      return GL_FALSE;
+  }
+
+  return GL_TRUE;
+}
+
+
+
+#define INTERESTED (~(NEW_MODELVIEW|NEW_PROJECTION|NEW_PROJECTION|NEW_TEXTURE_MATRIX|NEW_USER_CLIP|NEW_CLIENT_STATE|NEW_TEXTURE_ENABLE))
+
+static void fxDDUpdateDDPointers(GLcontext *ctx)
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+  GLuint new_state = ctx->NewState;
+
+  if (MESA_VERBOSE&(VERBOSE_DRIVER|VERBOSE_STATE)) 
+    fprintf(stderr,"fxmesa: fxDDUpdateDDPointers(...)\n");
+
+  if (new_state & (NEW_RASTER_OPS|NEW_TEXTURING))
+     fxMesa->is_in_hardware = fxIsInHardware(ctx);
+
+  if (fxMesa->is_in_hardware) {
+    if (fxMesa->new_state)
+      fxSetupFXUnits(ctx);
+
+    if(new_state & INTERESTED) {
+      fxDDChooseRenderState( ctx );
+      fxMesa->RenderVBTables=fxDDChooseRenderVBTables(ctx);
+      ctx->Driver.RasterSetup=fxDDChooseSetupFunction(ctx);
+    }
+      
+    ctx->Driver.PointsFunc=fxMesa->PointsFunc;
+    ctx->Driver.LineFunc=fxMesa->LineFunc;
+    ctx->Driver.TriangleFunc=fxMesa->TriangleFunc;
+    ctx->Driver.QuadFunc=fxMesa->QuadFunc;
+    ctx->Driver.RenderVBClippedTab=fxMesa->RenderVBTables[0];
+    ctx->Driver.RenderVBCulledTab=fxMesa->RenderVBTables[1];
+    ctx->Driver.RenderVBRawTab=fxMesa->RenderVBTables[2];
+
+  }
+
+  ctx->Driver.AllocDepthBuffer=fxAllocDepthBuffer;
+  ctx->Driver.DepthTestSpan=fxDDDepthTestSpanGeneric;
+  ctx->Driver.DepthTestPixels=fxDDDepthTestPixelsGeneric;
+  ctx->Driver.ReadDepthSpanFloat=fxDDReadDepthSpanFloat;
+  ctx->Driver.ReadDepthSpanInt=fxDDReadDepthSpanInt;
+  ctx->Driver.RenderStart = 0;
+}
+
+
+void fxSetupDDPointers(GLcontext *ctx)
+{
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+    fprintf(stderr,"fxmesa: fxSetupDDPointers()\n");
+  }
+
+  ctx->Driver.UpdateState=fxDDUpdateDDPointers;
+         
+  ctx->Driver.GetString=fxDDGetString;
+
+  ctx->Driver.Dither=fxDDDither;
+
+  ctx->Driver.NearFar=fxDDSetNearFar;
+
+  ctx->Driver.GetParameteri=fxDDGetParameteri;
+
+  ctx->Driver.ClearIndex=NULL;
+  ctx->Driver.ClearColor=fxDDClearColor;
+  ctx->Driver.Clear=fxDDClear;
+
+  ctx->Driver.Index=NULL;
+  ctx->Driver.Color=fxDDSetColor;
+
+  ctx->Driver.SetBuffer=fxDDSetBuffer;
+  ctx->Driver.GetBufferSize=fxDDBufferSize;
+
+  ctx->Driver.Bitmap=fxDDDrawBitMap;
+  ctx->Driver.DrawPixels=NULL;
+
+  ctx->Driver.Finish=fxDDFinish;
+  ctx->Driver.Flush=NULL;
+
+  ctx->Driver.RenderStart=NULL;
+  ctx->Driver.RenderFinish=NULL;
+
+  ctx->Driver.TexEnv=fxDDTexEnv;
+  ctx->Driver.TexImage=fxDDTexImg;
+  ctx->Driver.TexSubImage=fxDDTexSubImg;
+  ctx->Driver.TexParameter=fxDDTexParam;
+  ctx->Driver.BindTexture=fxDDTexBind;
+  ctx->Driver.DeleteTexture=fxDDTexDel;
+  ctx->Driver.UpdateTexturePalette=fxDDTexPalette;
+  ctx->Driver.UseGlobalTexturePalette=fxDDTexUseGlbPalette;
+
+  ctx->Driver.RectFunc=NULL;
+
+  ctx->Driver.AlphaFunc=fxDDAlphaFunc;
+  ctx->Driver.BlendFunc=fxDDBlendFunc;
+  ctx->Driver.DepthFunc=fxDDDepthFunc;
+  ctx->Driver.DepthMask=fxDDDepthMask;
+  ctx->Driver.ColorMask=fxDDColorMask;
+  ctx->Driver.Fogfv=fxDDFogfv;
+  ctx->Driver.Scissor=fxDDScissor;
+  ctx->Driver.FrontFace=fxDDFrontFace;
+  ctx->Driver.CullFace=fxDDCullFace;
+  ctx->Driver.ShadeModel=fxDDShadeModel;
+  ctx->Driver.Enable=fxDDEnable;
+  
+
+  ctx->Driver.RegisterVB=fxDDRegisterVB;
+  ctx->Driver.UnregisterVB=fxDDUnregisterVB;
+
+  ctx->Driver.RegisterPipelineStages = fxDDRegisterPipelineStages;
+
+  ctx->Driver.OptimizeImmediatePipeline = 0; /* nothing done yet */
+  ctx->Driver.OptimizePrecalcPipeline = 0;
+
+/*    if (getenv("MESA_USE_FAST") || getenv("FX_USE_FAST")) */
+/*       ctx->Driver.OptimizePrecalcPipeline = fxDDOptimizePrecalcPipeline; */
+
+  if (!getenv("FX_NO_FAST")) 
+      ctx->Driver.BuildPrecalcPipeline = fxDDBuildPrecalcPipeline; 
+
+  ctx->Driver.TriangleCaps = DD_TRI_CULL|DD_TRI_OFFSET|DD_TRI_LIGHT_TWOSIDE;
+
+  fxSetupDDSpanPointers(ctx);
+
+  FX_CONTEXT(ctx)->render_index = 1; /* force an update */
+  fxDDUpdateDDPointers(ctx);
+}
+
+
+#else
+
+
+/*
+ * Need this to provide at least one external definition.
+ */
+
+int gl_fx_dummy_function_dd(void)
+{
+  return 0;
+}
+
+#endif  /* FX */
diff --git a/src/mesa/drivers/glide/fxddspan.c b/src/mesa/drivers/glide/fxddspan.c
new file mode 100644 (file)
index 0000000..fc7c38d
--- /dev/null
@@ -0,0 +1,817 @@
+/* -*- mode: C; tab-width:8;  -*-
+
+             fxdd.c - 3Dfx VooDoo Mesa span and pixel functions
+*/
+
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * See the file fxapi.c for more informations about authors
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "conf.h"
+#endif
+
+#if defined(FX)
+
+#include "fxdrv.h"
+
+#ifdef _MSC_VER
+#ifdef _WIN32
+#pragma warning( disable : 4090 4022 )
+/* 4101 : "different 'const' qualifier"
+ * 4022 : "pointer mistmatch for actual parameter 'n'
+ */
+#endif
+#endif
+
+
+#if !defined(FXMESA_USE_ARGB) 
+
+    #define LFB_WRITE_SPAN_MESA(dst_buffer,dst_x,dst_y,src_width,src_stride,src_data)  \
+         grLfbWriteRegion(dst_buffer,dst_x,dst_y,src_width,1,GR_LFB_SRC_FMT_8888,src_stride,src_data)
+#else /* defined(FXMESA_USE_RGBA) */
+
+       #define MESACOLOR_TO_ARGB(c) (       \
+             ( ((unsigned int)(c[ACOMP]))<<24 ) | \
+             ( ((unsigned int)(c[RCOMP]))<<16 ) | \
+             ( ((unsigned int)(c[GCOMP]))<<8 )  | \
+             (  (unsigned int)(c[BCOMP])) )
+  
+      /* inline */ void LFB_WRITE_SPAN_MESA(GrBuffer_t dst_buffer, 
+                                 FxU32 dst_x, FxU32 dst_y, 
+                                 /* GrLfbSrcFmt_t src_format, format is GR_LFB_SRC_FMT_8888 */
+                                 FxU32 src_width,/* FxU32 src_height,  height is 1 */
+                                 FxI32 src_stride, void *src_data )
+       {
+             /* Covert to ARGB */
+             GLubyte (*rgba)[4] = src_data;
+             GLuint argb[MAX_WIDTH];
+             int i;
+   
+             for (i = 0; i < src_width; i++)
+             {
+                argb[i] = MESACOLOR_TO_ARGB(rgba[i]);
+             }
+           FX_grLfbWriteRegion(dst_buffer,dst_x,dst_y,GR_LFB_SRC_FMT_8888,src_width,1,src_stride,(void*)argb);
+       }
+#endif
+
+/************************************************************************/
+/*****                    Span functions                            *****/
+/************************************************************************/
+
+static void fxDDWriteRGBASpan(const GLcontext *ctx, 
+                              GLuint n, GLint x, GLint y,
+                              const GLubyte rgba[][4], const GLubyte mask[])
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+  GLuint i;
+  GLint bottom=fxMesa->height-1;
+
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+     fprintf(stderr,"fxmesa: fxDDWriteRGBASpan(...)\n");
+  }
+
+  if (mask) {
+    int span=0;
+
+    for (i=0;i<n;i++) {
+      if (mask[i]) {
+        ++span; 
+      } else {
+        if (span > 0) {
+          LFB_WRITE_SPAN_MESA( fxMesa->currentFB, x+i-span, bottom-y,
+                           /* GR_LFB_SRC_FMT_8888,*/ span, /*1,*/ 0, (void *) rgba[i-span] );
+          span = 0;
+        }
+      }
+    }
+
+    if (span > 0)
+      LFB_WRITE_SPAN_MESA( fxMesa->currentFB, x+n-span, bottom-y,
+                        /* GR_LFB_SRC_FMT_8888, */ span, /*1,*/ 0, (void *) rgba[n-span] );
+  } else
+    LFB_WRITE_SPAN_MESA( fxMesa->currentFB, x, bottom-y,/* GR_LFB_SRC_FMT_8888,*/
+                      n,/* 1,*/ 0, (void *) rgba );
+}
+
+
+static void fxDDWriteRGBSpan(const GLcontext *ctx, 
+                             GLuint n, GLint x, GLint y,
+                             const GLubyte rgb[][3], const GLubyte mask[])
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+  GLuint i;
+  GLint bottom=fxMesa->height-1;
+  GLubyte rgba[MAX_WIDTH][4];
+
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+     fprintf(stderr,"fxmesa: fxDDWriteRGBSpan()\n");
+  }
+
+  if (mask) {
+    int span=0;
+
+    for (i=0;i<n;i++) {
+      if (mask[i]) {
+        rgba[span][RCOMP] = rgb[i][0];
+        rgba[span][GCOMP] = rgb[i][1];
+        rgba[span][BCOMP] = rgb[i][2];
+        rgba[span][ACOMP] = 255;
+        ++span;
+      } else {
+        if (span > 0) {
+          LFB_WRITE_SPAN_MESA( fxMesa->currentFB, x+i-span, bottom-y,
+                            /*GR_LFB_SRC_FMT_8888,*/ span,/* 1,*/ 0, (void *) rgba );
+          span = 0;
+        }
+      }
+    }
+
+    if (span > 0)
+      LFB_WRITE_SPAN_MESA( fxMesa->currentFB, x+n-span, bottom-y,
+                        /*GR_LFB_SRC_FMT_8888,*/ span,/* 1,*/ 0, (void *) rgba );
+  } else {
+    for (i=0;i<n;i++) {
+      rgba[i][RCOMP]=rgb[i][0];
+      rgba[i][GCOMP]=rgb[i][1];
+      rgba[i][BCOMP]=rgb[i][2];
+      rgba[i][ACOMP]=255;
+    }
+
+    LFB_WRITE_SPAN_MESA( fxMesa->currentFB, x, bottom-y,/* GR_LFB_SRC_FMT_8888,*/
+                      n,/* 1,*/ 0, (void *) rgba );
+  }
+}
+
+
+static void fxDDWriteMonoRGBASpan(const GLcontext *ctx, 
+                                  GLuint n, GLint x, GLint y,
+                                  const GLubyte mask[])
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+  GLuint i;
+  GLint bottom=fxMesa->height-1;
+  GLuint data[MAX_WIDTH];
+
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+     fprintf(stderr,"fxmesa: fxDDWriteMonoRGBASpan(...)\n");
+  }
+
+  if (mask) {
+    int span=0;
+
+    for (i=0;i<n;i++) {
+      if (mask[i]) {
+        data[span] = (GLuint) fxMesa->color;
+        ++span;
+      } else {
+        if (span > 0) {
+          FX_grLfbWriteRegion( fxMesa->currentFB, x+i-span, bottom-y,
+                            GR_LFB_SRC_FMT_8888, span, 1, 0,
+                            (void *) data );
+          span = 0;
+        }
+      }
+    }
+
+    if (span > 0)
+      FX_grLfbWriteRegion( fxMesa->currentFB, x+n-span, bottom-y,
+                        GR_LFB_SRC_FMT_8888, span, 1, 0,
+                        (void *) data );
+  } else {
+    for (i=0;i<n;i++) {
+      data[i]=(GLuint) fxMesa->color;
+    }
+
+    FX_grLfbWriteRegion( fxMesa->currentFB, x, bottom-y, GR_LFB_SRC_FMT_8888,
+                      n, 1, 0, (void *) data );
+  }
+}
+
+
+static void fxDDReadRGBASpan(const GLcontext *ctx, 
+                             GLuint n, GLint x, GLint y, GLubyte rgba[][4])
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+  GLushort data[MAX_WIDTH];
+  GLuint i;
+  GLint bottom=fxMesa->height-1;
+
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+     fprintf(stderr,"fxmesa: fxDDReadRGBASpan(...)\n");
+  }
+
+  assert(n < MAX_WIDTH);
+
+  grLfbReadRegion( fxMesa->currentFB, x, bottom-y, n, 1, 0, data);
+  for (i=0;i<n;i++) {
+#if FXMESA_USE_ARGB
+    rgba[i][RCOMP]=(data[i] & 0xF800) >> 8;
+    rgba[i][GCOMP]=(data[i] & 0x07E0) >> 3;
+    rgba[i][BCOMP]=(data[i] & 0x001F) << 3;
+#else
+    rgba[i][RCOMP]=(data[i] & 0x001f) << 3;
+    rgba[i][GCOMP]=(data[i] & 0x07e0) >> 3;
+    rgba[i][BCOMP]=(data[i] & 0xf800) >> 8;
+#endif
+    rgba[i][ACOMP]=255;
+  }
+
+}
+
+/************************************************************************/
+/*****                    Pixel functions                           *****/
+/************************************************************************/
+
+static void fxDDWriteRGBAPixels(const GLcontext *ctx,
+                                GLuint n, const GLint x[], const GLint y[],
+                                CONST GLubyte rgba[][4], const GLubyte mask[])
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+  GLuint i;
+  GLint bottom=fxMesa->height-1;
+
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+     fprintf(stderr,"fxmesa: fxDDWriteRGBAPixels(...)\n");
+  }
+
+  for(i=0;i<n;i++)
+    if(mask[i])
+       LFB_WRITE_SPAN_MESA(fxMesa->currentFB,x[i],bottom-y[i],
+                       /*GR_LFB_SRC_FMT_8888,*/1,/*1,*/0,(void *)rgba[i]);
+}
+
+static void fxDDWriteMonoRGBAPixels(const GLcontext *ctx,
+                                    GLuint n, const GLint x[], const GLint y[],
+                                    const GLubyte mask[])
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+  GLuint i;
+  GLint bottom=fxMesa->height-1;
+
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+     fprintf(stderr,"fxmesa: fxDDWriteMonoRGBAPixels(...)\n");
+  }
+
+  for(i=0;i<n;i++)
+    if(mask[i])
+      FX_grLfbWriteRegion(fxMesa->currentFB,x[i],bottom-y[i],
+                       GR_LFB_SRC_FMT_8888,1,1,0,(void *) &fxMesa->color);
+}
+
+static void fxDDReadRGBAPixels(const GLcontext *ctx,
+                               GLuint n, const GLint x[], const GLint y[],
+                               GLubyte rgba[][4], const GLubyte mask[])
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+  GLuint i;
+  GLint bottom=fxMesa->height-1;
+  GLushort data;
+
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+     fprintf(stderr,"fxmesa: fxDDReadRGBAPixels(...)\n");
+  }
+
+  for(i=0;i<n;i++)
+    if(mask[i]) {
+      grLfbReadRegion(fxMesa->currentFB,x[i],bottom-y[i],1,1,0,&data);
+   #if FXMESA_USE_ARGB 
+      rgba[i][RCOMP]=(data & 0xF800) >> 8;
+      rgba[i][GCOMP]=(data & 0x07E0) >> 3;
+      rgba[i][BCOMP]=(data & 0x001F) >> 8;
+   #else
+      rgba[i][RCOMP]=(data & 0x001f) << 3;
+      rgba[i][GCOMP]=(data & 0x07e0) >> 3;
+      rgba[i][BCOMP]=(data & 0xf800) >> 8;
+   #endif
+      /* the alpha value should be read from the auxiliary buffer when required */
+
+      rgba[i][ACOMP]=255;
+    }
+}
+
+/************************************************************************/
+/*****                    Depth functions                           *****/
+/************************************************************************/
+
+void fxDDReadDepthSpanFloat(GLcontext *ctx,
+                           GLuint n, GLint x, GLint y, GLfloat depth[])
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+  GLuint i;
+  GLint bottom=fxMesa->height-1;
+  GLushort data[MAX_WIDTH];
+
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+     fprintf(stderr,"fxmesa: fxDDReadDepthSpanFloat(...)\n");
+  }
+
+  grLfbReadRegion(GR_BUFFER_AUXBUFFER,x,bottom-y,n,1,0,data);
+
+  /*
+    convert the read values to float values [0.0 .. 1.0].
+  */
+  for(i=0;i<n;i++)
+    depth[i]=data[i]/65535.0f;
+}
+
+void fxDDReadDepthSpanInt(GLcontext *ctx,
+                         GLuint n, GLint x, GLint y, GLdepth depth[])
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+  GLint bottom=fxMesa->height-1;
+
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+     fprintf(stderr,"fxmesa: fxDDReadDepthSpanInt(...)\n");
+  }
+
+  grLfbReadRegion(GR_BUFFER_AUXBUFFER,x,bottom-y,n,1,0,depth);
+}
+
+GLuint fxDDDepthTestSpanGeneric(GLcontext *ctx,
+                                       GLuint n, GLint x, GLint y, const GLdepth z[],
+                                       GLubyte mask[])
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+  GLushort depthdata[MAX_WIDTH];
+  GLdepth *zptr=depthdata;
+  GLubyte *m=mask;
+  GLuint i;
+  GLuint passed=0;
+  GLint bottom=fxMesa->height-1;
+
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+     fprintf(stderr,"fxmesa: fxDDDepthTestSpanGeneric(...)\n");
+  }
+
+  grLfbReadRegion(GR_BUFFER_AUXBUFFER,x,bottom-y,n,1,0,depthdata);
+
+  /* switch cases ordered from most frequent to less frequent */
+  switch (ctx->Depth.Func) {
+  case GL_LESS:
+    if (ctx->Depth.Mask) {
+      /* Update Z buffer */
+      for (i=0; i<n; i++,zptr++,m++) {
+        if (*m) {
+          if (z[i] < *zptr) {
+            /* pass */
+            *zptr = z[i];
+            passed++;
+          } else {
+            /* fail */
+            *m = 0;
+          }
+        }
+      }
+    } else {
+      /* Don't update Z buffer */
+      for (i=0; i<n; i++,zptr++,m++) {
+        if (*m) {
+          if (z[i] < *zptr) {
+            /* pass */
+            passed++;
+          } else {
+            *m = 0;
+          }
+        }
+      }
+    }
+    break;
+  case GL_LEQUAL:
+    if (ctx->Depth.Mask) {
+      /* Update Z buffer */
+      for (i=0;i<n;i++,zptr++,m++) {
+        if (*m) {
+          if (z[i] <= *zptr) {
+            *zptr = z[i];
+            passed++;
+          } else {
+            *m = 0;
+          }
+        }
+      }
+    } else {
+      /* Don't update Z buffer */
+      for (i=0;i<n;i++,zptr++,m++) {
+        if (*m) {
+          if (z[i] <= *zptr) {
+            /* pass */
+            passed++;
+          } else {
+            *m = 0;
+          }
+        }
+      }
+    }
+    break;
+  case GL_GEQUAL:
+    if (ctx->Depth.Mask) {
+      /* Update Z buffer */
+      for (i=0;i<n;i++,zptr++,m++) {
+        if (*m) {
+          if (z[i] >= *zptr) {
+            *zptr = z[i];
+            passed++;
+          } else {
+            *m = 0;
+          }
+        }
+      }
+    } else {
+      /* Don't update Z buffer */
+      for (i=0;i<n;i++,zptr++,m++) {
+        if (*m) {
+          if (z[i] >= *zptr) {
+            /* pass */
+            passed++;
+          } else {
+            *m = 0;
+          }
+        }
+      }
+    }
+    break;
+  case GL_GREATER:
+    if (ctx->Depth.Mask) {
+      /* Update Z buffer */
+      for (i=0;i<n;i++,zptr++,m++) {
+        if (*m) {
+          if (z[i] > *zptr) {
+            *zptr = z[i];
+            passed++;
+          } else {
+            *m = 0;
+          }
+        }
+      }
+    } else {
+      /* Don't update Z buffer */
+      for (i=0;i<n;i++,zptr++,m++) {
+        if (*m) {
+          if (z[i] > *zptr) {
+            /* pass */
+            passed++;
+          } else {
+            *m = 0;
+          }
+        }
+      }
+    }
+    break;
+  case GL_NOTEQUAL:
+    if (ctx->Depth.Mask) {
+      /* Update Z buffer */
+      for (i=0;i<n;i++,zptr++,m++) {
+        if (*m) {
+          if (z[i] != *zptr) {
+            *zptr = z[i];
+            passed++;
+          } else {
+            *m = 0;
+          }
+        }
+      }
+    } else {
+      /* Don't update Z buffer */
+      for (i=0;i<n;i++,zptr++,m++) {
+        if (*m) {
+          if (z[i] != *zptr) {
+            /* pass */
+            passed++;
+          } else {
+            *m = 0;
+          }
+        }
+      }
+    }
+    break;
+  case GL_EQUAL:
+    if (ctx->Depth.Mask) {
+      /* Update Z buffer */
+      for (i=0;i<n;i++,zptr++,m++) {
+        if (*m) {
+          if (z[i] == *zptr) {
+            *zptr = z[i];
+            passed++;
+          } else {
+            *m =0;
+          }
+        }
+      }
+    } else {
+      /* Don't update Z buffer */
+      for (i=0;i<n;i++,zptr++,m++) {
+        if (*m) {
+          if (z[i] == *zptr) {
+            /* pass */
+            passed++;
+          } else {
+            *m =0;
+          }
+        }
+      }
+    }
+    break;
+  case GL_ALWAYS:
+    if (ctx->Depth.Mask) {
+      /* Update Z buffer */
+      for (i=0;i<n;i++,zptr++,m++) {
+        if (*m) {
+          *zptr = z[i];
+          passed++;
+        }
+      }
+    } else {
+      /* Don't update Z buffer or mask */
+      passed = n;
+    }
+    break;
+  case GL_NEVER:
+    for (i=0;i<n;i++) {
+      mask[i] = 0;
+    }
+    break;
+  default:
+    ;
+  } /*switch*/
+
+  if(passed)
+    FX_grLfbWriteRegion(GR_BUFFER_AUXBUFFER,x,bottom-y,GR_LFB_SRC_FMT_ZA16,n,1,0,depthdata);
+
+  return passed;
+}
+
+void fxDDDepthTestPixelsGeneric(GLcontext* ctx,
+                                       GLuint n, const GLint x[], const GLint y[],
+                                       const GLdepth z[], GLubyte mask[])
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+  GLdepth zval;
+  GLuint i;
+  GLint bottom=fxMesa->height-1;
+
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+     fprintf(stderr,"fxmesa: fxDDDepthTestPixelsGeneric(...)\n");
+  }
+
+  /* switch cases ordered from most frequent to less frequent */
+  switch (ctx->Depth.Func) {
+  case GL_LESS:
+    if (ctx->Depth.Mask) {
+      /* Update Z buffer */
+      for (i=0; i<n; i++) {
+        if (mask[i]) {
+          grLfbReadRegion(GR_BUFFER_AUXBUFFER,x[i],bottom-y[i],1,1,0,&zval);
+          if (z[i] < zval) {
+            /* pass */
+            FX_grLfbWriteRegion(GR_BUFFER_AUXBUFFER,x[i],bottom-y[i],GR_LFB_SRC_FMT_ZA16,1,1,0,(void*)&z[i]);
+          } else {
+            /* fail */
+            mask[i] = 0;
+          }
+        }
+      }
+    } else {
+      /* Don't update Z buffer */
+      for (i=0; i<n; i++) {
+        if (mask[i]) {
+          grLfbReadRegion(GR_BUFFER_AUXBUFFER,x[i],bottom-y[i],1,1,0,&zval);
+          if (z[i] < zval) {
+            /* pass */
+          }
+          else {
+            /* fail */
+            mask[i] = 0;
+          }
+        }
+      }
+    }
+    break;
+  case GL_LEQUAL:
+    if (ctx->Depth.Mask) {
+      /* Update Z buffer */
+      for (i=0; i<n; i++) {
+        if (mask[i]) {
+          grLfbReadRegion(GR_BUFFER_AUXBUFFER,x[i],bottom-y[i],1,1,0,&zval);
+          if (z[i] <= zval) {
+            /* pass */
+            FX_grLfbWriteRegion(GR_BUFFER_AUXBUFFER,x[i],bottom-y[i],GR_LFB_SRC_FMT_ZA16,1,1,0,(void*)&z[i]);
+          } else {
+            /* fail */
+            mask[i] = 0;
+          }
+        }
+      }
+    } else {
+      /* Don't update Z buffer */
+      for (i=0; i<n; i++) {
+        if (mask[i]) {
+          grLfbReadRegion(GR_BUFFER_AUXBUFFER,x[i],bottom-y[i],1,1,0,&zval);
+          if (z[i] <= zval) {
+            /* pass */
+          } else {
+            /* fail */
+            mask[i] = 0;
+          }
+        }
+      }
+    }
+    break;
+  case GL_GEQUAL:
+    if (ctx->Depth.Mask) {
+      /* Update Z buffer */
+      for (i=0; i<n; i++) {
+        if (mask[i]) {
+          grLfbReadRegion(GR_BUFFER_AUXBUFFER,x[i],bottom-y[i],1,1,0,&zval);
+          if (z[i] >= zval) {
+            /* pass */
+            FX_grLfbWriteRegion(GR_BUFFER_AUXBUFFER,x[i],bottom-y[i],GR_LFB_SRC_FMT_ZA16,1,1,0,(void*)&z[i]);
+          } else {
+            /* fail */
+            mask[i] = 0;
+          }
+        }
+      }
+    } else {
+      /* Don't update Z buffer */
+      for (i=0; i<n; i++) {
+        if (mask[i]) {
+          grLfbReadRegion(GR_BUFFER_AUXBUFFER,x[i],bottom-y[i],1,1,0,&zval);
+          if (z[i] >= zval) {
+            /* pass */
+          } else {
+            /* fail */
+            mask[i] = 0;
+          }
+        }
+      }
+    }
+    break;
+  case GL_GREATER:
+    if (ctx->Depth.Mask) {
+      /* Update Z buffer */
+      for (i=0; i<n; i++) {
+        if (mask[i]) {
+          grLfbReadRegion(GR_BUFFER_AUXBUFFER,x[i],bottom-y[i],1,1,0,&zval);
+          if (z[i] > zval) {
+            /* pass */
+            FX_grLfbWriteRegion(GR_BUFFER_AUXBUFFER,x[i],bottom-y[i],GR_LFB_SRC_FMT_ZA16,1,1,0,(void*)&z[i]);
+          } else {
+            /* fail */
+            mask[i] = 0;
+          }
+        }
+      }
+    } else {
+      /* Don't update Z buffer */
+      for (i=0; i<n; i++) {
+        if (mask[i]) {
+          grLfbReadRegion(GR_BUFFER_AUXBUFFER,x[i],bottom-y[i],1,1,0,&zval);
+          if (z[i] > zval) {
+            /* pass */
+          } else {
+            /* fail */
+            mask[i] = 0;
+          }
+        }
+      }
+    }
+    break;
+  case GL_NOTEQUAL:
+    if (ctx->Depth.Mask) {
+      /* Update Z buffer */
+      for (i=0; i<n; i++) {
+        if (mask[i]) {
+          grLfbReadRegion(GR_BUFFER_AUXBUFFER,x[i],bottom-y[i],1,1,0,&zval);
+          if (z[i] != zval) {
+            /* pass */
+            FX_grLfbWriteRegion(GR_BUFFER_AUXBUFFER,x[i],bottom-y[i],GR_LFB_SRC_FMT_ZA16,1,1,0,(void*)&z[i]);
+          } else {
+            /* fail */
+            mask[i] = 0;
+          }
+        }
+      }
+    } else {
+      /* Don't update Z buffer */
+      for (i=0; i<n; i++) {
+        if (mask[i]) {
+          grLfbReadRegion(GR_BUFFER_AUXBUFFER,x[i],bottom-y[i],1,1,0,&zval);
+          if (z[i] != zval) {
+            /* pass */
+          }
+          else {
+            /* fail */
+            mask[i] = 0;
+          }
+        }
+      }
+    }
+    break;
+  case GL_EQUAL:
+    if (ctx->Depth.Mask) {
+      /* Update Z buffer */
+      for (i=0; i<n; i++) {
+        if (mask[i]) {
+          grLfbReadRegion(GR_BUFFER_AUXBUFFER,x[i],bottom-y[i],1,1,0,&zval);
+          if (z[i] == zval) {
+            /* pass */
+            FX_grLfbWriteRegion(GR_BUFFER_AUXBUFFER,x[i],bottom-y[i],GR_LFB_SRC_FMT_ZA16,1,1,0,(void*)&z[i]);
+          } else {
+            /* fail */
+            mask[i] = 0;
+          }
+        }
+      }
+    } else {
+      /* Don't update Z buffer */
+      for (i=0; i<n; i++) {
+        if (mask[i]) {
+          grLfbReadRegion(GR_BUFFER_AUXBUFFER,x[i],bottom-y[i],1,1,0,&zval);
+          if (z[i] == zval) {
+            /* pass */
+          } else {
+            /* fail */
+            mask[i] = 0;
+          }
+        }
+      }
+    }
+    break;
+  case GL_ALWAYS:
+    if (ctx->Depth.Mask) {
+      /* Update Z buffer */
+      for (i=0; i<n; i++) {
+        if (mask[i]) {
+          FX_grLfbWriteRegion(GR_BUFFER_AUXBUFFER,x[i],bottom-y[i],GR_LFB_SRC_FMT_ZA16,1,1,0,(void*)&z[i]);
+        }
+      }
+    } else {
+      /* Don't update Z buffer or mask */
+    }
+    break;
+  case GL_NEVER:
+    /* depth test never passes */
+    for (i=0;i<n;i++) {
+      mask[i] = 0;
+    }
+    break;
+  default:
+    ;
+  } /*switch*/
+}
+
+/************************************************************************/
+
+
+void fxSetupDDSpanPointers(GLcontext *ctx)
+{
+  ctx->Driver.WriteRGBASpan       =fxDDWriteRGBASpan;
+  ctx->Driver.WriteRGBSpan        =fxDDWriteRGBSpan;
+  ctx->Driver.WriteMonoRGBASpan   =fxDDWriteMonoRGBASpan;
+  ctx->Driver.WriteRGBAPixels     =fxDDWriteRGBAPixels;
+  ctx->Driver.WriteMonoRGBAPixels =fxDDWriteMonoRGBAPixels;
+
+  ctx->Driver.WriteCI8Span        =NULL;
+  ctx->Driver.WriteCI32Span       =NULL;
+  ctx->Driver.WriteMonoCISpan     =NULL;
+  ctx->Driver.WriteCI32Pixels     =NULL;
+  ctx->Driver.WriteMonoCIPixels   =NULL;
+
+  ctx->Driver.ReadRGBASpan        =fxDDReadRGBASpan;
+  ctx->Driver.ReadRGBAPixels      =fxDDReadRGBAPixels;
+
+  ctx->Driver.ReadCI32Span        =NULL;
+  ctx->Driver.ReadCI32Pixels      =NULL;
+}
+
+
+#else
+
+
+/*
+ * Need this to provide at least one external definition.
+ */
+
+int gl_fx_dummy_function_span(void)
+{
+  return 0;
+}
+
+#endif  /* FX */
diff --git a/src/mesa/drivers/glide/fxddtex.c b/src/mesa/drivers/glide/fxddtex.c
new file mode 100644 (file)
index 0000000..05ef775
--- /dev/null
@@ -0,0 +1,1299 @@
+/* -*- mode: C; tab-width:8;  -*-
+
+             fxddtex.c - 3Dfx VooDoo Texture mapping functions
+*/
+
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * See the file fxapi.c for more informations about authors
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "conf.h"
+#endif
+
+#if defined(FX)
+
+#include "fxdrv.h"
+
+/************************************************************************/
+/*************************** Texture Mapping ****************************/
+/************************************************************************/
+
+static void fxTexInvalidate(GLcontext *ctx, struct gl_texture_object *tObj)
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+  tfxTexInfo *ti;
+
+  fxTMMoveOutTM(fxMesa,tObj); /* TO DO: SLOW but easy to write */
+
+  ti=(tfxTexInfo *)tObj->DriverData;
+  ti->validated=GL_FALSE;
+  fxMesa->new_state|=FX_NEW_TEXTURING;
+  ctx->Driver.RenderStart = fxSetupFXUnits;
+}
+
+static tfxTexInfo *fxAllocTexObjData(fxMesaContext fxMesa)
+{
+  tfxTexInfo *ti;
+  int i;
+
+  if(!(ti=malloc(sizeof(tfxTexInfo)))) {
+    fprintf(stderr,"fx Driver: out of memory !\n");
+    fxCloseHardware();
+    exit(-1);
+  }
+
+  ti->validated=GL_FALSE;
+  ti->tmi.isInTM=GL_FALSE;
+
+  ti->tmi.whichTMU=FX_TMU_NONE;
+
+  ti->tmi.tm[FX_TMU0]=NULL;
+  ti->tmi.tm[FX_TMU1]=NULL;
+
+  ti->minFilt=GR_TEXTUREFILTER_POINT_SAMPLED;
+  ti->maxFilt=GR_TEXTUREFILTER_BILINEAR;
+
+  ti->sClamp=GR_TEXTURECLAMP_WRAP;
+  ti->tClamp=GR_TEXTURECLAMP_WRAP;
+
+  if(fxMesa->haveTwoTMUs) {
+    ti->mmMode=GR_MIPMAP_NEAREST;
+    ti->LODblend=FXTRUE;
+  } else {
+    ti->mmMode=GR_MIPMAP_NEAREST_DITHER;
+    ti->LODblend=FXFALSE;
+  }
+
+  for(i=0;i<MAX_TEXTURE_LEVELS;i++) {
+    ti->tmi.mipmapLevel[i].used=GL_FALSE;
+    ti->tmi.mipmapLevel[i].data=NULL;
+  }
+
+  return ti;
+}
+
+void fxDDTexBind(GLcontext *ctx, GLenum target, struct gl_texture_object *tObj)
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+  tfxTexInfo *ti;
+
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+     fprintf(stderr,"fxmesa: fxDDTexBind(%d,%x)\n",tObj->Name,(GLuint)tObj->DriverData);
+  }
+
+  if(target!=GL_TEXTURE_2D)
+    return;
+
+  if(!tObj->DriverData)
+    tObj->DriverData=fxAllocTexObjData(fxMesa);
+
+  ti=(tfxTexInfo *)tObj->DriverData;
+
+  fxMesa->texBindNumber++;
+  ti->tmi.lastTimeUsed=fxMesa->texBindNumber;
+
+  fxMesa->new_state|=FX_NEW_TEXTURING;
+  ctx->Driver.RenderStart = fxSetupFXUnits;
+}
+
+void fxDDTexEnv(GLcontext *ctx, GLenum pname, const GLfloat *param)
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+
+   if (MESA_VERBOSE&VERBOSE_DRIVER) {
+      if(param)
+        fprintf(stderr,"fxmesa: texenv(%x,%x)\n",pname,(GLint)(*param));
+      else
+        fprintf(stderr,"fxmesa: texenv(%x)\n",pname);
+   }
+
+   fxMesa->new_state|=FX_NEW_TEXTURING;
+   ctx->Driver.RenderStart = fxSetupFXUnits;
+}
+
+void fxDDTexParam(GLcontext *ctx, GLenum target, struct gl_texture_object *tObj,
+                  GLenum pname, const GLfloat *params)
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+  GLenum param=(GLenum)(GLint)params[0];
+  tfxTexInfo *ti;
+
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+     fprintf(stderr,"fxmesa: fxDDTexParam(%d,%x,%x,%x)\n",tObj->Name,(GLuint)tObj->DriverData,pname,param);
+  }
+
+  if(target!=GL_TEXTURE_2D)
+    return;
+
+  if(!tObj->DriverData)
+    tObj->DriverData=fxAllocTexObjData(fxMesa);
+
+  ti=(tfxTexInfo *)tObj->DriverData;
+
+  switch(pname) {
+
+  case GL_TEXTURE_MIN_FILTER:
+    switch(param) {
+    case GL_NEAREST:
+      ti->mmMode=GR_MIPMAP_DISABLE;
+      ti->minFilt=GR_TEXTUREFILTER_POINT_SAMPLED;
+      ti->LODblend=FXFALSE;
+      break;
+    case GL_LINEAR:
+      ti->mmMode=GR_MIPMAP_DISABLE;
+      ti->minFilt=GR_TEXTUREFILTER_BILINEAR;
+      ti->LODblend=FXFALSE;
+      break;
+    case GL_NEAREST_MIPMAP_NEAREST:
+      ti->mmMode=GR_MIPMAP_NEAREST;
+      ti->minFilt=GR_TEXTUREFILTER_POINT_SAMPLED;
+      ti->LODblend=FXFALSE;
+      break;
+    case GL_LINEAR_MIPMAP_NEAREST:
+      ti->mmMode=GR_MIPMAP_NEAREST;
+      ti->minFilt=GR_TEXTUREFILTER_BILINEAR;
+      ti->LODblend=FXFALSE;
+      break;
+    case GL_NEAREST_MIPMAP_LINEAR:
+      if(fxMesa->haveTwoTMUs) {
+        ti->mmMode=GR_MIPMAP_NEAREST;
+        ti->LODblend=FXTRUE;
+      } else {
+        ti->mmMode=GR_MIPMAP_NEAREST_DITHER;
+        ti->LODblend=FXFALSE;
+      }
+      ti->minFilt=GR_TEXTUREFILTER_POINT_SAMPLED;
+      break;
+    case GL_LINEAR_MIPMAP_LINEAR:
+      if(fxMesa->haveTwoTMUs) {
+        ti->mmMode=GR_MIPMAP_NEAREST;
+        ti->LODblend=FXTRUE;
+      } else {
+        ti->mmMode=GR_MIPMAP_NEAREST_DITHER;
+        ti->LODblend=FXFALSE;
+      }
+      ti->minFilt=GR_TEXTUREFILTER_BILINEAR;
+      break;
+    default:
+      break;
+    }
+    fxTexInvalidate(ctx,tObj);
+    break;
+
+  case GL_TEXTURE_MAG_FILTER:
+    switch(param) {
+    case GL_NEAREST:
+      ti->maxFilt=GR_TEXTUREFILTER_POINT_SAMPLED;
+      break;
+    case GL_LINEAR:
+      ti->maxFilt=GR_TEXTUREFILTER_BILINEAR;
+      break;
+    default:
+      break;
+    }
+    fxTexInvalidate(ctx,tObj);
+    break;
+
+  case GL_TEXTURE_WRAP_S:
+    switch(param) {
+    case GL_CLAMP:
+      ti->sClamp=GR_TEXTURECLAMP_CLAMP;
+      break;
+    case GL_REPEAT:
+      ti->sClamp=GR_TEXTURECLAMP_WRAP;
+      break;
+    default:
+      break;
+    }
+    fxMesa->new_state|=FX_NEW_TEXTURING;
+    ctx->Driver.RenderStart = fxSetupFXUnits;
+    break;
+
+  case GL_TEXTURE_WRAP_T:
+    switch(param) {
+    case GL_CLAMP:
+      ti->tClamp=GR_TEXTURECLAMP_CLAMP;
+      break;
+    case GL_REPEAT:
+      ti->tClamp=GR_TEXTURECLAMP_WRAP;
+      break;
+    default:
+      break;
+    }
+    fxMesa->new_state|=FX_NEW_TEXTURING;
+    ctx->Driver.RenderStart = fxSetupFXUnits;
+    break;
+
+  case GL_TEXTURE_BORDER_COLOR:
+    /* TO DO */
+    break;
+
+  case GL_TEXTURE_MIN_LOD:
+    /* TO DO */
+    break;
+  case GL_TEXTURE_MAX_LOD:
+    /* TO DO */
+    break;
+  case GL_TEXTURE_BASE_LEVEL:
+    fxTexInvalidate(ctx,tObj);
+    break;
+  case GL_TEXTURE_MAX_LEVEL:
+    fxTexInvalidate(ctx,tObj);
+    break;
+
+  default:
+    break;
+  }
+}
+
+void fxDDTexDel(GLcontext *ctx, struct gl_texture_object *tObj)
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+  tfxTexInfo *ti=(tfxTexInfo *)tObj->DriverData;
+
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+     fprintf(stderr,"fxmesa: fxDDTexDel(%d,%x)\n",tObj->Name,(GLuint)ti);
+  }
+
+  if(!ti)
+    return;
+
+  fxTMFreeTexture(fxMesa,tObj);
+
+  free(ti);
+  tObj->DriverData=NULL;
+
+  ctx->NewState|=NEW_TEXTURING;
+}
+
+void fxDDTexPalette(GLcontext *ctx, struct gl_texture_object *tObj)
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+  int i;
+  FxU32 r,g,b,a;
+  tfxTexInfo *ti;
+
+  if(tObj) {  
+     if (MESA_VERBOSE&VERBOSE_DRIVER) {
+       fprintf(stderr,"fxmesa: fxDDTexPalette(%d,%x)\n",tObj->Name,(GLuint)tObj->DriverData);
+     }
+
+    if(tObj->PaletteFormat!=GL_RGBA) {
+#ifndef FX_SILENT
+      fprintf(stderr,"fx Driver: unsupported palette format in texpalette()\n");
+#endif
+      return;
+    }
+
+    if(tObj->PaletteSize>256) {
+#ifndef FX_SILENT
+      fprintf(stderr,"fx Driver: unsupported palette size in texpalette()\n");
+#endif
+      return;
+    }
+
+    if(!tObj->DriverData)
+      tObj->DriverData=fxAllocTexObjData(fxMesa);
+  
+    ti=(tfxTexInfo *)tObj->DriverData;
+
+    for(i=0;i<tObj->PaletteSize;i++) {
+      r=tObj->Palette[i*4];
+      g=tObj->Palette[i*4+1];
+      b=tObj->Palette[i*4+2];
+      a=tObj->Palette[i*4+3];
+      ti->palette.data[i]=(a<<24)|(r<<16)|(g<<8)|b;
+    }
+
+    fxTexInvalidate(ctx,tObj);
+  } else {
+     if (MESA_VERBOSE&VERBOSE_DRIVER) {
+       fprintf(stderr,"fxmesa: fxDDTexPalette(global)\n");
+     }
+    if(ctx->Texture.PaletteFormat!=GL_RGBA) {
+#ifndef FX_SILENT
+      fprintf(stderr,"fx Driver: unsupported palette format in texpalette()\n");
+#endif
+      return;
+    }
+
+    if(ctx->Texture.PaletteSize>256) {
+#ifndef FX_SILENT
+      fprintf(stderr,"fx Driver: unsupported palette size in texpalette()\n");
+#endif
+      return;
+    }
+
+    for(i=0;i<ctx->Texture.PaletteSize;i++) {
+      r=ctx->Texture.Palette[i*4];
+      g=ctx->Texture.Palette[i*4+1];
+      b=ctx->Texture.Palette[i*4+2];
+      a=ctx->Texture.Palette[i*4+3];
+      fxMesa->glbPalette.data[i]=(a<<24)|(r<<16)|(g<<8)|b;
+    }
+
+    fxMesa->new_state|=FX_NEW_TEXTURING;
+    ctx->Driver.RenderStart = fxSetupFXUnits;
+  }
+}
+
+void fxDDTexUseGlbPalette(GLcontext *ctx, GLboolean state)
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+     fprintf(stderr,"fxmesa: fxDDTexUseGlbPalette(%d)\n",state);
+  }
+
+  if(state) {
+    fxMesa->haveGlobalPaletteTexture=1;
+
+    FX_grTexDownloadTable(GR_TMU0,GR_TEXTABLE_PALETTE,&(fxMesa->glbPalette));
+    if (fxMesa->haveTwoTMUs)
+       FX_grTexDownloadTable(GR_TMU1,GR_TEXTABLE_PALETTE,&(fxMesa->glbPalette));
+  } else {
+    fxMesa->haveGlobalPaletteTexture=0;
+
+    if((ctx->Texture.Unit[0].Current==ctx->Texture.Unit[0].CurrentD[2]) &&
+       (ctx->Texture.Unit[0].Current!=NULL)) {
+      struct gl_texture_object *tObj=ctx->Texture.Unit[0].Current;
+      tfxTexInfo *ti;
+
+      if(!tObj->DriverData)
+        tObj->DriverData=fxAllocTexObjData(fxMesa);
+  
+      ti=(tfxTexInfo *)tObj->DriverData;
+
+      fxTexInvalidate(ctx,tObj);
+    }
+  }
+}
+
+static int logbase2(int n)
+{
+  GLint i = 1;
+  GLint log2 = 0;
+
+  if (n<0) {
+    return -1;
+  }
+
+  while (n > i) {
+    i *= 2;
+    log2++;
+  }
+  if (i != n) {
+    return -1;
+  }
+  else {
+    return log2;
+  }
+}
+
+/* Need different versions for different cpus.
+ */
+#define INT_TRICK(l2) (0x800000 * l2)
+
+
+int fxTexGetInfo(int w, int h, GrLOD_t *lodlevel, GrAspectRatio_t *ar,
+                 float *sscale, float *tscale,
+                 int *i_sscale, int *i_tscale,
+                 int *wscale, int *hscale)
+{
+
+  static GrLOD_t lod[9]={GR_LOD_256,GR_LOD_128,GR_LOD_64,GR_LOD_32,
+                         GR_LOD_16,GR_LOD_8,GR_LOD_4,GR_LOD_2,GR_LOD_1};
+
+  int logw,logh,ws,hs;
+  GrLOD_t l;
+  GrAspectRatio_t aspectratio;
+  float s,t;
+  int is,it;
+
+  logw=logbase2(w);
+  logh=logbase2(h);
+
+  switch(logw-logh) {
+  case 0:
+    aspectratio=GR_ASPECT_1x1;
+    l=lod[8-logw];
+    s=t=256.0f;
+    is=it=INT_TRICK(8);
+    ws=hs=1;
+    break;
+  case 1:
+    aspectratio=GR_ASPECT_2x1;
+    l=lod[8-logw];
+    s=256.0f;
+    t=128.0f;
+    is=INT_TRICK(8);it=INT_TRICK(7);
+    ws=1;
+    hs=1;
+    break;
+  case 2:
+    aspectratio=GR_ASPECT_4x1;
+    l=lod[8-logw];
+    s=256.0f;
+    t=64.0f;
+    is=INT_TRICK(8);it=INT_TRICK(6);
+    ws=1;
+    hs=1;
+    break;
+  case 3:
+    aspectratio=GR_ASPECT_8x1;
+    l=lod[8-logw];
+    s=256.0f;
+    t=32.0f;
+    is=INT_TRICK(8);it=INT_TRICK(5);
+    ws=1;
+    hs=1;
+    break;
+  case 4:
+    aspectratio=GR_ASPECT_8x1;
+    l=lod[8-logw];
+    s=256.0f;
+    t=32.0f;
+    is=INT_TRICK(8);it=INT_TRICK(5);
+    ws=1;
+    hs=2;
+    break;
+  case 5:
+    aspectratio=GR_ASPECT_8x1;
+    l=lod[8-logw];
+    s=256.0f;
+    t=32.0f;
+    is=INT_TRICK(8);it=INT_TRICK(5);
+    ws=1;
+    hs=4;
+    break;
+  case 6:
+    aspectratio=GR_ASPECT_8x1;
+    l=lod[8-logw];
+    s=256.0f;
+    t=32.0f;
+    is=INT_TRICK(8);it=INT_TRICK(5);
+    ws=1;
+    hs=8;
+    break;
+  case 7:
+    aspectratio=GR_ASPECT_8x1;
+    l=lod[8-logw];
+    s=256.0f;
+    t=32.0f;
+    is=INT_TRICK(8);it=INT_TRICK(5);
+    ws=1;
+    hs=16;
+    break;
+  case 8:
+    aspectratio=GR_ASPECT_8x1;
+    l=lod[8-logw];
+    s=256.0f;
+    t=32.0f;
+    is=INT_TRICK(8);it=INT_TRICK(5);
+    ws=1;
+    hs=32;
+    break;
+  case -1:
+    aspectratio=GR_ASPECT_1x2;
+    l=lod[8-logh];
+    s=128.0f;
+    t=256.0f;
+    is=INT_TRICK(7);it=INT_TRICK(8);
+    ws=1;
+    hs=1;
+    break;
+  case -2:
+    aspectratio=GR_ASPECT_1x4;
+    l=lod[8-logh];
+    s=64.0f;
+    t=256.0f;
+    is=INT_TRICK(6);it=INT_TRICK(8);
+    ws=1;
+    hs=1;
+    break;
+  case -3:
+    aspectratio=GR_ASPECT_1x8;
+    l=lod[8-logh];
+    s=32.0f;
+    t=256.0f;
+    is=INT_TRICK(5);it=INT_TRICK(8);
+    ws=1;
+    hs=1;
+    break;
+  case -4:
+    aspectratio=GR_ASPECT_1x8;
+    l=lod[8-logh];
+    s=32.0f;
+    t=256.0f;
+    is=INT_TRICK(5);it=INT_TRICK(8);
+    ws=2;
+    hs=1;
+    break;
+  case -5:
+    aspectratio=GR_ASPECT_1x8;
+    l=lod[8-logh];
+    s=32.0f;
+    t=256.0f;
+    is=INT_TRICK(5);it=INT_TRICK(8);
+    ws=4;
+    hs=1;
+    break;
+  case -6:
+    aspectratio=GR_ASPECT_1x8;
+    l=lod[8-logh];
+    s=32.0f;
+    t=256.0f;
+    is=INT_TRICK(5);it=INT_TRICK(8);
+    ws=8;
+    hs=1;
+    break;
+  case -7:
+    aspectratio=GR_ASPECT_1x8;
+    l=lod[8-logh];
+    s=32.0f;
+    t=256.0f;
+    is=INT_TRICK(5);it=INT_TRICK(8);
+    ws=16;
+    hs=1;
+    break;
+  case -8:
+    aspectratio=GR_ASPECT_1x8;
+    l=lod[8-logh];
+    s=32.0f;
+    t=256.0f;
+    is=INT_TRICK(5);it=INT_TRICK(8);
+    ws=32;
+    hs=1;
+    break;
+  default:
+    return 0;
+    break;
+  }
+
+  if(lodlevel)
+    (*lodlevel)=l;
+
+  if(ar)
+    (*ar)=aspectratio;
+
+  if(sscale)
+    (*sscale)=s;
+
+  if(tscale)
+    (*tscale)=t;
+
+  if(wscale)
+    (*wscale)=ws;
+
+  if(hscale)
+    (*hscale)=hs;
+
+  if (i_sscale)
+     *i_sscale = is;
+
+  if (i_tscale)
+     *i_tscale = it;
+
+
+  return 1;
+}
+
+void fxTexGetFormat(GLenum glformat, GrTextureFormat_t *tfmt, GLint *ifmt)
+{
+  switch(glformat) {
+  case 1:
+  case GL_LUMINANCE:
+  case GL_LUMINANCE4:
+  case GL_LUMINANCE8:
+  case GL_LUMINANCE12:
+  case GL_LUMINANCE16:
+    if(tfmt)
+      (*tfmt)=GR_TEXFMT_INTENSITY_8;
+    if(ifmt)
+      (*ifmt)=GL_LUMINANCE;
+    break;
+  case 2:
+  case GL_LUMINANCE_ALPHA:
+  case GL_LUMINANCE4_ALPHA4:
+  case GL_LUMINANCE6_ALPHA2:
+  case GL_LUMINANCE8_ALPHA8:
+  case GL_LUMINANCE12_ALPHA4:
+  case GL_LUMINANCE12_ALPHA12:
+  case GL_LUMINANCE16_ALPHA16:
+    if(tfmt)
+      (*tfmt)=GR_TEXFMT_ALPHA_INTENSITY_88;
+    if(ifmt)
+      (*ifmt)=GL_LUMINANCE_ALPHA;
+    break;
+  case GL_INTENSITY:
+  case GL_INTENSITY4:
+  case GL_INTENSITY8:
+  case GL_INTENSITY12:
+  case GL_INTENSITY16:
+    if(tfmt)
+      (*tfmt)=GR_TEXFMT_ALPHA_8;
+    if(ifmt)
+      (*ifmt)=GL_INTENSITY;
+    break;
+  case GL_ALPHA:
+  case GL_ALPHA4:
+  case GL_ALPHA8:
+  case GL_ALPHA12:
+  case GL_ALPHA16:
+    if(tfmt)
+      (*tfmt)=GR_TEXFMT_ALPHA_8;
+    if(ifmt)
+      (*ifmt)=GL_ALPHA;
+    break;
+  case 3:
+  case GL_RGB:
+  case GL_R3_G3_B2:
+  case GL_RGB4:
+  case GL_RGB5:
+  case GL_RGB8:
+  case GL_RGB10:
+  case GL_RGB12:
+  case GL_RGB16:
+    if(tfmt)
+      (*tfmt)=GR_TEXFMT_RGB_565;
+    if(ifmt)
+      (*ifmt)=GL_RGB;
+    break;
+  case 4:
+  case GL_RGBA:
+  case GL_RGBA2:
+  case GL_RGBA4:
+  case GL_RGB5_A1:
+  case GL_RGBA8:
+  case GL_RGB10_A2:
+  case GL_RGBA12:
+  case GL_RGBA16:
+    if(tfmt)
+      (*tfmt)=GR_TEXFMT_ARGB_4444;
+    if(ifmt)
+      (*ifmt)=GL_RGBA;
+    break;
+  case GL_COLOR_INDEX:
+  case GL_COLOR_INDEX1_EXT:
+  case GL_COLOR_INDEX2_EXT:
+  case GL_COLOR_INDEX4_EXT:
+  case GL_COLOR_INDEX8_EXT:
+  case GL_COLOR_INDEX12_EXT:
+  case GL_COLOR_INDEX16_EXT:
+    if(tfmt)
+      (*tfmt)=GR_TEXFMT_P_8;
+    if(ifmt)
+      (*ifmt)=GL_RGBA;
+    break;
+  default:
+    fprintf(stderr,"fx Driver: unsupported internalFormat in fxTexGetFormat()\n");
+    fxCloseHardware();
+    exit(-1);
+    break;
+  }
+}
+
+static int fxIsTexSupported(GLenum target, GLint internalFormat,
+                            const struct gl_texture_image *image)
+{
+  if(target!=GL_TEXTURE_2D)
+    return GL_FALSE;
+
+  switch(internalFormat) {
+  case GL_INTENSITY:
+  case GL_INTENSITY4:
+  case GL_INTENSITY8:
+  case GL_INTENSITY12:
+  case GL_INTENSITY16:
+  case 1:
+  case GL_LUMINANCE:
+  case GL_LUMINANCE4:
+  case GL_LUMINANCE8:
+  case GL_LUMINANCE12:
+  case GL_LUMINANCE16:
+  case 2:
+  case GL_LUMINANCE_ALPHA:
+  case GL_LUMINANCE4_ALPHA4:
+  case GL_LUMINANCE6_ALPHA2:
+  case GL_LUMINANCE8_ALPHA8:
+  case GL_LUMINANCE12_ALPHA4:
+  case GL_LUMINANCE12_ALPHA12:
+  case GL_LUMINANCE16_ALPHA16:
+  case GL_ALPHA:
+  case GL_ALPHA4:
+  case GL_ALPHA8:
+  case GL_ALPHA12:
+  case GL_ALPHA16:
+  case 3:
+  case GL_RGB:
+  case GL_R3_G3_B2:
+  case GL_RGB4:
+  case GL_RGB5:
+  case GL_RGB8:
+  case GL_RGB10:
+  case GL_RGB12:
+  case GL_RGB16:
+  case 4:
+  case GL_RGBA:
+  case GL_RGBA2:
+  case GL_RGBA4:
+  case GL_RGB5_A1:
+  case GL_RGBA8:
+  case GL_RGB10_A2:
+  case GL_RGBA12:
+  case GL_RGBA16:
+  case GL_COLOR_INDEX:
+  case GL_COLOR_INDEX1_EXT:
+  case GL_COLOR_INDEX2_EXT:
+  case GL_COLOR_INDEX4_EXT:
+  case GL_COLOR_INDEX8_EXT:
+  case GL_COLOR_INDEX12_EXT:
+  case GL_COLOR_INDEX16_EXT:
+    break;
+  default:
+    return GL_FALSE;
+  }
+
+  if(image->Width>256)
+    return GL_FALSE;
+
+  if(image->Height>256)
+    return GL_FALSE;
+
+  if(!fxTexGetInfo(image->Width,image->Height,NULL,NULL,NULL,NULL,NULL,NULL,
+                  NULL,NULL))
+    return GL_FALSE;
+
+  return GL_TRUE;
+}
+
+static void fxTexBuildImageMap(const struct gl_texture_image *image,
+                               GLint internalFormat, unsigned short **dest,
+                               GLboolean *istranslate)
+{
+  unsigned short *src;
+  unsigned char *data;
+  int x,y,w,h,wscale,hscale,idx;
+
+  fxTexGetInfo(image->Width,image->Height,NULL,NULL,NULL,NULL,NULL,NULL,
+              &wscale,&hscale);
+  w=image->Width*wscale;
+  h=image->Height*hscale;
+
+  data=image->Data;
+  switch(internalFormat) {
+  case GL_INTENSITY:
+  case GL_INTENSITY4:
+  case GL_INTENSITY8:
+  case GL_INTENSITY12:
+  case GL_INTENSITY16:
+  case 1:
+  case GL_LUMINANCE:
+  case GL_LUMINANCE4:
+  case GL_LUMINANCE8:
+  case GL_LUMINANCE12:
+  case GL_LUMINANCE16:
+  case GL_ALPHA:
+  case GL_ALPHA4:
+  case GL_ALPHA8:
+  case GL_ALPHA12:
+  case GL_ALPHA16:
+  case GL_COLOR_INDEX:
+  case GL_COLOR_INDEX1_EXT:
+  case GL_COLOR_INDEX2_EXT:
+  case GL_COLOR_INDEX4_EXT:
+  case GL_COLOR_INDEX8_EXT:
+  case GL_COLOR_INDEX12_EXT:
+  case GL_COLOR_INDEX16_EXT:
+    /* Optimized for GLQuake */
+
+    if(wscale==hscale==1) {
+      (*istranslate)=GL_FALSE;
+
+      (*dest)=(unsigned short *)data;
+    } else {
+      unsigned char *srcb;
+
+      (*istranslate)=GL_TRUE;
+
+      if(!(*dest)) {
+        if(!((*dest)=src=(unsigned short *)malloc(sizeof(unsigned char)*w*h))) {
+          fprintf(stderr,"fx Driver: out of memory !\n");
+          fxCloseHardware();
+          exit(-1);
+        }
+      } else
+        src=(*dest);
+
+      srcb=(unsigned char *)src;
+
+      for(y=0;y<h;y++)
+        for(x=0;x<w;x++) {
+          idx=(x/wscale+(y/hscale)*(w/wscale));
+          srcb[x+y*w]=data[idx];
+        }
+    }
+    break;
+  case 2:
+  case GL_LUMINANCE_ALPHA:
+  case GL_LUMINANCE4_ALPHA4:
+  case GL_LUMINANCE6_ALPHA2:
+  case GL_LUMINANCE8_ALPHA8:
+  case GL_LUMINANCE12_ALPHA4:
+  case GL_LUMINANCE12_ALPHA12:
+  case GL_LUMINANCE16_ALPHA16:
+    (*istranslate)=GL_TRUE;
+
+    if(!(*dest)) {
+      if(!((*dest)=src=(unsigned short *)malloc(sizeof(unsigned short)*w*h))) {
+        fprintf(stderr,"fx Driver: out of memory !\n");
+        fxCloseHardware();
+        exit(-1);
+      }
+    } else
+      src=(*dest);
+
+    if(wscale==hscale==1) {
+      int i=0;
+      int lenght=h*w;
+      unsigned short a,l;
+
+      while(i++<lenght) {
+        l=*data++;
+        a=*data++;
+
+        *src++=(a << 8) | l;
+      }
+    } else {
+      unsigned short a,l;
+
+      for(y=0;y<h;y++)
+        for(x=0;x<w;x++) {
+          idx=(x/wscale+(y/hscale)*(w/wscale))*2;
+          l=data[idx];
+          a=data[idx+1];
+
+          src[x+y*w]=(a << 8) | l;
+        }
+    }
+    break;
+  case 3:
+  case GL_RGB:
+  case GL_R3_G3_B2:
+  case GL_RGB4:
+  case GL_RGB5:
+  case GL_RGB8:
+  case GL_RGB10:
+  case GL_RGB12:
+  case GL_RGB16:
+    (*istranslate)=GL_TRUE;
+
+    if(!(*dest)) {
+      if(!((*dest)=src=(unsigned short *)malloc(sizeof(unsigned short)*w*h))) {
+        fprintf(stderr,"fx Driver: out of memory !\n");
+        fxCloseHardware();
+        exit(-1);
+      }
+    } else
+      src=(*dest);
+
+    if(wscale==hscale==1) {
+      int i=0;
+      int lenght=h*w;
+      unsigned short r,g,b;
+
+      while(i++<lenght) {
+        r=*data++;
+        g=*data++;
+        b=*data++;
+
+        *src++=((0xf8 & r) << (11-3))  |
+          ((0xfc & g) << (5-3+1))      |
+          ((0xf8 & b) >> 3); 
+      }
+    } else {
+      unsigned short r,g,b;
+
+      for(y=0;y<h;y++)
+        for(x=0;x<w;x++) {
+          idx=(x/wscale+(y/hscale)*(w/wscale))*3;
+          r=data[idx];
+          g=data[idx+1];
+          b=data[idx+2];
+
+          src[x+y*w]=((0xf8 & r) << (11-3))  |
+            ((0xfc & g) << (5-3+1))      |
+            ((0xf8 & b) >> 3); 
+        }
+    }
+    break;
+  case 4:
+  case GL_RGBA:
+  case GL_RGBA2:
+  case GL_RGBA4:
+  case GL_RGB5_A1:
+  case GL_RGBA8:
+  case GL_RGB10_A2:
+  case GL_RGBA12:
+  case GL_RGBA16:
+    (*istranslate)=GL_TRUE;
+
+    if(!(*dest)) {
+      if(!((*dest)=src=(unsigned short *)malloc(sizeof(unsigned short)*w*h))) {
+        fprintf(stderr,"fx Driver: out of memory !\n");
+        fxCloseHardware();
+        exit(-1);
+      }
+    } else
+      src=(*dest);
+
+    if(wscale==hscale==1) {
+      int i=0;
+      int lenght=h*w;
+      unsigned short r,g,b,a;
+
+      while(i++<lenght) {
+        r=*data++;
+        g=*data++;
+        b=*data++;
+        a=*data++;
+
+        *src++=((0xf0 & a) << 8) |
+          ((0xf0 & r) << 4)      |
+          (0xf0 & g)             |
+          ((0xf0 & b) >> 4);
+      }
+    } else {
+      unsigned short r,g,b,a;
+
+      for(y=0;y<h;y++)
+        for(x=0;x<w;x++) {
+          idx=(x/wscale+(y/hscale)*(w/wscale))*4;
+          r=data[idx];
+          g=data[idx+1];
+          b=data[idx+2];
+          a=data[idx+3];
+
+          src[x+y*w]=((0xf0 & a) << 8) |
+            ((0xf0 & r) << 4)      |
+            (0xf0 & g)             |
+            ((0xf0 & b) >> 4);
+        }
+    }
+    break;
+  default:
+    fprintf(stderr,"fx Driver: wrong internalFormat in texbuildimagemap()\n");
+    fxCloseHardware();
+    exit(-1);
+    break;
+  }
+}
+
+void fxDDTexImg(GLcontext *ctx, GLenum target,
+                struct gl_texture_object *tObj, GLint level, GLint internalFormat,
+                const struct gl_texture_image *image)
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+  tfxTexInfo *ti;
+
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+     fprintf(stderr,"fxmesa: (%d) fxDDTexImg(...,%d,%x,%d,%d...)\n",tObj->Name,
+            target,internalFormat,image->Width,image->Height);
+  }
+
+  if(target!=GL_TEXTURE_2D)
+    return;
+
+  if(!tObj->DriverData)
+    tObj->DriverData=fxAllocTexObjData(fxMesa);
+
+  ti=(tfxTexInfo *)tObj->DriverData;
+
+  if(fxIsTexSupported(target,internalFormat,image)) {
+    GrTextureFormat_t gldformat;
+    tfxMipMapLevel *mml=&ti->tmi.mipmapLevel[level];
+
+    fxTexGetFormat(internalFormat,&gldformat,NULL);
+    
+    if(mml->used) {
+      if((mml->glideFormat==gldformat) &&
+         (mml->width==image->Width) &&
+         (mml->height==image->Height)) {
+        fxTexBuildImageMap(image,internalFormat,&(mml->data),
+                           &(mml->translated));
+
+        if(ti->validated && ti->tmi.isInTM)
+          fxTMReloadMipMapLevel(fxMesa,tObj,level);
+        else
+          fxTexInvalidate(ctx,tObj);
+
+        return;
+      } else {
+        if(mml->translated)
+          free(mml->data);
+        mml->data=NULL;
+      }
+    }
+
+    mml->glideFormat=gldformat;
+    mml->width=image->Width;
+    mml->height=image->Height;
+    mml->used=GL_TRUE;
+
+    fxTexBuildImageMap(image,internalFormat,&(mml->data),
+                       &(mml->translated));
+
+    fxTexInvalidate(ctx,tObj);
+  }
+#ifndef FX_SILENT
+  else
+    fprintf(stderr,"fx Driver: unsupported texture in fxDDTexImg()\n");
+#endif
+}
+
+static void fxTexBuildSubImageMap(const struct gl_texture_image *image,
+                                  GLint internalFormat,
+                                  GLint xoffset, GLint yoffset, GLint width, GLint height,
+                                  unsigned short *destimg)
+{
+  fxTexGetInfo(image->Width,image->Height,NULL,NULL,NULL,NULL,NULL,NULL,
+              NULL,NULL);
+
+  switch(internalFormat) {
+  case GL_INTENSITY:
+  case GL_INTENSITY4:
+  case GL_INTENSITY8:
+  case GL_INTENSITY12:
+  case GL_INTENSITY16:
+  case 1:
+  case GL_LUMINANCE:
+  case GL_LUMINANCE4:
+  case GL_LUMINANCE8:
+  case GL_LUMINANCE12:
+  case GL_LUMINANCE16:
+  case GL_ALPHA:
+  case GL_ALPHA4:
+  case GL_ALPHA8:
+  case GL_ALPHA12:
+  case GL_ALPHA16:
+  case GL_COLOR_INDEX:
+  case GL_COLOR_INDEX1_EXT:
+  case GL_COLOR_INDEX2_EXT:
+  case GL_COLOR_INDEX4_EXT:
+  case GL_COLOR_INDEX8_EXT:
+  case GL_COLOR_INDEX12_EXT:
+  case GL_COLOR_INDEX16_EXT:
+    {
+
+      int y;
+      unsigned char *bsrc,*bdst;
+
+      bsrc=(unsigned char *)(image->Data+(yoffset*image->Width+xoffset));
+      bdst=((unsigned char *)destimg)+(yoffset*image->Width+xoffset);
+    
+      for(y=0;y<height;y++) {
+        MEMCPY(bdst,bsrc,width);
+        bsrc += image->Width;
+        bdst += image->Width;
+      }
+    }
+    break;
+  case 2:
+  case GL_LUMINANCE_ALPHA:
+  case GL_LUMINANCE4_ALPHA4:
+  case GL_LUMINANCE6_ALPHA2:
+  case GL_LUMINANCE8_ALPHA8:
+  case GL_LUMINANCE12_ALPHA4:
+  case GL_LUMINANCE12_ALPHA12:
+  case GL_LUMINANCE16_ALPHA16:
+    {
+      int x,y;
+      unsigned char *src;
+      unsigned short *dst,a,l;
+      int simgw,dimgw;
+
+      src=(unsigned char *)(image->Data+(yoffset*image->Width+xoffset)*2);
+      dst=destimg+(yoffset*image->Width+xoffset);
+    
+      simgw=(image->Width-width)*2;
+      dimgw=image->Width-width;
+      for(y=0;y<height;y++) {
+        for(x=0;x<width;x++) {
+          l=*src++;
+          a=*src++;
+          *dst++=(a << 8) | l;
+        }
+
+        src += simgw;
+        dst += dimgw;
+      }
+    }
+    break;
+  case 3:
+  case GL_RGB:
+  case GL_R3_G3_B2:
+  case GL_RGB4:
+  case GL_RGB5:
+  case GL_RGB8:
+  case GL_RGB10:
+  case GL_RGB12:
+  case GL_RGB16:
+    {
+      int x,y;
+      unsigned char *src;
+      unsigned short *dst,r,g,b;
+      int simgw,dimgw;
+
+      src=(unsigned char *)(image->Data+(yoffset*image->Width+xoffset)*3);
+      dst=destimg+(yoffset*image->Width+xoffset);
+    
+      simgw=(image->Width-width)*3;
+      dimgw=image->Width-width;
+      for(y=0;y<height;y++) {
+        for(x=0;x<width;x++) {
+          r=*src++;
+          g=*src++;
+          b=*src++;
+          *dst++=((0xf8 & r) << (11-3))  |
+            ((0xfc & g) << (5-3+1))      |
+            ((0xf8 & b) >> 3); 
+        }
+
+        src += simgw;
+        dst += dimgw;
+      }
+    }
+    break;
+  case 4:
+  case GL_RGBA:
+  case GL_RGBA2:
+  case GL_RGBA4:
+  case GL_RGB5_A1:
+  case GL_RGBA8:
+  case GL_RGB10_A2:
+  case GL_RGBA12:
+  case GL_RGBA16:
+    {
+      int x,y;
+      unsigned char *src;
+      unsigned short *dst,r,g,b,a;
+      int simgw,dimgw;
+
+      src=(unsigned char *)(image->Data+(yoffset*image->Width+xoffset)*4);
+      dst=destimg+(yoffset*image->Width+xoffset);
+    
+      simgw=(image->Width-width)*4;
+      dimgw=image->Width-width;
+      for(y=0;y<height;y++) {
+        for(x=0;x<width;x++) {
+          r=*src++;
+          g=*src++;
+          b=*src++;
+          a=*src++;
+          *dst++=((0xf0 & a) << 8) |
+            ((0xf0 & r) << 4)      |
+            (0xf0 & g)             |
+            ((0xf0 & b) >> 4);
+        }
+
+        src += simgw;
+        dst += dimgw;
+      }
+    }
+    break;
+  default:
+    fprintf(stderr,"fx Driver: wrong internalFormat in fxTexBuildSubImageMap()\n");
+    fxCloseHardware();
+    exit(-1);
+    break;
+  }
+}
+
+void fxDDTexSubImg(GLcontext *ctx, GLenum target,
+                   struct gl_texture_object *tObj, GLint level,
+                   GLint xoffset, GLint yoffset, GLint width, GLint height,
+                   GLint internalFormat, const struct gl_texture_image *image)
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+  tfxTexInfo *ti;
+  GrTextureFormat_t gldformat;
+  int wscale,hscale;
+  tfxMipMapLevel *mml;
+
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+     fprintf(stderr,"fxmesa: (%d) fxDDTexSubImg(...,%d,%x,%d,%d...)\n",tObj->Name,
+            target,internalFormat,image->Width,image->Height);
+  }
+
+  if(target!=GL_TEXTURE_2D)
+    return;
+
+  if(!tObj->DriverData)
+    return;
+
+  ti=(tfxTexInfo *)tObj->DriverData;
+  mml=&ti->tmi.mipmapLevel[level];
+
+  fxTexGetFormat(internalFormat,&gldformat,NULL);
+
+  if(mml->glideFormat!=gldformat) {
+     if (MESA_VERBOSE&VERBOSE_DRIVER) {
+       fprintf(stderr,"fxmesa:  ti->info.format!=format in fxDDTexSubImg()\n");
+     }
+    fxDDTexImg(ctx,target,tObj,level,internalFormat,image);
+
+    return;
+  }
+
+  fxTexGetInfo(image->Width,image->Height,NULL,NULL,NULL,NULL,NULL,NULL,&wscale,&hscale);
+
+  if((wscale!=1) || (hscale!=1)) {
+     if (MESA_VERBOSE&VERBOSE_DRIVER) {
+       fprintf(stderr,"fxmesa:  (wscale!=1) || (hscale!=1) in fxDDTexSubImg()\n");
+     }
+    fxDDTexImg(ctx,target,tObj,level,internalFormat,image);
+
+    return;
+  }
+
+  if(mml->translated)
+    fxTexBuildSubImageMap(image,internalFormat,xoffset,yoffset,
+                          width,height,mml->data);
+
+  if(ti->validated && ti->tmi.isInTM)
+    fxTMReloadSubMipMapLevel(fxMesa,tObj,level,yoffset,height);
+  else
+    fxTexInvalidate(ctx,tObj);
+}
+
+
+#else
+
+
+/*
+ * Need this to provide at least one external definition.
+ */
+
+int gl_fx_dummy_function_ddtex(void)
+{
+  return 0;
+}
+
+#endif  /* FX */
diff --git a/src/mesa/drivers/glide/fxdrv.h b/src/mesa/drivers/glide/fxdrv.h
new file mode 100644 (file)
index 0000000..bb8f5b8
--- /dev/null
@@ -0,0 +1,576 @@
+/* -*- mode: C; tab-width:8;  -*-
+
+             fxdrv.h - 3Dfx VooDoo driver types
+*/
+
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * See the file fxapi.c for more informations about authors
+ *
+ */
+
+#ifndef FXDRV_H
+#define FXDRV_H
+
+/* If you comment out this define, a variable takes its place, letting
+ * you turn debugging on/off from the debugger.
+ */
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <assert.h>
+
+#if defined(__linux__)
+#include <signal.h>
+#endif
+
+#include "context.h"
+#include "macros.h"
+#include "matrix.h"
+#include "texture.h"
+#include "types.h"
+#include "vb.h"
+#include "xform.h"
+#include "clip.h"
+#include "vbrender.h"
+
+#include "GL/fxmesa.h"
+#include "fxglidew.h"
+/* use gl/gl.h GLAPI/GLAPIENTRY/GLCALLBACK in place of WINGDIAPI/APIENTRY/CALLBACK, */
+/* these are defined in mesa gl/gl.h - tjump@spgs.com */
+
+
+
+#if defined(MESA_DEBUG) && 0
+extern void fx_sanity_triangle( GrVertex *, GrVertex *, GrVertex * );
+#define grDrawTriangle fx_sanity_triangle
+#endif
+
+
+/* Define some shorter names for these things.
+ */
+#define XCOORD   GR_VERTEX_X_OFFSET
+#define YCOORD   GR_VERTEX_Y_OFFSET
+#define ZCOORD   GR_VERTEX_OOZ_OFFSET
+#define OOWCOORD GR_VERTEX_OOW_OFFSET
+
+#define RCOORD   GR_VERTEX_R_OFFSET
+#define GCOORD   GR_VERTEX_G_OFFSET
+#define BCOORD   GR_VERTEX_B_OFFSET
+#define ACOORD   GR_VERTEX_A_OFFSET
+
+#define S0COORD  GR_VERTEX_SOW_TMU0_OFFSET
+#define T0COORD  GR_VERTEX_TOW_TMU0_OFFSET
+#define S1COORD  GR_VERTEX_SOW_TMU1_OFFSET
+#define T1COORD  GR_VERTEX_TOW_TMU1_OFFSET
+
+#define CLIP_XCOORD 0          /* normal place */
+#define CLIP_YCOROD 1          /* normal place */
+#define CLIP_ZCOORD 2          /* GR_VERTEX_Z_OFFSET */
+#define CLIP_WCOORD 3          /* GR_VERTEX_R_OFFSET */
+#define CLIP_GCOORD 4          /* normal place */
+#define CLIP_BCOORD 5          /* normal place */
+#define CLIP_RCOORD 6          /* GR_VERTEX_OOZ_OFFSET */
+#define CLIP_ACOORD 7          /* normal place */
+
+
+
+
+/* Should have size == 16 * sizeof(float).
+ */
+typedef struct {
+   GLfloat f[15];              /* Same layout as GrVertex */
+   GLubyte mask;               /* Unsued  */
+   GLubyte usermask;           /* Unused */
+} fxVertex;
+
+
+
+
+#if defined(FXMESA_USE_ARGB)
+#define FXCOLOR4( c ) (      \
+  ( ((unsigned int)(c[3]))<<24 ) | \
+  ( ((unsigned int)(c[0]))<<16 ) | \
+  ( ((unsigned int)(c[1]))<<8 )  | \
+  (  (unsigned int)(c[2])) )
+  
+#else
+#ifdef __i386__
+#define FXCOLOR4( c )  (* (int *)c)
+#else
+#define FXCOLOR4( c ) (      \
+  ( ((unsigned int)(c[3]))<<24 ) | \
+  ( ((unsigned int)(c[2]))<<16 ) | \
+  ( ((unsigned int)(c[1]))<<8 )  | \
+  (  (unsigned int)(c[0])) )
+#endif
+#endif
+
+#define FX_VB_COLOR(fxm, color)                        \
+do {                                           \
+  if (sizeof(GLint) == 4*sizeof(GLubyte)) {    \
+     if (fxm->constColor != *(GLuint*)color) { \
+       fxm->constColor = *(GLuint*)color;      \
+       grConstantColorValue(FXCOLOR4(color));  \
+     }                                         \
+  } else {                                     \
+     grConstantColorValue(FXCOLOR4(color));    \
+  }                                            \
+} while (0)
+
+#define GOURAUD(x) {                                   \
+  GLubyte *col = VB->ColorPtr->data[(x)];              \
+  gWin[(x)].v.r=UBYTE_COLOR_TO_FLOAT_255_COLOR(col[0]);        \
+  gWin[(x)].v.g=UBYTE_COLOR_TO_FLOAT_255_COLOR(col[1]);        \
+  gWin[(x)].v.b=UBYTE_COLOR_TO_FLOAT_255_COLOR(col[2]);        \
+  gWin[(x)].v.a=UBYTE_COLOR_TO_FLOAT_255_COLOR(col[3]);        \
+}
+
+#define GOURAUD2(v, c) {                       \
+  GLubyte *col = c;                            \
+  v->r=UBYTE_COLOR_TO_FLOAT_255_COLOR(col[0]); \
+  v->g=UBYTE_COLOR_TO_FLOAT_255_COLOR(col[1]); \
+  v->b=UBYTE_COLOR_TO_FLOAT_255_COLOR(col[2]); \
+  v->a=UBYTE_COLOR_TO_FLOAT_255_COLOR(col[3]); \
+}
+
+
+/* Mergable items first
+ */
+#define SETUP_RGBA 0x1
+#define SETUP_TMU0 0x2
+#define SETUP_TMU1 0x4
+#define SETUP_XY   0x8
+#define SETUP_Z    0x10
+#define SETUP_W    0x20
+
+#define MAX_MERGABLE 0x8
+
+
+#define FX_NUM_TMU 2
+
+#define FX_TMU0      GR_TMU0
+#define FX_TMU1      GR_TMU1
+#define FX_TMU_SPLIT 98
+#define FX_TMU_BOTH  99
+#define FX_TMU_NONE  100
+
+/* Used for fxMesa->lastUnitsMode */
+
+#define FX_UM_NONE                  0x00000000
+
+#define FX_UM_E0_REPLACE            0x00000001
+#define FX_UM_E0_MODULATE           0x00000002
+#define FX_UM_E0_DECAL              0x00000004
+#define FX_UM_E0_BLEND              0x00000008
+
+#define FX_UM_E1_REPLACE            0x00000010
+#define FX_UM_E1_MODULATE           0x00000020
+#define FX_UM_E1_DECAL              0x00000040
+#define FX_UM_E1_BLEND              0x00000080
+
+#define FX_UM_E_ENVMODE             0x000000ff
+
+#define FX_UM_E0_ALPHA              0x00000100
+#define FX_UM_E0_LUMINANCE          0x00000200
+#define FX_UM_E0_LUMINANCE_ALPHA    0x00000400
+#define FX_UM_E0_INTENSITY          0x00000800
+#define FX_UM_E0_RGB                0x00001000
+#define FX_UM_E0_RGBA               0x00002000
+
+#define FX_UM_E1_ALPHA              0x00004000
+#define FX_UM_E1_LUMINANCE          0x00008000
+#define FX_UM_E1_LUMINANCE_ALPHA    0x00010000
+#define FX_UM_E1_INTENSITY          0x00020000
+#define FX_UM_E1_RGB                0x00040000
+#define FX_UM_E1_RGBA               0x00080000
+
+#define FX_UM_E_IFMT                0x000fff00
+
+#define FX_UM_COLOR_ITERATED        0x00100000
+#define FX_UM_COLOR_CONSTANT        0x00200000
+#define FX_UM_ALPHA_ITERATED        0x00400000
+#define FX_UM_ALPHA_CONSTANT        0x00800000
+
+typedef void (*tfxRenderVBFunc)(GLcontext *);
+
+typedef struct tfxTMFreeListNode {
+  struct tfxTMFreeListNode *next;
+  FxU32 startAddress, endAddress;
+} tfxTMFreeNode;
+
+typedef struct tfxTMAllocListNode {
+  struct tfxTMAllocListNode *next;
+  FxU32 startAddress, endAddress;
+  struct gl_texture_object *tObj;
+} tfxTMAllocNode;
+
+typedef struct {
+  GLsizei width, height;
+  GLint glideFormat;
+
+  unsigned short *data;
+  GLboolean translated, used;
+} tfxMipMapLevel;
+
+typedef struct {
+  GLuint lastTimeUsed;
+
+  FxU32 whichTMU;
+
+  tfxTMAllocNode *tm[FX_NUM_TMU];
+
+  tfxMipMapLevel mipmapLevel[MAX_TEXTURE_LEVELS];
+  GLboolean isInTM;
+} tfxTMInfo;
+
+typedef struct {
+  tfxTMInfo tmi;
+
+  GLint minLevel, maxLevel;
+  GLint baseLevelInternalFormat;
+
+  GrTexInfo info;
+
+  GrTextureFilterMode_t minFilt;
+  GrTextureFilterMode_t maxFilt;
+  FxBool LODblend;
+
+  GrTextureClampMode_t sClamp;
+  GrTextureClampMode_t tClamp;
+
+  GrMipMapMode_t mmMode;
+
+  GLfloat sScale, tScale;
+  GLint int_sScale, int_tScale;        /* x86 floating point trick for
+                                * multiplication by powers of 2.  
+                                * Used in fxfasttmp.h
+                                */
+
+  GuTexPalette palette;
+
+  GLboolean fixedPalette;
+  GLboolean validated;
+} tfxTexInfo;
+
+typedef struct {
+  GLuint swapBuffer;
+  GLuint reqTexUpload;
+  GLuint texUpload;
+  GLuint memTexUpload;
+} tfxStats;
+
+
+typedef void (*tfxTriViewClipFunc)( struct vertex_buffer *VB, 
+                                   GLuint v[],
+                                   GLubyte mask );
+
+typedef void (*tfxTriClipFunc)( struct vertex_buffer *VB, 
+                               GLuint v[],
+                               GLuint mask );
+
+
+typedef void (*tfxLineClipFunc)( struct vertex_buffer *VB, 
+                                GLuint v1, GLuint v2,
+                                GLubyte mask );
+
+
+extern tfxTriViewClipFunc fxTriViewClipTab[0x8];
+extern tfxTriClipFunc fxTriClipStrideTab[0x8];
+extern tfxLineClipFunc fxLineClipTab[0x8];
+
+typedef struct {
+  /* Alpha test */
+
+  GLboolean alphaTestEnabled;
+  GrCmpFnc_t alphaTestFunc;
+  GrAlpha_t alphaTestRefValue;
+
+  /* Blend function */
+
+  GLboolean blendEnabled;
+  GrAlphaBlendFnc_t blendSrcFuncRGB;
+  GrAlphaBlendFnc_t blendDstFuncRGB;
+  GrAlphaBlendFnc_t blendSrcFuncAlpha;
+  GrAlphaBlendFnc_t blendDstFuncAlpha;
+
+  /* Depth test */
+
+  GLboolean depthTestEnabled;
+  GLboolean depthMask;
+  GrCmpFnc_t depthTestFunc;
+} tfxUnitsState;
+
+
+/* Flags for render_index.
+ */
+#define FX_OFFSET             0x1
+#define FX_TWOSIDE            0x2
+#define FX_FRONT_BACK         0x4 
+#define FX_FLAT               0x8
+#define FX_ANTIALIAS          0x10 
+#define FX_FALLBACK           0x20 
+
+
+/* Flags for fxMesa->new_state
+ */
+#define FX_NEW_TEXTURING      0x1
+#define FX_NEW_BLEND          0x2
+#define FX_NEW_ALPHA          0x4
+#define FX_NEW_DEPTH          0x8
+#define FX_NEW_FOG            0x10
+#define FX_NEW_SCISSOR        0x20
+#define FX_NEW_COLOR_MASK     0x40
+#define FX_NEW_CULL           0x80
+
+/* FX struct stored in VB->driver_data.
+ */
+struct tfxMesaVertexBuffer {
+   GLvector1ui clipped_elements;
+
+   fxVertex *verts;
+   fxVertex *last_vert;
+   void *vert_store;
+#if defined(FX_GLIDE3)
+   GrVertex **triangle_b;      /* Triangle buffer */
+   GrVertex **strips_b;                /* Strips buffer */
+#endif
+
+   GLuint size;
+};
+
+#define FX_DRIVER_DATA(vb) ((struct tfxMesaVertexBuffer *)((vb)->driver_data))
+#define FX_CONTEXT(ctx) ((struct tfxMesaContext *)((ctx)->DriverCtx))
+#define FX_TEXTURE_DATA(t) ((tfxTexInfo *) ((t)->Current->DriverData))
+
+struct tfxMesaContext {
+  GuTexPalette glbPalette;
+
+  GLcontext *glCtx;              /* the core Mesa context */
+  GLvisual *glVis;               /* describes the color buffer */
+  GLframebuffer *glBuffer;       /* the ancillary buffers */
+
+  GLint board;                   /* the board used for this context */
+  GLint width, height;           /* size of color buffer */
+
+  GrBuffer_t currentFB;
+
+  GrColor_t color;
+  GrColor_t clearC;
+  GrAlpha_t clearA;
+  GLuint constColor;
+
+  tfxUnitsState unitsState;
+  tfxUnitsState restoreUnitsState; /* saved during multipass */
+
+
+  GLuint tmu_source[FX_NUM_TMU];
+  GLuint tex_dest[MAX_TEXTURE_UNITS];
+  GLuint setupindex;
+  GLuint partial_setup_index;
+  GLuint setupdone;
+  GLuint mergeindex;
+  GLuint mergeinputs;
+  GLuint render_index;
+  GLuint last_tri_caps;
+  GLuint stw_hint_state;               /* for grHints */
+  GLuint is_in_hardware;
+  GLuint new_state;   
+  GLuint using_fast_path, passes, multipass;
+
+  tfxLineClipFunc clip_line;
+  tfxTriClipFunc clip_tri_stride;
+  tfxTriViewClipFunc view_clip_tri;
+
+
+  /* Texture Memory Manager Data */
+
+  GLuint texBindNumber;
+  GLint tmuSrc;
+  GLuint lastUnitsMode;
+  GLuint freeTexMem[FX_NUM_TMU];
+  tfxTMFreeNode *tmFree[FX_NUM_TMU];
+  tfxTMAllocNode *tmAlloc[FX_NUM_TMU];
+
+  GLenum fogTableMode;
+  GLfloat fogDensity;
+  GrFog_t *fogTable;
+
+  /* Acc. functions */
+
+  points_func PointsFunc;
+  line_func LineFunc;
+  triangle_func TriangleFunc;
+  quad_func QuadFunc;
+
+  render_func **RenderVBTables;
+
+  tfxStats stats;
+
+  void *state;
+
+  /* Options */
+
+  GLboolean verbose;
+  GLboolean haveTwoTMUs;       /* True if we really have 2 tmu's  */
+  GLboolean emulateTwoTMUs;    /* True if we present 2 tmu's to mesa.  */
+  GLboolean haveAlphaBuffer;
+  GLboolean haveDoubleBuffer;
+  GLboolean haveGlobalPaletteTexture;
+  GLint swapInterval;
+  GLint maxPendingSwapBuffers;
+  
+  FX_GrContext_t glideContext;
+};
+
+typedef void (*tfxSetupFunc)(struct vertex_buffer *, GLuint, GLuint);
+
+extern GrHwConfiguration glbHWConfig;
+extern int glbCurrentBoard;
+
+extern void fxSetupFXUnits(GLcontext *);
+extern void fxSetupDDPointers(GLcontext *);
+extern void fxDDSetNearFar(GLcontext *, GLfloat, GLfloat);
+
+extern void fxDDSetupInit();
+extern void fxDDCvaInit();
+extern void fxDDTrifuncInit();
+extern void fxDDFastPathInit();
+
+extern void fxDDChooseRenderState( GLcontext *ctx );
+
+extern void fxRenderClippedLine( struct vertex_buffer *VB, 
+                                GLuint v1, GLuint v2 );
+
+extern void fxRenderClippedTriangle( struct vertex_buffer *VB,
+                                    GLuint n, GLuint vlist[] );
+
+
+extern tfxSetupFunc fxDDChooseSetupFunction(GLcontext *);
+
+extern points_func fxDDChoosePointsFunction(GLcontext *);
+extern line_func fxDDChooseLineFunction(GLcontext *);
+extern triangle_func fxDDChooseTriangleFunction(GLcontext *);
+extern quad_func fxDDChooseQuadFunction(GLcontext *);
+extern render_func **fxDDChooseRenderVBTables(GLcontext *);
+
+extern void fxDDRenderInit(GLcontext *);
+extern void fxDDClipInit();
+
+extern void fxUpdateDDSpanPointers(GLcontext *);
+extern void fxSetupDDSpanPointers(GLcontext *);
+
+extern void fxDDBufferSize(GLcontext *, GLuint *, GLuint *);
+
+extern void fxDDTexEnv(GLcontext *, GLenum, const GLfloat *);
+extern void fxDDTexImg(GLcontext *, GLenum, struct gl_texture_object *,
+                      GLint, GLint, const struct gl_texture_image *);
+extern void fxDDTexParam(GLcontext *, GLenum, struct gl_texture_object *,
+                        GLenum, const GLfloat *);
+extern void fxDDTexBind(GLcontext *, GLenum, struct gl_texture_object *);
+extern void fxDDTexDel(GLcontext *, struct gl_texture_object *);
+extern void fxDDTexPalette(GLcontext *, struct gl_texture_object *);
+extern void fxDDTexuseGlbPalette(GLcontext *, GLboolean);
+extern void fxDDTexSubImg(GLcontext *, GLenum, struct gl_texture_object *, GLint,
+                         GLint, GLint, GLint, GLint, GLint, const struct gl_texture_image *);
+extern void fxDDTexUseGlbPalette(GLcontext *, GLboolean);
+
+extern void fxDDEnable(GLcontext *, GLenum, GLboolean);
+extern void fxDDAlphaFunc(GLcontext *, GLenum, GLclampf);
+extern void fxDDBlendFunc(GLcontext *, GLenum, GLenum);
+extern void fxDDDepthMask(GLcontext *, GLboolean);
+extern void fxDDDepthFunc(GLcontext *, GLenum);
+
+extern void fxDDRegisterVB( struct vertex_buffer *VB );
+extern void fxDDUnregisterVB( struct vertex_buffer *VB );
+extern void fxDDResizeVB( struct tfxMesaVertexBuffer *fvb, GLuint size );
+
+extern void fxDDCheckMergeAndRender( GLcontext *ctx, 
+                                    struct gl_pipeline_stage *d );
+
+extern void fxDDMergeAndRender( struct vertex_buffer *VB );
+
+extern void fxDDCheckPartialRasterSetup( GLcontext *ctx, 
+                                        struct gl_pipeline_stage *d );
+
+extern void fxDDPartialRasterSetup( struct vertex_buffer *VB );
+
+extern void fxDDDoRasterSetup( struct vertex_buffer *VB );
+
+extern GLuint fxDDRegisterPipelineStages( struct gl_pipeline_stage *out,
+                                         const struct gl_pipeline_stage *in,
+                                         GLuint nr );
+
+extern GLboolean fxDDBuildPrecalcPipeline( GLcontext *ctx );
+
+extern void fxDDOptimizePrecalcPipeline( GLcontext *ctx, 
+                                        struct gl_pipeline *pipe );
+
+extern void fxDDRenderElementsDirect( struct vertex_buffer *VB );
+extern void fxDDRenderVBIndirectDirect( struct vertex_buffer *VB );
+
+extern void fxDDInitExtensions( GLcontext *ctx );
+
+extern void fxTMInit(fxMesaContext);
+extern void fxTMClose(fxMesaContext);
+extern void fxTMMoveInTM(fxMesaContext, struct gl_texture_object *, GLint);
+extern void fxTMMoveOutTM(fxMesaContext, struct gl_texture_object *);
+extern void fxTMFreeTexture(fxMesaContext, struct gl_texture_object *);
+extern void fxTMReloadMipMapLevel(fxMesaContext, struct gl_texture_object *, GLint);
+extern void fxTMReloadSubMipMapLevel(fxMesaContext, struct gl_texture_object *,
+                                    GLint, GLint, GLint);
+
+extern void fxTexGetFormat(GLenum, GrTextureFormat_t *, GLint *);
+extern int fxTexGetInfo(int, int, GrLOD_t *, GrAspectRatio_t *,
+                       float *, float *, int *, int *, int *, int *);
+
+extern void fxDDScissor( GLcontext *ctx,
+                             GLint x, GLint y, GLsizei w, GLsizei h );
+extern void fxDDFogfv( GLcontext *ctx, GLenum pname, const GLfloat *params );
+extern GLboolean fxDDColorMask(GLcontext *ctx, 
+                              GLboolean r, GLboolean g, 
+                              GLboolean b, GLboolean a );
+
+extern GLuint fxDDDepthTestSpanGeneric(GLcontext *ctx,
+                                       GLuint n, GLint x, GLint y, 
+                                      const GLdepth z[],
+                                       GLubyte mask[]);
+
+extern void fxDDDepthTestPixelsGeneric(GLcontext* ctx,
+                                       GLuint n, 
+                                      const GLint x[], const GLint y[],
+                                       const GLdepth z[], GLubyte mask[]);
+
+extern void fxDDReadDepthSpanFloat(GLcontext *ctx,
+                                  GLuint n, GLint x, GLint y, GLfloat depth[]);
+
+extern void fxDDReadDepthSpanInt(GLcontext *ctx,
+                                GLuint n, GLint x, GLint y, GLdepth depth[]);
+
+
+extern void fxDDFastPath( struct vertex_buffer *VB );
+
+extern void fxDDShadeModel(GLcontext *ctx, GLenum mode);
+
+extern void fxDDCullFace(GLcontext *ctx, GLenum mode);
+extern void fxDDFrontFace(GLcontext *ctx, GLenum mode);
+
+
+
+
+#endif
diff --git a/src/mesa/drivers/glide/fxglidew.c b/src/mesa/drivers/glide/fxglidew.c
new file mode 100644 (file)
index 0000000..3ced928
--- /dev/null
@@ -0,0 +1,247 @@
+/* $Id: fxglidew.c,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifdef HAVE_CONFIG_H
+#include "conf.h"
+#endif
+
+#if defined(FX)
+#include "glide.h"
+#include "fxglidew.h"
+#include "fxdrv.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+
+FxI32 FX_grGetInteger(FxU32 pname)
+{
+#if !defined(FX_GLIDE3)
+  switch (pname) 
+  {
+    case FX_FOG_TABLE_ENTRIES:
+       return GR_FOG_TABLE_SIZE;
+    case FX_GLIDE_STATE_SIZE:
+       return sizeof(GrState);
+    case FX_LFB_PIXEL_PIPE:
+       return FXFALSE;
+    case FX_PENDING_BUFFERSWAPS:
+       return grBufferNumPending();
+    default:
+       if (MESA_VERBOSE&VERBOSE_DRIVER) {
+          fprintf(stderr,"Wrong parameter in FX_grGetInteger!\n");
+          return -1;
+       }
+  }
+#else
+  FxU32 grname;
+  FxI32 result;
+  
+  switch (pname)
+  {
+     case FX_FOG_TABLE_ENTRIES:
+     case FX_GLIDE_STATE_SIZE:
+     case FX_LFB_PIXEL_PIPE:
+     case FX_PENDING_BUFFERSWAPS:
+       grname = pname;
+       break;
+     default:
+       if (MESA_VERBOSE&VERBOSE_DRIVER) {
+          fprintf(stderr,"Wrong parameter in FX_grGetInteger!\n");
+          return -1;
+       }
+  }
+  
+  grGet(grname,4,&result);
+  return result;
+#endif
+}
+
+
+
+#if defined(FX_GLIDE3)
+
+void FX_grGammaCorrectionValue(float val)
+{
+  (void)val;
+/* ToDo */
+}
+
+void FX_grSstControl(int par)
+{
+  (void)par;
+  /* ToDo */
+}
+int FX_getFogTableSize(void)
+{
+   int result;
+   grGet(GR_FOG_TABLE_ENTRIES,sizeof(int),(void*)&result);
+   return result; 
+}
+
+int FX_getGrStateSize(void)
+{
+   int result;
+   grGet(GR_GLIDE_STATE_SIZE,sizeof(int),(void*)&result);
+   
+   return result;
+   
+}
+int FX_grBufferNumPending()
+{
+   int result;
+   grGet(GR_PENDING_BUFFERSWAPS,sizeof(int),(void*)&result);
+   
+   return result;
+}
+
+int FX_grSstScreenWidth()
+{
+   FxI32 result[4];
+   
+   grGet(GR_VIEWPORT,sizeof(FxI32)*4,result);
+   
+   return result[2];
+}
+
+int FX_grSstScreenHeight()
+{
+   FxI32 result[4];
+   
+   grGet(GR_VIEWPORT,sizeof(FxI32)*4,result);
+   
+   return result[3];
+}
+
+void FX_grGlideGetVersion(char *buf)
+{
+   strcpy(buf,grGetString(GR_VERSION));
+}
+
+void FX_grSstPerfStats(GrSstPerfStats_t *st)
+{
+  /* ToDo */
+  st->pixelsIn = 0;
+  st->chromaFail = 0;
+  st->zFuncFail = 0;
+  st->aFuncFail = 0;
+  st->pixelsOut = 0;
+}
+
+void FX_grAADrawLine(GrVertex *a,GrVertex *b)
+{
+   /* ToDo */
+   grDrawLine(a,b);
+}
+void FX_grAADrawPoint(GrVertex *a)
+{
+  grDrawPoint(a);
+}
+
+void FX_setupGrVertexLayout(void)
+{
+   grReset(GR_VERTEX_PARAMETER);
+   
+   grCoordinateSpace(GR_WINDOW_COORDS);
+   grVertexLayout(GR_PARAM_XY,         GR_VERTEX_X_OFFSET << 2,        GR_PARAM_ENABLE);
+   grVertexLayout(GR_PARAM_RGB,        GR_VERTEX_R_OFFSET << 2,        GR_PARAM_ENABLE);
+ /*  grVertexLayout(GR_PARAM_Z,        GR_VERTEX_Z_OFFSET << 2,        GR_PARAM_ENABLE); */
+   grVertexLayout(GR_PARAM_A,          GR_VERTEX_A_OFFSET << 2,        GR_PARAM_ENABLE);
+   grVertexLayout(GR_PARAM_Q,          GR_VERTEX_OOW_OFFSET << 2,      GR_PARAM_ENABLE);
+   grVertexLayout(GR_PARAM_Z,           GR_VERTEX_OOZ_OFFSET << 2,     GR_PARAM_ENABLE);
+   grVertexLayout(GR_PARAM_ST0,        GR_VERTEX_SOW_TMU0_OFFSET << 2, GR_PARAM_ENABLE);       
+   grVertexLayout(GR_PARAM_Q0,         GR_VERTEX_OOW_TMU0_OFFSET << 2, GR_PARAM_DISABLE); 
+   grVertexLayout(GR_PARAM_ST1,        GR_VERTEX_SOW_TMU1_OFFSET << 2, GR_PARAM_DISABLE);      
+   grVertexLayout(GR_PARAM_Q1,         GR_VERTEX_OOW_TMU1_OFFSET << 2, GR_PARAM_DISABLE);      
+}
+
+void FX_grHints(GrHint_t hintType, FxU32 hintMask)
+{
+   switch(hintType) {
+      case GR_HINT_STWHINT:
+      {
+        if (hintMask & GR_STWHINT_W_DIFF_TMU0)
+           grVertexLayout(GR_PARAM_Q0, GR_VERTEX_OOW_TMU0_OFFSET << 2,         GR_PARAM_ENABLE);
+        else
+           grVertexLayout(GR_PARAM_Q0,GR_VERTEX_OOW_TMU0_OFFSET << 2,  GR_PARAM_DISABLE);
+           
+        if (hintMask & GR_STWHINT_ST_DIFF_TMU1)
+            grVertexLayout(GR_PARAM_ST1,GR_VERTEX_SOW_TMU1_OFFSET << 2, GR_PARAM_ENABLE);
+        else
+            grVertexLayout(GR_PARAM_ST1,GR_VERTEX_SOW_TMU1_OFFSET << 2, GR_PARAM_DISABLE);
+        
+        if (hintMask & GR_STWHINT_W_DIFF_TMU1)
+            grVertexLayout(GR_PARAM_Q1,GR_VERTEX_OOW_TMU1_OFFSET << 2, GR_PARAM_ENABLE);
+        else
+            grVertexLayout(GR_PARAM_Q1,GR_VERTEX_OOW_TMU1_OFFSET << 2, GR_PARAM_DISABLE);
+       
+      }
+   }
+}
+int FX_grSstQueryHardware(GrHwConfiguration *config)
+{
+   int i,j;
+   int numFB;
+   grGet(GR_NUM_BOARDS,4,(void*)&(config->num_sst));
+   if (config->num_sst == 0)
+       return 0;
+   for (i = 0; i< config->num_sst; i++)
+   {
+      config->SSTs[i].type = GR_SSTTYPE_VOODOO;
+      grSstSelect(i);
+      grGet(GR_MEMORY_FB,4,(void*)&(config->SSTs[i].sstBoard.VoodooConfig.fbRam));
+      config->SSTs[i].sstBoard.VoodooConfig.fbRam/= 1024*1024;
+      
+      grGet(GR_NUM_TMU,4,(void*)&(config->SSTs[i].sstBoard.VoodooConfig.nTexelfx));
+   
+      
+      grGet(GR_NUM_FB,4,(void*)&numFB);
+      if (numFB > 1)
+         config->SSTs[i].sstBoard.VoodooConfig.sliDetect = FXTRUE;
+      else
+         config->SSTs[i].sstBoard.VoodooConfig.sliDetect = FXFALSE;
+      for (j = 0; j < config->SSTs[i].sstBoard.VoodooConfig.nTexelfx; j++)
+      {
+        grGet(GR_MEMORY_TMU,4,(void*)&(config->SSTs[i].sstBoard.VoodooConfig.tmuConfig[i].tmuRam));
+      }
+   }
+   return 1;
+}
+
+
+#endif 
+#else
+
+/*
+ * Need this to provide at least one external definition.
+ */
+
+int gl_fx_dummy_function_glidew(void)
+{
+  return 0;
+}
+
+#endif /* FX */
diff --git a/src/mesa/drivers/glide/fxglidew.h b/src/mesa/drivers/glide/fxglidew.h
new file mode 100644 (file)
index 0000000..17f3956
--- /dev/null
@@ -0,0 +1,358 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef __FX_GLIDE_WARPER__
+#define __FX_GLIDE_WARPER__
+
+#include <glide.h>
+
+/* 
+ * General context: 
+ */
+#if !defined(FX_GLIDE3)
+     typedef FxU32      FX_GrContext_t;        /* Not used in Glide2 */
+#else
+     typedef GrContext_t FX_GrContext_t;
+#endif
+
+/* 
+ * Glide3 emulation on Glide2: 
+ */
+#if !defined(FX_GLIDE3)
+       /* Constanst for FX_grGetInteger( ) */
+       #define FX_FOG_TABLE_ENTRIES            0x0004    /* The number of entries in the hardware fog table. */
+       #define FX_GLIDE_STATE_SIZE             0x0006    /* Size of buffer, in bytes, needed to save Glide state. */
+       #define FX_LFB_PIXEL_PIPE               0x0009    /* 1 if LFB writes can go through the 3D pixel pipe. */               
+       #define FX_PENDING_BUFFERSWAPS          0x0014    /* The number of buffer swaps pending. */
+#else
+        #define FX_FOG_TABLE_ENTRIES            GR_FOG_TABLE_ENTRIES  
+       #define FX_GLIDE_STATE_SIZE             GR_GLIDE_STATE_SIZE
+       #define FX_LFB_PIXEL_PIPE               GR_LFB_PIXEL_PIPE               
+       #define FX_PENDING_BUFFERSWAPS          GR_PENDING_BUFFERSWAPS  
+#endif
+
+/*
+ * Genral warper functions for Glide2/Glide3:
+ */ 
+extern FxI32 FX_grGetInteger(FxU32 pname);
+
+/*
+ * Glide2 emulation on Glide3:
+ */
+#if defined(FX_GLIDE3)
+
+#define GR_ASPECT_1x1 GR_ASPECT_LOG2_1x1
+#define GR_ASPECT_2x1 GR_ASPECT_LOG2_2x1
+#define GR_ASPECT_4x1 GR_ASPECT_LOG2_4x1
+#define GR_ASPECT_8x1 GR_ASPECT_LOG2_8x1
+#define GR_ASPECT_1x2 GR_ASPECT_LOG2_1x2
+#define GR_ASPECT_1x4 GR_ASPECT_LOG2_1x4
+#define GR_ASPECT_1x8 GR_ASPECT_LOG2_1x8
+
+#define GR_LOD_256     GR_LOD_LOG2_256
+#define GR_LOD_128     GR_LOD_LOG2_128
+#define GR_LOD_64      GR_LOD_LOG2_64
+#define GR_LOD_32      GR_LOD_LOG2_32  
+#define GR_LOD_16      GR_LOD_LOG2_16
+#define GR_LOD_8       GR_LOD_LOG2_8
+#define GR_LOD_4       GR_LOD_LOG2_4
+#define GR_LOD_2       GR_LOD_LOG2_2
+#define GR_LOD_1       GR_LOD_LOG2_1
+
+#define GR_FOG_WITH_TABLE GR_FOG_WITH_TABLE_ON_Q
+
+typedef int GrSstType;
+
+#define MAX_NUM_SST            4
+
+#define GR_SSTTYPE_VOODOO    0
+#define GR_SSTTYPE_SST96     1
+#define GR_SSTTYPE_AT3D      2
+#define GR_SSTTYPE_Voodoo2   3
+
+typedef struct GrTMUConfig_St {
+  int    tmuRev;                /* Rev of Texelfx chip */
+  int    tmuRam;                /* 1, 2, or 4 MB */
+} GrTMUConfig_t;
+
+typedef struct GrVoodooConfig_St {
+  int    fbRam;                         /* 1, 2, or 4 MB */
+  int    fbiRev;                        /* Rev of Pixelfx chip */
+  int    nTexelfx;                      /* How many texelFX chips are there? */
+  FxBool sliDetect;                     /* Is it a scan-line interleaved board? */
+  GrTMUConfig_t tmuConfig[GLIDE_NUM_TMU];   /* Configuration of the Texelfx chips */
+} GrVoodooConfig_t;
+
+typedef struct GrSst96Config_St {
+  int   fbRam;                  /* How much? */
+  int   nTexelfx;
+  GrTMUConfig_t tmuConfig;
+} GrSst96Config_t;
+
+typedef GrVoodooConfig_t GrVoodoo2Config_t;
+
+typedef struct GrAT3DConfig_St {
+  int   rev;
+} GrAT3DConfig_t;
+
+typedef struct {
+  int num_sst;                  /* # of HW units in the system */
+  struct {
+    GrSstType type;             /* Which hardware is it? */
+    union SstBoard_u {
+      GrVoodooConfig_t  VoodooConfig;
+      GrSst96Config_t   SST96Config;
+      GrAT3DConfig_t    AT3DConfig;
+      GrVoodoo2Config_t Voodoo2Config;
+    } sstBoard;
+  } SSTs[MAX_NUM_SST];          /* configuration for each board */
+} GrHwConfiguration;
+
+typedef FxU32 GrHint_t;
+#define GR_HINTTYPE_MIN                 0
+#define GR_HINT_STWHINT                 0
+
+typedef FxU32 GrSTWHint_t;
+#define GR_STWHINT_W_DIFF_FBI   FXBIT(0)
+#define GR_STWHINT_W_DIFF_TMU0  FXBIT(1)
+#define GR_STWHINT_ST_DIFF_TMU0 FXBIT(2)
+#define GR_STWHINT_W_DIFF_TMU1  FXBIT(3)
+#define GR_STWHINT_ST_DIFF_TMU1 FXBIT(4)
+#define GR_STWHINT_W_DIFF_TMU2  FXBIT(5)
+#define GR_STWHINT_ST_DIFF_TMU2 FXBIT(6)
+
+#define GR_CONTROL_ACTIVATE            1
+#define GR_CONTROL_DEACTIVATE          0
+
+#define GrState                                void
+
+/*
+** move the vertex layout defintion to application
+*/
+typedef struct {
+  float  sow;                   /* s texture ordinate (s over w) */
+  float  tow;                   /* t texture ordinate (t over w) */  
+  float  oow;                   /* 1/w (used mipmapping - really 0xfff/w) */
+}  GrTmuVertex;
+
+typedef struct
+{
+  float x, y;         /* X and Y in screen space */
+  float ooz;          /* 65535/Z (used for Z-buffering) */
+  float oow;          /* 1/W (used for W-buffering, texturing) */
+  float r, g, b, a;   /* R, G, B, A [0..255.0] */
+  float z;            /* Z is ignored */
+  GrTmuVertex  tmuvtx[GLIDE_NUM_TMU];
+} GrVertex;
+
+#define GR_VERTEX_X_OFFSET              0
+#define GR_VERTEX_Y_OFFSET              1
+#define GR_VERTEX_OOZ_OFFSET            2
+#define GR_VERTEX_OOW_OFFSET            3
+#define GR_VERTEX_R_OFFSET              4
+#define GR_VERTEX_G_OFFSET              5
+#define GR_VERTEX_B_OFFSET              6
+#define GR_VERTEX_A_OFFSET              7
+#define GR_VERTEX_Z_OFFSET              8
+#define GR_VERTEX_SOW_TMU0_OFFSET       9
+#define GR_VERTEX_TOW_TMU0_OFFSET       10
+#define GR_VERTEX_OOW_TMU0_OFFSET       11
+#define GR_VERTEX_SOW_TMU1_OFFSET       12
+#define GR_VERTEX_TOW_TMU1_OFFSET       13
+#define GR_VERTEX_OOW_TMU1_OFFSET       14
+
+#endif
+
+
+/*
+ * Glide2 functions for Glide3
+ */
+#if defined(FX_GLIDE3)
+#define FX_grTexDownloadTable(TMU,type,data)           grTexDownloadTable(type,data)
+#else
+#define FX_grTexDownloadTable(TMU,type,data)           grTexDownloadTable(TMU,type,data)
+#endif
+
+/*
+ * Flush
+ */
+#if defined(FX_GLIDE3)
+#define FX_grFlush             grFlush
+#else
+#define FX_grFlush             grSstIdle
+#endif 
+/*
+ * Write region: ToDo possible exploit the PixelPipe parameter.
+ */
+#if defined(FX_GLIDE3)
+#define FX_grLfbWriteRegion(dst_buffer,dst_x,dst_y,src_format,src_width,src_height,src_stride,src_data)        \
+       grLfbWriteRegion(dst_buffer,dst_x,dst_y,src_format,src_width,src_height,FXFALSE,src_stride,src_data)
+#else
+#define FX_grLfbWriteRegion(dst_buffer,dst_x,dst_y,src_format,src_width,src_height,src_stride,src_data)        \
+       grLfbWriteRegion(dst_buffer,dst_x,dst_y,src_format,src_width,src_height,src_stride,src_data)
+#endif
+/*
+ * For Lod/LodLog2 conversion.
+ */
+#if defined(FX_GLIDE3)
+       #define FX_largeLodLog2(info)           (info).largeLodLog2
+#else
+       #define FX_largeLodLog2(info)           (info).largeLod 
+#endif
+
+#if defined(FX_GLIDE3)
+       #define FX_aspectRatioLog2(info)                (info).aspectRatioLog2
+#else
+       #define FX_aspectRatioLog2(info)                (info).aspectRatio
+#endif
+
+#if defined(FX_GLIDE3)
+       #define FX_smallLodLog2(info)           (info).smallLodLog2
+#else
+       #define FX_smallLodLog2(info)           (info).smallLod
+#endif
+
+#if defined(FX_GLIDE3)
+       #define FX_lodToValue(val)              ((int)(GR_LOD_256-val))
+#else
+       #define FX_lodToValue(val)              ((int)(val))
+#endif
+
+#if defined(FX_GLIDE3)
+       #define FX_largeLodValue(info)          ((int)(GR_LOD_256-(info).largeLodLog2))
+#else
+       #define FX_largeLodValue(info)          ((int)(info).largeLod)
+#endif
+
+#if defined(FX_GLIDE3)
+       #define FX_smallLodValue(info)          ((int)(GR_LOD_256-(info).smallLodLog2))
+#else
+       #define FX_smallLodValue(info)          ((int)(info).smallLod)
+#endif
+
+#if defined(FX_GLIDE3)
+       #define FX_valueToLod(val)              ((GrLOD_t)(GR_LOD_256-val))
+#else
+       #define FX_valueToLod(val)              ((GrLOD_t)(val))
+#endif
+
+/*
+ * ScreenWidth/Height stuff.
+ */
+#if defined(FX_GLIDE3)
+       extern int FX_grSstScreenWidth();
+       extern int FX_grSstScreenHeight();
+#else
+       #define FX_grSstScreenWidth()           grSstScreenWidth()
+       #define FX_grSstScreenHeight()          grSstScreenHeight()
+#endif
+
+
+/*
+ * Version string.
+ */
+#if defined(FX_GLIDE3)
+       extern void FX_grGlideGetVersion(char *buf);
+#else
+       #define FX_grGlideGetVersion            grGlideGetVersion       
+#endif
+/*
+ * Performance statistics
+ */
+#if defined(FX_GLIDE3)
+        extern void FX_grSstPerfStats(GrSstPerfStats_t *st);
+#else
+       #define FX_grSstPerfStats               grSstPerfStats
+#endif
+
+/*
+ * Hardware Query
+ */
+#if defined(FX_GLIDE3)
+       extern int FX_grSstQueryHardware(GrHwConfiguration *config);
+#else
+       #define FX_grSstQueryHardware           grSstQueryHardware              
+#endif
+
+/*
+ * GrHints
+ */
+#if defined(FX_GLIDE3)
+       extern void FX_grHints(GrHint_t hintType, FxU32 hintMask);
+#else
+       #define FX_grHints                      grHints
+#endif
+/*
+ * Antialiashed line+point drawing.
+ */
+#if defined(FX_GLIDE3)
+       extern void FX_grAADrawLine(GrVertex *a,GrVertex *b);
+#else
+       #define FX_grAADrawLine                 grAADrawLine
+#endif
+
+#if defined(FX_GLIDE3)
+       extern void FX_grAADrawPoint(GrVertex *a);
+#else
+       #define FX_grAADrawPoint                grAADrawPoint
+#endif
+
+/*
+ * Needed for Glide3 only, to set up Glide2 compatible vertex layout.
+ */
+#if defined(FX_GLIDE3)
+       extern void FX_setupGrVertexLayout(void);
+#else
+       #define FX_setupGrVertexLayout()                do {} while (0)
+#endif
+/*
+ * grSstControl stuff
+ */
+#if defined(FX_GLIDE3)
+       extern void FX_grSstControl(int par);
+#else
+       #define FX_grSstControl                         grSstControl
+#endif
+/*
+ * grGammaCorrectionValue
+ */
+#if defined(FX_GLIDE3)
+      extern void FX_grGammaCorrectionValue(float val);
+#else
+      #define FX_grGammaCorrectionValue                        grGammaCorrectionValue
+#endif
+
+/*
+ * WinOpen/Close.
+ */
+#if defined(FX_GLIDE3)
+       #define FX_grSstWinOpen(hWnd,screen_resolution,refresh_rate,color_format,origin_location,nColBuffers,nAuxBuffers) \
+                 grSstWinOpen(-1,screen_resolution,refresh_rate,color_format,origin_location,nColBuffers,nAuxBuffers)
+       #define FX_grSstWinClose                grSstWinClose
+#else
+       #define FX_grSstWinOpen         grSstWinOpen
+       #define FX_grSstWinClose(win)   grSstWinClose()
+#endif
+
+
+#endif /* __FX_GLIDE_WARPER__ */
diff --git a/src/mesa/drivers/glide/fxopengl.def b/src/mesa/drivers/glide/fxopengl.def
new file mode 100644 (file)
index 0000000..af76f4c
--- /dev/null
@@ -0,0 +1,467 @@
+EXPORTS\r
+ glAccum\r
+ glAlphaFunc\r
+ glAreTexturesResident\r
+ glArrayElement\r
+ glBegin\r
+ glBindTexture\r
+ glBitmap\r
+ glBlendFunc\r
+ glCallList\r
+ glCallLists\r
+ glClear\r
+ glClearAccum\r
+ glClearIndex\r
+ glClearColor\r
+ glClearDepth\r
+ glClearStencil\r
+ glClipPlane\r
+ glColor3b\r
+ glColor3d\r
+ glColor3f\r
+ glColor3i\r
+ glColor3s\r
+ glColor3ub\r
+ glColor3ui\r
+ glColor3us\r
+ glColor4b\r
+ glColor4d\r
+ glColor4f\r
+ glColor4i\r
+ glColor4s\r
+ glColor4ub\r
+ glColor4ui\r
+ glColor4us\r
+ glColor3bv\r
+ glColor3dv\r
+ glColor3fv\r
+ glColor3iv\r
+ glColor3sv\r
+ glColor3ubv\r
+ glColor3uiv\r
+ glColor3usv\r
+ glColor4bv\r
+ glColor4dv\r
+ glColor4fv\r
+ glColor4iv\r
+ glColor4sv\r
+ glColor4ubv\r
+ glColor4uiv\r
+ glColor4usv\r
+ glColorMask\r
+ glColorMaterial\r
+ glColorPointer\r
+ glColorTableEXT\r
+ glColorSubTableEXT\r
+ glCopyPixels\r
+ glCopyTexImage1D\r
+ glCopyTexImage2D\r
+ glCopyTexSubImage1D\r
+ glCopyTexSubImage2D\r
+ glCullFace\r
+ glDepthFunc\r
+ glDepthMask\r
+ glDepthRange\r
+ glDeleteLists\r
+ glDeleteTextures\r
+ glDisable\r
+ glDisableClientState\r
+ glDrawArrays\r
+ glDrawBuffer\r
+ glDrawElements\r
+ glDrawPixels\r
+ glEnable\r
+ glEnableClientState\r
+ glEnd\r
+ glEndList\r
+ glEvalCoord1d\r
+ glEvalCoord1f\r
+ glEvalCoord1dv\r
+ glEvalCoord1fv\r
+ glEvalCoord2d\r
+ glEvalCoord2f\r
+ glEvalCoord2dv\r
+ glEvalCoord2fv\r
+ glEvalPoint1\r
+ glEvalPoint2\r
+ glEvalMesh1\r
+ glEdgeFlag\r
+ glEdgeFlagv\r
+ glEdgeFlagPointer\r
+ glEvalMesh2\r
+ glFeedbackBuffer\r
+ glFinish\r
+ glFlush\r
+ glFogf\r
+ glFogi\r
+ glFogfv\r
+ glFogiv\r
+ glFrontFace\r
+ glFrustum\r
+ glGenLists\r
+ glGenTextures\r
+ glGetBooleanv\r
+ glGetClipPlane\r
+ glGetColorTableEXT\r
+ glGetColorTableParameterivEXT\r
+ glGetColorTableParameterfvEXT\r
+ glGetDoublev\r
+ glGetError\r
+ glGetFloatv\r
+ glGetIntegerv\r
+ glGetLightfv\r
+ glGetLightiv\r
+ glGetMapdv\r
+ glGetMapfv\r
+ glGetMapiv\r
+ glGetMaterialfv\r
+ glGetMaterialiv\r
+ glGetPixelMapfv\r
+ glGetPixelMapuiv\r
+ glGetPixelMapusv\r
+ glGetPointerv\r
+ glGetPolygonStipple\r
+ glGetString\r
+ glGetTexEnvfv\r
+ glGetTexEnviv\r
+ glGetTexGeniv\r
+ glGetTexGendv\r
+ glGetTexGenfv\r
+ glGetTexImage\r
+ glGetTexLevelParameterfv\r
+ glGetTexLevelParameteriv\r
+ glGetTexParameterfv\r
+ glGetTexParameteriv\r
+ glHint\r
+ glIndexd\r
+ glIndexf\r
+ glIndexi\r
+ glIndexs\r
+ glIndexub\r
+ glIndexdv\r
+ glIndexfv\r
+ glIndexiv\r
+ glIndexsv\r
+ glIndexubv\r
+ glIndexMask\r
+ glIndexPointer\r
+ glInterleavedArrays\r
+ glInitNames\r
+ glIsList\r
+ glIsTexture\r
+ glLightf\r
+ glLighti\r
+ glLightfv\r
+ glLightiv\r
+ glLightModelf\r
+ glLightModeli\r
+ glLightModelfv\r
+ glLightModeliv\r
+ glLineWidth\r
+ glLineStipple\r
+ glListBase\r
+ glLoadIdentity\r
+ glLoadMatrixd\r
+ glLoadMatrixf\r
+ glLoadName\r
+ glLogicOp\r
+ glMap1d\r
+ glMap1f\r
+ glMap2d\r
+ glMap2f\r
+ glMapGrid1d\r
+ glMapGrid1f\r
+ glMapGrid2d\r
+ glMapGrid2f\r
+ glMaterialf\r
+ glMateriali\r
+ glMaterialfv\r
+ glMaterialiv\r
+ glMatrixMode\r
+ glMultMatrixd\r
+ glMultMatrixf\r
+ glNewList\r
+ glNormal3b\r
+ glNormal3d\r
+ glNormal3f\r
+ glNormal3i\r
+ glNormal3s\r
+ glNormal3bv\r
+ glNormal3dv\r
+ glNormal3fv\r
+ glNormal3iv\r
+ glNormal3sv\r
+ glNormalPointer\r
+ glOrtho\r
+ glPassThrough\r
+ glPixelMapfv\r
+ glPixelMapuiv\r
+ glPixelMapusv\r
+ glPixelStoref\r
+ glPixelStorei\r
+ glPixelTransferf\r
+ glPixelTransferi\r
+ glPixelZoom\r
+ glPointSize\r
+ glPolygonMode\r
+ glPolygonOffset\r
+ glPolygonOffsetEXT\r
+ glPolygonStipple\r
+ glPopAttrib\r
+ glPopClientAttrib\r
+ glPopMatrix\r
+ glPopName\r
+ glPrioritizeTextures\r
+ glPushMatrix\r
+ glRasterPos2d\r
+ glRasterPos2f\r
+ glRasterPos2i\r
+ glRasterPos2s\r
+ glRasterPos3d\r
+ glRasterPos3f\r
+ glRasterPos3i\r
+ glRasterPos3s\r
+ glRasterPos4d\r
+ glRasterPos4f\r
+ glRasterPos4i\r
+ glRasterPos4s\r
+ glRasterPos2dv\r
+ glRasterPos2fv\r
+ glRasterPos2iv\r
+ glRasterPos2sv\r
+ glRasterPos3dv\r
+ glRasterPos3fv\r
+ glRasterPos3iv\r
+ glRasterPos3sv\r
+ glRasterPos4dv\r
+ glRasterPos4fv\r
+ glRasterPos4iv\r
+ glRasterPos4sv\r
+ glReadBuffer\r
+ glReadPixels\r
+ glRectd\r
+ glRectf\r
+ glRecti\r
+ glRects\r
+ glRectdv\r
+ glRectfv\r
+ glRectiv\r
+ glRectsv\r
+ glScissor\r
+ glIsEnabled\r
+ glPushAttrib\r
+ glPushClientAttrib\r
+ glPushName\r
+ glRenderMode\r
+ glRotated\r
+ glRotatef\r
+ glSelectBuffer\r
+ glScaled\r
+ glScalef\r
+ glShadeModel\r
+ glStencilFunc\r
+ glStencilMask\r
+ glStencilOp\r
+ glTexCoord1d\r
+ glTexCoord1f\r
+ glTexCoord1i\r
+ glTexCoord1s\r
+ glTexCoord2d\r
+ glTexCoord2f\r
+ glTexCoord2i\r
+ glTexCoord2s\r
+ glTexCoord3d\r
+ glTexCoord3f\r
+ glTexCoord3i\r
+ glTexCoord3s\r
+ glTexCoord4d\r
+ glTexCoord4f\r
+ glTexCoord4i\r
+ glTexCoord4s\r
+ glTexCoord1dv\r
+ glTexCoord1fv\r
+ glTexCoord1iv\r
+ glTexCoord1sv\r
+ glTexCoord2dv\r
+ glTexCoord2fv\r
+ glTexCoord2iv\r
+ glTexCoord2sv\r
+ glTexCoord3dv\r
+ glTexCoord3fv\r
+ glTexCoord3iv\r
+ glTexCoord3sv\r
+ glTexCoord4dv\r
+ glTexCoord4fv\r
+ glTexCoord4iv\r
+ glTexCoord4sv\r
+ glTexCoordPointer\r
+ glTexGend\r
+ glTexGenf\r
+ glTexGeni\r
+ glTexGendv\r
+ glTexGeniv\r
+ glTexGenfv\r
+ glTexEnvf\r
+ glTexEnvi\r
+ glTexEnvfv\r
+ glTexEnviv\r
+ glTexImage1D\r
+ glTexImage2D\r
+ glTexParameterf\r
+ glTexParameteri\r
+ glTexParameterfv\r
+ glTexParameteriv\r
+ glTexSubImage1D\r
+ glTexSubImage2D\r
+ glTranslated\r
+ glTranslatef\r
+ glVertex2d\r
+ glVertex2f\r
+ glVertex2i\r
+ glVertex2s\r
+ glVertex3d\r
+ glVertex3f\r
+ glVertex3i\r
+ glVertex3s\r
+ glVertex4d\r
+ glVertex4f\r
+ glVertex4i\r
+ glVertex4s\r
+ glVertex2dv\r
+ glVertex2fv\r
+ glVertex2iv\r
+ glVertex2sv\r
+ glVertex3dv\r
+ glVertex3fv\r
+ glVertex3iv\r
+ glVertex3sv\r
+ glVertex4dv\r
+ glVertex4fv\r
+ glVertex4iv\r
+ glVertex4sv\r
+ glVertexPointer\r
+ glViewport\r
+ glBlendEquationEXT\r
+ glBlendColorEXT\r
+ glVertexPointerEXT\r
+ glNormalPointerEXT\r
+ glColorPointerEXT\r
+ glIndexPointerEXT\r
+ glTexCoordPointerEXT\r
+ glEdgeFlagPointerEXT\r
+ glGetPointervEXT\r
+ glArrayElementEXT\r
+ glDrawArraysEXT\r
+ glBindTextureEXT\r
+ glDeleteTexturesEXT\r
+ glGenTexturesEXT\r
+ glPrioritizeTexturesEXT\r
+ glCopyTexSubImage3DEXT\r
+ glTexImage3DEXT\r
+ glTexSubImage3DEXT\r
+ glWindowPos4fMESA\r
+ glWindowPos2iMESA\r
+ glWindowPos2sMESA\r
+ glWindowPos2fMESA\r
+ glWindowPos2dMESA\r
+ glWindowPos2ivMESA\r
+ glWindowPos2svMESA\r
+ glWindowPos2fvMESA\r
+ glWindowPos2dvMESA\r
+ glWindowPos3iMESA\r
+ glWindowPos3sMESA\r
+ glWindowPos3fMESA\r
+ glWindowPos3dMESA\r
+ glWindowPos3ivMESA\r
+ glWindowPos3svMESA\r
+ glWindowPos3fvMESA\r
+ glWindowPos3dvMESA\r
+ glWindowPos4iMESA\r
+ glWindowPos4sMESA\r
+ glWindowPos4dMESA\r
+ glWindowPos4ivMESA\r
+ glWindowPos4svMESA\r
+ glWindowPos4fvMESA\r
+ glWindowPos4dvMESA\r
+ glResizeBuffersMESA\r
+ wglCopyContext\r
+ wglCreateContext\r
+ wglCreateLayerContext\r
+ wglDeleteContext\r
+;wglDescribeLayerPlane\r
+ wglGetCurrentContext\r
+ wglGetCurrentDC\r
+;wglGetLayerPaletteEntries\r
+ wglGetProcAddress\r
+ wglMakeCurrent\r
+;wglRealizeLayerPalette\r
+;wglSetLayerPaletteEntries\r
+ wglShareLists\r
+ wglSwapLayerBuffers\r
+ wglUseFontBitmapsA\r
+ wglUseFontBitmapsW\r
+ wglUseFontOutlinesA\r
+ wglUseFontOutlinesW\r
+ wglChoosePixelFormat\r
+ ChoosePixelFormat\r
+ wglDescribePixelFormat\r
+ DescribePixelFormat\r
+ wglGetPixelFormat\r
+ GetPixelFormat\r
+ wglSetPixelFormat\r
+ SetPixelFormat\r
+ wglSwapBuffers\r
+ SwapBuffers\r
+ gl3DfxSetPaletteEXT\r
+ glActiveTextureARB\r
+ glClientActiveTextureARB\r
+ glMultiTexCoord1dARB\r
+ glMultiTexCoord1dvARB\r
+ glMultiTexCoord1fARB\r
+ glMultiTexCoord1fvARB\r
+ glMultiTexCoord1iARB\r
+ glMultiTexCoord1ivARB\r
+ glMultiTexCoord1sARB\r
+ glMultiTexCoord1svARB\r
+ glMultiTexCoord2dARB\r
+ glMultiTexCoord2dvARB\r
+ glMultiTexCoord2fARB\r
+ glMultiTexCoord2fvARB\r
+ glMultiTexCoord2iARB\r
+ glMultiTexCoord2ivARB\r
+ glMultiTexCoord2sARB\r
+ glMultiTexCoord2svARB\r
+ glMultiTexCoord3dARB\r
+ glMultiTexCoord3dvARB\r
+ glMultiTexCoord3fARB\r
+ glMultiTexCoord3fvARB\r
+ glMultiTexCoord3iARB\r
+ glMultiTexCoord3ivARB\r
+ glMultiTexCoord3sARB\r
+ glMultiTexCoord3svARB\r
+ glMultiTexCoord4dARB\r
+ glMultiTexCoord4dvARB\r
+ glMultiTexCoord4fARB\r
+ glMultiTexCoord4fvARB\r
+ glMultiTexCoord4iARB\r
+ glMultiTexCoord4ivARB\r
+ glMultiTexCoord4sARB\r
+ glMultiTexCoord4svARB\r
+ fxMesaCreateContext\r
+ fxMesaCreateBestContext\r
+ fxMesaDestroyContext\r
+ fxMesaSelectCurrentBoard\r
+ fxMesaMakeCurrent\r
+ fxMesaGetCurrentContext\r
+ fxMesaSwapBuffers\r
+ fxMesaSetNearFar\r
+ fxMesaUpdateScreenSize\r
+ fxQueryHardware\r
+ fxCloseHardware\r
+ OSMesaCreateContext\r
+ OSMesaDestroyContext\r
+ OSMesaGetCurrentContext\r
+ OSMesaGetDepthBuffer\r
+ OSMesaGetIntegerv\r
+ OSMesaMakeCurrent\r
+ OSMesaPixelStore\r
diff --git a/src/mesa/drivers/glide/fxsetup.c b/src/mesa/drivers/glide/fxsetup.c
new file mode 100644 (file)
index 0000000..9996499
--- /dev/null
@@ -0,0 +1,1552 @@
+/* -*- mode: C; tab-width:8;  -*-
+
+             fxsetup.c - 3Dfx VooDoo rendering mode setup functions
+*/
+
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * See the file fxapi.c for more informations about authors
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "conf.h"
+#endif
+
+#if defined(FX)
+
+#include "fxdrv.h"
+#include "enums.h"
+
+static void fxTexValidate(GLcontext *ctx, struct gl_texture_object *tObj)
+{
+  tfxTexInfo *ti=(tfxTexInfo *)tObj->DriverData;
+  GLint minl,maxl;
+
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+     fprintf(stderr,"fxmesa: fxTexValidate(...) Start\n");
+  }
+
+  if(ti->validated) {
+     if (MESA_VERBOSE&VERBOSE_DRIVER) {
+       fprintf(stderr,"fxmesa: fxTexValidate(...) End (validated=GL_TRUE)\n");
+     }
+    return;
+  }
+
+  minl=ti->minLevel=tObj->BaseLevel;
+  maxl=ti->maxLevel=MIN2(tObj->MaxLevel,tObj->Image[0]->MaxLog2);
+
+  fxTexGetInfo(tObj->Image[minl]->Width,tObj->Image[minl]->Height,
+              &(FX_largeLodLog2(ti->info)),&(FX_aspectRatioLog2(ti->info)),
+              &(ti->sScale),&(ti->tScale),
+              &(ti->int_sScale),&(ti->int_tScale),            
+              NULL,NULL);
+
+
+  if((tObj->MinFilter!=GL_NEAREST) && (tObj->MinFilter!=GL_LINEAR))
+    fxTexGetInfo(tObj->Image[maxl]->Width,tObj->Image[maxl]->Height,
+                &(FX_smallLodLog2(ti->info)),NULL,
+                NULL,NULL,
+                NULL,NULL,
+                NULL,NULL);
+  else
+    FX_smallLodLog2(ti->info)=FX_largeLodLog2(ti->info);
+
+  fxTexGetFormat(tObj->Image[minl]->Format,&(ti->info.format),&(ti->baseLevelInternalFormat));
+
+  ti->validated=GL_TRUE;
+
+  ti->info.data=NULL;
+
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+     fprintf(stderr,"fxmesa: fxTexValidate(...) End\n");
+  }
+}
+
+static void fxPrintUnitsMode( const char *msg, GLuint mode )
+{
+   fprintf(stderr, 
+          "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
+          msg,
+          mode,
+          (mode & FX_UM_E0_REPLACE)         ? "E0_REPLACE, " : "",
+          (mode & FX_UM_E0_MODULATE)        ? "E0_MODULATE, " : "",
+          (mode & FX_UM_E0_DECAL)           ? "E0_DECAL, " : "",
+          (mode & FX_UM_E0_BLEND)           ? "E0_BLEND, " : "",
+          (mode & FX_UM_E1_REPLACE)         ? "E1_REPLACE, " : "",
+          (mode & FX_UM_E1_MODULATE)        ? "E1_MODULATE, " : "",
+          (mode & FX_UM_E1_DECAL)           ? "E1_DECAL, " : "",
+          (mode & FX_UM_E1_BLEND)           ? "E1_BLEND, " : "",
+          (mode & FX_UM_E0_ALPHA)           ? "E0_ALPHA, " : "",
+          (mode & FX_UM_E0_LUMINANCE)       ? "E0_LUMINANCE, " : "",
+          (mode & FX_UM_E0_LUMINANCE_ALPHA) ? "E0_LUMINANCE_ALPHA, " : "",
+          (mode & FX_UM_E0_INTENSITY)       ? "E0_INTENSITY, " : "",
+          (mode & FX_UM_E0_RGB)             ? "E0_RGB, " : "",
+          (mode & FX_UM_E0_RGBA)            ? "E0_RGBA, " : "",
+          (mode & FX_UM_E1_ALPHA)           ? "E1_ALPHA, " : "",
+          (mode & FX_UM_E1_LUMINANCE)       ? "E1_LUMINANCE, " : "",
+          (mode & FX_UM_E1_LUMINANCE_ALPHA) ? "E1_LUMINANCE_ALPHA, " : "",
+          (mode & FX_UM_E1_INTENSITY)       ? "E1_INTENSITY, " : "",
+          (mode & FX_UM_E1_RGB)             ? "E1_RGB, " : "",
+          (mode & FX_UM_E1_RGBA)            ? "E1_RGBA, " : "",
+          (mode & FX_UM_COLOR_ITERATED)     ? "COLOR_ITERATED, " : "",
+          (mode & FX_UM_COLOR_CONSTANT)     ? "COLOR_CONSTANT, " : "",
+          (mode & FX_UM_ALPHA_ITERATED)     ? "ALPHA_ITERATED, " : "",
+          (mode & FX_UM_ALPHA_CONSTANT)     ? "ALPHA_CONSTANT, " : "");
+}
+
+GLuint fxGetTexSetConfiguration(GLcontext *ctx,
+                               struct gl_texture_object *tObj0,
+                               struct gl_texture_object *tObj1)
+{
+  GLuint unitsmode=0;
+  GLuint envmode=0;
+  GLuint ifmt=0;
+
+  if((ctx->Light.ShadeModel==GL_SMOOTH) ||
+     (ctx->Point.SmoothFlag) ||
+     (ctx->Line.SmoothFlag) ||
+     (ctx->Polygon.SmoothFlag))
+    unitsmode|=FX_UM_ALPHA_ITERATED;
+  else
+    unitsmode|=FX_UM_ALPHA_CONSTANT;
+
+  if(ctx->Light.ShadeModel==GL_SMOOTH)
+    unitsmode|=FX_UM_COLOR_ITERATED;
+  else
+    unitsmode|=FX_UM_COLOR_CONSTANT;
+
+  if(tObj0) {
+    tfxTexInfo *ti0=(tfxTexInfo *)tObj0->DriverData;
+
+    switch(ti0->baseLevelInternalFormat) {
+    case GL_ALPHA:
+      ifmt|=FX_UM_E0_ALPHA;
+      break;
+    case GL_LUMINANCE:
+      ifmt|=FX_UM_E0_LUMINANCE;
+      break;
+    case GL_LUMINANCE_ALPHA:
+      ifmt|=FX_UM_E0_LUMINANCE_ALPHA;
+      break;
+    case GL_INTENSITY:
+      ifmt|=FX_UM_E0_INTENSITY;
+      break;
+    case GL_RGB:
+      ifmt|=FX_UM_E0_RGB;
+      break;
+    case GL_RGBA:
+      ifmt|=FX_UM_E0_RGBA;
+      break;
+    }
+
+    switch(ctx->Texture.Unit[0].EnvMode) {
+    case GL_DECAL:
+      envmode|=FX_UM_E0_DECAL;
+      break;
+    case GL_MODULATE:
+      envmode|=FX_UM_E0_MODULATE;
+      break;
+    case GL_REPLACE:
+      envmode|=FX_UM_E0_REPLACE;
+      break;
+    case GL_BLEND:
+      envmode|=FX_UM_E0_BLEND;
+      break;
+    default:
+      /* do nothing */
+      break;
+    }
+  }
+
+  if(tObj1) {
+    tfxTexInfo *ti1=(tfxTexInfo *)tObj1->DriverData;
+
+    switch(ti1->baseLevelInternalFormat) {
+    case GL_ALPHA:
+      ifmt|=FX_UM_E1_ALPHA;
+      break;
+    case GL_LUMINANCE:
+      ifmt|=FX_UM_E1_LUMINANCE;
+      break;
+    case GL_LUMINANCE_ALPHA:
+      ifmt|=FX_UM_E1_LUMINANCE_ALPHA;
+      break;
+    case GL_INTENSITY:
+      ifmt|=FX_UM_E1_INTENSITY;
+      break;
+    case GL_RGB:
+      ifmt|=FX_UM_E1_RGB;
+      break;
+    case GL_RGBA:
+      ifmt|=FX_UM_E1_RGBA;
+      break;
+    default:
+      /* do nothing */
+      break;
+    }
+
+    switch(ctx->Texture.Unit[1].EnvMode) {
+    case GL_DECAL:
+      envmode|=FX_UM_E1_DECAL;
+      break;
+    case GL_MODULATE:
+      envmode|=FX_UM_E1_MODULATE;
+      break;
+    case GL_REPLACE:
+      envmode|=FX_UM_E1_REPLACE;
+      break;
+    case GL_BLEND:
+      envmode|=FX_UM_E1_BLEND;
+      break;
+    default:
+      /* do nothing */
+      break;
+    }
+  }
+
+  unitsmode|=(ifmt | envmode);
+
+  if (MESA_VERBOSE & (VERBOSE_DRIVER|VERBOSE_TEXTURE))
+     fxPrintUnitsMode("unitsmode", unitsmode);
+
+  return unitsmode;
+}
+
+/************************************************************************/
+/************************* Rendering Mode SetUp *************************/
+/************************************************************************/
+
+/************************* Single Texture Set ***************************/
+
+static void fxSetupSingleTMU(fxMesaContext fxMesa, struct gl_texture_object *tObj)
+{
+  tfxTexInfo *ti=(tfxTexInfo *)tObj->DriverData;
+
+  if(!ti->tmi.isInTM) {
+    if(ti->LODblend)
+      fxTMMoveInTM(fxMesa,tObj,FX_TMU_SPLIT);
+    else {
+      if(fxMesa->haveTwoTMUs) {
+       if(fxMesa->freeTexMem[FX_TMU0]>grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH,&(ti->info)))
+         fxTMMoveInTM(fxMesa,tObj,FX_TMU0);
+       else
+         fxTMMoveInTM(fxMesa,tObj,FX_TMU1);
+      } else
+       fxTMMoveInTM(fxMesa,tObj,FX_TMU0);
+    }
+  }
+
+  if(ti->LODblend && ti->tmi.whichTMU == FX_TMU_SPLIT) {
+    if((ti->info.format==GR_TEXFMT_P_8) && (!fxMesa->haveGlobalPaletteTexture)) {
+       if (MESA_VERBOSE&VERBOSE_DRIVER) {
+         fprintf(stderr,"fxmesa: uploading texture palette\n");
+       }
+      FX_grTexDownloadTable(GR_TMU0,GR_TEXTABLE_PALETTE,&(ti->palette));
+      FX_grTexDownloadTable(GR_TMU1,GR_TEXTABLE_PALETTE,&(ti->palette));
+    }
+
+    grTexClampMode(GR_TMU0,ti->sClamp,ti->tClamp);
+    grTexClampMode(GR_TMU1,ti->sClamp,ti->tClamp);
+    grTexFilterMode(GR_TMU0,ti->minFilt,ti->maxFilt);
+    grTexFilterMode(GR_TMU1,ti->minFilt,ti->maxFilt);
+    grTexMipMapMode(GR_TMU0,ti->mmMode,ti->LODblend);
+    grTexMipMapMode(GR_TMU1,ti->mmMode,ti->LODblend);
+
+    grTexSource(GR_TMU0,ti->tmi.tm[FX_TMU0]->startAddress,
+               GR_MIPMAPLEVELMASK_ODD,&(ti->info));
+    grTexSource(GR_TMU1,ti->tmi.tm[FX_TMU1]->startAddress,
+               GR_MIPMAPLEVELMASK_EVEN,&(ti->info));
+  } else {
+    if((ti->info.format==GR_TEXFMT_P_8) && (!fxMesa->haveGlobalPaletteTexture)) {
+       if (MESA_VERBOSE&VERBOSE_DRIVER) {
+         fprintf(stderr,"fxmesa: uploading texture palette\n");
+       }
+      FX_grTexDownloadTable(ti->tmi.whichTMU,GR_TEXTABLE_PALETTE,&(ti->palette));
+    }
+
+    /* KW: The alternative is to do the download to the other tmu.  If
+     * we get to this point, I think it means we are thrashing the
+     * texture memory, so perhaps it's not a good idea.  
+     */
+    if (ti->LODblend && (MESA_VERBOSE&VERBOSE_DRIVER))
+       fprintf(stderr, "fxmesa: not blending texture - only on one tmu\n");
+
+    grTexClampMode(ti->tmi.whichTMU,ti->sClamp,ti->tClamp);
+    grTexFilterMode(ti->tmi.whichTMU,ti->minFilt,ti->maxFilt);
+    grTexMipMapMode(ti->tmi.whichTMU,ti->mmMode,FXFALSE);
+
+    grTexSource(ti->tmi.whichTMU,ti->tmi.tm[ti->tmi.whichTMU]->startAddress,
+               GR_MIPMAPLEVELMASK_BOTH,&(ti->info));
+  }
+}
+
+static void fxSelectSingleTMUSrc(fxMesaContext fxMesa, GLint tmu, FxBool LODblend)
+{
+   if (MESA_VERBOSE&VERBOSE_DRIVER) {
+      fprintf(stderr,"fxmesa: fxSelectSingleTMUSrc(%d,%d)\n",tmu,LODblend);
+   }
+
+  if(LODblend) {
+    grTexCombine(GR_TMU0,
+                GR_COMBINE_FUNCTION_BLEND,
+                GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION,
+                GR_COMBINE_FUNCTION_BLEND,
+                GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION,
+                FXFALSE,FXFALSE);
+
+    grTexCombine(GR_TMU1,
+                GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
+                GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
+                FXFALSE,FXFALSE);
+
+    fxMesa->tmuSrc=FX_TMU_SPLIT;
+  } else {
+    if(tmu==FX_TMU0) {
+      grTexCombine(GR_TMU0,
+                  GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
+                  GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
+                  FXFALSE,FXFALSE);
+      
+      fxMesa->tmuSrc=FX_TMU0;
+    } else {
+      grTexCombine(GR_TMU1,
+                  GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
+                  GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
+                  FXFALSE,FXFALSE);
+    
+      /* GR_COMBINE_FUNCTION_SCALE_OTHER doesn't work ?!? */
+    
+      grTexCombine(GR_TMU0,
+                  GR_COMBINE_FUNCTION_BLEND,GR_COMBINE_FACTOR_ONE,
+                  GR_COMBINE_FUNCTION_BLEND,GR_COMBINE_FACTOR_ONE,
+                  FXFALSE,FXFALSE);
+    
+      fxMesa->tmuSrc=FX_TMU1;
+    }
+  }
+}
+
+void fxSetupTextureSingleTMU(GLcontext *ctx, GLuint textureset)
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+  GrCombineLocal_t localc,locala;
+  GLuint unitsmode;
+  GLint ifmt;
+  tfxTexInfo *ti;
+  struct gl_texture_object *tObj=ctx->Texture.Unit[textureset].CurrentD[2];
+
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+     fprintf(stderr,"fxmesa: fxSetupTextureSingleTMU(...) Start\n");
+  }
+
+  ti=(tfxTexInfo *)tObj->DriverData;
+
+  fxTexValidate(ctx,tObj);
+
+  fxSetupSingleTMU(fxMesa,tObj);
+
+  if(fxMesa->tmuSrc!=ti->tmi.whichTMU)
+    fxSelectSingleTMUSrc(fxMesa,ti->tmi.whichTMU,ti->LODblend);
+
+  if(textureset==0 || !fxMesa->haveTwoTMUs)
+    unitsmode=fxGetTexSetConfiguration(ctx,tObj,NULL);
+  else
+    unitsmode=fxGetTexSetConfiguration(ctx,NULL,tObj);
+
+  if(fxMesa->lastUnitsMode==unitsmode)
+    return;
+
+  fxMesa->lastUnitsMode=unitsmode;
+
+  fxMesa->stw_hint_state = 0;
+  FX_grHints(GR_HINT_STWHINT,0);
+
+  ifmt=ti->baseLevelInternalFormat;
+
+  if(unitsmode & FX_UM_ALPHA_ITERATED)
+    locala=GR_COMBINE_LOCAL_ITERATED;
+  else
+    locala=GR_COMBINE_LOCAL_CONSTANT;
+
+  if(unitsmode & FX_UM_COLOR_ITERATED)
+    localc=GR_COMBINE_LOCAL_ITERATED;
+  else
+    localc=GR_COMBINE_LOCAL_CONSTANT;
+
+  if (MESA_VERBOSE & (VERBOSE_DRIVER|VERBOSE_TEXTURE))
+     fprintf(stderr, "fxMesa: fxSetupTextureSingleTMU, envmode is %s\n",
+            gl_lookup_enum_by_nr(ctx->Texture.Unit[textureset].EnvMode));
+
+  switch(ctx->Texture.Unit[textureset].EnvMode) {
+  case GL_DECAL:
+    grAlphaCombine(GR_COMBINE_FUNCTION_LOCAL,
+                  GR_COMBINE_FACTOR_NONE,
+                  locala,
+                  GR_COMBINE_OTHER_NONE,
+                  FXFALSE);
+
+    grColorCombine(GR_COMBINE_FUNCTION_BLEND,
+                  GR_COMBINE_FACTOR_TEXTURE_ALPHA,
+                  localc,
+                  GR_COMBINE_OTHER_TEXTURE,
+                  FXFALSE);
+    break;
+  case GL_MODULATE:
+    grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER,
+                  GR_COMBINE_FACTOR_LOCAL,
+                  locala,
+                  GR_COMBINE_OTHER_TEXTURE,
+                  FXFALSE);
+
+    if(ifmt==GL_ALPHA)
+      grColorCombine(GR_COMBINE_FUNCTION_LOCAL,
+                    GR_COMBINE_FACTOR_NONE,
+                    localc,
+                    GR_COMBINE_OTHER_NONE,
+                    FXFALSE);
+    else
+      grColorCombine(GR_COMBINE_FUNCTION_SCALE_OTHER,
+                    GR_COMBINE_FACTOR_LOCAL,
+                    localc,
+                    GR_COMBINE_OTHER_TEXTURE,
+                    FXFALSE);
+    break;
+  case GL_BLEND:
+#ifndef FX_SILENT
+    fprintf(stderr,"fx Driver: GL_BLEND not yet supported\n");
+#endif
+    /* TO DO (I think that the Voodoo Graphics isn't able to support GL_BLEND) */
+    break;
+  case GL_REPLACE:
+    if((ifmt==GL_RGB) || (ifmt==GL_LUMINANCE))
+      grAlphaCombine(GR_COMBINE_FUNCTION_LOCAL,
+                    GR_COMBINE_FACTOR_NONE,
+                    locala,
+                    GR_COMBINE_OTHER_NONE,
+                    FXFALSE);
+    else
+      grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER,
+                    GR_COMBINE_FACTOR_ONE,
+                    locala,
+                    GR_COMBINE_OTHER_TEXTURE,
+                    FXFALSE);
+    
+    if(ifmt==GL_ALPHA)
+      grColorCombine(GR_COMBINE_FUNCTION_LOCAL,
+                    GR_COMBINE_FACTOR_NONE,
+                    localc,
+                    GR_COMBINE_OTHER_NONE,
+                    FXFALSE);
+    else
+      grColorCombine(GR_COMBINE_FUNCTION_SCALE_OTHER,
+                    GR_COMBINE_FACTOR_ONE,
+                    localc,
+                    GR_COMBINE_OTHER_TEXTURE,
+                    FXFALSE);
+    break;
+  default:
+#ifndef FX_SILENT
+    fprintf(stderr,"fx Driver: %x Texture.EnvMode not yet supported\n",ctx->Texture.Unit[textureset].EnvMode);
+#endif
+    break;
+  }
+
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+     fprintf(stderr,"fxmesa: fxSetupTextureSingleTMU(...) End\n");
+  }
+}
+
+/************************* Double Texture Set ***************************/
+
+void fxSetupDoubleTMU(fxMesaContext fxMesa, struct gl_texture_object *tObj0,
+                     struct gl_texture_object *tObj1)
+{
+#define T0_NOT_IN_TMU  0x01
+#define T1_NOT_IN_TMU  0x02
+#define T0_IN_TMU0     0x04
+#define T1_IN_TMU0     0x08
+#define T0_IN_TMU1     0x10
+#define T1_IN_TMU1     0x20
+
+  tfxTexInfo *ti0=(tfxTexInfo *)tObj0->DriverData;
+  tfxTexInfo *ti1=(tfxTexInfo *)tObj1->DriverData;
+  GLuint tstate=0;
+
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+     fprintf(stderr,"fxmesa: fxSetupDoubleTMU(...)\n");
+  }
+
+  if(ti0->tmi.isInTM) {
+    if(ti0->tmi.whichTMU==FX_TMU0)
+      tstate|=T0_IN_TMU0;
+    else if(ti0->tmi.whichTMU==FX_TMU1)
+      tstate|=T0_IN_TMU1;
+    else {
+      fxTMMoveOutTM(fxMesa,tObj0);
+      tstate|=T0_NOT_IN_TMU;
+    }
+  } else
+    tstate|=T0_NOT_IN_TMU;
+
+  if(ti1->tmi.isInTM) {
+    if(ti1->tmi.whichTMU==FX_TMU0)
+      tstate|=T1_IN_TMU0;
+    else if(ti1->tmi.whichTMU==FX_TMU1)
+      tstate|=T1_IN_TMU1;
+    else {
+      fxTMMoveOutTM(fxMesa,tObj1);
+      tstate|=T1_NOT_IN_TMU;
+    }
+  } else
+    tstate|=T1_NOT_IN_TMU;
+
+  ti0->tmi.lastTimeUsed=fxMesa->texBindNumber;
+  ti1->tmi.lastTimeUsed=fxMesa->texBindNumber;
+
+  /* Move texture maps in TMUs */ 
+
+  switch(tstate) {
+  case (T0_IN_TMU0 | T1_IN_TMU0):
+    fxTMMoveOutTM(fxMesa,tObj1);
+
+    fxTMMoveInTM(fxMesa,tObj1,FX_TMU1);
+    break;
+
+  case (T0_IN_TMU1 | T1_IN_TMU1):
+    fxTMMoveOutTM(fxMesa,tObj0);
+
+    fxTMMoveInTM(fxMesa,tObj0,FX_TMU0);
+    break;
+
+  case (T0_NOT_IN_TMU | T1_NOT_IN_TMU):
+    fxTMMoveInTM(fxMesa,tObj0,FX_TMU0);
+    fxTMMoveInTM(fxMesa,tObj1,FX_TMU1);
+    break;
+
+    /*** T0/T1 ***/
+
+  case (T0_NOT_IN_TMU | T1_IN_TMU0):
+    fxTMMoveInTM(fxMesa,tObj0,FX_TMU1);
+    break;
+
+  case (T0_NOT_IN_TMU | T1_IN_TMU1):
+    fxTMMoveInTM(fxMesa,tObj0,FX_TMU0);
+    break;
+
+  case (T0_IN_TMU0 | T1_NOT_IN_TMU):
+    fxTMMoveInTM(fxMesa,tObj1,FX_TMU1);
+    break;
+
+  case (T0_IN_TMU1 | T1_NOT_IN_TMU):
+    fxTMMoveInTM(fxMesa,tObj1,FX_TMU0);
+    break;
+
+    /*** Best Case ***/
+
+  case (T0_IN_TMU1 | T1_IN_TMU0):
+  case (T0_IN_TMU0 | T1_IN_TMU1):
+    break;
+
+  default:
+    fprintf(stderr,"fx Driver: internal error in fxSetupDoubleTMU()\n");
+    fxCloseHardware();
+    exit(-1);
+    break;
+  }
+
+  if(!fxMesa->haveGlobalPaletteTexture) {
+    if(ti0->info.format==GR_TEXFMT_P_8) {
+       if (MESA_VERBOSE&VERBOSE_DRIVER) {
+         fprintf(stderr,"fxmesa: uploading texture palette TMU0\n");
+       }
+      FX_grTexDownloadTable(ti0->tmi.whichTMU,GR_TEXTABLE_PALETTE,&(ti0->palette));
+    }
+
+    if(ti1->info.format==GR_TEXFMT_P_8) {
+       if (MESA_VERBOSE&VERBOSE_DRIVER) {
+         fprintf(stderr,"fxmesa: uploading texture palette TMU1\n");
+       }
+      FX_grTexDownloadTable(ti1->tmi.whichTMU,GR_TEXTABLE_PALETTE,&(ti1->palette));
+    }
+  }
+
+  grTexClampMode(ti0->tmi.whichTMU,ti0->sClamp,ti0->tClamp);
+  grTexFilterMode(ti0->tmi.whichTMU,ti0->minFilt,ti0->maxFilt);
+  grTexMipMapMode(ti0->tmi.whichTMU,ti0->mmMode,FXFALSE);
+  grTexSource(ti0->tmi.whichTMU,ti0->tmi.tm[ti0->tmi.whichTMU]->startAddress,
+             GR_MIPMAPLEVELMASK_BOTH,&(ti0->info));
+
+  grTexClampMode(ti1->tmi.whichTMU,ti1->sClamp,ti1->tClamp);
+  grTexFilterMode(ti1->tmi.whichTMU,ti1->minFilt,ti1->maxFilt);
+  grTexMipMapMode(ti1->tmi.whichTMU,ti1->mmMode,FXFALSE);
+  grTexSource(ti1->tmi.whichTMU,ti1->tmi.tm[ti1->tmi.whichTMU]->startAddress,
+             GR_MIPMAPLEVELMASK_BOTH,&(ti1->info));
+
+#undef T0_NOT_IN_TMU
+#undef T1_NOT_IN_TMU
+#undef T0_IN_TMU0
+#undef T1_IN_TMU0
+#undef T0_IN_TMU1
+#undef T1_IN_TMU1
+}
+
+static void fxSetupTextureDoubleTMU(GLcontext *ctx)
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+  GrCombineLocal_t localc,locala;
+  tfxTexInfo *ti0,*ti1;
+  struct gl_texture_object *tObj0=ctx->Texture.Unit[0].CurrentD[2];
+  struct gl_texture_object *tObj1=ctx->Texture.Unit[1].CurrentD[2];
+  GLuint envmode,ifmt,unitsmode;
+
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+     fprintf(stderr,"fxmesa: fxSetupTextureDoubleTMU(...) Start\n");
+  }
+
+  ti0=(tfxTexInfo *)tObj0->DriverData;
+  fxTexValidate(ctx,tObj0);
+
+  ti1=(tfxTexInfo *)tObj1->DriverData;
+  fxTexValidate(ctx,tObj1);
+
+  fxSetupDoubleTMU(fxMesa,tObj0,tObj1);
+
+  unitsmode=fxGetTexSetConfiguration(ctx,tObj0,tObj1);
+
+  if(fxMesa->lastUnitsMode==unitsmode)
+    return;
+
+  fxMesa->lastUnitsMode=unitsmode;
+
+  fxMesa->stw_hint_state |= GR_STWHINT_ST_DIFF_TMU1;
+  FX_grHints(GR_HINT_STWHINT, fxMesa->stw_hint_state);
+
+  envmode=unitsmode & FX_UM_E_ENVMODE;
+  ifmt=unitsmode & FX_UM_E_IFMT;
+
+  if(unitsmode & FX_UM_ALPHA_ITERATED)
+    locala=GR_COMBINE_LOCAL_ITERATED;
+  else
+    locala=GR_COMBINE_LOCAL_CONSTANT;
+
+  if(unitsmode & FX_UM_COLOR_ITERATED)
+    localc=GR_COMBINE_LOCAL_ITERATED;
+  else
+    localc=GR_COMBINE_LOCAL_CONSTANT;
+
+
+  if (MESA_VERBOSE & (VERBOSE_DRIVER|VERBOSE_TEXTURE))
+     fprintf(stderr, "fxMesa: fxSetupTextureDoubleTMU, envmode is %s/%s\n",
+            gl_lookup_enum_by_nr(ctx->Texture.Unit[0].EnvMode),
+            gl_lookup_enum_by_nr(ctx->Texture.Unit[1].EnvMode));
+
+
+  fxMesa->tmuSrc=FX_TMU_BOTH;
+  switch(envmode) {
+  case (FX_UM_E0_MODULATE | FX_UM_E1_MODULATE):
+    {
+      GLboolean isalpha[FX_NUM_TMU];
+
+      if(ti0->baseLevelInternalFormat==GL_ALPHA)
+       isalpha[ti0->tmi.whichTMU]=GL_TRUE;
+      else
+       isalpha[ti0->tmi.whichTMU]=GL_FALSE;
+
+      if(ti1->baseLevelInternalFormat==GL_ALPHA)
+       isalpha[ti1->tmi.whichTMU]=GL_TRUE;
+      else
+       isalpha[ti1->tmi.whichTMU]=GL_FALSE;
+       
+      if(isalpha[FX_TMU1])
+       grTexCombine(GR_TMU1,
+                    GR_COMBINE_FUNCTION_ZERO,GR_COMBINE_FACTOR_NONE,
+                    GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
+                    FXTRUE,FXFALSE);
+      else
+       grTexCombine(GR_TMU1,
+                    GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
+                    GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
+                    FXFALSE,FXFALSE);
+
+      if(isalpha[FX_TMU0])
+       grTexCombine(GR_TMU0,
+                    GR_COMBINE_FUNCTION_BLEND_OTHER,GR_COMBINE_FACTOR_ONE,
+                    GR_COMBINE_FUNCTION_BLEND_OTHER,GR_COMBINE_FACTOR_LOCAL,
+                    FXFALSE,FXFALSE);
+      else
+       grTexCombine(GR_TMU0,
+                    GR_COMBINE_FUNCTION_BLEND_OTHER,GR_COMBINE_FACTOR_LOCAL,
+                    GR_COMBINE_FUNCTION_BLEND_OTHER,GR_COMBINE_FACTOR_LOCAL,
+                    FXFALSE,FXFALSE);
+
+      grColorCombine(GR_COMBINE_FUNCTION_SCALE_OTHER,
+                    GR_COMBINE_FACTOR_LOCAL,
+                    localc,
+                    GR_COMBINE_OTHER_TEXTURE,
+                    FXFALSE);
+
+      grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER,
+                    GR_COMBINE_FACTOR_LOCAL,
+                    locala,
+                    GR_COMBINE_OTHER_TEXTURE,
+                    FXFALSE);
+      break;
+    }
+  case (FX_UM_E0_REPLACE | FX_UM_E1_BLEND): /* Only for GLQuake */
+    if(ti1->tmi.whichTMU==FX_TMU1) {
+      grTexCombine(GR_TMU1,
+                  GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
+                  GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
+                  FXTRUE,FXFALSE);
+                 
+      grTexCombine(GR_TMU0,
+                  GR_COMBINE_FUNCTION_BLEND_OTHER,GR_COMBINE_FACTOR_LOCAL,
+                  GR_COMBINE_FUNCTION_BLEND_OTHER,GR_COMBINE_FACTOR_LOCAL,
+                  FXFALSE,FXFALSE);
+    } else {
+      grTexCombine(GR_TMU1,
+                  GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
+                  GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
+                  FXFALSE,FXFALSE);
+                 
+      grTexCombine(GR_TMU0,
+                  GR_COMBINE_FUNCTION_BLEND_OTHER,GR_COMBINE_FACTOR_ONE_MINUS_LOCAL,
+                  GR_COMBINE_FUNCTION_BLEND_OTHER,GR_COMBINE_FACTOR_ONE_MINUS_LOCAL,
+                  FXFALSE,FXFALSE);
+    }
+         
+    grAlphaCombine(GR_COMBINE_FUNCTION_LOCAL,
+                  GR_COMBINE_FACTOR_NONE,
+                  locala,
+                  GR_COMBINE_OTHER_NONE,
+                  FXFALSE);
+
+    grColorCombine(GR_COMBINE_FUNCTION_SCALE_OTHER,
+                  GR_COMBINE_FACTOR_ONE,
+                  localc,
+                  GR_COMBINE_OTHER_TEXTURE,
+                  FXFALSE);
+    break;
+  case (FX_UM_E0_REPLACE | FX_UM_E1_MODULATE): /* Quake 2 and 3 */
+    if(ti1->tmi.whichTMU==FX_TMU1) {
+      grTexCombine(GR_TMU1,
+                  GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
+                  GR_COMBINE_FUNCTION_ZERO,GR_COMBINE_FACTOR_NONE,
+                  FXFALSE,FXTRUE);
+                 
+      grTexCombine(GR_TMU0,
+                  GR_COMBINE_FUNCTION_BLEND_OTHER,GR_COMBINE_FACTOR_LOCAL,
+                  GR_COMBINE_FUNCTION_BLEND_OTHER,GR_COMBINE_FACTOR_LOCAL,
+                  FXFALSE,FXFALSE);
+
+    } else {
+      grTexCombine(GR_TMU1,
+                  GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
+                  GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
+                  FXFALSE,FXFALSE);
+                 
+      grTexCombine(GR_TMU0,
+                  GR_COMBINE_FUNCTION_BLEND_OTHER,GR_COMBINE_FACTOR_LOCAL,
+                  GR_COMBINE_FUNCTION_BLEND_OTHER,GR_COMBINE_FACTOR_ONE,
+                  FXFALSE,FXFALSE);
+    }
+         
+    if(ti0->baseLevelInternalFormat==GL_RGB)
+      grAlphaCombine(GR_COMBINE_FUNCTION_LOCAL,
+                    GR_COMBINE_FACTOR_NONE,
+                    locala,
+                    GR_COMBINE_OTHER_NONE,
+                    FXFALSE);
+    else
+      grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER,
+                    GR_COMBINE_FACTOR_ONE,
+                    locala,
+                    GR_COMBINE_OTHER_NONE,
+                    FXFALSE);
+
+
+    grColorCombine(GR_COMBINE_FUNCTION_SCALE_OTHER,
+                  GR_COMBINE_FACTOR_ONE,
+                  localc,
+                  GR_COMBINE_OTHER_TEXTURE,
+                  FXFALSE);
+    break;
+  }
+
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+     fprintf(stderr,"fxmesa: fxSetupTextureDoubleTMU(...) End\n");
+  }
+}
+
+/************************* No Texture ***************************/
+
+static void fxSetupTextureNone(GLcontext *ctx)
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+  GrCombineLocal_t localc,locala;
+
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+     fprintf(stderr,"fxmesa: fxSetupTextureNone(...)\n");
+  }
+
+  if((ctx->Light.ShadeModel==GL_SMOOTH) ||
+     (ctx->Point.SmoothFlag) ||
+     (ctx->Line.SmoothFlag) ||
+     (ctx->Polygon.SmoothFlag))
+    locala=GR_COMBINE_LOCAL_ITERATED;
+  else
+    locala=GR_COMBINE_LOCAL_CONSTANT;
+  
+  if(ctx->Light.ShadeModel==GL_SMOOTH)
+    localc=GR_COMBINE_LOCAL_ITERATED;
+  else
+    localc=GR_COMBINE_LOCAL_CONSTANT;
+  
+  grAlphaCombine(GR_COMBINE_FUNCTION_LOCAL,
+                GR_COMBINE_FACTOR_NONE,
+                locala,
+                GR_COMBINE_OTHER_NONE,
+                FXFALSE);
+
+  grColorCombine(GR_COMBINE_FUNCTION_LOCAL,
+                GR_COMBINE_FACTOR_NONE,
+                localc,
+                GR_COMBINE_OTHER_NONE,
+                FXFALSE);
+
+  fxMesa->lastUnitsMode=FX_UM_NONE;
+}
+
+/* See below.
+ */
+static GLboolean fxMultipassTexture( struct vertex_buffer *, GLuint );
+
+
+
+/************************************************************************/
+/************************** Texture Mode SetUp **************************/
+/************************************************************************/
+
+void fxSetupTexture(GLcontext *ctx)
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+  GLuint tex2Denabled;
+
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+     fprintf(stderr,"fxmesa: fxSetupTexture(...)\n");
+  }
+
+  /* Disable multipass texturing.
+   */
+  ctx->Driver.MultipassFunc = 0;
+
+  /* Texture Combine, Color Combine and Alpha Combine.
+   */  
+  tex2Denabled = (ctx->Texture.ReallyEnabled & TEXTURE0_2D);
+
+  if (fxMesa->emulateTwoTMUs)
+     tex2Denabled |= (ctx->Texture.ReallyEnabled & TEXTURE1_2D);
+  
+  switch(tex2Denabled) {
+  case TEXTURE0_2D:
+    fxSetupTextureSingleTMU(ctx,0);    
+    break;
+  case TEXTURE1_2D:
+    fxSetupTextureSingleTMU(ctx,1);
+    break;
+  case (TEXTURE0_2D|TEXTURE1_2D):
+     if (fxMesa->haveTwoTMUs)
+       fxSetupTextureDoubleTMU(ctx);
+     else {
+       if (MESA_VERBOSE&VERBOSE_DRIVER)
+          fprintf(stderr, "fxmesa: enabling fake multitexture\n");
+
+       fxSetupTextureSingleTMU(ctx,0);
+       ctx->Driver.MultipassFunc = fxMultipassTexture;
+     }
+    break;
+  default:
+    fxSetupTextureNone(ctx);
+    break;
+  }
+}
+
+/************************************************************************/
+/**************************** Blend SetUp *******************************/
+/************************************************************************/
+
+/* XXX consider supporting GL_INGR_blend_func_separate */
+void fxDDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor)
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+  tfxUnitsState *us=&fxMesa->unitsState;
+  GrAlphaBlendFnc_t sfact,dfact,asfact,adfact;
+
+  /* From the Glide documentation:
+     For alpha source and destination blend function factor
+     parameters, Voodoo Graphics supports only
+     GR_BLEND_ZERO and GR_BLEND_ONE.
+  */
+
+  switch(sfactor) {
+  case GL_ZERO:
+    asfact=sfact=GR_BLEND_ZERO;
+    break;
+  case GL_ONE:
+    asfact=sfact=GR_BLEND_ONE;
+    break;
+  case GL_DST_COLOR:
+    sfact=GR_BLEND_DST_COLOR;
+    asfact=GR_BLEND_ONE;
+    break;
+  case GL_ONE_MINUS_DST_COLOR:
+    sfact=GR_BLEND_ONE_MINUS_DST_COLOR;
+    asfact=GR_BLEND_ONE;
+    break;
+  case GL_SRC_ALPHA:
+    sfact=GR_BLEND_SRC_ALPHA;
+    asfact=GR_BLEND_ONE;
+    break;
+  case GL_ONE_MINUS_SRC_ALPHA:
+    sfact=GR_BLEND_ONE_MINUS_SRC_ALPHA;
+    asfact=GR_BLEND_ONE;
+    break;
+  case GL_DST_ALPHA:
+    sfact=GR_BLEND_DST_ALPHA;
+    asfact=GR_BLEND_ONE;
+    break;
+  case GL_ONE_MINUS_DST_ALPHA:
+    sfact=GR_BLEND_ONE_MINUS_DST_ALPHA;
+    asfact=GR_BLEND_ONE;
+    break;
+  case GL_SRC_ALPHA_SATURATE:
+    sfact=GR_BLEND_ALPHA_SATURATE;
+    asfact=GR_BLEND_ONE;
+    break;
+  case GL_SRC_COLOR:
+  case GL_ONE_MINUS_SRC_COLOR:
+    /* USELESS */
+    asfact=sfact=GR_BLEND_ONE;
+    break;
+  default:
+    asfact=sfact=GR_BLEND_ONE;
+    break;
+  }
+
+  if((sfact!=us->blendSrcFuncRGB) ||
+     (asfact!=us->blendSrcFuncAlpha)) {
+    us->blendSrcFuncRGB=sfact;
+    us->blendSrcFuncAlpha=asfact;
+    fxMesa->new_state |= FX_NEW_BLEND;
+    ctx->Driver.RenderStart = fxSetupFXUnits;
+  }
+
+  switch(dfactor) {
+  case GL_ZERO:
+    adfact=dfact=GR_BLEND_ZERO;
+    break;
+  case GL_ONE:
+    adfact=dfact=GR_BLEND_ONE;
+    break;
+  case GL_SRC_COLOR:
+    dfact=GR_BLEND_SRC_COLOR;
+    adfact=GR_BLEND_ZERO;
+    break;
+  case GL_ONE_MINUS_SRC_COLOR:
+    dfact=GR_BLEND_ONE_MINUS_SRC_COLOR;
+    adfact=GR_BLEND_ZERO;
+    break;
+  case GL_SRC_ALPHA:
+    dfact=GR_BLEND_SRC_ALPHA;
+    adfact=GR_BLEND_ZERO;
+    break;
+  case GL_ONE_MINUS_SRC_ALPHA:
+    dfact=GR_BLEND_ONE_MINUS_SRC_ALPHA;
+    adfact=GR_BLEND_ZERO;
+    break;
+  case GL_DST_ALPHA:
+    dfact=GR_BLEND_DST_ALPHA;
+    adfact=GR_BLEND_ZERO;
+    break;
+  case GL_ONE_MINUS_DST_ALPHA:
+    dfact=GR_BLEND_ONE_MINUS_DST_ALPHA;
+    adfact=GR_BLEND_ZERO;
+    break;
+  case GL_SRC_ALPHA_SATURATE:
+  case GL_DST_COLOR:
+  case GL_ONE_MINUS_DST_COLOR:
+    /* USELESS */
+    adfact=dfact=GR_BLEND_ZERO;
+    break;
+  default:
+    adfact=dfact=GR_BLEND_ZERO;
+    break;
+  }
+
+  if((dfact!=us->blendDstFuncRGB) ||
+     (adfact!=us->blendDstFuncAlpha)) {
+    us->blendDstFuncRGB=dfact;
+    us->blendDstFuncAlpha=adfact;
+    fxMesa->new_state |= FX_NEW_BLEND;
+    ctx->Driver.RenderStart = fxSetupFXUnits;
+  }
+}
+
+void fxSetupBlend(GLcontext *ctx)
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+  tfxUnitsState *us=&fxMesa->unitsState;
+
+  if(us->blendEnabled)
+     grAlphaBlendFunction(us->blendSrcFuncRGB,us->blendDstFuncRGB,
+                         us->blendSrcFuncAlpha,us->blendDstFuncAlpha);
+  else
+     grAlphaBlendFunction(GR_BLEND_ONE,GR_BLEND_ZERO,GR_BLEND_ONE,GR_BLEND_ZERO);
+}
+  
+/************************************************************************/
+/************************** Alpha Test SetUp ****************************/
+/************************************************************************/
+
+void fxDDAlphaFunc(GLcontext *ctx, GLenum func, GLclampf ref)
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+  tfxUnitsState *us=&fxMesa->unitsState;
+  GrCmpFnc_t newfunc;
+
+  switch(func) {
+  case GL_NEVER:
+    newfunc=GR_CMP_NEVER;
+    break;
+  case GL_LESS:
+    newfunc=GR_CMP_LESS;
+    break;
+  case GL_EQUAL:
+    newfunc=GR_CMP_EQUAL;
+    break;
+  case GL_LEQUAL:
+    newfunc=GR_CMP_LEQUAL;
+    break;
+  case GL_GREATER:
+    newfunc=GR_CMP_GREATER;
+    break;
+  case GL_NOTEQUAL:
+    newfunc=GR_CMP_NOTEQUAL;
+    break;
+  case GL_GEQUAL:
+    newfunc=GR_CMP_GEQUAL;
+    break;
+  case GL_ALWAYS:
+    newfunc=GR_CMP_ALWAYS;
+    break;
+  default:
+    fprintf(stderr,"fx Driver: internal error in fxDDAlphaFunc()\n");
+    fxCloseHardware();
+    exit(-1);
+    break;
+  }
+
+  if(newfunc!=us->alphaTestFunc) {
+    us->alphaTestFunc=newfunc;
+    fxMesa->new_state |= FX_NEW_ALPHA;
+    ctx->Driver.RenderStart = fxSetupFXUnits;
+  }
+
+  if(ctx->Color.AlphaRef!=us->alphaTestRefValue) {
+    us->alphaTestRefValue=ctx->Color.AlphaRef;
+    fxMesa->new_state |= FX_NEW_ALPHA;
+    ctx->Driver.RenderStart = fxSetupFXUnits;
+  }
+}
+
+static void fxSetupAlphaTest(GLcontext *ctx)
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+  tfxUnitsState *us=&fxMesa->unitsState;
+
+  if(us->alphaTestEnabled) {
+     grAlphaTestFunction(us->alphaTestFunc);
+     grAlphaTestReferenceValue(us->alphaTestRefValue);
+  } else
+     grAlphaTestFunction(GR_CMP_ALWAYS);
+}
+
+/************************************************************************/
+/************************** Depth Test SetUp ****************************/
+/************************************************************************/
+
+void fxDDDepthFunc(GLcontext *ctx, GLenum func)
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+  tfxUnitsState *us=&fxMesa->unitsState;
+  GrCmpFnc_t dfunc;
+
+  switch(func) {
+  case GL_NEVER:
+    dfunc=GR_CMP_NEVER;
+    break;
+  case GL_LESS:
+    dfunc=GR_CMP_LESS;
+    break;
+  case GL_GEQUAL:
+    dfunc=GR_CMP_GEQUAL;
+    break;
+  case GL_LEQUAL:
+    dfunc=GR_CMP_LEQUAL;
+    break;
+  case GL_GREATER:
+    dfunc=GR_CMP_GREATER;
+    break;
+  case GL_NOTEQUAL:
+    dfunc=GR_CMP_NOTEQUAL;
+    break;
+  case GL_EQUAL:
+    dfunc=GR_CMP_EQUAL;
+    break;
+  case GL_ALWAYS:
+    dfunc=GR_CMP_ALWAYS;
+    break;
+  default:
+    fprintf(stderr,"fx Driver: internal error in fxDDDepthFunc()\n");
+    fxCloseHardware();
+    exit(-1);
+    break;
+  }
+
+  if(dfunc!=us->depthTestFunc) {
+    us->depthTestFunc=dfunc;
+    fxMesa->new_state |= FX_NEW_DEPTH;
+    ctx->Driver.RenderStart = fxSetupFXUnits;
+  }
+
+}
+
+void fxDDDepthMask(GLcontext *ctx, GLboolean flag)
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+  tfxUnitsState *us=&fxMesa->unitsState;
+
+  if(flag!=us->depthMask) {
+    us->depthMask=flag;
+    fxMesa->new_state |= FX_NEW_DEPTH;
+    ctx->Driver.RenderStart = fxSetupFXUnits;
+  }
+}
+
+void fxSetupDepthTest(GLcontext *ctx)
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+  tfxUnitsState *us=&fxMesa->unitsState;
+
+  if(us->depthTestEnabled)
+     grDepthBufferFunction(us->depthTestFunc);
+  else
+     grDepthBufferFunction(GR_CMP_ALWAYS);
+
+  grDepthMask(us->depthMask);
+}
+
+/************************************************************************/
+/**************************** Color Mask SetUp **************************/
+/************************************************************************/
+
+GLboolean fxDDColorMask(GLcontext *ctx, 
+                       GLboolean r, GLboolean g, 
+                       GLboolean b, GLboolean a )
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+  fxMesa->new_state |= FX_NEW_COLOR_MASK;
+  ctx->Driver.RenderStart = fxSetupFXUnits;
+  (void) r; (void) g; (void) b; (void) a;
+  return 1;
+}
+
+static void fxSetupColorMask(GLcontext *ctx)
+{
+  fxMesaContext fxMesa = FX_CONTEXT(ctx);
+
+  grColorMask(ctx->Color.ColorMask[RCOMP] ||
+             ctx->Color.ColorMask[GCOMP] ||
+             ctx->Color.ColorMask[BCOMP],
+             ctx->Color.ColorMask[ACOMP] && fxMesa->haveAlphaBuffer);
+}
+
+
+
+/************************************************************************/
+/**************************** Fog Mode SetUp ****************************/
+/************************************************************************/
+
+void fxFogTableGenerate(GLcontext *ctx)
+{
+  int i;
+  float f,eyez;
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+
+  for(i=0;i<FX_grGetInteger(FX_FOG_TABLE_ENTRIES);i++) {
+    eyez=guFogTableIndexToW(i);
+
+    switch(ctx->Fog.Mode) {
+    case GL_LINEAR:
+      f=(ctx->Fog.End-eyez)/(ctx->Fog.End-ctx->Fog.Start);
+      break;
+    case GL_EXP:
+      f=exp(-ctx->Fog.Density*eyez);  
+      break;
+    case GL_EXP2:
+      f=exp(-ctx->Fog.Density*ctx->Fog.Density*eyez*eyez);
+      break;
+    default: /* That should never happen */
+      f=0.0f;
+      break; 
+    }
+
+    fxMesa->fogTable[i]=(GrFog_t)((1.0f-CLAMP(f,0.0f,1.0f))*255.0f);
+  }
+}
+
+void fxSetupFog(GLcontext *ctx, GLboolean forceTableRebuild)
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+
+  if(ctx->Fog.Enabled && ctx->FogMode==FOG_FRAGMENT) {
+    GLubyte col[4];
+    grFogMode(GR_FOG_WITH_TABLE);
+
+    col[0]=(unsigned int)(255*ctx->Fog.Color[0]);
+    col[1]=(unsigned int)(255*ctx->Fog.Color[1]);
+    col[2]=(unsigned int)(255*ctx->Fog.Color[2]); 
+    col[3]=(unsigned int)(255*ctx->Fog.Color[3]);
+
+    grFogColorValue(FXCOLOR4(col));
+
+    if(forceTableRebuild ||
+       (fxMesa->fogTableMode!=ctx->Fog.Mode) ||
+       (fxMesa->fogDensity!=ctx->Fog.Density)) {
+      fxFogTableGenerate(ctx);
+         
+      fxMesa->fogTableMode=ctx->Fog.Mode;
+      fxMesa->fogDensity=ctx->Fog.Density;
+    }
+      
+    grFogTable(fxMesa->fogTable);
+  } else
+    grFogMode(GR_FOG_DISABLE);
+}
+
+void fxDDFogfv( GLcontext *ctx, GLenum pname, const GLfloat *params )
+{
+   FX_CONTEXT(ctx)->new_state |= FX_NEW_FOG;
+   ctx->Driver.RenderStart = fxSetupFXUnits;
+}
+
+/************************************************************************/
+/************************** Scissor Test SetUp **************************/
+/************************************************************************/
+
+static void fxSetupScissor(GLcontext *ctx)
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+
+  if (ctx->Scissor.Enabled) {
+    int ymin, ymax;
+
+    ymin=ctx->Scissor.Y;
+    ymax=ctx->Scissor.Y+ctx->Scissor.Height;
+
+    if (ymin<0) ymin=0;
+
+    if (ymax>fxMesa->height) ymax=fxMesa->height;
+
+    grClipWindow(ctx->Scissor.X, 
+                ymin,
+                ctx->Scissor.X+ctx->Scissor.Width, 
+                ymax);
+  } else
+    grClipWindow(0,0,fxMesa->width,fxMesa->height);
+}
+
+void fxDDScissor( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h )
+{
+   FX_CONTEXT(ctx)->new_state |= FX_NEW_SCISSOR;
+   ctx->Driver.RenderStart = fxSetupFXUnits;
+}
+
+/************************************************************************/
+/*************************** Cull mode setup ****************************/
+/************************************************************************/
+
+
+void fxDDCullFace(GLcontext *ctx, GLenum mode)
+{
+   (void) mode;
+   FX_CONTEXT(ctx)->new_state |= FX_NEW_CULL;
+   ctx->Driver.RenderStart = fxSetupFXUnits;   
+}
+
+void fxDDFrontFace(GLcontext *ctx, GLenum mode)
+{
+   (void) mode;
+   FX_CONTEXT(ctx)->new_state |= FX_NEW_CULL;
+   ctx->Driver.RenderStart = fxSetupFXUnits;   
+}
+
+
+void fxSetupCull(GLcontext *ctx)
+{
+   if(ctx->Polygon.CullFlag) {
+      switch(ctx->Polygon.CullFaceMode) {
+      case GL_BACK:
+        if(ctx->Polygon.FrontFace==GL_CCW)
+           grCullMode(GR_CULL_NEGATIVE);
+        else
+           grCullMode(GR_CULL_POSITIVE);
+        break;
+      case GL_FRONT:
+        if(ctx->Polygon.FrontFace==GL_CCW)
+           grCullMode(GR_CULL_POSITIVE);
+        else
+           grCullMode(GR_CULL_NEGATIVE);
+        break;
+      case GL_FRONT_AND_BACK:
+        grCullMode(GR_CULL_DISABLE);
+        break;
+      default:
+        break;
+      }
+   } else
+      grCullMode(GR_CULL_DISABLE);
+}
+
+
+/************************************************************************/
+/****************************** DD Enable ******************************/
+/************************************************************************/
+
+void fxDDEnable(GLcontext *ctx, GLenum cap, GLboolean state)
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+  tfxUnitsState *us=&fxMesa->unitsState;
+
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+     fprintf(stderr,"fxmesa: fxDDEnable(...)\n");
+  }
+
+  switch(cap) {
+  case GL_ALPHA_TEST:
+    if(state!=us->alphaTestEnabled) {
+      us->alphaTestEnabled=state;
+      fxMesa->new_state |= FX_NEW_ALPHA;
+      ctx->Driver.RenderStart = fxSetupFXUnits;
+    }
+    break;
+  case GL_BLEND:
+    if(state!=us->blendEnabled) {
+      us->blendEnabled=state;
+      fxMesa->new_state |= FX_NEW_BLEND;
+      ctx->Driver.RenderStart = fxSetupFXUnits;
+    }
+    break;
+  case GL_DEPTH_TEST:
+    if(state!=us->depthTestEnabled) {
+      us->depthTestEnabled=state;
+      fxMesa->new_state |= FX_NEW_DEPTH;
+      ctx->Driver.RenderStart = fxSetupFXUnits;
+    }
+    break;
+  case GL_SCISSOR_TEST:
+     fxMesa->new_state |= FX_NEW_SCISSOR;
+     ctx->Driver.RenderStart = fxSetupFXUnits;
+     break;
+  case GL_FOG:
+     fxMesa->new_state |= FX_NEW_FOG;
+     ctx->Driver.RenderStart = fxSetupFXUnits;
+     break;
+  case GL_CULL_FACE:
+     fxMesa->new_state |= FX_NEW_CULL;
+     ctx->Driver.RenderStart = fxSetupFXUnits;
+     break;
+  case GL_LINE_SMOOTH:
+  case GL_POINT_SMOOTH:
+  case GL_POLYGON_SMOOTH:
+  case GL_TEXTURE_2D:
+      fxMesa->new_state |= FX_NEW_TEXTURING;
+      ctx->Driver.RenderStart = fxSetupFXUnits;
+      break;
+  default:
+    ;  /* XXX no-op??? */
+  }    
+}
+
+/************************************************************************/
+/******************** Fake Multitexture Support *************************/
+/************************************************************************/
+
+/* Its considered cheeky to try to fake ARB multitexture by doing
+ * multipass rendering, because it is not possible to emulate the full
+ * spec in this way.  The fact is that the voodoo 2 supports only a
+ * subset of the possible multitexturing modes, and it is possible to
+ * support almost the same subset using multipass blending on the
+ * voodoo 1.  In all other cases for both voodoo 1 and 2, we fall back
+ * to software rendering, satisfying the spec if not the user.  
+ */
+static GLboolean fxMultipassTexture( struct vertex_buffer *VB, GLuint pass )
+{
+   GLcontext *ctx = VB->ctx;
+   fxVertex *v = FX_DRIVER_DATA(VB)->verts;
+   fxVertex *last = FX_DRIVER_DATA(VB)->last_vert;
+   fxMesaContext fxMesa = FX_CONTEXT(ctx);
+
+   switch (pass) {
+   case 1:
+      if (MESA_VERBOSE&(VERBOSE_DRIVER|VERBOSE_PIPELINE|VERBOSE_TEXTURE))
+        fprintf(stderr, "fxmesa: Second texture pass\n");
+
+      for ( ; v != last ; v++) {
+        v->f[S0COORD] = v->f[S1COORD];
+        v->f[T0COORD] = v->f[T1COORD];
+      }
+
+      fxMesa->restoreUnitsState = fxMesa->unitsState; 
+      fxMesa->tmu_source[0] = 1;
+
+      if (ctx->Depth.Mask) {
+        switch (ctx->Depth.Func) {
+        case GL_NEVER:
+        case GL_ALWAYS:
+           break;
+        default:
+           fxDDDepthFunc( ctx, GL_EQUAL );
+           break;
+        }
+
+        fxDDDepthMask( ctx, GL_FALSE ); 
+      }
+      
+      if (ctx->Texture.Unit[1].EnvMode == GL_MODULATE) {
+        fxDDEnable( ctx, GL_BLEND, GL_TRUE );
+        fxDDBlendFunc( ctx, GL_DST_COLOR, GL_ZERO );
+      }
+
+      fxSetupTextureSingleTMU( ctx, 1 ); 
+      fxSetupBlend( ctx );
+      fxSetupDepthTest( ctx );
+      break;
+
+   case 2:
+      /* Restore original state.  
+       */
+      fxMesa->tmu_source[0] = 0;
+      fxMesa->unitsState = fxMesa->restoreUnitsState;
+      fxMesa->setupdone &= ~SETUP_TMU0;
+      fxSetupTextureSingleTMU( ctx, 0 ); 
+      fxSetupBlend( ctx );
+      fxSetupDepthTest( ctx );
+      break;
+   }
+
+   return pass == 1;      
+}
+
+
+/************************************************************************/
+/************************** Changes to units state **********************/
+/************************************************************************/
+
+
+/* All units setup is handled under texture setup.
+ */
+void fxDDShadeModel(GLcontext *ctx, GLenum mode)
+{
+   FX_CONTEXT(ctx)->new_state |= FX_NEW_TEXTURING;
+   ctx->Driver.RenderStart = fxSetupFXUnits;
+}
+
+
+
+/************************************************************************/
+/****************************** Units SetUp *****************************/
+/************************************************************************/
+void gl_print_fx_state_flags( const char *msg, GLuint flags )
+{
+   fprintf(stderr, 
+          "%s: (0x%x) %s%s%s%s%s%s%s\n",
+          msg,
+          flags,
+          (flags & FX_NEW_TEXTURING)   ? "texture, " : "",
+          (flags & FX_NEW_BLEND)       ? "blend, " : "",
+          (flags & FX_NEW_ALPHA)       ? "alpha, " : "",
+          (flags & FX_NEW_FOG)         ? "fog, " : "",
+          (flags & FX_NEW_SCISSOR)     ? "scissor, " : "",
+          (flags & FX_NEW_COLOR_MASK)  ? "colormask, " : "",
+          (flags & FX_NEW_CULL)        ? "cull, " : "");
+}
+
+void fxSetupFXUnits( GLcontext *ctx )
+{
+  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+  GLuint newstate = fxMesa->new_state;
+
+  if (MESA_VERBOSE&VERBOSE_DRIVER) 
+     gl_print_fx_state_flags("fxmesa: fxSetupFXUnits", newstate);
+
+  if (newstate) {
+     if (newstate & FX_NEW_TEXTURING)
+       fxSetupTexture(ctx);
+
+     if (newstate & FX_NEW_BLEND)
+       fxSetupBlend(ctx);
+
+     if (newstate & FX_NEW_ALPHA)
+       fxSetupAlphaTest(ctx);
+     
+     if (newstate & FX_NEW_DEPTH)
+       fxSetupDepthTest(ctx);
+
+     if (newstate & FX_NEW_FOG)
+       fxSetupFog(ctx,GL_FALSE);
+
+     if (newstate & FX_NEW_SCISSOR)
+       fxSetupScissor(ctx);
+
+     if (newstate & FX_NEW_COLOR_MASK)
+       fxSetupColorMask(ctx);
+
+     if (newstate & FX_NEW_CULL)
+       fxSetupCull(ctx);     
+
+     fxMesa->new_state = 0;
+     ctx->Driver.RenderStart = 0;
+  }
+}
+
+
+
+#else
+
+
+/*
+ * Need this to provide at least one external definition.
+ */
+
+int gl_fx_dummy_function_setup(void)
+{
+  return 0;
+}
+
+#endif  /* FX */
diff --git a/src/mesa/drivers/glide/fxtexman.c b/src/mesa/drivers/glide/fxtexman.c
new file mode 100644 (file)
index 0000000..5ee145e
--- /dev/null
@@ -0,0 +1,579 @@
+/* -*- mode: C; tab-width:8;  -*-
+
+             fxtexman.c - 3Dfx VooDoo texture memory functions
+*/
+
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * See the file fxapi.c for more informations about authors
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "conf.h"
+#endif
+
+#if defined(FX)
+
+#include "fxdrv.h"
+
+static tfxTMFreeNode *fxTMNewTMFreeNode(FxU32 start, FxU32 end)
+{
+  tfxTMFreeNode *tmn;
+
+  if(!(tmn=malloc(sizeof(tfxTMFreeNode)))) {
+    fprintf(stderr,"fx Driver: out of memory !\n");
+    fxCloseHardware();
+    exit(-1);
+  }
+
+  tmn->next=NULL;
+  tmn->startAddress=start;
+  tmn->endAddress=end;
+
+  return tmn;
+}
+
+static void fxTMUInit(fxMesaContext fxMesa, int tmu)
+{
+  tfxTMFreeNode *tmn,*tmntmp;
+  FxU32 start,end,blockstart,blockend;
+
+  start=grTexMinAddress(tmu);
+  end=grTexMaxAddress(tmu);
+
+  if(fxMesa->verbose) {
+    fprintf(stderr,"%s configuration:",(tmu==FX_TMU0) ? "TMU0" : "TMU1");
+    fprintf(stderr,"  Lower texture memory address (%u)\n",(unsigned int)start);
+    fprintf(stderr,"  Higher texture memory address (%u)\n",(unsigned int)end);
+    fprintf(stderr,"  Splitting Texture memory in 2Mb blocks:\n");
+  }
+
+  fxMesa->freeTexMem[tmu]=end-start;
+  fxMesa->tmFree[tmu]=NULL;
+  fxMesa->tmAlloc[tmu]=NULL;
+
+  blockstart=start;
+  while(blockstart<=end) {
+    if(blockstart+0x1fffff>end)
+      blockend=end;
+    else
+      blockend=blockstart+0x1fffff;
+
+    if(fxMesa->verbose)
+      fprintf(stderr,"    %07u-%07u\n",(unsigned int)blockstart,(unsigned int)blockend);
+
+    tmn=fxTMNewTMFreeNode(blockstart,blockend);
+
+    if(fxMesa->tmFree[tmu]) {
+      for(tmntmp=fxMesa->tmFree[tmu];tmntmp->next!=NULL;tmntmp=tmntmp->next){};
+      tmntmp->next=tmn;
+    } else
+      fxMesa->tmFree[tmu]=tmn;
+
+    blockstart+=0x1fffff+1;
+  }
+}
+
+void fxTMInit(fxMesaContext fxMesa)
+{
+  fxTMUInit(fxMesa,FX_TMU0);
+
+  if(fxMesa->haveTwoTMUs)
+    fxTMUInit(fxMesa,FX_TMU1);
+
+  fxMesa->texBindNumber=0;
+}
+
+static struct gl_texture_object *fxTMFindOldestTMBlock(fxMesaContext fxMesa,
+                                                      tfxTMAllocNode *tmalloc,
+                                                      GLuint texbindnumber)
+{
+  GLuint age,oldestage,lasttimeused;
+  struct gl_texture_object *oldesttexobj;
+
+  (void)fxMesa;
+  oldesttexobj=tmalloc->tObj;
+  oldestage=0;
+
+  while(tmalloc) {
+    lasttimeused=((tfxTexInfo *)(tmalloc->tObj->DriverData))->tmi.lastTimeUsed;
+
+    if(lasttimeused>texbindnumber)
+      age=texbindnumber+(UINT_MAX-lasttimeused+1); /* TO DO: check */
+    else
+      age=texbindnumber-lasttimeused;
+
+    if(age>=oldestage) {
+      oldestage=age;
+      oldesttexobj=tmalloc->tObj;
+    }
+
+    tmalloc=tmalloc->next;
+  }
+
+  return oldesttexobj;
+}
+
+static GLboolean fxTMFreeOldTMBlock(fxMesaContext fxMesa, GLint tmu)
+{
+  struct gl_texture_object *oldesttexobj;
+
+  if(!fxMesa->tmAlloc[tmu])
+    return GL_FALSE;
+
+  oldesttexobj=fxTMFindOldestTMBlock(fxMesa,fxMesa->tmAlloc[tmu],fxMesa->texBindNumber);
+
+  fxTMMoveOutTM(fxMesa,oldesttexobj);
+
+  return GL_TRUE;
+}
+
+static tfxTMFreeNode *fxTMExtractTMFreeBlock(tfxTMFreeNode *tmfree, int texmemsize,
+                                            GLboolean *success, FxU32 *startadr)
+{
+  int blocksize;
+
+  /* TO DO: cut recursion */
+
+  if(!tmfree) {
+    *success=GL_FALSE;
+    return NULL;
+  }
+
+  blocksize=(int)tmfree->endAddress-(int)tmfree->startAddress+1;
+
+  if(blocksize==texmemsize) {
+    tfxTMFreeNode *nexttmfree;
+
+    *success=GL_TRUE;
+    *startadr=tmfree->startAddress;
+
+    nexttmfree=tmfree->next;
+    free(tmfree);
+
+    return nexttmfree;
+  }
+
+  if(blocksize>texmemsize) {
+    *success=GL_TRUE;
+    *startadr=tmfree->startAddress;
+
+    tmfree->startAddress+=texmemsize;
+
+    return tmfree;
+  }
+
+  tmfree->next=fxTMExtractTMFreeBlock(tmfree->next,texmemsize,success,startadr);
+
+  return tmfree;
+}
+
+static tfxTMAllocNode *fxTMGetTMBlock(fxMesaContext fxMesa, struct gl_texture_object *tObj,
+                                     GLint tmu, int texmemsize)
+{
+  tfxTMFreeNode *newtmfree;
+  tfxTMAllocNode *newtmalloc;
+  GLboolean success;
+  FxU32 startadr;
+
+  for(;;) { /* TO DO: improve performaces */
+    newtmfree=fxTMExtractTMFreeBlock(fxMesa->tmFree[tmu],texmemsize,&success,&startadr);
+
+    if(success) {
+      fxMesa->tmFree[tmu]=newtmfree;
+
+      fxMesa->freeTexMem[tmu]-=texmemsize;
+
+      if(!(newtmalloc=malloc(sizeof(tfxTMAllocNode)))) {
+       fprintf(stderr,"fx Driver: out of memory !\n");
+       fxCloseHardware();
+       exit(-1);
+      }
+      
+      newtmalloc->next=fxMesa->tmAlloc[tmu];
+      newtmalloc->startAddress=startadr;
+      newtmalloc->endAddress=startadr+texmemsize-1;
+      newtmalloc->tObj=tObj;
+
+      fxMesa->tmAlloc[tmu]=newtmalloc;
+
+      return newtmalloc;
+    }
+
+    if(!fxTMFreeOldTMBlock(fxMesa,tmu)) {
+      fprintf(stderr,"fx Driver: internal error in fxTMGetTMBlock()\n");
+      fprintf(stderr,"           TMU: %d Size: %d\n",tmu,texmemsize);
+    
+      fxCloseHardware();
+      exit(-1);
+    }
+  }
+}
+
+void fxTMMoveInTM(fxMesaContext fxMesa, struct gl_texture_object *tObj, GLint where)
+{
+  tfxTexInfo *ti=(tfxTexInfo *)tObj->DriverData;
+  int i,l;
+  int texmemsize;
+
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+     fprintf(stderr,"fxmesa: fxTMMoveInTM(%d)\n",tObj->Name);
+  }
+
+  fxMesa->stats.reqTexUpload++;
+
+  if(!ti->validated) {
+    fprintf(stderr,"fx Driver: internal error in fxTMMoveInTM() -> not validated\n");
+    fxCloseHardware();
+    exit(-1);
+  }
+
+  if(ti->tmi.isInTM)
+    return;
+
+  if (MESA_VERBOSE&(VERBOSE_DRIVER|VERBOSE_TEXTURE)) {
+     fprintf(stderr,"fxmesa: downloading %x (%d) in texture memory in %d\n",(GLuint)tObj,tObj->Name,where);
+  }
+
+  ti->tmi.whichTMU=(FxU32)where;
+
+  switch(where) {
+  case FX_TMU0:
+  case FX_TMU1:
+    texmemsize=(int)grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH,&(ti->info));
+    ti->tmi.tm[where]=fxTMGetTMBlock(fxMesa,tObj,where,texmemsize);
+    fxMesa->stats.memTexUpload+=texmemsize;
+
+    for(i=FX_largeLodValue(ti->info),l=ti->minLevel;i<=FX_smallLodValue(ti->info);i++,l++)
+      grTexDownloadMipMapLevel(where,
+                              ti->tmi.tm[where]->startAddress,FX_valueToLod(i),
+                              FX_largeLodLog2(ti->info),FX_aspectRatioLog2(ti->info),
+                              ti->info.format,GR_MIPMAPLEVELMASK_BOTH,
+                              ti->tmi.mipmapLevel[l].data);
+    break;
+  case FX_TMU_SPLIT: /* TO DO: alternate even/odd TMU0/TMU1 */
+    texmemsize=(int)grTexTextureMemRequired(GR_MIPMAPLEVELMASK_ODD,&(ti->info));
+    ti->tmi.tm[FX_TMU0]=fxTMGetTMBlock(fxMesa,tObj,FX_TMU0,texmemsize);
+    fxMesa->stats.memTexUpload+=texmemsize;
+
+    texmemsize=(int)grTexTextureMemRequired(GR_MIPMAPLEVELMASK_EVEN,&(ti->info));
+    ti->tmi.tm[FX_TMU1]=fxTMGetTMBlock(fxMesa,tObj,FX_TMU1,texmemsize);
+    fxMesa->stats.memTexUpload+=texmemsize;
+
+    for(i=FX_largeLodValue(ti->info),l=ti->minLevel;i<=FX_smallLodValue(ti->info);i++,l++) {
+      grTexDownloadMipMapLevel(GR_TMU0,ti->tmi.tm[FX_TMU0]->startAddress,FX_valueToLod(i),
+                              FX_largeLodLog2(ti->info),FX_aspectRatioLog2(ti->info),
+                              ti->info.format,GR_MIPMAPLEVELMASK_ODD,
+                              ti->tmi.mipmapLevel[l].data);
+
+      grTexDownloadMipMapLevel(GR_TMU1,ti->tmi.tm[FX_TMU1]->startAddress,FX_valueToLod(i),
+                              FX_largeLodLog2(ti->info),FX_aspectRatioLog2(ti->info),
+                              ti->info.format,GR_MIPMAPLEVELMASK_EVEN,
+                              ti->tmi.mipmapLevel[l].data);
+    }
+    break;
+  default:
+    fprintf(stderr,"fx Driver: internal error in fxTMMoveInTM() -> wrong tmu (%d)\n",where);
+    fxCloseHardware();
+    exit(-1);
+  }
+
+  fxMesa->stats.texUpload++;
+
+  ti->tmi.isInTM=GL_TRUE;
+}
+
+void fxTMReloadMipMapLevel(fxMesaContext fxMesa, struct gl_texture_object *tObj, GLint level)
+{
+  tfxTexInfo *ti=(tfxTexInfo *)tObj->DriverData;
+  GrLOD_t lodlevel;
+  GLint tmu;
+
+  if(!ti->validated) {
+    fprintf(stderr,"fx Driver: internal error in fxTMReloadMipMapLevel() -> not validated\n");
+    fxCloseHardware();
+    exit(-1);
+  }
+
+  tmu=(int)ti->tmi.whichTMU;
+  fxTMMoveInTM(fxMesa,tObj,tmu);
+
+  fxTexGetInfo(ti->tmi.mipmapLevel[0].width,ti->tmi.mipmapLevel[0].height,
+              &lodlevel,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
+
+  switch(tmu) {
+  case FX_TMU0:
+  case FX_TMU1:
+    grTexDownloadMipMapLevel(tmu,
+                            ti->tmi.tm[tmu]->startAddress,FX_valueToLod(FX_lodToValue(lodlevel)+level),
+                            FX_largeLodLog2(ti->info),FX_aspectRatioLog2(ti->info),
+                            ti->info.format,GR_MIPMAPLEVELMASK_BOTH,
+                            ti->tmi.mipmapLevel[level].data);
+    break;
+  case FX_TMU_SPLIT: /* TO DO: alternate even/odd TMU0/TMU1 */
+    grTexDownloadMipMapLevel(GR_TMU0,
+                            ti->tmi.tm[GR_TMU0]->startAddress,FX_valueToLod(FX_lodToValue(lodlevel)+level),
+                            FX_largeLodLog2(ti->info),FX_aspectRatioLog2(ti->info),
+                            ti->info.format,GR_MIPMAPLEVELMASK_ODD,
+                            ti->tmi.mipmapLevel[level].data);
+    
+    grTexDownloadMipMapLevel(GR_TMU1,
+                            ti->tmi.tm[GR_TMU1]->startAddress,FX_valueToLod(FX_lodToValue(lodlevel)+level),
+                            FX_largeLodLog2(ti->info),FX_aspectRatioLog2(ti->info),
+                            ti->info.format,GR_MIPMAPLEVELMASK_EVEN,
+                            ti->tmi.mipmapLevel[level].data);
+    break;
+  default:
+    fprintf(stderr,"fx Driver: internal error in fxTMReloadMipMapLevel() -> wrong tmu (%d)\n",tmu);
+    fxCloseHardware();
+    exit(-1);
+  }
+}
+
+void fxTMReloadSubMipMapLevel(fxMesaContext fxMesa, struct gl_texture_object *tObj,
+                             GLint level, GLint yoffset, GLint height)
+{
+  tfxTexInfo *ti=(tfxTexInfo *)tObj->DriverData;
+  GrLOD_t lodlevel;
+  unsigned short *data;
+  GLint tmu;
+
+  if(!ti->validated) {
+    fprintf(stderr,"fx Driver: internal error in fxTMReloadSubMipMapLevel() -> not validated\n");
+    fxCloseHardware();
+    exit(-1);
+  }
+
+  tmu=(int)ti->tmi.whichTMU;
+  fxTMMoveInTM(fxMesa,tObj,tmu);
+
+  fxTexGetInfo(ti->tmi.mipmapLevel[0].width,ti->tmi.mipmapLevel[0].height,
+              &lodlevel,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
+
+  if((ti->info.format==GR_TEXFMT_INTENSITY_8) ||
+     (ti->info.format==GR_TEXFMT_P_8) ||
+     (ti->info.format==GR_TEXFMT_ALPHA_8))
+    data=ti->tmi.mipmapLevel[level].data+((yoffset*ti->tmi.mipmapLevel[level].width)>>1);
+  else
+    data=ti->tmi.mipmapLevel[level].data+yoffset*ti->tmi.mipmapLevel[level].width;
+
+  switch(tmu) {
+  case FX_TMU0:
+  case FX_TMU1:
+    grTexDownloadMipMapLevelPartial(tmu,
+                                   ti->tmi.tm[tmu]->startAddress,FX_valueToLod(FX_lodToValue(lodlevel)+level),
+                                   FX_largeLodLog2(ti->info),FX_aspectRatioLog2(ti->info),
+                                   ti->info.format,GR_MIPMAPLEVELMASK_BOTH,
+                                   data,
+                                   yoffset,yoffset+height-1);
+    break;
+  case FX_TMU_SPLIT: /* TO DO: alternate even/odd TMU0/TMU1 */
+    grTexDownloadMipMapLevelPartial(GR_TMU0,
+                                   ti->tmi.tm[FX_TMU0]->startAddress,FX_valueToLod(FX_lodToValue(lodlevel)+level),
+                                   FX_largeLodLog2(ti->info),FX_aspectRatioLog2(ti->info),
+                                   ti->info.format,GR_MIPMAPLEVELMASK_ODD,
+                                   data,
+                                   yoffset,yoffset+height-1);
+
+    grTexDownloadMipMapLevelPartial(GR_TMU1,
+                                   ti->tmi.tm[FX_TMU1]->startAddress,FX_valueToLod(FX_lodToValue(lodlevel)+level),
+                                   FX_largeLodLog2(ti->info),FX_aspectRatioLog2(ti->info),
+                                   ti->info.format,GR_MIPMAPLEVELMASK_EVEN,
+                                   data,
+                                   yoffset,yoffset+height-1);
+    break;
+  default:
+    fprintf(stderr,"fx Driver: internal error in fxTMReloadSubMipMapLevel() -> wrong tmu (%d)\n",tmu);
+    fxCloseHardware();
+    exit(-1);
+  }
+}
+
+static tfxTMAllocNode *fxTMFreeTMAllocBlock(tfxTMAllocNode *tmalloc,
+                                           tfxTMAllocNode *tmunalloc)
+{
+  if(!tmalloc)
+    return NULL;
+
+  if(tmalloc==tmunalloc) {
+    tfxTMAllocNode *newtmalloc;
+
+    newtmalloc=tmalloc->next;
+    free(tmalloc);
+
+    return newtmalloc;
+  }
+
+  tmalloc->next=fxTMFreeTMAllocBlock(tmalloc->next,tmunalloc);
+
+  return tmalloc;
+}
+
+static tfxTMFreeNode *fxTMAddTMFree(tfxTMFreeNode *tmfree, FxU32 startadr, FxU32 endadr)
+{
+  if(!tmfree)
+    return fxTMNewTMFreeNode(startadr,endadr);
+
+  if((endadr+1==tmfree->startAddress) && (tmfree->startAddress & 0x1fffff)) {
+    tmfree->startAddress=startadr;
+
+    return tmfree;
+  }
+
+  if((startadr-1==tmfree->endAddress) && (startadr & 0x1fffff)) {
+    tmfree->endAddress=endadr;
+
+    if((tmfree->next && (endadr+1==tmfree->next->startAddress) &&
+        (tmfree->next->startAddress & 0x1fffff))) {
+      tfxTMFreeNode *nexttmfree;
+
+      tmfree->endAddress=tmfree->next->endAddress;
+
+      nexttmfree=tmfree->next->next;
+      free(tmfree->next);
+
+      tmfree->next=nexttmfree;
+    }
+
+
+    return tmfree;
+  }
+
+  if(startadr<tmfree->startAddress) {
+    tfxTMFreeNode *newtmfree;
+
+    newtmfree=fxTMNewTMFreeNode(startadr,endadr);
+    newtmfree->next=tmfree;
+
+    return newtmfree;
+  }
+
+  tmfree->next=fxTMAddTMFree(tmfree->next,startadr,endadr);
+
+  return tmfree;
+}
+
+static void fxTMFreeTMBlock(fxMesaContext fxMesa, GLint tmu, tfxTMAllocNode *tmalloc)
+{
+  FxU32 startadr,endadr;
+
+  startadr=tmalloc->startAddress;
+  endadr=tmalloc->endAddress;
+
+  fxMesa->tmAlloc[tmu]=fxTMFreeTMAllocBlock(fxMesa->tmAlloc[tmu],tmalloc);
+
+  fxMesa->tmFree[tmu]=fxTMAddTMFree(fxMesa->tmFree[tmu],startadr,endadr);
+
+  fxMesa->freeTexMem[tmu]+=endadr-startadr+1;
+}
+
+void fxTMMoveOutTM(fxMesaContext fxMesa, struct gl_texture_object *tObj)
+{
+  tfxTexInfo *ti=(tfxTexInfo *)tObj->DriverData;
+
+  if (MESA_VERBOSE&VERBOSE_DRIVER) {
+     fprintf(stderr,"fxmesa: fxTMMoveOutTM(%x (%d))\n",(GLuint)tObj,tObj->Name);
+  }
+
+  if(!ti->tmi.isInTM)
+    return;
+
+  switch(ti->tmi.whichTMU) {
+  case FX_TMU0:
+  case FX_TMU1:
+    fxTMFreeTMBlock(fxMesa,(int)ti->tmi.whichTMU,ti->tmi.tm[ti->tmi.whichTMU]);
+    break;
+  case FX_TMU_SPLIT:
+    fxTMFreeTMBlock(fxMesa,FX_TMU0,ti->tmi.tm[FX_TMU0]);
+    fxTMFreeTMBlock(fxMesa,FX_TMU1,ti->tmi.tm[FX_TMU1]);
+    break;
+  default:
+    fprintf(stderr,"fx Driver: internal error in fxTMMoveOutTM()\n");
+    fxCloseHardware();
+    exit(-1);
+  }
+
+  ti->tmi.whichTMU=FX_TMU_NONE;
+  ti->tmi.isInTM=GL_FALSE;
+}
+
+void fxTMFreeTexture(fxMesaContext fxMesa, struct gl_texture_object *tObj)
+{
+  tfxTexInfo *ti=(tfxTexInfo *)tObj->DriverData;
+  int i;
+
+  fxTMMoveOutTM(fxMesa,tObj);
+
+  for(i=0;i<MAX_TEXTURE_LEVELS;i++) {
+    if(ti->tmi.mipmapLevel[i].used &&
+       ti->tmi.mipmapLevel[i].translated)
+      free(ti->tmi.mipmapLevel[i].data);
+
+    (void)ti->tmi.mipmapLevel[i].data;
+  }
+}
+
+void fxTMFreeAllFreeNode(tfxTMFreeNode *fn)
+{
+  if(!fn)
+    return;
+
+  if(fn->next)
+    fxTMFreeAllFreeNode(fn->next);
+
+  free(fn);
+}
+
+void fxTMFreeAllAllocNode(tfxTMAllocNode *an)
+{
+  if(!an)
+    return;
+
+  if(an->next)
+    fxTMFreeAllAllocNode(an->next);
+
+  free(an);
+}
+
+void fxTMClose(fxMesaContext fxMesa)
+{
+  fxTMFreeAllFreeNode(fxMesa->tmFree[FX_TMU0]);
+  fxTMFreeAllAllocNode(fxMesa->tmAlloc[FX_TMU0]);
+  fxMesa->tmFree[FX_TMU0] = NULL;
+  fxMesa->tmAlloc[FX_TMU0] = NULL;
+  if(fxMesa->haveTwoTMUs) {
+    fxTMFreeAllFreeNode(fxMesa->tmFree[FX_TMU1]);
+    fxTMFreeAllAllocNode(fxMesa->tmAlloc[FX_TMU1]);
+    fxMesa->tmFree[FX_TMU1] = NULL;
+    fxMesa->tmAlloc[FX_TMU1] = NULL;
+  }
+}
+
+
+#else
+
+
+/*
+ * Need this to provide at least one external definition.
+ */
+
+int gl_fx_dummy_function_texman(void)
+{
+  return 0;
+}
+
+#endif  /* FX */
diff --git a/src/mesa/drivers/glide/fxwgl.c b/src/mesa/drivers/glide/fxwgl.c
new file mode 100644 (file)
index 0000000..cbea79a
--- /dev/null
@@ -0,0 +1,806 @@
+/* fxwgl.c - Microsoft wgl functions emulation for
+ *           3Dfx VooDoo/Mesa interface
+ */
+
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * See the file fxapi.c for more informations about authors
+ *
+ */
+
+#ifdef __WIN32__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <windows.h>
+#include <GL/gl.h>
+#include <GL/glu.h>
+
+#ifdef __cplusplus
+           }
+#endif
+
+#include <stdio.h>
+#include <GL/fxmesa.h>
+#include "fxdrv.h"
+
+#define MAX_MESA_ATTRS  20
+
+struct __extensions__
+{
+  PROC  proc;
+  char  *name;
+};
+
+struct __pixelformat__
+{
+  PIXELFORMATDESCRIPTOR pfd;
+  GLint mesaAttr[MAX_MESA_ATTRS];
+};
+
+WINGDIAPI void GLAPIENTRY gl3DfxSetPaletteEXT(GLuint *);
+
+static struct __extensions__   ext[] = {
+
+#ifdef GL_EXT_polygon_offset
+   { (PROC)glPolygonOffsetEXT,                 "glPolygonOffsetEXT"            },
+#endif
+   { (PROC)glBlendEquationEXT,                 "glBlendEquationEXT"            },
+   { (PROC)glBlendColorEXT,                    "glBlendColorExt"               },
+   { (PROC)glVertexPointerEXT,                 "glVertexPointerEXT"            },
+   { (PROC)glNormalPointerEXT,                 "glNormalPointerEXT"            },
+   { (PROC)glColorPointerEXT,                  "glColorPointerEXT"             },
+   { (PROC)glIndexPointerEXT,                  "glIndexPointerEXT"             },
+   { (PROC)glTexCoordPointerEXT,               "glTexCoordPointer"             },
+   { (PROC)glEdgeFlagPointerEXT,               "glEdgeFlagPointerEXT"          },
+   { (PROC)glGetPointervEXT,                   "glGetPointervEXT"              },
+   { (PROC)glArrayElementEXT,                  "glArrayElementEXT"             },
+   { (PROC)glDrawArraysEXT,                    "glDrawArrayEXT"                },
+   { (PROC)glAreTexturesResidentEXT,           "glAreTexturesResidentEXT"      },
+   { (PROC)glBindTextureEXT,                   "glBindTextureEXT"              },
+   { (PROC)glDeleteTexturesEXT,                        "glDeleteTexturesEXT"           },
+   { (PROC)glGenTexturesEXT,                   "glGenTexturesEXT"              },
+   { (PROC)glIsTextureEXT,                     "glIsTextureEXT"                },
+   { (PROC)glPrioritizeTexturesEXT,            "glPrioritizeTexturesEXT"       },
+   { (PROC)glCopyTexSubImage3DEXT,             "glCopyTexSubImage3DEXT"        },
+   { (PROC)glTexImage3DEXT,                    "glTexImage3DEXT"               },
+   { (PROC)glTexSubImage3DEXT,                 "glTexSubImage3DEXT"            },
+   { (PROC)gl3DfxSetPaletteEXT,                        "3DFX_set_global_palette"       },
+   { (PROC)glColorTableEXT,                    "glColorTableEXT"               },
+   { (PROC)glColorSubTableEXT,                 "glColorSubTableEXT"            },
+   { (PROC)glGetColorTableEXT,                 "glGetColorTableEXT"            },
+   { (PROC)glGetColorTableParameterfvEXT,      "glGetColorTableParameterfvEXT" },
+   { (PROC)glGetColorTableParameterivEXT,      "glGetColorTableParameterivEXT" },
+   { (PROC)glPointParameterfEXT,               "glPointParameterfEXT"          },
+   { (PROC)glPointParameterfvEXT,              "glPointParameterfvEXT"         },
+   { (PROC)glBlendFuncSeparateINGR,            "glBlendFuncSeparateINGR"       },
+   { (PROC)glLockArraysEXT,                    "glLockArraysEXT"               },
+   { (PROC)glUnlockArraysEXT,                  "glUnlockArraysEXT"             }
+};
+
+static int qt_ext = sizeof(ext) / sizeof(ext[0]);
+
+struct __pixelformat__  pix[] =
+{
+  /* None */
+  {
+    {
+      sizeof(PIXELFORMATDESCRIPTOR),  1,
+      PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|
+      PFD_DOUBLEBUFFER|PFD_SWAP_COPY,
+      PFD_TYPE_RGBA,
+      32,
+      8,0,8,8,8,16,0,24,
+      0,0,0,0,0,
+      0,
+      0,
+      0,
+      PFD_MAIN_PLANE,
+      0,0,0,0
+    },
+    {
+      FXMESA_DOUBLEBUFFER,
+      FXMESA_ALPHA_SIZE,      0,
+      FXMESA_DEPTH_SIZE,      0,
+      FXMESA_STENCIL_SIZE,    0,
+      FXMESA_ACCUM_SIZE,      0,
+      FXMESA_NONE
+    }
+  },
+
+  /* Alpha */
+  {
+    {
+      sizeof(PIXELFORMATDESCRIPTOR),  1,
+      PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|
+      PFD_DOUBLEBUFFER|PFD_SWAP_COPY,
+      PFD_TYPE_RGBA,
+      32,
+      8,0,8,8,8,16,8,24,
+      0,0,0,0,0,
+      0,
+      0,
+      0,
+      PFD_MAIN_PLANE,
+      0,0,0,0
+    },
+    {
+      FXMESA_DOUBLEBUFFER,
+      FXMESA_ALPHA_SIZE,      8,
+      FXMESA_DEPTH_SIZE,      0,
+      FXMESA_STENCIL_SIZE,    0,
+      FXMESA_ACCUM_SIZE,      0,
+      FXMESA_NONE
+    }
+  },
+
+  /* Depth */
+  {
+    {
+      sizeof(PIXELFORMATDESCRIPTOR),  1,
+      PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|
+      PFD_DOUBLEBUFFER|PFD_SWAP_COPY,
+      PFD_TYPE_RGBA,
+      32,
+      8,0,8,8,8,16,0,24,
+      0,0,0,0,0,
+      16,
+      0,
+      0,
+      PFD_MAIN_PLANE,
+      0,0,0,0
+    },
+    {
+      FXMESA_DOUBLEBUFFER,
+      FXMESA_ALPHA_SIZE,      0,
+      FXMESA_DEPTH_SIZE,      16,
+      FXMESA_STENCIL_SIZE,    0,
+      FXMESA_ACCUM_SIZE,      0,
+      FXMESA_NONE
+    }
+  }
+};
+static int qt_pix = sizeof(pix) / sizeof(pix[0]);
+
+static fxMesaContext ctx = NULL;
+static WNDPROC hWNDOldProc;
+static int curPFD = 0;
+static HDC hDC;
+static HWND hWND;
+
+static GLboolean haveDualHead;
+
+/* For the in-window-rendering hack */
+
+static GLboolean   gdiWindowHack;
+static GLboolean   gdiWindowHackEna;
+static void        *dibSurfacePtr;
+static BITMAPINFO  *dibBMI;
+static HBITMAP     dibHBM;
+static HWND        dibWnd;
+
+LONG GLAPIENTRY __wglMonitor(HWND hwnd,UINT message,UINT wParam,LONG lParam)
+
+{
+  long ret; /* Now gives the resized window at the end to hWNDOldProc */
+
+  if(ctx && hwnd == hWND) {
+    switch(message) {
+    case WM_PAINT:
+    case WM_MOVE:
+      break;
+    case WM_DISPLAYCHANGE:
+    case WM_SIZE:
+      if (wParam != SIZE_MINIMIZED) {
+        static int moving = 0;
+        if (!moving) {
+          if(fxQueryHardware()!=GR_SSTTYPE_VOODOO) {
+            if(!grSstControl(GR_CONTROL_RESIZE)) {
+              moving = 1;
+              SetWindowPos(hwnd, 0, 0, 0, 300, 300, SWP_NOMOVE|SWP_NOZORDER);
+              moving = 0;
+              if(!grSstControl(GR_CONTROL_RESIZE)) {
+                /*MessageBox(0,_T("Error changing windowsize"),_T("fxMESA"),MB_OK);*/
+                PostMessage(hWND,WM_CLOSE,0,0);
+              }
+            }
+          }
+
+          /* Do the clipping in the glide library */
+          grClipWindow(0,0,grSstScreenWidth(),grSstScreenHeight());
+          /* And let the new size set in the context */
+          fxMesaUpdateScreenSize(ctx);
+        }
+      }
+      break;
+    case WM_ACTIVATE:
+      if((fxQueryHardware()==GR_SSTTYPE_VOODOO) &&
+         (!gdiWindowHack) &&
+         (!haveDualHead)) {
+        WORD fActive = LOWORD(wParam);
+        BOOL fMinimized = (BOOL) HIWORD(wParam);
+
+        if((fActive == WA_INACTIVE) || fMinimized)
+          grSstControl(GR_CONTROL_DEACTIVATE);
+        else
+          grSstControl(GR_CONTROL_ACTIVATE);
+      }
+      break;
+    case WM_SHOWWINDOW:
+      break;
+    case WM_SYSCHAR:
+      if(gdiWindowHackEna && (VK_RETURN == wParam)) {
+        if(gdiWindowHack) {
+          gdiWindowHack = GL_FALSE;
+          grSstControl(GR_CONTROL_ACTIVATE);
+        } else {
+          gdiWindowHack = GL_TRUE;
+          grSstControl(GR_CONTROL_DEACTIVATE);
+        }
+      }
+      break;
+    }
+  }
+
+  /* Finaly call the hWNDOldProc, which handles the resize witch the
+     now changed window sizes */
+  ret = CallWindowProc( hWNDOldProc, hwnd, message, wParam, lParam );
+
+  return(ret);
+}
+
+BOOL GLAPIENTRY wglCopyContext(HGLRC hglrcSrc,HGLRC hglrcDst,UINT mask)
+{
+  return(FALSE);
+}
+
+HGLRC GLAPIENTRY wglCreateContext(HDC hdc)
+{
+  HWND hWnd;
+  WNDPROC oldProc;
+  int error;
+
+  if(ctx) {
+    SetLastError(0);
+    return(NULL);
+  }
+
+  if(!(hWnd = WindowFromDC(hdc))) {
+    SetLastError(0);
+    return(NULL);
+  }
+
+  if(curPFD == 0) {
+    SetLastError(0);
+    return(NULL);
+  }
+
+  if((oldProc = (WNDPROC)GetWindowLong(hWnd,GWL_WNDPROC)) != __wglMonitor) {
+    hWNDOldProc = oldProc;
+    SetWindowLong(hWnd,GWL_WNDPROC,(LONG)__wglMonitor);
+  }
+
+#ifndef FX_SILENT
+  freopen("MESA.LOG","w",stderr);
+#endif
+
+  ShowWindow(hWnd, SW_SHOWNORMAL);
+  SetForegroundWindow(hWnd);
+  Sleep(100); /* an hack for win95 */
+
+  if(fxQueryHardware() == GR_SSTTYPE_VOODOO) {
+    RECT cliRect;
+
+    GetClientRect(hWnd,&cliRect);
+    error = !(ctx = fxMesaCreateBestContext((GLuint)hWnd,cliRect.right,cliRect.bottom,
+                                            pix[curPFD - 1].mesaAttr));
+
+    if(!error) {
+      /* create the DIB section for windowed rendering */
+      DWORD *p;
+
+      dibWnd = hWnd;
+
+      hDC = GetDC(dibWnd);
+
+      dibBMI = (BITMAPINFO*) malloc( sizeof(BITMAPINFO) + (256*sizeof(RGBQUAD)));
+
+      memset(dibBMI,0,sizeof(BITMAPINFO) + (256*sizeof(RGBQUAD)));
+
+      dibBMI->bmiHeader.biSize                  = sizeof(BITMAPINFOHEADER);
+      dibBMI->bmiHeader.biWidth                 = ctx->width;
+      dibBMI->bmiHeader.biHeight                = -ctx->height;
+      dibBMI->bmiHeader.biPlanes                = (short)1;
+      dibBMI->bmiHeader.biBitCount              = (short)16;
+      dibBMI->bmiHeader.biCompression           = BI_BITFIELDS;
+      dibBMI->bmiHeader.biSizeImage             = 0;
+      dibBMI->bmiHeader.biXPelsPerMeter         = 0;
+      dibBMI->bmiHeader.biYPelsPerMeter         = 0;
+      dibBMI->bmiHeader.biClrUsed               = 3;
+      dibBMI->bmiHeader.biClrImportant          = 3;
+
+      p = (DWORD*)dibBMI->bmiColors;
+      p[0] = 0xF800;
+      p[1] = 0x07E0;
+      p[2] = 0x001F;
+
+      dibHBM = CreateDIBSection(hDC, dibBMI, DIB_RGB_COLORS, &dibSurfacePtr, NULL, 0);
+
+      ReleaseDC(dibWnd, hDC);
+
+      gdiWindowHackEna = (dibHBM != NULL ? GL_TRUE : GL_FALSE);
+
+      if (!getenv("MESA_WGL_FX") || !strcmp(getenv("MESA_WGL_FX"),"fullscreen"))
+        gdiWindowHack = GL_FALSE;
+      else {
+        gdiWindowHack = GL_TRUE;
+        grSstControl(GR_CONTROL_DEACTIVATE);
+      }
+    }
+  } else {
+    /* For the Voodoo Rush */
+
+    if(getenv("MESA_WGL_FX") && !strcmp(getenv("MESA_WGL_FX"),"fullscreen")) {
+      RECT cliRect;
+
+      GetClientRect(hWnd,&cliRect);
+      error = !(ctx = fxMesaCreateBestContext((GLuint)hWnd,cliRect.right,cliRect.bottom,
+                                              pix[curPFD - 1].mesaAttr));
+    } else
+      error = !(ctx = fxMesaCreateContext((GLuint)hWnd,GR_RESOLUTION_NONE,GR_REFRESH_75Hz,
+                                          pix[curPFD - 1].mesaAttr));
+  }
+
+  if(getenv("SST_DUALHEAD"))
+    haveDualHead=((atoi(getenv("SST_DUALHEAD"))==1) ? GL_TRUE:GL_FALSE);
+  else
+    haveDualHead=GL_FALSE;
+
+  if(error) {
+    SetLastError(0);
+    return(NULL);
+  }
+
+  hDC = hdc;
+  hWND = hWnd;
+
+  /* Required by the OpenGL Optimizer 1.1 (is it a Optimizer bug ?) */
+  wglMakeCurrent(hdc,(HGLRC)1);
+
+  return((HGLRC)1);
+}
+
+HGLRC GLAPIENTRY wglCreateLayerContext(HDC hdc,int iLayerPlane)
+{
+  SetLastError(0);
+  return(NULL);
+}
+
+BOOL GLAPIENTRY wglDeleteContext(HGLRC hglrc)
+{
+  if(ctx && hglrc == (HGLRC)1) {
+    if (gdiWindowHackEna) {
+      DeleteObject(dibHBM);
+      free(dibBMI);
+
+      dibSurfacePtr = NULL;
+      dibBMI = NULL;
+      dibHBM = NULL;
+      dibWnd = NULL;
+    }
+
+    fxMesaDestroyContext(ctx);
+
+    SetWindowLong(WindowFromDC(hDC),GWL_WNDPROC,(LONG)hWNDOldProc);
+
+    ctx = NULL;
+    hDC = 0;
+    return(TRUE);
+  }
+
+  SetLastError(0);
+
+  return(FALSE);
+}
+
+HGLRC GLAPIENTRY wglGetCurrentContext(VOID)
+{
+  if(ctx)
+    return((HGLRC)1);
+
+  SetLastError(0);
+  return(NULL);
+}
+
+HDC GLAPIENTRY wglGetCurrentDC(VOID)
+{
+  if(ctx)
+    return(hDC);
+
+  SetLastError(0);
+  return(NULL);
+}
+
+PROC GLAPIENTRY wglGetProcAddress(LPCSTR lpszProc)
+{
+  int           i;
+
+  /*fprintf(stderr,"fxMesa: looking for extension %s\n",lpszProc);
+    fflush(stderr);*/
+
+  for(i = 0;i < qt_ext;i++)
+    if(!strcmp(lpszProc,ext[i].name)) {
+      /*fprintf(stderr,"fxMesa: found extension %s\n",lpszProc);
+        fflush(stderr);*/
+
+      return(ext[i].proc);
+    }
+  SetLastError(0);
+  return(NULL);
+}
+
+BOOL GLAPIENTRY wglMakeCurrent(HDC hdc,HGLRC hglrc)
+{
+  if((hdc==NULL) && (hglrc==NULL))
+    return(TRUE);
+
+  if(!ctx || hglrc != (HGLRC)1 || WindowFromDC(hdc) != hWND) {
+    SetLastError(0);
+    return(FALSE);
+  }
+
+  hDC = hdc;
+
+  fxMesaMakeCurrent(ctx);
+
+  return(TRUE);
+}
+
+BOOL GLAPIENTRY wglShareLists(HGLRC hglrc1,HGLRC hglrc2)
+{
+  if(!ctx || hglrc1 != (HGLRC)1 || hglrc1 != hglrc2) {
+    SetLastError(0);
+    return(FALSE);
+  }
+
+  return(TRUE);
+}
+
+BOOL GLAPIENTRY wglUseFontBitmaps(HDC fontDevice, DWORD firstChar, DWORD numChars, DWORD listBase)
+{
+#define VERIFY(a) a
+
+  TEXTMETRIC metric;
+  BITMAPINFO *dibInfo;
+  HDC bitDevice;
+  COLORREF tempColor;
+  int i;
+
+  VERIFY(GetTextMetrics(fontDevice, &metric));
+
+  dibInfo = (BITMAPINFO *) calloc(sizeof(BITMAPINFO) + sizeof(RGBQUAD), 1);
+  dibInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+  dibInfo->bmiHeader.biPlanes = 1;
+  dibInfo->bmiHeader.biBitCount = 1;
+  dibInfo->bmiHeader.biCompression = BI_RGB;
+
+  bitDevice = CreateCompatibleDC(fontDevice);
+  // HDC bitDevice = CreateDC("DISPLAY", NULL, NULL, NULL);
+  // VERIFY(bitDevice);
+
+  // Swap fore and back colors so the bitmap has the right polarity
+  tempColor = GetBkColor(bitDevice);
+  SetBkColor(bitDevice, GetTextColor(bitDevice));
+  SetTextColor(bitDevice, tempColor);
+
+  // Place chars based on base line
+  VERIFY(SetTextAlign(bitDevice, TA_BASELINE) >= 0);
+
+  for(i = 0; i < numChars; i++) {
+    SIZE size;
+    char curChar;
+    int charWidth,charHeight,bmapWidth,bmapHeight,numBytes,res;
+    HBITMAP bitObject;
+    HGDIOBJ origBmap;
+    unsigned char *bmap;
+
+    curChar = i + firstChar;
+
+    // Find how high/wide this character is
+    VERIFY(GetTextExtentPoint32(bitDevice, &curChar, 1, &size));
+
+    // Create the output bitmap
+    charWidth = size.cx;
+    charHeight = size.cy;
+    bmapWidth = ((charWidth + 31) / 32) * 32;   // Round up to the next multiple of 32 bits
+    bmapHeight = charHeight;
+    bitObject = CreateCompatibleBitmap(bitDevice,
+                                       bmapWidth,
+                                       bmapHeight);
+    //VERIFY(bitObject);
+
+    // Assign the output bitmap to the device
+    origBmap = SelectObject(bitDevice, bitObject);
+    VERIFY(origBmap);
+
+    VERIFY( PatBlt( bitDevice, 0, 0, bmapWidth, bmapHeight,BLACKNESS ) );
+
+    // Use our source font on the device
+    VERIFY(SelectObject(bitDevice, GetCurrentObject(fontDevice,OBJ_FONT)));
+
+    // Draw the character
+    VERIFY(TextOut(bitDevice, 0, metric.tmAscent, &curChar, 1));
+
+    // Unselect our bmap object
+    VERIFY(SelectObject(bitDevice, origBmap));
+
+    // Convert the display dependant representation to a 1 bit deep DIB
+    numBytes = (bmapWidth * bmapHeight) / 8;
+    bmap = malloc(numBytes);
+    dibInfo->bmiHeader.biWidth = bmapWidth;
+    dibInfo->bmiHeader.biHeight = bmapHeight;
+    res = GetDIBits(bitDevice, bitObject, 0, bmapHeight, bmap,
+                    dibInfo,
+                    DIB_RGB_COLORS);
+    //VERIFY(res);
+
+    // Create the GL object
+    glNewList(i + listBase, GL_COMPILE);
+    glBitmap(bmapWidth, bmapHeight, 0.0, metric.tmDescent,
+             charWidth, 0.0,
+             bmap);
+    glEndList();
+    // CheckGL();
+
+    // Destroy the bmap object
+    DeleteObject(bitObject);
+
+    // Deallocate the bitmap data
+    free(bmap);
+  }
+
+  // Destroy the DC
+  VERIFY(DeleteDC(bitDevice));
+
+  free(dibInfo);
+
+  return TRUE;
+#undef VERIFY
+}
+
+BOOL GLAPIENTRY wglUseFontBitmapsW(HDC hdc,DWORD first,DWORD count,DWORD listBase)
+{
+  return(FALSE);
+}
+
+BOOL GLAPIENTRY wglUseFontOutlinesA(HDC hdc,DWORD first,DWORD count,
+                                  DWORD listBase,FLOAT deviation,
+                                  FLOAT extrusion,int format,
+                                  LPGLYPHMETRICSFLOAT lpgmf)
+{
+  SetLastError(0);
+  return(FALSE);
+}
+
+BOOL GLAPIENTRY wglUseFontOutlinesW(HDC hdc,DWORD first,DWORD count,
+                                  DWORD listBase,FLOAT deviation,
+                                  FLOAT extrusion,int format,
+                                  LPGLYPHMETRICSFLOAT lpgmf)
+{
+  SetLastError(0);
+  return(FALSE);
+}
+
+
+BOOL GLAPIENTRY wglSwapLayerBuffers(HDC hdc,UINT fuPlanes)
+{
+  if(ctx && WindowFromDC(hdc) == hWND) {
+    fxMesaSwapBuffers();
+
+    return(TRUE);
+  }
+
+  SetLastError(0);
+  return(FALSE);
+}
+
+int GLAPIENTRY wglChoosePixelFormat(HDC hdc,
+                                  CONST PIXELFORMATDESCRIPTOR *ppfd)
+{
+  int i,best=-1,qt_valid_pix;
+
+  qt_valid_pix = qt_pix;
+
+  if(ppfd->nSize != sizeof(PIXELFORMATDESCRIPTOR) || ppfd->nVersion != 1) {
+    SetLastError(0);
+    return(0);
+  }
+
+  for(i = 0;i < qt_valid_pix;i++) {
+    if((ppfd->dwFlags & PFD_DRAW_TO_WINDOW) && !(pix[i].pfd.dwFlags & PFD_DRAW_TO_WINDOW))
+      continue;
+    if((ppfd->dwFlags & PFD_DRAW_TO_BITMAP) && !(pix[i].pfd.dwFlags & PFD_DRAW_TO_BITMAP))
+      continue;
+    if((ppfd->dwFlags & PFD_SUPPORT_GDI) && !(pix[i].pfd.dwFlags & PFD_SUPPORT_GDI))
+      continue;
+    if((ppfd->dwFlags & PFD_SUPPORT_OPENGL) && !(pix[i].pfd.dwFlags & PFD_SUPPORT_OPENGL))
+      continue;
+    if(!(ppfd->dwFlags & PFD_DOUBLEBUFFER_DONTCARE) &&
+       ((ppfd->dwFlags & PFD_DOUBLEBUFFER) != (pix[i].pfd.dwFlags & PFD_DOUBLEBUFFER)))
+      continue;
+    if(!(ppfd->dwFlags & PFD_STEREO_DONTCARE) &&
+       ((ppfd->dwFlags & PFD_STEREO) != (pix[i].pfd.dwFlags & PFD_STEREO)))
+      continue;
+
+    if (ppfd->cDepthBits > 0 && pix[i].pfd.cDepthBits == 0)
+      continue; /* need depth buffer */
+
+    if (ppfd->cAlphaBits > 0 && pix[i].pfd.cAlphaBits == 0)
+      continue; /* need alpha buffer */
+
+    if(ppfd->iPixelType == pix[i].pfd.iPixelType) {
+      best = i + 1;
+      break;
+    }
+  }
+
+  if(best == -1) {
+    SetLastError(0);
+    return(0);
+  }
+
+  return(best);
+}
+
+int GLAPIENTRY ChoosePixelFormat(HDC hdc,
+                              CONST PIXELFORMATDESCRIPTOR *ppfd)
+{
+  return wglChoosePixelFormat(hdc,ppfd);
+}
+
+int GLAPIENTRY wglDescribePixelFormat(HDC hdc,int iPixelFormat,UINT nBytes,
+                                    LPPIXELFORMATDESCRIPTOR ppfd)
+{
+  int qt_valid_pix;
+
+  qt_valid_pix = qt_pix;
+
+  if(iPixelFormat < 1 || iPixelFormat > qt_valid_pix ||
+     ((nBytes != sizeof(PIXELFORMATDESCRIPTOR)) && (nBytes != 0))) {
+    SetLastError(0);
+    return(0);
+  }
+
+  if(nBytes != 0)
+    *ppfd = pix[iPixelFormat - 1].pfd;
+
+  return(qt_valid_pix);
+}
+
+int GLAPIENTRY DescribePixelFormat(HDC hdc,int iPixelFormat,UINT nBytes,
+                                LPPIXELFORMATDESCRIPTOR ppfd)
+{
+  return wglDescribePixelFormat(hdc,iPixelFormat,nBytes,ppfd);
+}
+
+int GLAPIENTRY wglGetPixelFormat(HDC hdc)
+{
+  if(curPFD == 0) {
+    SetLastError(0);
+    return(0);
+  }
+
+  return(curPFD);
+}
+
+int GLAPIENTRY GetPixelFormat(HDC hdc)
+{
+  return wglGetPixelFormat(hdc);
+}
+
+BOOL GLAPIENTRY wglSetPixelFormat(HDC hdc,int iPixelFormat,
+                                CONST PIXELFORMATDESCRIPTOR *ppfd)
+{
+  int qt_valid_pix;
+
+  qt_valid_pix = qt_pix;
+
+  if(iPixelFormat < 1 || iPixelFormat > qt_valid_pix || ppfd->nSize != sizeof(PIXELFORMATDESCRIPTOR)) {
+    SetLastError(0);
+    return(FALSE);
+  }
+  curPFD = iPixelFormat;
+
+  return(TRUE);
+}
+
+BOOL GLAPIENTRY wglSwapBuffers(HDC hdc)
+{
+  if(!ctx) {
+    SetLastError(0);
+    return(FALSE);
+  }
+
+  fxMesaSwapBuffers();
+
+  if(gdiWindowHack) {
+    GLuint width=ctx->width;
+    GLuint height=ctx->height;
+
+    HDC hdcScreen      = GetDC(dibWnd);
+    HDC hdcDIBSection  = CreateCompatibleDC(hdcScreen);
+    HBITMAP holdBitmap = (HBITMAP) SelectObject(hdcDIBSection, dibHBM);
+
+    grLfbReadRegion(GR_BUFFER_FRONTBUFFER, 0, 0,
+                    width, height,
+                    width * 2,
+                    dibSurfacePtr);
+
+    /* Since the hardware is configured for GR_COLORFORMAT_ABGR the pixel data is
+     * going to come out as BGR 565, which is reverse of what we need for blitting
+     * to screen, so we need to convert it here pixel-by-pixel (ick). This loop would NOT
+     * be required if the color format was changed to GR_COLORFORMAT_ARGB, but I do
+     * not know the ramifications of that, so this will work until that is resolved.
+     *
+     * This routine CRIES out for MMX implementation, however since that's not
+     * guaranteed to be running on MMX enabled hardware so I'm not going to do
+     * that. I'm just going to try to make a reasonably efficient C
+     * version. -TAJ
+     *
+     * This routine drops frame rate by <1 fps on a 200Mhz MMX processor with a 640x480
+     * display. Obviously, it's performance hit will be higher on larger displays and
+     * less on smaller displays. To support the window-hack display this is probably fine.
+     */
+    {
+      unsigned long *pixel = dibSurfacePtr;
+      unsigned long count = (width * height) / 2;
+
+      while (count--)
+        {
+          *pixel++ = (*pixel & 0x07e007e0)                /* greens */
+            | ((*pixel & 0xf800f800) >> 11) /* swap blues */
+            | ((*pixel & 0x001f001f) << 11) /* swap reds */
+            ;
+        }
+    }
+
+    BitBlt(hdcScreen, 0, 0,
+           width, height,
+           hdcDIBSection,
+           0, 0, SRCCOPY);
+
+    ReleaseDC(dibWnd, hdcScreen);
+    SelectObject(hdcDIBSection, holdBitmap);
+    DeleteDC(hdcDIBSection);
+  }
+
+  return(TRUE);
+}
+
+BOOL GLAPIENTRY SetPixelFormat(HDC hdc, int iPixelFormat,
+                             CONST PIXELFORMATDESCRIPTOR *ppfd)
+{
+  return wglSetPixelFormat(hdc,iPixelFormat,ppfd);
+}
+
+BOOL GLAPIENTRY SwapBuffers(HDC hdc)
+{
+  return wglSwapBuffers(hdc);
+}
+
+#endif /* FX */
diff --git a/src/mesa/drivers/osmesa/osmesa.c b/src/mesa/drivers/osmesa/osmesa.c
new file mode 100644 (file)
index 0000000..25bba5b
--- /dev/null
@@ -0,0 +1,1594 @@
+/* $Id: osmesa.c,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/*
+ * Off-Screen Mesa rendering / Rendering into client memory space
+ */
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <stdlib.h>
+#include <string.h>
+#include "GL/osmesa.h"
+#include "context.h"
+#include "depth.h"
+#include "macros.h"
+#include "matrix.h"
+#include "types.h"
+#include "vb.h"
+#endif
+
+
+struct osmesa_context {
+   GLcontext *gl_ctx;          /* The core GL/Mesa context */
+   GLvisual *gl_visual;                /* Describes the buffers */
+   GLframebuffer *gl_buffer;   /* Depth, stencil, accum, etc buffers */
+   GLenum format;              /* either GL_RGBA or GL_COLOR_INDEX */
+   void *buffer;               /* the image buffer */
+   GLint width, height;                /* size of image buffer */
+   GLuint pixel;               /* current color index or RGBA pixel value */
+   GLuint clearpixel;          /* pixel for clearing the color buffer */
+   GLint rowlength;            /* number of pixels per row */
+   GLint userRowLength;                /* user-specified number of pixels per row */
+   GLint rshift, gshift;       /* bit shifts for RGBA formats */
+   GLint bshift, ashift;
+   GLint rind, gind, bind;     /* index offsets for RGBA formats */
+   void *rowaddr[MAX_HEIGHT];  /* address of first pixel in each image row */
+   GLboolean yup;              /* TRUE  -> Y increases upward */
+                               /* FALSE -> Y increases downward */
+};
+
+
+
+#ifdef THREADS
+
+#include "mthreads.h" /* Mesa platform independent threads interface */
+
+static MesaTSD osmesa_ctx_tsd;
+
+static void osmesa_ctx_thread_init() {
+  MesaInitTSD(&osmesa_ctx_tsd);
+}
+
+static OSMesaContext osmesa_get_thread_context( void ) {
+  return (OSMesaContext) MesaGetTSD(&osmesa_ctx_tsd);
+}
+
+static void osmesa_set_thread_context( OSMesaContext ctx ) {
+  MesaSetTSD(&osmesa_ctx_tsd, ctx, osmesa_ctx_thread_init);
+}
+
+
+#else
+   /* One current context for address space, all threads */
+   static OSMesaContext Current = NULL;
+#endif
+
+
+
+/* A forward declaration: */
+static void osmesa_update_state( GLcontext *ctx );
+
+
+
+/**********************************************************************/
+/*****                    Public Functions                        *****/
+/**********************************************************************/
+
+
+/*
+ * Create an Off-Screen Mesa rendering context.  The only attribute needed is
+ * an RGBA vs Color-Index mode flag.
+ *
+ * Input:  format - either GL_RGBA or GL_COLOR_INDEX
+ *         sharelist - specifies another OSMesaContext with which to share
+ *                     display lists.  NULL indicates no sharing.
+ * Return:  an OSMesaContext or 0 if error
+ */
+OSMesaContext GLAPIENTRY OSMesaCreateContext( GLenum format, OSMesaContext sharelist )
+{
+   OSMesaContext osmesa;
+   GLint rshift, gshift, bshift, ashift;
+   GLint rind, gind, bind;
+   GLint indexBits, alphaBits;
+   GLboolean rgbmode;
+   GLboolean swalpha;
+   GLuint i4 = 1;
+   GLubyte *i1 = (GLubyte *) &i4;
+   GLint little_endian = *i1;
+
+   swalpha = GL_FALSE;
+   rind = gind = bind = 0;
+   if (format==OSMESA_COLOR_INDEX) {
+      indexBits = 8;
+      rshift = gshift = bshift = ashift = 0;
+      rgbmode = GL_FALSE;
+   }
+   else if (format==OSMESA_RGBA) {
+      indexBits = 0;
+      alphaBits = 8;
+      if (little_endian) {
+         rshift = 0;
+         gshift = 8;
+         bshift = 16;
+         ashift = 24;
+      }
+      else {
+         rshift = 24;
+         gshift = 16;
+         bshift = 8;
+         ashift = 0;
+      }
+      rgbmode = GL_TRUE;
+   }
+   else if (format==OSMESA_BGRA) {
+      indexBits = 0;
+      alphaBits = 8;
+      if (little_endian) {
+         ashift = 0;
+         rshift = 8;
+         gshift = 16;
+         bshift = 24;
+      }
+      else {
+         bshift = 24;
+         gshift = 16;
+         rshift = 8;
+         ashift = 0;
+      }
+      rgbmode = GL_TRUE;
+   }
+   else if (format==OSMESA_ARGB) {
+      indexBits = 0;
+      alphaBits = 8;
+      if (little_endian) {
+         bshift = 0;
+         gshift = 8;
+         rshift = 16;
+         ashift = 24;
+      }
+      else {
+         ashift = 24;
+         rshift = 16;
+         gshift = 8;
+         bshift = 0;
+      }
+      rgbmode = GL_TRUE;
+   }
+   else if (format==OSMESA_RGB) {
+      indexBits = 0;
+      alphaBits = 0;
+      bshift = 0;
+      gshift = 8;
+      rshift = 16;
+      ashift = 24;
+      bind = 2;
+      gind = 1;
+      rind = 0;
+      rgbmode = GL_TRUE;
+      swalpha = GL_TRUE;
+   }
+   else if (format==OSMESA_BGR) {
+      indexBits = 0;
+      alphaBits = 0;
+      bshift = 0;
+      gshift = 8;
+      rshift = 16;
+      ashift = 24;
+      bind = 0;
+      gind = 1;
+      rind = 2;
+      rgbmode = GL_TRUE;
+      swalpha = GL_TRUE;
+   }
+   else {
+      return NULL;
+   }
+
+
+   osmesa = (OSMesaContext) calloc( 1, sizeof(struct osmesa_context) );
+   if (osmesa) {
+      osmesa->gl_visual = gl_create_visual( rgbmode,
+                                            swalpha,    /* software alpha */
+                                            GL_FALSE,  /* double buffer */
+                                            GL_FALSE,  /* stereo */
+                                            DEPTH_BITS,
+                                            STENCIL_BITS,
+                                            ACCUM_BITS,
+                                            indexBits,
+                                            8, 8, 8, alphaBits );
+      if (!osmesa->gl_visual) {
+         return NULL;
+      }
+
+      osmesa->gl_ctx = gl_create_context( osmesa->gl_visual,
+                            sharelist ? sharelist->gl_ctx : (GLcontext *) NULL,
+                            (void *) osmesa, GL_TRUE );
+      if (!osmesa->gl_ctx) {
+         gl_destroy_visual( osmesa->gl_visual );
+         free(osmesa);
+         return NULL;
+      }
+      osmesa->gl_buffer = gl_create_framebuffer( osmesa->gl_visual );
+      if (!osmesa->gl_buffer) {
+         gl_destroy_visual( osmesa->gl_visual );
+         gl_destroy_context( osmesa->gl_ctx );
+         free(osmesa);
+         return NULL;
+      }
+      osmesa->format = format;
+      osmesa->buffer = NULL;
+      osmesa->width = 0;
+      osmesa->height = 0;
+      osmesa->pixel = 0;
+      osmesa->clearpixel = 0;
+      osmesa->userRowLength = 0;
+      osmesa->rowlength = 0;
+      osmesa->yup = GL_TRUE;
+      osmesa->rshift = rshift;
+      osmesa->gshift = gshift;
+      osmesa->bshift = bshift;
+      osmesa->ashift = ashift;
+      osmesa->rind = rind;
+      osmesa->gind = gind;
+      osmesa->bind = bind;
+   }
+   return osmesa;
+}
+
+
+
+/*
+ * Destroy an Off-Screen Mesa rendering context.
+ *
+ * Input:  ctx - the context to destroy
+ */
+void GLAPIENTRY OSMesaDestroyContext( OSMesaContext ctx )
+{
+   if (ctx) {
+      gl_destroy_visual( ctx->gl_visual );
+      gl_destroy_framebuffer( ctx->gl_buffer );
+      gl_destroy_context( ctx->gl_ctx );
+      free( ctx );
+   }
+}
+
+
+
+/*
+ * Recompute the values of the context's rowaddr array.
+ */
+static void compute_row_addresses( OSMesaContext ctx )
+{
+   GLint i;
+
+   if (ctx->yup) {
+      /* Y=0 is bottom line of window */
+      if (ctx->format==OSMESA_COLOR_INDEX) {
+         /* 1-byte CI mode */
+         GLubyte *origin = (GLubyte *) ctx->buffer;
+         for (i=0;i<MAX_HEIGHT;i++) {
+            ctx->rowaddr[i] = origin + i * ctx->rowlength;
+         }
+      }
+      else {
+         if ((ctx->format==OSMESA_RGB) || (ctx->format==OSMESA_BGR)) {
+            /* 3-byte RGB mode */
+            GLubyte *origin = (GLubyte *) ctx->buffer;
+            for (i=0;i<MAX_HEIGHT;i++) {
+               ctx->rowaddr[i] = origin + (i * (ctx->rowlength*3));
+            }
+         } else {
+            /* 4-byte RGBA mode */
+            GLuint *origin = (GLuint *) ctx->buffer;
+            for (i=0;i<MAX_HEIGHT;i++) {
+               ctx->rowaddr[i] = origin + i * ctx->rowlength;
+            }
+         }
+      }
+   }
+   else {
+      /* Y=0 is top line of window */
+      if (ctx->format==OSMESA_COLOR_INDEX) {
+         /* 1-byte CI mode */
+         GLubyte *origin = (GLubyte *) ctx->buffer;
+         for (i=0;i<MAX_HEIGHT;i++) {
+            ctx->rowaddr[i] = origin + (ctx->height-i-1) * ctx->rowlength;
+         }
+      }
+      else {
+         if ((ctx->format==OSMESA_RGB) || (ctx->format==OSMESA_BGR)) {
+            /* 3-byte RGB mode */
+            GLubyte *origin = (GLubyte *) ctx->buffer;
+            for (i=0;i<MAX_HEIGHT;i++) {
+               ctx->rowaddr[i] = origin + ((ctx->height-i-1) * (ctx->rowlength*3));
+            }
+         } else {
+            /* 4-byte RGBA mode */
+            GLuint *origin = (GLuint *) ctx->buffer;
+            for (i=0;i<MAX_HEIGHT;i++) {
+               ctx->rowaddr[i] = origin + (ctx->height-i-1) * ctx->rowlength;
+            }
+         }
+      }
+   }
+}
+
+
+/*
+ * Bind an OSMesaContext to an image buffer.  The image buffer is just a
+ * block of memory which the client provides.  Its size must be at least
+ * as large as width*height*sizeof(type).  Its address should be a multiple
+ * of 4 if using RGBA mode.
+ *
+ * Image data is stored in the order of glDrawPixels:  row-major order
+ * with the lower-left image pixel stored in the first array position
+ * (ie. bottom-to-top).
+ *
+ * Since the only type initially supported is GL_UNSIGNED_BYTE, if the
+ * context is in RGBA mode, each pixel will be stored as a 4-byte RGBA
+ * value.  If the context is in color indexed mode, each pixel will be
+ * stored as a 1-byte value.
+ *
+ * If the context's viewport hasn't been initialized yet, it will now be
+ * initialized to (0,0,width,height).
+ *
+ * Input:  ctx - the rendering context
+ *         buffer - the image buffer memory
+ *         type - data type for pixel components, only GL_UNSIGNED_BYTE
+ *                supported now
+ *         width, height - size of image buffer in pixels, at least 1
+ * Return:  GL_TRUE if success, GL_FALSE if error because of invalid ctx,
+ *          invalid buffer address, type!=GL_UNSIGNED_BYTE, width<1, height<1,
+ *          width>internal limit or height>internal limit.
+ */
+GLboolean GLAPIENTRY OSMesaMakeCurrent( OSMesaContext ctx, void *buffer, GLenum type,
+                             GLsizei width, GLsizei height )
+{
+   if (!ctx || !buffer || type!=GL_UNSIGNED_BYTE
+       || width<1 || height<1 || width>MAX_WIDTH || height>MAX_HEIGHT) {
+      return GL_FALSE;
+   }
+
+   osmesa_update_state( ctx->gl_ctx );
+   gl_make_current( ctx->gl_ctx, ctx->gl_buffer );
+
+   ctx->buffer = buffer;
+   ctx->width = width;
+   ctx->height = height;
+   if (ctx->userRowLength)
+      ctx->rowlength = ctx->userRowLength;
+   else
+      ctx->rowlength = width;
+
+#ifdef THREADS
+   /* Set current context for the calling thread */
+   osmesa_set_thread_context(ctx);
+#else
+   /* Set current context for the address space, all threads */
+   Current = ctx;
+#endif
+
+   compute_row_addresses( ctx );
+
+   /* init viewport */
+   if (ctx->gl_ctx->Viewport.Width==0) {
+      /* initialize viewport and scissor box to buffer size */
+      gl_Viewport( ctx->gl_ctx, 0, 0, width, height );
+      ctx->gl_ctx->Scissor.Width = width;
+      ctx->gl_ctx->Scissor.Height = height;
+   }
+
+   return GL_TRUE;
+}
+
+
+
+
+OSMesaContext GLAPIENTRY OSMesaGetCurrentContext( void )
+{
+#ifdef THREADS
+   /* Return current handle for the calling thread */
+   return osmesa_get_thread_context();
+#else
+   /* Return current handle for the address space, all threads */
+   return Current;
+#endif
+}
+
+
+
+void GLAPIENTRY OSMesaPixelStore( GLint pname, GLint value )
+{
+   OSMesaContext ctx = OSMesaGetCurrentContext();
+
+   switch (pname) {
+      case OSMESA_ROW_LENGTH:
+         if (value<0) {
+            gl_error( ctx->gl_ctx, GL_INVALID_VALUE,
+                      "OSMesaPixelStore(value)" );
+            return;
+         }
+         ctx->userRowLength = value;
+         ctx->rowlength = value;
+         break;
+      case OSMESA_Y_UP:
+         ctx->yup = value ? GL_TRUE : GL_FALSE;
+         break;
+      default:
+         gl_error( ctx->gl_ctx, GL_INVALID_ENUM, "OSMesaPixelStore(pname)" );
+         return;
+   }
+
+   compute_row_addresses( ctx );
+}
+
+
+void GLAPIENTRY OSMesaGetIntegerv( GLint pname, GLint *value )
+{
+   OSMesaContext ctx = OSMesaGetCurrentContext();
+
+   switch (pname) {
+      case OSMESA_WIDTH:
+         *value = ctx->width;
+         return;
+      case OSMESA_HEIGHT:
+         *value = ctx->height;
+         return;
+      case OSMESA_FORMAT:
+         *value = ctx->format;
+         return;
+      case OSMESA_TYPE:
+         *value = GL_UNSIGNED_BYTE;
+         return;
+      case OSMESA_ROW_LENGTH:
+         *value = ctx->rowlength;
+         return;
+      case OSMESA_Y_UP:
+         *value = ctx->yup;
+         return;
+      default:
+         gl_error( ctx->gl_ctx, GL_INVALID_ENUM, "OSMesaGetIntergerv(pname)" );
+         return;
+   }
+}
+
+
+
+/*
+ * Return the depth buffer associated with an OSMesa context.
+ * Input:  c - the OSMesa context
+ * Output:  width, height - size of buffer in pixels
+ *          bytesPerValue - bytes per depth value (2 or 4)
+ *          buffer - pointer to depth buffer values
+ * Return:  GL_TRUE or GL_FALSE to indicate success or failure.
+ */
+GLboolean GLAPIENTRY OSMesaGetDepthBuffer( OSMesaContext c, GLint *width, GLint *height,
+                                GLint *bytesPerValue, void **buffer )
+{
+   if ((!c->gl_buffer) || (!c->gl_buffer->Depth)) {
+      *width = 0;
+      *height = 0;
+      *bytesPerValue = 0;
+      *buffer = 0;
+      return GL_FALSE;
+   }
+   else {
+      *width = c->gl_buffer->Width;
+      *height = c->gl_buffer->Height;
+      *bytesPerValue = sizeof(GLdepth);
+      *buffer = c->gl_buffer->Depth;
+      return GL_TRUE;
+   }
+}
+
+
+
+
+/**********************************************************************/
+/*** Device Driver Functions                                        ***/
+/**********************************************************************/
+
+
+/*
+ * Useful macros:
+ */
+#define PACK_RGBA(R,G,B,A)  (  ((R) << osmesa->rshift) \
+                             | ((G) << osmesa->gshift) \
+                             | ((B) << osmesa->bshift) \
+                             | ((A) << osmesa->ashift) )
+
+#define PACK_RGBA2(R,G,B,A)  (  ((R) << rshift) \
+                              | ((G) << gshift) \
+                              | ((B) << bshift) \
+                              | ((A) << ashift) )
+
+#define UNPACK_RED(P)      (((P) >> osmesa->rshift) & 0xff)
+#define UNPACK_GREEN(P)    (((P) >> osmesa->gshift) & 0xff)
+#define UNPACK_BLUE(P)     (((P) >> osmesa->bshift) & 0xff)
+#define UNPACK_ALPHA(P)    (((P) >> osmesa->ashift) & 0xff)
+
+#define PIXELADDR1(X,Y)  ((GLubyte *) osmesa->rowaddr[Y] + (X))
+#define PIXELADDR3(X,Y)  ((GLubyte *) osmesa->rowaddr[Y] + ((X)*3))
+#define PIXELADDR4(X,Y)  ((GLuint *)  osmesa->rowaddr[Y] + (X))
+
+
+
+
+static GLboolean set_buffer( GLcontext *ctx, GLenum mode )
+{
+   (void) ctx;
+   if (mode==GL_FRONT_LEFT) {
+      return GL_TRUE;
+   }
+   else {
+      return GL_FALSE;
+   }
+}
+
+
+static void clear_index( GLcontext *ctx, GLuint index )
+{
+   OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
+   osmesa->clearpixel = index;
+}
+
+
+
+static void clear_color( GLcontext *ctx,
+                         GLubyte r, GLubyte g, GLubyte b, GLubyte a )
+{
+   OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
+   osmesa->clearpixel = PACK_RGBA( r, g, b, a );
+}
+
+
+
+static GLbitfield clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
+                         GLint x, GLint y, GLint width, GLint height )
+{
+   OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
+   if (mask & GL_COLOR_BUFFER_BIT) {
+      if (osmesa->format==OSMESA_COLOR_INDEX) {
+         if (all) {
+            /* Clear whole CI buffer */
+            MEMSET(osmesa->buffer, osmesa->clearpixel,
+                   osmesa->rowlength * osmesa->height);
+         }
+         else {
+            /* Clear part of CI buffer */
+            GLint i, j;
+            for (i=0;i<height;i++) {
+               GLubyte *ptr1 = PIXELADDR1( x, (y+i) );
+               for (j=0;j<width;j++) {
+                  *ptr1++ = osmesa->clearpixel;
+               }
+            }
+         }
+      }
+      else if ((osmesa->format==OSMESA_RGB)||(osmesa->format==OSMESA_BGR)) {
+         GLubyte rval = UNPACK_RED(osmesa->clearpixel);
+         GLubyte gval = UNPACK_GREEN(osmesa->clearpixel);
+         GLubyte bval = UNPACK_BLUE(osmesa->clearpixel);
+         GLint   rind = osmesa->rind;
+         GLint   gind = osmesa->gind;
+         GLint   bind = osmesa->bind;
+         if (all) {
+            GLuint  i, n;
+            GLubyte *ptr3 = (GLubyte *) osmesa->buffer;
+            /* Clear whole RGB buffer */
+            n = osmesa->rowlength * osmesa->height;
+            for (i=0;i<n;i++) {
+               ptr3[rind] = rval;
+               ptr3[gind] = gval;
+               ptr3[bind] = bval;
+               ptr3 += 3;
+            }
+         }
+         else {
+            /* Clear part of RGB buffer */
+            GLint i, j;
+            for (i=0;i<height;i++) {
+               GLubyte *ptr3 = PIXELADDR3( x, (y+i) );
+               for (j=0;j<width;j++) {
+                  ptr3[rind] = rval;
+                  ptr3[gind] = gval;
+                  ptr3[bind] = bval;
+                  ptr3 += 3;
+               }
+            }
+         }
+      }
+      else {
+         if (all) {
+            /* Clear whole RGBA buffer */
+            GLuint i, n, *ptr4;
+            n = osmesa->rowlength * osmesa->height;
+            ptr4 = (GLuint *) osmesa->buffer;
+            for (i=0;i<n;i++) {
+               *ptr4++ = osmesa->clearpixel;
+            }
+         }
+         else {
+            /* Clear part of RGBA buffer */
+            GLint i, j;
+            for (i=0;i<height;i++) {
+               GLuint *ptr4 = PIXELADDR4( x, (y+i) );
+               for (j=0;j<width;j++) {
+                  *ptr4++ = osmesa->clearpixel;
+               }
+            }
+         }
+      }
+   }
+   return mask & (~GL_COLOR_BUFFER_BIT);
+}
+
+
+
+static void set_index( GLcontext *ctx, GLuint index )
+{
+   OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
+   osmesa->pixel = index;
+}
+
+
+
+static void set_color( GLcontext *ctx,
+                       GLubyte r, GLubyte g, GLubyte b, GLubyte a )
+{
+   OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
+   osmesa->pixel = PACK_RGBA( r, g, b, a );
+}
+
+
+
+static void buffer_size( GLcontext *ctx, GLuint *width, GLuint *height )
+{
+   OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
+   *width = osmesa->width;
+   *height = osmesa->height;
+}
+
+
+/**********************************************************************/
+/*****        Read/write spans/arrays of RGBA pixels              *****/
+/**********************************************************************/
+
+/* Write RGBA pixels to an RGBA (or permuted) buffer. */
+static void write_rgba_span( const GLcontext *ctx,
+                             GLuint n, GLint x, GLint y,
+                             CONST GLubyte rgba[][4], const GLubyte mask[] )
+{
+   OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
+   GLuint *ptr4 = PIXELADDR4( x, y );
+   GLuint i;
+   GLint rshift = osmesa->rshift;
+   GLint gshift = osmesa->gshift;
+   GLint bshift = osmesa->bshift;
+   GLint ashift = osmesa->ashift;
+   if (mask) {
+      for (i=0;i<n;i++,ptr4++) {
+         if (mask[i]) {
+            *ptr4 = PACK_RGBA2( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] );
+         }
+      }
+   }
+   else {
+      for (i=0;i<n;i++,ptr4++) {
+         *ptr4 = PACK_RGBA2( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] );
+      }
+   }
+}
+
+
+/* Write RGBA pixels to an RGBA buffer.  This is the fastest span-writer. */
+static void write_rgba_span_rgba( const GLcontext *ctx,
+                                  GLuint n, GLint x, GLint y,
+                                  CONST GLubyte rgba[][4],
+                                  const GLubyte mask[] )
+{
+   OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
+   GLuint *ptr4 = PIXELADDR4( x, y );
+   const GLuint *rgba4 = (const GLuint *) rgba;
+   GLuint i;
+   if (mask) {
+      for (i=0;i<n;i++) {
+         if (mask[i]) {
+            ptr4[i] = rgba4[i];
+         }
+      }
+   }
+   else {
+      MEMCPY( ptr4, rgba4, n * 4 );
+   }
+}
+
+
+/* Write RGB pixels to an RGBA (or permuted) buffer. */
+static void write_rgb_span( const GLcontext *ctx,
+                            GLuint n, GLint x, GLint y,
+                            CONST GLubyte rgb[][3], const GLubyte mask[] )
+{
+   OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
+   GLuint *ptr4 = PIXELADDR4( x, y );
+   GLuint i;
+   GLint rshift = osmesa->rshift;
+   GLint gshift = osmesa->gshift;
+   GLint bshift = osmesa->bshift;
+   GLint ashift = osmesa->ashift;
+   if (mask) {
+      for (i=0;i<n;i++,ptr4++) {
+         if (mask[i]) {
+            *ptr4 = PACK_RGBA2( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP], 255 );
+         }
+      }
+   }
+   else {
+      for (i=0;i<n;i++,ptr4++) {
+         *ptr4 = PACK_RGBA2( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP], 255);
+      }
+   }
+}
+
+
+
+static void write_monocolor_span( const GLcontext *ctx,
+                                  GLuint n, GLint x, GLint y,
+                                 const GLubyte mask[] )
+{
+   OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
+   GLuint *ptr4 = PIXELADDR4(x,y);
+   GLuint i;
+   for (i=0;i<n;i++,ptr4++) {
+      if (mask[i]) {
+         *ptr4 = osmesa->pixel;
+      }
+   }
+}
+
+
+
+static void write_rgba_pixels( const GLcontext *ctx,
+                               GLuint n, const GLint x[], const GLint y[],
+                               CONST GLubyte rgba[][4], const GLubyte mask[] )
+{
+   OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
+   GLuint i;
+   GLint rshift = osmesa->rshift;
+   GLint gshift = osmesa->gshift;
+   GLint bshift = osmesa->bshift;
+   GLint ashift = osmesa->ashift;
+   for (i=0;i<n;i++) {
+      if (mask[i]) {
+         GLuint *ptr4 = PIXELADDR4(x[i],y[i]);
+         *ptr4 = PACK_RGBA2( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] );
+      }
+   }
+}
+
+
+
+static void write_monocolor_pixels( const GLcontext *ctx,
+                                    GLuint n, const GLint x[], const GLint y[],
+                                   const GLubyte mask[] )
+{
+   OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
+   GLuint i;
+   for (i=0;i<n;i++) {
+      if (mask[i]) {
+         GLuint *ptr4 = PIXELADDR4(x[i],y[i]);
+         *ptr4 = osmesa->pixel;
+      }
+   }
+}
+
+
+static void read_rgba_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
+                             GLubyte rgba[][4] )
+{
+   OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
+   GLuint i;
+   GLuint *ptr4 = PIXELADDR4(x,y);
+   for (i=0;i<n;i++) {
+      GLuint pixel = *ptr4++;
+      rgba[i][RCOMP] = UNPACK_RED(pixel);
+      rgba[i][GCOMP] = UNPACK_GREEN(pixel);
+      rgba[i][BCOMP] = UNPACK_BLUE(pixel);
+      rgba[i][ACOMP] = UNPACK_ALPHA(pixel);
+   }
+}
+
+
+/* Read RGBA pixels from an RGBA buffer */
+static void read_rgba_span_rgba( const GLcontext *ctx,
+                                 GLuint n, GLint x, GLint y,
+                                 GLubyte rgba[][4] )
+{
+   OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
+   GLuint *ptr4 = PIXELADDR4(x,y);
+   MEMCPY( rgba, ptr4, n * 4 * sizeof(GLubyte) );
+}
+
+
+static void read_rgba_pixels( const GLcontext *ctx,
+                               GLuint n, const GLint x[], const GLint y[],
+                              GLubyte rgba[][4], const GLubyte mask[] )
+{
+   OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
+   GLuint i;
+   for (i=0;i<n;i++) {
+      if (mask[i]) {
+         GLuint *ptr4 = PIXELADDR4(x[i],y[i]);
+         GLuint pixel = *ptr4;
+         rgba[i][RCOMP] = UNPACK_RED(pixel);
+         rgba[i][GCOMP] = UNPACK_GREEN(pixel);
+         rgba[i][BCOMP] = UNPACK_BLUE(pixel);
+         rgba[i][ACOMP] = UNPACK_ALPHA(pixel);
+      }
+   }
+}
+
+/**********************************************************************/
+/*****                3 byte RGB pixel support funcs              *****/
+/**********************************************************************/
+
+/* Write RGBA pixels to an RGB or BGR buffer. */
+static void write_rgba_span3( const GLcontext *ctx,
+                              GLuint n, GLint x, GLint y,
+                              CONST GLubyte rgba[][4], const GLubyte mask[] )
+{
+   OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
+   GLubyte *ptr3 = PIXELADDR3( x, y);
+   GLuint i;
+   GLint rind = osmesa->rind;
+   GLint gind = osmesa->gind;
+   GLint bind = osmesa->bind;
+   if (mask) {
+      for (i=0;i<n;i++,ptr3+=3) {
+         if (mask[i]) {
+            ptr3[rind] = rgba[i][RCOMP];
+            ptr3[gind] = rgba[i][GCOMP];
+            ptr3[bind] = rgba[i][BCOMP];
+         }
+      }
+   }
+   else {
+      for (i=0;i<n;i++,ptr3+=3) {
+         ptr3[rind] = rgba[i][RCOMP];
+         ptr3[gind] = rgba[i][GCOMP];
+         ptr3[bind] = rgba[i][BCOMP];
+      }
+   }
+}
+
+/* Write RGB pixels to an RGB or BGR buffer. */
+static void write_rgb_span3( const GLcontext *ctx,
+                             GLuint n, GLint x, GLint y,
+                             CONST GLubyte rgb[][3], const GLubyte mask[] )
+{
+   OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
+   GLubyte *ptr3 = PIXELADDR3( x, y);
+   GLuint i;
+   GLint rind = osmesa->rind;
+   GLint gind = osmesa->gind;
+   GLint bind = osmesa->bind;
+   if (mask) {
+      for (i=0;i<n;i++,ptr3+=3) {
+         if (mask[i]) {
+            ptr3[rind] = rgb[i][RCOMP];
+            ptr3[gind] = rgb[i][GCOMP];
+            ptr3[bind] = rgb[i][BCOMP];
+         }
+      }
+   }
+   else {
+      for (i=0;i<n;i++,ptr3+=3) {
+         ptr3[rind] = rgb[i][RCOMP];
+         ptr3[gind] = rgb[i][GCOMP];
+         ptr3[bind] = rgb[i][BCOMP];
+      }
+   }
+}
+
+
+static void write_monocolor_span3( const GLcontext *ctx,
+                                  GLuint n, GLint x, GLint y,
+                                 const GLubyte mask[] )
+{
+   OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
+
+   GLubyte rval = UNPACK_RED(osmesa->pixel);
+   GLubyte gval = UNPACK_GREEN(osmesa->pixel);
+   GLubyte bval = UNPACK_BLUE(osmesa->pixel);
+   GLint   rind = osmesa->rind;
+   GLint   gind = osmesa->gind;
+   GLint   bind = osmesa->bind;
+
+
+   GLubyte *ptr3 = PIXELADDR3( x, y);
+   GLuint i;
+   for (i=0;i<n;i++,ptr3+=3) {
+      if (mask[i]) {
+         ptr3[rind] = rval;
+         ptr3[gind] = gval;
+         ptr3[bind] = bval;
+      }
+   }
+}
+
+static void write_rgba_pixels3( const GLcontext *ctx,
+                                GLuint n, const GLint x[], const GLint y[],
+                                CONST GLubyte rgba[][4], const GLubyte mask[] )
+{
+   OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
+   GLuint i;
+   GLint rind = osmesa->rind;
+   GLint gind = osmesa->gind;
+   GLint bind = osmesa->bind;
+
+   for (i=0;i<n;i++) {
+      if (mask[i]) {
+         GLubyte *ptr3 = PIXELADDR3(x[i],y[i]);
+         ptr3[rind] = rgba[i][RCOMP];
+         ptr3[gind] = rgba[i][GCOMP];
+         ptr3[bind] = rgba[i][BCOMP];
+      }
+   }
+}
+
+static void write_monocolor_pixels3( const GLcontext *ctx,
+                                    GLuint n, const GLint x[], const GLint y[],
+                                   const GLubyte mask[] )
+{
+   OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
+   GLuint i;
+   GLint rind = osmesa->rind;
+   GLint gind = osmesa->gind;
+   GLint bind = osmesa->bind;
+   GLubyte rval = UNPACK_RED(osmesa->pixel);
+   GLubyte gval = UNPACK_GREEN(osmesa->pixel);
+   GLubyte bval = UNPACK_BLUE(osmesa->pixel);
+   for (i=0;i<n;i++) {
+      if (mask[i]) {
+         GLubyte *ptr3 = PIXELADDR3(x[i],y[i]);
+         ptr3[rind] = rval;
+         ptr3[gind] = gval;
+         ptr3[bind] = bval;
+      }
+   }
+}
+
+static void read_rgba_span3( const GLcontext *ctx,
+                             GLuint n, GLint x, GLint y,
+                             GLubyte rgba[][4] )
+{
+   OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
+   GLuint i;
+   GLint rind = osmesa->rind;
+   GLint gind = osmesa->gind;
+   GLint bind = osmesa->bind;
+   GLubyte *ptr3 = PIXELADDR3( x, y);
+   for (i=0;i<n;i++,ptr3+=3) {
+      rgba[i][RCOMP] = ptr3[rind];
+      rgba[i][GCOMP] = ptr3[gind];
+      rgba[i][BCOMP] = ptr3[bind];
+      rgba[i][ACOMP] = 0;
+   }
+}
+
+static void read_rgba_pixels3( const GLcontext *ctx,
+                               GLuint n, const GLint x[], const GLint y[],
+                              GLubyte rgba[][4], const GLubyte mask[] )
+{
+   OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
+   GLuint i;
+   GLint rind = osmesa->rind;
+   GLint gind = osmesa->gind;
+   GLint bind = osmesa->bind;
+   for (i=0;i<n;i++) {
+      if (mask[i]) {
+         GLubyte *ptr3 = PIXELADDR3(x[i],y[i]);
+         rgba[i][RCOMP] = ptr3[rind];
+         rgba[i][GCOMP] = ptr3[gind];
+         rgba[i][BCOMP] = ptr3[bind];
+         rgba[i][ACOMP] = 0;
+      }
+   }
+}
+
+
+/**********************************************************************/
+/*****        Read/write spans/arrays of CI pixels                *****/
+/**********************************************************************/
+
+/* Write 32-bit color index to buffer */
+static void write_index32_span( const GLcontext *ctx,
+                                GLuint n, GLint x, GLint y,
+                                const GLuint index[], const GLubyte mask[] )
+{
+   OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
+   GLubyte *ptr1 = PIXELADDR1(x,y);
+   GLuint i;
+   if (mask) {
+      for (i=0;i<n;i++,ptr1++) {
+         if (mask[i]) {
+            *ptr1 = (GLubyte) index[i];
+         }
+      }
+   }
+   else {
+      for (i=0;i<n;i++,ptr1++) {
+         *ptr1 = (GLubyte) index[i];
+      }
+   }
+}
+
+
+/* Write 8-bit color index to buffer */
+static void write_index8_span( const GLcontext *ctx,
+                               GLuint n, GLint x, GLint y,
+                               const GLubyte index[], const GLubyte mask[] )
+{
+   OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
+   GLubyte *ptr1 = PIXELADDR1(x,y);
+   GLuint i;
+   if (mask) {
+      for (i=0;i<n;i++,ptr1++) {
+         if (mask[i]) {
+            *ptr1 = (GLubyte) index[i];
+         }
+      }
+   }
+   else {
+      MEMCPY( ptr1, index, n );
+   }
+}
+
+
+static void write_monoindex_span( const GLcontext *ctx,
+                                  GLuint n, GLint x, GLint y,
+                                 const GLubyte mask[] )
+{
+   OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
+   GLubyte *ptr1 = PIXELADDR1(x,y);
+   GLuint i;
+   for (i=0;i<n;i++,ptr1++) {
+      if (mask[i]) {
+         *ptr1 = (GLubyte) osmesa->pixel;
+      }
+   }
+}
+
+
+static void write_index_pixels( const GLcontext *ctx,
+                                GLuint n, const GLint x[], const GLint y[],
+                               const GLuint index[], const GLubyte mask[] )
+{
+   OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
+   GLuint i;
+   for (i=0;i<n;i++) {
+      if (mask[i]) {
+         GLubyte *ptr1 = PIXELADDR1(x[i],y[i]);
+         *ptr1 = (GLubyte) index[i];
+      }
+   }
+}
+
+
+static void write_monoindex_pixels( const GLcontext *ctx,
+                                    GLuint n, const GLint x[], const GLint y[],
+                                   const GLubyte mask[] )
+{
+   OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
+   GLuint i;
+   for (i=0;i<n;i++) {
+      if (mask[i]) {
+         GLubyte *ptr1 = PIXELADDR1(x[i],y[i]);
+         *ptr1 = (GLubyte) osmesa->pixel;
+      }
+   }
+}
+
+
+static void read_index_span( const GLcontext *ctx,
+                             GLuint n, GLint x, GLint y, GLuint index[] )
+{
+   OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
+   GLuint i;
+   GLubyte *ptr1 = PIXELADDR1(x,y);
+   for (i=0;i<n;i++,ptr1++) {
+      index[i] = (GLuint) *ptr1;
+   }
+}
+
+
+static void read_index_pixels( const GLcontext *ctx,
+                               GLuint n, const GLint x[], const GLint y[],
+                              GLuint index[], const GLubyte mask[] )
+{
+   OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
+   GLuint i;
+   for (i=0;i<n;i++) {
+      if (mask[i] ) {
+         GLubyte *ptr1 = PIXELADDR1(x[i],y[i]);
+         index[i] = (GLuint) *ptr1;
+      }
+   }
+}
+
+
+
+/**********************************************************************/
+/*****                   Optimized line rendering                 *****/
+/**********************************************************************/
+
+
+/*
+ * Draw a flat-shaded, RGB line into an osmesa buffer.
+ */
+static void flat_rgba_line( GLcontext *ctx,
+                            GLuint vert0, GLuint vert1, GLuint pvert )
+{
+   OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
+   GLubyte *color = ctx->VB->ColorPtr->data[pvert];
+   unsigned long pixel = PACK_RGBA( color[0], color[1], color[2], color[3] );
+
+#define INTERP_XY 1
+#define CLIP_HACK 1
+#define PLOT(X,Y) { GLuint *ptr4 = PIXELADDR4(X,Y); *ptr4 = pixel; }
+
+#ifdef WIN32
+#include "..\linetemp.h"
+#else
+#include "linetemp.h"
+#endif
+}
+
+
+/*
+ * Draw a flat-shaded, Z-less, RGB line into an osmesa buffer.
+ */
+static void flat_rgba_z_line( GLcontext *ctx,
+                              GLuint vert0, GLuint vert1, GLuint pvert )
+{
+   OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
+   GLubyte *color = ctx->VB->ColorPtr->data[pvert];
+   unsigned long pixel = PACK_RGBA( color[0], color[1], color[2], color[3] );
+
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define CLIP_HACK 1
+#define PLOT(X,Y)                              \
+       if (Z < *zPtr) {                        \
+          GLuint *ptr4 = PIXELADDR4(X,Y);      \
+          *ptr4 = pixel;                       \
+          *zPtr = Z;                           \
+       }
+
+#ifdef WIN32
+#include "..\linetemp.h"
+#else
+#include "linetemp.h"
+#endif
+}
+
+
+/*
+ * Draw a flat-shaded, alpha-blended, RGB line into an osmesa buffer.
+ */
+static void flat_blend_rgba_line( GLcontext *ctx,
+                                  GLuint vert0, GLuint vert1, GLuint pvert )
+{
+   OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
+   struct vertex_buffer *VB = ctx->VB;
+   GLint rshift = osmesa->rshift;
+   GLint gshift = osmesa->gshift;
+   GLint bshift = osmesa->bshift;
+   GLint avalue = VB->ColorPtr->data[pvert][3];
+   GLint msavalue = 255 - avalue;
+   GLint rvalue = VB->ColorPtr->data[pvert][0]*avalue;
+   GLint gvalue = VB->ColorPtr->data[pvert][1]*avalue;
+   GLint bvalue = VB->ColorPtr->data[pvert][2]*avalue;
+
+#define INTERP_XY 1
+#define CLIP_HACK 1
+#define PLOT(X,Y)                                      \
+   { GLuint *ptr4 = PIXELADDR4(X,Y); \
+     GLuint  pixel = 0; \
+     pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift);\
+     pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift);\
+     pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift);\
+     *ptr4 = pixel; \
+   }
+
+#ifdef WIN32
+#include "..\linetemp.h"
+#else
+#include "linetemp.h"
+#endif
+}
+
+/*
+ * Draw a flat-shaded, Z-less, alpha-blended, RGB line into an osmesa buffer.
+ */
+static void flat_blend_rgba_z_line( GLcontext *ctx,
+                                   GLuint vert0, GLuint vert1, GLuint pvert )
+{
+   OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
+   struct vertex_buffer *VB = ctx->VB;
+   GLint rshift = osmesa->rshift;
+   GLint gshift = osmesa->gshift;
+   GLint bshift = osmesa->bshift;
+   GLint avalue = VB->ColorPtr->data[pvert][3];
+   GLint msavalue = 256 - avalue;
+   GLint rvalue = VB->ColorPtr->data[pvert][0]*avalue;
+   GLint gvalue = VB->ColorPtr->data[pvert][1]*avalue;
+   GLint bvalue = VB->ColorPtr->data[pvert][2]*avalue;
+
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define CLIP_HACK 1
+#define PLOT(X,Y)                              \
+       if (Z < *zPtr) {                        \
+   { GLuint *ptr4 = PIXELADDR4(X,Y); \
+     GLuint  pixel = 0; \
+     pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift);\
+     pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift);\
+     pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift);\
+     *ptr4 = pixel; \
+   } \
+       }
+
+#ifdef WIN32
+#include "..\linetemp.h"
+#else
+#include "linetemp.h"
+#endif
+}
+
+/*
+ * Draw a flat-shaded, Z-less, alpha-blended, RGB line into an osmesa buffer.
+ */
+static void flat_blend_rgba_z_line_write( GLcontext *ctx,
+                                   GLuint vert0, GLuint vert1, GLuint pvert )
+{
+   OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
+   struct vertex_buffer *VB = ctx->VB;
+   GLint rshift = osmesa->rshift;
+   GLint gshift = osmesa->gshift;
+   GLint bshift = osmesa->bshift;
+   GLint avalue = VB->ColorPtr->data[pvert][3];
+   GLint msavalue = 256 - avalue;
+   GLint rvalue = VB->ColorPtr->data[pvert][0]*avalue;
+   GLint gvalue = VB->ColorPtr->data[pvert][1]*avalue;
+   GLint bvalue = VB->ColorPtr->data[pvert][2]*avalue;
+
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define CLIP_HACK 1
+#define PLOT(X,Y)                              \
+       if (Z < *zPtr) {                        \
+   { GLuint *ptr4 = PIXELADDR4(X,Y); \
+     GLuint  pixel = 0; \
+     pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift);\
+     pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift);\
+     pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift);\
+     *ptr4 = pixel; \
+   } \
+          *zPtr = Z;                           \
+       }
+
+#ifdef WIN32
+#include "..\linetemp.h"
+#else
+#include "linetemp.h"
+#endif
+}
+
+
+/*
+ * Analyze context state to see if we can provide a fast line drawing
+ * function, like those in lines.c.  Otherwise, return NULL.
+ */
+static line_func choose_line_function( GLcontext *ctx )
+{
+   OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
+
+   if (ctx->Line.SmoothFlag)              return NULL;
+   if (ctx->Texture.Enabled)              return NULL;
+   if (ctx->Light.ShadeModel!=GL_FLAT)    return NULL;
+
+   if (ctx->Line.Width==1.0F
+       && ctx->Line.StippleFlag==GL_FALSE) {
+
+       if (ctx->RasterMask==DEPTH_BIT
+           && ctx->Depth.Func==GL_LESS
+           && ctx->Depth.Mask==GL_TRUE) {
+           switch(osmesa->format) {
+                       case OSMESA_RGBA:
+                       case OSMESA_BGRA:
+                       case OSMESA_ARGB:
+                               return flat_rgba_z_line;
+                       default:
+                               return NULL;
+           }
+       }
+
+       if (ctx->RasterMask==0) {
+           switch(osmesa->format) {
+                       case OSMESA_RGBA:
+                       case OSMESA_BGRA:
+                       case OSMESA_ARGB:
+                               return flat_rgba_line;
+                       default:
+                               return NULL;
+           }
+       }
+
+       if (ctx->RasterMask==(DEPTH_BIT|BLEND_BIT)
+           && ctx->Depth.Func==GL_LESS
+           && ctx->Depth.Mask==GL_TRUE
+           && ctx->Color.BlendSrcRGB==GL_SRC_ALPHA
+           && ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA
+           && ctx->Color.BlendSrcA==GL_SRC_ALPHA
+           && ctx->Color.BlendDstA==GL_ONE_MINUS_SRC_ALPHA
+           && ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) {
+           switch(osmesa->format) {
+                       case OSMESA_RGBA:
+                       case OSMESA_BGRA:
+                       case OSMESA_ARGB:
+                               return flat_blend_rgba_z_line_write;
+                       default:
+                               return NULL;
+           }
+       }
+
+       if (ctx->RasterMask==(DEPTH_BIT|BLEND_BIT)
+           && ctx->Depth.Func==GL_LESS
+           && ctx->Depth.Mask==GL_FALSE
+           && ctx->Color.BlendSrcRGB==GL_SRC_ALPHA
+           && ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA
+           && ctx->Color.BlendSrcA==GL_SRC_ALPHA
+           && ctx->Color.BlendDstA==GL_ONE_MINUS_SRC_ALPHA
+           && ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) {
+           switch(osmesa->format) {
+                       case OSMESA_RGBA:
+                       case OSMESA_BGRA:
+                       case OSMESA_ARGB:
+                               return flat_blend_rgba_z_line;
+                       default:
+                               return NULL;
+           }
+       }
+
+       if (ctx->RasterMask==BLEND_BIT
+           && ctx->Color.BlendSrcRGB==GL_SRC_ALPHA
+           && ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA
+           && ctx->Color.BlendSrcA==GL_SRC_ALPHA
+           && ctx->Color.BlendDstA==GL_ONE_MINUS_SRC_ALPHA
+           && ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) {
+           switch(osmesa->format) {
+                       case OSMESA_RGBA:
+                       case OSMESA_BGRA:
+                       case OSMESA_ARGB:
+                               return flat_blend_rgba_line;
+                       default:
+                               return NULL;
+           }
+       }
+
+   }
+   return NULL;
+}
+
+
+/**********************************************************************/
+/*****                 Optimized triangle rendering               *****/
+/**********************************************************************/
+
+
+/*
+ * Smooth-shaded, z-less triangle, RGBA color.
+ */
+static void smooth_rgba_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                                    GLuint v2, GLuint pv )
+{
+   OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
+   GLint rshift = osmesa->rshift;
+   GLint gshift = osmesa->gshift;
+   GLint bshift = osmesa->bshift;
+   GLint ashift = osmesa->ashift;
+   (void) pv;
+#define INTERP_Z 1
+#define INTERP_RGB 1
+#define INTERP_ALPHA 1
+#define INNER_LOOP( LEFT, RIGHT, Y )                           \
+{                                                              \
+   GLint i, len = RIGHT-LEFT;                                  \
+   GLuint *img = PIXELADDR4(LEFT,Y);                                   \
+   for (i=0;i<len;i++,img++) {                                 \
+      GLdepth z = FixedToDepth(ffz);                           \
+      if (z < zRow[i]) {                                       \
+         *img = PACK_RGBA2( FixedToInt(ffr), FixedToInt(ffg),  \
+                           FixedToInt(ffb), FixedToInt(ffa) ); \
+         zRow[i] = z;                                          \
+      }                                                                \
+      ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;  ffa += fdadx;\
+      ffz += fdzdx;                                            \
+   }                                                           \
+}
+#ifdef WIN32
+#include "..\tritemp.h"
+#else
+#include "tritemp.h"
+#endif
+}
+
+
+
+
+/*
+ * Flat-shaded, z-less triangle, RGBA color.
+ */
+static void flat_rgba_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                                   GLuint v2, GLuint pv )
+{
+   OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
+#define INTERP_Z 1
+#define SETUP_CODE                     \
+   GLubyte r = VB->ColorPtr->data[pv][0];      \
+   GLubyte g = VB->ColorPtr->data[pv][1];      \
+   GLubyte b = VB->ColorPtr->data[pv][2];      \
+   GLubyte a = VB->ColorPtr->data[pv][3];      \
+   GLuint pixel = PACK_RGBA(r,g,b,a);
+
+#define INNER_LOOP( LEFT, RIGHT, Y )   \
+{                                      \
+   GLint i, len = RIGHT-LEFT;          \
+   GLuint *img = PIXELADDR4(LEFT,Y);           \
+   for (i=0;i<len;i++,img++) {         \
+      GLdepth z = FixedToDepth(ffz);   \
+      if (z < zRow[i]) {               \
+         *img = pixel;                 \
+         zRow[i] = z;                  \
+      }                                        \
+      ffz += fdzdx;                    \
+   }                                   \
+}
+#ifdef WIN32
+#include "..\tritemp.h"
+#else
+#include "tritemp.h"
+#endif
+}
+
+
+
+/*
+ * Return pointer to an accelerated triangle function if possible.
+ */
+static triangle_func choose_triangle_function( GLcontext *ctx )
+{
+   OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
+
+   if ((osmesa->format==OSMESA_RGB)||(osmesa->format==OSMESA_BGR)) return NULL;
+
+   if (ctx->Polygon.SmoothFlag)     return NULL;
+   if (ctx->Polygon.StippleFlag)    return NULL;
+   if (ctx->Texture.Enabled)        return NULL;
+
+   if (ctx->RasterMask==DEPTH_BIT
+       && ctx->Depth.Func==GL_LESS
+       && ctx->Depth.Mask==GL_TRUE
+       && osmesa->format!=OSMESA_COLOR_INDEX) {
+      if (ctx->Light.ShadeModel==GL_SMOOTH) {
+         return smooth_rgba_z_triangle;
+      }
+      else {
+         return flat_rgba_z_triangle;
+      }
+   }
+   return NULL;
+}
+
+
+
+static const GLubyte *get_string( GLcontext *ctx, GLenum name )
+{
+   (void) ctx;
+   switch (name) {
+      case GL_RENDERER:
+         return (const GLubyte *) "Mesa OffScreen";
+      default:
+         return NULL;
+   }
+}
+
+
+static void osmesa_update_state( GLcontext *ctx )
+{
+   OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
+
+   ctx->Driver.GetString = get_string;
+   ctx->Driver.UpdateState = osmesa_update_state;
+
+   ctx->Driver.SetBuffer = set_buffer;
+   ctx->Driver.Color = set_color;
+   ctx->Driver.Index = set_index;
+   ctx->Driver.ClearIndex = clear_index;
+   ctx->Driver.ClearColor = clear_color;
+   ctx->Driver.Clear = clear;
+
+   ctx->Driver.GetBufferSize = buffer_size;
+
+   ctx->Driver.PointsFunc = NULL;
+   ctx->Driver.LineFunc = choose_line_function( ctx );
+   ctx->Driver.TriangleFunc = choose_triangle_function( ctx );
+
+
+   /* RGB(A) span/pixel functions */
+   if ((osmesa->format==OSMESA_RGB) || (osmesa->format==OSMESA_BGR)) {
+      /* 3 bytes / pixel in frame buffer */
+      ctx->Driver.WriteRGBASpan = write_rgba_span3;
+      ctx->Driver.WriteRGBSpan = write_rgb_span3;
+      ctx->Driver.WriteRGBAPixels = write_rgba_pixels3;
+      ctx->Driver.WriteMonoRGBASpan = write_monocolor_span3;
+      ctx->Driver.WriteMonoRGBAPixels = write_monocolor_pixels3;
+      ctx->Driver.ReadRGBASpan = read_rgba_span3;
+      ctx->Driver.ReadRGBAPixels = read_rgba_pixels3;
+   }
+   else {
+      /* 4 bytes / pixel in frame buffer */
+      if (osmesa->format==OSMESA_RGBA
+          && RCOMP==0 && GCOMP==1 && BCOMP==2 && ACOMP==3)
+         ctx->Driver.WriteRGBASpan = write_rgba_span_rgba;
+      else
+         ctx->Driver.WriteRGBASpan = write_rgba_span;
+      ctx->Driver.WriteRGBSpan = write_rgb_span;
+      ctx->Driver.WriteRGBAPixels = write_rgba_pixels;
+      ctx->Driver.WriteMonoRGBASpan = write_monocolor_span;
+      ctx->Driver.WriteMonoRGBAPixels = write_monocolor_pixels;
+      if (osmesa->format==OSMESA_RGBA
+          && RCOMP==0 && GCOMP==1 && BCOMP==2 && ACOMP==3)
+         ctx->Driver.ReadRGBASpan = read_rgba_span_rgba;
+      else
+         ctx->Driver.ReadRGBASpan = read_rgba_span;
+      ctx->Driver.ReadRGBAPixels = read_rgba_pixels;
+   }
+
+   /* CI span/pixel functions */
+   ctx->Driver.WriteCI32Span = write_index32_span;
+   ctx->Driver.WriteCI8Span = write_index8_span;
+   ctx->Driver.WriteMonoCISpan = write_monoindex_span;
+   ctx->Driver.WriteCI32Pixels = write_index_pixels;
+   ctx->Driver.WriteMonoCIPixels = write_monoindex_pixels;
+   ctx->Driver.ReadCI32Span = read_index_span;
+   ctx->Driver.ReadCI32Pixels = read_index_pixels;
+}
diff --git a/src/mesa/drivers/svga/svgamesa.c b/src/mesa/drivers/svga/svgamesa.c
new file mode 100644 (file)
index 0000000..4c4d9f7
--- /dev/null
@@ -0,0 +1,540 @@
+/* $Id: svgamesa.c,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.0
+ * Copyright (C) 1995-1998  Brian Paul
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+
+/*
+ * Linux SVGA/Mesa interface.
+ *
+ * This interface is not finished!  Still have to implement pixel
+ * reading functions and double buffering.  Then, look into accelerated
+ * line and polygon rendering.  And, clean up a bunch of other stuff.
+ * Any volunteers?
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "conf.h"
+#endif
+
+#ifdef SVGA
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#include <vga.h>
+#include "GL/svgamesa.h"
+#include "context.h"
+#include "matrix.h"
+#include "types.h"
+#endif
+
+
+struct svgamesa_context {
+   GLcontext *gl_ctx;          /* the core Mesa context */
+   GLvisual *gl_vis;           /* describes the color buffer */
+   GLframebuffer *gl_buffer;   /* the ancillary buffers */
+   GLuint index;               /* current color index */
+   GLint red, green, blue;     /* current rgb color */
+   GLint width, height;                /* size of color buffer */
+   GLint depth;                        /* bits per pixel (8,16,24 or 32) */
+};
+
+
+static SVGAMesaContext SVGAMesa = NULL;    /* the current context */
+
+
+
+/*
+ * Convert Mesa window Y coordinate to VGA screen Y coordinate:
+ */
+#define FLIP(Y)  (SVGAMesa->height-(Y)-1)
+
+
+
+/**********************************************************************/
+/*****                 Miscellaneous functions                    *****/
+/**********************************************************************/
+
+
+static void get_buffer_size( GLcontext *ctx, GLuint *width, GLuint *height )
+{
+   *width = SVGAMesa->width = vga_getxdim();
+   *height = SVGAMesa->height = vga_getydim();
+}
+
+
+/* Set current color index */
+static void set_index( GLcontext *ctx, GLuint index )
+{
+   SVGAMesa->index = index;
+   vga_setcolor( index );
+}
+
+
+/* Set current drawing color */
+static void set_color( GLcontext *ctx,
+                       GLubyte red, GLubyte green,
+                       GLubyte blue, GLubyte alpha )
+{
+   SVGAMesa->red = red;
+   SVGAMesa->green = green;
+   SVGAMesa->blue = blue;
+   vga_setrgbcolor( red, green, blue );
+}
+
+
+static void clear_index( GLcontext *ctx, GLuint index )
+{
+   /* TODO: Implements glClearIndex() */
+}
+
+
+static void clear_color( GLcontext *ctx,
+                         GLubyte red, GLubyte green,
+                         GLubyte blue, GLubyte alpha )
+{
+   /* TODO: Implements glClearColor() */
+}
+
+
+static GLbitfield clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
+                         GLint x, GLint y, GLint width, GLint height )
+{
+   if (mask & GL_COLOR_BUFFER_BIT) {
+      vga_clear();
+   }
+   return mask & (~GL_COLOR_BUFFER_BIT);
+}
+
+
+static GLboolean set_buffer( GLcontext *ctx, GLenum buffer )
+{
+   /* TODO: implement double buffering and use this function to select */
+   /* between front and back buffers. */
+   if (buffer == GL_FRONT_LEFT)
+      return GL_TRUE;
+   else if (buffer == GL_BACK_LEFT)
+      return GL_TRUE;
+   else
+      return GL_FALSE;
+}
+
+
+
+
+/**********************************************************************/
+/*****            Write spans of pixels                           *****/
+/**********************************************************************/
+
+
+static void write_ci32_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
+                             const GLuint index[], const GLubyte mask[] )
+{
+   int i;
+   y = FLIP(y);
+   for (i=0;i<n;i++,x++) {
+      if (mask[i]) {
+         vga_setcolor( index[i] );
+         vga_drawpixel( x, y );
+      }
+   }
+}
+
+static void write_ci8_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
+                            const GLubyte index[], const GLubyte mask[] )
+{
+   int i;
+   y = FLIP(y);
+   for (i=0;i<n;i++,x++) {
+      if (mask[i]) {
+         vga_setcolor( index[i] );
+         vga_drawpixel( x, y );
+      }
+   }
+}
+
+
+
+static void write_mono_ci_span( const GLcontext *ctx, GLuint n,
+                                GLint x, GLint y, const GLubyte mask[] )
+{
+   int i;
+   y = FLIP(y);
+   /* use current color index */
+   vga_setcolor( SVGAMesa->index );
+   for (i=0;i<n;i++,x++) {
+      if (mask[i]) {
+         vga_drawpixel( x, y );
+      }
+   }
+}
+
+
+
+static void write_rgba_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
+                             const GLubyte rgba[][4], const GLubyte mask[] )
+{
+   int i;
+   y=FLIP(y);
+   if (mask) {
+      /* draw some pixels */
+      for (i=0; i<n; i++, x++) {
+         if (mask[i]) {
+            vga_setrgbcolor( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
+            vga_drawpixel( x, y );
+         }
+      }
+   }
+   else {
+      /* draw all pixels */
+      for (i=0; i<n; i++, x++) {
+         vga_setrgbcolor( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
+         vga_drawpixel( x, y );
+      }
+   }
+}
+
+
+
+static void write_mono_rgba_span( const GLcontext *ctx,
+                                  GLuint n, GLint x, GLint y,
+                                  const GLubyte mask[])
+{
+   int i;
+   y=FLIP(y);
+   /* use current rgb color */
+   vga_setrgbcolor( SVGAMesa->red, SVGAMesa->green, SVGAMesa->blue );
+   for (i=0; i<n; i++, x++) {
+      if (mask[i]) {
+         vga_drawpixel( x, y );
+      }
+   }
+}
+
+
+
+/**********************************************************************/
+/*****                 Read spans of pixels                       *****/
+/**********************************************************************/
+
+
+static void read_ci32_span( const GLcontext *ctx,
+                            GLuint n, GLint x, GLint y, GLuint index[])
+{
+   int i;
+   y = FLIP(y);
+   for (i=0; i<n; i++,x++) {
+      index[i] = vga_getpixel( x, y );
+   }
+}
+
+
+
+static void read_rgba_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
+                            GLubyte rgba[][4] )
+{
+   int i;
+   for (i=0; i<n; i++, x++) {
+      /* TODO */
+   }
+}
+
+
+
+/**********************************************************************/
+/*****                  Write arrays of pixels                    *****/
+/**********************************************************************/
+
+
+static void write_ci32_pixels( const GLcontext *ctx,
+                               GLuint n, const GLint x[], const GLint y[],
+                               const GLuint index[], const GLubyte mask[] )
+{
+   int i;
+   for (i=0; i<n; i++) {
+      if (mask[i]) {
+         vga_setcolor( index[i] );
+         vga_drawpixel( x[i], FLIP(y[i]) );
+      }
+   }
+}
+
+
+static void write_mono_ci_pixels( const GLcontext *ctx, GLuint n,
+                                  const GLint x[], const GLint y[],
+                                  const GLubyte mask[] )
+{
+   int i;
+   /* use current color index */
+   vga_setcolor( SVGAMesa->index );
+   for (i=0; i<n; i++) {
+      if (mask[i]) {
+         vga_drawpixel( x[i], FLIP(y[i]) );
+      }
+   }
+}
+
+
+
+static void write_rgba_pixels( const GLcontext *ctx,
+                               GLuint n, const GLint x[], const GLint y[],
+                               const GLubyte rgba[][4], const GLubyte mask[] )
+{
+   int i;
+   for (i=0; i<n; i++) {
+      if (mask[i]) {
+         vga_setrgbcolor( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
+         vga_drawpixel( x[i], FLIP(y[i]) );
+      }
+   }
+}
+
+
+
+static void write_mono_rgba_pixels( const GLcontext *ctx,
+                                    GLuint n,
+                                    const GLint x[], const GLint y[],
+                                    const GLubyte mask[] )
+{
+   int i;
+   /* use current rgb color */
+   vga_setrgbcolor( SVGAMesa->red, SVGAMesa->green, SVGAMesa->blue );
+   for (i=0; i<n; i++) {
+      if (mask[i]) {
+         vga_drawpixel( x[i], FLIP(y[i]) );
+      }
+   }
+}
+
+
+
+
+/**********************************************************************/
+/*****                   Read arrays of pixels                    *****/
+/**********************************************************************/
+
+/* Read an array of color index pixels. */
+static void read_ci32_pixels( const GLcontext *ctx,
+                              GLuint n, const GLint x[], const GLint y[],
+                              GLuint index[], const GLubyte mask[] )
+{
+   int i;
+   for (i=0; i<n; i++,x++) {
+      index[i] = vga_getpixel( x[i], FLIP(y[i]) );
+   }
+}
+
+
+
+static void read_rgba_pixels( const GLcontext *ctx,
+                              GLuint n, const GLint x[], const GLint y[],
+                              GLubyte rgba[][4], const GLubyte mask[] )
+{
+   /* TODO */
+}
+
+
+
+static void svgamesa_update_state( GLcontext *ctx )
+{
+   /* Initialize all the pointers in the DD struct.  Do this whenever */
+   /* a new context is made current or we change buffers via set_buffer! */
+
+   ctx->Driver.UpdateState = svgamesa_update_state;
+
+   ctx->Driver.ClearIndex = clear_index;
+   ctx->Driver.ClearColor = clear_color;
+   ctx->Driver.Clear = clear;
+
+   ctx->Driver.Index = set_index;
+   ctx->Driver.Color = set_color;
+
+   ctx->Driver.SetBuffer = set_buffer;
+   ctx->Driver.GetBufferSize = get_buffer_size;
+
+   ctx->Driver.PointsFunc = NULL;
+   ctx->Driver.LineFunc = NULL;
+   ctx->Driver.TriangleFunc = NULL;
+
+   /* Pixel/span writing functions: */
+   /* TODO: use different funcs for 8, 16, 32-bit depths */
+   ctx->Driver.WriteRGBASpan        = write_rgba_span;
+   ctx->Driver.WriteMonoRGBASpan    = write_mono_rgba_span;
+   ctx->Driver.WriteRGBAPixels      = write_rgba_pixels;
+   ctx->Driver.WriteMonoRGBAPixels  = write_mono_rgba_pixels;
+   ctx->Driver.WriteCI32Span        = write_ci32_span;
+   ctx->Driver.WriteCI8Span         = write_ci8_span;
+   ctx->Driver.WriteMonoCISpan      = write_mono_ci_span;
+   ctx->Driver.WriteCI32Pixels      = write_ci32_pixels;
+   ctx->Driver.WriteMonoCIPixels    = write_mono_ci_pixels;
+
+   /* Pixel/span reading functions: */
+   /* TODO: use different funcs for 8, 16, 32-bit depths */
+   ctx->Driver.ReadCI32Span   = read_ci32_span;
+   ctx->Driver.ReadRGBASpan   = read_rgba_span;
+   ctx->Driver.ReadCI32Pixels = read_ci32_pixels;
+   ctx->Driver.ReadRGBAPixels = read_rgba_pixels;
+}
+
+
+
+/*
+ * Create a new VGA/Mesa context and return a handle to it.
+ */
+SVGAMesaContext SVGAMesaCreateContext( GLboolean doubleBuffer )
+{
+   SVGAMesaContext ctx;
+   GLboolean rgb_flag;
+   GLfloat redscale, greenscale, bluescale, alphascale;
+   GLboolean alpha_flag = GL_FALSE;
+   int colors;
+   GLint index_bits;
+   GLint redbits, greenbits, bluebits, alphabits;
+
+   /* determine if we're in RGB or color index mode */
+   colors = vga_getcolors();
+   if (colors==32768) {
+      rgb_flag = GL_TRUE;
+      redscale = greenscale = bluescale = alphascale = 255.0;
+      redbits = greenbits = bluebits = 8;
+      alphabits = 0;
+      index_bits = 0;
+   }
+   else if (colors==256) {
+      rgb_flag = GL_FALSE;
+      redscale = greenscale = bluescale = alphascale = 0.0;
+      redbits = greenbits = bluebits = alphabits = 0;
+      index_bits = 8;
+   }
+   else {
+      printf(">16 bit color not implemented yet!\n");
+      return NULL;
+   }
+
+   ctx = (SVGAMesaContext) calloc( 1, sizeof(struct svgamesa_context) );
+   if (!ctx) {
+      return NULL;
+   }
+
+   ctx->gl_vis = gl_create_visual( rgb_flag,
+                                   alpha_flag,
+                                   doubleBuffer,
+                                   GL_FALSE,  /* stereo */
+                                   16,   /* depth_size */
+                                   8,    /* stencil_size */
+                                   16,   /* accum_size */
+                                   index_bits,
+                                   redbits, greenbits,
+                                   bluebits, alphabits );
+
+   ctx->gl_ctx = gl_create_context( ctx->gl_vis,
+                                    NULL,  /* share list context */
+                                    (void *) ctx, GL_TRUE );
+
+   ctx->gl_buffer = gl_create_framebuffer( ctx->gl_vis );
+
+   ctx->index = 1;
+   ctx->red = ctx->green = ctx->blue = 255;
+
+   ctx->width = ctx->height = 0;  /* temporary until first "make-current" */
+
+   return ctx;
+}
+
+
+
+
+/*
+ * Destroy the given VGA/Mesa context.
+ */
+void SVGAMesaDestroyContext( SVGAMesaContext ctx )
+{
+   if (ctx) {
+      gl_destroy_visual( ctx->gl_vis );
+      gl_destroy_context( ctx->gl_ctx );
+      gl_destroy_framebuffer( ctx->gl_buffer );
+      free( ctx );
+      if (ctx==SVGAMesa) {
+         SVGAMesa = NULL;
+      }
+   }
+}
+
+
+
+/*
+ * Make the specified VGA/Mesa context the current one.
+ */
+void SVGAMesaMakeCurrent( SVGAMesaContext ctx )
+{
+   SVGAMesa = ctx;
+   svgamesa_update_state( ctx->gl_ctx );
+   gl_make_current( ctx->gl_ctx, ctx->gl_buffer );
+
+   if (ctx->width==0 || ctx->height==0) {
+      /* setup initial viewport */
+      ctx->width = vga_getxdim();
+      ctx->height = vga_getydim();
+      gl_Viewport( ctx->gl_ctx, 0, 0, ctx->width, ctx->height );
+   }
+}
+
+
+
+/*
+ * Return a handle to the current VGA/Mesa context.
+ */
+SVGAMesaContext SVGAMesaGetCurrentContext( void )
+{
+   return SVGAMesa;
+}
+
+
+/*
+ * Swap front/back buffers for current context if double buffered.
+ */
+void SVGAMesaSwapBuffers( void )
+{
+   FLUSH_VB( SVGAMesa->gl_ctx, "swap buffers" );
+   if (SVGAMesa->gl_vis->DBflag) {
+      vga_flip();
+   }
+}
+
+
+#else
+
+/*
+ * Need this to provide at least one external definition when SVGA is
+ * not defined on the compiler command line.
+ */
+
+int gl_svga_dummy_function(void)
+{
+   return 0;
+}
+
+#endif  /*SVGA*/
+
diff --git a/src/mesa/drivers/windows/colors.h b/src/mesa/drivers/windows/colors.h
new file mode 100644 (file)
index 0000000..40ead30
--- /dev/null
@@ -0,0 +1,499 @@
+/*     File name       :       colors.h\r
+ *  Version            :       2.3\r
+ *\r
+ *  Header file for display driver for Mesa 2.3  under \r
+ *     Windows95 and WindowsNT \r
+ *     This file defines macros and global variables  needed\r
+ *     for converting color format\r
+ *\r
+ *     Copyright (C) 1996-  Li Wei\r
+ *  Address            :               Institute of Artificial Intelligence\r
+ *                             :                       & Robotics\r
+ *                             :               Xi'an Jiaotong University\r
+ *  Email              :               liwei@aiar.xjtu.edu.cn\r
+ *  Web page   :               http://sun.aiar.xjtu.edu.cn\r
+ *\r
+ *  This file and its associations are partially based on the \r
+ *  Windows NT driver for Mesa, written by Mark Leaming\r
+ *  (mark@rsinc.com).\r
+ */\r
+\r
+/* $Log: ddcolors.h 1997/6/14 by Li Wei(liwei@aiar.xjtu.edu.cn)\r
+ * Macros for pixel format defined\r
+ */\r
+\r
+/*\r
+ * $Log: colors.h,v $
+ * Revision 1.1  1999/08/19 00:55:42  jtg
+ * Initial revision
+ *
+ * Revision 1.2  1999/01/03 03:08:57  brianp
+ * Ted Jump's changes
+ *
+ * Revision 1.1  1999/01/03 03:08:12  brianp
+ * Initial revision
+ *\r
+ * Revision 2.0.2  1997/4/30 15:58:00  CST by Li Wei(liwei@aiar.xjtu.edu.cn)\r
+ * Add LUTs need for dithering\r
+ */\r
+\r
+/*\r
+ * $Log: colors.h,v $
+ * Revision 1.1  1999/08/19 00:55:42  jtg
+ * Initial revision
+ *
+ * Revision 1.2  1999/01/03 03:08:57  brianp
+ * Ted Jump's changes
+ *
+ * Revision 1.1  1999/01/03 03:08:12  brianp
+ * Initial revision
+ *\r
+ * Revision 2.0.1  1997/4/29 15:52:00  CST by Li Wei(liwei@aiar.xjtu.edu.cn)\r
+ * Add BGR8 Macro\r
+ */\r
\r
+/*\r
+ * $Log: colors.h,v $
+ * Revision 1.1  1999/08/19 00:55:42  jtg
+ * Initial revision
+ *
+ * Revision 1.2  1999/01/03 03:08:57  brianp
+ * Ted Jump's changes
+ *
+ * Revision 1.1  1999/01/03 03:08:12  brianp
+ * Initial revision
+ *\r
+ * Revision 2.0  1996/11/15 10:55:00  CST by Li Wei(liwei@aiar.xjtu.edu.cn)\r
+ * Initial revision\r
+ */\r
+/* Values for wmesa->pixelformat: */\r
+\r
+#define PF_8A8B8G8R    3       /* 32-bit TrueColor:  8-A, 8-B, 8-G, 8-R */\r
+#define PF_8R8G8B      4       /* 32-bit TrueColor:  8-R, 8-G, 8-B */\r
+#define PF_5R6G5B      5       /* 16-bit TrueColor:  5-R, 6-G, 5-B bits */\r
+#define PF_DITHER8     6       /* Dithered RGB using a lookup table */\r
+#define PF_LOOKUP      7       /* Undithered RGB using a lookup table */\r
+#define PF_GRAYSCALE   10      /* Grayscale or StaticGray */\r
+#define PF_BADFORMAT   11\r
+#define PF_INDEX8              12\r
+\r
+char ColorMap16[] = {\r
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\r
+0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,\r
+0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,\r
+0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,\r
+0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,\r
+0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,\r
+0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,\r
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,\r
+0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,\r
+0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,\r
+0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,\r
+0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,\r
+0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,\r
+0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,0x0D,\r
+0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,\r
+0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,\r
+0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,\r
+0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,\r
+0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,\r
+0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,\r
+0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,\r
+0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,\r
+0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16,\r
+0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,\r
+0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,\r
+0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,\r
+0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,\r
+0x1B,0x1B,0x1B,0x1B,0x1B,0x1B,0x1B,0x1B,\r
+0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,\r
+0x1D,0x1D,0x1D,0x1D,0x1D,0x1D,0x1D,0x1D,\r
+0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,\r
+0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F};\r
+\r
+#define BGR8(r,g,b)            (unsigned)(((BYTE)(b & 0xc0 | (g & 0xe0)>>2 | (r & 0xe0)>>5)))\r
+#ifdef DDRAW\r
+#define BGR16(r,g,b)   ((WORD)(((BYTE)(ColorMap16[b]) | ((BYTE)(g&0xfc) << 3)) | (((WORD)(BYTE)(ColorMap16[r])) << 11)))\r
+#else\r
+#define BGR16(r,g,b)   ((WORD)(((BYTE)(ColorMap16[b]) | ((BYTE)(ColorMap16[g]) << 5)) | (((WORD)(BYTE)(ColorMap16[r])) << 10)))\r
+#endif\r
+#define BGR24(r,g,b)   (unsigned long)(((DWORD)(((BYTE)(b)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(r))<<16))) << 8)\r
+#define BGR32(r,g,b)   (unsigned long)((DWORD)(((BYTE)(b)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(r))<<16)))\r
+\r
+\r
+\r
+/*\r
+ * If pixelformat==PF_8A8B8G8R:\r
+ */\r
+#define PACK_8A8B8G8R( R, G, B, A )    \\r
+       ( ((A) << 24) | ((B) << 16) | ((G) << 8) | (R) )\r
+\r
+\r
+/*\r
+ * If pixelformat==PF_8R8G8B:\r
+ */\r
+#define PACK_8R8G8B( R, G, B)   ( ((R) << 16) | ((G) << 8) | (B) )\r
+\r
+\r
+/*\r
+ * If pixelformat==PF_5R6G5B:\r
+ */\r
+\r
+\r
+#ifdef DDRAW\r
+#define PACK_5R6G5B( R, G, B) ((WORD)(((BYTE)(ColorMap16[B]) | ((BYTE)(G&0xfc) << 3)) | (((WORD)(BYTE)(ColorMap16[R])) << 11)))\r
+#else\r
+#define PACK_5R6G5B( R, G, B)  ((WORD)(((BYTE)(ColorMap16[B]) | ((BYTE)(ColorMap16[G]) << 5)) | (((WORD)(BYTE)(ColorMap16[R])) << 10)))\r
+#endif\r
+/*----------------------------------------------------------------------------\r
+\r
+Division lookup tables.  These tables compute 0-255 divided by 51 and\r
+modulo 51.  These tables could approximate gamma correction.\r
+\r
+*/\r
+\r
+char unsigned const aDividedBy51Rounded[256] =\r
+{\r
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+  0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\r
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\r
+  1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\r
+  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\r
+  2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\r
+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\r
+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\r
+  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\r
+  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\r
+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\r
+};\r
+\r
+char unsigned const aDividedBy51[256] =\r
+{\r
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+  0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\r
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\r
+  1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\r
+  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\r
+  2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\r
+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\r
+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\r
+  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\r
+  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, \r
+};\r
+\r
+char unsigned const aModulo51[256] =\r
+{\r
+  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,\r
+  20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,\r
+  38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 0, 1, 2, 3, 4, 5, 6,\r
+  7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,\r
+  26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,\r
+  44, 45, 46, 47, 48, 49, 50, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,\r
+  13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,\r
+  31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,\r
+  49, 50, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,\r
+  18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,\r
+  36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 0, 1, 2, 3,\r
+  4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,\r
+  23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,\r
+  41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 0, \r
+};\r
+\r
+/*----------------------------------------------------------------------------\r
+\r
+Multiplication LUTs.  These compute 0-5 times 6 and 36.\r
+\r
+*/\r
+\r
+char unsigned const aTimes6[6] =\r
+{\r
+  0, 6, 12, 18, 24, 30\r
+};\r
+\r
+char unsigned const aTimes36[6] =\r
+{\r
+  0, 36, 72, 108, 144, 180\r
+};\r
+\r
+\r
+/*----------------------------------------------------------------------------\r
+\r
+Dither matrices for 8 bit to 2.6 bit halftones.\r
+\r
+*/\r
+\r
+char unsigned const aHalftone16x16[256] =\r
+{\r
+  0, 44, 9, 41, 3, 46, 12, 43, 1, 44, 10, 41, 3, 46, 12, 43,\r
+  34, 16, 25, 19, 37, 18, 28, 21, 35, 16, 26, 19, 37, 18, 28, 21,\r
+  38, 6, 47, 3, 40, 9, 50, 6, 38, 7, 47, 4, 40, 9, 49, 6,\r
+  22, 28, 13, 31, 25, 31, 15, 34, 22, 29, 13, 32, 24, 31, 15, 34,\r
+  2, 46, 12, 43, 1, 45, 10, 42, 2, 45, 11, 42, 1, 45, 11, 42,\r
+  37, 18, 27, 21, 35, 17, 26, 20, 36, 17, 27, 20, 36, 17, 26, 20,\r
+  40, 8, 49, 5, 38, 7, 48, 4, 39, 8, 48, 5, 39, 7, 48, 4,\r
+  24, 30, 15, 33, 23, 29, 13, 32, 23, 30, 14, 33, 23, 29, 14, 32,\r
+  2, 46, 12, 43, 0, 44, 10, 41, 3, 47, 12, 44, 0, 44, 10, 41,\r
+  37, 18, 27, 21, 35, 16, 25, 19, 37, 19, 28, 22, 35, 16, 25, 19,\r
+  40, 9, 49, 5, 38, 7, 47, 4, 40, 9, 50, 6, 38, 6, 47, 3,\r
+  24, 30, 15, 34, 22, 29, 13, 32, 25, 31, 15, 34, 22, 28, 13, 31,\r
+  1, 45, 11, 42, 2, 46, 11, 42, 1, 45, 10, 41, 2, 46, 11, 43,\r
+  36, 17, 26, 20, 36, 17, 27, 21, 35, 16, 26, 20, 36, 18, 27, 21,\r
+  39, 8, 48, 4, 39, 8, 49, 5, 38, 7, 48, 4, 39, 8, 49, 5,\r
+  23, 29, 14, 33, 24, 30, 14, 33, 23, 29, 13, 32, 24, 30, 14, 33,\r
+};\r
+\r
+char unsigned const aHalftone8x8[64] =\r
+{\r
+   0, 38,  9, 47,  2, 40, 11, 50,\r
+  25, 12, 35, 22, 27, 15, 37, 24,\r
+   6, 44,  3, 41,  8, 47,  5, 43,\r
+  31, 19, 28, 15, 34, 21, 31, 18,\r
+   1, 39, 11, 49,  0, 39, 10, 48,\r
+  27, 14, 36, 23, 26, 13, 35, 23,\r
+   7, 46,  4, 43,  7, 45,  3, 42,\r
+  33, 20, 30, 17, 32, 19, 29, 16,\r
+};\r
+\r
+char unsigned const aHalftone4x4_1[16] =\r
+{\r
+  0, 25, 6, 31,\r
+  38, 12, 44, 19,\r
+  9, 35, 3, 28,\r
+  47, 22, 41, 15\r
+};\r
+\r
+char unsigned const aHalftone4x4_2[16] =\r
+{\r
+  41, 3, 9, 28,\r
+  35, 15, 22, 47,\r
+  6, 25, 38, 0,\r
+  19, 44, 31, 12\r
+};\r
+\r
+/***************************************************************************\r
+  aWinGHalftoneTranslation\r
+\r
+  Translates a 2.6 bit-per-pixel halftoned representation into the\r
+  slightly rearranged WinG Halftone Palette.\r
+*/\r
+\r
+char unsigned const aWinGHalftoneTranslation[216] =\r
+{\r
+  0,\r
+  29,\r
+  30,\r
+  31,\r
+  32,\r
+  249,\r
+  33,\r
+  34,\r
+  35,\r
+  36,\r
+  37,\r
+  38,\r
+  39,\r
+  40,\r
+  41,\r
+  42,\r
+  43,\r
+  44,\r
+  45,\r
+  46,\r
+  47,\r
+  48,\r
+  49,\r
+  50,\r
+  51,\r
+  52,\r
+  53,\r
+  54,\r
+  55,\r
+  56,\r
+  250,\r
+  250,\r
+  57,\r
+  58,\r
+  59,\r
+  251,\r
+  60,\r
+  61,\r
+  62,\r
+  63,\r
+  64,\r
+  65,\r
+  66,\r
+  67,\r
+  68,\r
+  69,\r
+  70,\r
+  71,\r
+  72,\r
+  73,\r
+  74,\r
+  75,\r
+  76,\r
+  77,\r
+  78,\r
+  79,\r
+  80,\r
+  81,\r
+  82,\r
+  83,\r
+  84,\r
+  85,\r
+  86,\r
+  87,\r
+  88,\r
+  89,\r
+  250,\r
+  90,\r
+  91,\r
+  92,\r
+  93,\r
+  94,\r
+  95,\r
+  96,\r
+  97,\r
+  98,\r
+  99,\r
+  100,\r
+  101,\r
+  102,\r
+  103,\r
+  104,\r
+  105,\r
+  106,\r
+  107,\r
+  108,\r
+  109,\r
+  110,\r
+  111,\r
+  227,\r
+  112,\r
+  113,\r
+  114,\r
+  115,\r
+  116,\r
+  117,\r
+  118,\r
+  119,\r
+  151,\r
+  120,\r
+  121,\r
+  122,\r
+  123,\r
+  124,\r
+  228,\r
+  125,\r
+  126,\r
+  229,\r
+  133,\r
+  162,\r
+  135,\r
+  131,\r
+  132,\r
+  137,\r
+  166,\r
+  134,\r
+  140,\r
+  130,\r
+  136,\r
+  143,\r
+  138,\r
+  139,\r
+  174,\r
+  141,\r
+  142,\r
+  177,\r
+  129,\r
+  144,\r
+  145,\r
+  146,\r
+  147,\r
+  148,\r
+  149,\r
+  150,\r
+  157,\r
+  152,\r
+  153,\r
+  154,\r
+  155,\r
+  156,\r
+  192,\r
+  158,\r
+  159,\r
+  160,\r
+  161,\r
+  196,\r
+  163,\r
+  164,\r
+  165,\r
+  127,\r
+  199,\r
+  167,\r
+  168,\r
+  169,\r
+  170,\r
+  171,\r
+  172,\r
+  173,\r
+  207,\r
+  175,\r
+  176,\r
+  210,\r
+  178,\r
+  179,\r
+  180,\r
+  181,\r
+  182,\r
+  183,\r
+  184,\r
+  185,\r
+  186,\r
+  187,\r
+  188,\r
+  189,\r
+  190,\r
+  191,\r
+  224,\r
+  193,\r
+  194,\r
+  195,\r
+  252,\r
+  252,\r
+  197,\r
+  198,\r
+  128,\r
+  253,\r
+  252,\r
+  200,\r
+  201,\r
+  202,\r
+  203,\r
+  204,\r
+  205,\r
+  206,\r
+  230,\r
+  208,\r
+  209,\r
+  231,\r
+  211,\r
+  212,\r
+  213,\r
+  214,\r
+  215,\r
+  216,\r
+  217,\r
+  218,\r
+  219,\r
+  220,\r
+  221,\r
+  222,\r
+  254,\r
+  223,\r
+  232,\r
+  225,\r
+  226,\r
+  255,\r
+};
\ No newline at end of file
diff --git a/src/mesa/drivers/windows/mesa_extend.c b/src/mesa/drivers/windows/mesa_extend.c
new file mode 100644 (file)
index 0000000..933e3ba
--- /dev/null
@@ -0,0 +1,211 @@
+/* File: mesa_extend.c for wmesa-2.3\r
+   Written by Li Wei (liwei@aiar.xjtu.edu.cn)\r
+*/\r
+\r
+/*******************************************************************\r
+ Users can use the following keys to control the view\r
+\r
+ The following four key combinations can shift the view correspondingly,\r
+ function in both stereo and normal mode.\r
+ Ctrl+left arrow\r
+ Ctrl+right arrow\r
+ Ctrl+up arrow\r
+ Ctrl+down arrow\r
+\r
+ F (captital letter) shift the camera far from objects\r
+ N (captital letter) shift the camera near from objects\r
+ S (captital letter) toggle between normal and stereo mode\r
+ I (captital letter) increase the distance between two views\r
+ D (captital letter) decrease the distance between two views\r
+\r
+ if the Key function defined by user maps any key appearing above, it will be\r
+ masked by the program. Hence, user should either modify his own code or\r
+ modify function defaultKeyProc at the end of this file \r
+*******************************************************************/\r
+\r
+/* Log 6/14, 1997\r
+ * revision 1.01\r
+ * struct DisplayOptions defined for tk_ddmesa.c to read the initial file\r
+ */\r
+\r
+#include "mesa_extend.h"\r
+#include "gltk.h"\r
+#include <stdio.h>\r
+#ifndef NO_STEREO\r
+       #include "stereo.h"\r
+#endif\r
+#ifndef NO_PARALLEL\r
+//     #include "parallel.h"\r
+#endif\r
+\r
+GLenum (*userKeyProc) (int, GLenum) = NULL;\r
+\r
+GLfloat viewDistance = 1.0;\r
+GLfloat deltaView = 0.1;\r
+GLfloat deltaShift = 0.1;\r
+\r
+GLuint viewShift = SHIFT_NONE;\r
+GLuint viewTag = 0 ;\r
+\r
+GLenum imageRendered = GL_FALSE;\r
+\r
+GLenum glImageRendered()\r
+{\r
+       return imageRendered; \r
+}\r
+\r
+//Code added by Li Wei to enable stereo display\r
+GLenum defaultKeyProc(int key, GLenum mask )\r
+{\r
+       GLenum flag = GL_FALSE ;\r
+       if(mask & TK_CONTROL){\r
+       flag = GL_TRUE ;\r
+       switch(key){\r
+               case TK_LEFT:\r
+               viewShift = SHIFT_LEFT;\r
+               break;\r
+               case TK_RIGHT:\r
+               viewShift = SHIFT_RIGHT;\r
+               break;\r
+               case TK_UP:\r
+               viewShift = SHIFT_UP;\r
+               break;\r
+               case TK_DOWN:\r
+               viewShift = SHIFT_DOWN;\r
+               break;\r
+               default:\r
+                       flag = GL_FALSE ;\r
+               }\r
+       }\r
+       if(flag == GL_FALSE){\r
+       flag = GL_TRUE ;\r
+       switch(key){\r
+               case TK_F:\r
+               viewShift = SHIFT_FAR;\r
+               break;\r
+               case TK_N:\r
+               viewShift = SHIFT_NEAR;\r
+               break;\r
+\r
+#if !defined(NO_STEREO)\r
+               case TK_D:\r
+               viewDistance-= deltaView;\r
+               break;\r
+               case TK_I:\r
+               viewDistance+= deltaView;\r
+               break;\r
+               case TK_S:\r
+               toggleStereoMode();\r
+               break;\r
+#endif\r
+\r
+#if !defined(NO_PARALLEL)\r
+               case TK_P:\r
+               if(machineType == MASTER)\r
+                       toggleParallelMode();\r
+               break;\r
+#endif\r
+               default:\r
+                       flag = GL_FALSE;\r
+               }\r
+               }\r
+\r
+       if(userKeyProc)\r
+               flag=flag||(*userKeyProc)(key, mask);\r
+\r
+#if !defined(NO_PARALLEL)\r
+       if(parallelFlag&&key!=TK_P&&machineType == MASTER){\r
+               PRKeyDown(key,mask);\r
+       }\r
+#endif\r
+\r
+       return flag;\r
+}\r
+\r
+/* The following function implemented key board control of the display,\r
+       availabe even in normal mode so long the driver is linked into exe file.\r
+*/\r
+void shiftView()\r
+{\r
+       GLfloat cm[16];\r
+       if(viewShift != SHIFT_NONE){\r
+/*     glGetFloatv(GL_MODELVIEW_MATRIX,cm);\r
+       glMatrixMode(GL_MODELVIEW);\r
+*/\r
+    GLint matrix_mode;\r
+    glGetIntegerv(GL_MATRIX_MODE,&matrix_mode);\r
+/*     if(matrix_mode!=GL_PROJECTION)\r
+        glMatrixMode(GL_PROJECTION);\r
+    glGetFloatv(GL_PROJECTION_MATRIX,cm);\r
+    glLoadIdentity();\r
+       switch(viewShift){\r
+               case SHIFT_LEFT:\r
+                       glTranslatef(-deltaShift,0,0);\r
+                       break;\r
+               case SHIFT_RIGHT:\r
+                       glTranslatef(deltaShift,0,0);\r
+                       break;\r
+               case SHIFT_UP:\r
+                       glTranslatef(0,deltaShift,0);\r
+                       break;\r
+               case SHIFT_DOWN:\r
+                       glTranslatef(0,-deltaShift,0);\r
+                       break;\r
+               case SHIFT_FAR:\r
+                       glTranslatef(0,0,-deltaShift);\r
+                       break;\r
+               case SHIFT_NEAR:\r
+                       glTranslatef(0,0,deltaShift);\r
+                       break;\r
+               }\r
+\r
+               viewShift = SHIFT_NONE;\r
+               glMultMatrixf( cm );\r
+        if(matrix_mode!=GL_PROJECTION)\r
+            glMatrixMode(matrix_mode);\r
+\r
+       }\r
+*/\r
+       if(matrix_mode!=GL_MODELVIEW)\r
+        glMatrixMode(GL_MODELVIEW);\r
+    glGetFloatv(GL_MODELVIEW_MATRIX,cm);\r
+    glLoadIdentity();\r
+       switch(viewShift){\r
+               case SHIFT_LEFT:\r
+                       glTranslatef(-deltaShift,0,0);\r
+                       break;\r
+               case SHIFT_RIGHT:\r
+                       glTranslatef(deltaShift,0,0);\r
+                       break;\r
+               case SHIFT_UP:\r
+                       glTranslatef(0,deltaShift,0);\r
+                       break;\r
+               case SHIFT_DOWN:\r
+                       glTranslatef(0,-deltaShift,0);\r
+                       break;\r
+               case SHIFT_FAR:\r
+                       glTranslatef(0,0,-deltaShift);\r
+                       break;\r
+               case SHIFT_NEAR:\r
+                       glTranslatef(0,0,deltaShift);\r
+                       break;\r
+               }\r
+\r
+               viewShift = SHIFT_NONE;\r
+               glMultMatrixf( cm );\r
+        if(matrix_mode!=GL_MODELVIEW)\r
+            glMatrixMode(matrix_mode);\r
+\r
+       }\r
+}\r
+\r
+\r
+void getDisplayOptions( void)\r
+{\r
+       displayOptions.stereo = GetPrivateProfileInt("DISPLAY", "STEREO",1,"ddmesa.ini" );\r
+       displayOptions.fullScreen = GetPrivateProfileInt("DISPLAY", "FULLSCREEN",0,"ddmesa.ini" );\r
+       displayOptions.mode = GetPrivateProfileInt("DISPLAY", "MODE",1, "ddmesa.ini");\r
+       displayOptions.bpp = GetPrivateProfileInt("DISPLAY", "BPP", 32, "ddmesa.ini");\r
+\r
+}\r
+//end modification\r
diff --git a/src/mesa/drivers/windows/mesa_extend.h b/src/mesa/drivers/windows/mesa_extend.h
new file mode 100644 (file)
index 0000000..66a8a77
--- /dev/null
@@ -0,0 +1,43 @@
+/* mesa_extend.h\r
+ * for wmesa-2.3\r
+ *  Written by Li Wei (liwei@aiar.xjtu.edu.cn)\r
+ */\r
+\r
+/* Log 6/14, 1997\r
+ * revision 1.01\r
+ * struct DisplayOptions defined for tk_ddmesa.c to read the initial file\r
+ */\r
+\r
+#include <GL/gl.h>\r
+#include <stdlib.h>\r
+#include <windows.h>\r
+#include <winbase.h>\r
+\r
+typedef enum SHIFT{ SHIFT_NONE, SHIFT_LEFT,SHIFT_RIGHT,SHIFT_UP,SHIFT_DOWN,SHIFT_FAR,SHIFT_NEAR};\r
+\r
+extern GLfloat deltaView ;\r
+\r
+extern GLuint viewShift;\r
+\r
+extern GLenum glImageRendered();\r
+\r
+extern GLenum imageRendered ;\r
+\r
+extern GLfloat deltaView ;\r
+\r
+extern GLfloat deltaShift;\r
+\r
+void shiftView( void );\r
+\r
+struct DISPLAY_OPTIONS {\r
+       int  stereo;\r
+       int  fullScreen;\r
+       int      mode;\r
+       int      bpp;\r
+};\r
+\r
+extern struct DISPLAY_OPTIONS displayOptions;\r
+extern void getDisplayOptions( void);\r
+\r
+GLenum defaultKeyProc(int, GLenum);\r
+extern GLenum (*userKeyProc) (int, GLenum);\r
diff --git a/src/mesa/drivers/windows/stereo.h b/src/mesa/drivers/windows/stereo.h
new file mode 100644 (file)
index 0000000..544af54
--- /dev/null
@@ -0,0 +1,47 @@
+/* File name stereov.h\r
+   header file for stereo display driver \r
+***************************************************************\r
+*                     WMesa                                   *\r
+*                     version 2.3                             *        \r
+*                                                             *\r
+*                        By                                   *\r
+*                      Li Wei                                 *\r
+*       Institute of Artificial Intelligence & Robotics       *\r
+*       Xi'an Jiaotong University                             *\r
+*       Email: liwei@aiar.xjtu.edu.cn                         * \r
+*       Web page: http://sun.aiar.xjtu.edu.cn                 *\r
+*                                                             *\r
+*             July 7th, 1997                                                 * \r
+***************************************************************\r
+\r
+*/\r
+#if defined( __WIN32__) || defined (WIN32)\r
+   #include <windows.h>\r
+#endif\r
+\r
+typedef enum VIEW_INDICATOR { FIRST, SECOND};\r
+\r
+#define MAXIMUM_DISPLAY_LIST 99\r
+\r
+extern GLenum stereoBuffer;\r
+\r
+extern GLint displayList;\r
+\r
+extern GLint stereo_flag ;\r
+\r
+extern GLfloat viewDistance;\r
+\r
+extern GLuint viewTag;\r
+\r
+extern GLuint displayListBase;\r
+\r
+extern GLuint numOfLists;\r
+\r
+extern GLenum stereoCompile;\r
+\r
+extern GLenum stereoShowing;\r
+\r
+extern void glShowStereo(GLuint list);\r
+\r
+extern void toggleStereoMode();\r
+\r
diff --git a/src/mesa/drivers/windows/wgl.c b/src/mesa/drivers/windows/wgl.c
new file mode 100644 (file)
index 0000000..d5f577d
--- /dev/null
@@ -0,0 +1,518 @@
+/* $Id: wgl.c,v 1.1 1999/08/19 00:55:42 jtg Exp $ */\r
+\r
+/*\r
+* This library is free software; you can redistribute it and/or\r
+* modify it under the terms of the GNU Library General Public\r
+* License as published by the Free Software Foundation; either\r
+* version 2 of the License, or (at your option) any later version.\r
+*\r
+* This library is distributed in the hope that it will be useful,\r
+* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+* Library General Public License for more details.\r
+*\r
+* You should have received a copy of the GNU Library General Public\r
+* License along with this library; if not, write to the Free\r
+* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
+*\r
+*/\r
+\r
+/*\r
+* File name    : wgl.c\r
+* WGL stuff. Added by Oleg Letsinsky, ajl@ultersys.ru\r
+* Some things originated from the 3Dfx WGL functions\r
+*/\r
+\r
+#ifdef WIN32\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+#include <windows.h>\r
+\r
+#include <GL/gl.h>\r
+#include <GL/glu.h>\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#include <stdio.h>\r
+#include <tchar.h>\r
+#include "wmesadef.h"\r
+#include "GL/wmesa.h"\r
+#include "types.h"\r
+\r
+#define MAX_MESA_ATTRS 20\r
+\r
+struct __extensions__\r
+{\r
+    PROC       proc;\r
+    char       *name;\r
+};\r
+\r
+struct __pixelformat__\r
+{\r
+    PIXELFORMATDESCRIPTOR      pfd;\r
+    GLboolean doubleBuffered;\r
+};\r
+\r
+struct __extensions__  ext[] = {\r
+\r
+#ifdef GL_EXT_polygon_offset\r
+   { (PROC)glPolygonOffsetEXT,                 "glPolygonOffsetEXT"            },\r
+#endif\r
+   { (PROC)glBlendEquationEXT,                 "glBlendEquationEXT"            },\r
+   { (PROC)glBlendColorEXT,                    "glBlendColorExt"               },\r
+   { (PROC)glVertexPointerEXT,                 "glVertexPointerEXT"            },\r
+   { (PROC)glNormalPointerEXT,                 "glNormalPointerEXT"            },\r
+   { (PROC)glColorPointerEXT,                  "glColorPointerEXT"             },\r
+   { (PROC)glIndexPointerEXT,                  "glIndexPointerEXT"             },\r
+   { (PROC)glTexCoordPointerEXT,               "glTexCoordPointer"             },\r
+   { (PROC)glEdgeFlagPointerEXT,               "glEdgeFlagPointerEXT"          },\r
+   { (PROC)glGetPointervEXT,                   "glGetPointervEXT"              },\r
+   { (PROC)glArrayElementEXT,                  "glArrayElementEXT"             },\r
+   { (PROC)glDrawArraysEXT,                    "glDrawArrayEXT"                },\r
+   { (PROC)glAreTexturesResidentEXT,           "glAreTexturesResidentEXT"      },\r
+   { (PROC)glBindTextureEXT,                   "glBindTextureEXT"              },\r
+   { (PROC)glDeleteTexturesEXT,                        "glDeleteTexturesEXT"           },\r
+   { (PROC)glGenTexturesEXT,                   "glGenTexturesEXT"              },\r
+   { (PROC)glIsTextureEXT,                     "glIsTextureEXT"                },\r
+   { (PROC)glPrioritizeTexturesEXT,            "glPrioritizeTexturesEXT"       },\r
+   { (PROC)glCopyTexSubImage3DEXT,             "glCopyTexSubImage3DEXT"        },\r
+   { (PROC)glTexImage3DEXT,                    "glTexImage3DEXT"               },\r
+   { (PROC)glTexSubImage3DEXT,                 "glTexSubImage3DEXT"            },\r
+   { (PROC)glColorTableEXT,                    "glColorTableEXT"               },\r
+   { (PROC)glColorSubTableEXT,                 "glColorSubTableEXT"            },\r
+   { (PROC)glGetColorTableEXT,                 "glGetColorTableEXT"            },\r
+   { (PROC)glGetColorTableParameterfvEXT,      "glGetColorTableParameterfvEXT" },\r
+   { (PROC)glGetColorTableParameterivEXT,      "glGetColorTableParameterivEXT" },\r
+   { (PROC)glPointParameterfEXT,               "glPointParameterfEXT"          },\r
+   { (PROC)glPointParameterfvEXT,              "glPointParameterfvEXT"         },\r
+   { (PROC)glBlendFuncSeparateINGR,            "glBlendFuncSeparateINGR"       },\r
+   { (PROC)glLockArraysEXT,                    "glLockArraysEXT"               },\r
+   { (PROC)glUnlockArraysEXT,                  "glUnlockArraysEXT"             }\r
+};\r
+\r
+int qt_ext = sizeof(ext) / sizeof(ext[0]);\r
+\r
+struct __pixelformat__ pix[] =\r
+{\r
+    {  {       sizeof(PIXELFORMATDESCRIPTOR),  1,\r
+        PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_GENERIC_FORMAT|PFD_DOUBLEBUFFER|PFD_SWAP_COPY,\r
+        PFD_TYPE_RGBA,\r
+        24,    8,      0,      8,      8,      8,      16,     8,      24,\r
+        0,     0,      0,      0,      0,      16,     8,      0,      0,      0,      0,      0,      0 },\r
+        GL_TRUE\r
+    },\r
+    {  {       sizeof(PIXELFORMATDESCRIPTOR),  1,\r
+        PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_GENERIC_FORMAT,\r
+        PFD_TYPE_RGBA,\r
+        24,    8,      0,      8,      8,      8,      16,     8,      24,\r
+        0,     0,      0,      0,      0,      16,     8,      0,      0,      0,      0,      0,      0 },\r
+        GL_FALSE\r
+    },\r
+};\r
+\r
+int                            qt_pix = sizeof(pix) / sizeof(pix[0]);\r
+\r
+typedef struct {\r
+    WMesaContext ctx;\r
+    HDC hdc;\r
+} MesaWglCtx;\r
+\r
+#define MESAWGL_CTX_MAX_COUNT 20\r
+\r
+static MesaWglCtx wgl_ctx[MESAWGL_CTX_MAX_COUNT];\r
+\r
+static unsigned ctx_count = 0;\r
+static unsigned ctx_current = -1;\r
+static unsigned curPFD = 0;\r
+\r
+GLAPI BOOL GLWINAPI wglCopyContext(HGLRC hglrcSrc,HGLRC hglrcDst,UINT mask)\r
+{\r
+    return(FALSE);\r
+}\r
+\r
+GLAPI HGLRC GLWINAPI wglCreateContext(HDC hdc)\r
+{\r
+    HWND               hWnd;\r
+    int i = 0;\r
+    if(!(hWnd = WindowFromDC(hdc)))\r
+    {\r
+        SetLastError(0);\r
+        return(NULL);\r
+    }\r
+    if (!ctx_count)\r
+    {\r
+       for(i=0;i<MESAWGL_CTX_MAX_COUNT;i++)\r
+       {\r
+               wgl_ctx[i].ctx = NULL;\r
+               wgl_ctx[i].hdc = NULL;\r
+       }\r
+    }\r
+    for( i = 0; i < MESAWGL_CTX_MAX_COUNT; i++ )\r
+    {\r
+        if ( wgl_ctx[i].ctx == NULL )\r
+        {\r
+            wgl_ctx[i].ctx = WMesaCreateContext( hWnd, NULL, GL_TRUE,\r
+                pix[curPFD-1].doubleBuffered );\r
+            if (wgl_ctx[i].ctx == NULL)\r
+                break;\r
+            wgl_ctx[i].hdc = hdc;\r
+            ctx_count++;\r
+            return ((HGLRC)wgl_ctx[i].ctx);\r
+        }\r
+    }\r
+    SetLastError(0);\r
+    return(NULL);\r
+}\r
+\r
+GLAPI BOOL GLWINAPI wglDeleteContext(HGLRC hglrc)\r
+{\r
+    int i;\r
+    for ( i = 0; i < MESAWGL_CTX_MAX_COUNT; i++ )\r
+    {\r
+       if ( wgl_ctx[i].ctx == (PWMC) hglrc )\r
+       {\r
+            WMesaMakeCurrent((PWMC) hglrc);\r
+            WMesaDestroyContext();\r
+            wgl_ctx[i].ctx = NULL;\r
+            wgl_ctx[i].hdc = NULL;\r
+            ctx_count--;\r
+            return(TRUE);\r
+       }\r
+    }\r
+    SetLastError(0);\r
+    return(FALSE);\r
+}\r
+\r
+GLAPI HGLRC GLWINAPI wglCreateLayerContext(HDC hdc,int iLayerPlane)\r
+{\r
+    SetLastError(0);\r
+    return(NULL);\r
+}\r
+\r
+GLAPI HGLRC GLWINAPI wglGetCurrentContext(VOID)\r
+{\r
+   if (ctx_current < 0)\r
+      return 0;\r
+   else\r
+      return (HGLRC) wgl_ctx[ctx_current].ctx;\r
+}\r
+\r
+GLAPI HDC GLWINAPI wglGetCurrentDC(VOID)\r
+{\r
+   if (ctx_current < 0)\r
+      return 0;\r
+   else\r
+      return wgl_ctx[ctx_current].hdc;\r
+}\r
+\r
+GLAPI BOOL GLWINAPI wglMakeCurrent(HDC hdc,HGLRC hglrc)\r
+{\r
+    int i;\r
+\r
+    /* new code suggested by Andy Sy */\r
+    if (!hdc || !hglrc) {\r
+       WMesaMakeCurrent(NULL);\r
+       ctx_current = -1;\r
+       return TRUE;\r
+    }\r
+\r
+    for ( i = 0; i < MESAWGL_CTX_MAX_COUNT; i++ )\r
+    {\r
+        if ( wgl_ctx[i].ctx == (PWMC) hglrc )\r
+        {\r
+            wgl_ctx[i].hdc = hdc;\r
+            WMesaMakeCurrent( (WMesaContext) hglrc );\r
+            ctx_current = i;\r
+            return TRUE;\r
+        }\r
+    }\r
+    return FALSE;\r
+}\r
+\r
+GLAPI BOOL GLWINAPI wglShareLists(HGLRC hglrc1,HGLRC hglrc2)\r
+{\r
+    return(TRUE);\r
+}\r
+\r
+
+static FIXED FixedFromDouble(double d)
+{
+   long l = (long) (d * 65536L);
+   return *(FIXED *)&l;
+}
+
+
+GLAPI BOOL GLWINAPI wglUseFontBitmapsA(HDC hdc, DWORD first,
+                                       DWORD count, DWORD listBase)
+{
+   int i;
+   GLuint font_list;
+   DWORD size;
+   GLYPHMETRICS gm;
+   HANDLE hBits;
+   LPSTR lpBits;
+   MAT2 mat;
+
+   if (first<0)
+      return FALSE;
+   if (count<0)
+      return FALSE;
+   if (listBase<0)
+      return FALSE;
+
+   font_list = glGenLists( count );
+   if(font_list == 0)
+      return FALSE;
+
+   mat.eM11 = FixedFromDouble(1);
+   mat.eM12 = FixedFromDouble(0);
+   mat.eM21 = FixedFromDouble(0);
+   mat.eM22 = FixedFromDouble(1);
+
+   memset(&gm,0,sizeof(gm));
+
+   for (i = 0; i < count; i++)
+   {
+      glNewList( font_list+i, GL_COMPILE );
+
+      /* allocate space for the bitmap/outline */
+      size = GetGlyphOutline(hdc, first + i, GGO_BITMAP, &gm, 0, NULL, &mat);
+      if (size == GDI_ERROR)
+      {
+         DWORD err;
+         err = GetLastError();
+         return(FALSE);
+      }
+
+      hBits  = GlobalAlloc(GHND, size);
+      lpBits = GlobalLock(hBits);
+
+      GetGlyphOutline(hdc,    /* handle to device context */
+                      first + i,          /* character to query */
+                      GGO_BITMAP,         /* format of data to return */
+                      &gm,                /* pointer to structure for metrics */
+                      size,               /* size of buffer for data */
+                      lpBits,             /* pointer to buffer for data */
+                      &mat                /* pointer to transformation */
+                                          /* matrix structure */
+                  );
+
+      if (*lpBits == GDI_ERROR)
+      {
+         DWORD err;
+         err = GetLastError();
+
+         GlobalUnlock(hBits);
+         GlobalFree(hBits);
+
+         return(FALSE);
+      }
+
+      glBitmap(gm.gmBlackBoxX,gm.gmBlackBoxY,
+               gm.gmptGlyphOrigin.x,
+               gm.gmptGlyphOrigin.y,
+               gm.gmCellIncX,gm.gmCellIncY,
+               (const GLubyte * )lpBits);
+
+      GlobalUnlock(hBits);
+      GlobalFree(hBits);
+
+      glEndList( );
+   }
+
+    return TRUE;
+}
+\r
+GLAPI BOOL GLWINAPI wglUseFontBitmapsW(HDC hdc,DWORD first,DWORD count,DWORD listBase)\r
+{\r
+    return FALSE;\r
+}\r
+\r
+GLAPI BOOL GLWINAPI wglUseFontOutlinesA(HDC hdc,DWORD first,DWORD count,\r
+                                  DWORD listBase,FLOAT deviation,\r
+                                  FLOAT extrusion,int format,\r
+                                  LPGLYPHMETRICSFLOAT lpgmf)\r
+{\r
+    SetLastError(0);\r
+    return(FALSE);\r
+}\r
+\r
+GLAPI BOOL GLWINAPI wglUseFontOutlinesW(HDC hdc,DWORD first,DWORD count,\r
+                                  DWORD listBase,FLOAT deviation,\r
+                                  FLOAT extrusion,int format,\r
+                                  LPGLYPHMETRICSFLOAT lpgmf)\r
+{\r
+    SetLastError(0);\r
+    return(FALSE);\r
+}\r
+\r
+GLAPI BOOL GLWINAPI wglDescribeLayerPlane(HDC hdc,int iPixelFormat,\r
+                                    int iLayerPlane,UINT nBytes,\r
+                                    LPLAYERPLANEDESCRIPTOR plpd)\r
+{\r
+    SetLastError(0);\r
+    return(FALSE);\r
+}\r
+\r
+GLAPI int GLWINAPI wglSetLayerPaletteEntries(HDC hdc,int iLayerPlane,\r
+                                       int iStart,int cEntries,\r
+                                       CONST COLORREF *pcr)\r
+{\r
+    SetLastError(0);\r
+    return(0);\r
+}\r
+\r
+GLAPI int GLWINAPI wglGetLayerPaletteEntries(HDC hdc,int iLayerPlane,\r
+                                       int iStart,int cEntries,\r
+                                       COLORREF *pcr)\r
+{\r
+    SetLastError(0);\r
+    return(0);\r
+}\r
+\r
+GLAPI BOOL GLWINAPI wglRealizeLayerPalette(HDC hdc,int iLayerPlane,BOOL bRealize)\r
+{\r
+    SetLastError(0);\r
+    return(FALSE);\r
+}\r
+\r
+GLAPI BOOL GLWINAPI wglSwapLayerBuffers(HDC hdc,UINT fuPlanes)\r
+{\r
+    if( !hdc )\r
+    {\r
+        WMesaSwapBuffers();\r
+        return(TRUE);\r
+    }\r
+    SetLastError(0);\r
+    return(FALSE);\r
+}\r
+\r
+GLAPI int GLWINAPI wglChoosePixelFormat(HDC hdc,\r
+                                  CONST PIXELFORMATDESCRIPTOR *ppfd)\r
+{\r
+    int                i,best = -1,bestdelta = 0x7FFFFFFF,delta,qt_valid_pix;\r
+\r
+    qt_valid_pix = qt_pix;\r
+    if(ppfd->nSize != sizeof(PIXELFORMATDESCRIPTOR) || ppfd->nVersion != 1)\r
+    {\r
+        SetLastError(0);\r
+        return(0);\r
+    }\r
+    for(i = 0;i < qt_valid_pix;i++)\r
+    {\r
+        delta = 0;\r
+        if(\r
+            (ppfd->dwFlags & PFD_DRAW_TO_WINDOW) &&\r
+            !(pix[i].pfd.dwFlags & PFD_DRAW_TO_WINDOW))\r
+            continue;\r
+        if(\r
+            (ppfd->dwFlags & PFD_DRAW_TO_BITMAP) &&\r
+            !(pix[i].pfd.dwFlags & PFD_DRAW_TO_BITMAP))\r
+            continue;\r
+        if(\r
+            (ppfd->dwFlags & PFD_SUPPORT_GDI) &&\r
+            !(pix[i].pfd.dwFlags & PFD_SUPPORT_GDI))\r
+            continue;\r
+        if(\r
+            (ppfd->dwFlags & PFD_SUPPORT_OPENGL) &&\r
+            !(pix[i].pfd.dwFlags & PFD_SUPPORT_OPENGL))\r
+            continue;\r
+        if(\r
+            !(ppfd->dwFlags & PFD_DOUBLEBUFFER_DONTCARE) &&\r
+            ((ppfd->dwFlags & PFD_DOUBLEBUFFER) != (pix[i].pfd.dwFlags & PFD_DOUBLEBUFFER)))\r
+            continue;\r
+        if(\r
+            !(ppfd->dwFlags & PFD_STEREO_DONTCARE) &&\r
+            ((ppfd->dwFlags & PFD_STEREO) != (pix[i].pfd.dwFlags & PFD_STEREO)))\r
+            continue;\r
+        if(ppfd->iPixelType != pix[i].pfd.iPixelType)\r
+            delta++;\r
+        if(delta < bestdelta)\r
+        {\r
+            best = i + 1;\r
+            bestdelta = delta;\r
+            if(bestdelta == 0)\r
+                break;\r
+        }\r
+    }\r
+    if(best == -1)\r
+    {\r
+        SetLastError(0);\r
+        return(0);\r
+    }\r
+    return(best);\r
+}\r
+\r
+GLAPI int GLWINAPI wglDescribePixelFormat(HDC hdc,int iPixelFormat,UINT nBytes,\r
+                                    LPPIXELFORMATDESCRIPTOR ppfd)\r
+{\r
+    int                qt_valid_pix;\r
+\r
+    qt_valid_pix = qt_pix;\r
+    if(iPixelFormat < 1 || iPixelFormat > qt_valid_pix || nBytes != sizeof(PIXELFORMATDESCRIPTOR))\r
+    {\r
+        SetLastError(0);\r
+        return(0);\r
+    }\r
+    *ppfd = pix[iPixelFormat - 1].pfd;\r
+    return(qt_valid_pix);\r
+}\r
+\r
+/*\r
+* GetProcAddress - return the address of an appropriate extension\r
+*/\r
+GLAPI PROC GLWINAPI wglGetProcAddress(LPCSTR lpszProc)\r
+{\r
+    int                i;\r
+    for(i = 0;i < qt_ext;i++)\r
+        if(!strcmp(lpszProc,ext[i].name))\r
+            return(ext[i].proc);\r
+\r
+        SetLastError(0);\r
+        return(NULL);\r
+}\r
+\r
+GLAPI int GLWINAPI wglGetPixelFormat(HDC hdc)\r
+{\r
+    if(curPFD == 0)\r
+    {\r
+        SetLastError(0);\r
+        return(0);\r
+    }\r
+    return(curPFD);\r
+}\r
+\r
+GLAPI BOOL GLWINAPI wglSetPixelFormat(HDC hdc,int iPixelFormat,\r
+                                PIXELFORMATDESCRIPTOR *ppfd)\r
+{\r
+    int                qt_valid_pix;\r
+\r
+    qt_valid_pix = qt_pix;\r
+    if(iPixelFormat < 1 || iPixelFormat > qt_valid_pix || ppfd->nSize != sizeof(PIXELFORMATDESCRIPTOR))\r
+    {\r
+        SetLastError(0);\r
+        return(FALSE);\r
+    }\r
+    curPFD = iPixelFormat;\r
+    return(TRUE);\r
+}\r
+\r
+GLAPI BOOL GLWINAPI wglSwapBuffers(HDC hdc)\r
+{\r
+   if (ctx_current < 0)\r
+      return FALSE;\r
+\r
+   if(wgl_ctx[ctx_current].ctx == NULL) {\r
+      SetLastError(0);\r
+      return(FALSE);\r
+   }\r
+   WMesaSwapBuffers();\r
+   return(TRUE);\r
+}\r
+\r
+#endif /* WIN32 */\r
diff --git a/src/mesa/drivers/windows/wing32.def b/src/mesa/drivers/windows/wing32.def
new file mode 100644 (file)
index 0000000..ac8fc1d
--- /dev/null
@@ -0,0 +1,12 @@
+EXPORTS
+        WinGBitBlt@32
+        WinGCreateBitmap@12
+        WinGCreateDC@0
+        WinGCreateHalftoneBrush@12
+        WinGCreateHalftonePalette@0
+        WinGGetDIBColorTable@16
+        WinGGetDIBPointer@8
+        WinGRecommendDIBFormat@4
+        WinGSetDIBColorTable@16
+        WinGStretchBlt@40
+
diff --git a/src/mesa/drivers/windows/wmesa.c b/src/mesa/drivers/windows/wmesa.c
new file mode 100644 (file)
index 0000000..d2c0a56
--- /dev/null
@@ -0,0 +1,3021 @@
+/* $Id: wmesa.c,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
+
+/*
+*   File name   :   wmesa.c
+*  Version      :   2.3
+*
+*  Display driver for Mesa 2.3  under
+*   Windows95 and WindowsNT
+*
+*   Copyright (C) 1996-  Li Wei
+*  Address      :       Institute of Artificial Intelligence
+*               :           & Robotics
+*               :       Xi'an Jiaotong University
+*  Email        :       liwei@aiar.xjtu.edu.cn
+*  Web page :       http://sun.aiar.xjtu.edu.cn
+*
+*  This file and its associations are partially borrowed from the
+*  Windows NT driver for Mesa 1.8 , written by Mark Leaming
+*  (mark@rsinc.com).
+*/
+
+
+/*
+ * $Log: wmesa.c,v $
+ * Revision 1.1  1999/08/19 00:55:42  jtg
+ * Initial revision
+ *
+ * Revision 3.10  1999/06/15 01:35:06  brianp
+ * small change to wmSetPixel() from TWILMOT@cpr.fr
+ *
+ * Revision 3.9  1999/05/11 19:06:01  brianp
+ * fixed a few VB->Index bugs (mikec@ensoniq.com)
+ *
+ * Revision 3.8  1999/05/08 15:15:23  brianp
+ * various updates from mikec@ensoniq.com
+ *
+ * Revision 3.7  1999/04/01 01:27:34  brianp
+ * always flip Y coord in read_rgba_span()
+ *
+ * Revision 3.6  1999/03/28 21:17:27  brianp
+ * updated SetBuffer driver function
+ *
+ * Revision 3.5  1999/03/16 01:36:42  brianp
+ * patched dither() to check if Current is NULL, per xzhou@nyx.net
+ *
+ * Revision 3.4  1999/02/25 14:12:33  keithw
+ * Merged in kw3 patch
+ *
+ * Revision 3.3  1999/01/03 03:08:57  brianp
+ * Ted Jump's changes
+ *
+ * Revision 3.2  1998/08/29 00:26:01
+ * updated for Mesa 3.0 to accomodate EGCS-Mingw32 build
+ *
+ * Revision 3.1  1998/06/11 01:42:08  brianp
+ * updated for Mesa 3.0 device driver interface (but not tested)
+ *
+ * Revision 3.0  1998/06/11 01:18:25  brianp
+ * initial revision
+ *
+ */
+
+
+#define WMESA_STEREO_C
+
+#include <windows.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <GL/wmesa.h>
+#include "mesa_extend.h"
+#include "colors.h"
+#include "macros.h"
+#include "context.h"
+#include "dd.h"
+#include "xform.h"
+#include "vb.h"
+#include "matrix.h"
+#include "depth.h"
+#include "wmesadef.h"
+
+#pragma warning ( disable : 4133 4761 )
+
+#ifdef PROFILE
+//  #include "profile.h"
+#endif
+
+#ifdef DITHER
+#include <wing.h>
+#endif
+
+#ifdef __CYGWIN32__
+#include "macros.h"
+#include <string.h>
+#define CopyMemory memcpy
+#endif
+
+#if !defined(NO_STEREO)
+
+#include "gl\glu.h"
+#include "stereo.h"
+
+#endif
+#if !defined(NO_PARALLEL)
+//  #include "parallel.h"
+#endif
+
+struct DISPLAY_OPTIONS displayOptions;
+
+GLenum stereoCompile = GL_FALSE ;
+GLenum stereoShowing  = GL_FALSE ;
+GLenum stereoBuffer = GL_FALSE;
+#if !defined(NO_STEREO)
+GLint displayList = MAXIMUM_DISPLAY_LIST ;
+#endif
+GLint stereo_flag = 0 ;
+
+/* end of added code*/
+
+static PWMC Current = NULL;
+WMesaContext WC = NULL;
+
+#ifdef NDEBUG
+#define assert(ignore)  ((void) 0)
+#else
+void Mesa_Assert(void *Cond,void *File,unsigned Line)
+{
+    char Msg[512];
+    sprintf(Msg,"%s %s %d",Cond,File,Line);
+    MessageBox(NULL,Msg,"Assertion failed.",MB_OK);
+    exit(1);
+}
+#define assert(e)   if (!e) Mesa_Assert(#e,__FILE__,__LINE__);
+#endif
+
+//#define DD_GETDC (Current->hDC )
+#define DD_GETDC ((Current->db_flag) ? Current->dib.hDC : Current->hDC )
+//#define DD_GETDC ((Current->db_flag) ? Current->hDCPrimary : Current->hDCBack )
+#define DD_RELEASEDC
+
+//#define BEGINGDICALL  if(Current->rgb_flag)wmFlushBits(Current);
+#define BEGINGDICALL
+//#define ENDGDICALL        if(Current->rgb_flag)wmGetBits(Current);
+#define ENDGDICALL
+
+//#define FLIP(Y)  (Current->dither_flag? Y : Current->height-(Y)-1)
+//#define FLIP(Y)  (Current->height-(Y)-1)
+//#define FLIP(Y) Y
+/*
+ * XXX Why only flip Y coord if single buffered???
+ */
+#define FLIP(Y)  (Current->db_flag? Y: Current->height-(Y)-1)
+#define STARTPROFILE
+#define ENDPROFILE(PARA)
+
+#define DITHER_RGB_TO_8BIT_SETUP            \
+GLubyte pixelDithered;
+
+#define DITHER_RGB_TO_8BIT(red, green, blue, pixel, scanline)               \
+{                                                                           \
+    char unsigned redtemp, greentemp, bluetemp, paletteindex;               \
+    redtemp = aDividedBy51[red]                                             \
+    + (aModulo51[red] > aHalftone8x8[(pixel%8)*8                        \
+    + scanline%8]);                                                 \
+    greentemp = aDividedBy51[(char unsigned)green]                          \
+    + (aModulo51[green] > aHalftone8x8[                             \
+    (pixel%8)*8 + scanline%8]);                                     \
+    bluetemp = aDividedBy51[(char unsigned)blue]                            \
+    + (aModulo51[blue] > aHalftone8x8[                              \
+    (pixel%8)*8 +scanline%8]);                                      \
+    paletteindex = redtemp + aTimes6[greentemp] + aTimes36[bluetemp];       \
+    pixelDithered = aWinGHalftoneTranslation[paletteindex];                 \
+}
+
+
+#ifdef DDRAW
+static BOOL DDInit( WMesaContext wc, HWND hwnd);
+static void DDFree( WMesaContext wc);
+static HRESULT DDRestoreAll( WMesaContext wc );
+static void DDDeleteOffScreen(WMesaContext wc);
+static BOOL DDCreateOffScreen(WMesaContext wc);
+#endif
+
+static void FlushToFile(PWMC pwc, PSTR  szFile);
+
+BOOL wmCreateBackingStore(PWMC pwc, long lxSize, long lySize);
+BOOL wmDeleteBackingStore(PWMC pwc);
+void wmCreatePalette( PWMC pwdc );
+BOOL wmSetDibColors(PWMC pwc);
+void wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b);
+
+void wmCreateDIBSection(
+                        HDC  hDC,
+                        PWMC pwc,   // handle of device context
+                        CONST BITMAPINFO *pbmi, // address of structure containing bitmap size, format, and color data
+                        UINT iUsage // color data type indicator: RGB values or palette indices
+                        );
+
+
+void WMesaViewport( GLcontext *ctx,
+                    GLint x, GLint y, GLsizei width, GLsizei height );
+
+
+static triangle_func choose_triangle_function( GLcontext *ctx );
+
+
+static void wmSetPixelFormat( PWMC wc, HDC hDC)
+{
+    if(wc->rgb_flag)
+        wc->cColorBits = GetDeviceCaps(hDC, BITSPIXEL);
+    else
+        wc->cColorBits = 8;
+    switch(wc->cColorBits){
+    case 8:
+        if(wc->dither_flag != GL_TRUE)
+            wc->pixelformat = PF_INDEX8;
+        else
+            wc->pixelformat = PF_DITHER8;
+        break;
+    case 16:
+        wc->pixelformat = PF_5R6G5B;
+        break;
+    case 32:
+        wc->pixelformat = PF_8R8G8B;
+        break;
+    default:
+        wc->pixelformat = PF_BADFORMAT;
+    }
+}
+
+//
+// This function sets the color table of a DIB section
+// to match that of the destination DC
+//
+BOOL /*WINAPI*/ wmSetDibColors(PWMC pwc)
+{
+    RGBQUAD         *pColTab, *pRGB;
+    PALETTEENTRY    *pPal, *pPE;
+    int             i, nColors;
+    BOOL            bRet=TRUE;
+    DWORD           dwErr=0;
+
+    /* Build a color table in the DIB that maps to the
+    selected palette in the DC.
+    */
+    nColors = 1 << pwc->cColorBits;
+    pPal = (PALETTEENTRY *)malloc( nColors * sizeof(PALETTEENTRY));
+    memset( pPal, 0, nColors * sizeof(PALETTEENTRY) );
+    GetPaletteEntries( pwc->hGLPalette, 0, nColors, pPal );
+    pColTab = (RGBQUAD *)malloc( nColors * sizeof(RGBQUAD));
+    for (i = 0, pRGB = pColTab, pPE = pPal; i < nColors; i++, pRGB++, pPE++) {
+        pRGB->rgbRed = pPE->peRed;
+        pRGB->rgbGreen = pPE->peGreen;
+        pRGB->rgbBlue = pPE->peBlue;
+    }
+    if(pwc->db_flag)
+        bRet = SetDIBColorTable(pwc->dib.hDC, 0, nColors, pColTab );
+
+    if(!bRet)
+        dwErr = GetLastError();
+
+    free( pColTab );
+    free( pPal );
+
+    return(bRet);
+}
+
+
+//
+// Free up the dib section that was created
+//
+BOOL wmDeleteBackingStore(PWMC pwc)
+{
+    SelectObject(pwc->dib.hDC, pwc->hOldBitmap);
+    DeleteDC(pwc->dib.hDC);
+    DeleteObject(pwc->hbmDIB);
+    UnmapViewOfFile(pwc->dib.base);
+    CloseHandle(pwc->dib.hFileMap);
+    return TRUE;
+}
+
+
+//
+// This function creates the DIB section that is used for combined
+// GL and GDI calls
+//
+BOOL /*WINAPI*/ wmCreateBackingStore(PWMC pwc, long lxSize, long lySize)
+{
+    HDC hdc = pwc->hDC;
+    LPBITMAPINFO pbmi = &(pwc->bmi);
+    int     iUsage;
+
+    pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+    pbmi->bmiHeader.biWidth = lxSize;
+    pbmi->bmiHeader.biHeight= -lySize;
+    pbmi->bmiHeader.biPlanes = 1;
+    if(pwc->rgb_flag)
+        pbmi->bmiHeader.biBitCount = GetDeviceCaps(pwc->hDC, BITSPIXEL);
+    else
+        pbmi->bmiHeader.biBitCount = 8;
+    pbmi->bmiHeader.biCompression = BI_RGB;
+    pbmi->bmiHeader.biSizeImage = 0;
+    pbmi->bmiHeader.biXPelsPerMeter = 0;
+    pbmi->bmiHeader.biYPelsPerMeter = 0;
+    pbmi->bmiHeader.biClrUsed = 0;
+    pbmi->bmiHeader.biClrImportant = 0;
+
+    iUsage = (pbmi->bmiHeader.biBitCount <= 8) ? DIB_PAL_COLORS : DIB_RGB_COLORS;
+
+    pwc->cColorBits = pbmi->bmiHeader.biBitCount;
+    pwc->ScanWidth = pwc->pitch = lxSize;
+
+    wmCreateDIBSection(hdc, pwc, pbmi, iUsage);
+
+    if ((iUsage == DIB_PAL_COLORS) && !(pwc->hGLPalette)) {
+        wmCreatePalette( pwc );
+        wmSetDibColors( pwc );
+    }
+    wmSetPixelFormat(pwc, pwc->hDC);
+    return(TRUE);
+
+}
+
+
+//
+// This function copies one scan line in a DIB section to another
+//
+BOOL WINAPI wmSetDIBits(PWMC pwc, UINT uiScanWidth, UINT uiNumScans, UINT nBypp, UINT uiNewWidth, LPBYTE pBits)
+{
+    UINT uiScans = 0;
+    LPBYTE  pDest = pwc->pbPixels;
+    DWORD   dwNextScan = uiScanWidth;
+    DWORD   dwNewScan = uiNewWidth;
+    DWORD   dwScanWidth = (uiScanWidth * nBypp);
+
+    //
+    // We need to round up to the nearest DWORD
+    // and multiply by the number of bytes per
+    // pixel
+    //
+    dwNextScan = (((dwNextScan * nBypp)+ 3) & ~3);
+    dwNewScan = (((dwNewScan * nBypp)+ 3) & ~3);
+
+    for(uiScans = 0; uiScans < uiNumScans; uiScans++){
+        CopyMemory(pDest, pBits, dwScanWidth);
+        pBits += dwNextScan;
+        pDest += dwNewScan;
+    }
+
+    return(TRUE);
+
+}
+
+
+BOOL wmFlush(PWMC pwc);
+
+/*
+* Useful macros:
+Modified from file osmesa.c
+*/
+
+
+#define PIXELADDR(X,Y)  ((GLubyte *)Current->pbPixels + (Current->height-Y-1)* Current->ScanWidth + (X)*nBypp)
+#define PIXELADDR1( X, Y )  \
+((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X))
+#define PIXELADDR2( X, Y )  \
+((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*2)
+#define PIXELADDR4( X, Y )  \
+((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*4)
+
+
+BYTE DITHER_RGB_2_8BIT( int r, int g, int b, int x, int y);
+
+/* Finish all pending operations and synchronize. */
+static void finish(GLcontext* ctx)
+{
+    /* No op */
+}
+
+
+//
+// We cache all gl draw routines until a flush is made
+//
+static void flush(GLcontext* ctx)
+{
+    STARTPROFILE
+        if((Current->rgb_flag /*&& !(Current->dib.fFlushed)*/&&!(Current->db_flag))
+            ||(!Current->rgb_flag))
+        {
+            wmFlush(Current);
+        }
+        ENDPROFILE(flush)
+
+}
+
+
+
+/*
+* Set the color index used to clear the color buffer.
+*/
+static void clear_index(GLcontext* ctx, GLuint index)
+{
+    STARTPROFILE
+        Current->clearpixel = index;
+    ENDPROFILE(clear_index)
+}
+
+
+
+/*
+* Set the color used to clear the color buffer.
+*/
+static void clear_color( GLcontext* ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )
+{
+    STARTPROFILE
+        Current->clearpixel=RGB(r, g, b );
+    ENDPROFILE(clear_color)
+}
+
+
+
+/*
+* Clear the specified region of the color buffer using the clear color
+* or index as specified by one of the two functions above.
+*/
+//static void clear(GLcontext* ctx,
+//                  GLboolean all,GLint x, GLint y, GLint width, GLint height )
+// TODO: I modified this function to match the prototype in dd.h. (swansma@geocities.com)
+//       dd.h does not explain what the return type is so I could not set this to the proper
+//       value.
+static GLbitfield clear(GLcontext* ctx, GLbitfield mask,
+                  GLboolean all, GLint x, GLint y, GLint width, GLint height)
+{
+    DWORD   dwColor;
+    WORD    wColor;
+    BYTE    bColor;
+    LPDWORD lpdw = (LPDWORD)Current->pbPixels;
+    LPWORD  lpw = (LPWORD)Current->pbPixels;
+    LPBYTE  lpb = Current->pbPixels;
+    int     lines;
+
+    STARTPROFILE
+
+        if (all){
+            x=y=0;
+            width=Current->width;
+            height=Current->height;
+        }
+        if(Current->db_flag==GL_TRUE){
+            UINT    nBypp = Current->cColorBits / 8;
+            int     i = 0;
+            int     iSize = 0;
+
+            if(nBypp ==1 ){
+                /* Need rectification */
+                iSize = Current->width/4;
+                bColor  = BGR8(GetRValue(Current->clearpixel),
+                    GetGValue(Current->clearpixel),
+                    GetBValue(Current->clearpixel));
+                wColor  = MAKEWORD(bColor,bColor);
+                dwColor = MAKELONG(wColor, wColor);
+            }
+            if(nBypp == 2){
+                iSize = Current->width / 2;
+                wColor = BGR16(GetRValue(Current->clearpixel),
+                    GetGValue(Current->clearpixel),
+                    GetBValue(Current->clearpixel));
+                dwColor = MAKELONG(wColor, wColor);
+            }
+            else if(nBypp == 4){
+                iSize = Current->width;
+                dwColor = BGR32(GetRValue(Current->clearpixel),
+                    GetGValue(Current->clearpixel),
+                    GetBValue(Current->clearpixel));
+            }
+
+            while(i < iSize){
+                *lpdw = dwColor;
+                lpdw++;
+                i++;
+            }
+
+            //
+            // This is the 24bit case
+            //
+            if (nBypp == 3) {
+                iSize = Current->width *3/4;
+                dwColor = BGR24(GetRValue(Current->clearpixel),
+                    GetGValue(Current->clearpixel),
+                    GetBValue(Current->clearpixel));
+                while(i < iSize){
+                    *lpdw = dwColor;
+                    lpb += nBypp;
+                    lpdw = (LPDWORD)lpb;
+                    i++;
+                }
+            }
+
+            i = 0;
+            if (stereo_flag)
+               lines = height /2;
+            else
+               lines = height;
+            do {
+                memcpy(lpb, Current->pbPixels, iSize*4);
+                lpb += Current->ScanWidth;
+                i++;
+            }
+            while (i<lines-1);
+        }
+        else { // For single buffer
+            HDC DC=DD_GETDC;
+            HPEN Pen=CreatePen(PS_SOLID,1,Current->clearpixel);
+            HBRUSH Brush=CreateSolidBrush(Current->clearpixel);
+            HPEN Old_Pen=SelectObject(DC,Pen);
+            HBRUSH Old_Brush=SelectObject(DC,Brush);
+            Rectangle(DC,x,y,x+width,y+height);
+            SelectObject(DC,Old_Pen);
+            SelectObject(DC,Old_Brush);
+            DeleteObject(Pen);
+            DeleteObject(Brush);
+            DD_RELEASEDC;
+        }
+
+
+
+        ENDPROFILE(clear)
+
+               return mask;    // TODO: I doubt this is correct. dd.h doesn't explain what this should
+                               //       be...
+}
+
+
+
+/* Set the current color index. */
+static void set_index(GLcontext* ctx, GLuint index)
+{
+    STARTPROFILE
+        Current->pixel=index;
+    ENDPROFILE(set_index)
+}
+
+
+
+/* Set the current RGBA color. */
+static void set_color( GLcontext* ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )
+{
+    STARTPROFILE
+        Current->pixel = RGB( r, g, b );
+    ENDPROFILE(set_color)
+}
+
+
+
+/* Set the index mode bitplane mask. */
+static GLboolean index_mask(GLcontext* ctx, GLuint mask)
+{
+    /* can't implement */
+    return GL_FALSE;
+}
+
+
+
+/* Set the RGBA drawing mask. */
+static GLboolean color_mask( GLcontext* ctx,
+                            GLboolean rmask, GLboolean gmask,
+                            GLboolean bmask, GLboolean amask)
+{
+    /* can't implement */
+    return GL_FALSE;
+}
+
+
+
+/*
+* Set the pixel logic operation.  Return GL_TRUE if the device driver
+* can perform the operation, otherwise return GL_FALSE.  If GL_FALSE
+* is returned, the logic op will be done in software by Mesa.
+*/
+GLboolean logicop( GLcontext* ctx, GLenum op )
+{
+    /* can't implement */
+    return GL_FALSE;
+}
+
+
+static void dither( GLcontext* ctx, GLboolean enable )
+{
+   if (!Current)
+      return;
+
+    if(enable == GL_FALSE){
+        Current->dither_flag = GL_FALSE;
+        if(Current->cColorBits == 8)
+            Current->pixelformat = PF_INDEX8;
+    }
+    else{
+        if (Current->rgb_flag && Current->cColorBits == 8){
+            Current->pixelformat = PF_DITHER8;
+            Current->dither_flag = GL_TRUE;
+        }
+        else
+            Current->dither_flag = GL_FALSE;
+    }
+}
+
+
+
+static GLboolean set_buffer( GLcontext* ctx, GLenum mode )
+{
+   STARTPROFILE
+   /* TODO: this could be better */
+   if (mode==GL_FRONT_LEFT || mode==GL_BACK_LEFT) {
+      return GL_TRUE;
+   }
+   else {
+      return GL_FALSE;
+   }
+   ENDPROFILE(set_buffer)
+}
+
+
+
+/* Return characteristics of the output buffer. */
+static void buffer_size( GLcontext* ctx, GLuint *width, GLuint *height )
+{
+   int New_Size;
+   RECT CR;
+
+   STARTPROFILE
+   GetClientRect(Current->Window,&CR);
+
+   *width=CR.right;
+   *height=CR.bottom;
+
+   New_Size=((*width)!=Current->width) || ((*height)!=Current->height);
+
+   if (New_Size){
+      Current->width=*width;
+      Current->height=*height;
+      Current->ScanWidth=Current->width;
+      if ((Current->ScanWidth%sizeof(long))!=0)
+         Current->ScanWidth+=(sizeof(long)-(Current->ScanWidth%sizeof(long)));
+
+      if (Current->db_flag){
+#ifdef DDRAW
+         DDDeleteOffScreen(Current);
+         DDCreateOffScreen(Current);
+#else
+         if (Current->rgb_flag==GL_TRUE && Current->dither_flag!=GL_TRUE){
+            wmDeleteBackingStore(Current);
+            wmCreateBackingStore(Current, Current->width, Current->height);
+         }
+#endif
+      }
+
+      //  Resize OsmesaBuffer if in Parallel mode
+#if !defined(NO_PARALLEL)
+      if(parallelFlag)
+         PRSizeRenderBuffer(Current->width, Current->height,Current->ScanWidth,
+                            Current->rgb_flag == GL_TRUE ? Current->pbPixels: Current->ScreenMem);
+#endif
+   }
+   ENDPROFILE(buffer_size)
+}
+
+
+
+/**********************************************************************/
+/*****           Accelerated point, line, polygon rendering       *****/
+/**********************************************************************/
+
+
+static void fast_rgb_points( GLcontext* ctx, GLuint first, GLuint last )
+{
+    GLuint i;
+    //  HDC DC=DD_GETDC;
+    PWMC    pwc = Current;
+
+    STARTPROFILE
+
+        if (0 /*Current->gl_ctx->VB->MonoColor*/) {
+            /* all drawn with current color */
+            for (i=first;i<=last;i++) {
+                if (!Current->gl_ctx->VB->ClipMask[i]) {
+                    int x, y;
+                    x =       (GLint) Current->gl_ctx->VB->Win.data[i][0];
+                    y = FLIP( (GLint) Current->gl_ctx->VB->Win.data[i][1] );
+                    wmSetPixel(pwc, y,x,GetRValue(Current->pixel),
+                        GetGValue(Current->pixel), GetBValue(Current->pixel));
+                }
+            }
+        }
+        else {
+            /* draw points of different colors */
+            for (i=first;i<=last;i++) {
+                if (!Current->gl_ctx->VB->ClipMask[i]) {
+                    int x, y;
+                    unsigned long pixel=RGB(Current->gl_ctx->VB->ColorPtr->data[i][0]*255.0,
+                        Current->gl_ctx->VB->ColorPtr->data[i][1]*255.0,
+                        Current->gl_ctx->VB->ColorPtr->data[i][2]*255.0);
+                    x =       (GLint) Current->gl_ctx->VB->Win.data[i][0];
+                    y = FLIP( (GLint) Current->gl_ctx->VB->Win.data[i][1] );
+                    wmSetPixel(pwc, y,x,Current->gl_ctx->VB->ColorPtr->data[i][0]*255.0,
+                        Current->gl_ctx->VB->ColorPtr->data[i][1]*255.0,
+                        Current->gl_ctx->VB->ColorPtr->data[i][2]*255.0);
+                }
+            }
+        }
+        //   DD_RELEASEDC;
+        ENDPROFILE(fast_rgb_points)
+}
+
+
+
+/* Return pointer to accerated points function */
+extern points_func choose_points_function( GLcontext* ctx )
+{
+    STARTPROFILE
+        if (ctx->Point.Size==1.0 && !ctx->Point.SmoothFlag && ctx->RasterMask==0
+            && !ctx->Texture.Enabled  && ctx->Visual->RGBAflag) {
+            ENDPROFILE(choose_points_function)
+                return fast_rgb_points;
+        }
+        else {
+            ENDPROFILE(choose_points_function)
+                return NULL;
+        }
+}
+
+
+
+/* Draw a line using the color specified by Current->gl_ctx->VB->ColorPtr->data[pv] */
+static void fast_flat_rgb_line( GLcontext* ctx, GLuint v0, GLuint v1, GLuint pv )
+{
+    STARTPROFILE
+        int x0, y0, x1, y1;
+    unsigned long pixel;
+    HDC DC=DD_GETDC;
+    HPEN Pen;
+    HPEN Old_Pen;
+
+    if (0 /*Current->gl_ctx->VB->MonoColor*/) {
+        pixel = Current->pixel;  /* use current color */
+    }
+    else {
+        pixel = RGB(Current->gl_ctx->VB->ColorPtr->data[pv][0]*255.0, Current->gl_ctx->VB->ColorPtr->data[pv][1]*255.0, Current->gl_ctx->VB->ColorPtr->data[pv][2]*255.0);
+    }
+
+    x0 =       (int) Current->gl_ctx->VB->Win.data[v0][0];
+    y0 = FLIP( (int) Current->gl_ctx->VB->Win.data[v0][1] );
+    x1 =       (int) Current->gl_ctx->VB->Win.data[v1][0];
+    y1 = FLIP( (int) Current->gl_ctx->VB->Win.data[v1][1] );
+
+
+    BEGINGDICALL
+
+    Pen=CreatePen(PS_SOLID,1,pixel);
+    Old_Pen=SelectObject(DC,Pen);
+    MoveToEx(DC,x0,y0,NULL);
+    LineTo(DC,x1,y1);
+    SelectObject(DC,Old_Pen);
+    DeleteObject(Pen);
+    DD_RELEASEDC;
+
+    ENDGDICALL
+
+    ENDPROFILE(fast_flat_rgb_line)
+}
+
+
+
+/* Return pointer to accerated line function */
+static line_func choose_line_function( GLcontext* ctx )
+{
+    STARTPROFILE
+    if (ctx->Line.Width==1.0 && !ctx->Line.SmoothFlag && !ctx->Line.StippleFlag
+        && ctx->Light.ShadeModel==GL_FLAT && ctx->RasterMask==0
+        && !ctx->Texture.Enabled && Current->rgb_flag) {
+       ENDPROFILE(choose_line_function)
+       return fast_flat_rgb_line;
+    }
+    else {
+       ENDPROFILE(choose_line_function)
+       return NULL;
+    }
+}
+
+
+/**********************************************************************/
+/*****                 Span-based pixel drawing                   *****/
+/**********************************************************************/
+
+
+/* Write a horizontal span of 32-bit color-index pixels with a boolean mask. */
+static void write_ci32_span( const GLcontext* ctx,
+                             GLuint n, GLint x, GLint y,
+                             const GLuint index[],
+                             const GLubyte mask[] )
+{
+    STARTPROFILE
+    GLuint i;
+    PBYTE Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
+    assert(Current->rgb_flag==GL_FALSE);
+    for (i=0; i<n; i++)
+        if (mask[i])
+            Mem[i]=index[i];
+    ENDPROFILE(write_ci32_span)
+}
+
+
+/* Write a horizontal span of 8-bit color-index pixels with a boolean mask. */
+static void write_ci8_span( const GLcontext* ctx,
+                            GLuint n, GLint x, GLint y,
+                            const GLubyte index[],
+                            const GLubyte mask[] )
+{
+    STARTPROFILE
+    GLuint i;
+    PBYTE Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
+    assert(Current->rgb_flag==GL_FALSE);
+    for (i=0; i<n; i++)
+        if (mask[i])
+            Mem[i]=index[i];
+    ENDPROFILE(write_ci8_span)
+}
+
+
+
+/*
+* Write a horizontal span of pixels with a boolean mask.  The current
+* color index is used for all pixels.
+*/
+static void write_mono_ci_span(const GLcontext* ctx,
+                               GLuint n,GLint x,GLint y,
+                               const GLubyte mask[])
+{
+   STARTPROFILE
+   GLuint i;
+   BYTE *Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
+   assert(Current->rgb_flag==GL_FALSE);
+   for (i=0; i<n; i++)
+      if (mask[i])
+         Mem[i]=Current->pixel;
+   ENDPROFILE(write_mono_ci_span)
+}
+
+/*
+ * To improve the performance of this routine, frob the data into an actual
+ * scanline and call bitblt on the complete scan line instead of SetPixel.
+ */
+
+/* Write a horizontal span of RGBA color pixels with a boolean mask. */
+static void write_rgba_span( const GLcontext* ctx, GLuint n, GLint x, GLint y,
+                             const GLubyte rgba[][4], const GLubyte mask[] )
+{
+    STARTPROFILE
+    PWMC    pwc = Current;
+
+    if (pwc->rgb_flag==GL_TRUE)
+    {
+        GLuint i;
+        HDC DC=DD_GETDC;
+        y=FLIP(y);
+        if (mask) {
+            for (i=0; i<n; i++)
+                if (mask[i])
+                    wmSetPixel(pwc, y, x + i, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
+        }
+        else {
+            for (i=0; i<n; i++)
+                wmSetPixel(pwc, y, x + i, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
+        }
+        DD_RELEASEDC;
+    }
+    else
+    {
+        GLuint i;
+        BYTE *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
+        y = FLIP(y);
+        if (mask) {
+            for (i=0; i<n; i++)
+                if (mask[i])
+                    Mem[i] = GetNearestPaletteIndex(Current->hPal,RGB(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]));
+        }
+        else {
+            for (i=0; i<n; i++)
+                Mem[i] = GetNearestPaletteIndex(Current->hPal,RGB(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]));
+        }
+    }
+    ENDPROFILE(write_rgba_span)
+
+}
+
+/* Write a horizontal span of RGB color pixels with a boolean mask. */
+static void write_rgb_span( const GLcontext* ctx,
+                            GLuint n, GLint x, GLint y,
+                            const GLubyte rgb[][3], const GLubyte mask[] )
+{
+    STARTPROFILE
+    PWMC    pwc = Current;
+
+    if (pwc->rgb_flag==GL_TRUE)
+    {
+        GLuint i;
+        HDC DC=DD_GETDC;
+        y=FLIP(y);
+        if (mask) {
+            for (i=0; i<n; i++)
+                if (mask[i])
+                    wmSetPixel(pwc, y, x + i, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
+        }
+        else {
+            for (i=0; i<n; i++)
+                wmSetPixel(pwc, y, x + i, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] );
+        }
+        DD_RELEASEDC;
+    }
+    else
+    {
+        GLuint i;
+        BYTE *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
+        y = FLIP(y);
+        if (mask) {
+            for (i=0; i<n; i++)
+                if (mask[i])
+                    Mem[i] = GetNearestPaletteIndex(Current->hPal,RGB(rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]));
+        }
+        else {
+            for (i=0; i<n; i++)
+                Mem[i] = GetNearestPaletteIndex(Current->hPal,RGB(rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]));
+        }
+    }
+    ENDPROFILE(write_rgb_span)
+
+}
+
+/*
+* Write a horizontal span of pixels with a boolean mask.  The current color
+* is used for all pixels.
+*/
+static void write_mono_rgba_span( const GLcontext* ctx,
+                                  GLuint n, GLint x, GLint y,
+                                  const GLubyte mask[])
+{
+    STARTPROFILE
+    GLuint i;
+    HDC DC=DD_GETDC;
+    PWMC pwc = Current;
+    assert(Current->rgb_flag==GL_TRUE);
+    y=FLIP(y);
+    if(Current->rgb_flag==GL_TRUE){
+        for (i=0; i<n; i++)
+            if (mask[i])
+                // Trying
+                wmSetPixel(pwc,y,x+i,GetRValue(Current->pixel), GetGValue(Current->pixel), GetBValue(Current->pixel));
+    }
+    else {
+        for (i=0; i<n; i++)
+            if (mask[i])
+                SetPixel(DC, y, x+i, Current->pixel);
+    }
+    DD_RELEASEDC;
+    ENDPROFILE(write_mono_rgba_span)
+}
+
+
+
+/**********************************************************************/
+/*****                   Array-based pixel drawing                *****/
+/**********************************************************************/
+
+
+/* Write an array of 32-bit index pixels with a boolean mask. */
+static void write_ci32_pixels( const GLcontext* ctx,
+                               GLuint n, const GLint x[], const GLint y[],
+                               const GLuint index[], const GLubyte mask[] )
+{
+   STARTPROFILE
+   GLuint i;
+   assert(Current->rgb_flag==GL_FALSE);
+   for (i=0; i<n; i++) {
+      if (mask[i]) {
+         BYTE *Mem=Current->ScreenMem+FLIP(y[i])*Current->ScanWidth+x[i];
+         *Mem = index[i];
+      }
+   }
+   ENDPROFILE(write_ci32_pixels)
+}
+
+
+
+/*
+* Write an array of pixels with a boolean mask.  The current color
+* index is used for all pixels.
+*/
+static void write_mono_ci_pixels( const GLcontext* ctx,
+                                  GLuint n,
+                                  const GLint x[], const GLint y[],
+                                  const GLubyte mask[] )
+{
+   STARTPROFILE
+   GLuint i;
+   assert(Current->rgb_flag==GL_FALSE);
+   for (i=0; i<n; i++) {
+      if (mask[i]) {
+         BYTE *Mem=Current->ScreenMem+FLIP(y[i])*Current->ScanWidth+x[i];
+         *Mem = Current->pixel;
+      }
+   }
+   ENDPROFILE(write_mono_ci_pixels)
+}
+
+
+
+/* Write an array of RGBA pixels with a boolean mask. */
+static void write_rgba_pixels( const GLcontext* ctx,
+                               GLuint n, const GLint x[], const GLint y[],
+                               const GLubyte rgba[][4], const GLubyte mask[] )
+{
+    STARTPROFILE
+        GLuint i;
+    PWMC    pwc = Current;
+    HDC DC=DD_GETDC;
+    assert(Current->rgb_flag==GL_TRUE);
+    for (i=0; i<n; i++)
+       if (mask[i])
+          wmSetPixel(pwc, FLIP(y[i]),x[i],rgba[i][RCOMP],rgba[i][GCOMP],rgba[i][BCOMP]);
+    DD_RELEASEDC;
+    ENDPROFILE(write_rgba_pixels)
+}
+
+
+
+/*
+* Write an array of pixels with a boolean mask.  The current color
+* is used for all pixels.
+*/
+static void write_mono_rgba_pixels( const GLcontext* ctx,
+                                    GLuint n,
+                                    const GLint x[], const GLint y[],
+                                    const GLubyte mask[] )
+{
+    STARTPROFILE
+    GLuint i;
+    PWMC    pwc = Current;
+    HDC DC=DD_GETDC;
+    assert(Current->rgb_flag==GL_TRUE);
+    for (i=0; i<n; i++)
+        if (mask[i])
+            wmSetPixel(pwc, FLIP(y[i]),x[i],GetRValue(Current->pixel),
+                       GetGValue(Current->pixel), GetBValue(Current->pixel));
+    DD_RELEASEDC;
+    ENDPROFILE(write_mono_rgba_pixels)
+}
+
+
+
+/**********************************************************************/
+/*****            Read spans/arrays of pixels                     *****/
+/**********************************************************************/
+
+
+/* Read a horizontal span of color-index pixels. */
+static void read_ci32_span( const GLcontext* ctx, GLuint n, GLint x, GLint y,
+                            GLuint index[])
+{
+   STARTPROFILE
+   GLuint i;
+   BYTE *Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
+   assert(Current->rgb_flag==GL_FALSE);
+   for (i=0; i<n; i++)
+      index[i]=Mem[i];
+   ENDPROFILE(read_ci32_span)
+}
+
+
+
+
+/* Read an array of color index pixels. */
+static void read_ci32_pixels( const GLcontext* ctx,
+                              GLuint n, const GLint x[], const GLint y[],
+                              GLuint indx[], const GLubyte mask[] )
+{
+   STARTPROFILE
+   GLuint i;
+   assert(Current->rgb_flag==GL_FALSE);
+   for (i=0; i<n; i++) {
+      if (mask[i]) {
+         indx[i]=*(Current->ScreenMem+FLIP(y[i])*Current->ScanWidth+x[i]);
+      }
+   }
+   ENDPROFILE(read_ci32_pixels)
+}
+
+
+
+/* Read a horizontal span of color pixels. */
+static void read_rgba_span( const GLcontext* ctx,
+                            GLuint n, GLint x, GLint y,
+                            GLubyte rgba[][4] )
+{
+   STARTPROFILE
+   UINT i;
+   COLORREF Color;
+   HDC DC=DD_GETDC;
+   assert(Current->rgb_flag==GL_TRUE);
+   /*   y=FLIP(y);*/
+   y = Current->height - y - 1;
+   for (i=0; i<n; i++) {
+      Color=GetPixel(DC,x+i,y);
+      rgba[i][RCOMP] = GetRValue(Color);
+      rgba[i][GCOMP] = GetGValue(Color);
+      rgba[i][BCOMP] = GetBValue(Color);
+      rgba[i][ACOMP] = 255;
+   }
+   DD_RELEASEDC;
+// Brian P. Has mentioned to comment this out.
+//   memset(alpha,0,n*sizeof(GLubyte));
+   ENDPROFILE(read_rgba_span)
+}
+
+
+/* Read an array of color pixels. */
+static void read_rgba_pixels( const GLcontext* ctx,
+                              GLuint n, const GLint x[], const GLint y[],
+                              GLubyte rgba[][4], const GLubyte mask[] )
+{
+   STARTPROFILE
+   GLuint i;
+   COLORREF Color;
+   HDC DC=DD_GETDC;
+   assert(Current->rgb_flag==GL_TRUE);
+   for (i=0; i<n; i++) {
+      if (mask[i]) {
+         Color=GetPixel(DC,x[i],FLIP(y[i]));
+         rgba[i][RCOMP] = GetRValue(Color);
+         rgba[i][GCOMP] = GetGValue(Color);
+         rgba[i][BCOMP] = GetBValue(Color);
+         rgba[i][ACOMP] = 255;
+      }
+   }
+   DD_RELEASEDC;
+// Brian P. has mentioned to comment this out.
+//   memset(alpha,0,n*sizeof(GLint));
+   ENDPROFILE(read_rgba_pixels)
+}
+
+
+
+/**********************************************************************/
+/**********************************************************************/
+
+
+static const char *renderer_string(void)
+{
+   return "Windows";
+}
+
+
+
+void setup_DD_pointers( GLcontext* ctx )
+{
+    ctx->Driver.RendererString = renderer_string;
+    ctx->Driver.UpdateState = setup_DD_pointers;
+    ctx->Driver.GetBufferSize = buffer_size;
+    ctx->Driver.Finish = finish;
+    ctx->Driver.Flush = flush;
+
+    ctx->Driver.ClearIndex = clear_index;
+    ctx->Driver.ClearColor = clear_color;
+    ctx->Driver.Clear = clear;
+
+    ctx->Driver.Index = set_index;
+    ctx->Driver.Color = set_color;
+    ctx->Driver.IndexMask = index_mask;
+    ctx->Driver.ColorMask = color_mask;
+
+    ctx->Driver.LogicOp = logicop;
+    ctx->Driver.Dither = dither;
+
+    ctx->Driver.SetBuffer = set_buffer;
+    ctx->Driver.GetBufferSize = buffer_size;
+
+    ctx->Driver.PointsFunc = choose_points_function(ctx);
+    ctx->Driver.LineFunc = choose_line_function(ctx);
+    ctx->Driver.TriangleFunc = choose_triangle_function( ctx );
+
+    /* Pixel/span writing functions: */
+       ctx->Driver.WriteRGBASpan        = write_rgba_span;
+    ctx->Driver.WriteRGBSpan         = write_rgb_span;
+    ctx->Driver.WriteMonoRGBASpan    = write_mono_rgba_span;
+    ctx->Driver.WriteRGBAPixels      = write_rgba_pixels;
+    ctx->Driver.WriteMonoRGBAPixels  = write_mono_rgba_pixels;
+    ctx->Driver.WriteCI32Span        = write_ci32_span;
+    ctx->Driver.WriteCI8Span         = write_ci8_span;
+    ctx->Driver.WriteMonoCISpan      = write_mono_ci_span;
+    ctx->Driver.WriteCI32Pixels      = write_ci32_pixels;
+    ctx->Driver.WriteMonoCIPixels    = write_mono_ci_pixels;
+
+    ctx->Driver.ReadCI32Span        = read_ci32_span;
+    ctx->Driver.ReadRGBASpan        = read_rgba_span;
+    ctx->Driver.ReadCI32Pixels      = read_ci32_pixels;
+    ctx->Driver.ReadRGBAPixels      = read_rgba_pixels;
+}
+
+
+/**********************************************************************/
+/*****                  WMesa API Functions                       *****/
+/**********************************************************************/
+
+
+
+#define PAL_SIZE 256
+static void GetPalette(HPALETTE Pal,RGBQUAD *aRGB)
+{
+    STARTPROFILE
+        int i;
+    HDC hdc;
+    struct
+    {
+        WORD Version;
+        WORD NumberOfEntries;
+        PALETTEENTRY aEntries[PAL_SIZE];
+    } Palette =
+    {
+        0x300,
+            PAL_SIZE
+    };
+    hdc=GetDC(NULL);
+    if (Pal!=NULL)
+        GetPaletteEntries(Pal,0,PAL_SIZE,Palette.aEntries);
+    else
+        GetSystemPaletteEntries(hdc,0,PAL_SIZE,Palette.aEntries);
+    if (GetSystemPaletteUse(hdc) == SYSPAL_NOSTATIC)
+    {
+        for(i = 0; i <PAL_SIZE; i++)
+            Palette.aEntries[i].peFlags = PC_RESERVED;
+        Palette.aEntries[255].peRed = 255;
+        Palette.aEntries[255].peGreen = 255;
+        Palette.aEntries[255].peBlue = 255;
+        Palette.aEntries[255].peFlags = 0;
+        Palette.aEntries[0].peRed = 0;
+        Palette.aEntries[0].peGreen = 0;
+        Palette.aEntries[0].peBlue = 0;
+        Palette.aEntries[0].peFlags = 0;
+    }
+    else
+    {
+        int nStaticColors;
+        int nUsableColors;
+        nStaticColors = GetDeviceCaps(hdc, NUMCOLORS)/2;
+        for (i=0; i<nStaticColors; i++)
+            Palette.aEntries[i].peFlags = 0;
+        nUsableColors = PAL_SIZE-nStaticColors;
+        for (; i<nUsableColors; i++)
+            Palette.aEntries[i].peFlags = PC_RESERVED;
+        for (; i<PAL_SIZE-nStaticColors; i++)
+            Palette.aEntries[i].peFlags = PC_RESERVED;
+        for (i=PAL_SIZE-nStaticColors; i<PAL_SIZE; i++)
+            Palette.aEntries[i].peFlags = 0;
+    }
+    ReleaseDC(NULL,hdc);
+    for (i=0; i<PAL_SIZE; i++)
+    {
+        aRGB[i].rgbRed=Palette.aEntries[i].peRed;
+        aRGB[i].rgbGreen=Palette.aEntries[i].peGreen;
+        aRGB[i].rgbBlue=Palette.aEntries[i].peBlue;
+        aRGB[i].rgbReserved=Palette.aEntries[i].peFlags;
+    }
+    ENDPROFILE(GetPalette)
+}
+
+
+WMesaContext WMesaCreateContext( HWND hWnd, HPALETTE* Pal,
+                                GLboolean rgb_flag,
+                                GLboolean db_flag )
+{
+    RECT CR;
+    WMesaContext c;
+    GLboolean true_color_flag;
+    c = (struct wmesa_context * ) calloc(1,sizeof(struct wmesa_context));
+    if (!c)
+        return NULL;
+
+    c->Window=hWnd;
+    c->hDC = GetDC(hWnd);
+    true_color_flag = GetDeviceCaps(c->hDC, BITSPIXEL) > 8;
+#ifdef DDRAW
+    if(true_color_flag) c->rgb_flag = rgb_flag = GL_TRUE;
+#endif
+
+
+#ifdef DITHER
+    if ((true_color_flag==GL_FALSE) && (rgb_flag == GL_TRUE)){
+        c->dither_flag = GL_TRUE;
+        c->hPalHalfTone = WinGCreateHalftonePalette();
+    }
+    else
+        c->dither_flag = GL_FALSE;
+#else
+    c->dither_flag = GL_FALSE;
+#endif
+
+
+    if (rgb_flag==GL_FALSE)
+    {
+        c->rgb_flag = GL_FALSE;
+        //    c->pixel = 1;
+        c->db_flag = db_flag =GL_TRUE; // WinG requires double buffering
+        printf("Single buffer is not supported in color index mode, setting to double buffer.\n");
+    }
+    else
+    {
+        c->rgb_flag = GL_TRUE;
+        //    c->pixel = 0;
+    }
+    GetClientRect(c->Window,&CR);
+    c->width=CR.right;
+    c->height=CR.bottom;
+    if (db_flag)
+    {
+        c->db_flag = 1;
+        /* Double buffered */
+#ifndef DDRAW
+        //  if (c->rgb_flag==GL_TRUE && c->dither_flag != GL_TRUE )
+        {
+            wmCreateBackingStore(c, c->width, c->height);
+
+        }
+#endif
+    }
+    else
+    {
+        /* Single Buffered */
+        if (c->rgb_flag)
+            c->db_flag = 0;
+    }
+#ifdef DDRAW
+    if (DDInit(c,hWnd) == GL_FALSE) {
+        free( (void *) c );
+        exit(1);
+    }
+#endif
+
+
+    c->gl_visual = gl_create_visual(rgb_flag,
+                                    GL_FALSE,   /* software alpha */
+                                    db_flag,    /* db_flag */
+                                    GL_FALSE,   /* stereo */
+                                    16,         /* depth_bits */
+                                    8,          /* stencil_bits */
+                                    8,          /* accum_bits */
+                                    0,          /* index bits */
+                                    8,8,8,8 );  /* r, g, b, a bits */
+
+    if (!c->gl_visual) {
+        return NULL;
+    }
+
+    /* allocate a new Mesa context */
+    c->gl_ctx = gl_create_context( c->gl_visual, NULL, c, GL_TRUE);
+
+    if (!c->gl_ctx) {
+        gl_destroy_visual( c->gl_visual );
+        free(c);
+        return NULL;
+    }
+
+    c->gl_buffer = gl_create_framebuffer( c->gl_visual );
+    if (!c->gl_buffer) {
+        gl_destroy_visual( c->gl_visual );
+        gl_destroy_context( c->gl_ctx );
+        free(c);
+        return NULL;
+    }
+
+       c->gl_ctx->Driver.UpdateState = setup_DD_pointers;
+
+    //  setup_DD_pointers(c->gl_ctx);
+
+    return c;
+}
+
+void WMesaDestroyContext( void )
+{
+    WMesaContext c = Current;
+    ReleaseDC(c->Window,c->hDC);
+    WC = c;
+    if(c->hPalHalfTone != NULL)
+        DeleteObject(c->hPalHalfTone);
+    gl_destroy_visual( c->gl_visual );
+    gl_destroy_framebuffer( c->gl_buffer );
+    gl_destroy_context( c->gl_ctx );
+
+    if (c->db_flag)
+#ifdef DDRAW
+        DDFree(c);
+#else
+    wmDeleteBackingStore(c);
+#endif
+    free( (void *) c );
+    //Following code is added to enable parallel render
+    // Parallel render only work in double buffer mode
+#if !defined(NO_PARALLEL)
+    if(parallelMachine)
+        PRDestroyRenderBuffer();
+#endif
+    // End modification
+}
+
+
+
+void /*APIENTRY*/ WMesaMakeCurrent( WMesaContext c )
+{
+    if(!c){
+        Current = c;
+        return;
+    }
+
+    //
+    // A little optimization
+    // If it already is current,
+    // don't set it again
+    //
+    if(Current == c)
+        return;
+
+    //gl_set_context( c->gl_ctx );
+    gl_make_current(c->gl_ctx, c->gl_buffer);
+    setup_DD_pointers(c->gl_ctx);
+    Current = c;
+    if (Current->gl_ctx->Viewport.Width==0) {
+        /* initialize viewport to window size */
+        gl_Viewport( Current->gl_ctx,
+            0, 0, Current->width, Current->height );
+    }
+    if ((c->cColorBits <= 8 ) && (c->rgb_flag == GL_TRUE)){
+        WMesaPaletteChange(c->hPalHalfTone);
+    }
+}
+
+
+
+void /*APIENTRY*/ WMesaSwapBuffers( void )
+{
+    HDC DC = Current->hDC;
+    if (Current->db_flag)
+        wmFlush(Current);
+}
+
+
+
+void /*APIENTRY*/ WMesaPaletteChange(HPALETTE Pal)
+{
+    int vRet;
+    LPPALETTEENTRY pPal;
+    if (Current && (Current->rgb_flag==GL_FALSE || Current->dither_flag == GL_TRUE))
+    {
+        pPal = (PALETTEENTRY *)malloc( 256 * sizeof(PALETTEENTRY));
+        Current->hPal=Pal;
+        //  GetPaletteEntries( Pal, 0, 256, pPal );
+        GetPalette( Pal, pPal );
+#ifdef DDRAW
+        Current->lpDD->lpVtbl->CreatePalette(Current->lpDD,DDPCAPS_8BIT,
+            pPal, &(Current->lpDDPal), NULL);
+        if (Current->lpDDPal)
+            Current->lpDDSPrimary->lpVtbl->SetPalette(Current->lpDDSPrimary,Current->lpDDPal);
+#else
+        vRet = SetDIBColorTable(Current->dib.hDC,0,256,pPal);
+#endif
+        free( pPal );
+    }
+
+}
+
+
+
+
+static unsigned char threeto8[8] = {
+    0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377
+};
+
+static unsigned char twoto8[4] = {
+    0, 0x55, 0xaa, 0xff
+};
+
+static unsigned char oneto8[2] = {
+    0, 255
+};
+
+static unsigned char componentFromIndex(UCHAR i, UINT nbits, UINT shift)
+{
+    unsigned char val;
+
+    val = i >> shift;
+    switch (nbits) {
+
+    case 1:
+        val &= 0x1;
+        return oneto8[val];
+
+    case 2:
+        val &= 0x3;
+        return twoto8[val];
+
+    case 3:
+        val &= 0x7;
+        return threeto8[val];
+
+    default:
+        return 0;
+    }
+}
+
+void /*WINAPI*/ wmCreatePalette( PWMC pwdc )
+{
+    /* Create a compressed and re-expanded 3:3:2 palette */
+    int            i;
+    LOGPALETTE     *pPal;
+    BYTE           rb, rs, gb, gs, bb, bs;
+
+    pwdc->nColors = 0x100;
+
+    pPal = (PLOGPALETTE)malloc(sizeof(LOGPALETTE) + pwdc->nColors * sizeof(PALETTEENTRY));
+    memset( pPal, 0, sizeof(LOGPALETTE) + pwdc->nColors * sizeof(PALETTEENTRY) );
+
+    pPal->palVersion = 0x300;
+
+    rb = REDBITS;
+    rs = REDSHIFT;
+    gb = GREENBITS;
+    gs = GREENSHIFT;
+    bb = BLUEBITS;
+    bs = BLUESHIFT;
+
+    if (pwdc->db_flag) {
+
+        /* Need to make two palettes: one for the screen DC and one for the DIB. */
+        pPal->palNumEntries = pwdc->nColors;
+        for (i = 0; i < pwdc->nColors; i++) {
+            pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs );
+            pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs );
+            pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs );
+            pPal->palPalEntry[i].peFlags = 0;
+        }
+        pwdc->hGLPalette = CreatePalette( pPal );
+        pwdc->hPalette = CreatePalette( pPal );
+    }
+
+    else {
+        pPal->palNumEntries = pwdc->nColors;
+        for (i = 0; i < pwdc->nColors; i++) {
+            pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs );
+            pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs );
+            pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs );
+            pPal->palPalEntry[i].peFlags = 0;
+        }
+        pwdc->hGLPalette = CreatePalette( pPal );
+    }
+
+    free(pPal);
+
+}
+
+void /*WINAPI*/ wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
+{
+    if (Current->db_flag) {
+        LPBYTE  lpb = pwc->pbPixels;
+        LPDWORD lpdw;
+        LPWORD  lpw;
+        UINT    nBypp = pwc->cColorBits >> 3;
+        UINT    nOffset = iPixel % nBypp;
+
+        // Move the pixel buffer pointer to the scanline that we
+        // want to access
+
+        //      pwc->dib.fFlushed = FALSE;
+
+        lpb += pwc->ScanWidth * iScanLine;
+        // Now move to the desired pixel
+        lpb += iPixel * nBypp;
+        lpb = PIXELADDR(iPixel, iScanLine);
+        lpdw = (LPDWORD)lpb;
+        lpw = (LPWORD)lpb;
+
+        if(nBypp == 1){
+            if(pwc->dither_flag)
+                *lpb = DITHER_RGB_2_8BIT(r,g,b,iScanLine,iPixel);
+            else
+                *lpb = BGR8(r,g,b);
+        }
+        else if(nBypp == 2)
+            *lpw = BGR16(r,g,b);
+        else if (nBypp == 3){
+            *lpdw = BGR24(r,g,b);
+        }
+        else if (nBypp == 4)
+            *lpdw = BGR32(r,g,b);
+    }
+    else{
+        SetPixel(Current->hDC, iPixel, iScanLine, RGB(r,g,b));
+        DD_RELEASEDC;
+    }
+}
+
+void /*WINAPI*/ wmCreateDIBSection(
+                                   HDC   hDC,
+                                   PWMC pwc,    // handle of device context
+                                   CONST BITMAPINFO *pbmi,  // address of structure containing bitmap size, format, and color data
+                                   UINT iUsage  // color data type indicator: RGB values or palette indices
+                                   )
+{
+    DWORD   dwSize = 0;
+    DWORD   dwScanWidth;
+    UINT    nBypp = pwc->cColorBits / 8;
+    HDC     hic;
+
+    dwScanWidth = (((pwc->ScanWidth * nBypp)+ 3) & ~3);
+
+    pwc->ScanWidth =pwc->pitch = dwScanWidth;
+
+    if (stereo_flag)
+        pwc->ScanWidth = 2* pwc->pitch;
+
+    dwSize = sizeof(BITMAPINFO) + (dwScanWidth * pwc->height);
+
+    pwc->dib.hFileMap = CreateFileMapping((HANDLE)PAGE_FILE,
+        NULL,
+        PAGE_READWRITE | SEC_COMMIT,
+        0,
+        dwSize,
+        NULL);
+
+    if (!pwc->dib.hFileMap)
+        return;
+
+    pwc->dib.base = MapViewOfFile(pwc->dib.hFileMap,
+        FILE_MAP_ALL_ACCESS,
+        0,
+        0,
+        0);
+
+    if(!pwc->dib.base){
+        CloseHandle(pwc->dib.hFileMap);
+        return;
+    }
+
+    //  pwc->pbPixels = pwc->addrOffScreen = ((LPBYTE)pwc->dib.base) + sizeof(BITMAPINFO);
+
+    //  pwc->dib.hDC = CreateCompatibleDC(hDC);
+
+    CopyMemory(pwc->dib.base, pbmi, sizeof(BITMAPINFO));
+
+    hic = CreateIC("display", NULL, NULL, NULL);
+    pwc->dib.hDC = CreateCompatibleDC(hic);
+
+
+    /*  pwc->hbmDIB = CreateDIBitmap(hic,
+    &(pwc->bmi.bmiHeader),
+    CBM_INIT,
+    pwc->pbPixels,
+    &(pwc->bmi),
+    DIB_RGB_COLORS);
+    */
+    pwc->hbmDIB = CreateDIBSection(hic,
+        &(pwc->bmi),
+        (iUsage ? DIB_PAL_COLORS : DIB_RGB_COLORS),
+        &(pwc->pbPixels),
+        pwc->dib.hFileMap,
+        0);
+        /*
+        pwc->hbmDIB = CreateDIBSection(hic,
+        &(pwc->bmi),
+        DIB_RGB_COLORS,
+        &(pwc->pbPixels),
+        pwc->dib.hFileMap,
+        0);
+    */
+    pwc->ScreenMem = pwc->addrOffScreen = pwc->pbPixels;
+    pwc->hOldBitmap = SelectObject(pwc->dib.hDC, pwc->hbmDIB);
+
+    DeleteDC(hic);
+
+    return;
+
+}
+
+//
+// Blit memory DC to screen DC
+//
+BOOL /*WINAPI*/ wmFlush(PWMC pwc)
+{
+    BOOL    bRet = 0;
+    DWORD   dwErr = 0;
+#ifdef DDRAW
+    HRESULT             ddrval;
+#endif
+
+    // Now search through the torus frames and mark used colors
+    if(pwc->db_flag){
+#ifdef DDRAW
+        if (pwc->lpDDSOffScreen == NULL)
+            if(DDCreateOffScreen(pwc) == GL_FALSE)
+                return;
+
+            pwc->lpDDSOffScreen->lpVtbl->Unlock(pwc->lpDDSOffScreen, NULL);
+
+            while( 1 )
+            {
+                ddrval = pwc->lpDDSPrimary->lpVtbl->Blt( pwc->lpDDSPrimary,
+                    &(pwc->rectSurface), pwc->lpDDSOffScreen, &(pwc->rectOffScreen), 0, NULL );
+
+                if( ddrval == DD_OK )
+                {
+                    break;
+                }
+                if( ddrval == DDERR_SURFACELOST )
+                {
+                    if(!DDRestoreAll(pwc))
+                    {
+                        break;
+                    }
+                }
+                if( ddrval != DDERR_WASSTILLDRAWING )
+                {
+                    break;
+                }
+            }
+
+            while (pwc->lpDDSOffScreen->lpVtbl->Lock(pwc->lpDDSOffScreen,
+                NULL, &(pwc->ddsd), 0, NULL) == DDERR_WASSTILLDRAWING)
+                ;
+
+            if(ddrval != DD_OK)
+                dwErr = GetLastError();
+#else
+            bRet = BitBlt(pwc->hDC, 0, 0, pwc->width, pwc->height,
+                pwc->dib.hDC, 0, 0, SRCCOPY);
+#endif
+    }
+
+    return(TRUE);
+
+}
+
+
+// The following code is added by Li Wei to enable stereo display
+
+#if !defined(NO_STEREO)
+
+void WMesaShowStereo(GLuint list)
+{
+
+    GLbitfield mask = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
+    GLfloat cm[16];
+    GLint matrix_mode;
+    // Must use double Buffer
+    if( ! Current-> db_flag )
+        return;
+
+
+    glGetIntegerv(GL_MATRIX_MODE,&matrix_mode);
+
+    //  glPushMatrix();  //****
+    WMesaViewport(Current->gl_ctx,0,Current->height/2,Current->width,Current->height/2);
+    //  Current->gl_ctx->NewState = 0;
+
+    //  glViewport(0,0,Current->width,Current->height/2);
+    if(matrix_mode!=GL_MODELVIEW)
+        glMatrixMode(GL_MODELVIEW);
+
+    glGetFloatv(GL_MODELVIEW_MATRIX,cm);
+    glLoadIdentity();
+    gluLookAt(viewDistance/2,0.0,0.0 ,
+        viewDistance/2,0.0,-1.0,
+        0.0,1.0,0.0 );
+    //  glTranslatef(viewDistance/2.0,0.,0.);
+    glMultMatrixf( cm );
+
+    Current->ScreenMem = Current->pbPixels = Current->addrOffScreen;
+    //glPushMatrix();
+    glCallList( list );
+    //glPopMatrix();
+
+    glGetFloatv(GL_MODELVIEW_MATRIX,cm);
+    glLoadIdentity();
+    gluLookAt(-viewDistance/2,0.0,0.0 ,
+        -viewDistance/2,0.0,-1.0,
+        0.0,1.0,0.0 );
+    //  glTranslatef(-viewDistance/2.0,0.,0.);
+    glMultMatrixf(cm);
+
+    Current->ScreenMem = Current->pbPixels = Current->addrOffScreen + Current->pitch;
+    glCallList(list);
+    if(matrix_mode!=GL_MODELVIEW)
+        glMatrixMode(matrix_mode);
+
+    //  glPopMatrix();
+    glFlush();
+
+    WMesaViewport(Current->gl_ctx,0,0,Current->width,Current->height);
+    //  Current->gl_ctx->NewState = 0;
+    WMesaSwapBuffers();
+
+}
+
+void toggleStereoMode()
+{
+    if(!Current->db_flag)
+        return;
+    if(!stereo_flag){
+        stereo_flag = 1;
+        if(stereoBuffer==GL_FALSE)
+#if !defined(NO_PARALLEL)
+            if(!parallelFlag)
+#endif
+            {
+                Current->ScanWidth = Current->pitch*2;
+            }
+    }
+    else {
+        stereo_flag = 0;
+#if !defined(NO_PARALLEL)
+        if(!parallelFlag)
+#endif
+            Current->ScanWidth = Current->pitch;
+        Current->pbPixels = Current->addrOffScreen;
+    }
+}
+
+/* if in stereo mode, the following function is called */
+void glShowStereo(GLuint list)
+{
+    WMesaShowStereo(list);
+}
+
+#endif // End if NO_STEREO not defined
+
+#if !defined(NO_PARALLEL)
+
+void toggleParallelMode(void)
+{
+    if(!parallelFlag){
+        parallelFlag = GL_TRUE;
+        if(parallelMachine==GL_FALSE){
+            PRCreateRenderBuffer( Current->rgb_flag? GL_RGBA :GL_COLOR_INDEX,
+                Current->cColorBits/8,
+                Current->width ,Current->height,
+                Current->ScanWidth,
+                Current->rgb_flag? Current->pbPixels: Current->ScreenMem);
+            parallelMachine = GL_TRUE;
+        }
+    }
+    else {
+        parallelFlag = GL_FALSE;
+        if(parallelMachine==GL_TRUE){
+            PRDestroyRenderBuffer();
+            parallelMachine=GL_FALSE;
+            ReadyForNextFrame = GL_TRUE;
+        }
+
+        /***********************************************
+        // Seems something wrong!!!!
+        ************************************************/
+
+        WMesaMakeCurrent(Current);
+#if !defined(NO_STEREO)
+        stereo_flag = GL_FALSE ;
+#endif
+    }
+}
+
+void PRShowRenderResult(void)
+{
+    int flag = 0;
+    if(!glImageRendered())
+        return;
+
+    if (parallelFlag)
+    {
+        WMesaSwapBuffers();
+    }
+
+}
+#endif //End if NO_PARALLEL not defined
+
+//end modification
+
+BYTE DITHER_RGB_2_8BIT( int red, int green, int blue, int pixel, int scanline)
+{
+    char unsigned redtemp, greentemp, bluetemp, paletteindex;
+
+    //*** now, look up each value in the halftone matrix
+    //*** using an 8x8 ordered dither.
+    redtemp = aDividedBy51[red]
+        + (aModulo51[red] > aHalftone8x8[(pixel%8)*8
+        + scanline%8]);
+    greentemp = aDividedBy51[(char unsigned)green]
+        + (aModulo51[green] > aHalftone8x8[
+        (pixel%8)*8 + scanline%8]);
+    bluetemp = aDividedBy51[(char unsigned)blue]
+        + (aModulo51[blue] > aHalftone8x8[
+        (pixel%8)*8 +scanline%8]);
+
+    //*** recombine the halftoned rgb values into a palette index
+    paletteindex =
+        redtemp + aTimes6[greentemp] + aTimes36[bluetemp];
+
+    //*** and translate through the wing halftone palette
+    //*** translation vector to give the correct value.
+    return aWinGHalftoneTranslation[paletteindex];
+}
+
+#ifdef DDRAW
+/*
+* restoreAll
+*
+* restore all lost objects
+*/
+HRESULT DDRestoreAll( WMesaContext wc )
+{
+    HRESULT     ddrval;
+
+    ddrval = wc->lpDDSPrimary->lpVtbl->Restore(wc->lpDDSPrimary);
+    if( ddrval == DD_OK )
+    {
+        ddrval = wc->lpDDSOffScreen->lpVtbl->Restore(wc->lpDDSOffScreen);
+    }
+    return ddrval;
+
+} /* restoreAll */
+
+
+  /*
+  * This function is called if the initialization function fails
+*/
+BOOL initFail( HWND hwnd, WMesaContext wc )
+{
+    DDFree(wc);
+    MessageBox( hwnd, "DirectDraw Init FAILED", "", MB_OK );
+    return FALSE;
+
+} /* initFail */
+
+
+static void DDDeleteOffScreen(WMesaContext wc)
+{
+    if( wc->lpDDSOffScreen != NULL )
+    {
+        wc->lpDDSOffScreen->lpVtbl->Unlock(wc->lpDDSOffScreen,NULL);
+        wc->lpDDSOffScreen->lpVtbl->Release(wc->lpDDSOffScreen);
+        wc->lpDDSOffScreen = NULL;
+    }
+
+}
+
+static void DDFreePrimarySurface(WMesaContext wc)
+{
+    if( wc->lpDDSPrimary != NULL )
+    {
+        if(wc->db_flag == GL_FALSE)
+            wc->lpDDSPrimary->lpVtbl->ReleaseDC(wc->lpDDSPrimary, wc->hDC);
+        wc->lpDDSPrimary->lpVtbl->Release(wc->lpDDSPrimary);
+        wc->lpDDSPrimary = NULL;
+    }
+}
+
+static BOOL DDCreatePrimarySurface(WMesaContext wc)
+{
+    HRESULT ddrval;
+    DDSCAPS             ddscaps;
+    wc->ddsd.dwSize = sizeof( wc->ddsd );
+    wc->ddsd.dwFlags = DDSD_CAPS;
+    wc->ddsd.ddsCaps.dwCaps =   DDSCAPS_PRIMARYSURFACE;
+
+    ddrval = wc->lpDD->lpVtbl->CreateSurface( wc->lpDD,&(wc->ddsd), &(wc->lpDDSPrimary), NULL );
+    if( ddrval != DD_OK )
+    {
+        return initFail(wc->hwnd , wc);
+    }
+    if(wc->db_flag == GL_FALSE)
+        wc->lpDDSPrimary->lpVtbl->GetDC(wc->lpDDSPrimary, wc->hDC);
+    return TRUE;
+}
+
+static BOOL DDCreateOffScreen(WMesaContext wc)
+{
+    POINT   pt;
+    HRESULT     ddrval;
+    if(wc->lpDD == NULL)
+        return FALSE;
+    GetClientRect( wc->hwnd, &(wc->rectOffScreen) );
+    wc->ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
+    wc->ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
+    wc->ddsd.dwHeight = wc->rectOffScreen.bottom - wc->rectOffScreen.top;
+    wc->ddsd.dwWidth = wc->rectOffScreen.right - wc->rectOffScreen.left;
+
+    ddrval = wc->lpDD->lpVtbl->CreateSurface( wc->lpDD, &(wc->ddsd), &(wc->lpDDSOffScreen), NULL );
+    if( ddrval != DD_OK )
+    {
+        return FALSE;
+    }
+
+    while (wc->lpDDSOffScreen->lpVtbl->Lock(wc->lpDDSOffScreen,NULL, &(wc->ddsd), 0, NULL) == DDERR_WASSTILLDRAWING)
+        ;
+    //  while ((ddrval = wc->lpDDSOffScreen->lpVtbl->Lock(wc->lpDDSOffScreen,NULL, &(wc->ddsd), DDLOCK_SURFACEMEMORYPTR , NULL)) != DD_OK)
+    ;
+    if(wc->ddsd.lpSurface==NULL)
+        return initFail(wc->hwnd, wc);
+
+    wc->ScreenMem = wc->pbPixels = wc->addrOffScreen = (PBYTE)(wc->ddsd.lpSurface);
+    wc->ScanWidth = wc->pitch = wc->ddsd.lPitch;
+    if (stereo_flag)
+        wc->ScanWidth = wc->ddsd.lPitch*2;
+
+    GetClientRect( wc->hwnd, &(wc->rectSurface) );
+    pt.x = pt.y = 0;
+    ClientToScreen( wc->hwnd, &pt );
+    OffsetRect(&(wc->rectSurface), pt.x, pt.y);
+    wmSetPixelFormat(wc, wc->hDC);
+    return TRUE;
+}
+
+/*
+* doInit - do work required for every instance of the application:
+*                create the window, initialize data
+*/
+static BOOL DDInit( WMesaContext wc, HWND hwnd)
+{
+    HRESULT             ddrval;
+    DWORD dwFrequency;
+
+    LPDIRECTDRAW            lpDD;           // DirectDraw object
+    LPDIRECTDRAW2            lpDD2;
+
+
+    wc->fullScreen = displayOptions.fullScreen;
+    wc->gMode = displayOptions.mode;
+    wc->hwnd = hwnd;
+    stereo_flag = displayOptions.stereo;
+    if(wc->db_flag!= GL_TRUE)
+        stereo_flag = GL_FALSE;
+        /*
+        * create the main DirectDraw object
+    */
+    ddrval = DirectDrawCreate( NULL, &(wc->lpDD), NULL );
+    if( ddrval != DD_OK )
+    {
+        return initFail(hwnd,wc);
+    }
+
+    // Get exclusive mode if requested
+    if(wc->fullScreen)
+    {
+        ddrval = wc->lpDD->lpVtbl->SetCooperativeLevel( wc->lpDD, hwnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN );
+    }
+    else
+    {
+        ddrval = wc->lpDD->lpVtbl->SetCooperativeLevel( wc->lpDD, hwnd, DDSCL_NORMAL );
+    }
+    if( ddrval != DD_OK )
+    {
+        return initFail(hwnd , wc);
+    }
+
+
+    /*  ddrval = wc->lpDD->lpVtbl->QueryInterface(wc->lpDD, IID_IDirectDraw2,
+    (LPVOID *)((wc->lpDD2)));
+
+    */
+    if(ddrval != DD_OK)
+        return initFail(hwnd , wc);
+
+
+    //ddrval = wc->lpDD->lpVtbl->GetDisplayMode( wc->lpDD, &(wc->ddsd));
+    //  wc->lpDD2->lpVtbl->GetMonitorFrequency(wc->lpDD, &dwFrequency);
+    switch( wc->gMode )
+    {
+    case 1:  ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 640, 480, displayOptions.bpp); break;
+    case 2:  ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 800, 600, displayOptions.bpp); break;
+    case 3:  ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 1024, 768, displayOptions.bpp); break;
+    case 4:  ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 1152, 864, displayOptions.bpp); break;
+    case 5:  ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 1280, 1024, displayOptions.bpp); break;
+    }
+
+    if( ddrval != DD_OK )
+    {
+        printf("Can't modify display mode, current mode used\n");
+        //        return initFail(hwnd , wc);
+    }
+    //ddrval = wc->lpDD->lpVtbl->GetDisplayMode( wc->lpDD, &(wc->ddsd));
+    switch(ddrval){
+    case DDERR_INVALIDOBJECT:
+        break;
+    case DDERR_INVALIDPARAMS:
+        break;
+    case DDERR_UNSUPPORTEDMODE:
+        ;
+    }
+
+    if(DDCreatePrimarySurface(wc) == GL_FALSE)
+        return initFail(hwnd, wc);
+
+    if(wc->db_flag)
+        return DDCreateOffScreen(wc);
+} /* DDInit */
+
+static void DDFree( WMesaContext wc)
+{
+    if( wc->lpDD != NULL )
+    {
+        DDFreePrimarySurface(wc);
+        DDDeleteOffScreen(wc);
+        wc->lpDD->lpVtbl->Release(wc->lpDD);
+        wc->lpDD = NULL;
+    }
+    // Clean up the screen on exit
+    RedrawWindow( NULL, NULL, NULL, RDW_INVALIDATE | RDW_ERASE |
+        RDW_ALLCHILDREN );
+
+}
+#endif
+
+void WMesaMove(void)
+{
+    WMesaContext wc = Current;
+    POINT   pt;
+    if (Current != NULL){
+        GetClientRect( wc->hwnd, &(wc->rectSurface) );
+        pt.x = pt.y = 0;
+        ClientToScreen( wc->hwnd, &pt );
+        OffsetRect(&(wc->rectSurface), pt.x, pt.y);
+    }
+}
+
+
+
+/*
+* Like PACK_8A8B8G8R() but don't use alpha.  This is usually an acceptable
+* shortcut.
+*/
+#define PACK_8B8G8R( R, G, B )   ( ((B) << 16) | ((G) << 8) | (R) )
+
+
+/**********************************************************************/
+/***                   Triangle rendering                            ***/
+/**********************************************************************/
+
+/*
+ * XImage, smooth, depth-buffered, PF_8A8B8G8R triangle.
+ */
+static void smooth_8A8B8G8R_z_triangle( GLcontext *ctx,
+                                       GLuint v0, GLuint v1, GLuint v2,
+                                       GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define INTERP_Z 1
+#define INTERP_RGB 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
+#define PIXEL_TYPE GLuint
+    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define INNER_LOOP( LEFT, RIGHT, Y )                    \
+    {                                   \
+    GLint i, len = RIGHT-LEFT;                      \
+    for (i=0;i<len;i++) {                       \
+    GLdepth z = FixedToDepth(ffz);                  \
+    if (z < zRow[i]) {                      \
+    pRow[i] = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg),    \
+    FixedToInt(ffb) );          \
+    zRow[i] = z;                            \
+    }                                   \
+    ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;         \
+    ffz += fdzdx;                           \
+    }                                   \
+    }
+
+#ifdef __MINGW32__
+       #include "tritemp.h"
+#else
+
+       #ifdef WIN32
+               #include "..\tritemp.h"
+       #else
+               #include "tritemp.h"
+       #endif
+#endif
+}
+
+
+/*
+* XImage, smooth, depth-buffered, PF_8R8G8B triangle.
+*/
+static void smooth_8R8G8B_z_triangle( GLcontext *ctx,
+                                     GLuint v0, GLuint v1, GLuint v2,
+                                     GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define INTERP_Z 1
+#define INTERP_RGB 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
+#define PIXEL_TYPE GLuint
+    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define INNER_LOOP( LEFT, RIGHT, Y )                    \
+    {                                   \
+    GLint i, len = RIGHT-LEFT;                      \
+    for (i=0;i<len;i++) {                       \
+    GLdepth z = FixedToDepth(ffz);                  \
+    if (z < zRow[i]) {                      \
+    pRow[i] = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg),    \
+    FixedToInt(ffb) );          \
+    zRow[i] = z;                            \
+    }                                   \
+    ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;         \
+    ffz += fdzdx;                           \
+    }                                   \
+    }
+#ifdef __MINGW32__
+       #include "tritemp.h"
+#else
+
+       #ifdef WIN32
+               #include "..\tritemp.h"
+       #else
+               #include "tritemp.h"
+       #endif
+#endif
+}
+
+
+
+/*
+* XImage, smooth, depth-buffered, PF_5R6G5B triangle.
+*/
+static void smooth_5R6G5B_z_triangle( GLcontext *ctx,
+                                     GLuint v0, GLuint v1, GLuint v2,
+                                     GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define INTERP_Z 1
+#define INTERP_RGB 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
+#define PIXEL_TYPE GLushort
+    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define INNER_LOOP( LEFT, RIGHT, Y )                    \
+    {                                   \
+    GLint i, len = RIGHT-LEFT;                      \
+    for (i=0;i<len;i++) {                       \
+    GLdepth z = FixedToDepth(ffz);                  \
+    if (z < zRow[i]) {                      \
+    pRow[i] = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg),    \
+    FixedToInt(ffb) );          \
+    zRow[i] = z;                            \
+    }                                   \
+    ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;         \
+    ffz += fdzdx;                           \
+    }                                   \
+    }
+#ifdef __MINGW32__
+       #include "tritemp.h"
+#else
+
+       #ifdef WIN32
+               #include "..\tritemp.h"
+       #else
+               #include "tritemp.h"
+       #endif
+#endif
+}
+
+/*
+* XImage, flat, depth-buffered, PF_8A8B8G8R triangle.
+*/
+static void flat_8A8B8G8R_z_triangle( GLcontext *ctx, GLuint v0,
+                                     GLuint v1, GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define INTERP_Z 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
+#define PIXEL_TYPE GLuint
+    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define SETUP_CODE                  \
+    unsigned long p = PACK_8B8G8R( VB->ColorPtr->data[pv][0],    \
+    VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
+#define INNER_LOOP( LEFT, RIGHT, Y )                    \
+    {                                   \
+    GLint i, len = RIGHT-LEFT;                      \
+    for (i=0;i<len;i++) {                       \
+    GLdepth z = FixedToDepth(ffz);                  \
+    if (z < zRow[i]) {                      \
+    pRow[i] = p;                            \
+    zRow[i] = z;                            \
+    }                                   \
+    ffz += fdzdx;                           \
+    }                                   \
+    }
+#ifdef __MINGW32__
+       #include "tritemp.h"
+#else
+
+       #ifdef WIN32
+               #include "..\tritemp.h"
+       #else
+               #include "tritemp.h"
+       #endif
+#endif
+}
+
+
+/*
+* XImage, flat, depth-buffered, PF_8R8G8B triangle.
+*/
+static void flat_8R8G8B_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                                   GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define INTERP_Z 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
+#define PIXEL_TYPE GLuint
+    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define SETUP_CODE                  \
+    unsigned long p = PACK_8R8G8B( VB->ColorPtr->data[pv][0],    \
+    VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
+#define INNER_LOOP( LEFT, RIGHT, Y )            \
+    {                           \
+    GLint i, len = RIGHT-LEFT;              \
+    for (i=0;i<len;i++) {               \
+    GLdepth z = FixedToDepth(ffz);          \
+    if (z < zRow[i]) {              \
+    pRow[i] = p;                    \
+    zRow[i] = z;                    \
+    }                           \
+    ffz += fdzdx;                   \
+    }                           \
+    }
+#ifdef __MINGW32__
+       #include "tritemp.h"
+#else
+
+       #ifdef WIN32
+               #include "..\tritemp.h"
+       #else
+               #include "tritemp.h"
+       #endif
+#endif
+}
+
+
+/*
+* XImage, flat, depth-buffered, PF_5R6G5B triangle.
+*/
+static void flat_5R6G5B_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                                   GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define INTERP_Z 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
+#define PIXEL_TYPE GLushort
+    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define SETUP_CODE                  \
+    unsigned long p = PACK_5R6G5B( VB->ColorPtr->data[pv][0],    \
+    VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
+#define INNER_LOOP( LEFT, RIGHT, Y )            \
+    {                           \
+    GLint i, len = RIGHT-LEFT;              \
+    for (i=0;i<len;i++) {               \
+    GLdepth z = FixedToDepth(ffz);          \
+    if (z < zRow[i]) {              \
+    pRow[i] = p;                    \
+    zRow[i] = z;                    \
+    }                           \
+    ffz += fdzdx;                   \
+    }                           \
+    }
+#ifdef __MINGW32__
+       #include "tritemp.h"
+#else
+
+       #ifdef WIN32
+               #include "..\tritemp.h"
+       #else
+               #include "tritemp.h"
+       #endif
+#endif
+}
+
+
+/*
+* XImage, smooth, NON-depth-buffered, PF_8A8B8G8R triangle.
+*/
+static void smooth_8A8B8G8R_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                                     GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define INTERP_RGB 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
+#define PIXEL_TYPE GLuint
+    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define INNER_LOOP( LEFT, RIGHT, Y )                    \
+    {                                   \
+    GLint xx;                               \
+    PIXEL_TYPE *pixel = pRow;                       \
+    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {               \
+    *pixel = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg),     \
+                FixedToInt(ffb) );          \
+                ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;         \
+    }                                   \
+    }
+#ifdef __MINGW32__
+       #include "tritemp.h"
+#else
+
+       #ifdef WIN32
+               #include "..\tritemp.h"
+       #else
+               #include "tritemp.h"
+       #endif
+#endif
+}
+
+
+/*
+* XImage, smooth, NON-depth-buffered, PF_8R8G8B triangle.
+*/
+static void smooth_8R8G8B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                                   GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define INTERP_RGB 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
+#define PIXEL_TYPE GLuint
+    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define INNER_LOOP( LEFT, RIGHT, Y )                    \
+    {                                   \
+    GLint xx;                               \
+    PIXEL_TYPE *pixel = pRow;                       \
+    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {               \
+    *pixel = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg),     \
+                FixedToInt(ffb) );          \
+                ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;         \
+    }                                   \
+    }
+#ifdef __MINGW32__
+       #include "tritemp.h"
+#else
+
+       #ifdef WIN32
+               #include "..\tritemp.h"
+       #else
+               #include "tritemp.h"
+       #endif
+#endif
+}
+
+
+/*
+* XImage, smooth, NON-depth-buffered, PF_5R6G5B triangle.
+*/
+static void smooth_5R6G5B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                                   GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define INTERP_RGB 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
+#define PIXEL_TYPE GLushort
+    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define INNER_LOOP( LEFT, RIGHT, Y )                    \
+    {                                   \
+    GLint xx;                               \
+    PIXEL_TYPE *pixel = pRow;                       \
+    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {               \
+    *pixel = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg),     \
+                FixedToInt(ffb) );          \
+                ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;         \
+    }                                   \
+    }
+#ifdef __MINGW32__
+       #include "tritemp.h"
+#else
+
+       #ifdef WIN32
+               #include "..\tritemp.h"
+       #else
+               #include "tritemp.h"
+       #endif
+#endif
+}
+
+
+
+/*
+* XImage, flat, NON-depth-buffered, PF_8A8B8G8R triangle.
+*/
+static void flat_8A8B8G8R_triangle( GLcontext *ctx, GLuint v0,
+                                   GLuint v1, GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
+#define PIXEL_TYPE GLuint
+    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define SETUP_CODE                  \
+    unsigned long p = PACK_8B8G8R( VB->ColorPtr->data[pv][0],    \
+    VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
+#define INNER_LOOP( LEFT, RIGHT, Y )            \
+    {                           \
+    GLint xx;                       \
+    PIXEL_TYPE *pixel = pRow;               \
+    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {       \
+    *pixel = p;                 \
+    }                           \
+    }
+
+#ifdef __MINGW32__
+       #include "tritemp.h"
+#else
+
+       #ifdef WIN32
+               #include "..\tritemp.h"
+       #else
+               #include "tritemp.h"
+       #endif
+#endif
+}
+
+
+/*
+* XImage, flat, NON-depth-buffered, PF_8R8G8B triangle.
+*/
+static void flat_8R8G8B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                                 GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
+#define PIXEL_TYPE GLuint
+    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define SETUP_CODE                  \
+    unsigned long p = PACK_8R8G8B( VB->ColorPtr->data[pv][0],    \
+    VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
+#define INNER_LOOP( LEFT, RIGHT, Y )            \
+    {                           \
+    GLint xx;                       \
+    PIXEL_TYPE *pixel = pRow;               \
+    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {       \
+    *pixel = p;                 \
+    }                           \
+    }
+#ifdef __MINGW32__
+       #include "tritemp.h"
+#else
+
+       #ifdef WIN32
+               #include "..\tritemp.h"
+       #else
+               #include "tritemp.h"
+       #endif
+#endif
+}
+
+
+/*
+* XImage, flat, NON-depth-buffered, PF_5R6G5B triangle.
+*/
+static void flat_5R6G5B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                                 GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
+#define PIXEL_TYPE GLushort
+    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define SETUP_CODE                  \
+    unsigned long p = PACK_5R6G5B( VB->ColorPtr->data[pv][0],    \
+    VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] );
+#define INNER_LOOP( LEFT, RIGHT, Y )            \
+    {                           \
+    GLint xx;                       \
+    PIXEL_TYPE *pixel = pRow;               \
+    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {       \
+    *pixel = p;                 \
+    }                           \
+    }
+#ifdef __MINGW32__
+       #include "tritemp.h"
+#else
+
+       #ifdef WIN32
+               #include "..\tritemp.h"
+       #else
+               #include "tritemp.h"
+       #endif
+#endif
+}
+
+
+/*
+* XImage, smooth, depth-buffered, 8-bit PF_LOOKUP triangle.
+*/
+
+static void smooth_ci_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                                 GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define INTERP_Z 1
+#define INTERP_INDEX 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
+#define PIXEL_TYPE GLubyte
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define INNER_LOOP( LEFT, RIGHT, Y )                                \
+    {                                                                   \
+    GLint i, len = RIGHT-LEFT;                                      \
+    for (i=0;i<len;i++) {                                           \
+    GLdepth z = FixedToDepth(ffz);                              \
+    if (z < zRow[i]) {                                          \
+    pRow[i] = FixedToInt(ffi);                                  \
+    zRow[i] = z;                                                \
+    }                                                               \
+    ffi += fdidx;                                                   \
+    ffz += fdzdx;                                                   \
+    }                                                               \
+    }
+#ifdef __MINGW32__
+       #include "tritemp.h"
+#else
+
+       #ifdef WIN32
+               #include "..\tritemp.h"
+       #else
+               #include "tritemp.h"
+       #endif
+#endif
+}
+
+
+/*
+* XImage, flat, depth-buffered, 8-bit PF_LOOKUP triangle.
+*/
+
+static void flat_ci_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                               GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define INTERP_Z 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
+#define PIXEL_TYPE GLubyte
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define SETUP_CODE                     \
+   GLuint index = VB->IndexPtr->data[pv];      \
+   (*ctx->Driver.Index)( ctx, index );
+#define INNER_LOOP( LEFT, RIGHT, Y )   \
+   {                                   \
+      GLint i, len = RIGHT-LEFT;       \
+      for (i=0;i<len;i++) {            \
+         GLdepth z = FixedToDepth(ffz);        \
+         if (z < zRow[i]) {            \
+            pRow[i] = index;           \
+            zRow[i] = z;               \
+         }                             \
+         ffz += fdzdx;                 \
+      }                                        \
+   }
+#ifdef __MINGW32__
+       #include "tritemp.h"
+#else
+
+       #ifdef WIN32
+               #include "..\tritemp.h"
+       #else
+               #include "tritemp.h"
+       #endif
+#endif
+}
+
+
+
+/*
+* XImage, smooth, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
+*/
+
+static void smooth_ci_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                               GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define INTERP_Z 1
+#define INTERP_INDEX 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
+#define PIXEL_TYPE GLubyte
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define INNER_LOOP( LEFT, RIGHT, Y )                    \
+    {                                   \
+    GLint xx;                               \
+    PIXEL_TYPE *pixel = pRow;                       \
+    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {               \
+    *pixel = FixedToInt(ffi);           \
+    ffi += fdidx;           \
+    }                                   \
+    }
+#ifdef __MINGW32__
+       #include "tritemp.h"
+#else
+
+       #ifdef WIN32
+               #include "..\tritemp.h"
+       #else
+               #include "tritemp.h"
+       #endif
+#endif
+}
+
+
+/*
+* XImage, flat, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
+*/
+static void flat_ci_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                             GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define INTERP_Z 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
+#define PIXEL_TYPE GLubyte
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define SETUP_CODE                     \
+   GLuint index = VB->IndexPtr->data[pv];      \
+   (*ctx->Driver.Index)( ctx, index );
+#define INNER_LOOP( LEFT, RIGHT, Y )           \
+   {                                           \
+      GLint xx;                                        \
+      PIXEL_TYPE *pixel = pRow;                        \
+      for (xx=LEFT;xx<RIGHT;xx++,pixel++) {    \
+         *pixel = index;                       \
+      }                                                \
+   }
+#ifdef __MINGW32__
+       #include "tritemp.h"
+#else
+
+       #ifdef WIN32
+               #include "..\tritemp.h"
+       #else
+               #include "tritemp.h"
+       #endif
+#endif
+}
+
+/*
+* XImage, smooth, depth-buffered, 8-bit, PF_DITHER8 triangle.
+*/
+static void smooth_DITHER8_z_triangle( GLcontext *ctx,
+                                      GLuint v0, GLuint v1, GLuint v2,
+                                      GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+    DITHER_RGB_TO_8BIT_SETUP
+#define INTERP_Z 1
+#define INTERP_RGB 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
+#define PIXEL_TYPE GLubyte
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define INNER_LOOP( LEFT, RIGHT, Y )                                    \
+    {                                                                       \
+    GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT;                 \
+    for (i=0;i<len;i++,xx++) {                                          \
+    GLdepth z = FixedToDepth(ffz);                                  \
+    if (z < zRow[i]) {                                              \
+    DITHER_RGB_TO_8BIT( FixedToInt(ffr), FixedToInt(ffg),           \
+    FixedToInt(ffb), xx, yy);               \
+    pRow[i] = pixelDithered;                                        \
+    zRow[i] = z;                                                    \
+    }                                                                   \
+    ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;                     \
+    ffz += fdzdx;                                                       \
+    }                                                                   \
+    }
+#ifdef __MINGW32__
+       #include "tritemp.h"
+#else
+
+       #ifdef WIN32
+               #include "..\tritemp.h"
+       #else
+               #include "tritemp.h"
+       #endif
+#endif
+}
+
+/*
+* XImage, flat, depth-buffered, 8-bit PF_DITHER triangle.
+*/
+static void flat_DITHER8_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                                    GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+    DITHER_RGB_TO_8BIT_SETUP
+#define INTERP_Z 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
+#define PIXEL_TYPE GLubyte
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+
+#define INNER_LOOP( LEFT, RIGHT, Y )                                    \
+    {                                                                       \
+    GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT;                 \
+    for (i=0;i<len;i++,xx++) {                                          \
+    GLdepth z = FixedToDepth(ffz);                                  \
+    if (z < zRow[i]) {                                              \
+    DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0],                           \
+             VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy);               \
+             pRow[i] = pixelDithered;                                       \
+             zRow[i] = z;                                                   \
+    }                                                                   \
+    ffz += fdzdx;                                                       \
+    }                                                                   \
+    }
+#ifdef __MINGW32__
+       #include "tritemp.h"
+#else
+
+       #ifdef WIN32
+               #include "..\tritemp.h"
+       #else
+               #include "tritemp.h"
+       #endif
+#endif
+}
+
+/*
+* XImage, smooth, NON-depth-buffered, 8-bit PF_DITHER triangle.
+*/
+static void smooth_DITHER8_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                                    GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+    DITHER_RGB_TO_8BIT_SETUP
+#define INTERP_RGB 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
+#define PIXEL_TYPE GLubyte
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define INNER_LOOP( LEFT, RIGHT, Y )                                    \
+    {                                                                       \
+    GLint xx, yy = FLIP(Y);                                             \
+    PIXEL_TYPE *pixel = pRow;                                           \
+    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {                               \
+    DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0],   VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy);\
+    *pixel = pixelDithered;                                         \
+    ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;                     \
+    }                                                                   \
+    }
+#ifdef __MINGW32__
+       #include "tritemp.h"
+#else
+
+       #ifdef WIN32
+               #include "..\tritemp.h"
+       #else
+               #include "tritemp.h"
+       #endif
+#endif
+}
+
+/*
+* XImage, flat, NON-depth-buffered, 8-bit PF_DITHER triangle.
+*/
+
+static void flat_DITHER8_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                                  GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+    DITHER_RGB_TO_8BIT_SETUP
+#define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
+#define PIXEL_TYPE GLubyte
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+
+#define INNER_LOOP( LEFT, RIGHT, Y )                                    \
+    {                                                                       \
+    GLint xx, yy = FLIP(Y);                                             \
+    PIXEL_TYPE *pixel = pRow;                                           \
+    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {                               \
+    DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0],                               \
+             VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy);               \
+             *pixel = pixelDithered;                                            \
+    }                                                                   \
+    }
+#ifdef __MINGW32__
+       #include "tritemp.h"
+#else
+
+       #ifdef WIN32
+               #include "..\tritemp.h"
+       #else
+               #include "tritemp.h"
+       #endif
+#endif
+}
+
+
+
+
+static triangle_func choose_triangle_function( GLcontext *ctx )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+    int depth = wmesa->cColorBits;
+
+    if (ctx->Polygon.SmoothFlag)     return NULL;
+    if (ctx->Texture.Enabled)        return NULL;
+    if (!wmesa->db_flag) return NULL;
+    /*if (wmesa->xm_buffer->buffer==XIMAGE)*/ {
+    if (   ctx->Light.ShadeModel==GL_SMOOTH
+        && ctx->RasterMask==DEPTH_BIT
+        && ctx->Depth.Func==GL_LESS
+        && ctx->Depth.Mask==GL_TRUE
+        && ctx->Polygon.StippleFlag==GL_FALSE) {
+        switch (wmesa->pixelformat) {
+        case PF_8A8B8G8R:
+            return smooth_8A8B8G8R_z_triangle;
+        case PF_8R8G8B:
+            return smooth_8R8G8B_z_triangle;
+        case PF_5R6G5B:
+            return smooth_5R6G5B_z_triangle;
+        case PF_DITHER8:
+            return  smooth_DITHER8_z_triangle;
+        case PF_INDEX8:
+            return smooth_ci_z_triangle;
+        default:
+            return NULL;
+        }
+    }
+    if (   ctx->Light.ShadeModel==GL_FLAT
+        && ctx->RasterMask==DEPTH_BIT
+        && ctx->Depth.Func==GL_LESS
+        && ctx->Depth.Mask==GL_TRUE
+        && ctx->Polygon.StippleFlag==GL_FALSE) {
+        switch (wmesa->pixelformat) {
+        case PF_8A8B8G8R:
+            return flat_8A8B8G8R_z_triangle;
+        case PF_8R8G8B:
+            return flat_8R8G8B_z_triangle;
+        case PF_5R6G5B:
+            return flat_5R6G5B_z_triangle;
+        case PF_DITHER8:
+            return flat_DITHER8_z_triangle;
+        case PF_INDEX8:
+            return flat_ci_z_triangle;
+        default:
+            return NULL;
+        }
+    }
+    if (   ctx->RasterMask==0   /* no depth test */
+        && ctx->Light.ShadeModel==GL_SMOOTH
+        && ctx->Polygon.StippleFlag==GL_FALSE) {
+        switch (wmesa->pixelformat) {
+        case PF_8A8B8G8R:
+            return smooth_8A8B8G8R_triangle;
+        case PF_8R8G8B:
+            return smooth_8R8G8B_triangle;
+        case PF_5R6G5B:
+            return smooth_5R6G5B_triangle;
+        case PF_DITHER8:
+            return smooth_DITHER8_triangle;
+        case PF_INDEX8:
+            return smooth_ci_triangle;
+        default:
+            return NULL;
+        }
+    }
+
+    if (   ctx->RasterMask==0   /* no depth test */
+        && ctx->Light.ShadeModel==GL_FLAT
+        && ctx->Polygon.StippleFlag==GL_FALSE) {
+        switch (wmesa->pixelformat) {
+        case PF_8A8B8G8R:
+            return flat_8A8B8G8R_triangle;
+        case PF_8R8G8B:
+            return flat_8R8G8B_triangle;
+        case PF_5R6G5B:
+            return flat_5R6G5B_triangle;
+        case PF_DITHER8:
+            return flat_DITHER8_triangle;
+        case PF_INDEX8:
+            return flat_ci_triangle;
+        default:
+            return NULL;
+        }
+    }
+
+    return NULL;
+    }
+}
+
+/*
+* Define a new viewport and reallocate auxillary buffers if the size of
+* the window (color buffer) has changed.
+*/
+void WMesaViewport( GLcontext *ctx,
+                   GLint x, GLint y, GLsizei width, GLsizei height )
+{
+    /* Save viewport */
+    ctx->Viewport.X = x;
+    ctx->Viewport.Width = width;
+    ctx->Viewport.Y = y;
+    ctx->Viewport.Height = height;
+
+    /* compute scale and bias values */
+/* Pre-Keith 3.1 changes
+    ctx->Viewport.Map.m[Sx] = (GLfloat) width / 2.0F;
+    ctx->Viewport.Map.m[Tx] = ctx->Viewport.Sx + x;
+    ctx->Viewport.Map.m[Sy] = (GLfloat) height / 2.0F;
+    ctx->Viewport.Map.m[Ty] = ctx->Viewport.Sy + y;
+*/
+       ctx->Viewport.WindowMap.m[MAT_SX] = (GLfloat) width / 2.0F;
+       ctx->Viewport.WindowMap.m[MAT_TX] = ctx->Viewport.WindowMap.m[MAT_SX] + x;
+       ctx->Viewport.WindowMap.m[MAT_SY] = (GLfloat) height / 2.0F;
+       ctx->Viewport.WindowMap.m[MAT_TY] = ctx->Viewport.WindowMap.m[MAT_SY] + y;
+}
diff --git a/src/mesa/drivers/windows/wmesaBackup.c b/src/mesa/drivers/windows/wmesaBackup.c
new file mode 100644 (file)
index 0000000..57269fb
--- /dev/null
@@ -0,0 +1,2879 @@
+/* $Id: wmesaBackup.c,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
+
+/*
+*   File name   :   wmesa.c
+*  Version      :   2.3
+*
+*  Display driver for Mesa 2.3  under
+*   Windows95 and WindowsNT
+*
+*   Copyright (C) 1996-  Li Wei
+*  Address      :       Institute of Artificial Intelligence
+*               :           & Robotics
+*               :       Xi'an Jiaotong University
+*  Email        :       liwei@aiar.xjtu.edu.cn
+*  Web page :       http://sun.aiar.xjtu.edu.cn
+*
+*  This file and its associations are partially borrowed from the
+*  Windows NT driver for Mesa 1.8 , written by Mark Leaming
+*  (mark@rsinc.com).
+*/
+
+
+/*
+ * $Log: wmesaBackup.c,v $
+ * Revision 1.1  1999/08/19 00:55:42  jtg
+ * Initial revision
+ *
+ * Revision 1.1  1999/01/03 03:08:57  brianp
+ * Initial revision
+ *
+ * Revision 3.1  1998/06/11 01:42:08  brianp
+ * updated for Mesa 3.0 device driver interface (but not tested)
+ *
+ * Revision 3.0  1998/06/11 01:18:25  brianp
+ * initial revision
+ *
+ */
+
+
+#define WMESA_STEREO_C
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <GL/wmesa.h>
+#include "mesa_extend.h"
+#include "colors.h"
+#include "macros.h"
+#include "context.h"
+#include "dd.h"
+#include "xform.h"
+#include "vb.h"
+#include "matrix.h"
+#include "depth.h"
+#include "wmesadef.h"
+
+#pragma warning ( disable : 4133 4761 )
+
+#ifdef PROFILE
+//  #include "profile.h"
+#endif
+
+#ifdef DITHER
+#include <wing.h>
+#endif
+
+#ifdef __CYGWIN32__
+#include "macros.h"
+#include <string.h>
+#define CopyMemory memcpy
+#endif
+
+#if !defined(NO_STEREO)
+
+#include "gl\glu.h"
+#include "stereo.h"
+
+#endif
+#if !defined(NO_PARALLEL)
+//  #include "parallel.h"
+#endif
+
+struct DISPLAY_OPTIONS displayOptions;
+
+GLenum stereoCompile = GL_FALSE ;
+GLenum stereoShowing  = GL_FALSE ;
+GLenum stereoBuffer = GL_FALSE;
+#if !defined(NO_STEREO)
+GLint displayList = MAXIMUM_DISPLAY_LIST ;
+#endif
+GLint stereo_flag = 0 ;
+
+/* end of added code*/
+
+static PWMC Current = NULL;
+WMesaContext WC = NULL;
+
+#ifdef NDEBUG
+#define assert(ignore)  ((void) 0)
+#else
+void Mesa_Assert(void *Cond,void *File,unsigned Line)
+{
+    char Msg[512];
+    sprintf(Msg,"%s %s %d",Cond,File,Line);
+    MessageBox(NULL,Msg,"Assertion failed.",MB_OK);
+    exit(1);
+}
+#define assert(e)   if (!e) Mesa_Assert(#e,__FILE__,__LINE__);
+#endif
+
+//#define DD_GETDC (Current->hDC )
+#define DD_GETDC ((Current->db_flag) ? Current->dib.hDC : Current->hDC )
+//#define DD_GETDC ((Current->db_flag) ? Current->hDCPrimary : Current->hDCBack )
+#define DD_RELEASEDC
+
+//#define BEGINGDICALL  if(Current->rgb_flag)wmFlushBits(Current);
+#define BEGINGDICALL
+//#define ENDGDICALL        if(Current->rgb_flag)wmGetBits(Current);
+#define ENDGDICALL
+
+//#define FLIP(Y)  (Current->dither_flag? Y : Current->height-(Y)-1)
+//#define FLIP(Y)  (Current->height-(Y)-1)
+//#define FLIP(Y) Y
+#define FLIP(Y)  (Current->db_flag? Y: Current->height-(Y)-1)
+#define STARTPROFILE
+#define ENDPROFILE(PARA)
+
+#define DITHER_RGB_TO_8BIT_SETUP            \
+GLubyte pixelDithered;
+
+#define DITHER_RGB_TO_8BIT(red, green, blue, pixel, scanline)               \
+{                                                                           \
+    char unsigned redtemp, greentemp, bluetemp, paletteindex;               \
+    redtemp = aDividedBy51[red]                                             \
+    + (aModulo51[red] > aHalftone8x8[(pixel%8)*8                        \
+    + scanline%8]);                                                 \
+    greentemp = aDividedBy51[(char unsigned)green]                          \
+    + (aModulo51[green] > aHalftone8x8[                             \
+    (pixel%8)*8 + scanline%8]);                                     \
+    bluetemp = aDividedBy51[(char unsigned)blue]                            \
+    + (aModulo51[blue] > aHalftone8x8[                              \
+    (pixel%8)*8 +scanline%8]);                                      \
+    paletteindex = redtemp + aTimes6[greentemp] + aTimes36[bluetemp];       \
+    pixelDithered = aWinGHalftoneTranslation[paletteindex];                 \
+}
+
+
+#ifdef DDRAW
+static BOOL DDInit( WMesaContext wc, HWND hwnd);
+static void DDFree( WMesaContext wc);
+static HRESULT DDRestoreAll( WMesaContext wc );
+static void DDDeleteOffScreen(WMesaContext wc);
+static BOOL DDCreateOffScreen(WMesaContext wc);
+#endif
+
+static void FlushToFile(PWMC pwc, PSTR  szFile);
+
+BOOL wmCreateBackingStore(PWMC pwc, long lxSize, long lySize);
+BOOL wmDeleteBackingStore(PWMC pwc);
+void wmCreatePalette( PWMC pwdc );
+BOOL wmSetDibColors(PWMC pwc);
+void wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b);
+
+void wmCreateDIBSection(
+                        HDC  hDC,
+                        PWMC pwc,   // handle of device context
+                        CONST BITMAPINFO *pbmi, // address of structure containing bitmap size, format, and color data
+                        UINT iUsage // color data type indicator: RGB values or palette indices
+                        );
+
+
+void WMesaViewport( GLcontext *ctx,
+                    GLint x, GLint y, GLsizei width, GLsizei height );
+
+
+static triangle_func choose_triangle_function( GLcontext *ctx );
+
+
+static void wmSetPixelFormat( PWMC wc, HDC hDC)
+{
+    if(wc->rgb_flag)
+        wc->cColorBits = GetDeviceCaps(hDC, BITSPIXEL);
+    else
+        wc->cColorBits = 8;
+    switch(wc->cColorBits){
+    case 8:
+        if(wc->dither_flag != GL_TRUE)
+            wc->pixelformat = PF_INDEX8;
+        else
+            wc->pixelformat = PF_DITHER8;
+        break;
+    case 16:
+        wc->pixelformat = PF_5R6G5B;
+        break;
+    case 32:
+        wc->pixelformat = PF_8R8G8B;
+        break;
+    default:
+        wc->pixelformat = PF_BADFORMAT;
+    }
+}
+
+//
+// This function sets the color table of a DIB section
+// to match that of the destination DC
+//
+BOOL /*WINAPI*/ wmSetDibColors(PWMC pwc)
+{
+    RGBQUAD         *pColTab, *pRGB;
+    PALETTEENTRY    *pPal, *pPE;
+    int             i, nColors;
+    BOOL            bRet=TRUE;
+    DWORD           dwErr=0;
+
+    /* Build a color table in the DIB that maps to the
+    selected palette in the DC.
+    */
+    nColors = 1 << pwc->cColorBits;
+    pPal = (PALETTEENTRY *)malloc( nColors * sizeof(PALETTEENTRY));
+    memset( pPal, 0, nColors * sizeof(PALETTEENTRY) );
+    GetPaletteEntries( pwc->hGLPalette, 0, nColors, pPal );
+    pColTab = (RGBQUAD *)malloc( nColors * sizeof(RGBQUAD));
+    for (i = 0, pRGB = pColTab, pPE = pPal; i < nColors; i++, pRGB++, pPE++) {
+        pRGB->rgbRed = pPE->peRed;
+        pRGB->rgbGreen = pPE->peGreen;
+        pRGB->rgbBlue = pPE->peBlue;
+    }
+    if(pwc->db_flag)
+        bRet = SetDIBColorTable(pwc->dib.hDC, 0, nColors, pColTab );
+
+    if(!bRet)
+        dwErr = GetLastError();
+
+    free( pColTab );
+    free( pPal );
+
+    return(bRet);
+}
+
+
+//
+// Free up the dib section that was created
+//
+BOOL wmDeleteBackingStore(PWMC pwc)
+{
+    SelectObject(pwc->dib.hDC, pwc->hOldBitmap);
+    DeleteDC(pwc->dib.hDC);
+    DeleteObject(pwc->hbmDIB);
+    UnmapViewOfFile(pwc->dib.base);
+    CloseHandle(pwc->dib.hFileMap);
+    return TRUE;
+}
+
+
+//
+// This function creates the DIB section that is used for combined
+// GL and GDI calls
+//
+BOOL /*WINAPI*/ wmCreateBackingStore(PWMC pwc, long lxSize, long lySize)
+{
+    HDC hdc = pwc->hDC;
+    LPBITMAPINFO pbmi = &(pwc->bmi);
+    int     iUsage;
+
+    pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+    pbmi->bmiHeader.biWidth = lxSize;
+    pbmi->bmiHeader.biHeight= -lySize;
+    pbmi->bmiHeader.biPlanes = 1;
+    if(pwc->rgb_flag)
+        pbmi->bmiHeader.biBitCount = GetDeviceCaps(pwc->hDC, BITSPIXEL);
+    else
+        pbmi->bmiHeader.biBitCount = 8;
+    pbmi->bmiHeader.biCompression = BI_RGB;
+    pbmi->bmiHeader.biSizeImage = 0;
+    pbmi->bmiHeader.biXPelsPerMeter = 0;
+    pbmi->bmiHeader.biYPelsPerMeter = 0;
+    pbmi->bmiHeader.biClrUsed = 0;
+    pbmi->bmiHeader.biClrImportant = 0;
+
+    iUsage = (pbmi->bmiHeader.biBitCount <= 8) ? DIB_PAL_COLORS : DIB_RGB_COLORS;
+
+    pwc->cColorBits = pbmi->bmiHeader.biBitCount;
+    pwc->ScanWidth = pwc->pitch = lxSize;
+
+    wmCreateDIBSection(hdc, pwc, pbmi, iUsage);
+
+    if ((iUsage == DIB_PAL_COLORS) && !(pwc->hGLPalette)) {
+        wmCreatePalette( pwc );
+        wmSetDibColors( pwc );
+    }
+    wmSetPixelFormat(pwc, pwc->hDC);
+    return(TRUE);
+
+}
+
+
+//
+// This function copies one scan line in a DIB section to another
+//
+BOOL GLWINAPI wmSetDIBits(PWMC pwc, UINT uiScanWidth, UINT uiNumScans, UINT nBypp, UINT uiNewWidth, LPBYTE pBits)
+{
+    UINT uiScans = 0;
+    LPBYTE  pDest = pwc->pbPixels;
+    DWORD   dwNextScan = uiScanWidth;
+    DWORD   dwNewScan = uiNewWidth;
+    DWORD   dwScanWidth = (uiScanWidth * nBypp);
+
+    //
+    // We need to round up to the nearest DWORD
+    // and multiply by the number of bytes per
+    // pixel
+    //
+    dwNextScan = (((dwNextScan * nBypp)+ 3) & ~3);
+    dwNewScan = (((dwNewScan * nBypp)+ 3) & ~3);
+
+    for(uiScans = 0; uiScans < uiNumScans; uiScans++){
+        CopyMemory(pDest, pBits, dwScanWidth);
+        pBits += dwNextScan;
+        pDest += dwNewScan;
+    }
+
+    return(TRUE);
+
+}
+
+
+BOOL wmFlush(PWMC pwc);
+
+/*
+* Useful macros:
+Modified from file osmesa.c
+*/
+
+
+#define PIXELADDR(X,Y)  ((GLubyte *)Current->pbPixels + (Current->height-Y-1)* Current->ScanWidth + (X)*nBypp)
+#define PIXELADDR1( X, Y )  \
+((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X))
+#define PIXELADDR2( X, Y )  \
+((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*2)
+#define PIXELADDR4( X, Y )  \
+((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*4)
+
+
+BYTE DITHER_RGB_2_8BIT( int r, int g, int b, int x, int y);
+
+/* Finish all pending operations and synchronize. */
+static void finish(GLcontext* ctx)
+{
+    /* No op */
+}
+
+
+//
+// We cache all gl draw routines until a flush is made
+//
+static void flush(GLcontext* ctx)
+{
+    STARTPROFILE
+        if((Current->rgb_flag /*&& !(Current->dib.fFlushed)*/&&!(Current->db_flag))
+            ||(!Current->rgb_flag))
+        {
+            wmFlush(Current);
+        }
+        ENDPROFILE(flush)
+
+}
+
+
+
+/*
+* Set the color index used to clear the color buffer.
+*/
+static void clear_index(GLcontext* ctx, GLuint index)
+{
+    STARTPROFILE
+        Current->clearpixel = index;
+    ENDPROFILE(clear_index)
+}
+
+
+
+/*
+* Set the color used to clear the color buffer.
+*/
+static void clear_color( GLcontext* ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )
+{
+    STARTPROFILE
+        Current->clearpixel=RGB(r, g, b );
+    ENDPROFILE(clear_color)
+}
+
+
+
+/*
+* Clear the specified region of the color buffer using the clear color
+* or index as specified by one of the two functions above.
+*/
+//static void clear(GLcontext* ctx,
+//                  GLboolean all,GLint x, GLint y, GLint width, GLint height )
+// TODO: I modified this function to match the prototype in dd.h. (swansma@geocities.com)
+//       dd.h does not explain what the return type is so I could not set this to the proper
+//       value.
+static GLbitfield clear(GLcontext* ctx, GLbitfield mask,
+                  GLboolean all, GLint x, GLint y, GLint width, GLint height)
+{
+    DWORD   dwColor;
+    WORD    wColor;
+    BYTE    bColor;
+    LPDWORD lpdw = (LPDWORD)Current->pbPixels;
+    LPWORD  lpw = (LPWORD)Current->pbPixels;
+    LPBYTE  lpb = Current->pbPixels;
+    int     lines;
+
+    STARTPROFILE
+
+        if (all){
+            x=y=0;
+            width=Current->width;
+            height=Current->height;
+        }
+        if(Current->db_flag==GL_TRUE){
+            UINT    nBypp = Current->cColorBits / 8;
+            int     i = 0;
+            int     iSize = 0;
+
+            if(nBypp ==1 ){
+                /* Need rectification */
+                iSize = Current->width/4;
+                bColor  = BGR8(GetRValue(Current->clearpixel),
+                    GetGValue(Current->clearpixel),
+                    GetBValue(Current->clearpixel));
+                wColor  = MAKEWORD(bColor,bColor);
+                dwColor = MAKELONG(wColor, wColor);
+            }
+            if(nBypp == 2){
+                iSize = Current->width / 2;
+                wColor = BGR16(GetRValue(Current->clearpixel),
+                    GetGValue(Current->clearpixel),
+                    GetBValue(Current->clearpixel));
+                dwColor = MAKELONG(wColor, wColor);
+            }
+            else if(nBypp == 4){
+                iSize = Current->width;
+                dwColor = BGR32(GetRValue(Current->clearpixel),
+                    GetGValue(Current->clearpixel),
+                    GetBValue(Current->clearpixel));
+            }
+
+            while(i < iSize){
+                *lpdw = dwColor;
+                lpdw++;
+                i++;
+            }
+
+            //
+            // This is the 24bit case
+            //
+            if (nBypp == 3) {
+                iSize = Current->width *3/4;
+                dwColor = BGR24(GetRValue(Current->clearpixel),
+                    GetGValue(Current->clearpixel),
+                    GetBValue(Current->clearpixel));
+                while(i < iSize){
+                    *lpdw = dwColor;
+                    lpb += nBypp;
+                    lpdw = (LPDWORD)lpb;
+                    i++;
+                }
+            }
+
+            i = 0;
+            if (stereo_flag)
+               lines = height /2;
+            else
+               lines = height;
+            do {
+                memcpy(lpb, Current->pbPixels, iSize*4);
+                lpb += Current->ScanWidth;
+                i++;
+            }
+            while (i<lines-1);
+        }
+        else { // For single buffer
+            HDC DC=DD_GETDC;
+            HPEN Pen=CreatePen(PS_SOLID,1,Current->clearpixel);
+            HBRUSH Brush=CreateSolidBrush(Current->clearpixel);
+            HPEN Old_Pen=SelectObject(DC,Pen);
+            HBRUSH Old_Brush=SelectObject(DC,Brush);
+            Rectangle(DC,x,y,x+width,y+height);
+            SelectObject(DC,Old_Pen);
+            SelectObject(DC,Old_Brush);
+            DeleteObject(Pen);
+            DeleteObject(Brush);
+            DD_RELEASEDC;
+        }
+
+
+
+        ENDPROFILE(clear)
+
+               return mask;    // TODO: I doubt this is correct. dd.h doesn't explain what this should
+                               //       be...
+}
+
+
+
+/* Set the current color index. */
+static void set_index(GLcontext* ctx, GLuint index)
+{
+    STARTPROFILE
+        Current->pixel=index;
+    ENDPROFILE(set_index)
+}
+
+
+
+/* Set the current RGBA color. */
+static void set_color( GLcontext* ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )
+{
+    STARTPROFILE
+        Current->pixel = RGB( r, g, b );
+    ENDPROFILE(set_color)
+}
+
+
+
+/* Set the index mode bitplane mask. */
+static GLboolean index_mask(GLcontext* ctx, GLuint mask)
+{
+    /* can't implement */
+    return GL_FALSE;
+}
+
+
+
+/* Set the RGBA drawing mask. */
+static GLboolean color_mask( GLcontext* ctx,
+                            GLboolean rmask, GLboolean gmask,
+                            GLboolean bmask, GLboolean amask)
+{
+    /* can't implement */
+    return GL_FALSE;
+}
+
+
+
+/*
+* Set the pixel logic operation.  Return GL_TRUE if the device driver
+* can perform the operation, otherwise return GL_FALSE.  If GL_FALSE
+* is returned, the logic op will be done in software by Mesa.
+*/
+GLboolean logicop( GLcontext* ctx, GLenum op )
+{
+    /* can't implement */
+    return GL_FALSE;
+}
+
+
+static void dither( GLcontext* ctx, GLboolean enable )
+{
+    if(enable == GL_FALSE){
+        Current->dither_flag = GL_FALSE;
+        if(Current->cColorBits == 8)
+            Current->pixelformat = PF_INDEX8;
+    }
+    else{
+        if (Current->rgb_flag && Current->cColorBits == 8){
+            Current->pixelformat = PF_DITHER8;
+            Current->dither_flag = GL_TRUE;
+        }
+        else
+            Current->dither_flag = GL_FALSE;
+    }
+}
+
+
+
+static GLboolean set_buffer( GLcontext* ctx, GLenum mode )
+{
+   STARTPROFILE
+   /* TODO: this could be better */
+   if (mode==GL_FRONT || mode==GL_BACK) {
+      return GL_TRUE;
+   }
+   else {
+      return GL_FALSE;
+   }
+   ENDPROFILE(set_buffer)
+}
+
+
+
+/* Return characteristics of the output buffer. */
+static void buffer_size( GLcontext* ctx, GLuint *width, GLuint *height )
+{
+   int New_Size;
+   RECT CR;
+
+   STARTPROFILE
+   GetClientRect(Current->Window,&CR);
+
+   *width=CR.right;
+   *height=CR.bottom;
+
+   New_Size=((*width)!=Current->width) || ((*height)!=Current->height);
+
+   if (New_Size){
+      Current->width=*width;
+      Current->height=*height;
+      Current->ScanWidth=Current->width;
+      if ((Current->ScanWidth%sizeof(long))!=0)
+         Current->ScanWidth+=(sizeof(long)-(Current->ScanWidth%sizeof(long)));
+
+      if (Current->db_flag){
+#ifdef DDRAW
+         DDDeleteOffScreen(Current);
+         DDCreateOffScreen(Current);
+#else
+         if (Current->rgb_flag==GL_TRUE && Current->dither_flag!=GL_TRUE){
+            wmDeleteBackingStore(Current);
+            wmCreateBackingStore(Current, Current->width, Current->height);
+         }
+#endif
+      }
+
+      //  Resize OsmesaBuffer if in Parallel mode
+#if !defined(NO_PARALLEL)
+      if(parallelFlag)
+         PRSizeRenderBuffer(Current->width, Current->height,Current->ScanWidth,
+                            Current->rgb_flag == GL_TRUE ? Current->pbPixels: Current->ScreenMem);
+#endif
+   }
+   ENDPROFILE(buffer_size)
+}
+
+
+
+/**********************************************************************/
+/*****           Accelerated point, line, polygon rendering       *****/
+/**********************************************************************/
+
+
+static void fast_rgb_points( GLcontext* ctx, GLuint first, GLuint last )
+{
+    GLuint i;
+    //  HDC DC=DD_GETDC;
+    PWMC    pwc = Current;
+
+    STARTPROFILE
+
+        if (Current->gl_ctx->VB->MonoColor) {
+            /* all drawn with current color */
+            for (i=first;i<=last;i++) {
+                if (!Current->gl_ctx->VB->ClipMask[i]) {
+                    int x, y;
+                    x =       (GLint) Current->gl_ctx->VB->Win[i][0];
+                    y = FLIP( (GLint) Current->gl_ctx->VB->Win[i][1] );
+                    wmSetPixel(pwc, y,x,GetRValue(Current->pixel),
+                        GetGValue(Current->pixel), GetBValue(Current->pixel));
+                }
+            }
+        }
+        else {
+            /* draw points of different colors */
+            for (i=first;i<=last;i++) {
+                if (!Current->gl_ctx->VB->ClipMask[i]) {
+                    int x, y;
+                    unsigned long pixel=RGB(Current->gl_ctx->VB->Color[i][0]*255.0,
+                        Current->gl_ctx->VB->Color[i][1]*255.0,
+                        Current->gl_ctx->VB->Color[i][2]*255.0);
+                    x =       (GLint) Current->gl_ctx->VB->Win[i][0];
+                    y = FLIP( (GLint) Current->gl_ctx->VB->Win[i][1] );
+                    wmSetPixel(pwc, y,x,Current->gl_ctx->VB->Color[i][0]*255.0,
+                        Current->gl_ctx->VB->Color[i][1]*255.0,
+                        Current->gl_ctx->VB->Color[i][2]*255.0);
+                }
+            }
+        }
+        //   DD_RELEASEDC;
+        ENDPROFILE(fast_rgb_points)
+}
+
+
+
+/* Return pointer to accerated points function */
+extern points_func choose_points_function( GLcontext* ctx )
+{
+    STARTPROFILE
+        if (ctx->Point.Size==1.0 && !ctx->Point.SmoothFlag && ctx->RasterMask==0
+            && !ctx->Texture.Enabled  && ctx->Visual->RGBAflag) {
+            ENDPROFILE(choose_points_function)
+                return fast_rgb_points;
+        }
+        else {
+            ENDPROFILE(choose_points_function)
+                return NULL;
+        }
+}
+
+
+
+/* Draw a line using the color specified by Current->gl_ctx->VB->Color[pv] */
+static void fast_flat_rgb_line( GLcontext* ctx, GLuint v0, GLuint v1, GLuint pv )
+{
+    STARTPROFILE
+        int x0, y0, x1, y1;
+    unsigned long pixel;
+    HDC DC=DD_GETDC;
+    HPEN Pen;
+    HPEN Old_Pen;
+
+    if (Current->gl_ctx->VB->MonoColor) {
+        pixel = Current->pixel;  /* use current color */
+    }
+    else {
+        pixel = RGB(Current->gl_ctx->VB->Color[pv][0]*255.0, Current->gl_ctx->VB->Color[pv][1]*255.0, Current->gl_ctx->VB->Color[pv][2]*255.0);
+    }
+
+    x0 =       (int) Current->gl_ctx->VB->Win[v0][0];
+    y0 = FLIP( (int) Current->gl_ctx->VB->Win[v0][1] );
+    x1 =       (int) Current->gl_ctx->VB->Win[v1][0];
+    y1 = FLIP( (int) Current->gl_ctx->VB->Win[v1][1] );
+
+
+    BEGINGDICALL
+
+    Pen=CreatePen(PS_SOLID,1,pixel);
+    Old_Pen=SelectObject(DC,Pen);
+    MoveToEx(DC,x0,y0,NULL);
+    LineTo(DC,x1,y1);
+    SelectObject(DC,Old_Pen);
+    DeleteObject(Pen);
+    DD_RELEASEDC;
+
+    ENDGDICALL
+
+    ENDPROFILE(fast_flat_rgb_line)
+}
+
+
+
+/* Return pointer to accerated line function */
+static line_func choose_line_function( GLcontext* ctx )
+{
+    STARTPROFILE
+    if (ctx->Line.Width==1.0 && !ctx->Line.SmoothFlag && !ctx->Line.StippleFlag
+        && ctx->Light.ShadeModel==GL_FLAT && ctx->RasterMask==0
+        && !ctx->Texture.Enabled && Current->rgb_flag) {
+       ENDPROFILE(choose_line_function)
+       return fast_flat_rgb_line;
+    }
+    else {
+       ENDPROFILE(choose_line_function)
+       return NULL;
+    }
+}
+
+
+/**********************************************************************/
+/*****                 Span-based pixel drawing                   *****/
+/**********************************************************************/
+
+
+/* Write a horizontal span of 32-bit color-index pixels with a boolean mask. */
+static void write_ci32_span( const GLcontext* ctx,
+                             GLuint n, GLint x, GLint y,
+                             const GLuint index[],
+                             const GLubyte mask[] )
+{
+    STARTPROFILE
+    GLuint i;
+    PBYTE Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
+    assert(Current->rgb_flag==GL_FALSE);
+    for (i=0; i<n; i++)
+        if (mask[i])
+            Mem[i]=index[i];
+    ENDPROFILE(write_ci32_span)
+}
+
+
+/* Write a horizontal span of 8-bit color-index pixels with a boolean mask. */
+static void write_ci8_span( const GLcontext* ctx,
+                            GLuint n, GLint x, GLint y,
+                            const GLubyte index[],
+                            const GLubyte mask[] )
+{
+    STARTPROFILE
+    GLuint i;
+    PBYTE Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
+    assert(Current->rgb_flag==GL_FALSE);
+    for (i=0; i<n; i++)
+        if (mask[i])
+            Mem[i]=index[i];
+    ENDPROFILE(write_ci8_span)
+}
+
+
+
+/*
+* Write a horizontal span of pixels with a boolean mask.  The current
+* color index is used for all pixels.
+*/
+static void write_mono_ci_span(const GLcontext* ctx,
+                               GLuint n,GLint x,GLint y,
+                               const GLubyte mask[])
+{
+   STARTPROFILE
+   GLuint i;
+   BYTE *Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
+   assert(Current->rgb_flag==GL_FALSE);
+   for (i=0; i<n; i++)
+      if (mask[i])
+         Mem[i]=Current->pixel;
+   ENDPROFILE(write_mono_ci_span)
+}
+
+/*
+ * To improve the performance of this routine, frob the data into an actual
+ * scanline and call bitblt on the complete scan line instead of SetPixel.
+ */
+
+/* Write a horizontal span of RGBA color pixels with a boolean mask. */
+static void write_rgba_span( const GLcontext* ctx, GLuint n, GLint x, GLint y,
+                             const GLubyte rgba[][4], const GLubyte mask[] )
+{
+    STARTPROFILE
+    PWMC    pwc = Current;
+
+    if (pwc->rgb_flag==GL_TRUE)
+    {
+        GLuint i;
+        HDC DC=DD_GETDC;
+        y=FLIP(y);
+        if (mask) {
+            for (i=0; i<n; i++)
+                if (mask[i])
+                    wmSetPixel(pwc, y, x + i, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
+        }
+        else {
+            for (i=0; i<n; i++)
+                wmSetPixel(pwc, y, x + i, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
+        }
+        DD_RELEASEDC;
+    }
+    else
+    {
+        GLuint i;
+        BYTE *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
+        y = FLIP(y);
+        if (mask) {
+            for (i=0; i<n; i++)
+                if (mask[i])
+                    Mem[i] = GetNearestPaletteIndex(Current->hPal,RGB(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]));
+        }
+        else {
+            for (i=0; i<n; i++)
+                Mem[i] = GetNearestPaletteIndex(Current->hPal,RGB(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]));
+        }
+    }
+    ENDPROFILE(write_rgba_span)
+
+}
+
+/* Write a horizontal span of RGB color pixels with a boolean mask. */
+static void write_rgb_span( const GLcontext* ctx,
+                            GLuint n, GLint x, GLint y,
+                            const GLubyte rgb[][3], const GLubyte mask[] )
+{
+    STARTPROFILE
+    PWMC    pwc = Current;
+
+    if (pwc->rgb_flag==GL_TRUE)
+    {
+        GLuint i;
+        HDC DC=DD_GETDC;
+        y=FLIP(y);
+        if (mask) {
+            for (i=0; i<n; i++)
+                if (mask[i])
+                    wmSetPixel(pwc, y, x + i, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
+        }
+        else {
+            for (i=0; i<n; i++)
+                wmSetPixel(pwc, y, x + i, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] );
+        }
+        DD_RELEASEDC;
+    }
+    else
+    {
+        GLuint i;
+        BYTE *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
+        y = FLIP(y);
+        if (mask) {
+            for (i=0; i<n; i++)
+                if (mask[i])
+                    Mem[i] = GetNearestPaletteIndex(Current->hPal,RGB(rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]));
+        }
+        else {
+            for (i=0; i<n; i++)
+                Mem[i] = GetNearestPaletteIndex(Current->hPal,RGB(rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]));
+        }
+    }
+    ENDPROFILE(write_rgb_span)
+
+}
+
+/*
+* Write a horizontal span of pixels with a boolean mask.  The current color
+* is used for all pixels.
+*/
+static void write_mono_rgba_span( const GLcontext* ctx,
+                                  GLuint n, GLint x, GLint y,
+                                  const GLubyte mask[])
+{
+    STARTPROFILE
+    GLuint i;
+    HDC DC=DD_GETDC;
+    PWMC pwc = Current;
+    assert(Current->rgb_flag==GL_TRUE);
+    y=FLIP(y);
+    if(Current->rgb_flag==GL_TRUE){
+        for (i=0; i<n; i++)
+            if (mask[i])
+                // Trying
+                wmSetPixel(pwc,y,x+i,GetRValue(Current->pixel), GetGValue(Current->pixel), GetBValue(Current->pixel));
+    }
+    else {
+        for (i=0; i<n; i++)
+            if (mask[i])
+                SetPixel(DC, y, x+i, Current->pixel);
+    }
+    DD_RELEASEDC;
+    ENDPROFILE(write_mono_rgba_span)
+}
+
+
+
+/**********************************************************************/
+/*****                   Array-based pixel drawing                *****/
+/**********************************************************************/
+
+
+/* Write an array of 32-bit index pixels with a boolean mask. */
+static void write_ci32_pixels( const GLcontext* ctx,
+                               GLuint n, const GLint x[], const GLint y[],
+                               const GLuint index[], const GLubyte mask[] )
+{
+   STARTPROFILE
+   GLuint i;
+   assert(Current->rgb_flag==GL_FALSE);
+   for (i=0; i<n; i++) {
+      if (mask[i]) {
+         BYTE *Mem=Current->ScreenMem+FLIP(y[i])*Current->ScanWidth+x[i];
+         *Mem = index[i];
+      }
+   }
+   ENDPROFILE(write_ci32_pixels)
+}
+
+
+
+/*
+* Write an array of pixels with a boolean mask.  The current color
+* index is used for all pixels.
+*/
+static void write_mono_ci_pixels( const GLcontext* ctx,
+                                  GLuint n,
+                                  const GLint x[], const GLint y[],
+                                  const GLubyte mask[] )
+{
+   STARTPROFILE
+   GLuint i;
+   assert(Current->rgb_flag==GL_FALSE);
+   for (i=0; i<n; i++) {
+      if (mask[i]) {
+         BYTE *Mem=Current->ScreenMem+FLIP(y[i])*Current->ScanWidth+x[i];
+         *Mem = Current->pixel;
+      }
+   }
+   ENDPROFILE(write_mono_ci_pixels)
+}
+
+
+
+/* Write an array of RGBA pixels with a boolean mask. */
+static void write_rgba_pixels( const GLcontext* ctx,
+                               GLuint n, const GLint x[], const GLint y[],
+                               const GLubyte rgba[][4], const GLubyte mask[] )
+{
+    STARTPROFILE
+        GLuint i;
+    PWMC    pwc = Current;
+    HDC DC=DD_GETDC;
+    assert(Current->rgb_flag==GL_TRUE);
+    for (i=0; i<n; i++)
+       if (mask[i])
+          wmSetPixel(pwc, FLIP(y[i]),x[i],rgba[i][RCOMP],rgba[i][GCOMP],rgba[i][BCOMP]);
+    DD_RELEASEDC;
+    ENDPROFILE(write_rgba_pixels)
+}
+
+
+
+/*
+* Write an array of pixels with a boolean mask.  The current color
+* is used for all pixels.
+*/
+static void write_mono_rgba_pixels( const GLcontext* ctx,
+                                    GLuint n,
+                                    const GLint x[], const GLint y[],
+                                    const GLubyte mask[] )
+{
+    STARTPROFILE
+    GLuint i;
+    PWMC    pwc = Current;
+    HDC DC=DD_GETDC;
+    assert(Current->rgb_flag==GL_TRUE);
+    for (i=0; i<n; i++)
+        if (mask[i])
+            wmSetPixel(pwc, FLIP(y[i]),x[i],GetRValue(Current->pixel),
+                       GetGValue(Current->pixel), GetBValue(Current->pixel));
+    DD_RELEASEDC;
+    ENDPROFILE(write_mono_rgba_pixels)
+}
+
+
+
+/**********************************************************************/
+/*****            Read spans/arrays of pixels                     *****/
+/**********************************************************************/
+
+
+/* Read a horizontal span of color-index pixels. */
+static void read_ci32_span( const GLcontext* ctx, GLuint n, GLint x, GLint y,
+                            GLuint index[])
+{
+   STARTPROFILE
+   GLuint i;
+   BYTE *Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
+   assert(Current->rgb_flag==GL_FALSE);
+   for (i=0; i<n; i++)
+      index[i]=Mem[i];
+   ENDPROFILE(read_ci32_span)
+}
+
+
+
+
+/* Read an array of color index pixels. */
+static void read_ci32_pixels( const GLcontext* ctx,
+                              GLuint n, const GLint x[], const GLint y[],
+                              GLuint indx[], const GLubyte mask[] )
+{
+   STARTPROFILE
+   GLuint i;
+   assert(Current->rgb_flag==GL_FALSE);
+   for (i=0; i<n; i++) {
+      if (mask[i]) {
+         indx[i]=*(Current->ScreenMem+FLIP(y[i])*Current->ScanWidth+x[i]);
+      }
+   }
+   ENDPROFILE(read_ci32_pixels)
+}
+
+
+
+/* Read a horizontal span of color pixels. */
+static void read_rgba_span( const GLcontext* ctx,
+                            GLuint n, GLint x, GLint y,
+                            GLubyte rgba[][4] )
+{
+   STARTPROFILE
+   UINT i;
+   COLORREF Color;
+   HDC DC=DD_GETDC;
+   assert(Current->rgb_flag==GL_TRUE);
+   y=FLIP(y);
+   for (i=0; i<n; i++) {
+      Color=GetPixel(DC,x+i,y);
+      rgba[i][RCOMP] = GetRValue(Color);
+      rgba[i][GCOMP] = GetGValue(Color);
+      rgba[i][BCOMP] = GetBValue(Color);
+      rgba[i][ACOMP] = 255;
+   }
+   DD_RELEASEDC;
+// Brian P. Has mentioned to comment this out.
+//   memset(alpha,0,n*sizeof(GLubyte));
+   ENDPROFILE(read_rgba_span)
+}
+
+
+/* Read an array of color pixels. */
+static void read_rgba_pixels( const GLcontext* ctx,
+                              GLuint n, const GLint x[], const GLint y[],
+                              GLubyte rgba[][4], const GLubyte mask[] )
+{
+   STARTPROFILE
+   GLuint i;
+   COLORREF Color;
+   HDC DC=DD_GETDC;
+   assert(Current->rgb_flag==GL_TRUE);
+   for (i=0; i<n; i++) {
+      if (mask[i]) {
+         Color=GetPixel(DC,x[i],FLIP(y[i]));
+         rgba[i][RCOMP] = GetRValue(Color);
+         rgba[i][GCOMP] = GetGValue(Color);
+         rgba[i][BCOMP] = GetBValue(Color);
+         rgba[i][ACOMP] = 255;
+      }
+   }
+   DD_RELEASEDC;
+// Brian P. has mentioned to comment this out.
+//   memset(alpha,0,n*sizeof(GLint));
+   ENDPROFILE(read_rgba_pixels)
+}
+
+
+
+/**********************************************************************/
+/**********************************************************************/
+
+
+static const char *renderer_string(void)
+{
+   return "Windows";
+}
+
+
+
+void setup_DD_pointers( GLcontext* ctx )
+{
+    ctx->Driver.RendererString = renderer_string;
+    ctx->Driver.UpdateState = setup_DD_pointers;
+    ctx->Driver.GetBufferSize = buffer_size;
+    ctx->Driver.Finish = finish;
+    ctx->Driver.Flush = flush;
+
+    ctx->Driver.ClearIndex = clear_index;
+    ctx->Driver.ClearColor = clear_color;
+    ctx->Driver.Clear = clear;
+
+    ctx->Driver.Index = set_index;
+    ctx->Driver.Color = set_color;
+    ctx->Driver.IndexMask = index_mask;
+    ctx->Driver.ColorMask = color_mask;
+
+    ctx->Driver.LogicOp = logicop;
+    ctx->Driver.Dither = dither;
+
+    ctx->Driver.SetBuffer = set_buffer;
+    ctx->Driver.GetBufferSize = buffer_size;
+
+    ctx->Driver.PointsFunc = choose_points_function(ctx);
+    ctx->Driver.LineFunc = choose_line_function(ctx);
+    ctx->Driver.TriangleFunc = choose_triangle_function( ctx );
+
+    /* Pixel/span writing functions: */
+       ctx->Driver.WriteRGBASpan        = write_rgba_span;
+    ctx->Driver.WriteRGBSpan         = write_rgb_span;
+    ctx->Driver.WriteMonoRGBASpan    = write_mono_rgba_span;
+    ctx->Driver.WriteRGBAPixels      = write_rgba_pixels;
+    ctx->Driver.WriteMonoRGBAPixels  = write_mono_rgba_pixels;
+    ctx->Driver.WriteCI32Span        = write_ci32_span;
+    ctx->Driver.WriteCI8Span         = write_ci8_span;
+    ctx->Driver.WriteMonoCISpan      = write_mono_ci_span;
+    ctx->Driver.WriteCI32Pixels      = write_ci32_pixels;
+    ctx->Driver.WriteMonoCIPixels    = write_mono_ci_pixels;
+
+    ctx->Driver.ReadCI32Span        = read_ci32_span;
+    ctx->Driver.ReadRGBASpan        = read_rgba_span;
+    ctx->Driver.ReadCI32Pixels      = read_ci32_pixels;
+    ctx->Driver.ReadRGBAPixels      = read_rgba_pixels;
+}
+
+
+/**********************************************************************/
+/*****                  WMesa API Functions                       *****/
+/**********************************************************************/
+
+
+
+#define PAL_SIZE 256
+static void GetPalette(HPALETTE Pal,RGBQUAD *aRGB)
+{
+    STARTPROFILE
+        int i;
+    HDC hdc;
+    struct
+    {
+        WORD Version;
+        WORD NumberOfEntries;
+        PALETTEENTRY aEntries[PAL_SIZE];
+    } Palette =
+    {
+        0x300,
+            PAL_SIZE
+    };
+    hdc=GetDC(NULL);
+    if (Pal!=NULL)
+        GetPaletteEntries(Pal,0,PAL_SIZE,Palette.aEntries);
+    else
+        GetSystemPaletteEntries(hdc,0,PAL_SIZE,Palette.aEntries);
+    if (GetSystemPaletteUse(hdc) == SYSPAL_NOSTATIC)
+    {
+        for(i = 0; i <PAL_SIZE; i++)
+            Palette.aEntries[i].peFlags = PC_RESERVED;
+        Palette.aEntries[255].peRed = 255;
+        Palette.aEntries[255].peGreen = 255;
+        Palette.aEntries[255].peBlue = 255;
+        Palette.aEntries[255].peFlags = 0;
+        Palette.aEntries[0].peRed = 0;
+        Palette.aEntries[0].peGreen = 0;
+        Palette.aEntries[0].peBlue = 0;
+        Palette.aEntries[0].peFlags = 0;
+    }
+    else
+    {
+        int nStaticColors;
+        int nUsableColors;
+        nStaticColors = GetDeviceCaps(hdc, NUMCOLORS)/2;
+        for (i=0; i<nStaticColors; i++)
+            Palette.aEntries[i].peFlags = 0;
+        nUsableColors = PAL_SIZE-nStaticColors;
+        for (; i<nUsableColors; i++)
+            Palette.aEntries[i].peFlags = PC_RESERVED;
+        for (; i<PAL_SIZE-nStaticColors; i++)
+            Palette.aEntries[i].peFlags = PC_RESERVED;
+        for (i=PAL_SIZE-nStaticColors; i<PAL_SIZE; i++)
+            Palette.aEntries[i].peFlags = 0;
+    }
+    ReleaseDC(NULL,hdc);
+    for (i=0; i<PAL_SIZE; i++)
+    {
+        aRGB[i].rgbRed=Palette.aEntries[i].peRed;
+        aRGB[i].rgbGreen=Palette.aEntries[i].peGreen;
+        aRGB[i].rgbBlue=Palette.aEntries[i].peBlue;
+        aRGB[i].rgbReserved=Palette.aEntries[i].peFlags;
+    }
+    ENDPROFILE(GetPalette)
+}
+
+
+WMesaContext WMesaCreateContext( HWND hWnd,
+                                                                                       HPALETTE* Pal,
+                                                                                       GLboolean rgb_flag,
+                                                                                       GLboolean db_flag )
+{
+    RECT CR;
+    WMesaContext c;
+    GLboolean true_color_flag;
+    c = (struct wmesa_context * ) calloc(1,sizeof(struct wmesa_context));
+    if (!c)
+        return NULL;
+
+    c->Window=hWnd;
+    c->hDC = GetDC(hWnd);
+    true_color_flag = GetDeviceCaps(c->hDC, BITSPIXEL) > 8;
+#ifdef DDRAW
+    if(true_color_flag) c->rgb_flag = rgb_flag = GL_TRUE;
+#endif
+
+
+#ifdef DITHER
+    if ((true_color_flag==GL_FALSE) && (rgb_flag == GL_TRUE)){
+        c->dither_flag = GL_TRUE;
+        c->hPalHalfTone = WinGCreateHalftonePalette();
+    }
+    else
+        c->dither_flag = GL_FALSE;
+#else
+    c->dither_flag = GL_FALSE;
+#endif
+
+
+    if (rgb_flag==GL_FALSE)
+    {
+        c->rgb_flag = GL_FALSE;
+        //    c->pixel = 1;
+        c->db_flag = db_flag =GL_TRUE; // WinG requires double buffering
+        printf("Single buffer is not supported in color index mode, setting to double buffer.\n");
+    }
+    else
+    {
+        c->rgb_flag = GL_TRUE;
+        //    c->pixel = 0;
+    }
+    GetClientRect(c->Window,&CR);
+    c->width=CR.right;
+    c->height=CR.bottom;
+    if (db_flag)
+    {
+        c->db_flag = 1;
+        /* Double buffered */
+#ifndef DDRAW
+        //  if (c->rgb_flag==GL_TRUE && c->dither_flag != GL_TRUE )
+        {
+            wmCreateBackingStore(c, c->width, c->height);
+
+        }
+#endif
+    }
+    else
+    {
+        /* Single Buffered */
+        if (c->rgb_flag)
+            c->db_flag = 0;
+    }
+#ifdef DDRAW
+    if (DDInit(c,hWnd) == GL_FALSE) {
+        free( (void *) c );
+        exit(1);
+    }
+#endif
+
+
+    c->gl_visual = gl_create_visual(rgb_flag,
+                                    GL_FALSE,   /* software alpha */
+                                    db_flag,    /* db_flag */
+                                    GL_FALSE,   /* stereo */
+                                    16,         /* depth_bits */
+                                    8,          /* stencil_bits */
+                                    8,          /* accum_bits */
+                                    0,          /* index bits */
+                                    8,8,8,8 );  /* r, g, b, a bits */
+
+    if (!c->gl_visual) {
+        return NULL;
+    }
+
+    /* allocate a new Mesa context */
+    c->gl_ctx = gl_create_context( c->gl_visual, NULL, c, GL_TRUE);
+
+    if (!c->gl_ctx) {
+        gl_destroy_visual( c->gl_visual );
+        free(c);
+        return NULL;
+    }
+
+    c->gl_buffer = gl_create_framebuffer( c->gl_visual );
+    if (!c->gl_buffer) {
+        gl_destroy_visual( c->gl_visual );
+        gl_destroy_context( c->gl_ctx );
+        free(c);
+        return NULL;
+    }\r
+\r
+       c->gl_ctx->Driver.UpdateState = setup_DD_pointers;\r
+
+    //  setup_DD_pointers(c->gl_ctx);
+
+    return c;
+}
+
+void WMesaDestroyContext( void )
+{
+    WMesaContext c = Current;
+    ReleaseDC(c->Window,c->hDC);
+    WC = c;
+    if(c->hPalHalfTone != NULL)
+        DeleteObject(c->hPalHalfTone);
+    gl_destroy_visual( c->gl_visual );
+    gl_destroy_framebuffer( c->gl_buffer );
+    gl_destroy_context( c->gl_ctx );
+
+    if (c->db_flag)
+#ifdef DDRAW
+        DDFree(c);
+#else
+    wmDeleteBackingStore(c);
+#endif
+    free( (void *) c );
+    //Following code is added to enable parallel render
+    // Parallel render only work in double buffer mode
+#if !defined(NO_PARALLEL)
+    if(parallelMachine)
+        PRDestroyRenderBuffer();
+#endif
+    // End modification
+}
+
+void WMesaMakeCurrent( WMesaContext c )
+{
+    if(!c){
+        Current = c;
+        return;
+    }
+
+    //
+    // A little optimization
+    // If it already is current,
+    // don't set it again
+    //
+    if(Current == c)
+        return;
+
+    //gl_set_context( c->gl_ctx );
+    gl_make_current(c->gl_ctx, c->gl_buffer);
+    setup_DD_pointers(c->gl_ctx);\r
+    Current = c;
+    if (Current->gl_ctx->Viewport.Width==0) {
+        /* initialize viewport to window size */
+        gl_Viewport( Current->gl_ctx,
+            0, 0, Current->width, Current->height );
+    }
+    if ((c->cColorBits <= 8 ) && (c->rgb_flag == GL_TRUE)){
+        WMesaPaletteChange(c->hPalHalfTone);
+    }
+}
+
+void  WMesaSwapBuffers( void )
+{
+    HDC DC = Current->hDC;
+    if (Current->db_flag)
+        wmFlush(Current);
+}
+
+void  WMesaPaletteChange(HPALETTE Pal)
+{
+    int vRet;
+    LPPALETTEENTRY pPal;
+    if (Current && (Current->rgb_flag==GL_FALSE || Current->dither_flag == GL_TRUE))
+    {
+        pPal = (PALETTEENTRY *)malloc( 256 * sizeof(PALETTEENTRY));
+        Current->hPal=Pal;
+        //  GetPaletteEntries( Pal, 0, 256, pPal );
+        GetPalette( Pal, pPal );
+#ifdef DDRAW
+        Current->lpDD->lpVtbl->CreatePalette(Current->lpDD,DDPCAPS_8BIT,
+            pPal, &(Current->lpDDPal), NULL);
+        if (Current->lpDDPal)
+            Current->lpDDSPrimary->lpVtbl->SetPalette(Current->lpDDSPrimary,Current->lpDDPal);
+#else
+        vRet = SetDIBColorTable(Current->dib.hDC,0,256,pPal);
+#endif
+        free( pPal );
+    }
+
+}
+
+static unsigned char threeto8[8] = {
+    0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377
+};
+
+static unsigned char twoto8[4] = {
+    0, 0x55, 0xaa, 0xff
+};
+
+static unsigned char oneto8[2] = {
+    0, 255
+};
+
+static unsigned char componentFromIndex(UCHAR i, UINT nbits, UINT shift)
+{
+    unsigned char val;
+
+    val = i >> shift;
+    switch (nbits) {
+
+    case 1:
+        val &= 0x1;
+        return oneto8[val];
+
+    case 2:
+        val &= 0x3;
+        return twoto8[val];
+
+    case 3:
+        val &= 0x7;
+        return threeto8[val];
+
+    default:
+        return 0;
+    }
+}
+
+void wmCreatePalette( PWMC pwdc )
+{
+    /* Create a compressed and re-expanded 3:3:2 palette */
+    int            i;
+    LOGPALETTE     *pPal;
+    BYTE           rb, rs, gb, gs, bb, bs;
+
+    pwdc->nColors = 0x100;
+
+    pPal = (PLOGPALETTE)malloc(sizeof(LOGPALETTE) + pwdc->nColors * sizeof(PALETTEENTRY));
+    memset( pPal, 0, sizeof(LOGPALETTE) + pwdc->nColors * sizeof(PALETTEENTRY) );
+
+    pPal->palVersion = 0x300;
+
+    rb = REDBITS;
+    rs = REDSHIFT;
+    gb = GREENBITS;
+    gs = GREENSHIFT;
+    bb = BLUEBITS;
+    bs = BLUESHIFT;
+
+    if (pwdc->db_flag) {
+
+        /* Need to make two palettes: one for the screen DC and one for the DIB. */
+        pPal->palNumEntries = pwdc->nColors;
+        for (i = 0; i < pwdc->nColors; i++) {
+            pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs );
+            pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs );
+            pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs );
+            pPal->palPalEntry[i].peFlags = 0;
+        }
+        pwdc->hGLPalette = CreatePalette( pPal );
+        pwdc->hPalette = CreatePalette( pPal );
+    }
+
+    else {
+        pPal->palNumEntries = pwdc->nColors;
+        for (i = 0; i < pwdc->nColors; i++) {
+            pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs );
+            pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs );
+            pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs );
+            pPal->palPalEntry[i].peFlags = 0;
+        }
+        pwdc->hGLPalette = CreatePalette( pPal );
+    }
+
+    free(pPal);
+
+}
+
+void wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
+{
+    if(Current->db_flag){
+        LPBYTE  lpb = pwc->pbPixels;
+        LPDWORD lpdw;
+        LPWORD  lpw;
+        UINT    nBypp = pwc->cColorBits / 8;
+        UINT    nOffset = iPixel % nBypp;
+
+        // Move the pixel buffer pointer to the scanline that we
+        // want to access
+
+        //      pwc->dib.fFlushed = FALSE;
+
+        lpb += pwc->ScanWidth * iScanLine;
+        // Now move to the desired pixel
+        lpb += iPixel * nBypp;
+        lpb = PIXELADDR(iPixel, iScanLine);
+        lpdw = (LPDWORD)lpb;
+        lpw = (LPWORD)lpb;
+
+        if(nBypp == 1){
+            if(pwc->dither_flag)
+                *lpb = DITHER_RGB_2_8BIT(r,g,b,iScanLine,iPixel);
+            else
+                *lpb = BGR8(r,g,b);
+        }
+        else if(nBypp == 2)
+            *lpw = BGR16(r,g,b);
+        else if (nBypp == 3){
+            *lpdw = BGR24(r,g,b);
+        }
+        else if (nBypp == 4)
+            *lpdw = BGR32(r,g,b);
+    }
+    else{
+        HDC DC = DD_GETDC;
+        SetPixel(DC, iPixel, iScanLine, RGB(r,g,b));
+        DD_RELEASEDC;
+    }
+}
+
+void wmCreateDIBSection( HDC   hDC,
+                                                PWMC pwc,    // handle of device context
+                                                CONST BITMAPINFO *pbmi,  // address of structure containing bitmap size, format, and color data
+                                                UINT iUsage  // color data type indicator: RGB values or palette indices
+                       )
+{
+    DWORD   dwSize = 0;
+    DWORD   dwScanWidth;
+    UINT    nBypp = pwc->cColorBits / 8;
+    HDC     hic;
+
+    dwScanWidth = (((pwc->ScanWidth * nBypp)+ 3) & ~3);
+
+    pwc->ScanWidth =pwc->pitch = dwScanWidth;
+
+    if (stereo_flag)
+        pwc->ScanWidth = 2* pwc->pitch;
+
+    dwSize = sizeof(BITMAPINFO) + (dwScanWidth * pwc->height);
+
+    pwc->dib.hFileMap = CreateFileMapping((HANDLE)PAGE_FILE,
+        NULL,
+        PAGE_READWRITE | SEC_COMMIT,
+        0,
+        dwSize,
+        NULL);
+
+    if (!pwc->dib.hFileMap)
+        return;
+
+    pwc->dib.base = MapViewOfFile(pwc->dib.hFileMap,
+        FILE_MAP_ALL_ACCESS,
+        0,
+        0,
+        0);
+
+    if(!pwc->dib.base){
+        CloseHandle(pwc->dib.hFileMap);
+        return;
+    }
+
+    //  pwc->pbPixels = pwc->addrOffScreen = ((LPBYTE)pwc->dib.base) + sizeof(BITMAPINFO);
+
+    //  pwc->dib.hDC = CreateCompatibleDC(hDC);
+
+    CopyMemory(pwc->dib.base, pbmi, sizeof(BITMAPINFO));
+
+    hic = CreateIC("display", NULL, NULL, NULL);
+    pwc->dib.hDC = CreateCompatibleDC(hic);
+
+
+    /*  pwc->hbmDIB = CreateDIBitmap(hic,
+    &(pwc->bmi.bmiHeader),
+    CBM_INIT,
+    pwc->pbPixels,
+    &(pwc->bmi),
+    DIB_RGB_COLORS);
+    */
+    pwc->hbmDIB = CreateDIBSection(hic,
+        &(pwc->bmi),
+        (iUsage ? DIB_PAL_COLORS : DIB_RGB_COLORS),
+        &(pwc->pbPixels),
+        pwc->dib.hFileMap,
+        0);
+        /*
+        pwc->hbmDIB = CreateDIBSection(hic,
+        &(pwc->bmi),
+        DIB_RGB_COLORS,
+        &(pwc->pbPixels),
+        pwc->dib.hFileMap,
+        0);
+    */
+    pwc->ScreenMem = pwc->addrOffScreen = pwc->pbPixels;
+    pwc->hOldBitmap = SelectObject(pwc->dib.hDC, pwc->hbmDIB);
+
+    DeleteDC(hic);
+
+    return;
+
+}
+
+//
+// Blit memory DC to screen DC
+//
+BOOL wmFlush(PWMC pwc)
+{
+    BOOL    bRet = 0;
+    DWORD   dwErr = 0;
+#ifdef DDRAW
+    HRESULT             ddrval;
+#endif
+
+    // Now search through the torus frames and mark used colors
+    if(pwc->db_flag){
+#ifdef DDRAW
+        if (pwc->lpDDSOffScreen == NULL)
+            if(DDCreateOffScreen(pwc) == GL_FALSE)
+                return;
+
+            pwc->lpDDSOffScreen->lpVtbl->Unlock(pwc->lpDDSOffScreen, NULL);
+
+            while( 1 )
+            {
+                ddrval = pwc->lpDDSPrimary->lpVtbl->Blt( pwc->lpDDSPrimary,
+                    &(pwc->rectSurface), pwc->lpDDSOffScreen, &(pwc->rectOffScreen), 0, NULL );
+
+                if( ddrval == DD_OK )
+                {
+                    break;
+                }
+                if( ddrval == DDERR_SURFACELOST )
+                {
+                    if(!DDRestoreAll(pwc))
+                    {
+                        break;
+                    }
+                }
+                if( ddrval != DDERR_WASSTILLDRAWING )
+                {
+                    break;
+                }
+            }
+
+            while (pwc->lpDDSOffScreen->lpVtbl->Lock(pwc->lpDDSOffScreen,
+                NULL, &(pwc->ddsd), 0, NULL) == DDERR_WASSTILLDRAWING)
+                ;
+
+            if(ddrval != DD_OK)
+                dwErr = GetLastError();
+#else
+            bRet = BitBlt(pwc->hDC, 0, 0, pwc->width, pwc->height,
+                pwc->dib.hDC, 0, 0, SRCCOPY);
+#endif
+    }
+
+    return(TRUE);
+
+}
+
+// The following code is added by Li Wei to enable stereo display
+
+#if !defined(NO_STEREO)
+
+void WMesaShowStereo(GLuint list)
+{
+
+    GLbitfield mask = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
+    GLfloat cm[16];
+    GLint matrix_mode;
+    // Must use double Buffer
+    if( ! Current-> db_flag )
+        return;
+
+
+    glGetIntegerv(GL_MATRIX_MODE,&matrix_mode);
+
+    //  glPushMatrix();  //****
+    WMesaViewport(Current->gl_ctx,0,Current->height/2,Current->width,Current->height/2);
+    //  Current->gl_ctx->NewState = 0;
+
+    //  glViewport(0,0,Current->width,Current->height/2);
+    if(matrix_mode!=GL_MODELVIEW)
+        glMatrixMode(GL_MODELVIEW);
+
+    glGetFloatv(GL_MODELVIEW_MATRIX,cm);
+    glLoadIdentity();
+    gluLookAt(viewDistance/2,0.0,0.0 ,
+        viewDistance/2,0.0,-1.0,
+        0.0,1.0,0.0 );
+    //  glTranslatef(viewDistance/2.0,0.,0.);
+    glMultMatrixf( cm );
+
+    Current->ScreenMem = Current->pbPixels = Current->addrOffScreen;
+    //glPushMatrix();
+    glCallList( list );
+    //glPopMatrix();
+
+    glGetFloatv(GL_MODELVIEW_MATRIX,cm);
+    glLoadIdentity();
+    gluLookAt(-viewDistance/2,0.0,0.0 ,
+        -viewDistance/2,0.0,-1.0,
+        0.0,1.0,0.0 );
+    //  glTranslatef(-viewDistance/2.0,0.,0.);
+    glMultMatrixf(cm);
+
+    Current->ScreenMem = Current->pbPixels = Current->addrOffScreen + Current->pitch;
+    glCallList(list);
+    if(matrix_mode!=GL_MODELVIEW)
+        glMatrixMode(matrix_mode);
+
+    //  glPopMatrix();
+    glFlush();
+
+    WMesaViewport(Current->gl_ctx,0,0,Current->width,Current->height);
+    //  Current->gl_ctx->NewState = 0;
+    WMesaSwapBuffers();
+
+}
+
+void toggleStereoMode()
+{
+    if(!Current->db_flag)
+        return;
+    if(!stereo_flag){
+        stereo_flag = 1;
+        if(stereoBuffer==GL_FALSE)
+#if !defined(NO_PARALLEL)
+            if(!parallelFlag)
+#endif
+            {
+                Current->ScanWidth = Current->pitch*2;
+            }
+    }
+    else {
+        stereo_flag = 0;
+#if !defined(NO_PARALLEL)
+        if(!parallelFlag)
+#endif
+            Current->ScanWidth = Current->pitch;
+        Current->pbPixels = Current->addrOffScreen;
+    }
+}
+
+/* if in stereo mode, the following function is called */
+void glShowStereo(GLuint list)
+{
+    WMesaShowStereo(list);
+}
+
+#endif // End if NO_STEREO not defined
+
+#if !defined(NO_PARALLEL)
+
+void toggleParallelMode(void)
+{
+    if(!parallelFlag){
+        parallelFlag = GL_TRUE;
+        if(parallelMachine==GL_FALSE){
+            PRCreateRenderBuffer( Current->rgb_flag? GL_RGBA :GL_COLOR_INDEX,
+                Current->cColorBits/8,
+                Current->width ,Current->height,
+                Current->ScanWidth,
+                Current->rgb_flag? Current->pbPixels: Current->ScreenMem);
+            parallelMachine = GL_TRUE;
+        }
+    }
+    else {
+        parallelFlag = GL_FALSE;
+        if(parallelMachine==GL_TRUE){
+            PRDestroyRenderBuffer();
+            parallelMachine=GL_FALSE;
+            ReadyForNextFrame = GL_TRUE;
+        }
+
+        /***********************************************
+        // Seems something wrong!!!!
+        ************************************************/
+
+        WMesaMakeCurrent(Current);
+#if !defined(NO_STEREO)
+        stereo_flag = GL_FALSE ;
+#endif
+    }
+}
+
+void PRShowRenderResult(void)
+{
+    int flag = 0;
+    if(!glImageRendered())
+        return;
+
+    if (parallelFlag)
+    {
+        WMesaSwapBuffers();
+    }
+
+}
+#endif //End if NO_PARALLEL not defined
+
+//end modification
+
+BYTE DITHER_RGB_2_8BIT( int red, int green, int blue, int pixel, int scanline)
+{
+    char unsigned redtemp, greentemp, bluetemp, paletteindex;
+
+    //*** now, look up each value in the halftone matrix
+    //*** using an 8x8 ordered dither.
+    redtemp = aDividedBy51[red]
+        + (aModulo51[red] > aHalftone8x8[(pixel%8)*8
+        + scanline%8]);
+    greentemp = aDividedBy51[(char unsigned)green]
+        + (aModulo51[green] > aHalftone8x8[
+        (pixel%8)*8 + scanline%8]);
+    bluetemp = aDividedBy51[(char unsigned)blue]
+        + (aModulo51[blue] > aHalftone8x8[
+        (pixel%8)*8 +scanline%8]);
+
+    //*** recombine the halftoned rgb values into a palette index
+    paletteindex =
+        redtemp + aTimes6[greentemp] + aTimes36[bluetemp];
+
+    //*** and translate through the wing halftone palette
+    //*** translation vector to give the correct value.
+    return aWinGHalftoneTranslation[paletteindex];
+}
+
+#ifdef DDRAW
+/*
+* restoreAll
+*
+* restore all lost objects
+*/
+static HRESULT DDRestoreAll( WMesaContext wc )
+{
+    HRESULT     ddrval;
+
+    ddrval = wc->lpDDSPrimary->lpVtbl->Restore(wc->lpDDSPrimary);
+    if( ddrval == DD_OK )
+    {
+        ddrval = wc->lpDDSOffScreen->lpVtbl->Restore(wc->lpDDSOffScreen);
+    }
+    return ddrval;
+
+} /* restoreAll */
+
+
+  /*
+  * This function is called if the initialization function fails
+*/
+static BOOL initFail( HWND hwnd, WMesaContext wc )
+{
+    DDFree(wc);
+    MessageBox( hwnd, "DirectDraw Init FAILED", "", MB_OK );
+    return FALSE;
+
+} /* initFail */
+
+
+static void DDDeleteOffScreen(WMesaContext wc)
+{
+    if( wc->lpDDSOffScreen != NULL )
+    {
+        wc->lpDDSOffScreen->lpVtbl->Unlock(wc->lpDDSOffScreen,NULL);
+        wc->lpDDSOffScreen->lpVtbl->Release(wc->lpDDSOffScreen);
+        wc->lpDDSOffScreen = NULL;
+    }
+
+}
+
+static void DDFreePrimarySurface(WMesaContext wc)
+{
+    if( wc->lpDDSPrimary != NULL )
+    {
+        if(wc->db_flag == GL_FALSE)
+            wc->lpDDSPrimary->lpVtbl->ReleaseDC(wc->lpDDSPrimary, wc->hDC);
+        wc->lpDDSPrimary->lpVtbl->Release(wc->lpDDSPrimary);
+        wc->lpDDSPrimary = NULL;
+    }
+}
+
+static BOOL DDCreatePrimarySurface(WMesaContext wc)
+{
+    HRESULT ddrval;
+    DDSCAPS             ddscaps;
+    wc->ddsd.dwSize = sizeof( wc->ddsd );
+    wc->ddsd.dwFlags = DDSD_CAPS;
+    wc->ddsd.ddsCaps.dwCaps =   DDSCAPS_PRIMARYSURFACE;
+
+    ddrval = wc->lpDD->lpVtbl->CreateSurface( wc->lpDD,&(wc->ddsd), &(wc->lpDDSPrimary), NULL );
+    if( ddrval != DD_OK )
+    {
+        return initFail(wc->hwnd , wc);
+    }
+    if(wc->db_flag == GL_FALSE)
+        wc->lpDDSPrimary->lpVtbl->GetDC(wc->lpDDSPrimary, wc->hDC);
+    return TRUE;
+}
+
+static BOOL DDCreateOffScreen(WMesaContext wc)
+{
+    POINT   pt;
+    HRESULT     ddrval;
+    if(wc->lpDD == NULL)
+        return FALSE;
+    GetClientRect( wc->hwnd, &(wc->rectOffScreen) );
+    wc->ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
+    wc->ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
+    wc->ddsd.dwHeight = wc->rectOffScreen.bottom - wc->rectOffScreen.top;
+    wc->ddsd.dwWidth = wc->rectOffScreen.right - wc->rectOffScreen.left;
+
+    ddrval = wc->lpDD->lpVtbl->CreateSurface( wc->lpDD, &(wc->ddsd), &(wc->lpDDSOffScreen), NULL );
+    if( ddrval != DD_OK )
+    {
+        return FALSE;
+    }
+
+    while (wc->lpDDSOffScreen->lpVtbl->Lock(wc->lpDDSOffScreen,NULL, &(wc->ddsd), 0, NULL) == DDERR_WASSTILLDRAWING)
+        ;
+    //  while ((ddrval = wc->lpDDSOffScreen->lpVtbl->Lock(wc->lpDDSOffScreen,NULL, &(wc->ddsd), DDLOCK_SURFACEMEMORYPTR , NULL)) != DD_OK)
+    ;
+    if(wc->ddsd.lpSurface==NULL)
+        return initFail(wc->hwnd, wc);
+
+    wc->ScreenMem = wc->pbPixels = wc->addrOffScreen = (PBYTE)(wc->ddsd.lpSurface);
+    wc->ScanWidth = wc->pitch = wc->ddsd.lPitch;
+    if (stereo_flag)
+        wc->ScanWidth = wc->ddsd.lPitch*2;
+
+    GetClientRect( wc->hwnd, &(wc->rectSurface) );
+    pt.x = pt.y = 0;
+    ClientToScreen( wc->hwnd, &pt );
+    OffsetRect(&(wc->rectSurface), pt.x, pt.y);
+    wmSetPixelFormat(wc, wc->hDC);
+    return TRUE;
+}
+
+/*
+* doInit - do work required for every instance of the application:
+*                create the window, initialize data
+*/
+static BOOL DDInit( WMesaContext wc, HWND hwnd)
+{
+    HRESULT             ddrval;
+    DWORD dwFrequency;
+
+    LPDIRECTDRAW            lpDD;           // DirectDraw object
+    LPDIRECTDRAW2            lpDD2;
+
+
+    wc->fullScreen = displayOptions.fullScreen;
+    wc->gMode = displayOptions.mode;
+    wc->hwnd = hwnd;
+    stereo_flag = displayOptions.stereo;
+    if(wc->db_flag!= GL_TRUE)
+        stereo_flag = GL_FALSE;
+        /*
+        * create the main DirectDraw object
+    */
+    ddrval = DirectDrawCreate( NULL, &(wc->lpDD), NULL );
+    if( ddrval != DD_OK )
+    {
+        return initFail(hwnd,wc);
+    }
+
+    // Get exclusive mode if requested
+    if(wc->fullScreen)
+    {
+        ddrval = wc->lpDD->lpVtbl->SetCooperativeLevel( wc->lpDD, hwnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN );
+    }
+    else
+    {
+        ddrval = wc->lpDD->lpVtbl->SetCooperativeLevel( wc->lpDD, hwnd, DDSCL_NORMAL );
+    }
+    if( ddrval != DD_OK )
+    {
+        return initFail(hwnd , wc);
+    }
+
+
+    /*  ddrval = wc->lpDD->lpVtbl->QueryInterface(wc->lpDD, IID_IDirectDraw2,
+    (LPVOID *)((wc->lpDD2)));
+
+    */
+    if(ddrval != DD_OK)
+        return initFail(hwnd , wc);
+
+
+    //ddrval = wc->lpDD->lpVtbl->GetDisplayMode( wc->lpDD, &(wc->ddsd));
+    //  wc->lpDD2->lpVtbl->GetMonitorFrequency(wc->lpDD, &dwFrequency);
+    switch( wc->gMode )
+    {
+    case 1:  ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 640, 480, displayOptions.bpp); break;
+    case 2:  ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 800, 600, displayOptions.bpp); break;
+    case 3:  ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 1024, 768, displayOptions.bpp); break;
+    case 4:  ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 1152, 864, displayOptions.bpp); break;
+    case 5:  ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 1280, 1024, displayOptions.bpp); break;
+    }
+
+    if( ddrval != DD_OK )
+    {
+        printf("Can't modify display mode, current mode used\n");
+        //        return initFail(hwnd , wc);
+    }
+    //ddrval = wc->lpDD->lpVtbl->GetDisplayMode( wc->lpDD, &(wc->ddsd));
+    switch(ddrval){
+    case DDERR_INVALIDOBJECT:
+        break;
+    case DDERR_INVALIDPARAMS:
+        break;
+    case DDERR_UNSUPPORTEDMODE:
+        ;
+    }
+
+    if(DDCreatePrimarySurface(wc) == GL_FALSE)
+        return initFail(hwnd, wc);
+
+    if(wc->db_flag)
+        return DDCreateOffScreen(wc);
+} /* DDInit */
+
+static void DDFree( WMesaContext wc)
+{
+    if( wc->lpDD != NULL )
+    {
+        DDFreePrimarySurface(wc);
+        DDDeleteOffScreen(wc);
+        wc->lpDD->lpVtbl->Release(wc->lpDD);
+        wc->lpDD = NULL;
+    }
+    // Clean up the screen on exit
+    RedrawWindow( NULL, NULL, NULL, RDW_INVALIDATE | RDW_ERASE |
+        RDW_ALLCHILDREN );
+
+}
+#endif
+
+void WMesaMove(void)
+{
+    WMesaContext wc = Current;
+    POINT   pt;
+    if (Current != NULL){
+        GetClientRect( wc->hwnd, &(wc->rectSurface) );
+        pt.x = pt.y = 0;
+        ClientToScreen( wc->hwnd, &pt );
+        OffsetRect(&(wc->rectSurface), pt.x, pt.y);
+    }
+}
+
+
+
+/*
+* Like PACK_8A8B8G8R() but don't use alpha.  This is usually an acceptable
+* shortcut.
+*/
+#define PACK_8B8G8R( R, G, B )   ( ((B) << 16) | ((G) << 8) | (R) )
+
+
+/**********************************************************************/
+/***                   Triangle rendering                            ***/
+/**********************************************************************/
+
+/*
+ * XImage, smooth, depth-buffered, PF_8A8B8G8R triangle.
+ */
+static void smooth_8A8B8G8R_z_triangle( GLcontext *ctx,
+                                       GLuint v0, GLuint v1, GLuint v2,
+                                       GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define INTERP_Z 1
+#define INTERP_RGB 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
+#define PIXEL_TYPE GLuint
+    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define INNER_LOOP( LEFT, RIGHT, Y )                    \
+    {                                   \
+    GLint i, len = RIGHT-LEFT;                      \
+    for (i=0;i<len;i++) {                       \
+    GLdepth z = FixedToDepth(ffz);                  \
+    if (z < zRow[i]) {                      \
+    pRow[i] = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg),    \
+    FixedToInt(ffb) );          \
+    zRow[i] = z;                            \
+    }                                   \
+    ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;         \
+    ffz += fdzdx;                           \
+    }                                   \
+    }
+#ifdef WIN32
+       #include "..\tritemp.h"
+#else
+       #include "tritemp.h"
+#endif
+}
+
+
+/*
+* XImage, smooth, depth-buffered, PF_8R8G8B triangle.
+*/
+static void smooth_8R8G8B_z_triangle( GLcontext *ctx,
+                                     GLuint v0, GLuint v1, GLuint v2,
+                                     GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define INTERP_Z 1
+#define INTERP_RGB 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
+#define PIXEL_TYPE GLuint
+    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define INNER_LOOP( LEFT, RIGHT, Y )                    \
+    {                                   \
+    GLint i, len = RIGHT-LEFT;                      \
+    for (i=0;i<len;i++) {                       \
+    GLdepth z = FixedToDepth(ffz);                  \
+    if (z < zRow[i]) {                      \
+    pRow[i] = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg),    \
+    FixedToInt(ffb) );          \
+    zRow[i] = z;                            \
+    }                                   \
+    ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;         \
+    ffz += fdzdx;                           \
+    }                                   \
+    }
+#ifdef WIN32
+       #include "..\tritemp.h"
+#else
+       #include "tritemp.h"
+#endif
+}
+
+
+
+/*
+* XImage, smooth, depth-buffered, PF_5R6G5B triangle.
+*/
+static void smooth_5R6G5B_z_triangle( GLcontext *ctx,
+                                     GLuint v0, GLuint v1, GLuint v2,
+                                     GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define INTERP_Z 1
+#define INTERP_RGB 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
+#define PIXEL_TYPE GLushort
+    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define INNER_LOOP( LEFT, RIGHT, Y )                    \
+    {                                   \
+    GLint i, len = RIGHT-LEFT;                      \
+    for (i=0;i<len;i++) {                       \
+    GLdepth z = FixedToDepth(ffz);                  \
+    if (z < zRow[i]) {                      \
+    pRow[i] = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg),    \
+    FixedToInt(ffb) );          \
+    zRow[i] = z;                            \
+    }                                   \
+    ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;         \
+    ffz += fdzdx;                           \
+    }                                   \
+    }
+#ifdef WIN32
+       #include "..\tritemp.h"
+#else
+       #include "tritemp.h"
+#endif
+}
+
+/*
+* XImage, flat, depth-buffered, PF_8A8B8G8R triangle.
+*/
+static void flat_8A8B8G8R_z_triangle( GLcontext *ctx, GLuint v0,
+                                     GLuint v1, GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define INTERP_Z 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
+#define PIXEL_TYPE GLuint
+    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define SETUP_CODE                  \
+    unsigned long p = PACK_8B8G8R( VB->Color[pv][0],    \
+    VB->Color[pv][1], VB->Color[pv][2] );
+#define INNER_LOOP( LEFT, RIGHT, Y )                    \
+    {                                   \
+    GLint i, len = RIGHT-LEFT;                      \
+    for (i=0;i<len;i++) {                       \
+    GLdepth z = FixedToDepth(ffz);                  \
+    if (z < zRow[i]) {                      \
+    pRow[i] = p;                            \
+    zRow[i] = z;                            \
+    }                                   \
+    ffz += fdzdx;                           \
+    }                                   \
+    }
+#ifdef WIN32
+       #include "..\tritemp.h"
+#else
+       #include "tritemp.h"
+#endif
+}
+
+
+/*
+* XImage, flat, depth-buffered, PF_8R8G8B triangle.
+*/
+static void flat_8R8G8B_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                                   GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define INTERP_Z 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
+#define PIXEL_TYPE GLuint
+    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define SETUP_CODE                  \
+    unsigned long p = PACK_8R8G8B( VB->Color[pv][0],    \
+    VB->Color[pv][1], VB->Color[pv][2] );
+#define INNER_LOOP( LEFT, RIGHT, Y )            \
+    {                           \
+    GLint i, len = RIGHT-LEFT;              \
+    for (i=0;i<len;i++) {               \
+    GLdepth z = FixedToDepth(ffz);          \
+    if (z < zRow[i]) {              \
+    pRow[i] = p;                    \
+    zRow[i] = z;                    \
+    }                           \
+    ffz += fdzdx;                   \
+    }                           \
+    }
+#ifdef WIN32
+       #include "..\tritemp.h"
+#else
+       #include "tritemp.h"
+#endif
+}
+
+
+/*
+* XImage, flat, depth-buffered, PF_5R6G5B triangle.
+*/
+static void flat_5R6G5B_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                                   GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define INTERP_Z 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
+#define PIXEL_TYPE GLushort
+    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define SETUP_CODE                  \
+    unsigned long p = PACK_5R6G5B( VB->Color[pv][0],    \
+    VB->Color[pv][1], VB->Color[pv][2] );
+#define INNER_LOOP( LEFT, RIGHT, Y )            \
+    {                           \
+    GLint i, len = RIGHT-LEFT;              \
+    for (i=0;i<len;i++) {               \
+    GLdepth z = FixedToDepth(ffz);          \
+    if (z < zRow[i]) {              \
+    pRow[i] = p;                    \
+    zRow[i] = z;                    \
+    }                           \
+    ffz += fdzdx;                   \
+    }                           \
+    }
+#ifdef WIN32
+       #include "..\tritemp.h"
+#else
+       #include "tritemp.h"
+#endif
+}
+
+
+/*
+* XImage, smooth, NON-depth-buffered, PF_8A8B8G8R triangle.
+*/
+static void smooth_8A8B8G8R_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                                     GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define INTERP_RGB 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
+#define PIXEL_TYPE GLuint
+    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define INNER_LOOP( LEFT, RIGHT, Y )                    \
+    {                                   \
+    GLint xx;                               \
+    PIXEL_TYPE *pixel = pRow;                       \
+    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {               \
+    *pixel = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg),     \
+                FixedToInt(ffb) );          \
+                ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;         \
+    }                                   \
+    }
+#ifdef WIN32
+       #include "..\tritemp.h"
+#else
+       #include "tritemp.h"
+#endif
+}
+
+
+/*
+* XImage, smooth, NON-depth-buffered, PF_8R8G8B triangle.
+*/
+static void smooth_8R8G8B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                                   GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define INTERP_RGB 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
+#define PIXEL_TYPE GLuint
+    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define INNER_LOOP( LEFT, RIGHT, Y )                    \
+    {                                   \
+    GLint xx;                               \
+    PIXEL_TYPE *pixel = pRow;                       \
+    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {               \
+    *pixel = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg),     \
+                FixedToInt(ffb) );          \
+                ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;         \
+    }                                   \
+    }
+#ifdef WIN32
+       #include "..\tritemp.h"
+#else
+       #include "tritemp.h"
+#endif
+}
+
+
+/*
+* XImage, smooth, NON-depth-buffered, PF_5R6G5B triangle.
+*/
+static void smooth_5R6G5B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                                   GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define INTERP_RGB 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
+#define PIXEL_TYPE GLushort
+    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define INNER_LOOP( LEFT, RIGHT, Y )                    \
+    {                                   \
+    GLint xx;                               \
+    PIXEL_TYPE *pixel = pRow;                       \
+    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {               \
+    *pixel = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg),     \
+                FixedToInt(ffb) );          \
+                ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;         \
+    }                                   \
+    }
+#ifdef WIN32
+       #include "..\tritemp.h"
+#else
+       #include "tritemp.h"
+#endif
+}
+
+
+
+/*
+* XImage, flat, NON-depth-buffered, PF_8A8B8G8R triangle.
+*/
+static void flat_8A8B8G8R_triangle( GLcontext *ctx, GLuint v0,
+                                   GLuint v1, GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
+#define PIXEL_TYPE GLuint
+    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define SETUP_CODE                  \
+    unsigned long p = PACK_8B8G8R( VB->Color[pv][0],    \
+    VB->Color[pv][1], VB->Color[pv][2] );
+#define INNER_LOOP( LEFT, RIGHT, Y )            \
+    {                           \
+    GLint xx;                       \
+    PIXEL_TYPE *pixel = pRow;               \
+    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {       \
+    *pixel = p;                 \
+    }                           \
+    }
+#ifdef WIN32
+       #include "..\tritemp.h"
+#else
+       #include "tritemp.h"
+#endif
+}
+
+
+/*
+* XImage, flat, NON-depth-buffered, PF_8R8G8B triangle.
+*/
+static void flat_8R8G8B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                                 GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
+#define PIXEL_TYPE GLuint
+    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define SETUP_CODE                  \
+    unsigned long p = PACK_8R8G8B( VB->Color[pv][0],    \
+    VB->Color[pv][1], VB->Color[pv][2] );
+#define INNER_LOOP( LEFT, RIGHT, Y )            \
+    {                           \
+    GLint xx;                       \
+    PIXEL_TYPE *pixel = pRow;               \
+    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {       \
+    *pixel = p;                 \
+    }                           \
+    }
+#ifdef WIN32
+       #include "..\tritemp.h"
+#else
+       #include "tritemp.h"
+#endif
+}
+
+
+/*
+* XImage, flat, NON-depth-buffered, PF_5R6G5B triangle.
+*/
+static void flat_5R6G5B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                                 GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
+#define PIXEL_TYPE GLushort
+    //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define SETUP_CODE                  \
+    unsigned long p = PACK_5R6G5B( VB->Color[pv][0],    \
+    VB->Color[pv][1], VB->Color[pv][2] );
+#define INNER_LOOP( LEFT, RIGHT, Y )            \
+    {                           \
+    GLint xx;                       \
+    PIXEL_TYPE *pixel = pRow;               \
+    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {       \
+    *pixel = p;                 \
+    }                           \
+    }
+#ifdef WIN32
+       #include "..\tritemp.h"
+#else
+       #include "tritemp.h"
+#endif
+}
+
+
+/*
+* XImage, smooth, depth-buffered, 8-bit PF_LOOKUP triangle.
+*/
+
+static void smooth_ci_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                                 GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define INTERP_Z 1
+#define INTERP_INDEX 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
+#define PIXEL_TYPE GLubyte
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define INNER_LOOP( LEFT, RIGHT, Y )                                \
+    {                                                                   \
+    GLint i, len = RIGHT-LEFT;                                      \
+    for (i=0;i<len;i++) {                                           \
+    GLdepth z = FixedToDepth(ffz);                              \
+    if (z < zRow[i]) {                                          \
+    pRow[i] = FixedToInt(ffi);                                  \
+    zRow[i] = z;                                                \
+    }                                                               \
+    ffi += fdidx;                                                   \
+    ffz += fdzdx;                                                   \
+    }                                                               \
+    }
+
+#ifdef WIN32
+       #include "..\tritemp.h"
+#else
+       #include "tritemp.h"
+#endif
+}
+
+
+/*
+* XImage, flat, depth-buffered, 8-bit PF_LOOKUP triangle.
+*/
+
+static void flat_ci_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                               GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define INTERP_Z 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
+#define PIXEL_TYPE GLubyte
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define SETUP_CODE                                                  \
+    GLuint index = VB->Index[pv];                                   \
+    if (!VB->MonoColor) {                                           \
+    /* set the color index */                                       \
+    (*ctx->Driver.Index)( ctx, index );                         \
+    }
+#define INNER_LOOP( LEFT, RIGHT, Y )                                \
+    {                                                                   \
+    GLint i, len = RIGHT-LEFT;                                      \
+    for (i=0;i<len;i++) {                                           \
+    GLdepth z = FixedToDepth(ffz);                              \
+    if (z < zRow[i]) {                                          \
+    pRow[i] = index;                                            \
+    zRow[i] = z;                                                \
+    }                                                               \
+    ffz += fdzdx;                                                   \
+    }                                                               \
+    }
+#ifdef WIN32
+       #include "..\tritemp.h"
+#else
+       #include "tritemp.h"
+#endif
+}
+
+
+
+/*
+* XImage, smooth, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
+*/
+
+static void smooth_ci_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                               GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define INTERP_Z 1
+#define INTERP_INDEX 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
+#define PIXEL_TYPE GLubyte
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define INNER_LOOP( LEFT, RIGHT, Y )                    \
+    {                                   \
+    GLint xx;                               \
+    PIXEL_TYPE *pixel = pRow;                       \
+    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {               \
+    *pixel = FixedToInt(ffi);           \
+    ffi += fdidx;           \
+    }                                   \
+    }
+#ifdef WIN32
+       #include "..\tritemp.h"
+#else
+       #include "tritemp.h"
+#endif
+}
+
+
+/*
+* XImage, flat, NON-depth-buffered, 8-bit PF_LOOKUP triangle.
+*/
+static void flat_ci_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                             GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+#define INTERP_Z 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
+#define PIXEL_TYPE GLubyte
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define SETUP_CODE                                                  \
+    GLuint index = VB->Index[pv];                                   \
+    if (!VB->MonoColor) {                                           \
+    /* set the color index */                                       \
+    (*ctx->Driver.Index)( ctx, index );                         \
+    }
+#define INNER_LOOP( LEFT, RIGHT, Y )            \
+    {                           \
+    GLint xx;                       \
+    PIXEL_TYPE *pixel = pRow;               \
+    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {       \
+    *pixel = index;                 \
+    }                           \
+    }
+#ifdef WIN32
+       #include "..\tritemp.h"
+#else
+       #include "tritemp.h"
+#endif
+}
+
+/*
+* XImage, smooth, depth-buffered, 8-bit, PF_DITHER8 triangle.
+*/
+static void smooth_DITHER8_z_triangle( GLcontext *ctx,
+                                      GLuint v0, GLuint v1, GLuint v2,
+                                      GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+    DITHER_RGB_TO_8BIT_SETUP
+#define INTERP_Z 1
+#define INTERP_RGB 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
+#define PIXEL_TYPE GLubyte
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define INNER_LOOP( LEFT, RIGHT, Y )                                    \
+    {                                                                       \
+    GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT;                 \
+    for (i=0;i<len;i++,xx++) {                                          \
+    GLdepth z = FixedToDepth(ffz);                                  \
+    if (z < zRow[i]) {                                              \
+    DITHER_RGB_TO_8BIT( FixedToInt(ffr), FixedToInt(ffg),           \
+    FixedToInt(ffb), xx, yy);               \
+    pRow[i] = pixelDithered;                                        \
+    zRow[i] = z;                                                    \
+    }                                                                   \
+    ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;                     \
+    ffz += fdzdx;                                                       \
+    }                                                                   \
+    }
+#ifdef WIN32
+       #include "..\tritemp.h"
+#else
+       #include "tritemp.h"
+#endif
+}
+
+/*
+* XImage, flat, depth-buffered, 8-bit PF_DITHER triangle.
+*/
+static void flat_DITHER8_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                                    GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+    DITHER_RGB_TO_8BIT_SETUP
+#define INTERP_Z 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
+#define PIXEL_TYPE GLubyte
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+
+#define INNER_LOOP( LEFT, RIGHT, Y )                                    \
+    {                                                                       \
+    GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT;                 \
+    for (i=0;i<len;i++,xx++) {                                          \
+    GLdepth z = FixedToDepth(ffz);                                  \
+    if (z < zRow[i]) {                                              \
+    DITHER_RGB_TO_8BIT( VB->Color[pv][0],                           \
+             VB->Color[pv][1], VB->Color[pv][2], xx, yy);               \
+             pRow[i] = pixelDithered;                                       \
+             zRow[i] = z;                                                   \
+    }                                                                   \
+    ffz += fdzdx;                                                       \
+    }                                                                   \
+    }
+#ifdef WIN32
+       #include "..\tritemp.h"
+#else
+       #include "tritemp.h"
+#endif
+}
+
+/*
+* XImage, smooth, NON-depth-buffered, 8-bit PF_DITHER triangle.
+*/
+static void smooth_DITHER8_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                                    GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+    DITHER_RGB_TO_8BIT_SETUP
+#define INTERP_RGB 1
+#define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
+#define PIXEL_TYPE GLubyte
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+#define INNER_LOOP( LEFT, RIGHT, Y )                                    \
+    {                                                                       \
+    GLint xx, yy = FLIP(Y);                                             \
+    PIXEL_TYPE *pixel = pRow;                                           \
+    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {                               \
+    DITHER_RGB_TO_8BIT( VB->Color[pv][0],   VB->Color[pv][1], VB->Color[pv][2], xx, yy);\
+    *pixel = pixelDithered;                                         \
+    ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;                     \
+    }                                                                   \
+    }
+#ifdef WIN32
+       #include "..\tritemp.h"
+#else
+       #include "tritemp.h"
+#endif
+}
+
+/*
+* XImage, flat, NON-depth-buffered, 8-bit PF_DITHER triangle.
+*/
+
+static void flat_DITHER8_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
+                                  GLuint v2, GLuint pv )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+    DITHER_RGB_TO_8BIT_SETUP
+#define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
+#define PIXEL_TYPE GLubyte
+#define BYTES_PER_ROW (wmesa->ScanWidth)
+
+#define INNER_LOOP( LEFT, RIGHT, Y )                                    \
+    {                                                                       \
+    GLint xx, yy = FLIP(Y);                                             \
+    PIXEL_TYPE *pixel = pRow;                                           \
+    for (xx=LEFT;xx<RIGHT;xx++,pixel++) {                               \
+    DITHER_RGB_TO_8BIT( VB->Color[pv][0],                               \
+             VB->Color[pv][1], VB->Color[pv][2], xx, yy);               \
+             *pixel = pixelDithered;                                            \
+    }                                                                   \
+    }
+#ifdef WIN32
+       #include "..\tritemp.h"
+#else
+       #include "tritemp.h"
+#endif
+}
+
+
+
+
+static triangle_func choose_triangle_function( GLcontext *ctx )
+{
+    WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;
+    int depth = wmesa->cColorBits;
+
+    if (ctx->Polygon.SmoothFlag)     return NULL;
+    if (ctx->Texture.Enabled)        return NULL;
+    if (!wmesa->db_flag) return NULL;
+    /*if (wmesa->xm_buffer->buffer==XIMAGE)*/ {
+    if (   ctx->Light.ShadeModel==GL_SMOOTH
+        && ctx->RasterMask==DEPTH_BIT
+        && ctx->Depth.Func==GL_LESS
+        && ctx->Depth.Mask==GL_TRUE
+        && ctx->Polygon.StippleFlag==GL_FALSE) {
+        switch (wmesa->pixelformat) {
+        case PF_8A8B8G8R:
+            return smooth_8A8B8G8R_z_triangle;
+        case PF_8R8G8B:
+            return smooth_8R8G8B_z_triangle;
+        case PF_5R6G5B:
+            return smooth_5R6G5B_z_triangle;
+        case PF_DITHER8:
+            return  smooth_DITHER8_z_triangle;
+        case PF_INDEX8:
+            return smooth_ci_z_triangle;
+        default:
+            return NULL;
+        }
+    }
+    if (   ctx->Light.ShadeModel==GL_FLAT
+        && ctx->RasterMask==DEPTH_BIT
+        && ctx->Depth.Func==GL_LESS
+        && ctx->Depth.Mask==GL_TRUE
+        && ctx->Polygon.StippleFlag==GL_FALSE) {
+        switch (wmesa->pixelformat) {
+        case PF_8A8B8G8R:
+            return flat_8A8B8G8R_z_triangle;
+        case PF_8R8G8B:
+            return flat_8R8G8B_z_triangle;
+        case PF_5R6G5B:
+            return flat_5R6G5B_z_triangle;
+        case PF_DITHER8:
+            return flat_DITHER8_z_triangle;
+        case PF_INDEX8:
+            return flat_ci_z_triangle;
+        default:
+            return NULL;
+        }
+    }
+    if (   ctx->RasterMask==0   /* no depth test */
+        && ctx->Light.ShadeModel==GL_SMOOTH
+        && ctx->Polygon.StippleFlag==GL_FALSE) {
+        switch (wmesa->pixelformat) {
+        case PF_8A8B8G8R:
+            return smooth_8A8B8G8R_triangle;
+        case PF_8R8G8B:
+            return smooth_8R8G8B_triangle;
+        case PF_5R6G5B:
+            return smooth_5R6G5B_triangle;
+        case PF_DITHER8:
+            return smooth_DITHER8_triangle;
+        case PF_INDEX8:
+            return smooth_ci_triangle;
+        default:
+            return NULL;
+        }
+    }
+
+    if (   ctx->RasterMask==0   /* no depth test */
+        && ctx->Light.ShadeModel==GL_FLAT
+        && ctx->Polygon.StippleFlag==GL_FALSE) {
+        switch (wmesa->pixelformat) {
+        case PF_8A8B8G8R:
+            return flat_8A8B8G8R_triangle;
+        case PF_8R8G8B:
+            return flat_8R8G8B_triangle;
+        case PF_5R6G5B:
+            return flat_5R6G5B_triangle;
+        case PF_DITHER8:
+            return flat_DITHER8_triangle;
+        case PF_INDEX8:
+            return flat_ci_triangle;
+        default:
+            return NULL;
+        }
+    }
+
+    return NULL;
+    }
+}
+
+/*
+* Define a new viewport and reallocate auxillary buffers if the size of
+* the window (color buffer) has changed.
+*/
+void WMesaViewport( GLcontext *ctx,
+                   GLint x, GLint y, GLsizei width, GLsizei height )
+{
+    /* Save viewport */
+    ctx->Viewport.X = x;
+    ctx->Viewport.Width = width;
+    ctx->Viewport.Y = y;
+    ctx->Viewport.Height = height;
+
+    /* compute scale and bias values */
+    ctx->Viewport.Sx = (GLfloat) width / 2.0F;
+    ctx->Viewport.Tx = ctx->Viewport.Sx + x;
+    ctx->Viewport.Sy = (GLfloat) height / 2.0F;
+    ctx->Viewport.Ty = ctx->Viewport.Sy + y;
+}
diff --git a/src/mesa/drivers/windows/wmesaOld.c b/src/mesa/drivers/windows/wmesaOld.c
new file mode 100644 (file)
index 0000000..afaeece
--- /dev/null
@@ -0,0 +1,2737 @@
+/*\r
+ *     File name       :       wmesa.c\r
+ *  Version            :       2.3\r
+ *\r
+ *  Display driver for Mesa 2.3  under\r
+ *     Windows95 and WindowsNT\r
+ *\r
+ *     Copyright (C) 1996-  Li Wei\r
+ *  Address            :               Institute of Artificial Intelligence\r
+ *                             :                       & Robotics\r
+ *                             :               Xi'an Jiaotong University\r
+ *  Email              :               liwei@aiar.xjtu.edu.cn\r
+ *  Web page   :               http://sun.aiar.xjtu.edu.cn\r
+ *\r
+ *  This file and its associations are partially borrowed from the\r
+ *  Windows NT driver for Mesa 1.8 , written by Mark Leaming\r
+ *  (mark@rsinc.com).\r
+ */\r
+\r
+\r
+/*\r
+ * $Log: wmesaOld.c,v $
+ * Revision 1.1  1999/08/19 00:55:42  jtg
+ * Initial revision
+ *
+ * Revision 1.2  1999/01/03 03:08:57  brianp
+ * Ted Jump's changes
+ *\r
+ * Revision 1.0  1997/06/14 17:51:00 CST by Li Wei(liwei@aiar.xjtu.edu.cn)\r
+ * New display driver for Mesa 2.x using Microsoft Direct Draw\r
+ * Initial vision\r
+ */\r
+\r
+\r
+#define WMESA_STEREO_C\r
+\r
+#include <windows.h>\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <GL/wmesa.h>\r
+#include "wmesadef.h"\r
+#include "context.h"\r
+#include "dd.h"\r
+#include "xform.h"\r
+#include "vb.h"\r
+#include "matrix.h"\r
+#include "depth.h"\r
+\r
+#ifdef PROFILE\r
+//     #include "profile.h"\r
+#endif\r
+\r
+#ifdef DITHER\r
+       #include <wing.h>\r
+#endif\r
+\r
+#ifdef __CYGWIN32__\r
+#include "macros.h"\r
+#include <string.h>\r
+#define CopyMemory memcpy\r
+#endif\r
+#include "mesa_extend.h"\r
+#include "colors.h"\r
+\r
+#if !defined(NO_STEREO)\r
+\r
+       #include "gl\glu.h"\r
+       #include "stereo.h"\r
+\r
+#endif\r
+#if !defined(NO_PARALLEL)\r
+//     #include "parallel.h"\r
+#endif\r
+\r
+struct DISPLAY_OPTIONS displayOptions;\r
+\r
+GLenum stereoCompile = GL_FALSE ;\r
+GLenum stereoShowing  = GL_FALSE ;\r
+GLenum stereoBuffer = GL_FALSE;\r
+#if !defined(NO_STEREO)\r
+GLint displayList = MAXIMUM_DISPLAY_LIST ;\r
+#endif\r
+GLint stereo_flag = 0 ;\r
+\r
+/* end of added code*/\r
+\r
+static PWMC Current = NULL;\r
+WMesaContext WC = NULL;\r
+\r
+#ifdef NDEBUG\r
+  #define assert(ignore)       ((void) 0)\r
+#else\r
+  void Mesa_Assert(void *Cond,void *File,unsigned Line)\r
+  {\r
+    char Msg[512];\r
+    sprintf(Msg,"%s %s %d",Cond,File,Line);\r
+    MessageBox(NULL,Msg,"Assertion failed.",MB_OK);\r
+    exit(1);\r
+  }\r
+  #define assert(e)    if (!e) Mesa_Assert(#e,__FILE__,__LINE__);\r
+#endif\r
+\r
+//#define DD_GETDC (Current->hDC )\r
+#define DD_GETDC ((Current->db_flag) ? Current->dib.hDC : Current->hDC )\r
+//#define DD_GETDC ((Current->db_flag) ? Current->hDCPrimary : Current->hDCBack )\r
+#define DD_RELEASEDC\r
+\r
+//#define BEGINGDICALL if(Current->rgb_flag)wmFlushBits(Current);\r
+#define BEGINGDICALL\r
+//#define ENDGDICALL           if(Current->rgb_flag)wmGetBits(Current);\r
+#define ENDGDICALL\r
+\r
+//#define FLIP(Y)  (Current->dither_flag? Y : Current->height-(Y)-1)\r
+//#define FLIP(Y)  (Current->height-(Y)-1)\r
+//#define FLIP(Y) Y\r
+#define FLIP(Y)  (Current->db_flag? Y: Current->height-(Y)-1)\r
+#define STARTPROFILE\r
+#define ENDPROFILE(PARA)\r
+\r
+#define DITHER_RGB_TO_8BIT_SETUP                       \\r
+               GLubyte pixelDithered;\r
+\r
+#define DITHER_RGB_TO_8BIT(red, green, blue, pixel, scanline)                          \\r
+{                                                                                                                                                      \\r
+       char unsigned redtemp, greentemp, bluetemp, paletteindex;                               \\r
+    redtemp = aDividedBy51[red]                                                                                                \\r
+          + (aModulo51[red] > aHalftone8x8[(pixel%8)*8                                         \\r
+          + scanline%8]);                                                                                                      \\r
+    greentemp = aDividedBy51[(char unsigned)green]                                                     \\r
+          + (aModulo51[green] > aHalftone8x8[                                                          \\r
+          (pixel%8)*8 + scanline%8]);                                                                          \\r
+    bluetemp = aDividedBy51[(char unsigned)blue]                                                       \\r
+          + (aModulo51[blue] > aHalftone8x8[                                                           \\r
+          (pixel%8)*8 +scanline%8]);                                                                           \\r
+    paletteindex = redtemp + aTimes6[greentemp] + aTimes36[bluetemp];          \\r
+       pixelDithered = aWinGHalftoneTranslation[paletteindex];                                 \\r
+}\r
+\r
+\r
+#ifdef DDRAW\r
+       static BOOL DDInit( WMesaContext wc, HWND hwnd);\r
+       static void DDFree( WMesaContext wc);\r
+       static HRESULT DDRestoreAll( WMesaContext wc );\r
+       static void DDDeleteOffScreen(WMesaContext wc);\r
+       static BOOL DDCreateOffScreen(WMesaContext wc);\r
+#endif\r
+\r
+static void FlushToFile(PWMC pwc, PSTR szFile);\r
+\r
+BOOL wmCreateBackingStore(PWMC pwc, long lxSize, long lySize);\r
+BOOL wmDeleteBackingStore(PWMC pwc);\r
+void wmCreatePalette( PWMC pwdc );\r
+BOOL wmSetDibColors(PWMC pwc);\r
+void wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b);\r
+\r
+void wmCreateDIBSection(\r
+       HDC      hDC,\r
+    PWMC pwc,  // handle of device context\r
+    CONST BITMAPINFO *pbmi,    // address of structure containing bitmap size, format, and color data\r
+    UINT iUsage        // color data type indicator: RGB values or palette indices\r
+    );\r
+\r
+\r
+void WMesaViewport( GLcontext *ctx,\r
+                  GLint x, GLint y, GLsizei width, GLsizei height );\r
+\r
+static triangle_func choose_triangle_function( GLcontext *ctx );\r
+\r
+static void wmSetPixelFormat( PWMC wc, HDC hDC)\r
+{\r
+       if(wc->rgb_flag)\r
+               wc->cColorBits = GetDeviceCaps(hDC, BITSPIXEL);\r
+       else\r
+           wc->cColorBits = 8;\r
+       switch(wc->cColorBits){\r
+               case 8:\r
+                       if(wc->dither_flag != GL_TRUE)\r
+                               wc->pixelformat = PF_INDEX8;\r
+                       else\r
+                               wc->pixelformat = PF_DITHER8;\r
+                       break;\r
+               case 16:\r
+                       wc->pixelformat = PF_5R6G5B;\r
+                       break;\r
+               case 32:\r
+                       wc->pixelformat = PF_8R8G8B;\r
+                       break;\r
+               default:\r
+                       wc->pixelformat = PF_BADFORMAT;\r
+       }\r
+}\r
+\r
+//\r
+// This function sets the color table of a DIB section\r
+// to match that of the destination DC\r
+//\r
+BOOL /*WINAPI*/ wmSetDibColors(PWMC pwc)\r
+{\r
+    RGBQUAD                    *pColTab, *pRGB;\r
+    PALETTEENTRY       *pPal, *pPE;\r
+    int                                i, nColors;\r
+       BOOL                    bRet=TRUE;\r
+       DWORD                   dwErr=0;\r
+\r
+    /* Build a color table in the DIB that maps to the\r
+       selected palette in the DC.\r
+       */\r
+    nColors = 1 << pwc->cColorBits;\r
+       pPal = (PALETTEENTRY *)malloc( nColors * sizeof(PALETTEENTRY));\r
+    memset( pPal, 0, nColors * sizeof(PALETTEENTRY) );\r
+    GetPaletteEntries( pwc->hGLPalette, 0, nColors, pPal );\r
+    pColTab = (RGBQUAD *)malloc( nColors * sizeof(RGBQUAD));\r
+    for (i = 0, pRGB = pColTab, pPE = pPal; i < nColors; i++, pRGB++, pPE++) {\r
+        pRGB->rgbRed = pPE->peRed;\r
+        pRGB->rgbGreen = pPE->peGreen;\r
+        pRGB->rgbBlue = pPE->peBlue;\r
+    }\r
+       if(pwc->db_flag)\r
+           bRet = SetDIBColorTable(pwc->dib.hDC, 0, nColors, pColTab );\r
+\r
+       if(!bRet)\r
+               dwErr = GetLastError();\r
+\r
+    free( pColTab );\r
+    free( pPal );\r
+\r
+       return(bRet);\r
+}\r
+\r
+\r
+//\r
+// Free up the dib section that was created\r
+//\r
+BOOL wmDeleteBackingStore(PWMC pwc)\r
+{\r
+       SelectObject(pwc->dib.hDC, pwc->hOldBitmap);\r
+       DeleteDC(pwc->dib.hDC);\r
+       DeleteObject(pwc->hbmDIB);\r
+       UnmapViewOfFile(pwc->dib.base);\r
+       CloseHandle(pwc->dib.hFileMap);\r
+       return TRUE;\r
+}\r
+\r
+\r
+//\r
+// This function creates the DIB section that is used for combined\r
+// GL and GDI calls\r
+//\r
+BOOL /*WINAPI*/ wmCreateBackingStore(PWMC pwc, long lxSize, long lySize)\r
+{\r
+    HDC hdc = pwc->hDC;\r
+    LPBITMAPINFO pbmi = &(pwc->bmi);\r
+       int             iUsage;\r
+\r
+    pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);\r
+    pbmi->bmiHeader.biWidth = lxSize;\r
+    pbmi->bmiHeader.biHeight= -lySize;\r
+    pbmi->bmiHeader.biPlanes = 1;\r
+       if(pwc->rgb_flag)\r
+               pbmi->bmiHeader.biBitCount = GetDeviceCaps(pwc->hDC, BITSPIXEL);\r
+       else\r
+               pbmi->bmiHeader.biBitCount = 8;\r
+    pbmi->bmiHeader.biCompression = BI_RGB;\r
+    pbmi->bmiHeader.biSizeImage = 0;\r
+    pbmi->bmiHeader.biXPelsPerMeter = 0;\r
+    pbmi->bmiHeader.biYPelsPerMeter = 0;\r
+    pbmi->bmiHeader.biClrUsed = 0;\r
+    pbmi->bmiHeader.biClrImportant = 0;\r
+\r
+       iUsage = (pbmi->bmiHeader.biBitCount <= 8) ? DIB_PAL_COLORS : DIB_RGB_COLORS;\r
+\r
+       pwc->cColorBits = pbmi->bmiHeader.biBitCount;\r
+       pwc->ScanWidth = pwc->pitch = lxSize;\r
+\r
+       wmCreateDIBSection(hdc, pwc, pbmi, iUsage);\r
+\r
+       if ((iUsage == DIB_PAL_COLORS) && !(pwc->hGLPalette)) {\r
+               wmCreatePalette( pwc );\r
+               wmSetDibColors( pwc );\r
+       }\r
+       wmSetPixelFormat(pwc, pwc->hDC);\r
+       return(TRUE);\r
+\r
+}\r
+\r
+\r
+//\r
+// This function copies one scan line in a DIB section to another\r
+//\r
+BOOL GLWINAPI wmSetDIBits(PWMC pwc, UINT uiScanWidth, UINT uiNumScans, UINT nBypp, UINT uiNewWidth, LPBYTE pBits)\r
+{\r
+       UINT uiScans = 0;\r
+       LPBYTE  pDest = pwc->pbPixels;\r
+       DWORD   dwNextScan = uiScanWidth;\r
+       DWORD   dwNewScan = uiNewWidth;\r
+       DWORD   dwScanWidth = (uiScanWidth * nBypp);\r
+\r
+       //\r
+       // We need to round up to the nearest DWORD\r
+       // and multiply by the number of bytes per\r
+       // pixel\r
+       //\r
+       dwNextScan = (((dwNextScan * nBypp)+ 3) & ~3);\r
+       dwNewScan = (((dwNewScan * nBypp)+ 3) & ~3);\r
+\r
+       for(uiScans = 0; uiScans < uiNumScans; uiScans++){\r
+               CopyMemory(pDest, pBits, dwScanWidth);\r
+               pBits += dwNextScan;\r
+               pDest += dwNewScan;\r
+       }\r
+\r
+       return(TRUE);\r
+\r
+}\r
+\r
+\r
+BOOL wmFlush(PWMC pwc);\r
+\r
+/*\r
+ * Useful macros:\r
+   Modified from file osmesa.c\r
+ */\r
+\r
+\r
+#define PIXELADDR(X,Y)  ((GLubyte *)Current->pbPixels + (Current->height-Y-1)* Current->ScanWidth + (X)*nBypp)\r
+#define PIXELADDR1( X, Y )  \\r
+       ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X))\r
+#define PIXELADDR2( X, Y )  \\r
+       ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*2)\r
+#define PIXELADDR4( X, Y )  \\r
+       ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*4)\r
+\r
+\r
+BYTE DITHER_RGB_2_8BIT( int r, int g, int b, int x, int y);\r
+\r
+/* Finish all pending operations and synchronize. */\r
+static void finish(GLcontext* ctx)\r
+{\r
+ /* No op */\r
+}\r
+\r
+\r
+//\r
+// We cache all gl draw routines until a flush is made\r
+//\r
+static void flush(GLcontext* ctx)\r
+{\r
+       STARTPROFILE\r
+       if((Current->rgb_flag /*&& !(Current->dib.fFlushed)*/&&!(Current->db_flag))\r
+               ||(!Current->rgb_flag))\r
+       {\r
+               wmFlush(Current);\r
+       }\r
+       ENDPROFILE(flush)\r
+\r
+}\r
+\r
+\r
+\r
+/*\r
+ * Set the color index used to clear the color buffer.\r
+ */\r
+static void clear_index(GLcontext* ctx, GLuint index)\r
+{\r
+  STARTPROFILE\r
+  Current->clearpixel = index;\r
+  ENDPROFILE(clear_index)\r
+}\r
+\r
+\r
+\r
+/*\r
+ * Set the color used to clear the color buffer.\r
+ */\r
+static void clear_color( GLcontext* ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )\r
+{\r
+  STARTPROFILE\r
+  Current->clearpixel=RGB(r, g, b );\r
+  ENDPROFILE(clear_color)\r
+}\r
+\r
+\r
+\r
+/*\r
+ * Clear the specified region of the color buffer using the clear color\r
+ * or index as specified by one of the two functions above.\r
+ */\r
+static void clear(GLcontext* ctx,\r
+                                 GLboolean all,GLint x, GLint y, GLint width, GLint height )\r
+{\r
+       DWORD   dwColor;\r
+       WORD    wColor;\r
+       BYTE    bColor;\r
+       LPDWORD lpdw = (LPDWORD)Current->pbPixels;\r
+       LPWORD  lpw = (LPWORD)Current->pbPixels;\r
+       LPBYTE  lpb = Current->pbPixels;\r
+       int             lines;\r
+\r
+    STARTPROFILE\r
+\r
+       if (all){\r
+               x=y=0;\r
+               width=Current->width;\r
+               height=Current->height;\r
+       }\r
+       if(Current->db_flag==GL_TRUE){\r
+               UINT    nBypp = Current->cColorBits / 8;\r
+               int             i = 0;\r
+               int             iSize;\r
+\r
+               if(nBypp ==1 ){\r
+                       /* Need rectification */\r
+                       iSize = Current->width/4;\r
+                       bColor  = BGR8(GetRValue(Current->clearpixel),\r
+                                                  GetGValue(Current->clearpixel),\r
+                                                  GetBValue(Current->clearpixel));\r
+                       wColor  = MAKEWORD(bColor,bColor);\r
+                       dwColor = MAKELONG(wColor, wColor);\r
+               }\r
+               if(nBypp == 2){\r
+                       iSize = Current->width / 2;\r
+                       wColor = BGR16(GetRValue(Current->clearpixel),\r
+                                                  GetGValue(Current->clearpixel),\r
+                                                  GetBValue(Current->clearpixel));\r
+                       dwColor = MAKELONG(wColor, wColor);\r
+               }\r
+               else if(nBypp == 4){\r
+                       iSize = Current->width;\r
+                       dwColor = BGR32(GetRValue(Current->clearpixel),\r
+                                                  GetGValue(Current->clearpixel),\r
+                                                  GetBValue(Current->clearpixel));\r
+               }\r
+\r
+               while(i < iSize){\r
+                       *lpdw = dwColor;\r
+                       lpdw++;\r
+                       i++;\r
+               }\r
+\r
+               //\r
+               // This is the 24bit case\r
+               //\r
+               if (nBypp == 3) {\r
+                       iSize = Current->width *3/4;\r
+                       dwColor = BGR24(GetRValue(Current->clearpixel),\r
+                                                  GetGValue(Current->clearpixel),\r
+                                                  GetBValue(Current->clearpixel));\r
+                       while(i < iSize){\r
+                               *lpdw = dwColor;\r
+                               lpb += nBypp;\r
+                               lpdw = (LPDWORD)lpb;\r
+                               i++;\r
+                       }\r
+               }\r
+\r
+               i = 0;\r
+               if(stereo_flag) lines = height /2;\r
+               else lines = height;\r
+               do{\r
+                       lpb += Current->ScanWidth;\r
+                       memcpy(lpb, Current->pbPixels, iSize*4);\r
+                       i++;\r
+               }\r
+               while(i<lines-1);\r
+       }\r
+       else{ // For single buffer\r
+                HDC DC=DD_GETDC;\r
+                HPEN Pen=CreatePen(PS_SOLID,1,Current->clearpixel);\r
+                HBRUSH Brush=CreateSolidBrush(Current->clearpixel);\r
+                HPEN Old_Pen=SelectObject(DC,Pen);\r
+                HBRUSH Old_Brush=SelectObject(DC,Brush);\r
+                Rectangle(DC,x,y,x+width,y+height);\r
+                SelectObject(DC,Old_Pen);\r
+                SelectObject(DC,Old_Brush);\r
+                DeleteObject(Pen);\r
+                DeleteObject(Brush);\r
+                DD_RELEASEDC;\r
+       }\r
+\r
+\r
+\r
+       ENDPROFILE(clear)\r
+}\r
+\r
+\r
+\r
+/* Set the current color index. */\r
+static void set_index(GLcontext* ctx, GLuint index)\r
+{\r
+  STARTPROFILE\r
+  Current->pixel=index;\r
+  ENDPROFILE(set_index)\r
+}\r
+\r
+\r
+\r
+/* Set the current RGBA color. */\r
+static void set_color( GLcontext* ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )\r
+{\r
+  STARTPROFILE\r
+  Current->pixel = RGB( r, g, b );\r
+  ENDPROFILE(set_color)\r
+}\r
+\r
+\r
+\r
+/* Set the index mode bitplane mask. */\r
+static GLboolean index_mask(GLcontext* ctx, GLuint mask)\r
+{\r
+   /* can't implement */\r
+   return GL_FALSE;\r
+}\r
+\r
+\r
+\r
+/* Set the RGBA drawing mask. */\r
+static GLboolean color_mask( GLcontext* ctx,\r
+                                                        GLboolean rmask, GLboolean gmask,\r
+                                                        GLboolean bmask, GLboolean amask)\r
+{\r
+   /* can't implement */\r
+   return GL_FALSE;\r
+}\r
+\r
+\r
+\r
+/*\r
+ * Set the pixel logic operation.  Return GL_TRUE if the device driver\r
+ * can perform the operation, otherwise return GL_FALSE.  If GL_FALSE\r
+ * is returned, the logic op will be done in software by Mesa.\r
+ */\r
+GLboolean logicop( GLcontext* ctx, GLenum op )\r
+{\r
+   /* can't implement */\r
+   return GL_FALSE;\r
+}\r
+\r
+\r
+static void dither( GLcontext* ctx, GLboolean enable )\r
+{\r
+       if(enable == GL_FALSE){\r
+          Current->dither_flag = GL_FALSE;\r
+          if(Current->cColorBits == 8)\r
+                  Current->pixelformat = PF_INDEX8;\r
+   }\r
+   else{\r
+          if (Current->rgb_flag && Current->cColorBits == 8){\r
+                  Current->pixelformat = PF_DITHER8;\r
+                  Current->dither_flag = GL_TRUE;\r
+          }\r
+          else\r
+                  Current->dither_flag = GL_FALSE;\r
+   }\r
+}\r
+\r
+\r
+\r
+static GLboolean set_buffer( GLcontext* ctx, GLenum mode )\r
+{\r
+   STARTPROFILE\r
+   /* TODO: this could be better */\r
+   if (mode==GL_FRONT || mode==GL_BACK) {\r
+      return GL_TRUE;\r
+   }\r
+   else {\r
+      return GL_FALSE;\r
+   }\r
+   ENDPROFILE(set_buffer)\r
+}\r
+\r
+\r
+\r
+/* Return characteristics of the output buffer. */\r
+static void buffer_size( GLcontext* ctx, GLuint *width, GLuint *height /*, GLuint *depth */)\r
+{\r
+\r
+       int New_Size;\r
+       RECT CR;\r
+\r
+       STARTPROFILE\r
+       GetClientRect(Current->Window,&CR);\r
+\r
+       *width=CR.right;\r
+       *height=CR.bottom;\r
+//     *depth = Current->depth;\r
+\r
+       New_Size=((*width)!=Current->width) || ((*height)!=Current->height);\r
+\r
+       if (New_Size){\r
+               Current->width=*width;\r
+               Current->height=*height;\r
+               Current->ScanWidth=Current->width;\r
+           if ((Current->ScanWidth%sizeof(long))!=0)\r
+                       Current->ScanWidth+=(sizeof(long)-(Current->ScanWidth%sizeof(long)));\r
+\r
+               if (Current->db_flag){\r
+#ifdef DDRAW\r
+                       DDDeleteOffScreen(Current);\r
+                       DDCreateOffScreen(Current);\r
+#else\r
+               if (Current->rgb_flag==GL_TRUE && Current->dither_flag!=GL_TRUE){\r
+                               wmDeleteBackingStore(Current);\r
+                               wmCreateBackingStore(Current, Current->width, Current->height);\r
+                       }\r
+#endif\r
+                       }\r
+\r
+//     Resize OsmesaBuffer if in Parallel mode\r
+#if !defined(NO_PARALLEL)\r
+                       if(parallelFlag)\r
+                       PRSizeRenderBuffer(Current->width, Current->height,Current->ScanWidth,\r
+                       Current->rgb_flag == GL_TRUE ? Current->pbPixels: Current->ScreenMem);\r
+#endif\r
+               }\r
+   ENDPROFILE(buffer_size)\r
+}\r
+\r
+\r
+\r
+/**********************************************************************/\r
+/*****           Accelerated point, line, polygon rendering       *****/\r
+/**********************************************************************/\r
+\r
+\r
+static void fast_rgb_points( GLcontext* ctx, GLuint first, GLuint last )\r
+{\r
+   GLuint i;\r
+ //  HDC DC=DD_GETDC;\r
+       PWMC    pwc = Current;\r
+\r
+       STARTPROFILE\r
+\r
+       if (Current->gl_ctx->VB->MonoColor) {\r
+      /* all drawn with current color */\r
+      for (i=first;i<=last;i++) {\r
+         if (!Current->gl_ctx->VB->ClipMask[i]) {\r
+            int x, y;\r
+            x =       (GLint) Current->gl_ctx->VB->Win[i][0];\r
+            y = FLIP( (GLint) Current->gl_ctx->VB->Win[i][1] );\r
+                       wmSetPixel(pwc, y,x,GetRValue(Current->pixel),\r
+                                           GetGValue(Current->pixel), GetBValue(Current->pixel));\r
+         }\r
+      }\r
+   }\r
+   else {\r
+      /* draw points of different colors */\r
+      for (i=first;i<=last;i++) {\r
+         if (!Current->gl_ctx->VB->ClipMask[i]) {\r
+            int x, y;\r
+            unsigned long pixel=RGB(Current->gl_ctx->VB->Color[i][0]*255.0,\r
+                                    Current->gl_ctx->VB->Color[i][1]*255.0,\r
+                                    Current->gl_ctx->VB->Color[i][2]*255.0);\r
+            x =       (GLint) Current->gl_ctx->VB->Win[i][0];\r
+            y = FLIP( (GLint) Current->gl_ctx->VB->Win[i][1] );\r
+                       wmSetPixel(pwc, y,x,Current->gl_ctx->VB->Color[i][0]*255.0,\r
+                                    Current->gl_ctx->VB->Color[i][1]*255.0,\r
+                                    Current->gl_ctx->VB->Color[i][2]*255.0);\r
+         }\r
+      }\r
+   }\r
+//   DD_RELEASEDC;\r
+   ENDPROFILE(fast_rgb_points)\r
+}\r
+\r
+\r
+\r
+/* Return pointer to accerated points function */\r
+extern points_func choose_points_function( GLcontext* ctx )\r
+{\r
+   STARTPROFILE\r
+   if (ctx->Point.Size==1.0 && !ctx->Point.SmoothFlag && ctx->RasterMask==0\r
+       && !ctx->Texture.Enabled  && ctx->Visual->RGBAflag) {\r
+   ENDPROFILE(choose_points_function)\r
+      return fast_rgb_points;\r
+   }\r
+   else {\r
+   ENDPROFILE(choose_points_function)\r
+      return NULL;\r
+   }\r
+}\r
+\r
+\r
+\r
+/* Draw a line using the color specified by Current->gl_ctx->VB->Color[pv] */\r
+static void fast_flat_rgb_line( GLcontext* ctx, GLuint v0, GLuint v1, GLuint pv )\r
+{\r
+       STARTPROFILE\r
+       int x0, y0, x1, y1;\r
+       unsigned long pixel;\r
+       HDC DC=DD_GETDC;\r
+       HPEN Pen;\r
+       HPEN Old_Pen;\r
+\r
+       if (Current->gl_ctx->VB->MonoColor) {\r
+         pixel = Current->pixel;  /* use current color */\r
+       }\r
+       else {\r
+         pixel = RGB(Current->gl_ctx->VB->Color[pv][0]*255.0, Current->gl_ctx->VB->Color[pv][1]*255.0, Current->gl_ctx->VB->Color[pv][2]*255.0);\r
+       }\r
+\r
+       x0 =       (int) Current->gl_ctx->VB->Win[v0][0];\r
+       y0 = FLIP( (int) Current->gl_ctx->VB->Win[v0][1] );\r
+       x1 =       (int) Current->gl_ctx->VB->Win[v1][0];\r
+       y1 = FLIP( (int) Current->gl_ctx->VB->Win[v1][1] );\r
+\r
+\r
+       BEGINGDICALL\r
+\r
+       Pen=CreatePen(PS_SOLID,1,pixel);\r
+       Old_Pen=SelectObject(DC,Pen);\r
+       MoveToEx(DC,x0,y0,NULL);\r
+       LineTo(DC,x1,y1);\r
+       SelectObject(DC,Old_Pen);\r
+       DeleteObject(Pen);\r
+       DD_RELEASEDC;\r
+\r
+       ENDGDICALL\r
+\r
+       ENDPROFILE(fast_flat_rgb_line)\r
+}\r
+\r
+\r
+\r
+/* Return pointer to accerated line function */\r
+static line_func choose_line_function( GLcontext* ctx )\r
+{\r
+       STARTPROFILE\r
+   if (ctx->Line.Width==1.0 && !ctx->Line.SmoothFlag && !ctx->Line.StippleFlag\r
+       && ctx->Light.ShadeModel==GL_FLAT && ctx->RasterMask==0\r
+       && !ctx->Texture.Enabled && Current->rgb_flag) {\r
+   ENDPROFILE(choose_line_function)\r
+      return fast_flat_rgb_line;\r
+   }\r
+   else {\r
+   ENDPROFILE(choose_line_function)\r
+      return NULL;\r
+   }\r
+}\r
+\r
+\r
+/**********************************************************************/\r
+/*****                 Span-based pixel drawing                   *****/\r
+/**********************************************************************/\r
+\r
+\r
+/* Write a horizontal span of color-index pixels with a boolean mask. */\r
+static void write_index_span( GLcontext* ctx,\r
+                                                         GLuint n, GLint x, GLint y,\r
+                                                         const GLuint index[],\r
+                              const GLubyte mask[] )\r
+{\r
+         STARTPROFILE\r
+         GLuint i;\r
+         PBYTE Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;\r
+         assert(Current->rgb_flag==GL_FALSE);\r
+         for (i=0; i<n; i++)\r
+               if (mask[i])\r
+                 Mem[i]=index[i];\r
+          ENDPROFILE(write_index_span)\r
+}\r
+\r
+\r
+\r
+/*\r
+ * Write a horizontal span of pixels with a boolean mask.  The current\r
+ * color index is used for all pixels.\r
+ */\r
+static void write_monoindex_span(GLcontext* ctx,\r
+                                                                GLuint n,GLint x,GLint y,\r
+                                                                const GLubyte mask[])\r
+{\r
+         STARTPROFILE\r
+         GLuint i;\r
+         BYTE *Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;\r
+         assert(Current->rgb_flag==GL_FALSE);\r
+         for (i=0; i<n; i++)\r
+               if (mask[i])\r
+                 Mem[i]=Current->pixel;\r
+         ENDPROFILE(write_monoindex_span)\r
+}\r
+\r
+/*\r
+       To improve the performance of this routine, frob the data into an actual scanline\r
+       and call bitblt on the complete scan line instead of SetPixel.\r
+*/\r
+\r
+/* Write a horizontal span of color pixels with a boolean mask. */\r
+static void write_color_span( GLcontext* ctx,\r
+                         GLuint n, GLint x, GLint y,\r
+                         const GLubyte\r
+                         red[], const GLubyte green[],\r
+                         const GLubyte blue[], const GLubyte alpha[],\r
+                         const GLubyte mask[] )\r
+{\r
+       STARTPROFILE\r
+\r
+       PWMC    pwc = Current;\r
+\r
+       if (pwc->rgb_flag==GL_TRUE)\r
+       {\r
+               GLuint i;\r
+               HDC DC=DD_GETDC;\r
+               y=FLIP(y);\r
+\r
+               if (mask) {\r
+                       for (i=0; i<n; i++)\r
+                               if (mask[i])\r
+                                       wmSetPixel(pwc, y, x + i,red[i], green[i], blue[i]);\r
+               }\r
+\r
+               else {\r
+                       for (i=0; i<n; i++)\r
+                               wmSetPixel(pwc, y, x + i, red[i], green[i], blue[i]);\r
+               }\r
+\r
+               DD_RELEASEDC;\r
+\r
+       }\r
+\r
+  else\r
+  {\r
+               GLuint i;\r
+               BYTE *Mem=Current->ScreenMem+y*Current->ScanWidth+x;\r
+               y=FLIP(y);\r
+               if (mask) {\r
+                  for (i=0; i<n; i++)\r
+                        if (mask[i])\r
+                          Mem[i]=GetNearestPaletteIndex(Current->hPal,RGB(red[i],green[i],blue[i]));\r
+               }\r
+               else {\r
+                  for (i=0; i<n; i++)\r
+                        Mem[i]=GetNearestPaletteIndex(Current->hPal,RGB(red[i],green[i],blue[i]));\r
+                       }\r
+       }\r
+   ENDPROFILE(write_color_span)\r
+\r
+}\r
+\r
+/*\r
+ * Write a horizontal span of pixels with a boolean mask.  The current color\r
+ * is used for all pixels.\r
+ */\r
+static void write_monocolor_span( GLcontext* ctx,\r
+                                                                 GLuint n, GLint x, GLint y,\r
+                                                                 const GLubyte mask[])\r
+{\r
+  STARTPROFILE\r
+  GLuint i;\r
+  HDC DC=DD_GETDC;\r
+  PWMC pwc = Current;\r
+\r
+  assert(Current->rgb_flag==GL_TRUE);\r
+  y=FLIP(y);\r
+\r
+  if(Current->rgb_flag==GL_TRUE){\r
+         for (i=0; i<n; i++)\r
+               if (mask[i])\r
+// Trying\r
+               wmSetPixel(pwc,y,x+i,GetRValue(Current->pixel), GetGValue(Current->pixel), GetBValue(Current->pixel));\r
+  }\r
+  else {\r
+         for (i=0; i<n; i++)\r
+               if (mask[i])\r
+                       SetPixel(DC, y, x+i, Current->pixel);\r
+  }\r
+\r
+       DD_RELEASEDC;\r
+\r
+       ENDPROFILE(write_monocolor_span)\r
+}\r
+\r
+\r
+\r
+/**********************************************************************/\r
+/*****                   Array-based pixel drawing                *****/\r
+/**********************************************************************/\r
+\r
+\r
+/* Write an array of pixels with a boolean mask. */\r
+static void write_index_pixels( GLcontext* ctx,\r
+                                                           GLuint n, const GLint x[], const GLint y[],\r
+                                                               const GLuint index[], const GLubyte mask[] )\r
+{\r
+   STARTPROFILE\r
+   GLuint i;\r
+   assert(Current->rgb_flag==GL_FALSE);\r
+   for (i=0; i<n; i++) {\r
+      if (mask[i]) {\r
+         BYTE *Mem=Current->ScreenMem+FLIP(y[i])*Current->ScanWidth+x[i];\r
+                  *Mem = index[i];\r
+      }\r
+   }\r
+   ENDPROFILE(write_index_pixels)\r
+}\r
+\r
+\r
+\r
+/*\r
+ * Write an array of pixels with a boolean mask.  The current color\r
+ * index is used for all pixels.\r
+ */\r
+static void write_monoindex_pixels( GLcontext* ctx,\r
+                                                                   GLuint n,\r
+                                                                       const GLint x[], const GLint y[],\r
+                                    const GLubyte mask[] )\r
+{\r
+   STARTPROFILE\r
+   GLuint i;\r
+   assert(Current->rgb_flag==GL_FALSE);\r
+   for (i=0; i<n; i++) {\r
+      if (mask[i]) {\r
+         BYTE *Mem=Current->ScreenMem+FLIP(y[i])*Current->ScanWidth+x[i];\r
+                       *Mem = Current->pixel;\r
+      }\r
+   }\r
+   ENDPROFILE(write_monoindex_pixels)\r
+}\r
+\r
+\r
+\r
+/* Write an array of pixels with a boolean mask. */\r
+static void write_color_pixels( GLcontext* ctx,\r
+                                                           GLuint n, const GLint x[], const GLint y[],\r
+                                                               const GLubyte r[], const GLubyte g[],\r
+                                const GLubyte b[], const GLubyte a[],\r
+                                const GLubyte mask[] )\r
+{\r
+       STARTPROFILE\r
+       GLuint i;\r
+       PWMC    pwc = Current;\r
+       HDC DC=DD_GETDC;\r
+       assert(Current->rgb_flag==GL_TRUE);\r
+       for (i=0; i<n; i++)\r
+               if (mask[i])\r
+                       wmSetPixel(pwc, FLIP(y[i]),x[i],r[i],g[i],b[i]);\r
+       DD_RELEASEDC;\r
+       ENDPROFILE(write_color_pixels)\r
+}\r
+\r
+\r
+\r
+/*\r
+ * Write an array of pixels with a boolean mask.  The current color\r
+ * is used for all pixels.\r
+ */\r
+static void write_monocolor_pixels( GLcontext* ctx,\r
+                                                                   GLuint n,\r
+                                                                       const GLint x[], const GLint y[],\r
+                                    const GLubyte mask[] )\r
+{\r
+       STARTPROFILE\r
+       GLuint i;\r
+       PWMC    pwc = Current;\r
+       HDC DC=DD_GETDC;\r
+       assert(Current->rgb_flag==GL_TRUE);\r
+       for (i=0; i<n; i++)\r
+               if (mask[i])\r
+                       wmSetPixel(pwc, FLIP(y[i]),x[i],GetRValue(Current->pixel),\r
+                                           GetGValue(Current->pixel), GetBValue(Current->pixel));\r
+       DD_RELEASEDC;\r
+       ENDPROFILE(write_monocolor_pixels)\r
+}\r
+\r
+\r
+\r
+/**********************************************************************/\r
+/*****            Read spans/arrays of pixels                     *****/\r
+/**********************************************************************/\r
+\r
+\r
+/* Read a horizontal span of color-index pixels. */\r
+static void read_index_span( GLcontext* ctx, GLuint n, GLint x, GLint y, GLuint index[])\r
+{\r
+  STARTPROFILE\r
+  GLuint i;\r
+  BYTE *Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;\r
+  assert(Current->rgb_flag==GL_FALSE);\r
+  for (i=0; i<n; i++)\r
+    index[i]=Mem[i];\r
+  ENDPROFILE(read_index_span)\r
+\r
+}\r
+\r
+\r
+\r
+\r
+/* Read an array of color index pixels. */\r
+static void read_index_pixels( GLcontext* ctx,\r
+                                                          GLuint n, const GLint x[], const GLint y[],\r
+                                                          GLuint indx[], const GLubyte mask[] )\r
+{\r
+   STARTPROFILE\r
+   GLuint i;\r
+  assert(Current->rgb_flag==GL_FALSE);\r
+  for (i=0; i<n; i++) {\r
+     if (mask[i]) {\r
+        indx[i]=*(Current->ScreenMem+FLIP(y[i])*Current->ScanWidth+x[i]);\r
+     }\r
+  }\r
+   ENDPROFILE(read_index_pixels)\r
+}\r
+\r
+\r
+\r
+/* Read a horizontal span of color pixels. */\r
+static void read_color_span( GLcontext* ctx,\r
+                                                        GLuint n, GLint x, GLint y,\r
+                                                        GLubyte red[], GLubyte green[],\r
+                             GLubyte blue[], GLubyte alpha[] )\r
+{\r
+   STARTPROFILE\r
+  UINT i;\r
+  COLORREF Color;\r
+  HDC DC=DD_GETDC;\r
+  assert(Current->rgb_flag==GL_TRUE);\r
+  y=FLIP(y);\r
+  for (i=0; i<n; i++)\r
+  {\r
+    Color=GetPixel(DC,x+i,y);\r
+    red[i]=GetRValue(Color);\r
+    green[i]=GetGValue(Color);\r
+    blue[i]=GetBValue(Color);\r
+    alpha[i]=255;\r
+  }\r
+  DD_RELEASEDC;\r
+  memset(alpha,0,n*sizeof(GLint));\r
+   ENDPROFILE(read_color_span)\r
+}\r
+\r
+\r
+/* Read an array of color pixels. */\r
+static void read_color_pixels( GLcontext* ctx,\r
+                                                          GLuint n, const GLint x[], const GLint y[],\r
+                                                          GLubyte red[], GLubyte green[],\r
+                               GLubyte blue[], GLubyte alpha[],\r
+                               const GLubyte mask[] )\r
+{\r
+   STARTPROFILE\r
+  GLuint i;\r
+  COLORREF Color;\r
+  HDC DC=DD_GETDC;\r
+  assert(Current->rgb_flag==GL_TRUE);\r
+  for (i=0; i<n; i++) {\r
+     if (mask[i]) {\r
+        Color=GetPixel(DC,x[i],FLIP(y[i]));\r
+        red[i]=GetRValue(Color);\r
+        green[i]=GetGValue(Color);\r
+        blue[i]=GetBValue(Color);\r
+        alpha[i]=255;\r
+     }\r
+  }\r
+  DD_RELEASEDC;\r
+  memset(alpha,0,n*sizeof(GLint));\r
+   ENDPROFILE(read_color_pixels)\r
+}\r
+\r
+\r
+\r
+/**********************************************************************/\r
+/**********************************************************************/\r
+\r
+\r
+\r
+void setup_DD_pointers( GLcontext* ctx )\r
+{\r
+   ctx->Driver.UpdateState = setup_DD_pointers;\r
+   ctx->Driver.GetBufferSize = buffer_size;\r
+   ctx->Driver.Finish = finish;\r
+   ctx->Driver.Flush = flush;\r
+\r
+   ctx->Driver.ClearIndex = clear_index;\r
+   ctx->Driver.ClearColor = clear_color;\r
+   ctx->Driver.Clear = clear;\r
+\r
+   ctx->Driver.Index = set_index;\r
+   ctx->Driver.Color = set_color;\r
+   ctx->Driver.IndexMask = index_mask;\r
+   ctx->Driver.ColorMask = color_mask;\r
+\r
+   ctx->Driver.LogicOp = logicop;\r
+   ctx->Driver.Dither = dither;\r
+\r
+   ctx->Driver.SetBuffer = set_buffer;\r
+   ctx->Driver.GetBufferSize = buffer_size;\r
+\r
+   ctx->Driver.PointsFunc = choose_points_function(ctx);\r
+   ctx->Driver.LineFunc = choose_line_function(ctx);\r
+   ctx->Driver.TriangleFunc = choose_triangle_function( ctx );\r
+\r
+   /* Pixel/span writing functions: */\r
+   ctx->Driver.WriteColorSpan       = write_color_span;\r
+   ctx->Driver.WriteMonocolorSpan   = write_monocolor_span;\r
+   ctx->Driver.WriteColorPixels     = write_color_pixels;\r
+   ctx->Driver.WriteMonocolorPixels = write_monocolor_pixels;\r
+   ctx->Driver.WriteIndexSpan       = write_index_span;\r
+   ctx->Driver.WriteMonoindexSpan   = write_monoindex_span;\r
+   ctx->Driver.WriteIndexPixels     = write_index_pixels;\r
+   ctx->Driver.WriteMonoindexPixels = write_monoindex_pixels;\r
+\r
+   /* Pixel/span reading functions: */\r
+   ctx->Driver.ReadIndexSpan = read_index_span;\r
+   ctx->Driver.ReadColorSpan = read_color_span;\r
+   ctx->Driver.ReadIndexPixels = read_index_pixels;\r
+   ctx->Driver.ReadColorPixels = read_color_pixels;\r
+}\r
+\r
+\r
+/**********************************************************************/\r
+/*****                  WMesa API Functions                       *****/\r
+/**********************************************************************/\r
+\r
+\r
+\r
+#define PAL_SIZE 256\r
+static void GetPalette(HPALETTE Pal,RGBQUAD *aRGB)\r
+{\r
+   STARTPROFILE\r
+       int i;\r
+       HDC hdc;\r
+       struct\r
+       {\r
+               WORD Version;\r
+               WORD NumberOfEntries;\r
+               PALETTEENTRY aEntries[PAL_SIZE];\r
+       } Palette =\r
+       {\r
+               0x300,\r
+               PAL_SIZE\r
+       };\r
+       hdc=GetDC(NULL);\r
+       if (Pal!=NULL)\r
+    GetPaletteEntries(Pal,0,PAL_SIZE,Palette.aEntries);\r
+  else\r
+    GetSystemPaletteEntries(hdc,0,PAL_SIZE,Palette.aEntries);\r
+       if (GetSystemPaletteUse(hdc) == SYSPAL_NOSTATIC)\r
+       {\r
+               for(i = 0; i <PAL_SIZE; i++)\r
+                       Palette.aEntries[i].peFlags = PC_RESERVED;\r
+               Palette.aEntries[255].peRed = 255;\r
+               Palette.aEntries[255].peGreen = 255;\r
+               Palette.aEntries[255].peBlue = 255;\r
+               Palette.aEntries[255].peFlags = 0;\r
+               Palette.aEntries[0].peRed = 0;\r
+               Palette.aEntries[0].peGreen = 0;\r
+               Palette.aEntries[0].peBlue = 0;\r
+               Palette.aEntries[0].peFlags = 0;\r
+       }\r
+       else\r
+       {\r
+               int nStaticColors;\r
+               int nUsableColors;\r
+               nStaticColors = GetDeviceCaps(hdc, NUMCOLORS)/2;\r
+               for (i=0; i<nStaticColors; i++)\r
+                       Palette.aEntries[i].peFlags = 0;\r
+               nUsableColors = PAL_SIZE-nStaticColors;\r
+               for (; i<nUsableColors; i++)\r
+                       Palette.aEntries[i].peFlags = PC_RESERVED;\r
+               for (; i<PAL_SIZE-nStaticColors; i++)\r
+                       Palette.aEntries[i].peFlags = PC_RESERVED;\r
+               for (i=PAL_SIZE-nStaticColors; i<PAL_SIZE; i++)\r
+                       Palette.aEntries[i].peFlags = 0;\r
+       }\r
+       ReleaseDC(NULL,hdc);\r
+  for (i=0; i<PAL_SIZE; i++)\r
+  {\r
+    aRGB[i].rgbRed=Palette.aEntries[i].peRed;\r
+    aRGB[i].rgbGreen=Palette.aEntries[i].peGreen;\r
+    aRGB[i].rgbBlue=Palette.aEntries[i].peBlue;\r
+    aRGB[i].rgbReserved=Palette.aEntries[i].peFlags;\r
+  }\r
+         ENDPROFILE(GetPalette)\r
+}\r
+\r
+\r
+WMesaContext WMesaCreateContext( HWND hWnd, HPALETTE* Pal,\r
+                                                                                         GLboolean rgb_flag,\r
+                                                                                         GLboolean db_flag )\r
+{\r
+  RECT CR;\r
+  WMesaContext c;\r
+  GLboolean true_color_flag;\r
+  c = (struct wmesa_context * ) calloc(1,sizeof(struct wmesa_context));\r
+  if (!c)\r
+    return NULL;\r
+\r
+  c->Window=hWnd;\r
+  c->hDC = GetDC(hWnd);\r
+  true_color_flag = GetDeviceCaps(c->hDC, BITSPIXEL) > 8;\r
+#ifdef DDRAW\r
+  if(true_color_flag) c->rgb_flag = rgb_flag = GL_TRUE;\r
+#endif\r
+\r
+\r
+#ifdef DITHER\r
+  if ((true_color_flag==GL_FALSE) && (rgb_flag == GL_TRUE)){\r
+       c->dither_flag = GL_TRUE;\r
+       c->hPalHalfTone = WinGCreateHalftonePalette();\r
+  }\r
+  else\r
+       c->dither_flag = GL_FALSE;\r
+#else\r
+       c->dither_flag = GL_FALSE;\r
+#endif\r
+\r
+\r
+  if (rgb_flag==GL_FALSE)\r
+  {\r
+    c->rgb_flag = GL_FALSE;\r
+//    c->pixel = 1;\r
+    c->db_flag = db_flag =GL_TRUE; // WinG requires double buffering\r
+       printf("Single buffer is not supported in color index mode, setting to double buffer.\n");\r
+  }\r
+  else\r
+  {\r
+    c->rgb_flag = GL_TRUE;\r
+//    c->pixel = 0;\r
+  }\r
+  GetClientRect(c->Window,&CR);\r
+  c->width=CR.right;\r
+  c->height=CR.bottom;\r
+  if (db_flag)\r
+  {\r
+    c->db_flag = 1;\r
+       /* Double buffered */\r
+#ifndef DDRAW\r
+//     if (c->rgb_flag==GL_TRUE && c->dither_flag != GL_TRUE )\r
+    {\r
+               wmCreateBackingStore(c, c->width, c->height);\r
+\r
+    }\r
+#endif\r
+  }\r
+  else\r
+  {\r
+    /* Single Buffered */\r
+       if (c->rgb_flag)\r
+         c->db_flag = 0;\r
+  }\r
+#ifdef DDRAW\r
+  if (DDInit(c,hWnd) == GL_FALSE) {\r
+               free( (void *) c );\r
+               exit(1);\r
+               }\r
+#endif\r
+\r
+\r
+  c->gl_visual = gl_create_visual(rgb_flag,\r
+                                                                 GL_FALSE,     /* software alpha */\r
+                                  db_flag,     /* db_flag */\r
+                                  16,          /* depth_bits */\r
+                                  8,           /* stencil_bits */\r
+                                  8,           /* accum_bits */\r
+                                  8,\r
+                                  255.0, 255.0, 255.0, 255.0,\r
+                                                                 8,8,8,8 );\r
+\r
+       if (!c->gl_visual) {\r
+         return NULL;\r
+      }\r
+\r
+  /* allocate a new Mesa context */\r
+  c->gl_ctx = gl_create_context( c->gl_visual, NULL,c);\r
+\r
+  if (!c->gl_ctx) {\r
+         gl_destroy_visual( c->gl_visual );\r
+         free(c);\r
+         return NULL;\r
+      }\r
+\r
+      c->gl_buffer = gl_create_framebuffer( c->gl_visual );\r
+      if (!c->gl_buffer) {\r
+         gl_destroy_visual( c->gl_visual );\r
+         gl_destroy_context( c->gl_ctx );\r
+         free(c);\r
+         return NULL;\r
+      }\r
+//  setup_DD_pointers(c->gl_ctx);\r
+\r
+  return c;\r
+}\r
+\r
+void WMesaDestroyContext( void )\r
+{\r
+       WMesaContext c = Current;\r
+       ReleaseDC(c->Window,c->hDC);\r
+       WC = c;\r
+       if(c->hPalHalfTone != NULL)\r
+               DeleteObject(c->hPalHalfTone);\r
+    gl_destroy_visual( c->gl_visual );\r
+    gl_destroy_framebuffer( c->gl_buffer );\r
+       gl_destroy_context( c->gl_ctx );\r
+\r
+       if (c->db_flag)\r
+#ifdef DDRAW\r
+               DDFree(c);\r
+#else\r
+               wmDeleteBackingStore(c);\r
+#endif\r
+       free( (void *) c );\r
+//Following code is added to enable parallel render\r
+// Parallel render only work in double buffer mode\r
+#if !defined(NO_PARALLEL)\r
+       if(parallelMachine)\r
+               PRDestroyRenderBuffer();\r
+#endif\r
+// End modification\r
+}\r
+\r
+\r
+\r
+void /*APIENTRY*/ WMesaMakeCurrent( WMesaContext c )\r
+{\r
+       if(!c){\r
+               Current = c;\r
+               return;\r
+       }\r
+\r
+       //\r
+       // A little optimization\r
+       // If it already is current,\r
+       // don't set it again\r
+       //\r
+       if(Current == c)\r
+               return;\r
+\r
+       //gl_set_context( c->gl_ctx );\r
+       gl_make_current(c->gl_ctx, c->gl_buffer);\r
+       Current = c;\r
+       setup_DD_pointers(c->gl_ctx);\r
+       if (Current->gl_ctx->Viewport.Width==0) {\r
+         /* initialize viewport to window size */\r
+         gl_Viewport( Current->gl_ctx,\r
+                          0, 0, Current->width, Current->height );\r
+       }\r
+       if ((c->cColorBits <= 8 ) && (c->rgb_flag == GL_TRUE)){\r
+                       WMesaPaletteChange(c->hPalHalfTone);\r
+       }\r
+}\r
+\r
+\r
+\r
+void /*APIENTRY*/ WMesaSwapBuffers( void )\r
+{\r
+  HDC DC = Current->hDC;\r
+  if (Current->db_flag)\r
+       wmFlush(Current);\r
+}\r
+\r
+\r
+\r
+void /*APIENTRY*/ WMesaPaletteChange(HPALETTE Pal)\r
+{\r
+  int vRet;\r
+  LPPALETTEENTRY pPal;\r
+  if (Current && (Current->rgb_flag==GL_FALSE || Current->dither_flag == GL_TRUE))\r
+  {\r
+       pPal = (PALETTEENTRY *)malloc( 256 * sizeof(PALETTEENTRY));\r
+       Current->hPal=Pal;\r
+//     GetPaletteEntries( Pal, 0, 256, pPal );\r
+       GetPalette( Pal, pPal );\r
+#ifdef DDRAW\r
+       Current->lpDD->lpVtbl->CreatePalette(Current->lpDD,DDPCAPS_8BIT,\r
+               pPal, &(Current->lpDDPal), NULL);\r
+       if (Current->lpDDPal)\r
+        Current->lpDDSPrimary->lpVtbl->SetPalette(Current->lpDDSPrimary,Current->lpDDPal);\r
+#else\r
+    vRet = SetDIBColorTable(Current->dib.hDC,0,256,pPal);\r
+#endif\r
+       free( pPal );\r
+  }\r
+\r
+}\r
+\r
+\r
+\r
+\r
+static unsigned char threeto8[8] = {\r
+       0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377\r
+};\r
+\r
+static unsigned char twoto8[4] = {\r
+       0, 0x55, 0xaa, 0xff\r
+};\r
+\r
+static unsigned char oneto8[2] = {\r
+       0, 255\r
+};\r
+\r
+static unsigned char componentFromIndex(UCHAR i, UINT nbits, UINT shift)\r
+{\r
+       unsigned char val;\r
+\r
+       val = i >> shift;\r
+       switch (nbits) {\r
+\r
+               case 1:\r
+                       val &= 0x1;\r
+                       return oneto8[val];\r
+\r
+               case 2:\r
+                       val &= 0x3;\r
+                       return twoto8[val];\r
+\r
+               case 3:\r
+                       val &= 0x7;\r
+                       return threeto8[val];\r
+\r
+               default:\r
+                       return 0;\r
+       }\r
+}\r
+\r
+void /*WINAPI*/ wmCreatePalette( PWMC pwdc )\r
+{\r
+    /* Create a compressed and re-expanded 3:3:2 palette */\r
+       int            i;\r
+       LOGPALETTE     *pPal;\r
+    BYTE           rb, rs, gb, gs, bb, bs;\r
+\r
+    pwdc->nColors = 0x100;\r
+\r
+       pPal = (PLOGPALETTE)malloc(sizeof(LOGPALETTE) + pwdc->nColors * sizeof(PALETTEENTRY));\r
+    memset( pPal, 0, sizeof(LOGPALETTE) + pwdc->nColors * sizeof(PALETTEENTRY) );\r
+\r
+       pPal->palVersion = 0x300;\r
+\r
+    rb = REDBITS;\r
+    rs = REDSHIFT;\r
+    gb = GREENBITS;\r
+    gs = GREENSHIFT;\r
+    bb = BLUEBITS;\r
+    bs = BLUESHIFT;\r
+\r
+    if (pwdc->db_flag) {\r
+\r
+        /* Need to make two palettes: one for the screen DC and one for the DIB. */\r
+           pPal->palNumEntries = pwdc->nColors;\r
+           for (i = 0; i < pwdc->nColors; i++) {\r
+                   pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs );\r
+                   pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs );\r
+                   pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs );\r
+                   pPal->palPalEntry[i].peFlags = 0;\r
+           }\r
+       pwdc->hGLPalette = CreatePalette( pPal );\r
+       pwdc->hPalette = CreatePalette( pPal );\r
+    }\r
+\r
+       else {\r
+           pPal->palNumEntries = pwdc->nColors;\r
+           for (i = 0; i < pwdc->nColors; i++) {\r
+                   pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs );\r
+                   pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs );\r
+                   pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs );\r
+                   pPal->palPalEntry[i].peFlags = 0;\r
+           }\r
+       pwdc->hGLPalette = CreatePalette( pPal );\r
+    }\r
+\r
+       free(pPal);\r
+\r
+}\r
+\r
+void /*WINAPI*/ wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)\r
+{\r
+       if(Current->db_flag){\r
+               LPBYTE  lpb = pwc->pbPixels;\r
+               LPDWORD lpdw;\r
+               LPWORD  lpw;\r
+               UINT    nBypp = pwc->cColorBits / 8;\r
+               UINT    nOffset = iPixel % nBypp;\r
+\r
+               // Move the pixel buffer pointer to the scanline that we\r
+               // want to access\r
+\r
+//             pwc->dib.fFlushed = FALSE;\r
+\r
+               lpb += pwc->ScanWidth * iScanLine;\r
+               // Now move to the desired pixel\r
+               lpb += iPixel * nBypp;\r
+               lpb = PIXELADDR(iPixel, iScanLine);\r
+               lpdw = (LPDWORD)lpb;\r
+               lpw = (LPWORD)lpb;\r
+\r
+               if(nBypp == 1){\r
+                       if(pwc->dither_flag)\r
+                               *lpb = DITHER_RGB_2_8BIT(r,g,b,iScanLine,iPixel);\r
+                       else\r
+                               *lpb = BGR8(r,g,b);\r
+               }\r
+               else if(nBypp == 2)\r
+                       *lpw = BGR16(r,g,b);\r
+               else if (nBypp == 3){\r
+                       *lpdw = BGR24(r,g,b);\r
+               }\r
+               else if (nBypp == 4)\r
+                       *lpdw = BGR32(r,g,b);\r
+       }\r
+       else{\r
+               HDC DC = DD_GETDC;\r
+               SetPixel(DC, iPixel, iScanLine, RGB(r,g,b));\r
+               DD_RELEASEDC;\r
+       }\r
+}\r
+\r
+void /*WINAPI*/ wmCreateDIBSection(\r
+       HDC      hDC,\r
+    PWMC pwc,  // handle of device context\r
+    CONST BITMAPINFO *pbmi,    // address of structure containing bitmap size, format, and color data\r
+    UINT iUsage        // color data type indicator: RGB values or palette indices\r
+)\r
+{\r
+       DWORD   dwSize = 0;\r
+       DWORD   dwScanWidth;\r
+       UINT    nBypp = pwc->cColorBits / 8;\r
+       HDC             hic;\r
+\r
+       dwScanWidth = (((pwc->ScanWidth * nBypp)+ 3) & ~3);\r
+\r
+       pwc->ScanWidth =pwc->pitch = dwScanWidth;\r
+\r
+       if (stereo_flag)\r
+               pwc->ScanWidth = 2* pwc->pitch;\r
+\r
+       dwSize = sizeof(BITMAPINFO) + (dwScanWidth * pwc->height);\r
+\r
+       pwc->dib.hFileMap = CreateFileMapping((HANDLE)PAGE_FILE,\r
+                                                                                 NULL,\r
+                                                                                 PAGE_READWRITE | SEC_COMMIT,\r
+                                                                                 0,\r
+                                                                                 dwSize,\r
+                                                                                 NULL);\r
+\r
+       if (!pwc->dib.hFileMap)\r
+               return;\r
+\r
+       pwc->dib.base = MapViewOfFile(pwc->dib.hFileMap,\r
+                                                                 FILE_MAP_ALL_ACCESS,\r
+                                                                 0,\r
+                                                                 0,\r
+                                                                 0);\r
+\r
+       if(!pwc->dib.base){\r
+               CloseHandle(pwc->dib.hFileMap);\r
+               return;\r
+       }\r
+\r
+//     pwc->pbPixels = pwc->addrOffScreen = ((LPBYTE)pwc->dib.base) + sizeof(BITMAPINFO);\r
+\r
+//     pwc->dib.hDC = CreateCompatibleDC(hDC);\r
+\r
+       CopyMemory(pwc->dib.base, pbmi, sizeof(BITMAPINFO));\r
+\r
+       hic = CreateIC("display", NULL, NULL, NULL);\r
+       pwc->dib.hDC = CreateCompatibleDC(hic);\r
+\r
+\r
+/*     pwc->hbmDIB = CreateDIBitmap(hic,\r
+                                                &(pwc->bmi.bmiHeader),\r
+                                                CBM_INIT,\r
+                                                pwc->pbPixels,\r
+                                                &(pwc->bmi),\r
+                                                DIB_RGB_COLORS);\r
+*/\r
+  pwc->hbmDIB = CreateDIBSection(hic,\r
+                                               &(pwc->bmi),\r
+                                               (iUsage ? DIB_PAL_COLORS : DIB_RGB_COLORS),\r
+                                               &(pwc->pbPixels),\r
+                                               pwc->dib.hFileMap,\r
+                                               0);\r
+  /*\r
+       pwc->hbmDIB = CreateDIBSection(hic,\r
+                                               &(pwc->bmi),\r
+                                               DIB_RGB_COLORS,\r
+                                               &(pwc->pbPixels),\r
+                                               pwc->dib.hFileMap,\r
+                                               0);\r
+       */\r
+       pwc->ScreenMem = pwc->addrOffScreen = pwc->pbPixels;\r
+       pwc->hOldBitmap = SelectObject(pwc->dib.hDC, pwc->hbmDIB);\r
+\r
+       DeleteDC(hic);\r
+\r
+       return;\r
+\r
+}\r
+\r
+//\r
+// Blit memory DC to screen DC\r
+//\r
+BOOL /*WINAPI*/ wmFlush(PWMC pwc)\r
+{\r
+       BOOL    bRet = 0;\r
+       DWORD   dwErr = 0;\r
+       HRESULT             ddrval;\r
+\r
+    // Now search through the torus frames and mark used colors\r
+       if(pwc->db_flag){\r
+#ifdef DDRAW\r
+               if (pwc->lpDDSOffScreen == NULL)\r
+               if(DDCreateOffScreen(pwc) == GL_FALSE)\r
+                       return;\r
+\r
+               pwc->lpDDSOffScreen->lpVtbl->Unlock(pwc->lpDDSOffScreen, NULL);\r
+\r
+               while( 1 )\r
+               {\r
+                       ddrval = pwc->lpDDSPrimary->lpVtbl->Blt( pwc->lpDDSPrimary,\r
+                                       &(pwc->rectSurface), pwc->lpDDSOffScreen, &(pwc->rectOffScreen), 0, NULL );\r
+\r
+                       if( ddrval == DD_OK )\r
+                       {\r
+                               break;\r
+                       }\r
+                       if( ddrval == DDERR_SURFACELOST )\r
+                       {\r
+                               if(!DDRestoreAll(pwc))\r
+                               {\r
+                                       break;\r
+                               }\r
+                       }\r
+                       if( ddrval != DDERR_WASSTILLDRAWING )\r
+                       {\r
+                               break;\r
+                       }\r
+               }\r
+\r
+               while (pwc->lpDDSOffScreen->lpVtbl->Lock(pwc->lpDDSOffScreen,\r
+                                               NULL, &(pwc->ddsd), 0, NULL) == DDERR_WASSTILLDRAWING)\r
+                       ;\r
+\r
+               if(ddrval != DD_OK)\r
+               dwErr = GetLastError();\r
+#else\r
+       bRet = BitBlt(pwc->hDC, 0, 0, pwc->width, pwc->height,\r
+                  pwc->dib.hDC, 0, 0, SRCCOPY);\r
+#endif\r
+       }\r
+\r
+       return(TRUE);\r
+\r
+}\r
+\r
+\r
+// The following code is added by Li Wei to enable stereo display\r
+\r
+#if !defined(NO_STEREO)\r
+\r
+void WMesaShowStereo(GLuint list)\r
+{\r
+\r
+       GLbitfield mask = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;\r
+       GLfloat cm[16];\r
+       GLint matrix_mode;\r
+       // Must use double Buffer\r
+       if( ! Current-> db_flag )\r
+               return;\r
+\r
+\r
+    glGetIntegerv(GL_MATRIX_MODE,&matrix_mode);\r
+\r
+//     glPushMatrix();  //****\r
+       WMesaViewport(Current->gl_ctx,0,Current->height/2,Current->width,Current->height/2);\r
+//     Current->gl_ctx->NewState = 0;\r
+\r
+       //      glViewport(0,0,Current->width,Current->height/2);\r
+       if(matrix_mode!=GL_MODELVIEW)\r
+        glMatrixMode(GL_MODELVIEW);\r
+\r
+       glGetFloatv(GL_MODELVIEW_MATRIX,cm);\r
+       glLoadIdentity();\r
+       gluLookAt(viewDistance/2,0.0,0.0 ,\r
+                        viewDistance/2,0.0,-1.0,\r
+                        0.0,1.0,0.0 );\r
+//     glTranslatef(viewDistance/2.0,0.,0.);\r
+       glMultMatrixf( cm );\r
+\r
+       Current->ScreenMem = Current->pbPixels = Current->addrOffScreen;\r
+       //glPushMatrix();\r
+       glCallList( list );\r
+       //glPopMatrix();\r
+\r
+    glGetFloatv(GL_MODELVIEW_MATRIX,cm);\r
+       glLoadIdentity();\r
+       gluLookAt(-viewDistance/2,0.0,0.0 ,\r
+                        -viewDistance/2,0.0,-1.0,\r
+                        0.0,1.0,0.0 );\r
+//     glTranslatef(-viewDistance/2.0,0.,0.);\r
+       glMultMatrixf(cm);\r
+\r
+       Current->ScreenMem = Current->pbPixels = Current->addrOffScreen + Current->pitch;\r
+       glCallList(list);\r
+       if(matrix_mode!=GL_MODELVIEW)\r
+               glMatrixMode(matrix_mode);\r
+\r
+//     glPopMatrix();\r
+       glFlush();\r
+\r
+       WMesaViewport(Current->gl_ctx,0,0,Current->width,Current->height);\r
+//     Current->gl_ctx->NewState = 0;\r
+       WMesaSwapBuffers();\r
+\r
+}\r
+\r
+void toggleStereoMode()\r
+{\r
+       if(!Current->db_flag)\r
+               return;\r
+       if(!stereo_flag){\r
+               stereo_flag = 1;\r
+               if(stereoBuffer==GL_FALSE)\r
+#if !defined(NO_PARALLEL)\r
+                       if(!parallelFlag)\r
+#endif\r
+               {\r
+                       Current->ScanWidth = Current->pitch*2;\r
+                       }\r
+       }\r
+       else {\r
+               stereo_flag = 0;\r
+#if !defined(NO_PARALLEL)\r
+               if(!parallelFlag)\r
+#endif\r
+               Current->ScanWidth = Current->pitch;\r
+               Current->pbPixels = Current->addrOffScreen;\r
+       }\r
+}\r
+\r
+/* if in stereo mode, the following function is called */\r
+void glShowStereo(GLuint list)\r
+{\r
+       WMesaShowStereo(list);\r
+}\r
+\r
+#endif // End if NO_STEREO not defined\r
+\r
+#if !defined(NO_PARALLEL)\r
+\r
+void toggleParallelMode(void)\r
+{\r
+       if(!parallelFlag){\r
+               parallelFlag = GL_TRUE;\r
+               if(parallelMachine==GL_FALSE){\r
+                               PRCreateRenderBuffer( Current->rgb_flag? GL_RGBA :GL_COLOR_INDEX,\r
+                                                                         Current->cColorBits/8,\r
+                                                                         Current->width ,Current->height,\r
+                                                                         Current->ScanWidth,\r
+                                                                         Current->rgb_flag? Current->pbPixels: Current->ScreenMem);\r
+                               parallelMachine = GL_TRUE;\r
+                               }\r
+               }\r
+       else {\r
+               parallelFlag = GL_FALSE;\r
+               if(parallelMachine==GL_TRUE){\r
+                               PRDestroyRenderBuffer();\r
+                               parallelMachine=GL_FALSE;\r
+                               ReadyForNextFrame = GL_TRUE;\r
+                               }\r
+\r
+/***********************************************\r
+// Seems something wrong!!!!\r
+************************************************/\r
+\r
+               WMesaMakeCurrent(Current);\r
+#if !defined(NO_STEREO)\r
+               stereo_flag = GL_FALSE ;\r
+#endif\r
+       }\r
+}\r
+\r
+void PRShowRenderResult(void)\r
+{\r
+       int flag = 0;\r
+if(!glImageRendered())\r
+               return;\r
+\r
+  if (parallelFlag)\r
+       {\r
+         WMesaSwapBuffers();\r
+        }\r
+\r
+}\r
+#endif //End if NO_PARALLEL not defined\r
+\r
+//end modification\r
+\r
+BYTE DITHER_RGB_2_8BIT( int red, int green, int blue, int pixel, int scanline)\r
+{\r
+    char unsigned redtemp, greentemp, bluetemp, paletteindex;\r
+\r
+       //*** now, look up each value in the halftone matrix\r
+    //*** using an 8x8 ordered dither.\r
+    redtemp = aDividedBy51[red]\r
+          + (aModulo51[red] > aHalftone8x8[(pixel%8)*8\r
+          + scanline%8]);\r
+    greentemp = aDividedBy51[(char unsigned)green]\r
+          + (aModulo51[green] > aHalftone8x8[\r
+          (pixel%8)*8 + scanline%8]);\r
+    bluetemp = aDividedBy51[(char unsigned)blue]\r
+          + (aModulo51[blue] > aHalftone8x8[\r
+          (pixel%8)*8 +scanline%8]);\r
+\r
+    //*** recombine the halftoned rgb values into a palette index\r
+    paletteindex =\r
+    redtemp + aTimes6[greentemp] + aTimes36[bluetemp];\r
+\r
+    //*** and translate through the wing halftone palette\r
+    //*** translation vector to give the correct value.\r
+    return aWinGHalftoneTranslation[paletteindex];\r
+}\r
+\r
+#ifdef DDRAW\r
+/*\r
+ * restoreAll\r
+ *\r
+ * restore all lost objects\r
+ */\r
+HRESULT DDRestoreAll( WMesaContext wc )\r
+{\r
+    HRESULT     ddrval;\r
+\r
+    ddrval = wc->lpDDSPrimary->lpVtbl->Restore(wc->lpDDSPrimary);\r
+    if( ddrval == DD_OK )\r
+    {\r
+        ddrval = wc->lpDDSOffScreen->lpVtbl->Restore(wc->lpDDSOffScreen);\r
+    }\r
+    return ddrval;\r
+\r
+} /* restoreAll */\r
+\r
+\r
+/*\r
+ * This function is called if the initialization function fails\r
+ */\r
+BOOL initFail( HWND hwnd, WMesaContext wc )\r
+{\r
+    DDFree(wc);\r
+    MessageBox( hwnd, "DirectDraw Init FAILED", "", MB_OK );\r
+    return FALSE;\r
+\r
+} /* initFail */\r
+\r
+\r
+static void DDDeleteOffScreen(WMesaContext wc)\r
+{\r
+               if( wc->lpDDSOffScreen != NULL )\r
+               {\r
+                       wc->lpDDSOffScreen->lpVtbl->Unlock(wc->lpDDSOffScreen,NULL);\r
+            wc->lpDDSOffScreen->lpVtbl->Release(wc->lpDDSOffScreen);\r
+            wc->lpDDSOffScreen = NULL;\r
+               }\r
+\r
+}\r
+\r
+static void DDFreePrimarySurface(WMesaContext wc)\r
+{\r
+               if( wc->lpDDSPrimary != NULL )\r
+               {\r
+                       if(wc->db_flag == GL_FALSE)\r
+                               wc->lpDDSPrimary->lpVtbl->ReleaseDC(wc->lpDDSPrimary, wc->hDC);\r
+                       wc->lpDDSPrimary->lpVtbl->Release(wc->lpDDSPrimary);\r
+            wc->lpDDSPrimary = NULL;\r
+               }\r
+}\r
+\r
+static BOOL DDCreatePrimarySurface(WMesaContext wc)\r
+{\r
+       HRESULT ddrval;\r
+       DDSCAPS             ddscaps;\r
+       wc->ddsd.dwSize = sizeof( wc->ddsd );\r
+    wc->ddsd.dwFlags = DDSD_CAPS;\r
+    wc->ddsd.ddsCaps.dwCaps =  DDSCAPS_PRIMARYSURFACE;\r
+\r
+    ddrval = wc->lpDD->lpVtbl->CreateSurface( wc->lpDD,&(wc->ddsd), &(wc->lpDDSPrimary), NULL );\r
+    if( ddrval != DD_OK )\r
+    {\r
+        return initFail(wc->hwnd , wc);\r
+    }\r
+       if(wc->db_flag == GL_FALSE)\r
+                wc->lpDDSPrimary->lpVtbl->GetDC(wc->lpDDSPrimary, wc->hDC);\r
+       return TRUE;\r
+}\r
+\r
+static BOOL DDCreateOffScreen(WMesaContext wc)\r
+{\r
+       POINT   pt;\r
+       HRESULT         ddrval;\r
+       if(wc->lpDD == NULL)\r
+               return FALSE;\r
+       GetClientRect( wc->hwnd, &(wc->rectOffScreen) );\r
+       wc->ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;\r
+    wc->ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;\r
+    wc->ddsd.dwHeight = wc->rectOffScreen.bottom - wc->rectOffScreen.top;\r
+    wc->ddsd.dwWidth = wc->rectOffScreen.right - wc->rectOffScreen.left;\r
+\r
+    ddrval = wc->lpDD->lpVtbl->CreateSurface( wc->lpDD, &(wc->ddsd), &(wc->lpDDSOffScreen), NULL );\r
+    if( ddrval != DD_OK )\r
+    {\r
+               return FALSE;\r
+    }\r
+\r
+       while (wc->lpDDSOffScreen->lpVtbl->Lock(wc->lpDDSOffScreen,NULL, &(wc->ddsd), 0, NULL) == DDERR_WASSTILLDRAWING)\r
+        ;\r
+//     while ((ddrval = wc->lpDDSOffScreen->lpVtbl->Lock(wc->lpDDSOffScreen,NULL, &(wc->ddsd), DDLOCK_SURFACEMEMORYPTR , NULL)) != DD_OK)\r
+               ;\r
+       if(wc->ddsd.lpSurface==NULL)\r
+               return initFail(wc->hwnd, wc);\r
+\r
+       wc->ScreenMem = wc->pbPixels = wc->addrOffScreen = (PBYTE)(wc->ddsd.lpSurface);\r
+       wc->ScanWidth = wc->pitch = wc->ddsd.lPitch;\r
+       if (stereo_flag)\r
+               wc->ScanWidth = wc->ddsd.lPitch*2;\r
+\r
+       GetClientRect( wc->hwnd, &(wc->rectSurface) );\r
+       pt.x = pt.y = 0;\r
+    ClientToScreen( wc->hwnd, &pt );\r
+    OffsetRect(&(wc->rectSurface), pt.x, pt.y);\r
+       wmSetPixelFormat(wc, wc->hDC);\r
+       return TRUE;\r
+}\r
+\r
+/*\r
+ * doInit - do work required for every instance of the application:\r
+ *                create the window, initialize data\r
+ */\r
+static BOOL DDInit( WMesaContext wc, HWND hwnd)\r
+{\r
+    HRESULT             ddrval;\r
+       DWORD dwFrequency;\r
+\r
+       LPDIRECTDRAW            lpDD;           // DirectDraw object\r
+       LPDIRECTDRAW2            lpDD2;\r
+\r
+\r
+       wc->fullScreen = displayOptions.fullScreen;\r
+       wc->gMode = displayOptions.mode;\r
+       wc->hwnd = hwnd;\r
+       stereo_flag = displayOptions.stereo;\r
+       if(wc->db_flag!= GL_TRUE)\r
+               stereo_flag = GL_FALSE;\r
+    /*\r
+     * create the main DirectDraw object\r
+     */\r
+    ddrval = DirectDrawCreate( NULL, &(wc->lpDD), NULL );\r
+    if( ddrval != DD_OK )\r
+    {\r
+        return initFail(hwnd,wc);\r
+    }\r
+\r
+    // Get exclusive mode if requested\r
+    if(wc->fullScreen)\r
+    {\r
+        ddrval = wc->lpDD->lpVtbl->SetCooperativeLevel( wc->lpDD, hwnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN );\r
+    }\r
+    else\r
+    {\r
+        ddrval = wc->lpDD->lpVtbl->SetCooperativeLevel( wc->lpDD, hwnd, DDSCL_NORMAL );\r
+    }\r
+    if( ddrval != DD_OK )\r
+    {\r
+        return initFail(hwnd , wc);\r
+    }\r
+\r
+\r
+/*     ddrval = wc->lpDD->lpVtbl->QueryInterface(wc->lpDD, IID_IDirectDraw2,\r
+                       (LPVOID *)((wc->lpDD2)));\r
+\r
+*/\r
+       if(ddrval != DD_OK)\r
+        return initFail(hwnd , wc);\r
+\r
+\r
+   //ddrval = wc->lpDD->lpVtbl->GetDisplayMode( wc->lpDD, &(wc->ddsd));\r
+ //  wc->lpDD2->lpVtbl->GetMonitorFrequency(wc->lpDD, &dwFrequency);\r
+    switch( wc->gMode )\r
+    {\r
+        case 1:  ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 640, 480, displayOptions.bpp); break;\r
+        case 2:  ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 800, 600, displayOptions.bpp); break;\r
+        case 3:  ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 1024, 768, displayOptions.bpp); break;\r
+               case 4:  ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 1152, 864, displayOptions.bpp); break;\r
+        case 5:  ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 1280, 1024, displayOptions.bpp); break;\r
+    }\r
+\r
+    if( ddrval != DD_OK )\r
+    {\r
+               printf("Can't modify display mode, current mode used\n");\r
+//        return initFail(hwnd , wc);\r
+    }\r
+//ddrval = wc->lpDD->lpVtbl->GetDisplayMode( wc->lpDD, &(wc->ddsd));\r
+switch(ddrval){\r
+case DDERR_INVALIDOBJECT:\r
+       break;\r
+case DDERR_INVALIDPARAMS:\r
+       break;\r
+case DDERR_UNSUPPORTEDMODE:\r
+       ;\r
+}\r
+\r
+       if(DDCreatePrimarySurface(wc) == GL_FALSE)\r
+               return initFail(hwnd, wc);\r
+\r
+       if(wc->db_flag)\r
+               return DDCreateOffScreen(wc);\r
+} /* DDInit */\r
+\r
+static void DDFree( WMesaContext wc)\r
+{\r
+    if( wc->lpDD != NULL )\r
+    {\r
+               DDFreePrimarySurface(wc);\r
+               DDDeleteOffScreen(wc);\r
+        wc->lpDD->lpVtbl->Release(wc->lpDD);\r
+        wc->lpDD = NULL;\r
+    }\r
+    // Clean up the screen on exit\r
+    RedrawWindow( NULL, NULL, NULL, RDW_INVALIDATE | RDW_ERASE |\r
+                     RDW_ALLCHILDREN );\r
+\r
+}\r
+#endif\r
+\r
+void WMesaMove(void)\r
+{\r
+       WMesaContext wc = Current;\r
+       POINT   pt;\r
+       if (Current != NULL){\r
+               GetClientRect( wc->hwnd, &(wc->rectSurface) );\r
+               pt.x = pt.y = 0;\r
+               ClientToScreen( wc->hwnd, &pt );\r
+               OffsetRect(&(wc->rectSurface), pt.x, pt.y);\r
+       }\r
+}\r
+\r
+/*\r
+ * Like PACK_8A8B8G8R() but don't use alpha.  This is usually an acceptable\r
+ * shortcut.\r
+ */\r
+#define PACK_8B8G8R( R, G, B )   ( ((B) << 16) | ((G) << 8) | (R) )\r
+\r
+\r
+/**********************************************************************/\r
+/***                   Triangle rendering                            ***/\r
+/**********************************************************************/\r
+\r
+\r
+\r
+/*\r
+ * XImage, smooth, depth-buffered, PF_8A8B8G8R triangle.\r
+ */\r
+static void smooth_8A8B8G8R_z_triangle( GLcontext *ctx,\r
+                                         GLuint v0, GLuint v1, GLuint v2,\r
+                                         GLuint pv )\r
+{\r
+WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;\r
+#define INTERP_Z 1\r
+#define INTERP_RGB 1\r
+#define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)\r
+#define PIXEL_TYPE GLuint\r
+//#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)\r
+#define BYTES_PER_ROW (wmesa->ScanWidth)\r
+#define INNER_LOOP( LEFT, RIGHT, Y )                                   \\r
+{                                                                      \\r
+   GLint i, len = RIGHT-LEFT;                                          \\r
+   for (i=0;i<len;i++) {                                               \\r
+      GLdepth z = FixedToDepth(ffz);                                   \\r
+      if (z < zRow[i]) {                                               \\r
+         pRow[i] = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg),      \\r
+                                FixedToInt(ffb) );                     \\r
+         zRow[i] = z;                                                  \\r
+      }                                                                        \\r
+      ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;                      \\r
+      ffz += fdzdx;                                                    \\r
+   }                                                                   \\r
+}\r
+#include "tritemp.h"\r
+}\r
+\r
+\r
+/*\r
+ * XImage, smooth, depth-buffered, PF_8R8G8B triangle.\r
+ */\r
+static void smooth_8R8G8B_z_triangle( GLcontext *ctx,\r
+                                         GLuint v0, GLuint v1, GLuint v2,\r
+                                         GLuint pv )\r
+{\r
+   WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;\r
+#define INTERP_Z 1\r
+#define INTERP_RGB 1\r
+#define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)\r
+#define PIXEL_TYPE GLuint\r
+//#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)\r
+#define BYTES_PER_ROW (wmesa->ScanWidth)\r
+#define INNER_LOOP( LEFT, RIGHT, Y )                                   \\r
+{                                                                      \\r
+   GLint i, len = RIGHT-LEFT;                                          \\r
+   for (i=0;i<len;i++) {                                               \\r
+      GLdepth z = FixedToDepth(ffz);                                   \\r
+      if (z < zRow[i]) {                                               \\r
+         pRow[i] = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg),      \\r
+                                FixedToInt(ffb) );                     \\r
+         zRow[i] = z;                                                  \\r
+      }                                                                        \\r
+      ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;                      \\r
+      ffz += fdzdx;                                                    \\r
+   }                                                                   \\r
+}\r
+#include "tritemp.h"\r
+}\r
+\r
+\r
+\r
+/*\r
+ * XImage, smooth, depth-buffered, PF_5R6G5B triangle.\r
+ */\r
+static void smooth_5R6G5B_z_triangle( GLcontext *ctx,\r
+                                         GLuint v0, GLuint v1, GLuint v2,\r
+                                         GLuint pv )\r
+{\r
+   WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;\r
+#define INTERP_Z 1\r
+#define INTERP_RGB 1\r
+#define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)\r
+#define PIXEL_TYPE GLushort\r
+//#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)\r
+#define BYTES_PER_ROW (wmesa->ScanWidth)\r
+#define INNER_LOOP( LEFT, RIGHT, Y )                                   \\r
+{                                                                      \\r
+   GLint i, len = RIGHT-LEFT;                                          \\r
+   for (i=0;i<len;i++) {                                               \\r
+      GLdepth z = FixedToDepth(ffz);                                   \\r
+      if (z < zRow[i]) {                                               \\r
+         pRow[i] = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg),      \\r
+                                FixedToInt(ffb) );                     \\r
+         zRow[i] = z;                                                  \\r
+      }                                                                        \\r
+      ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;                      \\r
+      ffz += fdzdx;                                                    \\r
+   }                                                                   \\r
+}\r
+#include "tritemp.h"\r
+}\r
+\r
+/*\r
+ * XImage, flat, depth-buffered, PF_8A8B8G8R triangle.\r
+ */\r
+static void flat_8A8B8G8R_z_triangle( GLcontext *ctx, GLuint v0,\r
+                                     GLuint v1, GLuint v2, GLuint pv )\r
+{\r
+   WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;\r
+#define INTERP_Z 1\r
+#define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)\r
+#define PIXEL_TYPE GLuint\r
+//#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)\r
+#define BYTES_PER_ROW (wmesa->ScanWidth)\r
+#define SETUP_CODE                                     \\r
+   unsigned long p = PACK_8B8G8R( VB->Color[pv][0],    \\r
+                VB->Color[pv][1], VB->Color[pv][2] );\r
+#define INNER_LOOP( LEFT, RIGHT, Y )                                   \\r
+{                                                                      \\r
+   GLint i, len = RIGHT-LEFT;                                          \\r
+   for (i=0;i<len;i++) {                                               \\r
+      GLdepth z = FixedToDepth(ffz);                                   \\r
+      if (z < zRow[i]) {                                               \\r
+        pRow[i] = p;                                                   \\r
+         zRow[i] = z;                                                  \\r
+      }                                                                        \\r
+      ffz += fdzdx;                                                    \\r
+   }                                                                   \\r
+}\r
+#include "tritemp.h"\r
+}\r
+\r
+\r
+/*\r
+ * XImage, flat, depth-buffered, PF_8R8G8B triangle.\r
+ */\r
+static void flat_8R8G8B_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,\r
+                                    GLuint v2, GLuint pv )\r
+{\r
+   WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;\r
+#define INTERP_Z 1\r
+#define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)\r
+#define PIXEL_TYPE GLuint\r
+//#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)\r
+#define BYTES_PER_ROW (wmesa->ScanWidth)\r
+#define SETUP_CODE                                     \\r
+   unsigned long p = PACK_8R8G8B( VB->Color[pv][0],    \\r
+                VB->Color[pv][1], VB->Color[pv][2] );\r
+#define INNER_LOOP( LEFT, RIGHT, Y )                   \\r
+{                                                      \\r
+   GLint i, len = RIGHT-LEFT;                          \\r
+   for (i=0;i<len;i++) {                               \\r
+      GLdepth z = FixedToDepth(ffz);                   \\r
+      if (z < zRow[i]) {                               \\r
+        pRow[i] = p;                                   \\r
+         zRow[i] = z;                                  \\r
+      }                                                        \\r
+      ffz += fdzdx;                                    \\r
+   }                                                   \\r
+}\r
+#include "tritemp.h"\r
+}\r
+\r
+\r
+/*\r
+ * XImage, flat, depth-buffered, PF_5R6G5B triangle.\r
+ */\r
+static void flat_5R6G5B_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,\r
+                                    GLuint v2, GLuint pv )\r
+{\r
+   WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;\r
+#define INTERP_Z 1\r
+#define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)\r
+#define PIXEL_TYPE GLushort\r
+//#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)\r
+#define BYTES_PER_ROW (wmesa->ScanWidth)\r
+#define SETUP_CODE                                     \\r
+   unsigned long p = PACK_5R6G5B( VB->Color[pv][0],    \\r
+                VB->Color[pv][1], VB->Color[pv][2] );\r
+#define INNER_LOOP( LEFT, RIGHT, Y )                   \\r
+{                                                      \\r
+   GLint i, len = RIGHT-LEFT;                          \\r
+   for (i=0;i<len;i++) {                               \\r
+      GLdepth z = FixedToDepth(ffz);                   \\r
+      if (z < zRow[i]) {                               \\r
+        pRow[i] = p;                                   \\r
+         zRow[i] = z;                                  \\r
+      }                                                        \\r
+      ffz += fdzdx;                                    \\r
+   }                                                   \\r
+}\r
+#include "tritemp.h"\r
+}\r
+\r
+\r
+/*\r
+ * XImage, smooth, NON-depth-buffered, PF_8A8B8G8R triangle.\r
+ */\r
+static void smooth_8A8B8G8R_triangle( GLcontext *ctx, GLuint v0, GLuint v1,\r
+                                     GLuint v2, GLuint pv )\r
+{\r
+   WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;\r
+#define INTERP_RGB 1\r
+#define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)\r
+#define PIXEL_TYPE GLuint\r
+//#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)\r
+#define BYTES_PER_ROW (wmesa->ScanWidth)\r
+#define INNER_LOOP( LEFT, RIGHT, Y )                                   \\r
+{                                                                      \\r
+   GLint xx;                                                           \\r
+   PIXEL_TYPE *pixel = pRow;                                           \\r
+   for (xx=LEFT;xx<RIGHT;xx++,pixel++) {                               \\r
+      *pixel = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg),          \\r
+                               FixedToInt(ffb) );                      \\r
+      ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;                      \\r
+   }                                                                   \\r
+}\r
+#include "tritemp.h"\r
+}\r
+\r
+\r
+/*\r
+ * XImage, smooth, NON-depth-buffered, PF_8R8G8B triangle.\r
+ */\r
+static void smooth_8R8G8B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,\r
+                                    GLuint v2, GLuint pv )\r
+{\r
+   WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;\r
+#define INTERP_RGB 1\r
+#define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)\r
+#define PIXEL_TYPE GLuint\r
+//#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)\r
+#define BYTES_PER_ROW (wmesa->ScanWidth)\r
+#define INNER_LOOP( LEFT, RIGHT, Y )                                   \\r
+{                                                                      \\r
+   GLint xx;                                                           \\r
+   PIXEL_TYPE *pixel = pRow;                                           \\r
+   for (xx=LEFT;xx<RIGHT;xx++,pixel++) {                               \\r
+      *pixel = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg),          \\r
+                               FixedToInt(ffb) );                      \\r
+      ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;                      \\r
+   }                                                                   \\r
+}\r
+#include "tritemp.h"\r
+}\r
+\r
+\r
+/*\r
+ * XImage, smooth, NON-depth-buffered, PF_5R6G5B triangle.\r
+ */\r
+static void smooth_5R6G5B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,\r
+                                   GLuint v2, GLuint pv )\r
+{\r
+   WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;\r
+#define INTERP_RGB 1\r
+#define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)\r
+#define PIXEL_TYPE GLushort\r
+//#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)\r
+#define BYTES_PER_ROW (wmesa->ScanWidth)\r
+#define INNER_LOOP( LEFT, RIGHT, Y )                                   \\r
+{                                                                      \\r
+   GLint xx;                                                           \\r
+   PIXEL_TYPE *pixel = pRow;                                           \\r
+   for (xx=LEFT;xx<RIGHT;xx++,pixel++) {                               \\r
+      *pixel = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg),          \\r
+                               FixedToInt(ffb) );                      \\r
+      ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;                      \\r
+   }                                                                   \\r
+}\r
+#include "tritemp.h"\r
+}\r
+\r
+\r
+\r
+/*\r
+ * XImage, flat, NON-depth-buffered, PF_8A8B8G8R triangle.\r
+ */\r
+static void flat_8A8B8G8R_triangle( GLcontext *ctx, GLuint v0,\r
+                                   GLuint v1, GLuint v2, GLuint pv )\r
+{\r
+   WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;\r
+#define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)\r
+#define PIXEL_TYPE GLuint\r
+//#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)\r
+#define BYTES_PER_ROW (wmesa->ScanWidth)\r
+#define SETUP_CODE                                     \\r
+   unsigned long p = PACK_8B8G8R( VB->Color[pv][0],    \\r
+                VB->Color[pv][1], VB->Color[pv][2] );\r
+#define INNER_LOOP( LEFT, RIGHT, Y )                   \\r
+{                                                      \\r
+   GLint xx;                                           \\r
+   PIXEL_TYPE *pixel = pRow;                           \\r
+   for (xx=LEFT;xx<RIGHT;xx++,pixel++) {               \\r
+      *pixel = p;                                      \\r
+   }                                                   \\r
+}\r
+#include "tritemp.h"\r
+}\r
+\r
+\r
+/*\r
+ * XImage, flat, NON-depth-buffered, PF_8R8G8B triangle.\r
+ */\r
+static void flat_8R8G8B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,\r
+                                  GLuint v2, GLuint pv )\r
+{\r
+   WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;\r
+#define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)\r
+#define PIXEL_TYPE GLuint\r
+//#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)\r
+#define BYTES_PER_ROW (wmesa->ScanWidth)\r
+#define SETUP_CODE                                     \\r
+   unsigned long p = PACK_8R8G8B( VB->Color[pv][0],    \\r
+                VB->Color[pv][1], VB->Color[pv][2] );\r
+#define INNER_LOOP( LEFT, RIGHT, Y )                   \\r
+{                                                      \\r
+   GLint xx;                                           \\r
+   PIXEL_TYPE *pixel = pRow;                           \\r
+   for (xx=LEFT;xx<RIGHT;xx++,pixel++) {               \\r
+      *pixel = p;                                      \\r
+   }                                                   \\r
+}\r
+#include "tritemp.h"\r
+}\r
+\r
+\r
+/*\r
+ * XImage, flat, NON-depth-buffered, PF_5R6G5B triangle.\r
+ */\r
+static void flat_5R6G5B_triangle( GLcontext *ctx, GLuint v0, GLuint v1,\r
+                                  GLuint v2, GLuint pv )\r
+{\r
+   WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;\r
+#define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)\r
+#define PIXEL_TYPE GLushort\r
+//#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line)\r
+#define BYTES_PER_ROW (wmesa->ScanWidth)\r
+#define SETUP_CODE                                     \\r
+   unsigned long p = PACK_5R6G5B( VB->Color[pv][0],    \\r
+                VB->Color[pv][1], VB->Color[pv][2] );\r
+#define INNER_LOOP( LEFT, RIGHT, Y )                   \\r
+{                                                      \\r
+   GLint xx;                                           \\r
+   PIXEL_TYPE *pixel = pRow;                           \\r
+   for (xx=LEFT;xx<RIGHT;xx++,pixel++) {               \\r
+      *pixel = p;                                      \\r
+   }                                                   \\r
+}\r
+#include "tritemp.h"\r
+}\r
+\r
+\r
+/*\r
+ * XImage, smooth, depth-buffered, 8-bit PF_LOOKUP triangle.\r
+ */\r
+\r
+static void smooth_ci_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,\r
+                                       GLuint v2, GLuint pv )\r
+{\r
+   WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;\r
+#define INTERP_Z 1\r
+#define INTERP_INDEX 1\r
+#define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)\r
+#define PIXEL_TYPE GLubyte\r
+#define BYTES_PER_ROW (wmesa->ScanWidth)\r
+#define INNER_LOOP( LEFT, RIGHT, Y )                                                           \\r
+{                                                                                                                                      \\r
+   GLint i, len = RIGHT-LEFT;                                                                          \\r
+   for (i=0;i<len;i++) {                                                                                       \\r
+      GLdepth z = FixedToDepth(ffz);                                                           \\r
+      if (z < zRow[i]) {                                                                                       \\r
+         pRow[i] = FixedToInt(ffi);                                                                    \\r
+         zRow[i] = z;                                                                                          \\r
+      }                                                                                                                                \\r
+      ffi += fdidx;                                                                                                    \\r
+      ffz += fdzdx;                                                                                                    \\r
+   }                                                                                                                           \\r
+}\r
+\r
+#include "tritemp.h"\r
+}\r
+\r
+\r
+/*\r
+ * XImage, flat, depth-buffered, 8-bit PF_LOOKUP triangle.\r
+ */\r
+\r
+static void flat_ci_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,\r
+                                    GLuint v2, GLuint pv )\r
+{\r
+   WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;\r
+#define INTERP_Z 1\r
+#define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)\r
+#define PIXEL_TYPE GLubyte\r
+#define BYTES_PER_ROW (wmesa->ScanWidth)\r
+#define SETUP_CODE                                                                                                     \\r
+   GLuint index = VB->Index[pv];                                                                       \\r
+   if (!VB->MonoColor) {                                                                                       \\r
+      /* set the color index */                                                                                \\r
+      (*ctx->Driver.Index)( ctx, index );                                                      \\r
+   }\r
+#define INNER_LOOP( LEFT, RIGHT, Y )                                                           \\r
+{                                                                                                                                      \\r
+   GLint i, len = RIGHT-LEFT;                                                                          \\r
+   for (i=0;i<len;i++) {                                                                                       \\r
+      GLdepth z = FixedToDepth(ffz);                                                           \\r
+      if (z < zRow[i]) {                                                                                       \\r
+                pRow[i] = index;                                                                                       \\r
+         zRow[i] = z;                                                                                          \\r
+      }                                                                                                                                \\r
+      ffz += fdzdx;                                                                                                    \\r
+   }                                                                                                                           \\r
+}\r
+#include "tritemp.h"\r
+}\r
+\r
+\r
+\r
+/*\r
+ * XImage, smooth, NON-depth-buffered, 8-bit PF_LOOKUP triangle.\r
+ */\r
+\r
+static void smooth_ci_triangle( GLcontext *ctx, GLuint v0, GLuint v1,\r
+                                     GLuint v2, GLuint pv )\r
+{\r
+   WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;\r
+#define INTERP_Z 1\r
+#define INTERP_INDEX 1\r
+#define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)\r
+#define PIXEL_TYPE GLubyte\r
+#define BYTES_PER_ROW (wmesa->ScanWidth)\r
+#define INNER_LOOP( LEFT, RIGHT, Y )                                   \\r
+{                                                                      \\r
+   GLint xx;                                                           \\r
+   PIXEL_TYPE *pixel = pRow;                                           \\r
+   for (xx=LEFT;xx<RIGHT;xx++,pixel++) {                               \\r
+      *pixel = FixedToInt(ffi);                        \\r
+      ffi += fdidx;                    \\r
+   }                                                                   \\r
+}\r
+#include "tritemp.h"\r
+}\r
+\r
+\r
+/*\r
+ * XImage, flat, NON-depth-buffered, 8-bit PF_LOOKUP triangle.\r
+ */\r
+static void flat_ci_triangle( GLcontext *ctx, GLuint v0, GLuint v1,\r
+                                    GLuint v2, GLuint pv )\r
+{\r
+   WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;\r
+#define INTERP_Z 1\r
+#define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)\r
+#define PIXEL_TYPE GLubyte\r
+#define BYTES_PER_ROW (wmesa->ScanWidth)\r
+#define SETUP_CODE                                                                                                     \\r
+   GLuint index = VB->Index[pv];                                                                       \\r
+   if (!VB->MonoColor) {                                                                                       \\r
+      /* set the color index */                                                                                \\r
+      (*ctx->Driver.Index)( ctx, index );                                                      \\r
+   }\r
+#define INNER_LOOP( LEFT, RIGHT, Y )                   \\r
+{                                                      \\r
+   GLint xx;                                           \\r
+   PIXEL_TYPE *pixel = pRow;                           \\r
+   for (xx=LEFT;xx<RIGHT;xx++,pixel++) {               \\r
+      *pixel = index;                                  \\r
+   }                                                   \\r
+}\r
+#include "tritemp.h"\r
+}\r
+\r
+/*\r
+ * XImage, smooth, depth-buffered, 8-bit, PF_DITHER8 triangle.\r
+ */\r
+static void smooth_DITHER8_z_triangle( GLcontext *ctx,\r
+                                       GLuint v0, GLuint v1, GLuint v2,\r
+                                       GLuint pv )\r
+{\r
+   WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;\r
+   DITHER_RGB_TO_8BIT_SETUP\r
+#define INTERP_Z 1\r
+#define INTERP_RGB 1\r
+#define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)\r
+#define PIXEL_TYPE GLubyte\r
+#define BYTES_PER_ROW (wmesa->ScanWidth)\r
+#define INNER_LOOP( LEFT, RIGHT, Y )                                                                   \\r
+{                                                                                                                                              \\r
+   GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT;                                 \\r
+   for (i=0;i<len;i++,xx++) {                                                                                  \\r
+      GLdepth z = FixedToDepth(ffz);                                                                   \\r
+      if (z < zRow[i]) {                                                                                               \\r
+                DITHER_RGB_TO_8BIT( FixedToInt(ffr), FixedToInt(ffg),                  \\r
+                                                               FixedToInt(ffb), xx, yy);                               \\r
+                pRow[i] = pixelDithered;                                                                               \\r
+         zRow[i] = z;                                                                                                  \\r
+      }                                                                                                                                        \\r
+      ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;                                              \\r
+      ffz += fdzdx;                                                                                                            \\r
+   }                                                                                                                                   \\r
+}\r
+#include "tritemp.h"\r
+}\r
+\r
+/*\r
+ * XImage, flat, depth-buffered, 8-bit PF_DITHER triangle.\r
+ */\r
+static void flat_DITHER8_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,\r
+                                     GLuint v2, GLuint pv )\r
+{\r
+   WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;\r
+   DITHER_RGB_TO_8BIT_SETUP\r
+#define INTERP_Z 1\r
+#define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)\r
+#define PIXEL_TYPE GLubyte\r
+#define BYTES_PER_ROW (wmesa->ScanWidth)\r
+\r
+#define INNER_LOOP( LEFT, RIGHT, Y )                                                                   \\r
+{                                                                                                                                              \\r
+   GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT;                                 \\r
+   for (i=0;i<len;i++,xx++) {                                                                                  \\r
+      GLdepth z = FixedToDepth(ffz);                                                                   \\r
+      if (z < zRow[i]) {                                                                                               \\r
+               DITHER_RGB_TO_8BIT( VB->Color[pv][0],                                                   \\r
+                        VB->Color[pv][1], VB->Color[pv][2], xx, yy);                           \\r
+               pRow[i] = pixelDithered;                                                                                \\r
+         zRow[i] = z;                                                                                                  \\r
+      }                                                                                                                                        \\r
+      ffz += fdzdx;                                                                                                            \\r
+   }                                                                                                                                   \\r
+}\r
+#include "tritemp.h"\r
+}\r
+\r
+/*\r
+ * XImage, smooth, NON-depth-buffered, 8-bit PF_DITHER triangle.\r
+ */\r
+static void smooth_DITHER8_triangle( GLcontext *ctx, GLuint v0, GLuint v1,\r
+                                    GLuint v2, GLuint pv )\r
+{\r
+   WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;\r
+   DITHER_RGB_TO_8BIT_SETUP\r
+#define INTERP_RGB 1\r
+#define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)\r
+#define PIXEL_TYPE GLubyte\r
+#define BYTES_PER_ROW (wmesa->ScanWidth)\r
+#define INNER_LOOP( LEFT, RIGHT, Y )                                                                   \\r
+{                                                                                                                                              \\r
+   GLint xx, yy = FLIP(Y);                                                                                             \\r
+   PIXEL_TYPE *pixel = pRow;                                                                                   \\r
+   for (xx=LEFT;xx<RIGHT;xx++,pixel++) {                                                               \\r
+         DITHER_RGB_TO_8BIT( VB->Color[pv][0], VB->Color[pv][1], VB->Color[pv][2], xx, yy);\\r
+         *pixel = pixelDithered;                                                                                       \\r
+         ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;                                           \\r
+   }                                                                                                                                   \\r
+}\r
+#include "tritemp.h"\r
+}\r
+\r
+/*\r
+ * XImage, flat, NON-depth-buffered, 8-bit PF_DITHER triangle.\r
+ */\r
+\r
+static void flat_DITHER8_triangle( GLcontext *ctx, GLuint v0, GLuint v1,\r
+                                   GLuint v2, GLuint pv )\r
+{\r
+   WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;\r
+   DITHER_RGB_TO_8BIT_SETUP\r
+#define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)\r
+#define PIXEL_TYPE GLubyte\r
+#define BYTES_PER_ROW (wmesa->ScanWidth)\r
+\r
+#define INNER_LOOP( LEFT, RIGHT, Y )                                                                   \\r
+{                                                                                                                                              \\r
+   GLint xx, yy = FLIP(Y);                                                                                             \\r
+   PIXEL_TYPE *pixel = pRow;                                                                                   \\r
+   for (xx=LEFT;xx<RIGHT;xx++,pixel++) {                                                               \\r
+      DITHER_RGB_TO_8BIT( VB->Color[pv][0],                                                            \\r
+                        VB->Color[pv][1], VB->Color[pv][2], xx, yy);                           \\r
+         *pixel = pixelDithered;                                                                                       \\r
+   }                                                                                                                                   \\r
+}\r
+#include "tritemp.h"\r
+}\r
+\r
+\r
+\r
+\r
+static triangle_func choose_triangle_function( GLcontext *ctx )\r
+{\r
+   WMesaContext wmesa = (WMesaContext) ctx->DriverCtx;\r
+   int depth = wmesa->cColorBits;\r
+\r
+   if (ctx->Polygon.SmoothFlag)     return NULL;\r
+   if (ctx->Texture.Enabled)        return NULL;\r
+   if (!wmesa->db_flag) return NULL;\r
+   /*if (wmesa->xm_buffer->buffer==XIMAGE)*/ {\r
+      if (   ctx->Light.ShadeModel==GL_SMOOTH\r
+          && ctx->RasterMask==DEPTH_BIT\r
+          && ctx->Depth.Func==GL_LESS\r
+          && ctx->Depth.Mask==GL_TRUE\r
+          && ctx->Polygon.StippleFlag==GL_FALSE) {\r
+         switch (wmesa->pixelformat) {\r
+            case PF_8A8B8G8R:\r
+               return smooth_8A8B8G8R_z_triangle;\r
+            case PF_8R8G8B:\r
+               return smooth_8R8G8B_z_triangle;\r
+            case PF_5R6G5B:\r
+               return smooth_5R6G5B_z_triangle;\r
+            case PF_DITHER8:\r
+               return  smooth_DITHER8_z_triangle;\r
+            case PF_INDEX8:\r
+               return smooth_ci_z_triangle;\r
+            default:\r
+               return NULL;\r
+         }\r
+      }\r
+      if (   ctx->Light.ShadeModel==GL_FLAT\r
+          && ctx->RasterMask==DEPTH_BIT\r
+          && ctx->Depth.Func==GL_LESS\r
+          && ctx->Depth.Mask==GL_TRUE\r
+          && ctx->Polygon.StippleFlag==GL_FALSE) {\r
+         switch (wmesa->pixelformat) {\r
+            case PF_8A8B8G8R:\r
+               return flat_8A8B8G8R_z_triangle;\r
+            case PF_8R8G8B:\r
+               return flat_8R8G8B_z_triangle;\r
+            case PF_5R6G5B:\r
+               return flat_5R6G5B_z_triangle;\r
+            case PF_DITHER8:\r
+               return flat_DITHER8_z_triangle;\r
+            case PF_INDEX8:\r
+               return flat_ci_z_triangle;\r
+                       default:\r
+               return NULL;\r
+         }\r
+      }\r
+      if (   ctx->RasterMask==0   /* no depth test */\r
+          && ctx->Light.ShadeModel==GL_SMOOTH\r
+          && ctx->Polygon.StippleFlag==GL_FALSE) {\r
+         switch (wmesa->pixelformat) {\r
+            case PF_8A8B8G8R:\r
+               return smooth_8A8B8G8R_triangle;\r
+            case PF_8R8G8B:\r
+               return smooth_8R8G8B_triangle;\r
+            case PF_5R6G5B:\r
+               return smooth_5R6G5B_triangle;\r
+            case PF_DITHER8:\r
+               return smooth_DITHER8_triangle;\r
+                       case PF_INDEX8:\r
+               return smooth_ci_triangle;\r
+            default:\r
+               return NULL;\r
+         }\r
+      }\r
+\r
+      if (   ctx->RasterMask==0   /* no depth test */\r
+          && ctx->Light.ShadeModel==GL_FLAT\r
+          && ctx->Polygon.StippleFlag==GL_FALSE) {\r
+         switch (wmesa->pixelformat) {\r
+            case PF_8A8B8G8R:\r
+               return flat_8A8B8G8R_triangle;\r
+            case PF_8R8G8B:\r
+               return flat_8R8G8B_triangle;\r
+            case PF_5R6G5B:\r
+               return flat_5R6G5B_triangle;\r
+            case PF_DITHER8:\r
+               return flat_DITHER8_triangle;\r
+                       case PF_INDEX8:\r
+               return flat_ci_triangle;\r
+            default:\r
+               return NULL;\r
+         }\r
+      }\r
+\r
+      return NULL;\r
+   }\r
+}\r
+\r
+/*\r
+ * Define a new viewport and reallocate auxillary buffers if the size of\r
+ * the window (color buffer) has changed.\r
+ */\r
+void WMesaViewport( GLcontext *ctx,\r
+                  GLint x, GLint y, GLsizei width, GLsizei height )\r
+{\r
+   /* Save viewport */\r
+   ctx->Viewport.X = x;\r
+   ctx->Viewport.Width = width;\r
+   ctx->Viewport.Y = y;\r
+   ctx->Viewport.Height = height;\r
+\r
+   /* compute scale and bias values */\r
+   ctx->Viewport.Sx = (GLfloat) width / 2.0F;\r
+   ctx->Viewport.Tx = ctx->Viewport.Sx + x;\r
+   ctx->Viewport.Sy = (GLfloat) height / 2.0F;\r
+   ctx->Viewport.Ty = ctx->Viewport.Sy + y;\r
+}\r
diff --git a/src/mesa/drivers/windows/wmesa_stereo.c b/src/mesa/drivers/windows/wmesa_stereo.c
new file mode 100644 (file)
index 0000000..ea721a1
--- /dev/null
@@ -0,0 +1,1872 @@
+/*\r
+       WMesa_stereo.c\r
+*/\r
+// Stereo display feature added by Li Wei\r
+// Updated 1996/10/06  11:16:15 CST\r
+// Paralell render feature added by Li Wei\r
+// liwei@aiar.xjtu.edu.cn\r
+// http://sun.aiar.xjtu.edu.cn\r
+\r
+#define WMESA_STEREO_C\r
+\r
+#include <windows.h>\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <wmesadef.h>\r
+\r
+#include <GL\wmesa.h>\r
+#include "context.h"\r
+#include "dd.h"\r
+#include "xform.h"\r
+#include "vb.h"\r
+#include "matrix.h"\r
+#include "depth.h"\r
+\r
+#ifdef PROFILE\r
+       #include "profile.h"\r
+#endif\r
+\r
+#include <wing.h>\r
+\r
+// Code added by Li Wei to enable stereo display  and Paralell render\r
+\r
+\r
+/*#include "mesa_extend.h"*/\r
+\r
+#if !defined(NO_STEREO)\r
+\r
+       #include "gl\glu.h"\r
+       #include "stereo.h"\r
+\r
+       PBYTE Buffer_Stereo;\r
+\r
+       void WMesaCreateStereoBuffer(void);\r
+\r
+       void WMesaInterleave( GLenum aView);\r
+\r
+       void WMesaDestroyStereoBuffer(void);\r
+\r
+       void WMesaShowStereo(GLuint list);\r
+#endif\r
+#if !defined(NO_PARALLEL)\r
+       #include "parallel.h"\r
+#endif\r
+\r
+/* end of added code*/\r
+\r
+/* Bit's used for dest: */\r
+#define FRONT_PIXMAP   1\r
+#define BACK_PIXMAP    2\r
+#define BACK_XIMAGE    4\r
+\r
+static PWMC Current = NULL;\r
+WMesaContext WC = NULL;\r
+\r
+#ifdef NDEBUG\r
+  #define assert(ignore)       ((void) 0)\r
+#else\r
+  void Mesa_Assert(void *Cond,void *File,unsigned Line)\r
+  {\r
+    char Msg[512];\r
+    sprintf(Msg,"%s %s %d",Cond,File,Line);\r
+    MessageBox(NULL,Msg,"Assertion failed.",MB_OK);\r
+    exit(1);\r
+  }\r
+  #define assert(e)    if (!e) Mesa_Assert(#e,__FILE__,__LINE__);\r
+#endif\r
+\r
+#define DD_GETDC ((Current->db_flag) ? Current->dib.hDC : Current->hDC )\r
+#define DD_RELEASEDC\r
+\r
+//#define BEGINGDICALL if(Current->rgb_flag)wmFlushBits(Current);\r
+#define BEGINGDICALL\r
+//#define ENDGDICALL           if(Current->rgb_flag)wmGetBits(Current);\r
+#define ENDGDICALL\r
+\r
+#define FLIP(Y)  (Current->height-(Y)-1)\r
+\r
+#define STARTPROFILE\r
+#define ENDPROFILE(PARA)\r
+\r
+static void FlushToFile(PWMC pwc, PSTR szFile);\r
+\r
+BOOL wmCreateBackingStore(PWMC pwc, long lxSize, long lySize);\r
+\r
+BOOL wmDeleteBackingStore(PWMC pwc);\r
+\r
+void wmCreatePalette( PWMC pwdc );\r
+BOOL wmSetDibColors(PWMC pwc);\r
+void wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b);\r
+\r
+void wmCreateDIBSection(\r
+       HDC      hDC,\r
+    PWMC pwc,  // handle of device context\r
+    CONST BITMAPINFO *pbmi,    // address of structure containing bitmap size, format, and color data\r
+    UINT iUsage        // color data type indicator: RGB values or palette indices\r
+    );\r
+\r
+BOOL wmFlush(PWMC pwc);\r
+\r
+/*\r
+ * Useful macros:\r
+   Modified from file osmesa.c\r
+ */\r
+\r
+#define PIXELADDR(X,Y)  ((GLbyte *)Current->pbPixels + (Current->height-Y)* Current->ScanWidth + (X)*nBypp)\r
+\r
+\r
+/* Finish all pending operations and synchronize. */\r
+static void finish(GLcontext* ctx)\r
+{\r
+   /* no op */\r
+}\r
+\r
+\r
+//\r
+// We cache all gl draw routines until a flush is made\r
+//\r
+static void flush(GLcontext* ctx)\r
+{\r
+       STARTPROFILE\r
+       if(Current->rgb_flag && !(Current->dib.fFlushed)&&!(Current->db_flag)){\r
+               wmFlush(Current);\r
+       }\r
+       ENDPROFILE(flush)\r
+\r
+}\r
+\r
+\r
+\r
+/*\r
+ * Set the color index used to clear the color buffer.\r
+ */\r
+static void clear_index(GLcontext* ctx, GLuint index)\r
+{\r
+  STARTPROFILE\r
+  Current->clearpixel = index;\r
+  ENDPROFILE(clear_index)\r
+}\r
+\r
+\r
+\r
+/*\r
+ * Set the color used to clear the color buffer.\r
+ */\r
+static void clear_color( GLcontext* ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )\r
+{\r
+  STARTPROFILE\r
+  Current->clearpixel=RGB(r, g, b );\r
+  ENDPROFILE(clear_color)\r
+}\r
+\r
+\r
+\r
+/*\r
+ * Clear the specified region of the color buffer using the clear color\r
+ * or index as specified by one of the two functions above.\r
+ */\r
+static void clear(GLcontext* ctx,\r
+                                 GLboolean all,GLint x, GLint y, GLint width, GLint height )\r
+{\r
+       DWORD   dwColor;\r
+       WORD    wColor;\r
+       LPDWORD lpdw = (LPDWORD)Current->pbPixels;\r
+       LPWORD  lpw = (LPWORD)Current->pbPixels;\r
+       LPBYTE  lpb = Current->pbPixels;\r
+\r
+    STARTPROFILE\r
+\r
+       if (all){\r
+               x=y=0;\r
+               width=Current->width;\r
+               height=Current->height;\r
+       }\r
+       if (Current->rgb_flag==GL_TRUE){\r
+               if(Current->db_flag==GL_TRUE){\r
+                       UINT    nBypp = Current->cColorBits / 8;\r
+                       int             i = 0;\r
+                       int             iSize;\r
+\r
+                       if(nBypp == 2){\r
+                               iSize = (Current->width * Current->height) / nBypp;\r
+\r
+                               wColor = BGR16(GetRValue(Current->clearpixel),\r
+                                                          GetGValue(Current->clearpixel),\r
+                                                          GetBValue(Current->clearpixel));\r
+                               dwColor = MAKELONG(wColor, wColor);\r
+                       }\r
+                       else if(nBypp == 4){\r
+                               iSize = (Current->width * Current->height);\r
+\r
+                               dwColor = BGR32(GetRValue(Current->clearpixel),\r
+                                                          GetGValue(Current->clearpixel),\r
+                                                          GetBValue(Current->clearpixel));\r
+                       }\r
+                       //\r
+                       // This is the 24bit case\r
+                       //\r
+                       else {\r
+\r
+                               iSize = (Current->width * Current->height) / nBypp;\r
+\r
+                               dwColor = BGR24(GetRValue(Current->clearpixel),\r
+                                                          GetGValue(Current->clearpixel),\r
+                                                          GetBValue(Current->clearpixel));\r
+\r
+\r
+                               while(i < iSize){\r
+                                       *lpdw = dwColor;\r
+                                       lpb += nBypp;\r
+                                       lpdw = (LPDWORD)lpb;\r
+                                       i++;\r
+                               }\r
+\r
+       //                      ENDPROFILE(clear)\r
+\r
+                               return;\r
+                       }\r
+\r
+                       while(i < iSize){\r
+                               *lpdw = dwColor;\r
+                               lpdw++;\r
+                               i++;\r
+                       }\r
+               }\r
+               else{ // For single buffer\r
+                HDC DC=DD_GETDC;\r
+                HPEN Pen=CreatePen(PS_SOLID,1,Current->clearpixel);\r
+                HBRUSH Brush=CreateSolidBrush(Current->clearpixel);\r
+                HPEN Old_Pen=SelectObject(DC,Pen);\r
+                HBRUSH Old_Brush=SelectObject(DC,Brush);\r
+                Rectangle(DC,x,y,x+width,y+height);\r
+                SelectObject(DC,Old_Pen);\r
+                SelectObject(DC,Old_Brush);\r
+                DeleteObject(Pen);\r
+                DeleteObject(Brush);\r
+                DD_RELEASEDC;\r
+               }\r
+       }\r
+       else {\r
+               int i;\r
+               char *Mem=Current->ScreenMem+y*Current->ScanWidth+x;\r
+               for (i=0; i<height; i++){\r
+                       memset(Mem,Current->clearpixel,width);\r
+                       Mem+=width;\r
+               }\r
+       }\r
+       ENDPROFILE(clear)\r
+}\r
+\r
+\r
+\r
+/* Set the current color index. */\r
+static void set_index(GLcontext* ctx, GLuint index)\r
+{\r
+  STARTPROFILE\r
+  Current->pixel=index;\r
+  ENDPROFILE(set_index)\r
+}\r
+\r
+\r
+\r
+/* Set the current RGBA color. */\r
+static void set_color( GLcontext* ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )\r
+{\r
+  STARTPROFILE\r
+  Current->pixel = RGB( r, g, b );\r
+  ENDPROFILE(set_color)\r
+}\r
+\r
+\r
+\r
+/* Set the index mode bitplane mask. */\r
+static GLboolean index_mask(GLcontext* ctx, GLuint mask)\r
+{\r
+   /* can't implement */\r
+   return GL_FALSE;\r
+}\r
+\r
+\r
+\r
+/* Set the RGBA drawing mask. */\r
+static GLboolean color_mask( GLcontext* ctx,\r
+                                                        GLboolean rmask, GLboolean gmask,\r
+                                                        GLboolean bmask, GLboolean amask)\r
+{\r
+   /* can't implement */\r
+   return GL_FALSE;\r
+}\r
+\r
+\r
+\r
+/*\r
+ * Set the pixel logic operation.  Return GL_TRUE if the device driver\r
+ * can perform the operation, otherwise return GL_FALSE.  If GL_FALSE\r
+ * is returned, the logic op will be done in software by Mesa.\r
+ */\r
+GLboolean logicop( GLcontext* ctx, GLenum op )\r
+{\r
+   /* can't implement */\r
+   return GL_FALSE;\r
+}\r
+\r
+\r
+static void dither( GLcontext* ctx, GLboolean enable )\r
+{\r
+   /* No op */\r
+}\r
+\r
+\r
+\r
+static GLboolean set_buffer( GLcontext* ctx, GLenum mode )\r
+{\r
+   STARTPROFILE\r
+   /* TODO: this could be better */\r
+   if (mode==GL_FRONT || mode==GL_BACK) {\r
+      return GL_TRUE;\r
+   }\r
+   else {\r
+      return GL_FALSE;\r
+   }\r
+   ENDPROFILE(set_buffer)\r
+}\r
+\r
+\r
+\r
+/* Return characteristics of the output buffer. */\r
+static void buffer_size( GLcontext* ctx, GLuint *width, GLuint *height /*, GLuint *depth */)\r
+{\r
+\r
+       int New_Size;\r
+       RECT CR;\r
+\r
+       STARTPROFILE\r
+       GetClientRect(Current->Window,&CR);\r
+\r
+       *width=CR.right;\r
+       *height=CR.bottom;\r
+//     *depth = Current->depth;\r
+\r
+       New_Size=((*width)!=Current->width) || ((*height)!=Current->height);\r
+\r
+       if (New_Size){\r
+               Current->width=*width;\r
+               Current->height=*height;\r
+               Current->ScanWidth=Current->width;\r
+           if ((Current->ScanWidth%sizeof(long))!=0)\r
+                       Current->ScanWidth+=(sizeof(long)-(Current->ScanWidth%sizeof(long)));\r
+\r
+               if (Current->db_flag){\r
+                       if (Current->rgb_flag==GL_TRUE){\r
+                               wmDeleteBackingStore(Current);\r
+                               wmCreateBackingStore(Current, Current->width, Current->height);\r
+                       }\r
+                       else{\r
+                               Current->ScanWidth=Current->width;\r
+                           if ((Current->ScanWidth%sizeof(long))!=0)\r
+                               Current->ScanWidth+=(sizeof(long)-(Current->ScanWidth%sizeof(long)));\r
+\r
+                               Current->IndexFormat->bmiHeader.biWidth=Current->width;\r
+\r
+                               if (Current->IndexFormat->bmiHeader.biHeight<0)\r
+                                       Current->IndexFormat->bmiHeader.biHeight=-(Current->height);\r
+                               else\r
+                                       Current->IndexFormat->bmiHeader.biHeight=Current->height;\r
+\r
+                               Current->Compat_BM=WinGCreateBitmap(Current->dib.hDC,Current->IndexFormat,&((void *) Current->ScreenMem));\r
+\r
+                               DeleteObject(SelectObject(Current->dib.hDC,Current->Compat_BM));\r
+                       }\r
+//Code added by Li Wei to enable stereo display\r
+// Recreate stereo buffer when stereo_flag is TRUE while parallelFlag is FALSE\r
+#if !defined(NO_STEREO)\r
+                       if(stereo_flag\r
+#if !defined(NO_PARALLEL)\r
+                               &&!parallelFlag\r
+#endif\r
+                               ) {\r
+                       if(stereoBuffer == GL_TRUE)\r
+                               WMesaDestroyStereoBuffer();\r
+                       WMesaCreateStereoBuffer();\r
+                       }\r
+#endif\r
+//     Resize OsmesaBuffer if in Parallel mode\r
+#if !defined(NO_PARALLEL)\r
+                       if(parallelFlag)\r
+                       PRSizeRenderBuffer(Current->width, Current->height,Current->ScanWidth,\r
+                       Current->rgb_flag == GL_TRUE ? Current->pbPixels: Current->ScreenMem);\r
+#endif\r
+//end modification\r
+\r
+               }\r
+       }\r
+\r
+   ENDPROFILE(buffer_size)\r
+}\r
+\r
+\r
+\r
+/**********************************************************************/\r
+/*****           Accelerated point, line, polygon rendering       *****/\r
+/**********************************************************************/\r
+\r
+\r
+static void fast_rgb_points( GLcontext* ctx, GLuint first, GLuint last )\r
+{\r
+   GLuint i;\r
+ //  HDC DC=DD_GETDC;\r
+       PWMC    pwc = Current;\r
+\r
+       STARTPROFILE\r
+\r
+       if (Current->gl_ctx->VB->MonoColor) {\r
+      /* all drawn with current color */\r
+      for (i=first;i<=last;i++) {\r
+         if (Current->gl_ctx->VB->ClipMask[i]==0) {\r
+            int x, y;\r
+            x =       (GLint) Current->gl_ctx->VB->Win[i][0];\r
+            y = FLIP( (GLint) Current->gl_ctx->VB->Win[i][1] );\r
+                       wmSetPixel(pwc, y,x,GetRValue(Current->pixel),\r
+                                           GetGValue(Current->pixel), GetBValue(Current->pixel));\r
+         }\r
+      }\r
+   }\r
+   else {\r
+      /* draw points of different colors */\r
+      for (i=first;i<=last;i++) {\r
+         if (Current->gl_ctx->VB->ClipMask[i]==0) {\r
+            int x, y;\r
+            unsigned long pixel=RGB(Current->gl_ctx->VB->Color[i][0]*255.0,\r
+                                    Current->gl_ctx->VB->Color[i][1]*255.0,\r
+                                    Current->gl_ctx->VB->Color[i][2]*255.0);\r
+            x =       (GLint) Current->gl_ctx->VB->Win[i][0];\r
+            y = FLIP( (GLint) Current->gl_ctx->VB->Win[i][1] );\r
+                       wmSetPixel(pwc, y,x,Current->gl_ctx->VB->Color[i][0]*255.0,\r
+                                    Current->gl_ctx->VB->Color[i][1]*255.0,\r
+                                    Current->gl_ctx->VB->Color[i][2]*255.0);\r
+         }\r
+      }\r
+   }\r
+//   DD_RELEASEDC;\r
+   ENDPROFILE(fast_rgb_points)\r
+}\r
+\r
+\r
+\r
+/* Return pointer to accerated points function */\r
+extern points_func choose_points_function( GLcontext* ctx )\r
+{\r
+   STARTPROFILE\r
+   if (ctx->Point.Size==1.0 && !ctx->Point.SmoothFlag && ctx->RasterMask==0\r
+       && !ctx->Texture.Enabled  && ctx->Visual->RGBAflag) {\r
+   ENDPROFILE(choose_points_function)\r
+      return fast_rgb_points;\r
+   }\r
+   else {\r
+   ENDPROFILE(choose_points_function)\r
+      return NULL;\r
+   }\r
+}\r
+\r
+\r
+\r
+/* Draw a line using the color specified by Current->gl_ctx->VB->Color[pv] */\r
+static void fast_flat_rgb_line( GLcontext* ctx, GLuint v0, GLuint v1, GLuint pv )\r
+{\r
+       STARTPROFILE\r
+       int x0, y0, x1, y1;\r
+       unsigned long pixel;\r
+       HDC DC=DD_GETDC;\r
+       HPEN Pen;\r
+       HPEN Old_Pen;\r
+\r
+       if (Current->gl_ctx->VB->MonoColor) {\r
+         pixel = Current->pixel;  /* use current color */\r
+       }\r
+       else {\r
+         pixel = RGB(Current->gl_ctx->VB->Color[pv][0]*255.0, Current->gl_ctx->VB->Color[pv][1]*255.0, Current->gl_ctx->VB->Color[pv][2]*255.0);\r
+       }\r
+\r
+       x0 =       (int) Current->gl_ctx->VB->Win[v0][0];\r
+       y0 = FLIP( (int) Current->gl_ctx->VB->Win[v0][1] );\r
+       x1 =       (int) Current->gl_ctx->VB->Win[v1][0];\r
+       y1 = FLIP( (int) Current->gl_ctx->VB->Win[v1][1] );\r
+\r
+\r
+       BEGINGDICALL\r
+\r
+       Pen=CreatePen(PS_SOLID,1,pixel);\r
+       Old_Pen=SelectObject(DC,Pen);\r
+       MoveToEx(DC,x0,y0,NULL);\r
+       LineTo(DC,x1,y1);\r
+       SelectObject(DC,Old_Pen);\r
+       DeleteObject(Pen);\r
+       DD_RELEASEDC;\r
+\r
+       ENDGDICALL\r
+\r
+       ENDPROFILE(fast_flat_rgb_line)\r
+}\r
+\r
+\r
+\r
+/* Return pointer to accerated line function */\r
+static line_func choose_line_function( GLcontext* ctx )\r
+{\r
+       STARTPROFILE\r
+   if (ctx->Line.Width==1.0 && !ctx->Line.SmoothFlag && !ctx->Line.StippleFlag\r
+       && ctx->Light.ShadeModel==GL_FLAT && ctx->RasterMask==0\r
+       && !ctx->Texture.Enabled && Current->rgb_flag) {\r
+   ENDPROFILE(choose_line_function)\r
+      return fast_flat_rgb_line;\r
+   }\r
+   else {\r
+   ENDPROFILE(choose_line_function)\r
+      return NULL;\r
+   }\r
+}\r
+\r
+/**********************************************************************/\r
+/*****                 Optimized triangle rendering               *****/\r
+/**********************************************************************/\r
+\r
+\r
+/*\r
+ * Smooth-shaded, z-less triangle, RGBA color.\r
+ */\r
+static void smooth_color_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,\r
+                                     GLuint v2, GLuint pv )\r
+{\r
+UINT   nBypp = Current->cColorBits / 8;\r
+GLbyte* img;\r
+GLushort* img16;\r
+GLuint *img24 ,*img32;\r
+#define INTERP_Z 1\r
+#define INTERP_RGB 1\r
+#define INTERP_ALPHA 1\r
+#define INNER_LOOP( LEFT, RIGHT, Y )                                                   \\r
+{                                                                                                                              \\r
+   GLint i, len = RIGHT-LEFT;                                                                  \\r
+   img = PIXELADDR(LEFT,Y);                                                                    \\r
+   for (i=0;i<len;i++,img+=nBypp) {                                                            \\r
+      GLdepth z = FixedToDepth(ffz);                                                   \\r
+      if (z < zRow[i]) {                                                                               \\r
+                img16 = img24 = img32 = img;                                                   \\r
+                if(nBypp == 2)                                                                                 \\r
+                       *img16 = BGR16( FixedToInt(ffr), FixedToInt(ffg),       \\r
+                                                       FixedToInt(ffb));                                       \\r
+                if(nBypp == 3)                                                                                 \\r
+                       *img24 = BGR24( FixedToInt(ffr), FixedToInt(ffg),       \\r
+                                                       FixedToInt(ffb));                                       \\r
+                if(nBypp == 4)                                                                                 \\r
+                       *img32 = BGR32( FixedToInt(ffr), FixedToInt(ffg),       \\r
+                                                       FixedToInt(ffb));                                       \\r
+         zRow[i] = z;                                                                                  \\r
+      }                                                                                                                        \\r
+      ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;  ffa += fdadx;\\r
+      ffz += fdzdx;                                                                                            \\r
+   }                                                                                                                   \\r
+}\r
+\r
+       #include "tritemp.h"\r
+ }\r
+\r
+\r
+\r
+\r
+/*\r
+ * Flat-shaded, z-less triangle, RGBA color.\r
+ */\r
+static void flat_color_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,\r
+                                   GLuint v2, GLuint pv )\r
+{\r
+GLbyte* img;\r
+GLushort* img16;\r
+GLuint *img24, *img32;\r
+UINT   nBypp = Current->cColorBits / 8;\r
+GLubyte r, g, b ;\r
+GLushort pixel16 = BGR16(r,g,b);\r
+GLuint   pixel24 = BGR24(r,g,b);\r
+GLuint   pixel32 = BGR32(r,g,b);\r
+\r
+#define INTERP_Z 1\r
+#define SETUP_CODE                     \\r
+   r = VB->Color[pv][0];       \\r
+   g = VB->Color[pv][1];       \\r
+   b = VB->Color[pv][2];\r
+\r
+#define INNER_LOOP( LEFT, RIGHT, Y )                                                   \\r
+{                                                                                                                              \\r
+   GLint i, len = RIGHT-LEFT;                                                                  \\r
+   img = PIXELADDR(LEFT,Y);                                                                            \\r
+   for (i=0;i<len;i++,img+=nBypp) {                                                            \\r
+      GLdepth z = FixedToDepth(ffz);                                                   \\r
+      if (z < zRow[i]) {                                                                               \\r
+         img16 = img24 = img32 = img;                                                  \\r
+                if(nBypp == 2)                                                                                 \\r
+                       *img16 = pixel16;                                                                       \\r
+                if(nBypp == 3)                                                                                 \\r
+                       *img24 = pixel24;                                                                       \\r
+                if(nBypp == 4)                                                                                 \\r
+                       *img32 = pixel32;                                                                       \\r
+         zRow[i] = z;                                                                                  \\r
+      }                                                                                                                        \\r
+      ffz += fdzdx;                                                                                            \\r
+   }                                                                                                                   \\r
+}\r
+\r
+#include "tritemp.h"\r
+}\r
+\r
+\r
+\r
+/*\r
+ * Return pointer to an accelerated triangle function if possible.\r
+ */\r
+static triangle_func choose_triangle_function( GLcontext *ctx )\r
+{\r
+   if (ctx->Polygon.SmoothFlag)     return NULL;\r
+   if (ctx->Polygon.StippleFlag)    return NULL;\r
+   if (ctx->Texture.Enabled)        return NULL;\r
+\r
+   if (ctx->RasterMask==DEPTH_BIT\r
+       && ctx->Depth.Func==GL_LESS\r
+       && ctx->Depth.Mask==GL_TRUE\r
+       && ctx->Visual->RGBAflag) {\r
+       if (ctx->Light.ShadeModel==GL_SMOOTH) {\r
+         return smooth_color_z_triangle;\r
+      }\r
+      else {\r
+         return flat_color_z_triangle;\r
+      }\r
+   }\r
+   return NULL;\r
+}\r
+\r
+\r
+/* Draw a convex polygon using color Current->gl_ctx->VB->Color[pv] */\r
+static void fast_flat_rgb_polygon( GLcontext* ctx, GLuint n, GLuint vlist[], GLuint pv )\r
+{\r
+   STARTPROFILE\r
+   POINT *Pts=(POINT *) malloc(n*sizeof(POINT));\r
+   HDC DC=DD_GETDC;\r
+   HPEN Pen;\r
+   HBRUSH Brush;\r
+   HPEN Old_Pen;\r
+   HBRUSH Old_Brush;\r
+   GLint pixel;\r
+   GLuint i;\r
+\r
+   if (Current->gl_ctx->VB->MonoColor) {\r
+      pixel = Current->pixel;  /* use current color */\r
+   }\r
+   else {\r
+      pixel = RGB(Current->gl_ctx->VB->Color[pv][0]*255.0, Current->gl_ctx->VB->Color[pv][1]*255.0, Current->gl_ctx->VB->Color[pv][2]*255.0);\r
+   }\r
+\r
+   Pen=CreatePen(PS_SOLID,1,pixel);\r
+   Brush=CreateSolidBrush(pixel);\r
+   Old_Pen=SelectObject(DC,Pen);\r
+   Old_Brush=SelectObject(DC,Brush);\r
+\r
+   for (i=0; i<n; i++) {\r
+      int j = vlist[i];\r
+      Pts[i].x =       (int) Current->gl_ctx->VB->Win[j][0];\r
+      Pts[i].y = FLIP( (int) Current->gl_ctx->VB->Win[j][1] );\r
+   }\r
+\r
+   BEGINGDICALL\r
+\r
+   Polygon(DC,Pts,n);\r
+   SelectObject(DC,Old_Pen);\r
+   SelectObject(DC,Old_Brush);\r
+   DeleteObject(Pen);\r
+   DeleteObject(Brush);\r
+   DD_RELEASEDC;\r
+   free(Pts);\r
+\r
+   ENDGDICALL\r
+\r
+  ENDPROFILE(fast_flat_rgb_polygon)\r
+}\r
+\r
+\r
+\r
+/* Return pointer to accerated polygon function */\r
+static polygon_func choose_polygon_function( GLcontext* ctx )\r
+{\r
+       STARTPROFILE\r
+   if (!ctx->Polygon.SmoothFlag && !ctx->Polygon.StippleFlag\r
+       && ctx->Light.ShadeModel==GL_FLAT && ctx->RasterMask==0\r
+       && !ctx->Texture.Enabled && Current->rgb_flag==GL_TRUE) {\r
+   ENDPROFILE(choose_polygon_function)\r
+      return fast_flat_rgb_polygon;\r
+   }\r
+   else {\r
+   ENDPROFILE(choose_polygon_function)\r
+      return NULL;\r
+   }\r
+}\r
+\r
+\r
+\r
+/**********************************************************************/\r
+/*****                 Span-based pixel drawing                   *****/\r
+/**********************************************************************/\r
+\r
+\r
+/* Write a horizontal span of color-index pixels with a boolean mask. */\r
+static void write_index_span( GLcontext* ctx,\r
+                                                         GLuint n, GLint x, GLint y,\r
+                                                         const GLuint index[],\r
+                              const GLubyte mask[] )\r
+{\r
+         STARTPROFILE\r
+         GLuint i;\r
+         char *Mem=Current->ScreenMem+y*Current->ScanWidth+x;\r
+         assert(Current->rgb_flag==GL_FALSE);\r
+         for (i=0; i<n; i++)\r
+               if (mask[i])\r
+                 Mem[i]=index[i];\r
+          ENDPROFILE(write_index_span)\r
+}\r
+\r
+\r
+\r
+/*\r
+ * Write a horizontal span of pixels with a boolean mask.  The current\r
+ * color index is used for all pixels.\r
+ */\r
+static void write_monoindex_span(GLcontext* ctx,\r
+                                                                GLuint n,GLint x,GLint y,\r
+                                                                const GLubyte mask[])\r
+{\r
+         STARTPROFILE\r
+         GLuint i;\r
+         char *Mem=Current->ScreenMem+y*Current->ScanWidth+x;\r
+         assert(Current->rgb_flag==GL_FALSE);\r
+         for (i=0; i<n; i++)\r
+               if (mask[i])\r
+                 Mem[i]=Current->pixel;\r
+         ENDPROFILE(write_monoindex_span)\r
+}\r
+\r
+/*\r
+       To improve the performance of this routine, frob the data into an actual scanline\r
+       and call bitblt on the complete scan line instead of SetPixel.\r
+*/\r
+\r
+/* Write a horizontal span of color pixels with a boolean mask. */\r
+static void write_color_span( GLcontext* ctx,\r
+                         GLuint n, GLint x, GLint y,\r
+                         const GLubyte\r
+                         red[], const GLubyte green[],\r
+                         const GLubyte blue[], const GLubyte alpha[],\r
+                         const GLubyte mask[] )\r
+{\r
+       STARTPROFILE\r
+\r
+       PWMC    pwc = Current;\r
+\r
+       if (pwc->rgb_flag==GL_TRUE)\r
+       {\r
+               GLuint i;\r
+               HDC DC=DD_GETDC;\r
+               y=FLIP(y);\r
+\r
+               if (mask) {\r
+                       for (i=0; i<n; i++)\r
+                               if (mask[i])\r
+                                       wmSetPixel(pwc, y, x + i,red[i], green[i], blue[i]);\r
+               }\r
+\r
+               else {\r
+                       for (i=0; i<n; i++)\r
+                               wmSetPixel(pwc, y, x + i, red[i], green[i], blue[i]);\r
+               }\r
+\r
+               DD_RELEASEDC;\r
+\r
+       }\r
+\r
+  else\r
+  {\r
+               GLuint i;\r
+               char *Mem=Current->ScreenMem+y*Current->ScanWidth+x;\r
+               if (mask) {\r
+                  for (i=0; i<n; i++)\r
+                        if (mask[i])\r
+                          Mem[i]=GetNearestPaletteIndex(Current->hPal,RGB(red[i],green[i],blue[i]));\r
+               }\r
+               else {\r
+                  for (i=0; i<n; i++)\r
+                        Mem[i]=GetNearestPaletteIndex(Current->hPal,RGB(red[i],green[i],blue[i]));\r
+                       }\r
+       }\r
+   ENDPROFILE(write_color_span)\r
+\r
+}\r
+\r
+/*\r
+ * Write a horizontal span of pixels with a boolean mask.  The current color\r
+ * is used for all pixels.\r
+ */\r
+static void write_monocolor_span( GLcontext* ctx,\r
+                                                                 GLuint n, GLint x, GLint y,\r
+                                                                 const GLubyte mask[])\r
+{\r
+  STARTPROFILE\r
+  GLuint i;\r
+  HDC DC=DD_GETDC;\r
+  PWMC pwc = Current;\r
+\r
+  assert(Current->rgb_flag==GL_TRUE);\r
+  y=FLIP(y);\r
+\r
+  if(Current->rgb_flag==GL_TRUE){\r
+         for (i=0; i<n; i++)\r
+               if (mask[i])\r
+// Trying\r
+               wmSetPixel(pwc,y,x+i,GetRValue(Current->pixel), GetGValue(Current->pixel), GetBValue(Current->pixel));\r
+  }\r
+  else {\r
+         for (i=0; i<n; i++)\r
+               if (mask[i])\r
+                       SetPixel(DC, y, x+i, Current->pixel);\r
+  }\r
+\r
+       DD_RELEASEDC;\r
+\r
+       ENDPROFILE(write_monocolor_span)\r
+}\r
+\r
+\r
+\r
+/**********************************************************************/\r
+/*****                   Array-based pixel drawing                *****/\r
+/**********************************************************************/\r
+\r
+\r
+/* Write an array of pixels with a boolean mask. */\r
+static void write_index_pixels( GLcontext* ctx,\r
+                                                           GLuint n, const GLint x[], const GLint y[],\r
+                                                               const GLuint index[], const GLubyte mask[] )\r
+{\r
+   STARTPROFILE\r
+   GLuint i;\r
+   assert(Current->rgb_flag==GL_FALSE);\r
+   for (i=0; i<n; i++) {\r
+      if (mask[i]) {\r
+         char *Mem=Current->ScreenMem+y[i]*Current->ScanWidth+x[i];\r
+                  *Mem = index[i];\r
+      }\r
+   }\r
+   ENDPROFILE(write_index_pixels)\r
+}\r
+\r
+\r
+\r
+/*\r
+ * Write an array of pixels with a boolean mask.  The current color\r
+ * index is used for all pixels.\r
+ */\r
+static void write_monoindex_pixels( GLcontext* ctx,\r
+                                                                   GLuint n,\r
+                                                                       const GLint x[], const GLint y[],\r
+                                    const GLubyte mask[] )\r
+{\r
+   STARTPROFILE\r
+   GLuint i;\r
+   assert(Current->rgb_flag==GL_FALSE);\r
+   for (i=0; i<n; i++) {\r
+      if (mask[i]) {\r
+         char *Mem=Current->ScreenMem+y[i]*Current->ScanWidth+x[i];\r
+                       *Mem = Current->pixel;\r
+      }\r
+   }\r
+   ENDPROFILE(write_monoindex_pixels)\r
+}\r
+\r
+\r
+\r
+/* Write an array of pixels with a boolean mask. */\r
+static void write_color_pixels( GLcontext* ctx,\r
+                                                           GLuint n, const GLint x[], const GLint y[],\r
+                                                               const GLubyte r[], const GLubyte g[],\r
+                                const GLubyte b[], const GLubyte a[],\r
+                                const GLubyte mask[] )\r
+{\r
+       STARTPROFILE\r
+       GLuint i;\r
+       PWMC    pwc = Current;\r
+       HDC DC=DD_GETDC;\r
+       assert(Current->rgb_flag==GL_TRUE);\r
+       for (i=0; i<n; i++)\r
+               if (mask[i])\r
+                       wmSetPixel(pwc, FLIP(y[i]),x[i],r[i],g[i],b[i]);\r
+       DD_RELEASEDC;\r
+       ENDPROFILE(write_color_pixels)\r
+}\r
+\r
+\r
+\r
+/*\r
+ * Write an array of pixels with a boolean mask.  The current color\r
+ * is used for all pixels.\r
+ */\r
+static void write_monocolor_pixels( GLcontext* ctx,\r
+                                                                   GLuint n,\r
+                                                                       const GLint x[], const GLint y[],\r
+                                    const GLubyte mask[] )\r
+{\r
+       STARTPROFILE\r
+       GLuint i;\r
+       PWMC    pwc = Current;\r
+       HDC DC=DD_GETDC;\r
+       assert(Current->rgb_flag==GL_TRUE);\r
+       for (i=0; i<n; i++)\r
+               if (mask[i])\r
+                       wmSetPixel(pwc, FLIP(y[i]),x[i],GetRValue(Current->pixel),\r
+                                           GetGValue(Current->pixel), GetBValue(Current->pixel));\r
+       DD_RELEASEDC;\r
+       ENDPROFILE(write_monocolor_pixels)\r
+}\r
+\r
+\r
+\r
+/**********************************************************************/\r
+/*****            Read spans/arrays of pixels                     *****/\r
+/**********************************************************************/\r
+\r
+\r
+/* Read a horizontal span of color-index pixels. */\r
+static void read_index_span( GLcontext* ctx, GLuint n, GLint x, GLint y, GLuint index[])\r
+{\r
+  STARTPROFILE\r
+  GLuint i;\r
+  char *Mem=Current->ScreenMem+y*Current->ScanWidth+x;\r
+  assert(Current->rgb_flag==GL_FALSE);\r
+  for (i=0; i<n; i++)\r
+    index[i]=Mem[i];\r
+  ENDPROFILE(read_index_span)\r
+\r
+}\r
+\r
+\r
+\r
+\r
+/* Read an array of color index pixels. */\r
+static void read_index_pixels( GLcontext* ctx,\r
+                                                          GLuint n, const GLint x[], const GLint y[],\r
+                                                          GLuint indx[], const GLubyte mask[] )\r
+{\r
+   STARTPROFILE\r
+   GLuint i;\r
+  assert(Current->rgb_flag==GL_FALSE);\r
+  for (i=0; i<n; i++) {\r
+     if (mask[i]) {\r
+        indx[i]=*(Current->ScreenMem+y[i]*Current->ScanWidth+x[i]);\r
+     }\r
+  }\r
+   ENDPROFILE(read_index_pixels)\r
+}\r
+\r
+\r
+\r
+/* Read a horizontal span of color pixels. */\r
+static void read_color_span( GLcontext* ctx,\r
+                                                        GLuint n, GLint x, GLint y,\r
+                                                        GLubyte red[], GLubyte green[],\r
+                             GLubyte blue[], GLubyte alpha[] )\r
+{\r
+   STARTPROFILE\r
+  UINT i;\r
+  COLORREF Color;\r
+  HDC DC=DD_GETDC;\r
+  assert(Current->rgb_flag==GL_TRUE);\r
+  y=FLIP(y);\r
+  for (i=0; i<n; i++)\r
+  {\r
+    Color=GetPixel(DC,x+i,y);\r
+    red[i]=GetRValue(Color);\r
+    green[i]=GetGValue(Color);\r
+    blue[i]=GetBValue(Color);\r
+    alpha[i]=255;\r
+  }\r
+  DD_RELEASEDC;\r
+  memset(alpha,0,n*sizeof(GLint));\r
+   ENDPROFILE(read_color_span)\r
+}\r
+\r
+\r
+/* Read an array of color pixels. */\r
+static void read_color_pixels( GLcontext* ctx,\r
+                                                          GLuint n, const GLint x[], const GLint y[],\r
+                                                          GLubyte red[], GLubyte green[],\r
+                               GLubyte blue[], GLubyte alpha[],\r
+                               const GLubyte mask[] )\r
+{\r
+   STARTPROFILE\r
+  GLuint i;\r
+  COLORREF Color;\r
+  HDC DC=DD_GETDC;\r
+  assert(Current->rgb_flag==GL_TRUE);\r
+  for (i=0; i<n; i++) {\r
+     if (mask[i]) {\r
+        Color=GetPixel(DC,x[i],FLIP(y[i]));\r
+        red[i]=GetRValue(Color);\r
+        green[i]=GetGValue(Color);\r
+        blue[i]=GetBValue(Color);\r
+        alpha[i]=255;\r
+     }\r
+  }\r
+  DD_RELEASEDC;\r
+  memset(alpha,0,n*sizeof(GLint));\r
+   ENDPROFILE(read_color_pixels)\r
+}\r
+\r
+\r
+\r
+/**********************************************************************/\r
+/**********************************************************************/\r
+\r
+\r
+\r
+void setup_DD_pointers( GLcontext* ctx )\r
+{\r
+   ctx->Driver.Finish = finish;\r
+   ctx->Driver.Flush = flush;\r
+\r
+   ctx->Driver.ClearIndex = clear_index;\r
+   ctx->Driver.ClearColor = clear_color;\r
+   ctx->Driver.Clear = clear;\r
+\r
+   ctx->Driver.Index = set_index;\r
+   ctx->Driver.Color = set_color;\r
+   ctx->Driver.IndexMask = index_mask;\r
+   ctx->Driver.ColorMask = color_mask;\r
+\r
+   ctx->Driver.LogicOp = logicop;\r
+   ctx->Driver.Dither = dither;\r
+\r
+   ctx->Driver.SetBuffer = set_buffer;\r
+   ctx->Driver.GetBufferSize = buffer_size;\r
+\r
+   ctx->Driver.PointsFunc = choose_points_function(ctx);\r
+   ctx->Driver.LineFunc = choose_line_function(ctx);\r
+   ctx->Driver.TriangleFunc = choose_triangle_function( ctx );\r
+   //   ctx->Driver.TriangleFunc = choose_polygon_function(ctx);\r
+\r
+   /* Pixel/span writing functions: */\r
+   ctx->Driver.WriteColorSpan       = write_color_span;\r
+   ctx->Driver.WriteMonocolorSpan   = write_monocolor_span;\r
+   ctx->Driver.WriteColorPixels     = write_color_pixels;\r
+   ctx->Driver.WriteMonocolorPixels = write_monocolor_pixels;\r
+   ctx->Driver.WriteIndexSpan       = write_index_span;\r
+   ctx->Driver.WriteMonoindexSpan   = write_monoindex_span;\r
+   ctx->Driver.WriteIndexPixels     = write_index_pixels;\r
+   ctx->Driver.WriteMonoindexPixels = write_monoindex_pixels;\r
+\r
+   /* Pixel/span reading functions: */\r
+   ctx->Driver.ReadIndexSpan = read_index_span;\r
+   ctx->Driver.ReadColorSpan = read_color_span;\r
+   ctx->Driver.ReadIndexPixels = read_index_pixels;\r
+   ctx->Driver.ReadColorPixels = read_color_pixels;\r
+}\r
+\r
+//\r
+// MesaGL32 is the DLL version of MesaGL for Win32\r
+//\r
+\r
+/**********************************************************************/\r
+/*****                  WMesa API Functions                       *****/\r
+/**********************************************************************/\r
+\r
+\r
+\r
+#define PAL_SIZE 256\r
+static void GetPalette(HPALETTE Pal,RGBQUAD *aRGB)\r
+{\r
+   STARTPROFILE\r
+       int i;\r
+       HDC hdc;\r
+       struct\r
+       {\r
+               WORD Version;\r
+               WORD NumberOfEntries;\r
+               PALETTEENTRY aEntries[PAL_SIZE];\r
+       } Palette =\r
+       {\r
+               0x300,\r
+               PAL_SIZE\r
+       };\r
+       hdc=GetDC(NULL);\r
+       if (Pal!=NULL)\r
+    GetPaletteEntries(Pal,0,PAL_SIZE,Palette.aEntries);\r
+  else\r
+    GetSystemPaletteEntries(hdc,0,PAL_SIZE,Palette.aEntries);\r
+       if (GetSystemPaletteUse(hdc) == SYSPAL_NOSTATIC)\r
+       {\r
+               for(i = 0; i <PAL_SIZE; i++)\r
+                       Palette.aEntries[i].peFlags = PC_RESERVED;\r
+               Palette.aEntries[255].peRed = 255;\r
+               Palette.aEntries[255].peGreen = 255;\r
+               Palette.aEntries[255].peBlue = 255;\r
+               Palette.aEntries[255].peFlags = 0;\r
+               Palette.aEntries[0].peRed = 0;\r
+               Palette.aEntries[0].peGreen = 0;\r
+               Palette.aEntries[0].peBlue = 0;\r
+               Palette.aEntries[0].peFlags = 0;\r
+       }\r
+       else\r
+       {\r
+               int nStaticColors;\r
+               int nUsableColors;\r
+               nStaticColors = GetDeviceCaps(hdc, NUMCOLORS)/2;\r
+               for (i=0; i<nStaticColors; i++)\r
+                       Palette.aEntries[i].peFlags = 0;\r
+               nUsableColors = PAL_SIZE-nStaticColors;\r
+               for (; i<nUsableColors; i++)\r
+                       Palette.aEntries[i].peFlags = PC_RESERVED;\r
+               for (; i<PAL_SIZE-nStaticColors; i++)\r
+                       Palette.aEntries[i].peFlags = PC_RESERVED;\r
+               for (i=PAL_SIZE-nStaticColors; i<PAL_SIZE; i++)\r
+                       Palette.aEntries[i].peFlags = 0;\r
+       }\r
+       ReleaseDC(NULL,hdc);\r
+  for (i=0; i<PAL_SIZE; i++)\r
+  {\r
+    aRGB[i].rgbRed=Palette.aEntries[i].peRed;\r
+    aRGB[i].rgbGreen=Palette.aEntries[i].peGreen;\r
+    aRGB[i].rgbBlue=Palette.aEntries[i].peBlue;\r
+    aRGB[i].rgbReserved=Palette.aEntries[i].peFlags;\r
+  }\r
+         ENDPROFILE(GetPalette)\r
+}\r
+\r
+\r
+WMesaContext /*APIENTRY*/ WMesaCreateContext( HWND hWnd, HPALETTE Pal,\r
+                                                                                        /*HDC hDC,*/ GLboolean rgb_flag,\r
+                                                                                         GLboolean db_flag )\r
+{\r
+  BITMAPINFO *Rec;\r
+  //HDC DC;\r
+  RECT CR;\r
+  WMesaContext c;\r
+\r
+  c = (struct wmesa_context * ) calloc(1,sizeof(struct wmesa_context));\r
+  if (!c)\r
+    return NULL;\r
+\r
+  c->Window=hWnd;\r
+  c->hDC = GetDC(hWnd);\r
+\r
+  if (rgb_flag==GL_FALSE)\r
+  {\r
+    c->rgb_flag = GL_FALSE;\r
+    c->pixel = 1;\r
+    db_flag=GL_TRUE; // WinG requires double buffering\r
+    //c->gl_ctx->BufferDepth = windepth;\r
+  }\r
+  else\r
+  {\r
+    c->rgb_flag = GL_TRUE;\r
+    c->pixel = 0;\r
+  }\r
+  GetClientRect(c->Window,&CR);\r
+  c->width=CR.right;\r
+  c->height=CR.bottom;\r
+  if (db_flag)\r
+  {\r
+    c->db_flag = 1;\r
+//     c->hDC GetDC(c->Window);\r
+       /* Double buffered */\r
+    if (c->rgb_flag==GL_TRUE)\r
+    {\r
+      //DC = c->hDC = hDC;\r
+\r
+//             DC = c->hDC = GetDC(c->Window);\r
+               wmCreateBackingStore(c, c->width, c->height);\r
+//             ReleaseDC(c->Window,DC);\r
+    }\r
+    else\r
+    {\r
+      c->dib.hDC=WinGCreateDC();\r
+      Rec=(BITMAPINFO *) malloc(sizeof(BITMAPINFO)+(PAL_SIZE-1)*sizeof(RGBQUAD));\r
+      c->hPal=Pal;\r
+      GetPalette(Pal,Rec->bmiColors);\r
+      WinGRecommendDIBFormat(Rec);\r
+      Rec->bmiHeader.biWidth=c->width;\r
+      Rec->bmiHeader.biHeight*=c->height;\r
+      Rec->bmiHeader.biClrUsed=PAL_SIZE;\r
+      if (Rec->bmiHeader.biPlanes!=1 || Rec->bmiHeader.biBitCount!=8)\r
+      {\r
+        MessageBox(NULL,"Error.","This code presumes a 256 color, single plane, WinG Device.\n",MB_OK);\r
+        exit(1);\r
+      }\r
+      c->Compat_BM=WinGCreateBitmap(c->dib.hDC,Rec,&((void *) c->ScreenMem));\r
+      c->Old_Compat_BM=SelectObject(c->dib.hDC,c->Compat_BM);\r
+      WinGSetDIBColorTable(c->dib.hDC,0,PAL_SIZE,Rec->bmiColors);\r
+      c->IndexFormat=Rec;\r
+      c->ScanWidth=c->width;\r
+         c->cColorBits = 8;\r
+      if ((c->ScanWidth%sizeof(long))!=0)\r
+        c->ScanWidth+=(sizeof(long)-(c->ScanWidth%sizeof(long)));\r
+    }\r
+  }\r
+  else\r
+  {\r
+    /* Single Buffered */\r
+       c->db_flag = 0;\r
+\r
+//     wmCreateBackingStore(c, c->width, c->height);\r
+  }\r
+\r
+\r
+\r
+  c->gl_visual = gl_create_visual(rgb_flag,\r
+                                                                 GL_FALSE,     /* software alpha */\r
+                                  db_flag,     /* db_flag */\r
+                                  16,          /* depth_bits */\r
+                                  8,           /* stencil_bits */\r
+                                  8,           /* accum_bits */\r
+                                  8,\r
+                                  255.0, 255.0, 255.0, 255.0 );\r
+\r
+       if (!c->gl_visual) {\r
+         return NULL;\r
+      }\r
+\r
+  /* allocate a new Mesa context */\r
+  c->gl_ctx = gl_create_context( c->gl_visual, NULL,c);\r
+\r
+  if (!c->gl_ctx) {\r
+         gl_destroy_visual( c->gl_visual );\r
+         free(c);\r
+         return NULL;\r
+      }\r
+\r
+      c->gl_buffer = gl_create_framebuffer( c->gl_visual );\r
+      if (!c->gl_buffer) {\r
+         gl_destroy_visual( c->gl_visual );\r
+         gl_destroy_context( c->gl_ctx );\r
+         free(c);\r
+         return NULL;\r
+      }\r
+//  setup_DD_pointers(c->gl_ctx);\r
+\r
+  return c;\r
+}\r
+\r
+\r
+\r
+void /*APIENTRY*/ WMesaDestroyContext( void )\r
+{\r
+       WMesaContext c = Current;\r
+       ReleaseDC(c->Window,c->hDC);\r
+       WC = c;\r
+\r
+    gl_destroy_visual( c->gl_visual );\r
+    gl_destroy_framebuffer( c->gl_buffer );\r
+       gl_destroy_context( c->gl_ctx );\r
+\r
+       if (c->db_flag){\r
+               wmDeleteBackingStore(c);\r
+\r
+//Code added by Li Wei to enable parallel render\r
+#if !defined(NO_STEREO)\r
+               if(stereoBuffer==GL_TRUE){\r
+                       WMesaDestroyStereoBuffer();\r
+                       stereoBuffer=GL_FALSE;\r
+               }\r
+#endif\r
+// End modification\r
+       }\r
+       free( (void *) c );\r
+//Code added by Li Wei to enable parallel render\r
+// Parallel render only work in double buffer mode\r
+#if !defined(NO_PARALLEL)\r
+       if(parallelMachine)\r
+               PRDestroyRenderBuffer();\r
+#endif\r
+// End modification\r
+}\r
+\r
+\r
+\r
+void /*APIENTRY*/ WMesaMakeCurrent( WMesaContext c )\r
+{\r
+       if(!c){\r
+               Current = c;\r
+               return;\r
+       }\r
+\r
+       //\r
+       // A little optimization\r
+       // If it already is current,\r
+       // don't set it again\r
+       //\r
+       if(Current == c)\r
+               return;\r
+\r
+       //gl_set_context( c->gl_ctx );\r
+       gl_make_current(c->gl_ctx, c->gl_buffer);\r
+       Current = c;\r
+       setup_DD_pointers(c->gl_ctx);\r
+       if (Current->gl_ctx->Viewport.Width==0) {\r
+         /* initialize viewport to window size */\r
+         gl_Viewport( Current->gl_ctx,\r
+                          0, 0, Current->width, Current->height );\r
+       }\r
+}\r
+\r
+\r
+\r
+void /*APIENTRY*/ WMesaSwapBuffers( void )\r
+{\r
+  HDC DC = Current->hDC;\r
+  if (Current->db_flag)\r
+  {\r
+    if (Current->rgb_flag)\r
+               wmFlush(Current);\r
+    else\r
+      WinGBitBlt(DC,0,0,Current->width,Current->height,Current->dib.hDC,0,0);\r
+  }\r
+}\r
+\r
+\r
+\r
+void /*APIENTRY*/ WMesaPaletteChange(HPALETTE Pal)\r
+{\r
+  if (Current && Current->rgb_flag==GL_FALSE)\r
+  {\r
+    Current->hPal=Pal;\r
+    GetPalette(Pal,Current->IndexFormat->bmiColors);\r
+    WinGSetDIBColorTable(Current->dib.hDC,0,PAL_SIZE,Current->IndexFormat->bmiColors);\r
+  }\r
+}\r
+\r
+//\r
+// Free up the dib section that was created\r
+//\r
+BOOL wmDeleteBackingStore(PWMC pwc)\r
+{\r
+       SelectObject(pwc->dib.hDC, pwc->hOldBitmap);\r
+       DeleteDC(pwc->dib.hDC);\r
+       DeleteObject(pwc->hbmDIB);\r
+       UnmapViewOfFile(pwc->dib.base);\r
+       CloseHandle(pwc->dib.hFileMap);\r
+       return TRUE;\r
+}\r
+\r
+\r
+//\r
+// This function creates the DIB section that is used for combined\r
+// GL and GDI calls\r
+//\r
+BOOL /*WINAPI*/ wmCreateBackingStore(PWMC pwc, long lxSize, long lySize)\r
+{\r
+    HDC hdc = pwc->hDC;\r
+    LPBITMAPINFO pbmi = &(pwc->bmi);\r
+       int             iUsage;\r
+\r
+    pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);\r
+    pbmi->bmiHeader.biWidth = lxSize;\r
+    pbmi->bmiHeader.biHeight= -lySize;\r
+    pbmi->bmiHeader.biPlanes = 1;\r
+    pbmi->bmiHeader.biBitCount = GetDeviceCaps(pwc->hDC, BITSPIXEL);\r
+    pbmi->bmiHeader.biCompression = BI_RGB;\r
+    pbmi->bmiHeader.biSizeImage = 0;\r
+    pbmi->bmiHeader.biXPelsPerMeter = 0;\r
+    pbmi->bmiHeader.biYPelsPerMeter = 0;\r
+    pbmi->bmiHeader.biClrUsed = 0;\r
+    pbmi->bmiHeader.biClrImportant = 0;\r
+\r
+       iUsage = (pbmi->bmiHeader.biBitCount <= 8) ? DIB_PAL_COLORS : DIB_RGB_COLORS;\r
+\r
+       pwc->cColorBits = pbmi->bmiHeader.biBitCount;\r
+       pwc->ScanWidth = lxSize;\r
+\r
+       wmCreateDIBSection(hdc, pwc, pbmi, iUsage);\r
+\r
+       if ((iUsage == DIB_PAL_COLORS) && !(pwc->hGLPalette)) {\r
+               wmCreatePalette( pwc );\r
+               wmSetDibColors( pwc );\r
+       }\r
+\r
+       return(TRUE);\r
+\r
+}\r
+\r
+\r
+//\r
+// This function copies one scan line in a DIB section to another\r
+//\r
+BOOL GLWINAPI wmSetDIBits(PWMC pwc, UINT uiScanWidth, UINT uiNumScans, UINT nBypp, UINT uiNewWidth, LPBYTE pBits)\r
+{\r
+       UINT uiScans = 0;\r
+       LPBYTE  pDest = pwc->pbPixels;\r
+       DWORD   dwNextScan = uiScanWidth;\r
+       DWORD   dwNewScan = uiNewWidth;\r
+       DWORD   dwScanWidth = (uiScanWidth * nBypp);\r
+\r
+       //\r
+       // We need to round up to the nearest DWORD\r
+       // and multiply by the number of bytes per\r
+       // pixel\r
+       //\r
+       dwNextScan = (((dwNextScan * nBypp)+ 3) & ~3);\r
+       dwNewScan = (((dwNewScan * nBypp)+ 3) & ~3);\r
+\r
+       for(uiScans = 0; uiScans < uiNumScans; uiScans++){\r
+               CopyMemory(pDest, pBits, dwScanWidth);\r
+               pBits += dwNextScan;\r
+               pDest += dwNewScan;\r
+       }\r
+\r
+       return(TRUE);\r
+\r
+}\r
+\r
+BOOL GLWINAPI wmSetPixelFormat( PWMC pwdc, HDC hDC, DWORD dwFlags )\r
+{\r
+       return(TRUE);\r
+}\r
+\r
+static unsigned char threeto8[8] = {\r
+       0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377\r
+};\r
+\r
+static unsigned char twoto8[4] = {\r
+       0, 0x55, 0xaa, 0xff\r
+};\r
+\r
+static unsigned char oneto8[2] = {\r
+       0, 255\r
+};\r
+\r
+static unsigned char componentFromIndex(UCHAR i, UINT nbits, UINT shift)\r
+{\r
+       unsigned char val;\r
+\r
+       val = i >> shift;\r
+       switch (nbits) {\r
+\r
+               case 1:\r
+                       val &= 0x1;\r
+                       return oneto8[val];\r
+\r
+               case 2:\r
+                       val &= 0x3;\r
+                       return twoto8[val];\r
+\r
+               case 3:\r
+                       val &= 0x7;\r
+                       return threeto8[val];\r
+\r
+               default:\r
+                       return 0;\r
+       }\r
+}\r
+\r
+void /*WINAPI*/ wmCreatePalette( PWMC pwdc )\r
+{\r
+    /* Create a compressed and re-expanded 3:3:2 palette */\r
+       int            i;\r
+       LOGPALETTE     *pPal;\r
+    BYTE           rb, rs, gb, gs, bb, bs;\r
+\r
+    pwdc->nColors = 0x100;\r
+\r
+       pPal = (PLOGPALETTE)malloc(sizeof(LOGPALETTE) + pwdc->nColors * sizeof(PALETTEENTRY));\r
+    memset( pPal, 0, sizeof(LOGPALETTE) + pwdc->nColors * sizeof(PALETTEENTRY) );\r
+\r
+       pPal->palVersion = 0x300;\r
+\r
+    rb = REDBITS;\r
+    rs = REDSHIFT;\r
+    gb = GREENBITS;\r
+    gs = GREENSHIFT;\r
+    bb = BLUEBITS;\r
+    bs = BLUESHIFT;\r
+\r
+    if (pwdc->db_flag) {\r
+\r
+        /* Need to make two palettes: one for the screen DC and one for the DIB. */\r
+           pPal->palNumEntries = pwdc->nColors;\r
+           for (i = 0; i < pwdc->nColors; i++) {\r
+                   pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs );\r
+                   pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs );\r
+                   pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs );\r
+                   pPal->palPalEntry[i].peFlags = 0;\r
+           }\r
+       pwdc->hGLPalette = CreatePalette( pPal );\r
+       pwdc->hPalette = CreatePalette( pPal );\r
+    }\r
+\r
+       else {\r
+           pPal->palNumEntries = pwdc->nColors;\r
+           for (i = 0; i < pwdc->nColors; i++) {\r
+                   pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs );\r
+                   pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs );\r
+                   pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs );\r
+                   pPal->palPalEntry[i].peFlags = 0;\r
+           }\r
+       pwdc->hGLPalette = CreatePalette( pPal );\r
+    }\r
+\r
+       free(pPal);\r
+\r
+}\r
+\r
+//\r
+// This function sets the color table of a DIB section\r
+// to match that of the destination DC\r
+//\r
+BOOL /*WINAPI*/ wmSetDibColors(PWMC pwc)\r
+{\r
+    RGBQUAD                    *pColTab, *pRGB;\r
+    PALETTEENTRY       *pPal, *pPE;\r
+    int                                i, nColors;\r
+       BOOL                    bRet=TRUE;\r
+       DWORD                   dwErr=0;\r
+\r
+    /* Build a color table in the DIB that maps to the\r
+       selected palette in the DC.\r
+       */\r
+    nColors = 1 << pwc->cColorBits;\r
+       pPal = (PALETTEENTRY *)malloc( nColors * sizeof(PALETTEENTRY));\r
+    memset( pPal, 0, nColors * sizeof(PALETTEENTRY) );\r
+    GetPaletteEntries( pwc->hGLPalette, 0, nColors, pPal );\r
+    pColTab = (RGBQUAD *)malloc( nColors * sizeof(RGBQUAD));\r
+    for (i = 0, pRGB = pColTab, pPE = pPal; i < nColors; i++, pRGB++, pPE++) {\r
+        pRGB->rgbRed = pPE->peRed;\r
+        pRGB->rgbGreen = pPE->peGreen;\r
+        pRGB->rgbBlue = pPE->peBlue;\r
+    }\r
+       if(pwc->db_flag)\r
+           bRet = SetDIBColorTable(pwc->hDC, 0, nColors, pColTab );\r
+\r
+       if(!bRet)\r
+               dwErr = GetLastError();\r
+\r
+    free( pColTab );\r
+    free( pPal );\r
+\r
+       return(bRet);\r
+}\r
+\r
+void /*WINAPI*/ wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)\r
+{\r
+       if(Current->db_flag){\r
+               LPBYTE  lpb = pwc->pbPixels;\r
+               LPDWORD lpdw;\r
+               LPWORD  lpw;\r
+               UINT    nBypp = pwc->cColorBits / 8;\r
+               UINT    nOffset = iPixel % nBypp;\r
+\r
+               // Move the pixel buffer pointer to the scanline that we\r
+               // want to access\r
+\r
+               pwc->dib.fFlushed = FALSE;\r
+\r
+               lpb += pwc->ScanWidth * iScanLine;\r
+               // Now move to the desired pixel\r
+               lpb += iPixel * nBypp;\r
+\r
+               lpdw = (LPDWORD)lpb;\r
+               lpw = (LPWORD)lpb;\r
+\r
+               if(nBypp == 2)\r
+                       *lpw = BGR16(r,g,b);\r
+               else if (nBypp == 3){\r
+                       *lpdw = BGR24(r,g,b);\r
+               }\r
+               else\r
+                       *lpdw = BGR32(r,g,b);\r
+       }\r
+       else{\r
+               HDC DC = DD_GETDC;\r
+               SetPixel(DC, iPixel, iScanLine, RGB(r,g,b));\r
+               DD_RELEASEDC;\r
+       }\r
+}\r
+\r
+void /*WINAPI*/ wmCreateDIBSection(\r
+       HDC      hDC,\r
+    PWMC pwc,  // handle of device context\r
+    CONST BITMAPINFO *pbmi,    // address of structure containing bitmap size, format, and color data\r
+    UINT iUsage        // color data type indicator: RGB values or palette indices\r
+)\r
+{\r
+       DWORD   dwSize = 0;\r
+       DWORD   dwScanWidth;\r
+       UINT    nBypp = pwc->cColorBits / 8;\r
+       HDC             hic;\r
+\r
+       dwScanWidth = (((pwc->ScanWidth * nBypp)+ 3) & ~3);\r
+\r
+       pwc->ScanWidth = dwScanWidth;\r
+\r
+       dwSize = sizeof(BITMAPINFO) + (dwScanWidth * pwc->height);\r
+\r
+       pwc->dib.hFileMap = CreateFileMapping((HANDLE)PAGE_FILE,\r
+                                                                                 NULL,\r
+                                                                                 PAGE_READWRITE | SEC_COMMIT,\r
+                                                                                 0,\r
+                                                                                 dwSize,\r
+                                                                                 NULL);\r
+\r
+       if (!pwc->dib.hFileMap)\r
+               return;\r
+\r
+       pwc->dib.base = MapViewOfFile(pwc->dib.hFileMap,\r
+                                                                 FILE_MAP_ALL_ACCESS,\r
+                                                                 0,\r
+                                                                 0,\r
+                                                                 0);\r
+\r
+       if(!pwc->dib.base){\r
+               CloseHandle(pwc->dib.hFileMap);\r
+               return;\r
+       }\r
+\r
+       pwc->pbPixels = ((LPBYTE)pwc->dib.base) + sizeof(BITMAPINFO);\r
+\r
+       pwc->dib.hDC = CreateCompatibleDC(hDC);\r
+\r
+       CopyMemory(pwc->dib.base, pbmi, sizeof(BITMAPINFO));\r
+\r
+       hic = CreateIC("display", NULL, NULL, NULL);\r
+\r
+/*     pwc->hbmDIB = CreateDIBitmap(hic,\r
+                                                &(pwc->bmi.bmiHeader),\r
+                                                CBM_INIT,\r
+                                                pwc->pbPixels,\r
+                                                &(pwc->bmi),\r
+                                                DIB_RGB_COLORS);\r
+*/\r
+  pwc->hbmDIB = CreateDIBSection(hic,\r
+                                               &(pwc->bmi.bmiHeader),\r
+                                               DIB_RGB_COLORS,\r
+                                               &(pwc->pbPixels),\r
+                                               pwc->dib.hFileMap,\r
+                                               0);\r
+       pwc->hOldBitmap = SelectObject(pwc->dib.hDC, pwc->hbmDIB);\r
+\r
+       DeleteDC(hic);\r
+\r
+       return;\r
+\r
+}\r
+\r
+//\r
+// Blit memory DC to screen DC\r
+//\r
+BOOL /*WINAPI*/ wmFlush(PWMC pwc)\r
+{\r
+       BOOL    bRet = 0;\r
+       DWORD   dwErr = 0;\r
+\r
+\r
+//     wmFlushBits(pwc);\r
+\r
+       bRet = BitBlt(pwc->hDC, 0, 0, pwc->width, pwc->height,\r
+                  pwc->dib.hDC, 0, 0, SRCCOPY);\r
+\r
+       if(!bRet)\r
+               dwErr = GetLastError();\r
+\r
+       pwc->dib.fFlushed = TRUE;\r
+\r
+       return(TRUE);\r
+\r
+}\r
+\r
+\r
+// The following code is added by Li Wei to enable stereo display\r
+\r
+#if !defined(NO_STEREO)\r
+\r
+void WMesaCreateStereoBuffer()\r
+{\r
+       /* Must use double buffer and not in parallelMode */\r
+       if (! Current->db_flag\r
+#if !defined(NO_PARALLEL)\r
+               || parallelFlag\r
+#endif\r
+               )\r
+               return;\r
+\r
+       Buffer_Stereo = malloc( Current->ScanWidth * Current->height);\r
+       ZeroMemory(Buffer_Stereo,Current->ScanWidth * Current->height);\r
+       stereoBuffer = GL_TRUE ;\r
+}\r
+\r
+void WMesaDestroyStereoBuffer()\r
+{\r
+       /* Must use double buffer and not in parallelMode */\r
+       if (! Current->db_flag\r
+#if !defined(NO_PARALLEL)\r
+               || parallelFlag\r
+#endif\r
+               )\r
+               return;\r
+       if(stereoBuffer){\r
+               free(Buffer_Stereo);\r
+               stereoBuffer = GL_FALSE ;\r
+       }\r
+}\r
+\r
+void WMesaInterleave(GLenum aView)\r
+{\r
+       int offset;\r
+       unsigned line;\r
+       LPBYTE dest;\r
+       LPBYTE src;\r
+       if(aView == FIRST)\r
+               offset = 0;\r
+       else offset = 1;\r
+\r
+       dest = Buffer_Stereo + offset * Current->ScanWidth;\r
+       if(Current->rgb_flag )\r
+               src = Current->pbPixels + Current->ScanWidth*(Current->height/2);\r
+       else\r
+               src = Current->ScreenMem;\r
+\r
+       for(line = 0; line<Current->height/2; line ++){\r
+               CopyMemory(dest, src, Current->ScanWidth);\r
+               dest += 2*Current->ScanWidth;\r
+               src += Current->ScanWidth;\r
+       }\r
+       if(aView == SECOND)\r
+               if(Current->rgb_flag)\r
+                       CopyMemory(Current->pbPixels, Buffer_Stereo, Current->ScanWidth*Current->height);\r
+               else\r
+                       CopyMemory(Current->ScreenMem, Buffer_Stereo, Current->ScanWidth*Current->height);\r
+}\r
+\r
+void WMesaShowStereo(GLuint list)\r
+{\r
+\r
+       GLbitfield mask = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;\r
+       GLfloat cm[16];\r
+       // Must use double Buffer\r
+       if( ! Current-> db_flag )\r
+               return;\r
+\r
+       glViewport(0,0,Current->width,Current->height/2);\r
+\r
+       glGetFloatv(GL_MODELVIEW_MATRIX,cm);\r
+       glMatrixMode(GL_MODELVIEW);\r
+       glLoadIdentity();\r
+       gluLookAt(viewDistance/2,0.0,0.0 ,\r
+                        viewDistance/2,0.0,-1.0,\r
+                        0.0,1.0,0.0 );\r
+       glMultMatrixf( cm );\r
+       glMatrixMode(GL_MODELVIEW);\r
+       glPushMatrix();\r
+       glCallList( list );\r
+       glPopMatrix();\r
+       glFlush();\r
+       WMesaInterleave( FIRST );\r
+\r
+       glGetFloatv(GL_MODELVIEW_MATRIX,cm);\r
+       glMatrixMode(GL_MODELVIEW);\r
+       glLoadIdentity();\r
+       gluLookAt(-viewDistance/2,0.0,0.0 ,\r
+                        -viewDistance/2,0.0,-1.0,\r
+                        0.0,1.0,0.0 );\r
+       glMultMatrixf(cm);\r
+       glMatrixMode(GL_MODELVIEW);\r
+       glCallList(list);\r
+       glFlush();\r
+       WMesaInterleave( SECOND );\r
+       glViewport(0,0,Current->width,Current->height);\r
+       WMesaSwapBuffers();\r
+\r
+}\r
+\r
+void toggleStereoMode()\r
+{\r
+       if(!Current->db_flag)\r
+               return;\r
+       if(!stereo_flag){\r
+               stereo_flag = 1;\r
+               if(stereoBuffer==GL_FALSE)\r
+#if !defined(NO_PARALLEL)\r
+                       if(!parallelFlag)\r
+#endif\r
+               {\r
+                       WMesaCreateStereoBuffer();\r
+                       }\r
+       }\r
+       else {\r
+               stereo_flag = 0;\r
+       if(stereoBuffer==GL_TRUE)\r
+#if !defined(NO_PARALLEL)\r
+               if(!parallelFlag)\r
+#endif\r
+                       if(stereoBuffer==GL_TRUE){\r
+                               WMesaDestroyStereoBuffer();\r
+                       }\r
+       }\r
+}\r
+\r
+/* if in stereo mode, the following function is called */\r
+void glShowStereo(GLuint list)\r
+{\r
+       WMesaShowStereo(list);\r
+}\r
+\r
+#endif // End if NO_STEREO not defined\r
+\r
+#if !defined(NO_PARALLEL)\r
+\r
+void toggleParallelMode(void)\r
+{\r
+       if(!parallelFlag){\r
+               parallelFlag = GL_TRUE;\r
+               if(parallelMachine==GL_FALSE){\r
+                               PRCreateRenderBuffer( Current->rgb_flag? GL_RGBA :GL_COLOR_INDEX,\r
+                                                                         Current->cColorBits/8,\r
+                                                                         Current->width ,Current->height,\r
+                                                                         Current->ScanWidth,\r
+                                                                         Current->rgb_flag? Current->pbPixels: Current->ScreenMem);\r
+                               parallelMachine = GL_TRUE;\r
+                               }\r
+               }\r
+       else {\r
+               parallelFlag = GL_FALSE;\r
+               if(parallelMachine==GL_TRUE){\r
+                               PRDestroyRenderBuffer();\r
+                               parallelMachine=GL_FALSE;\r
+                               ReadyForNextFrame = GL_TRUE;\r
+                               }\r
+\r
+/***********************************************\r
+// Seems something wrong!!!!\r
+************************************************/\r
+\r
+               WMesaMakeCurrent(Current);\r
+#if !defined(NO_STEREO)\r
+               stereo_flag = GL_FALSE ;\r
+#endif\r
+       }\r
+}\r
+\r
+void PRShowRenderResult(void)\r
+{\r
+       int flag = 0;\r
+if(!glImageRendered())\r
+               return;\r
+\r
+  if (parallelFlag)\r
+       {\r
+         WMesaSwapBuffers();\r
+        }\r
+\r
+}\r
+#endif //End if NO_PARALLEL not defined\r
+\r
+//end modification\r
diff --git a/src/mesa/drivers/windows/wmesadef.h b/src/mesa/drivers/windows/wmesadef.h
new file mode 100644 (file)
index 0000000..7cd4bb9
--- /dev/null
@@ -0,0 +1,154 @@
+/*     File name       :       wmesadef.h\r
+ *  Version            :       2.3\r
+ *\r
+ *  Header file for display driver for Mesa 2.3  under\r
+ *     Windows95, WindowsNT and Win32\r
+ *\r
+ *     Copyright (C) 1996-  Li Wei\r
+ *  Address            :               Institute of Artificial Intelligence\r
+ *                             :                       & Robotics\r
+ *                             :               Xi'an Jiaotong University\r
+ *  Email              :               liwei@aiar.xjtu.edu.cn\r
+ *  Web page   :               http://sun.aiar.xjtu.edu.cn\r
+ *\r
+ *  This file and its associations are partially based on the\r
+ *  Windows NT driver for Mesa, written by Mark Leaming\r
+ *  (mark@rsinc.com).\r
+ */\r
+\r
+/*\r
+ * $Log: wmesadef.h,v $
+ * Revision 1.1  1999/08/19 00:55:42  jtg
+ * Initial revision
+ *
+ * Revision 1.3  1999/01/03 03:08:57  brianp
+ * Ted Jump's changes
+ *\r
+ * Initial version 1997/6/14 CST by Li Wei(liwei@aiar.xjtu.edu.cn)\r
+ */\r
+\r
+/*\r
+ * $Log: wmesadef.h,v $
+ * Revision 1.1  1999/08/19 00:55:42  jtg
+ * Initial revision
+ *
+ * Revision 1.3  1999/01/03 03:08:57  brianp
+ * Ted Jump's changes
+ *\r
+ * Revision 2.1  1996/11/15 10:54:00  CST by Li Wei(liwei@aiar.xjtu.edu.cn)\r
+ * a new element added to wmesa_context :\r
+ * dither_flag\r
+ */\r
+\r
+/*\r
+ * $Log: wmesadef.h,v $
+ * Revision 1.1  1999/08/19 00:55:42  jtg
+ * Initial revision
+ *
+ * Revision 1.3  1999/01/03 03:08:57  brianp
+ * Ted Jump's changes
+ *\r
+ * Revision 2.0  1996/11/15 10:54:00  CST by Li Wei(liwei@aiar.xjtu.edu.cn)\r
+ * Initial revision\r
+ */\r
+\r
+\r
+\r
+#ifndef DDMESADEF_H\r
+#define DDMESADEF_H\r
+\r
+#include <windows.h>\r
+#include <GL\gl.h>\r
+#include "context.h"\r
+#ifdef DDRAW\r
+       #include <ddraw.h>\r
+#endif\r
+//#include "profile.h"\r
+\r
+#define REDBITS                0x03\r
+#define REDSHIFT       0x00\r
+#define GREENBITS      0x03\r
+#define GREENSHIFT     0x03\r
+#define BLUEBITS       0x02\r
+#define BLUESHIFT      0x06\r
+\r
+typedef struct _dibSection{\r
+       HDC             hDC;\r
+       HANDLE  hFileMap;\r
+       BOOL    fFlushed;\r
+       LPVOID  base;\r
+}WMDIBSECTION, *PWMDIBSECTION;\r
+\r
+\r
+typedef struct wmesa_context{\r
+    GLcontext *gl_ctx;         /* The core GL/Mesa context */\r
+       GLvisual *gl_visual;            /* Describes the buffers */\r
+    GLframebuffer *gl_buffer;  /* Depth, stencil, accum, etc buffers */\r
+\r
+\r
+       HWND                            Window;\r
+    HDC                 hDC;\r
+    HPALETTE            hPalette;\r
+    HPALETTE            hOldPalette;\r
+    HPEN                hPen;\r
+    HPEN                hOldPen;\r
+    HCURSOR             hOldCursor;\r
+    COLORREF            crColor;\r
+    // 3D projection stuff\r
+    RECT                drawRect;\r
+    UINT                uiDIBoffset;\r
+    // OpenGL stuff\r
+    HPALETTE            hGLPalette;\r
+       GLuint                          width;\r
+       GLuint                          height;\r
+       GLuint                          ScanWidth;\r
+       GLboolean                       db_flag;        //* double buffered?\r
+       GLboolean                       rgb_flag;       //* RGB mode?\r
+       GLboolean                       dither_flag;    //* use dither when 256 color mode for RGB?\r
+       GLuint                          depth;          //* bits per pixel (1, 8, 24, etc)\r
+       ULONG                           pixel;  // current color index or RGBA pixel value\r
+       ULONG                           clearpixel; //* pixel for clearing the color buffers\r
+       PBYTE                           ScreenMem; // WinG memory\r
+       BITMAPINFO                      *IndexFormat;\r
+       HPALETTE                        hPal; // Current Palette\r
+       HPALETTE                        hPalHalfTone;\r
+\r
+\r
+       WMDIBSECTION            dib;\r
+    BITMAPINFO          bmi;\r
+    HBITMAP             hbmDIB;\r
+    HBITMAP             hOldBitmap;\r
+       HBITMAP                         Old_Compat_BM;\r
+       HBITMAP                         Compat_BM;            // Bitmap for double buffering\r
+    PBYTE               pbPixels;\r
+    int                 nColors;\r
+       BYTE                            cColorBits;\r
+       int                                     pixelformat;\r
+\r
+#ifdef DDRAW\r
+       LPDIRECTDRAW            lpDD;           // DirectDraw object\r
+//     LPDIRECTDRAW2            lpDD2;           // DirectDraw object\r
+       LPDIRECTDRAWSURFACE     lpDDSPrimary;   // DirectDraw primary surface\r
+       LPDIRECTDRAWSURFACE     lpDDSOffScreen; // DirectDraw off screen surface\r
+       LPDIRECTDRAWPALETTE     lpDDPal;        // DirectDraw palette\r
+       BOOL                    bActive;        // is application active?\r
+       DDSURFACEDESC           ddsd;\r
+       int                                     fullScreen;\r
+       int                                 gMode ;\r
+#endif\r
+       RECT                                    rectOffScreen;\r
+       RECT                                    rectSurface;\r
+       HWND                                    hwnd;\r
+       DWORD                                   pitch;\r
+       PBYTE                                   addrOffScreen;\r
+//#ifdef PROFILE\r
+//     MESAPROF        profile;\r
+//#endif\r
+}  *PWMC;\r
+\r
+\r
+#define PAGE_FILE              0xffffffff\r
+\r
+\r
+\r
+#endif\r
diff --git a/src/mesa/drivers/x11/fakeglx.c b/src/mesa/drivers/x11/fakeglx.c
new file mode 100644 (file)
index 0000000..12567fe
--- /dev/null
@@ -0,0 +1,1516 @@
+/* $Id: fakeglx.c,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+/*
+ * A pseudo-GLX implementation to allow OpenGL/GLX programs to work with Mesa.
+ * The Fake_glX*() functions implemented here are called from glxapi.c
+ *
+ * Thanks to the contributors:
+ *
+ * Initial version:  Philip Brown (philb@CSUA.Berkeley.EDU)
+ * Better glXGetConfig() support: Armin Liebchen (liebchen@asylum.cs.utah.edu)
+ * Further visual-handling refinements: Wolfram Gloger
+ *    (wmglo@Dent.MED.Uni-Muenchen.DE).
+ *
+ * Notes:
+ *   Don't be fooled, stereo isn't supported yet.
+ */
+
+
+
+#ifdef HAVE_CONFIG_H
+#include "conf.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include "GL/gl.h"
+#include "GL/xmesa.h"
+#include "context.h"
+#include "config.h"
+#include "fakeglx.h"
+#include "macros.h"
+#include "types.h"
+#include "xmesaP.h"
+
+
+
+#define DONT_CARE -1
+
+
+
+#define MAX_VISUALS 100
+static XMesaVisual VisualTable[MAX_VISUALS];
+static int NumVisuals = 0;
+
+
+
+/*
+ * This struct and some code fragments borrowed
+ * from Mark Kilgard's GLUT library.
+ */
+typedef struct _OverlayInfo {
+  /* Avoid 64-bit portability problems by being careful to use
+     longs due to the way XGetWindowProperty is specified. Note
+     that these parameters are passed as CARD32s over X
+     protocol. */
+  unsigned long overlay_visual;
+  long transparent_type;
+  long value;
+  long layer;
+} OverlayInfo;
+
+
+
+/* Macro to handle c_class vs class field name in XVisualInfo struct */
+#if defined(__cplusplus) || defined(c_plusplus)
+#define CLASS c_class
+#else
+#define CLASS class
+#endif
+
+
+
+
+/*
+ * Test if the given XVisualInfo is usable for Mesa rendering.
+ */
+static GLboolean is_usable_visual( XVisualInfo *vinfo )
+{
+   switch (vinfo->CLASS) {
+      case StaticGray:
+      case GrayScale:
+         /* Any StaticGray/GrayScale visual works in RGB or CI mode */
+         return GL_TRUE;
+      case StaticColor:
+      case PseudoColor:
+        /* Any StaticColor/PseudoColor visual of at least 4 bits */
+        if (vinfo->depth>=4) {
+           return GL_TRUE;
+        }
+        else {
+           return GL_FALSE;
+        }
+      case TrueColor:
+      case DirectColor:
+        /* Any depth of TrueColor or DirectColor works in RGB mode */
+        return GL_TRUE;
+      default:
+        /* This should never happen */
+        return GL_FALSE;
+   }
+}
+
+
+
+/*
+ * Return the level (overlay, normal, underlay) of a given XVisualInfo.
+ * Input:  dpy - the X display
+ *         vinfo - the XVisualInfo to test
+ * Return:  level of the visual:
+ *             0 = normal planes
+ *            >0 = overlay planes
+ *            <0 = underlay planes
+ */
+static int level_of_visual( Display *dpy, XVisualInfo *vinfo )
+{
+   Atom overlayVisualsAtom;
+   OverlayInfo *overlay_info = NULL;
+   int numOverlaysPerScreen;
+   Status status;
+   Atom actualType;
+   int actualFormat;
+   unsigned long sizeData, bytesLeft;
+   int i;
+
+   /*
+    * The SERVER_OVERLAY_VISUALS property on the root window contains
+    * a list of overlay visuals.  Get that list now.
+    */
+   overlayVisualsAtom = XInternAtom(dpy,"SERVER_OVERLAY_VISUALS", True);
+   if (overlayVisualsAtom == None) {
+      return 0;
+   }
+
+   status = XGetWindowProperty(dpy, RootWindow( dpy, vinfo->screen ),
+                               overlayVisualsAtom, 0L, (long) 10000, False,
+                               overlayVisualsAtom, &actualType, &actualFormat,
+                               &sizeData, &bytesLeft,
+                               (unsigned char **) &overlay_info );
+
+   if (status != Success || actualType != overlayVisualsAtom ||
+       actualFormat != 32 || sizeData < 4) {
+      /* something went wrong */
+      XFree((void *) overlay_info);
+      return 0;
+   }
+
+   /* search the overlay visual list for the visual ID of interest */
+   numOverlaysPerScreen = (int) (sizeData / 4);
+   for (i=0;i<numOverlaysPerScreen;i++) {
+      OverlayInfo *ov;
+      ov = overlay_info + i;
+      if (ov->overlay_visual==vinfo->visualid) {
+         /* found the visual */
+         if (/*ov->transparent_type==1 &&*/ ov->layer!=0) {
+            int level = ov->layer;
+            XFree((void *) overlay_info);
+            return level;
+         }
+         else {
+            XFree((void *) overlay_info);
+            return 0;
+         }
+      }
+   }
+
+   /* The visual ID was not found in the overlay list. */
+   XFree((void *) overlay_info);
+   return 0;
+}
+
+
+
+
+/*
+ * Given an XVisualInfo and RGB, Double, and Depth buffer flags, save the
+ * configuration in our list of GLX visuals.
+ */
+static XMesaVisual
+save_glx_visual( Display *dpy, XVisualInfo *vinfo,
+                 GLboolean rgbFlag, GLboolean alphaFlag, GLboolean dbFlag,
+                 GLboolean stereoFlag,
+                 GLint depth_size, GLint stencil_size,
+                 GLint accum_size, GLint level )
+{
+   GLboolean ximageFlag = GL_TRUE;
+   XMesaVisual xmvis;
+   GLint i;
+   GLboolean comparePointers;
+
+   if (dbFlag) {
+      /* Check if the MESA_BACK_BUFFER env var is set */
+      char *backbuffer = getenv("MESA_BACK_BUFFER");
+      if (backbuffer) {
+         if (backbuffer[0]=='p' || backbuffer[0]=='P') {
+            ximageFlag = GL_FALSE;
+         }
+         else if (backbuffer[0]=='x' || backbuffer[0]=='X') {
+            ximageFlag = GL_TRUE;
+         }
+         else {
+            fprintf(stderr, "Mesa: invalid value for MESA_BACK_BUFFER ");
+            fprintf(stderr, "environment variable, using an XImage.\n");
+         }
+      }
+   }
+
+   /* Comparing IDs uses less memory but sometimes fails. */
+   /* XXX revisit this after 3.0 is finished. */
+   if (getenv("MESA_GLX_VISUAL_HACK"))
+      comparePointers = GL_TRUE;
+   else
+      comparePointers = GL_FALSE;
+
+   /* First check if a matching visual is already in the list */
+   for (i=0; i<NumVisuals; i++) {
+      XMesaVisual v = VisualTable[i];
+      if (v->display == dpy
+          && v->level == level
+          && v->ximage_flag == ximageFlag
+          && v->gl_visual->RGBAflag == rgbFlag
+          && v->gl_visual->DBflag == dbFlag
+          && v->gl_visual->StereoFlag == stereoFlag
+          && (v->gl_visual->AlphaBits > 0) == alphaFlag
+          && (v->gl_visual->DepthBits >= depth_size || depth_size == 0)
+          && (v->gl_visual->StencilBits >= stencil_size || stencil_size == 0)
+          && (v->gl_visual->AccumBits >= accum_size || accum_size == 0)) {
+         /* now either compare XVisualInfo pointers or visual IDs */
+         if ((!comparePointers && v->vishandle->visualid == vinfo->visualid)
+             || (comparePointers && v->vishandle == vinfo)) {
+            return v;
+         }
+      }
+   }
+
+   /* Create a new visual and add it to the list. */
+
+   if (NumVisuals>=MAX_VISUALS) {
+      fprintf( stderr, "GLX Error: maximum number of visuals exceeded\n");
+      return NULL;
+   }
+
+   xmvis = XMesaCreateVisual( dpy, vinfo, rgbFlag, alphaFlag, dbFlag,
+                              stereoFlag, ximageFlag,
+                              depth_size, stencil_size, accum_size, level );
+   if (xmvis) {
+      VisualTable[NumVisuals] = xmvis;
+      NumVisuals++;
+   }
+   return xmvis;
+}
+
+
+
+/*
+ * Create a GLX visual from a regular XVisualInfo.
+ */
+static XMesaVisual
+create_glx_visual( Display *dpy, XVisualInfo *visinfo )
+{
+   int vislevel;
+
+   vislevel = level_of_visual( dpy, visinfo );
+   if (vislevel) {
+      /* Configure this visual as a CI, single-buffered overlay */
+      return save_glx_visual( dpy, visinfo,
+                              GL_FALSE,  /* rgb */
+                              GL_FALSE,  /* alpha */
+                              GL_FALSE,  /* double */
+                              GL_FALSE,  /* stereo */
+                              0,         /* depth bits */
+                              0,         /* stencil bits */
+                              0,         /* accum bits */
+                              vislevel   /* level */
+                            );
+   }
+   else if (is_usable_visual( visinfo )) {
+      /* Configure this visual as RGB, double-buffered, depth-buffered. */
+      /* This is surely wrong for some people's needs but what else */
+      /* can be done?  They should use glXChooseVisual(). */
+      return save_glx_visual( dpy, visinfo,
+                              GL_TRUE,   /* rgb */
+                              GL_FALSE,  /* alpha */
+                              GL_TRUE,   /* double */
+                              GL_FALSE,  /* stereo */
+                              8*sizeof(GLdepth),
+                              8*sizeof(GLstencil),
+                              8*sizeof(GLaccum),
+                              0          /* level */
+                            );
+   }
+   else {
+      fprintf(stderr,"Mesa: error in glXCreateContext: bad visual\n");
+      return NULL;
+   }
+}
+
+
+
+/*
+ * Find the GLX visual associated with an XVisualInfo.
+ */
+static XMesaVisual
+find_glx_visual( Display *dpy, XVisualInfo *vinfo )
+{
+   int i;
+
+   /* First try to match pointers */
+   for (i=0;i<NumVisuals;i++) {
+      if (VisualTable[i]->display==dpy && VisualTable[i]->vishandle==vinfo) {
+         return VisualTable[i];
+      }
+   }
+   /* try to match visual id */
+   for (i=0;i<NumVisuals;i++) {
+      if (VisualTable[i]->display==dpy
+          && VisualTable[i]->visinfo->visualid == vinfo->visualid) {
+         return VisualTable[i];
+      }
+   }
+   return NULL;
+}
+
+
+
+/*
+ * Return the transparent pixel value for a GLX visual.
+ * Input:  glxvis - the glx_visual
+ * Return:  a pixel value or -1 if no transparent pixel
+ */
+static int transparent_pixel( XMesaVisual glxvis )
+{
+   Display *dpy = glxvis->display;
+   XVisualInfo *vinfo = glxvis->visinfo;
+   Atom overlayVisualsAtom;
+   OverlayInfo *overlay_info = NULL;
+   int numOverlaysPerScreen;
+   Status status;
+   Atom actualType;
+   int actualFormat;
+   unsigned long sizeData, bytesLeft;
+   int i;
+
+   /*
+    * The SERVER_OVERLAY_VISUALS property on the root window contains
+    * a list of overlay visuals.  Get that list now.
+    */
+   overlayVisualsAtom = XInternAtom(dpy,"SERVER_OVERLAY_VISUALS", True);
+   if (overlayVisualsAtom == None) {
+      return -1;
+   }
+
+   status = XGetWindowProperty(dpy, RootWindow( dpy, vinfo->screen ),
+                               overlayVisualsAtom, 0L, (long) 10000, False,
+                               overlayVisualsAtom, &actualType, &actualFormat,
+                               &sizeData, &bytesLeft,
+                               (unsigned char **) &overlay_info );
+
+   if (status != Success || actualType != overlayVisualsAtom ||
+       actualFormat != 32 || sizeData < 4) {
+      /* something went wrong */
+      XFree((void *) overlay_info);
+      return -1;
+   }
+
+   /* search the overlay visual list for the visual ID of interest */
+   numOverlaysPerScreen = (int) (sizeData / 4);
+   for (i=0;i<numOverlaysPerScreen;i++) {
+      OverlayInfo *ov;
+      ov = overlay_info + i;
+      if (ov->overlay_visual==vinfo->visualid) {
+         /* found it! */
+         if (ov->transparent_type==0) {
+            /* type 0 indicates no transparency */
+            XFree((void *) overlay_info);
+            return -1;
+         }
+         else {
+            /* ov->value is the transparent pixel */
+            XFree((void *) overlay_info);
+            return ov->value;
+         }
+      }
+   }
+
+   /* The visual ID was not found in the overlay list. */
+   XFree((void *) overlay_info);
+   return -1;
+}
+
+
+
+/*
+ * Return number of bits set in n.
+ */
+static int bitcount( unsigned long n )
+{
+   int bits;
+   for (bits=0; n>0; n=n>>1) {
+      if (n&1) {
+         bits++;
+      }
+   }
+   return bits;
+}
+
+
+/*
+ * Try to get an X visual which matches the given arguments.
+ */
+static XVisualInfo *get_visual( Display *dpy, int scr,
+                               unsigned int depth, int xclass )
+{
+   XVisualInfo temp, *vis;
+   long mask;
+   int n;
+   unsigned int default_depth;
+   int default_class;
+
+   mask = VisualScreenMask | VisualDepthMask | VisualClassMask;
+   temp.screen = scr;
+   temp.depth = depth;
+   temp.CLASS = xclass;
+
+   default_depth = DefaultDepth(dpy,scr);
+   default_class = DefaultVisual(dpy,scr)->CLASS;
+
+   if (depth==default_depth && xclass==default_class) {
+      /* try to get root window's visual */
+      temp.visualid = DefaultVisual(dpy,scr)->visualid;
+      mask |= VisualIDMask;
+   }
+
+   vis = XGetVisualInfo( dpy, mask, &temp, &n );
+
+   /* In case bits/pixel > 24, make sure color channels are still <=8 bits.
+    * An SGI Infinite Reality system, for example, can have 30bpp pixels:
+    * 10 bits per color channel.  Mesa's limited to a max of 8 bits/channel.
+    */
+   if (vis && depth > 24 && (xclass==TrueColor || xclass==DirectColor)) {
+      if (bitcount(vis->red_mask) <= 8
+          && bitcount(vis->green_mask) <= 8
+          && bitcount(vis->blue_mask) <= 8) {
+         return vis;
+      }
+      else {
+         XFree((void *) vis);
+         return NULL;
+      }
+   }
+
+   return vis;
+}
+
+
+
+/*
+ * Retrieve the value of the given environment variable and find
+ * the X visual which matches it.
+ * Input:  dpy - the display
+ *         screen - the screen number
+ *         varname - the name of the environment variable
+ * Return:  an XVisualInfo pointer to NULL if error.
+ */
+static XVisualInfo *get_env_visual(Display *dpy, int scr, const char *varname)
+{
+   char value[100], type[100];
+   int depth, xclass = -1;
+   XVisualInfo *vis;
+
+   if (!getenv( varname )) {
+      return NULL;
+   }
+
+   strncpy( value, getenv(varname), 100 );
+   value[99] = 0;
+
+   sscanf( value, "%s %d", type, &depth );
+
+   if (strcmp(type,"TrueColor")==0)          xclass = TrueColor;
+   else if (strcmp(type,"DirectColor")==0)   xclass = DirectColor;
+   else if (strcmp(type,"PseudoColor")==0)   xclass = PseudoColor;
+   else if (strcmp(type,"StaticColor")==0)   xclass = StaticColor;
+   else if (strcmp(type,"GrayScale")==0)     xclass = GrayScale;
+   else if (strcmp(type,"StaticGray")==0)    xclass = StaticGray;
+
+   if (xclass>-1 && depth>0) {
+      vis = get_visual( dpy, scr, depth, xclass );
+      if (vis) {
+        return vis;
+      }
+   }
+
+   fprintf( stderr, "Mesa: GLX unable to find visual class=%s, depth=%d.\n",
+           type, depth );
+   return NULL;
+}
+
+
+
+/*
+ * Select an X visual which satisfies the RGBA/CI flag and minimum depth.
+ * Input:  dpy, screen - X display and screen number
+ *         rgba - GL_TRUE = RGBA mode, GL_FALSE = CI mode
+ *         min_depth - minimum visual depth
+ *         preferred_class - preferred GLX visual class or DONT_CARE
+ * Return:  pointer to an XVisualInfo or NULL.
+ */
+static XVisualInfo *choose_x_visual( Display *dpy, int screen,
+                                    GLboolean rgba, int min_depth,
+                                     int preferred_class )
+{
+   XVisualInfo *vis;
+   int xclass, visclass;
+   int depth;
+
+   if (rgba) {
+      Atom hp_cr_maps = XInternAtom(dpy, "_HP_RGB_SMOOTH_MAP_LIST", True);
+      /* First see if the MESA_RGB_VISUAL env var is defined */
+      vis = get_env_visual( dpy, screen, "MESA_RGB_VISUAL" );
+      if (vis) {
+        return vis;
+      }
+      /* Otherwise, search for a suitable visual */
+      if (preferred_class==DONT_CARE) {
+         for (xclass=0;xclass<6;xclass++) {
+            switch (xclass) {
+               case 0:  visclass = TrueColor;    break;
+               case 1:  visclass = DirectColor;  break;
+               case 2:  visclass = PseudoColor;  break;
+               case 3:  visclass = StaticColor;  break;
+               case 4:  visclass = GrayScale;    break;
+               case 5:  visclass = StaticGray;   break;
+            }
+            if (min_depth==0) {
+               /* start with shallowest */
+               for (depth=0;depth<=32;depth++) {
+                  if (visclass==TrueColor && depth==8 && !hp_cr_maps) {
+                     /* Special case:  try to get 8-bit PseudoColor before */
+                     /* 8-bit TrueColor */
+                     vis = get_visual( dpy, screen, 8, PseudoColor );
+                     if (vis) {
+                        return vis;
+                     }
+                  }
+                  vis = get_visual( dpy, screen, depth, visclass );
+                  if (vis) {
+                     return vis;
+                  }
+               }
+            }
+            else {
+               /* start with deepest */
+               for (depth=32;depth>=min_depth;depth--) {
+                  if (visclass==TrueColor && depth==8 && !hp_cr_maps) {
+                     /* Special case:  try to get 8-bit PseudoColor before */
+                     /* 8-bit TrueColor */
+                     vis = get_visual( dpy, screen, 8, PseudoColor );
+                     if (vis) {
+                        return vis;
+                     }
+                  }
+                  vis = get_visual( dpy, screen, depth, visclass );
+                  if (vis) {
+                     return vis;
+                  }
+               }
+            }
+         }
+      }
+      else {
+         /* search for a specific visual class */
+         switch (preferred_class) {
+            case GLX_TRUE_COLOR_EXT:    visclass = TrueColor;    break;
+            case GLX_DIRECT_COLOR_EXT:  visclass = DirectColor;  break;
+            case GLX_PSEUDO_COLOR_EXT:  visclass = PseudoColor;  break;
+            case GLX_STATIC_COLOR_EXT:  visclass = StaticColor;  break;
+            case GLX_GRAY_SCALE_EXT:    visclass = GrayScale;    break;
+            case GLX_STATIC_GRAY_EXT:   visclass = StaticGray;   break;
+            default:   return NULL;
+         }
+         if (min_depth==0) {
+            /* start with shallowest */
+            for (depth=0;depth<=32;depth++) {
+               vis = get_visual( dpy, screen, depth, visclass );
+               if (vis) {
+                  return vis;
+               }
+            }
+         }
+         else {
+            /* start with deepest */
+            for (depth=32;depth>=min_depth;depth--) {
+               vis = get_visual( dpy, screen, depth, visclass );
+               if (vis) {
+                  return vis;
+               }
+            }
+         }
+      }
+   }
+   else {
+      /* First see if the MESA_CI_VISUAL env var is defined */
+      vis = get_env_visual( dpy, screen, "MESA_CI_VISUAL" );
+      if (vis) {
+        return vis;
+      }
+      /* Otherwise, search for a suitable visual, starting with shallowest */
+      if (preferred_class==DONT_CARE) {
+         for (xclass=0;xclass<4;xclass++) {
+            switch (xclass) {
+               case 0:  visclass = PseudoColor;  break;
+               case 1:  visclass = StaticColor;  break;
+               case 2:  visclass = GrayScale;    break;
+               case 3:  visclass = StaticGray;   break;
+            }
+            /* try 8-bit up through 16-bit */
+            for (depth=8;depth<=16;depth++) {
+               vis = get_visual( dpy, screen, depth, visclass );
+               if (vis) {
+                  return vis;
+               }
+            }
+            /* try min_depth up to 8-bit */
+            for (depth=min_depth;depth<8;depth++) {
+               vis = get_visual( dpy, screen, depth, visclass );
+               if (vis) {
+                  return vis;
+               }
+            }
+         }
+      }
+      else {
+         /* search for a specific visual class */
+         switch (preferred_class) {
+            case GLX_TRUE_COLOR_EXT:    visclass = TrueColor;    break;
+            case GLX_DIRECT_COLOR_EXT:  visclass = DirectColor;  break;
+            case GLX_PSEUDO_COLOR_EXT:  visclass = PseudoColor;  break;
+            case GLX_STATIC_COLOR_EXT:  visclass = StaticColor;  break;
+            case GLX_GRAY_SCALE_EXT:    visclass = GrayScale;    break;
+            case GLX_STATIC_GRAY_EXT:   visclass = StaticGray;   break;
+            default:   return NULL;
+         }
+         /* try 8-bit up through 16-bit */
+         for (depth=8;depth<=16;depth++) {
+            vis = get_visual( dpy, screen, depth, visclass );
+            if (vis) {
+               return vis;
+            }
+         }
+         /* try min_depth up to 8-bit */
+         for (depth=min_depth;depth<8;depth++) {
+            vis = get_visual( dpy, screen, depth, visclass );
+            if (vis) {
+               return vis;
+            }
+         }
+      }
+   }
+
+   /* didn't find a visual */
+   return NULL;
+}
+
+
+
+/*
+ * Find the deepest X over/underlay visual of at least min_depth.
+ * Input:  dpy, screen - X display and screen number
+ *         level - the over/underlay level
+ *         trans_type - transparent pixel type: GLX_NONE_EXT,
+ *                      GLX_TRANSPARENT_RGB_EXT, GLX_TRANSPARENT_INDEX_EXT,
+ *                      or DONT_CARE
+ *         trans_value - transparent pixel value or DONT_CARE
+ *         min_depth - minimum visual depth
+ *         preferred_class - preferred GLX visual class or DONT_CARE
+ * Return:  pointer to an XVisualInfo or NULL.
+ */
+static XVisualInfo *choose_x_overlay_visual( Display *dpy, int scr,
+                                             int level, int trans_type,
+                                             int trans_value,
+                                             int min_depth,
+                                             int preferred_class )
+{
+   Atom overlayVisualsAtom;
+   OverlayInfo *overlay_info;
+   int numOverlaysPerScreen;
+   Status status;
+   Atom actualType;
+   int actualFormat;
+   unsigned long sizeData, bytesLeft;
+   int i;
+   XVisualInfo *deepvis;
+   int deepest;
+
+   /*DEBUG int tt, tv; */
+
+   switch (preferred_class) {
+      case GLX_TRUE_COLOR_EXT:    preferred_class = TrueColor;    break;
+      case GLX_DIRECT_COLOR_EXT:  preferred_class = DirectColor;  break;
+      case GLX_PSEUDO_COLOR_EXT:  preferred_class = PseudoColor;  break;
+      case GLX_STATIC_COLOR_EXT:  preferred_class = StaticColor;  break;
+      case GLX_GRAY_SCALE_EXT:    preferred_class = GrayScale;    break;
+      case GLX_STATIC_GRAY_EXT:   preferred_class = StaticGray;   break;
+      default:                    preferred_class = DONT_CARE;
+   }
+
+   /*
+    * The SERVER_OVERLAY_VISUALS property on the root window contains
+    * a list of overlay visuals.  Get that list now.
+    */
+   overlayVisualsAtom = XInternAtom(dpy,"SERVER_OVERLAY_VISUALS", True);
+   if (overlayVisualsAtom == (Atom) None) {
+      return NULL;
+   }
+
+   status = XGetWindowProperty(dpy, RootWindow( dpy, scr ),
+                               overlayVisualsAtom, 0L, (long) 10000, False,
+                               overlayVisualsAtom, &actualType, &actualFormat,
+                               &sizeData, &bytesLeft,
+                               (unsigned char **) &overlay_info );
+
+   if (status != Success || actualType != overlayVisualsAtom ||
+       actualFormat != 32 || sizeData < 4) {
+      /* something went wrong */
+      return NULL;
+   }
+
+   /* Search for the deepest overlay which satisifies all criteria. */
+   deepest = min_depth;
+   deepvis = NULL;
+
+   numOverlaysPerScreen = (int) (sizeData / 4);
+   for (i=0;i<numOverlaysPerScreen;i++) {
+      XVisualInfo *vislist, vistemplate;
+      int count;
+      OverlayInfo *ov;
+      ov = overlay_info + i;
+
+      if (ov->layer!=level) {
+         /* failed overlay level criteria */
+         continue;
+      }
+      if (!(trans_type==DONT_CARE
+            || (trans_type==GLX_TRANSPARENT_INDEX_EXT
+                && ov->transparent_type>0)
+            || (trans_type==GLX_NONE_EXT && ov->transparent_type==0))) {
+         /* failed transparent pixel type criteria */
+         continue;
+      }
+      if (trans_value!=DONT_CARE && trans_value!=ov->value) {
+         /* failed transparent pixel value criteria */
+         continue;
+      }
+
+      /* get XVisualInfo and check the depth */
+      vistemplate.visualid = ov->overlay_visual;
+      vistemplate.screen = scr;
+      vislist = XGetVisualInfo( dpy, VisualIDMask | VisualScreenMask,
+                                &vistemplate, &count );
+
+      if (count!=1) {
+         /* something went wrong */
+         continue;
+      }
+      if (preferred_class!=DONT_CARE && preferred_class!=vislist->CLASS) {
+         /* wrong visual class */
+         continue;
+      }
+
+      if (deepvis==NULL || vislist->depth > deepest) {
+         /* YES!  found a satisfactory visual */
+         if (deepvis) {
+            free( deepvis );
+         }
+         deepest = vislist->depth;
+         deepvis = vislist;
+         /* DEBUG  tt = ov->transparent_type;*/
+         /* DEBUG  tv = ov->value; */
+      }
+   }
+
+/*DEBUG
+   if (deepvis) {
+      printf("chose 0x%x:  layer=%d depth=%d trans_type=%d trans_value=%d\n",
+             deepvis->visualid, level, deepvis->depth, tt, tv );
+   }
+*/
+   return deepvis;
+}
+
+
+
+XVisualInfo *Fake_glXChooseVisual( Display *dpy, int screen, int *list )
+{
+   int *parselist;
+   XVisualInfo *vis;
+   int min_ci = 0;
+   int min_red=0, min_green=0, min_blue=0;
+   GLboolean rgb_flag = GL_FALSE;
+   GLboolean alpha_flag = GL_FALSE;
+   GLboolean double_flag = GL_FALSE;
+   GLboolean stereo_flag = GL_FALSE;
+   GLint depth_size = 0;
+   GLint stencil_size = 0;
+   GLint accum_size = 0;
+   int level = 0;
+   int visual_type = DONT_CARE;
+   int trans_type = DONT_CARE;
+   int trans_value = DONT_CARE;
+
+   parselist = list;
+
+   while (*parselist) {
+
+      switch (*parselist) {
+        case GLX_USE_GL:
+           /* ignore */
+           parselist++;
+           break;
+        case GLX_BUFFER_SIZE:
+           parselist++;
+           min_ci = *parselist++;
+           break;
+        case GLX_LEVEL:
+           parselist++;
+            level = *parselist++;
+           break;
+        case GLX_RGBA:
+           rgb_flag = GL_TRUE;
+           parselist++;
+           break;
+        case GLX_DOUBLEBUFFER:
+           double_flag = GL_TRUE;
+           parselist++;
+           break;
+        case GLX_STEREO:
+            stereo_flag = GL_TRUE;
+            return NULL;
+        case GLX_AUX_BUFFERS:
+           /* ignore */
+           parselist++;
+           parselist++;
+           break;
+        case GLX_RED_SIZE:
+           parselist++;
+           min_red = *parselist++;
+           break;
+        case GLX_GREEN_SIZE:
+           parselist++;
+           min_green = *parselist++;
+           break;
+        case GLX_BLUE_SIZE:
+           parselist++;
+           min_blue = *parselist++;
+           break;
+        case GLX_ALPHA_SIZE:
+           parselist++;
+            {
+               GLint size = *parselist++;
+               alpha_flag = size>0 ? 1 : 0;
+            }
+           break;
+        case GLX_DEPTH_SIZE:
+           parselist++;
+           depth_size = *parselist++;
+           break;
+        case GLX_STENCIL_SIZE:
+           parselist++;
+           stencil_size = *parselist++;
+           break;
+        case GLX_ACCUM_RED_SIZE:
+        case GLX_ACCUM_GREEN_SIZE:
+        case GLX_ACCUM_BLUE_SIZE:
+        case GLX_ACCUM_ALPHA_SIZE:
+           parselist++;
+            {
+               GLint size = *parselist++;
+               accum_size = MAX2( accum_size, size );
+            }
+           break;
+
+         /*
+          * GLX_EXT_visual_info extension
+          */
+         case GLX_X_VISUAL_TYPE_EXT:
+            parselist++;
+            visual_type = *parselist++;
+            break;
+         case GLX_TRANSPARENT_TYPE_EXT:
+            parselist++;
+            trans_type = *parselist++;
+            break;
+         case GLX_TRANSPARENT_INDEX_VALUE_EXT:
+            parselist++;
+            trans_value = *parselist++;
+            break;
+         case GLX_TRANSPARENT_RED_VALUE_EXT:
+         case GLX_TRANSPARENT_GREEN_VALUE_EXT:
+         case GLX_TRANSPARENT_BLUE_VALUE_EXT:
+         case GLX_TRANSPARENT_ALPHA_VALUE_EXT:
+           /* ignore */
+           parselist++;
+           parselist++;
+           break;
+         
+        case None:
+           break;
+        default:
+           /* undefined attribute */
+           return NULL;
+      }
+   }
+
+   /*
+    * Since we're only simulating the GLX extension this function will never
+    * find any real GL visuals.  Instead, all we can do is try to find an RGB
+    * or CI visual of appropriate depth.  Other requested attributes such as
+    * double buffering, depth buffer, etc. will be associated with the X
+    * visual and stored in the VisualTable[].
+    */
+   if (level==0) {
+      /* normal color planes */
+      if (rgb_flag) {
+         /* Get an RGB visual */
+         int min_rgb = min_red + min_green + min_blue;
+         if (min_rgb>1 && min_rgb<8) {
+            /* a special case to be sure we can get a monochrome visual */
+            min_rgb = 1;
+         }
+         vis = choose_x_visual( dpy, screen, rgb_flag, min_rgb, visual_type );
+      }
+      else {
+         /* Get a color index visual */
+         vis = choose_x_visual( dpy, screen, rgb_flag, min_ci, visual_type );
+         accum_size = 0;
+      }
+   }
+   else {
+      /* over/underlay planes */
+      vis = choose_x_overlay_visual( dpy, screen, level, trans_type,
+                                     trans_value, min_ci, visual_type );
+   }
+
+   if (vis) {
+      if (!save_glx_visual( dpy, vis, rgb_flag, alpha_flag, double_flag,
+                            stereo_flag,
+                            depth_size, stencil_size, accum_size, level ))
+         return NULL;
+   }
+
+   return vis;
+}
+
+
+
+
+GLXContext Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo,
+                                  GLXContext share_list, Bool direct )
+{
+   XMesaVisual glxvis;
+   XMesaContext xmctx;
+
+   /* deallocate unused windows/buffers */
+   XMesaGarbageCollect();
+
+   glxvis = find_glx_visual( dpy, visinfo );
+   if (!glxvis) {
+      /* This visual wasn't found with glXChooseVisual() */
+      glxvis = create_glx_visual( dpy, visinfo );
+      if (!glxvis) {
+         /* unusable visual */
+         return NULL;
+      }
+   }
+
+   xmctx = XMesaCreateContext( glxvis, (XMesaContext) share_list );
+   if (xmctx) {
+      /* set the direct/indirect flag */
+      xmctx->direct = direct;
+   }
+   return (GLXContext) xmctx;
+}
+
+
+static GLXDrawable MakeCurrent_PrevDrawable = 0;
+static GLXContext MakeCurrent_PrevContext = 0;
+static XMesaBuffer MakeCurrent_PrevBuffer = 0;
+
+Bool Fake_glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx )
+{
+   if (ctx && drawable) {
+      XMesaBuffer buffer;
+
+      if (drawable==MakeCurrent_PrevDrawable && ctx==MakeCurrent_PrevContext) {
+         buffer = MakeCurrent_PrevBuffer;
+      }
+      else {
+         buffer = XMesaFindBuffer( dpy, drawable );
+      }
+      if (!buffer) {
+         /* drawable must be a new window! */
+         buffer = XMesaCreateWindowBuffer2( ctx->xm_visual, drawable, ctx );
+         if (!buffer) {
+            /* Out of memory, or context/drawable depth mismatch */
+            return False;
+         }
+      }
+      MakeCurrent_PrevContext = ctx;
+      MakeCurrent_PrevDrawable = drawable;
+      MakeCurrent_PrevBuffer = buffer;
+
+      /* Now make current! */
+      return (Bool) XMesaMakeCurrent( (XMesaContext) ctx, buffer );
+   }
+   else if (!ctx && !drawable) {
+      /* release current context w/out assigning new one. */
+      XMesaMakeCurrent( NULL, NULL );
+      MakeCurrent_PrevContext = 0;
+      MakeCurrent_PrevDrawable = 0;
+      MakeCurrent_PrevBuffer = 0;
+      return True;
+   }
+   else {
+      /* ctx XOR drawable is NULL, this is an error */
+      return False;
+   }
+}
+
+
+
+GLXPixmap Fake_glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo,
+                                   Pixmap pixmap )
+{
+   XMesaVisual v;
+   XMesaBuffer b;
+
+   v = find_glx_visual( dpy, visinfo );
+   if (!v) {
+      v = create_glx_visual( dpy, visinfo );
+      if (!v) {
+         /* unusable visual */
+         return 0;
+      }
+   }
+
+   b = XMesaCreatePixmapBuffer( v, pixmap, 0 );
+   if (!b) {
+      return 0;
+   }
+   return b->frontbuffer;
+}
+
+
+#ifdef GLX_MESA_pixmap_colormap
+
+GLXPixmap Fake_glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo,
+                                       Pixmap pixmap, Colormap cmap )
+{
+   XMesaVisual v;
+   XMesaBuffer b;
+
+   v = find_glx_visual( dpy, visinfo );
+   if (!v) {
+      v = create_glx_visual( dpy, visinfo );
+      if (!v) {
+         /* unusable visual */
+         return 0;
+      }
+   }
+
+   b = XMesaCreatePixmapBuffer( v, pixmap, cmap );
+   if (!b) {
+      return 0;
+   }
+   return b->frontbuffer;
+}
+
+#endif
+
+
+void Fake_glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap )
+{
+   XMesaBuffer b = XMesaFindBuffer(dpy, pixmap);
+   if (b) {
+      XMesaDestroyBuffer(b);
+   }
+   else if (getenv("MESA_DEBUG")) {
+      fprintf( stderr, "Mesa: glXDestroyGLXPixmap: invalid pixmap\n");
+   }
+}
+
+
+void Fake_glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
+                          GLuint mask )
+{
+   XMesaContext xm_src = (XMesaContext) src;
+   XMesaContext xm_dst = (XMesaContext) dst;
+   (void) dpy;
+   gl_copy_context( xm_src->gl_ctx, xm_dst->gl_ctx, mask );
+}
+
+
+
+Bool Fake_glXQueryExtension( Display *dpy, int *errorb, int *event )
+{
+   /* Mesa's GLX isn't really an X extension but we try to act like one. */
+   (void) dpy;
+   (void) errorb;
+   (void) event;
+   return True;
+}
+
+
+void _kw_ungrab_all( Display *dpy )
+{
+   XUngrabPointer( dpy, CurrentTime );
+   XUngrabKeyboard( dpy, CurrentTime );
+}
+
+
+void Fake_glXDestroyContext( Display *dpy, GLXContext ctx )
+{
+   (void) dpy;
+   MakeCurrent_PrevContext = 0;
+   MakeCurrent_PrevDrawable = 0;
+   MakeCurrent_PrevBuffer = 0;
+   XMesaDestroyContext( (XMesaContext) ctx );
+   XMesaGarbageCollect();
+}
+
+
+
+Bool Fake_glXIsDirect( Display *dpy, GLXContext ctx )
+{
+   (void) dpy;
+   return ((XMesaContext) ctx)->direct;
+}
+
+
+
+void Fake_glXSwapBuffers( Display *dpy, GLXDrawable drawable )
+{
+   XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable );
+   static GLXDrawable last = 0;
+   static Window window = 0;
+   if (drawable != last && 0) {
+      XSetWindowAttributes cwa;
+
+      _kw_ungrab_all( dpy );
+      cwa.override_redirect = 0;
+      XChangeWindowAttributes( dpy, drawable, CWOverrideRedirect,
+                              &cwa );
+/*       printf("KW: Ungrab display %s\n", DisplayString(dpy)); */
+
+
+/*       last = drawable; */
+
+
+      if (!window) {
+        XSetWindowAttributes cwa;
+
+        if ((window = XCreateSimpleWindow( dpy, 
+                                           RootWindow( dpy, 0 ),
+                                           10,10,100,100, 0, 
+                                           WhitePixel( dpy, 0 ),
+                                           BlackPixel( dpy, 0 ))) == 0)
+        {
+           printf("Failed to open radar window\n");
+           abort();
+        }
+   
+        cwa.event_mask = (PointerMotionMask |
+                          ButtonPressMask |
+                          ButtonReleaseMask |
+                          KeyPressMask |
+                          KeyReleaseMask |
+                          ExposureMask );
+
+        XChangeWindowAttributes( dpy, window, 
+                                 CWEventMask,
+                                 &cwa );
+
+        XMapWindow( dpy, window );
+        XFlush( dpy );
+      }
+   }
+   if (buffer) {
+      XMesaSwapBuffers(buffer);
+   }
+   else if (getenv("MESA_DEBUG")) {
+      fprintf(stderr, "Mesa Warning: glXSwapBuffers: invalid drawable\n");
+   }
+}
+
+
+void Fake_glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable,
+                               int x, int y, int width, int height )
+{
+   XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable );
+   if (buffer) {
+      XMesaCopySubBuffer(buffer, x, y, width, height);
+   }
+   else if (getenv("MESA_DEBUG")) {
+      fprintf(stderr, "Mesa Warning: glXCopySubBufferMESA: invalid drawable\n");
+   }
+}
+
+
+
+Bool Fake_glXQueryVersion( Display *dpy, int *maj, int *min )
+{
+   (void) dpy;
+   /* Return GLX version, not Mesa version */
+   *maj = 1;
+   *min = 1;
+   return True;
+}
+
+
+
+/*
+ * Query the GLX attributes of the given XVisualInfo.
+ */
+int Fake_glXGetConfig( Display *dpy, XVisualInfo *visinfo,
+                       int attrib, int *value )
+{
+   XMesaVisual glxvis;
+
+   glxvis = find_glx_visual( dpy, visinfo );
+   if (!glxvis) {
+      /* this visual wasn't obtained with glXChooseVisual */
+      glxvis = create_glx_visual( dpy, visinfo );
+      if (!glxvis) {
+        /* this visual can't be used for GL rendering */
+        if (attrib==GLX_USE_GL) {
+           *value = (int) False;
+           return 0;
+        }
+        else {
+           /*fprintf( stderr, "Mesa: Error in glXGetConfig: bad visual\n");*/
+           return GLX_BAD_VISUAL;
+        }
+      }
+   }
+
+   switch(attrib) {
+      case GLX_USE_GL:
+         *value = (int) True;
+        return 0;
+      case GLX_BUFFER_SIZE:
+        *value = visinfo->depth;
+        return 0;
+      case GLX_LEVEL:
+        *value = glxvis->level;
+        return 0;
+      case GLX_RGBA:
+        if (glxvis->gl_visual->RGBAflag) {
+           *value = True;
+        }
+        else {
+           *value = False;
+        }
+        return 0;
+      case GLX_DOUBLEBUFFER:
+        *value = (int) glxvis->gl_visual->DBflag;
+        return 0;
+      case GLX_STEREO:
+        *value = (int) glxvis->gl_visual->StereoFlag;
+        return 0;
+      case GLX_AUX_BUFFERS:
+        *value = (int) False;
+        return 0;
+      case GLX_RED_SIZE:
+         *value = glxvis->gl_visual->RedBits;
+        return 0;
+      case GLX_GREEN_SIZE:
+         *value = glxvis->gl_visual->GreenBits;
+        return 0;
+      case GLX_BLUE_SIZE:
+         *value = glxvis->gl_visual->BlueBits;
+        return 0;
+      case GLX_ALPHA_SIZE:
+         *value = glxvis->gl_visual->AlphaBits;
+        return 0;
+      case GLX_DEPTH_SIZE:
+         *value = glxvis->gl_visual->DepthBits;
+        return 0;
+      case GLX_STENCIL_SIZE:
+        *value = glxvis->gl_visual->StencilBits;
+        return 0;
+      case GLX_ACCUM_RED_SIZE:
+      case GLX_ACCUM_GREEN_SIZE:
+      case GLX_ACCUM_BLUE_SIZE:
+        *value = glxvis->gl_visual->AccumBits;
+        return 0;
+      case GLX_ACCUM_ALPHA_SIZE:
+         if (glxvis->gl_visual->AlphaBits > 0)
+            *value = glxvis->gl_visual->AccumBits;
+         else
+            *value = 0;
+        return 0;
+
+      /*
+       * GLX_EXT_visual_info extension
+       */
+      case GLX_X_VISUAL_TYPE_EXT:
+         switch (glxvis->visinfo->CLASS) {
+            case StaticGray:   *value = GLX_STATIC_GRAY_EXT;   return 0;
+            case GrayScale:    *value = GLX_GRAY_SCALE_EXT;    return 0;
+            case StaticColor:  *value = GLX_STATIC_GRAY_EXT;   return 0;
+            case PseudoColor:  *value = GLX_PSEUDO_COLOR_EXT;  return 0;
+            case TrueColor:    *value = GLX_TRUE_COLOR_EXT;    return 0;
+            case DirectColor:  *value = GLX_DIRECT_COLOR_EXT;  return 0;
+         }
+         return 0;
+      case GLX_TRANSPARENT_TYPE_EXT:
+         if (glxvis->level==0) {
+            /* normal planes */
+            *value = GLX_NONE_EXT;
+         }
+         else if (glxvis->level>0) {
+            /* overlay */
+            if (glxvis->gl_visual->RGBAflag) {
+               *value = GLX_TRANSPARENT_RGB_EXT;
+            }
+            else {
+               *value = GLX_TRANSPARENT_INDEX_EXT;
+            }
+         }
+         else if (glxvis->level<0) {
+            /* underlay */
+            *value = GLX_NONE_EXT;
+         }
+         return 0;
+      case GLX_TRANSPARENT_INDEX_VALUE_EXT:
+         {
+            int pixel = transparent_pixel( glxvis );
+            if (pixel>=0) {
+               *value = pixel;
+            }
+            /* else undefined */
+         }
+         return 0;
+      case GLX_TRANSPARENT_RED_VALUE_EXT:
+         /* undefined */
+         return 0;
+      case GLX_TRANSPARENT_GREEN_VALUE_EXT:
+         /* undefined */
+         return 0;
+      case GLX_TRANSPARENT_BLUE_VALUE_EXT:
+         /* undefined */
+         return 0;
+      case GLX_TRANSPARENT_ALPHA_VALUE_EXT:
+         /* undefined */
+         return 0;
+
+      /*
+       * Extensions
+       */
+      default:
+        return GLX_BAD_ATTRIBUTE;
+   }
+}
+
+
+
+GLXContext Fake_glXGetCurrentContext( void )
+{
+   return (GLXContext) XMesaGetCurrentContext();
+}
+
+
+
+GLXDrawable Fake_glXGetCurrentDrawable( void )
+{
+   XMesaBuffer b = XMesaGetCurrentBuffer();
+   if (b) {
+      return b->frontbuffer;
+   }
+   else {
+      return 0;
+   }
+}
+
+
+void Fake_glXWaitGL( void )
+{
+   XMesaContext xmesa = XMesaGetCurrentContext();
+   XMesaFlush( xmesa );
+}
+
+
+
+void Fake_glXWaitX( void )
+{
+   XMesaContext xmesa = XMesaGetCurrentContext();
+   XMesaFlush( xmesa );
+}
+
+
+
+#define EXTENSIONS "GLX_MESA_pixmap_colormap GLX_EXT_visual_info GLX_MESA_release_buffers GLX_MESA_copy_sub_buffer GLX_SGI_video_sync"
+
+
+/* GLX 1.1 and later */
+const char *Fake_glXQueryExtensionsString( Display *dpy, int screen )
+{
+   static char *extensions = EXTENSIONS;
+   (void) dpy;
+   (void) screen;
+   return extensions;
+}
+
+
+
+/* GLX 1.1 and later */
+const char *Fake_glXQueryServerString( Display *dpy, int screen, int name )
+{
+   static char *extensions = EXTENSIONS;
+   static char *vendor = "Brian Paul";
+   static char *version = "1.1 Mesa 3.0";
+
+   (void) dpy;
+   (void) screen;
+
+   switch (name) {
+      case GLX_EXTENSIONS:
+         return extensions;
+      case GLX_VENDOR:
+        return vendor;
+      case GLX_VERSION:
+        return version;
+      default:
+         return NULL;
+   }
+}
+
+
+
+/* GLX 1.1 and later */
+const char *Fake_glXGetClientString( Display *dpy, int name )
+{
+   static char *extensions = EXTENSIONS;
+   static char *vendor = "Brian Paul";
+   static char *version = "1.1 Mesa 3.0";
+
+   (void) dpy;
+
+   switch (name) {
+      case GLX_EXTENSIONS:
+         return extensions;
+      case GLX_VENDOR:
+        return vendor;
+      case GLX_VERSION:
+        return version;
+      default:
+         return NULL;
+   }
+}
+
+
+
+/*
+ * Release the depth, stencil, accum buffers attached to a GLXDrawable
+ * (a window or pixmap) prior to destroying the GLXDrawable.
+ */
+Bool Fake_glXReleaseBuffersMESA( Display *dpy, GLXDrawable d )
+{
+   XMesaBuffer b = XMesaFindBuffer(dpy, d);
+   if (b) {
+      XMesaDestroyBuffer(b);
+      return True;
+   }
+   return False;
+}
+
+
+/* Silence compiler warnings */
+void Fake_glXDummyFunc( void )
+{
+   (void) kernel8;
+   (void) DitherValues;
+   (void) HPCR_DRGB;
+   (void) kernel1;
+}
diff --git a/src/mesa/drivers/x11/glxapi.c b/src/mesa/drivers/x11/glxapi.c
new file mode 100644 (file)
index 0000000..b65bada
--- /dev/null
@@ -0,0 +1,405 @@
+/* $Id: glxapi.c,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+/*
+ * GLX API functions which either call fake or real GLX implementations
+ *
+ * To enable real GLX encoding the REALGLX preprocessor symbol should be
+ * defined on the command line.
+ */
+
+
+
+#ifdef HAVE_CONFIG_H
+#include "conf.h"
+#endif
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include "GL/glx.h"
+#include "fakeglx.h"
+#include "realglx.h"
+
+
+#ifdef REALGLX
+static Display *CurrentDisplay = NULL;
+#endif
+
+
+/*
+ * This functions determines whether a call to a glX*() function should
+ * be routed to the "fake" (Mesa) or "real" (GLX-encoder) functions.
+ * Input:  dpy - the X display.
+ * Return:   GL_TRUE if the given display supports the real GLX extension,
+ *           GL_FALSE otherwise.
+ */
+static GLboolean display_has_glx( Display *dpy )
+{
+   /* TODO: we should use a lookup table to avoid calling XQueryExtension
+    * every time.
+    */
+   int ignore;
+   if (XQueryExtension( dpy, "GLX", &ignore, &ignore, &ignore )) {
+      return GL_TRUE;
+   }
+   else {
+      return GL_FALSE;
+   }
+}
+
+
+
+XVisualInfo *glXChooseVisual( Display *dpy, int screen, int *list )
+{
+#ifdef REALGLX
+   if (display_has_glx(dpy))
+      return Real_glXChooseVisual( dpy, screen, list );
+   else
+#endif
+      return Fake_glXChooseVisual( dpy, screen, list );
+}
+
+
+
+int glXGetConfig( Display *dpy, XVisualInfo *visinfo, int attrib, int *value )
+{
+#ifdef REALGLX
+   if (display_has_glx(dpy))
+      return Real_glXGetConfig( dpy, visinfo, attrib, value );
+   else
+#endif
+      return Fake_glXGetConfig( dpy, visinfo, attrib, value );
+}
+
+
+
+GLXContext glXCreateContext( Display *dpy, XVisualInfo *visinfo,
+                            GLXContext shareList, Bool direct )
+{
+#ifdef REALGLX
+   if (display_has_glx(dpy))
+      return Real_glXCreateContext( dpy, visinfo, shareList, direct );
+   else
+#endif
+      return Fake_glXCreateContext( dpy, visinfo, shareList, direct );
+}
+
+
+
+void glXDestroyContext( Display *dpy, GLXContext ctx )
+{
+#ifdef REALGLX
+   if (display_has_glx(dpy))
+      Real_glXDestroyContext( dpy, ctx );
+   else
+#endif
+      Fake_glXDestroyContext( dpy, ctx );
+}
+
+
+
+void glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
+                    GLuint mask )
+{
+#ifdef REALGLX
+   if (display_has_glx(dpy))
+      Real_glXCopyContext( dpy, src, dst, mask );
+   else
+#endif
+      Fake_glXCopyContext( dpy, src, dst, mask );
+}
+
+
+
+Bool glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx )
+{
+#ifdef REALGLX
+   if (display_has_glx(dpy)) {
+      if (Real_glXMakeCurrent( dpy, drawable, ctx )) {
+         CurrentDisplay = dpy;
+         return True;
+      }
+      else {
+         return False;
+      }
+   }
+   else {
+      if (Fake_glXMakeCurrent( dpy, drawable, ctx )) {
+         CurrentDisplay = dpy;
+         return True;
+      }
+      else {
+         return False;
+      }
+   }
+#else
+   return Fake_glXMakeCurrent( dpy, drawable, ctx );
+#endif
+}
+
+
+
+GLXContext glXGetCurrentContext( void )
+{
+#ifdef REALGLX
+   if (display_has_glx(CurrentDisplay))
+      return Real_glXGetCurrentContext();
+   else
+#endif
+      return Fake_glXGetCurrentContext();
+}
+
+
+
+GLXDrawable glXGetCurrentDrawable( void )
+{
+#ifdef REALGLX
+   if (display_has_glx(CurrentDisplay))
+      return Real_glXGetCurrentDrawable();
+   else
+#endif
+      return Fake_glXGetCurrentDrawable();
+}
+
+
+
+GLXPixmap glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo,
+                              Pixmap pixmap )
+{
+#ifdef REALGLX
+   if (display_has_glx(dpy))
+      return Real_glXCreateGLXPixmap( dpy, visinfo, pixmap );
+   else
+#endif
+      return Fake_glXCreateGLXPixmap( dpy, visinfo, pixmap );
+}
+
+
+void glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap )
+{
+#ifdef REALGLX
+   if (display_has_glx(dpy))
+      Real_glXDestroyGLXPixmap( dpy, pixmap );
+   else
+#endif
+      Fake_glXDestroyGLXPixmap( dpy, pixmap );
+}
+
+
+
+Bool glXQueryExtension( Display *dpy, int *errorb, int *event )
+{
+#ifdef REALGLX
+   if (display_has_glx(dpy))
+      return Real_glXQueryExtension( dpy, errorb, event );
+   else
+#endif
+      return Fake_glXQueryExtension( dpy, errorb, event );
+}
+
+
+
+Bool glXIsDirect( Display *dpy, GLXContext ctx )
+{
+#ifdef REALGLX
+   if (display_has_glx(dpy))
+      return Real_glXIsDirect( dpy, ctx );
+   else
+#endif
+      return Fake_glXIsDirect( dpy, ctx );
+}
+
+
+
+void glXSwapBuffers( Display *dpy, GLXDrawable drawable )
+{
+#ifdef REALGLX
+   if (display_has_glx(dpy))
+      Real_glXSwapBuffers( dpy, drawable );
+   else
+#endif
+      Fake_glXSwapBuffers( dpy, drawable );
+}
+
+
+
+void glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable,
+                           int x, int y, int width, int height )
+{
+#ifdef REALGLX
+   /* can't implement! */
+   return;
+#endif
+   Fake_glXCopySubBufferMESA( dpy, drawable, x, y, width, height );
+}
+
+
+
+Bool glXQueryVersion( Display *dpy, int *maj, int *min )
+{
+#ifdef REALGLX
+   if (display_has_glx(dpy))
+      return Real_glXQueryVersion( dpy, maj, min );
+   else
+#endif
+      return Fake_glXQueryVersion( dpy, maj, min );
+}
+
+
+
+void glXUseXFont( Font font, int first, int count, int listBase )
+{
+#ifdef REALGLX
+   if (display_has_glx(CurrentDisplay))
+      Real_glXUseXFont( font, first, count, listBase );
+   else
+#endif
+      Fake_glXUseXFont( font, first, count, listBase );
+}
+
+
+void glXWaitGL( void )
+{
+#ifdef REALGLX
+   if (display_has_glx(CurrentDisplay))
+      Real_glXWaitGL();
+   else
+#endif
+      Fake_glXWaitGL();
+}
+
+
+
+void glXWaitX( void )
+{
+#ifdef REALGLX
+   if (display_has_glx(CurrentDisplay))
+      Real_glXWaitX();
+   else
+#endif
+      Fake_glXWaitX();
+}
+
+
+
+/* GLX 1.1 and later */
+const char *glXQueryExtensionsString( Display *dpy, int screen )
+{
+#ifdef REALGLX
+   if (display_has_glx(dpy))
+      return Real_glXQueryExtensionsString( dpy, screen );
+   else
+#endif
+      return Fake_glXQueryExtensionsString( dpy, screen );
+}
+
+
+
+/* GLX 1.1 and later */
+const char *glXQueryServerString( Display *dpy, int screen, int name )
+{
+#ifdef REALGLX
+   if (display_has_glx(dpy))
+      return Real_glXQueryServerString( dpy, screen, name );
+   else
+#endif
+      return Fake_glXQueryServerString( dpy, screen, name );
+}
+
+
+
+/* GLX 1.1 and later */
+const char *glXGetClientString( Display *dpy, int name )
+{
+#ifdef REALGLX
+   if (display_has_glx(dpy))
+      return Real_glXGetClientString( dpy, name );
+   else
+#endif
+      return Fake_glXGetClientString( dpy, name );
+}
+
+
+
+#ifdef GLX_MESA_release_buffers
+Bool glXReleaseBuffersMESA( Display *dpy, Window w )
+{
+#ifdef REALGLX
+   if (display_has_glx(dpy))
+      return GL_FALSE;
+   else
+#endif
+      return Fake_glXReleaseBuffersMESA( dpy, w );
+}
+#endif
+
+
+#ifdef GLX_MESA_pixmap_colormap
+GLXPixmap glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo,
+                                  Pixmap pixmap, Colormap cmap )
+{
+#ifdef REALGLX
+   if (display_has_glx(dpy))
+      return 0;
+   else
+#endif
+      return Fake_glXCreateGLXPixmapMESA( dpy, visinfo, pixmap, cmap );
+}
+#endif
+
+
+
+#ifdef GLX_SGI_video_sync
+
+/*
+ * This function doesn't really do anything.  But, at least one
+ * application uses the function so this stub is useful.
+ */
+int glXGetVideoSyncSGI(unsigned int *count)
+{
+   static unsigned int counter = 0;
+   *count = counter++;
+   return 0;
+}
+
+
+/*
+ * Again, this is really just a stub function.
+ */
+int glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
+{
+   static unsigned int counter = 0;
+   while (counter % divisor != remainder)
+      counter++;
+   *count = counter;
+   return 0;
+}
+
+#endif
diff --git a/src/mesa/drivers/x11/realglx.c b/src/mesa/drivers/x11/realglx.c
new file mode 100644 (file)
index 0000000..79a2804
--- /dev/null
@@ -0,0 +1,239 @@
+/* $Id: realglx.c,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+/*
+ * Real GLX-encoder functions.  Called from glxapi.c
+ *
+ * Steven Parker's code for the GLX client API functions should be
+ * put in this file.
+ *
+ * Also, the main API functions in api.c should somehow hook into the
+ * GLX-encoding functions...
+ */
+
+
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include "realglx.h"
+
+
+
+XVisualInfo *Real_glXChooseVisual( Display *dpy, int screen, int *list )
+{
+   (void) dpy;
+   (void) screen;
+   (void) list;
+   return 0;
+}
+
+
+
+int Real_glXGetConfig( Display *dpy, XVisualInfo *visinfo,
+                       int attrib, int *value )
+{
+   (void) dpy;
+   (void) visinfo;
+   (void) attrib;
+   (void) value;
+   return 0;
+}
+
+
+
+GLXContext Real_glXCreateContext( Display *dpy, XVisualInfo *visinfo,
+                                  GLXContext shareList, Bool direct )
+{
+   (void) dpy;
+   (void) visinfo;
+   (void) shareList;
+   (void) direct;
+   return 0;
+}
+
+
+
+void Real_glXDestroyContext( Display *dpy, GLXContext ctx )
+{
+   (void) dpy;
+   (void) ctx;
+}
+
+
+
+void Real_glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
+                          GLuint mask )
+{
+   (void) dpy;
+   (void) src;
+   (void) dst;
+   (void) mask;
+}
+
+
+
+Bool Real_glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx )
+{
+   (void) dpy;
+   (void) drawable;
+   (void) ctx;
+   return 0;
+}
+
+
+
+GLXContext Real_glXGetCurrentContext( void )
+{
+   return 0;
+}
+
+
+
+GLXDrawable Real_glXGetCurrentDrawable( void )
+{
+   return 0;
+}
+
+
+
+GLXPixmap Real_glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo,
+                                  Pixmap pixmap )
+{
+   (void) dpy;
+   (void) visinfo;
+   (void) pixmap;
+   return 0;
+}
+
+
+void Real_glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap )
+{
+   (void) dpy;
+   (void) pixmap;
+}
+
+
+
+Bool Real_glXQueryExtension( Display *dpy, int *errorb, int *event )
+{
+   (void) dpy;
+   (void) errorb;
+   (void) event;
+   return 0;
+}
+
+
+
+Bool Real_glXIsDirect( Display *dpy, GLXContext ctx )
+{
+   (void) dpy;
+   (void) ctx;
+   return 0;
+}
+
+
+
+void Real_glXSwapBuffers( Display *dpy, GLXDrawable drawable )
+{
+   (void) dpy;
+   (void) drawable;
+}
+
+
+
+Bool Real_glXQueryVersion( Display *dpy, int *maj, int *min )
+{
+   (void) dpy;
+   (void) maj;
+   (void) min;
+   return 0;
+}
+
+
+
+void Real_glXUseXFont( Font font, int first, int count, int listBase )
+{
+   (void) font;
+   (void) first;
+   (void) count;
+   (void) listBase;
+}
+
+
+typedef struct {
+   struct {
+      int major_opcode;
+   } codes;
+
+
+
+} XExtDisplayInfo;
+
+
+void Real_glXWaitGL( void )
+{
+}
+
+
+
+void Real_glXWaitX( void )
+{
+}
+
+
+
+/* GLX 1.1 and later */
+const char *Real_glXQueryExtensionsString( Display *dpy, int screen )
+{
+   (void) dpy;
+   (void) screen;
+   return 0;
+}
+
+
+
+/* GLX 1.1 and later */
+const char *Real_glXQueryServerString( Display *dpy, int screen, int name )
+{
+   (void) dpy;
+   (void) screen;
+   (void) name;
+   return 0;
+}
+
+
+
+/* GLX 1.1 and later */
+const char *Real_glXGetClientString( Display *dpy, int name )
+{
+   (void) dpy;
+   (void) name;
+   return 0;
+}
diff --git a/src/mesa/drivers/x11/realglx.h b/src/mesa/drivers/x11/realglx.h
new file mode 100644 (file)
index 0000000..9587db6
--- /dev/null
@@ -0,0 +1,111 @@
+/* $Id: realglx.h,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+#ifndef REALGLX_H
+#define REALGLX_H
+
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include "GL/glx.h"
+
+
+
+extern XVisualInfo *Real_glXChooseVisual( Display *dpy,
+                                          int screen, int *list );
+
+
+extern int Real_glXGetConfig( Display *dpy, XVisualInfo *visinfo,
+                              int attrib, int *value );
+
+
+extern GLXContext Real_glXCreateContext( Display *dpy, XVisualInfo *visinfo,
+                                         GLXContext shareList, Bool direct );
+
+
+extern void Real_glXDestroyContext( Display *dpy, GLXContext ctx );
+
+
+extern void Real_glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
+                                 GLuint mask );
+
+
+extern Bool Real_glXMakeCurrent( Display *dpy, GLXDrawable drawable,
+                                 GLXContext ctx );
+
+
+extern GLXContext Real_glXGetCurrentContext( void );
+
+
+extern GLXDrawable Real_glXGetCurrentDrawable( void );
+
+
+extern GLXPixmap Real_glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo,
+                                          Pixmap pixmap );
+
+
+extern void Real_glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap );
+
+
+extern Bool Real_glXQueryExtension( Display *dpy, int *errorb, int *event );
+
+
+extern Bool Real_glXIsDirect( Display *dpy, GLXContext ctx );
+
+
+extern void Real_glXSwapBuffers( Display *dpy, GLXDrawable drawable );
+
+
+extern Bool Real_glXQueryVersion( Display *dpy, int *maj, int *min );
+
+
+extern void Real_glXUseXFont( Font font, int first, int count, int listBase );
+
+
+extern void Real_glXWaitGL( void );
+
+
+extern void Real_glXWaitX( void );
+
+
+/* GLX 1.1 and later */
+extern const char *Real_glXQueryExtensionsString( Display *dpy, int screen );
+
+
+/* GLX 1.1 and later */
+extern const char *Real_glXQueryServerString( Display *dpy, int screen,
+                                              int name );
+
+
+/* GLX 1.1 and later */
+extern const char *Real_glXGetClientString( Display *dpy, int name );
+
+
+#endif
diff --git a/src/mesa/drivers/x11/xfonts.c b/src/mesa/drivers/x11/xfonts.c
new file mode 100644 (file)
index 0000000..c0e0a5f
--- /dev/null
@@ -0,0 +1,398 @@
+/* $Id: xfonts.c,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ *
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/* xfonts.c -- glXUseXFont() for Mesa written by
+ * Copyright (C) 1995 Thorsten.Ohl @ Physik.TH-Darmstadt.de
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "conf.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include "GL/gl.h"
+#include "GL/glx.h"
+#include "GL/xmesa.h"
+#include "context.h"
+#include "fakeglx.h"
+#include "macros.h"
+#include "xmesaP.h"
+
+/* Some debugging info.  */
+
+#ifdef DEBUG
+#undef _R
+#undef _G
+#undef _B
+#include <ctype.h>
+
+int debug_xfonts = 0;
+
+static void
+dump_char_struct (XCharStruct *ch, char *prefix)
+{
+  printf ("%slbearing = %d, rbearing = %d, width = %d\n",
+          prefix, ch->lbearing, ch->rbearing, ch->width);
+  printf ("%sascent = %d, descent = %d, attributes = %u\n",
+          prefix, ch->ascent, ch->descent, (unsigned int) ch->attributes);
+}
+
+static void
+dump_font_struct (XFontStruct *font)
+{
+  printf ("ascent = %d, descent = %d\n", font->ascent, font->descent);
+  printf ("char_or_byte2 = (%u,%u)\n",
+          font->min_char_or_byte2, font->max_char_or_byte2);
+  printf ("byte1 = (%u,%u)\n", font->min_byte1, font->max_byte1);
+  printf ("all_chars_exist = %s\n", font->all_chars_exist ? "True" : 
+"False");
+  printf ("default_char = %c (\\%03o)\n",
+          (char) (isprint (font->default_char) ? font->default_char : ' '),
+          font->default_char);
+  dump_char_struct (&font->min_bounds, "min> ");
+  dump_char_struct (&font->max_bounds, "max> ");
+#if 0
+  for (c = font->min_char_or_byte2; c <= font->max_char_or_byte2; c++)
+    {
+      char prefix[8];
+      sprintf (prefix, "%d> ", c);
+      dump_char_struct (&font->per_char[c], prefix);
+    }
+#endif
+}
+
+static void
+dump_bitmap (unsigned int width, unsigned int height, GLubyte *bitmap)
+{
+  unsigned int x, y;
+
+  printf ("    ");
+  for (x = 0; x < 8*width; x++)
+    printf ("%o", 7 - (x % 8));
+  putchar ('\n');
+  for (y = 0; y < height; y++)
+    {
+      printf ("%3o:", y);
+      for (x = 0; x < 8*width; x++)
+        putchar ((bitmap[width*(height - y - 1) + x/8] & (1 << (7 - (x % 
+8))))
+                 ? '*' : '.');
+      printf ("   ");
+      for (x = 0; x < width; x++)
+        printf ("0x%02x, ", bitmap[width*(height - y - 1) + x]);
+      putchar ('\n');
+    }
+}
+#endif /* DEBUG */
+
+
+/* Implementation.  */
+
+/* Fill a BITMAP with a character C from thew current font
+   in the graphics context GC.  WIDTH is the width in bytes
+   and HEIGHT is the height in bits.
+
+   Note that the generated bitmaps must be used with
+
+        glPixelStorei (GL_UNPACK_SWAP_BYTES, GL_FALSE);
+        glPixelStorei (GL_UNPACK_LSB_FIRST, GL_FALSE);
+        glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
+        glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
+        glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
+        glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
+
+   Possible optimizations:
+
+     * use only one reusable pixmap with the maximum dimensions.
+     * draw the entire font into a single pixmap (careful with
+       proportional fonts!).
+*/
+
+
+/*
+ * Generate OpenGL-compatible bitmap.
+ */
+static void
+fill_bitmap (Display *dpy, Window win, GC gc,
+             unsigned int width, unsigned int height,
+             int x0, int y0, unsigned int c, GLubyte *bitmap)
+{
+  XImage *image;
+  unsigned int x, y;
+  Pixmap pixmap;
+  XChar2b char2b;
+
+  pixmap = XCreatePixmap (dpy, win, 8*width, height, 1);
+  XSetForeground(dpy, gc, 0);
+  XFillRectangle (dpy, pixmap, gc, 0, 0, 8*width, height);
+  XSetForeground(dpy, gc, 1);
+
+  char2b.byte1 = (c >> 8) & 0xff;
+  char2b.byte2 = (c & 0xff);
+
+  XDrawString16 (dpy, pixmap, gc, x0, y0, &char2b, 1);
+
+  image = XGetImage (dpy, pixmap, 0, 0, 8*width, height, 1, XYPixmap);
+  if (image) {
+    /* Fill the bitmap (X11 and OpenGL are upside down wrt each other).  */
+    for (y = 0; y < height; y++)
+      for (x = 0; x < 8*width; x++)
+        if (XGetPixel (image, x, y))
+          bitmap[width*(height - y - 1) + x/8] |= (1 << (7 - (x % 8)));
+    XDestroyImage (image);
+  }
+
+  XFreePixmap (dpy, pixmap);
+}
+
+/*
+ * determine if a given glyph is valid and return the
+ * corresponding XCharStruct.
+ */
+static XCharStruct *isvalid(XFontStruct *fs, int which)
+{
+  unsigned int  rows,pages;
+  int           byte1,byte2;
+  int           i,valid = 1;
+
+  rows = fs->max_byte1 - fs->min_byte1 + 1;
+  pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1;
+
+  if (rows == 1) {
+    /* "linear" fonts */
+    if ((fs->min_char_or_byte2 > which) ||
+        (fs->max_char_or_byte2 < which)) valid = 0;
+  } else {
+    /* "matrix" fonts */
+    byte2 = which & 0xff;
+    byte1 = which >> 8;
+    if ((fs->min_char_or_byte2 > byte2) ||
+        (fs->max_char_or_byte2 < byte2) ||
+        (fs->min_byte1 > byte1) ||
+        (fs->max_byte1 < byte1)) valid = 0;
+  }
+
+  if (valid) {
+    if (fs->per_char) {
+      if (rows == 1) {
+        /* "linear" fonts */
+        return(fs->per_char + (which-fs->min_char_or_byte2) );
+      } else {
+        /* "matrix" fonts */
+        i = ((byte1 - fs->min_byte1) * pages) +
+             (byte2 - fs->min_char_or_byte2);
+        return(fs->per_char + i);
+      }
+    } else {
+        return(&fs->min_bounds);
+    }
+  }
+  return(NULL);
+}
+
+
+void Fake_glXUseXFont( Font font, int first, int count, int listbase )
+{
+  XMesaContext CC;
+  Display *dpy;
+  Window win;
+  Pixmap pixmap;
+  GC gc;
+  XGCValues values;
+  unsigned long valuemask;
+  XFontStruct *fs;
+
+  GLint swapbytes, lsbfirst, rowlength;
+  GLint skiprows, skippixels, alignment;
+
+  unsigned int max_width, max_height, max_bm_width, max_bm_height;
+  GLubyte *bm;
+
+  int i;
+
+  CC = XMesaGetCurrentContext();
+  dpy = CC->display;
+  win = CC->xm_buffer->frontbuffer;
+
+  fs = XQueryFont (dpy, font);
+  if (!fs)
+    {
+      gl_error (CC->gl_ctx, GL_INVALID_VALUE,
+                "Couldn't get font structure information");
+      return;
+    }
+
+  /* Allocate a bitmap that can fit all characters.  */
+  max_width = fs->max_bounds.rbearing - fs->min_bounds.lbearing;
+  max_height = fs->max_bounds.ascent + fs->max_bounds.descent;
+  max_bm_width = (max_width + 7) / 8;
+  max_bm_height = max_height;
+
+  bm = (GLubyte *) malloc ((max_bm_width * max_bm_height) * sizeof 
+(GLubyte));
+  if (!bm) {
+      XFreeFontInfo( NULL, fs, 0 );
+      gl_error (CC->gl_ctx, GL_OUT_OF_MEMORY,
+                "Couldn't allocate bitmap in glXUseXFont()");
+      return;
+    }
+
+#if 0
+  /* get the page info */
+  pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1;
+  firstchar = (fs->min_byte1 << 8) + fs->min_char_or_byte2;
+  lastchar = (fs->max_byte1 << 8) + fs->max_char_or_byte2;
+  rows = fs->max_byte1 - fs->min_byte1 + 1;
+  unsigned int first_char, last_char, pages, rows;
+#endif
+
+  /* Save the current packing mode for bitmaps.  */
+  glGetIntegerv (GL_UNPACK_SWAP_BYTES, &swapbytes);
+  glGetIntegerv (GL_UNPACK_LSB_FIRST, &lsbfirst);
+  glGetIntegerv (GL_UNPACK_ROW_LENGTH, &rowlength);
+  glGetIntegerv (GL_UNPACK_SKIP_ROWS, &skiprows);
+  glGetIntegerv (GL_UNPACK_SKIP_PIXELS, &skippixels);
+  glGetIntegerv (GL_UNPACK_ALIGNMENT, &alignment);
+
+  /* Enforce a standard packing mode which is compatible with
+     fill_bitmap() from above.  This is actually the default mode,
+     except for the (non)alignment.  */
+  glPixelStorei (GL_UNPACK_SWAP_BYTES, GL_FALSE);
+  glPixelStorei (GL_UNPACK_LSB_FIRST, GL_FALSE);
+  glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
+  glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
+  glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
+  glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
+
+  pixmap = XCreatePixmap (dpy, win, 10, 10, 1);
+  values.foreground = BlackPixel (dpy, DefaultScreen (dpy));
+  values.background = WhitePixel (dpy, DefaultScreen (dpy));
+  values.font = fs->fid;
+  valuemask = GCForeground | GCBackground | GCFont;
+  gc = XCreateGC (dpy, pixmap, valuemask, &values);
+  XFreePixmap (dpy, pixmap);
+
+#ifdef DEBUG
+  if (debug_xfonts)
+    dump_font_struct (fs);
+#endif
+
+  for (i = 0; i < count; i++)
+    {
+      unsigned int width, height, bm_width, bm_height;
+      GLfloat x0, y0, dx, dy;
+      XCharStruct *ch;
+      int x, y;
+      unsigned int c = first + i;
+      int list = listbase + i;
+      int valid;
+
+      /* check on index validity and get the bounds */
+      ch = isvalid(fs, c);
+      if (!ch) {
+        ch = &fs->max_bounds;
+        valid = 0;
+      } else {
+        valid = 1;
+      }
+
+#ifdef DEBUG
+      if (debug_xfonts) {
+          char s[7];
+          sprintf (s, isprint (c) ? "%c> " : "\\%03o> ", c);
+          dump_char_struct (ch, s);
+      }
+#endif
+
+      /* glBitmap()' parameters:
+         straight from the glXUseXFont(3) manpage.  */
+      width = ch->rbearing - ch->lbearing;
+      height = ch->ascent + ch->descent;
+      x0 = - ch->lbearing;
+      y0 = ch->descent - 1;
+      dx = ch->width;
+      dy = 0;
+
+      /* X11's starting point.  */
+      x = - ch->lbearing;
+      y = ch->ascent;
+
+      /* Round the width to a multiple of eight.  We will use this also
+         for the pixmap for capturing the X11 font.  This is slightly
+         inefficient, but it makes the OpenGL part real easy.  */
+      bm_width = (width + 7) / 8;
+      bm_height = height;
+
+      glNewList (list, GL_COMPILE);
+        if (valid && (bm_width > 0) && (bm_height > 0)) {
+
+            MEMSET (bm, '\0', bm_width * bm_height);
+            fill_bitmap (dpy, win, gc, bm_width, bm_height, x, y, c, bm);
+
+            glBitmap (width, height, x0, y0, dx, dy, bm);
+#ifdef DEBUG
+            if (debug_xfonts) {
+                printf ("width/height = %u/%u\n", width, height);
+                printf ("bm_width/bm_height = %u/%u\n", bm_width, 
+bm_height);
+                dump_bitmap (bm_width, bm_height, bm);
+              }
+#endif
+          } else {
+            glBitmap (0, 0, 0.0, 0.0, dx, dy, NULL);
+          }
+      glEndList ();
+    }
+
+  free (bm);
+  XFreeFontInfo( NULL, fs, 0 );
+  XFreeGC (dpy, gc);
+
+  /* Restore saved packing modes.  */
+  glPixelStorei(GL_UNPACK_SWAP_BYTES, swapbytes);
+  glPixelStorei(GL_UNPACK_LSB_FIRST, lsbfirst);
+  glPixelStorei(GL_UNPACK_ROW_LENGTH, rowlength);
+  glPixelStorei(GL_UNPACK_SKIP_ROWS, skiprows);
+  glPixelStorei(GL_UNPACK_SKIP_PIXELS, skippixels);
+  glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
+}
+
+void xmesa_xfonts_dummy( void )
+{
+   /* silence unused var warnings */
+   (void) kernel8;
+   (void) DitherValues;
+   (void) HPCR_DRGB;
+   (void) kernel1;
+}
+
+/* The End. */
diff --git a/src/mesa/drivers/x11/xmesaP.h b/src/mesa/drivers/x11/xmesaP.h
new file mode 100644 (file)
index 0000000..256a47f
--- /dev/null
@@ -0,0 +1,499 @@
+/* $Id: xmesaP.h,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef XMESAP_H
+#define XMESAP_H
+
+
+#ifdef XFree86Server
+#include "xf86glx_util.h"
+#else
+#ifdef SHM
+#include <X11/extensions/XShm.h>
+#endif
+#endif
+#include "GL/xmesa.h"
+#include "types.h"
+#ifdef FX
+#include "GL/fxmesa.h"
+#include "../FX/fxdrv.h"
+#endif
+
+
+/* for PF_8R8G8B24 pixel format */
+typedef struct {
+   GLubyte b;
+   GLubyte g;
+   GLubyte r;
+} bgr_t;
+
+
+/*
+ * "Derived" from gl_visual.  Basically corresponds to an XVisualInfo.
+ */
+struct xmesa_visual {
+   GLvisual *gl_visual;                /* Device independent visual parameters */
+   XMesaDisplay *display;      /* The X11 display */
+#ifndef XFree86Server
+   XVisualInfo *vishandle;     /* The pointer returned by glXChooseVisual */
+#endif
+   XMesaVisualInfo visinfo;    /* X's visual info */
+
+   GLint level;                        /* 0=normal, 1=overlay, etc */
+
+   GLboolean ximage_flag;      /* Use XImage for back buffer (not pixmap)? */
+
+   GLuint dithered_pf;         /* Pixel format when dithering */
+   GLuint undithered_pf;       /* Pixel format when not dithering */
+
+   GLfloat RedGamma;           /* Gamma values, 1.0 is default */
+   GLfloat GreenGamma;
+   GLfloat BlueGamma;
+
+   GLint rmult, gmult, bmult;  /* Range of color values */
+   GLint index_bits;           /* Bits per pixel in CI mode */
+
+   /* For PF_TRUECOLOR */
+   GLint rshift, gshift, bshift;/* Pixel color component shifts */
+   GLubyte Kernel[16];         /* Dither kernel */
+   unsigned long RtoPixel[512];        /* RGB to pixel conversion */
+   unsigned long GtoPixel[512];
+   unsigned long BtoPixel[512];
+   GLubyte PixelToR[256];      /* Pixel to RGB conversion */
+   GLubyte PixelToG[256];
+   GLubyte PixelToB[256];
+
+   /* For PF_HPCR */
+   short       hpcr_rgbTbl[3][256];
+   GLboolean   hpcr_clear_flag;
+   GLubyte     hpcr_clear_ximage_pattern[2][16];
+   XMesaImage *hpcr_clear_ximage;
+   XMesaPixmap hpcr_clear_pixmap;
+
+   /* For PF_1BIT */
+   int bitFlip;
+};
+
+
+
+/*
+ * "Derived" from gl_context.  Basically corresponds to a GLXContext.
+ */
+struct xmesa_context {
+   GLcontext *gl_ctx;          /* the core library context */
+   XMesaVisual xm_visual;      /* Describes the buffers */
+   XMesaBuffer xm_buffer;      /* current framebuffer */
+
+   XMesaDisplay *display;      /* == xm_visual->display */
+   GLboolean swapbytes;                /* Host byte order != display byte order? */
+   GLboolean direct;           /* Direct rendering context? */
+
+   GLuint pixelformat;         /* Current pixel format */
+
+   GLubyte red, green, blue, alpha;    /* current drawing color */
+   unsigned long pixel;                        /* current drawing pixel value */
+
+   GLubyte clearcolor[4];              /* current clearing color */
+   unsigned long clearpixel;           /* current clearing pixel value */
+};
+
+
+
+/*
+ * "Derived" from gl_buffer.  Basically corresponds to a GLXDrawable.
+ */
+struct xmesa_buffer {
+   GLboolean wasCurrent;       /* was ever the current buffer? */
+   GLframebuffer *gl_buffer;   /* depth, stencil, accum, etc buffers */
+   XMesaVisual xm_visual;      /* the X/Mesa visual */
+
+   XMesaContext xm_context;     /* the context associated with this buffer */
+   XMesaDisplay *display;
+   GLboolean pixmap_flag;      /* is the buffer a Pixmap? */
+   XMesaDrawable frontbuffer;  /* either a window or pixmap */
+   XMesaPixmap backpixmap;     /* back buffer Pixmap */
+   XMesaImage *backimage;      /* back buffer simulated XImage */
+
+   XMesaDrawable buffer;       /* the current buffer, either equal to */
+                               /* frontbuffer, backpixmap or XIMAGE (None) */
+
+   XMesaColormap cmap;         /* the X colormap */
+
+   GLint db_state;             /* 0 = single buffered */
+                               /* BACK_PIXMAP = use Pixmap for back buffer */
+                               /* BACK_XIMAGE = use XImage for back buffer */
+
+#ifndef XFree86Server
+   GLuint shm;                 /* X Shared Memory extension status:    */
+                               /*    0 = not available                 */
+                               /*    1 = XImage support available      */
+                               /*    2 = Pixmap support available too  */
+#ifdef SHM
+   XShmSegmentInfo shminfo;
+#endif
+#endif
+
+   XMesaImage *rowimage;       /* Used for optimized span writing */
+
+   GLuint width, height;       /* size of buffer */
+
+   GLint bottom;               /* used for FLIP macro below */
+   GLubyte *ximage_origin1;    /* used for PIXELADDR1 macro */
+   GLint ximage_width1;
+   GLushort *ximage_origin2;   /* used for PIXELADDR2 macro */
+   GLint ximage_width2;
+   bgr_t *ximage_origin3;      /* used for PIXELADDR3 macro */
+   GLint ximage_width3;
+   GLuint *ximage_origin4;     /* used for PIXELADDR4 macro */
+   GLint ximage_width4;
+
+   XMesaPixmap stipple_pixmap; /* For polygon stippling */
+   XMesaGC stipple_gc;         /* For polygon stippling */
+
+   XMesaGC gc1;                        /* GC for infrequent color changes */
+   XMesaGC gc2;                        /* GC for frequent color changes */
+   XMesaGC cleargc;            /* GC for clearing the color buffer */
+
+   /* The following are here instead of in the XMesaVisual
+    * because they depend on the window's colormap.
+    */
+
+   /* For PF_DITHER, PF_LOOKUP, PF_GRAYSCALE */
+   unsigned long color_table[576];     /* RGB -> pixel value */
+
+   /* For PF_DITHER, PF_LOOKUP, PF_GRAYSCALE */
+   GLubyte pixel_to_r[65536];          /* pixel value -> red */
+   GLubyte pixel_to_g[65536];          /* pixel value -> green */
+   GLubyte pixel_to_b[65536];          /* pixel value -> blue */
+
+   /* Used to do XAllocColor/XFreeColors accounting: */
+   int num_alloced;
+   unsigned long alloced_colors[256];
+
+#ifdef FX
+   /* For 3Dfx Glide only */
+   GLboolean FXisHackUsable;   /* Can we render into window? */
+   GLboolean FXwindowHack;     /* Are we rendering into a window? */
+   fxMesaContext FXctx;
+#endif
+
+   struct xmesa_buffer *Next;  /* Linked list pointer: */
+};
+
+
+
+/* Values for xmesa->dest: */
+#define FRONT_PIXMAP   1
+#define BACK_PIXMAP    2
+#define BACK_XIMAGE    4
+
+
+/* Values for xmesa->pixelformat: */
+#define PF_INDEX          1    /* Color Index mode */
+#define PF_TRUECOLOR      2    /* TrueColor or DirectColor, any depth */
+#define PF_TRUEDITHER     3    /* TrueColor with dithering */
+#define PF_8A8B8G8R       4    /* 32-bit TrueColor:  8-A, 8-B, 8-G, 8-R */
+#define PF_8R8G8B         5    /* 32-bit TrueColor:  8-R, 8-G, 8-B bits */
+#define PF_5R6G5B         6    /* 16-bit TrueColor:  5-R, 6-G, 5-B bits */
+#define PF_DITHER         7    /* Color-mapped RGB with dither */
+#define PF_LOOKUP         8    /* Color-mapped RGB without dither */
+#define PF_HPCR           9    /* HP Color Recovery (ad@lms.be 30/08/95) */
+#define PF_1BIT          10    /* monochrome dithering of RGB */
+#define PF_GRAYSCALE     11    /* Grayscale or StaticGray */
+#define PF_8R8G8B24      12    /* 24-bit TrueColor: 8-R, 8-G, 8-B bits */
+#define PF_DITHER_5R6G5B 13    /* 16-bit dithered TrueColor: 5-R, 6-G, 5-B */
+
+
+/*
+ * If pixelformat==PF_TRUECOLOR:
+ */
+#define PACK_TRUECOLOR( PIXEL, R, G, B )       \
+   PIXEL = xmesa->xm_visual->RtoPixel[R]       \
+         | xmesa->xm_visual->GtoPixel[G]       \
+         | xmesa->xm_visual->BtoPixel[B];      \
+
+
+/*
+ * If pixelformat==PF_TRUEDITHER:
+ */
+#define PACK_TRUEDITHER( PIXEL, X, Y, R, G, B )                        \
+{                                                              \
+   int d = xmesa->xm_visual->Kernel[((X)&3) | (((Y)&3)<<2)];   \
+   PIXEL = xmesa->xm_visual->RtoPixel[(R)+d]                   \
+         | xmesa->xm_visual->GtoPixel[(G)+d]                   \
+         | xmesa->xm_visual->BtoPixel[(B)+d];                  \
+}
+
+
+
+/*
+ * If pixelformat==PF_8A8B8G8R:
+ */
+#define PACK_8A8B8G8R( R, G, B, A )    \
+       ( ((A) << 24) | ((B) << 16) | ((G) << 8) | (R) )
+
+
+/*
+ * Like PACK_8A8B8G8R() but don't use alpha.  This is usually an acceptable
+ * shortcut.
+ */
+#define PACK_8B8G8R( R, G, B )   ( ((B) << 16) | ((G) << 8) | (R) )
+
+
+
+/*
+ * If pixelformat==PF_8R8G8B:
+ */
+#define PACK_8R8G8B( R, G, B)   ( ((R) << 16) | ((G) << 8) | (B) )
+
+
+/*
+ * If pixelformat==PF_5R6G5B:
+ */
+#define PACK_5R6G5B( R, G, B)   ( (((R) & 0xf8) << 8) | (((G) & 0xfc) << 3) | ((B) >> 3) )
+
+
+
+/*
+ * If pixelformat==PF_DITHER:
+ *
+ * Improved 8-bit RGB dithering code contributed by Bob Mercier
+ * (mercier@hollywood.cinenet.net).  Thanks Bob!
+ */
+#undef _R
+#undef _G
+#undef _B
+#ifdef DITHER666
+# define _R   6
+# define _G   6
+# define _B   6
+# define _MIX(r,g,b)  (((r)*_G+(g))*_B+(b))
+#else
+# define _R    5
+# define _G    9
+# define _B    5
+# define _MIX(r,g,b)   ( ((g)<<6) | ((b)<<3) | (r) )
+#endif
+#define _DX    4
+#define _DY    4
+#define _D     (_DX*_DY)
+
+/*#define _DITH(C,c,d) (((unsigned)((_D*(C-1)+1)*c+d))/(_D*256))*/
+#define _DITH(C,c,d)   (((unsigned)((_D*(C-1)+1)*c+d)) >> 12)
+
+#define MAXC   256
+static int kernel8[_DY*_DX] = {
+    0 * MAXC,  8 * MAXC,  2 * MAXC, 10 * MAXC,
+   12 * MAXC,  4 * MAXC, 14 * MAXC,  6 * MAXC,
+    3 * MAXC, 11 * MAXC,  1 * MAXC,  9 * MAXC,
+   15 * MAXC,  7 * MAXC, 13 * MAXC,  5 * MAXC,
+};
+/*static int __d;*/
+
+/* Dither for random X,Y */
+#define DITHER_SETUP                                           \
+       int __d;                                                \
+       unsigned long *ctable = xmesa->xm_buffer->color_table;
+
+#define DITHER( X, Y, R, G, B )                                \
+       (__d = kernel8[(((Y)&3)<<2) | ((X)&3)],         \
+        ctable[_MIX(_DITH(_R, (R), __d),               \
+                    _DITH(_G, (G), __d),               \
+                    _DITH(_B, (B), __d))])
+
+/* Dither for random X, fixed Y */
+#define XDITHER_SETUP(Y)                                       \
+       int __d;                                                \
+       unsigned long *ctable = xmesa->xm_buffer->color_table;  \
+       int *kernel = &kernel8[ ((Y)&3) << 2 ];
+
+#define XDITHER( X, R, G, B )                          \
+       (__d = kernel[(X)&3],                           \
+       ctable[_MIX(_DITH(_R, (R), __d),                \
+                   _DITH(_G, (G), __d),                \
+                   _DITH(_B, (B), __d))])
+
+
+
+/*
+ * Dithering for flat-shaded triangles.  Precompute all 16 possible
+ * pixel values given the triangle's RGB color.  Contributed by Martin Shenk.
+ */
+static GLushort DitherValues[16];   /* array of (up to) 16-bit pixel values */
+
+#define FLAT_DITHER_SETUP( R, G, B )                                   \
+       {                                                               \
+          unsigned long *ctable = xmesa->xm_buffer->color_table;       \
+          int msdr = (_D*((_R)-1)+1) * (R);                            \
+          int msdg = (_D*((_G)-1)+1) * (G);                            \
+          int msdb = (_D*((_B)-1)+1) * (B);                            \
+          int i;                                                       \
+          for (i=0;i<16;i++) {                                         \
+             int k = kernel8[i];                                       \
+             int j = _MIX( (msdr+k)>>12, (msdg+k)>>12, (msdb+k)>>12 ); \
+             DitherValues[i] = (GLushort) ctable[j];                   \
+          }                                                            \
+        }
+
+#define FLAT_DITHER_ROW_SETUP(Y)                                       \
+       GLushort *ditherRow = DitherValues + ( ((Y)&3) << 2);
+
+#define FLAT_DITHER(X)  ditherRow[(X)&3]
+
+
+
+/*
+ * If pixelformat==PF_LOOKUP:
+ */
+#define _DITH0(C,c)    (((unsigned)((_D*(C-1)+1)*c)) >> 12)
+
+#define LOOKUP_SETUP                                           \
+       unsigned long *ctable = xmesa->xm_buffer->color_table
+
+#define LOOKUP( R, G, B )                      \
+       ctable[_MIX(_DITH0(_R, (R)),            \
+                   _DITH0(_G, (G)),            \
+                   _DITH0(_B, (B)))]
+
+
+
+/*
+ * If pixelformat==PF_HPCR:
+ *
+ *      HP Color Recovery dithering               (ad@lms.be 30/08/95)
+ *      HP has on it's 8-bit 700-series computers, a feature called
+ *      'Color Recovery'.  This allows near 24-bit output (so they say).
+ *      It is enabled by selecting the 8-bit  TrueColor  visual AND
+ *      corresponding  colormap (see tkInitWindow) AND doing some special
+ *      dither.
+ */
+static const short HPCR_DRGB[3][2][16] = {
+{
+    { 16, -4,  1,-11, 14, -6,  3, -9, 15, -5,  2,-10, 13, -7,  4, -8},
+    {-15,  5,  0, 12,-13,  7, -2, 10,-14,  6, -1, 11,-12,  8, -3,  9} 
+},
+{
+    {-11, 15, -7,  3, -8, 14, -4,  2,-10, 16, -6,  4, -9, 13, -5,  1},
+    { 12,-14,  8, -2,  9,-13,  5, -1, 11,-15,  7, -3, 10,-12,  6,  0} 
+},
+{
+    {  6,-18, 26,-14,  2,-22, 30,-10,  8,-16, 28,-12,  4,-20, 32, -8},
+    { -4, 20,-24, 16,  0, 24,-28, 12, -6, 18,-26, 14, -2, 22,-30, 10} 
+}
+};
+
+#define DITHER_HPCR( X, Y, R, G, B )                                      \
+  ( ((xmesa->xm_visual->hpcr_rgbTbl[0][R] + HPCR_DRGB[0][(Y)&1][(X)&15]) & 0xE0)     \
+  |(((xmesa->xm_visual->hpcr_rgbTbl[1][G] + HPCR_DRGB[1][(Y)&1][(X)&15]) & 0xE0)>>3) \
+  | ((xmesa->xm_visual->hpcr_rgbTbl[2][B] + HPCR_DRGB[2][(Y)&1][(X)&15])>>6)      \
+  )
+
+
+
+/*
+ * If pixelformat==PF_1BIT:
+ */
+static int const kernel1[16] = {
+   0*47,  9*47,  4*47, 12*47,     /* 47 = (255*3)/16 */
+   6*47,  2*47, 14*47,  8*47,
+  10*47,  1*47,  5*47, 11*47,
+   7*47, 13*47,  3*47, 15*47 };
+
+#define SETUP_1BIT  int bitFlip = xmesa->xm_visual->bitFlip
+#define DITHER_1BIT( X, Y, R, G, B )   \
+       (( ((int)(R)+(int)(G)+(int)(B)) > kernel1[(((Y)&3) << 2) | ((X)&3)] ) ^ bitFlip)
+
+
+
+/*
+ * If pixelformat==PF_GRAYSCALE:
+ */
+#define GRAY_RGB( R, G, B )   xmesa->xm_buffer->color_table[((R) + (G) + (B))/3]
+
+
+
+#define XIMAGE None
+
+
+/*
+ * Converts a GL window Y coord to an X window Y coord:
+ */
+#define FLIP(Y)  (xmesa->xm_buffer->bottom-(Y))
+
+
+/*
+ * Return the address of a 1, 2 or 4-byte pixel in the back XImage:
+ * X==0 is left, Y==0 is bottom.
+ */
+#define PIXELADDR1( X, Y )  \
+      ( xmesa->xm_buffer->ximage_origin1 - (Y) * xmesa->xm_buffer->ximage_width1 + (X) )
+
+#define PIXELADDR2( X, Y )  \
+      ( xmesa->xm_buffer->ximage_origin2 - (Y) * xmesa->xm_buffer->ximage_width2 + (X) )
+
+#define PIXELADDR3( X, Y )  \
+      ( xmesa->xm_buffer->ximage_origin3 - (Y) * xmesa->xm_buffer->ximage_width3 + (X) )
+
+#define PIXELADDR4( X, Y )  \
+      ( xmesa->xm_buffer->ximage_origin4 - (Y) * xmesa->xm_buffer->ximage_width4 + (X) )
+
+
+
+/*
+ * External functions:
+ */
+
+extern unsigned long xmesa_color_to_pixel( XMesaContext xmesa,
+                                 GLubyte r, GLubyte g, GLubyte b, GLubyte a );
+
+extern void xmesa_alloc_back_buffer( XMesaBuffer b );
+
+extern void xmesa_update_state( GLcontext *ctx );
+
+extern points_func xmesa_get_points_func( GLcontext *ctx );
+
+extern line_func xmesa_get_line_func( GLcontext *ctx );
+
+extern triangle_func xmesa_get_triangle_func( GLcontext *ctx );
+
+
+/* XXX this is a hack to implement shared display lists with 3Dfx */
+extern XMesaBuffer XMesaCreateWindowBuffer2( XMesaVisual v,
+                                            XMesaWindow w,
+                                            XMesaContext c );
+
+
+/*
+ * These are the extra routines required for integration with XFree86.
+ * None of these routines should be user visible. -KEM
+ */
+extern void XMesaSetVisualDisplay( XMesaDisplay *dpy, XMesaVisual v );
+extern GLboolean XMesaForceCurrent(XMesaContext c);
+extern GLboolean XMesaLoseCurrent(XMesaContext c);
+extern void XMesaReset( void );
+
+#endif
diff --git a/src/mesa/main/Imakefile b/src/mesa/main/Imakefile
new file mode 100644 (file)
index 0000000..115f16c
--- /dev/null
@@ -0,0 +1,127 @@
+#define DoNormalLib NO\r
+#define DoSharedLib YES\r
+#define DoDebugLib NO\r
+#define DoProfileLib NO\r
+#define LibName MESAGL\r
+#define SoRev SOX11REV\r
+#define LibHeaders NO\r
+\r
+#include <Threads.tmpl>\r
+\r
+REQUIREDLIBS = $(X11ROOT)\\XFree86\\lib\\ Xext X11\r
+BUILDLIBDIR = $(TOP)\\lib\r
+\r
+INCLUDES = -I$(TOP)\\include\r
+\r
+SRCS = \\r
+accum.c \\r
+alpha.c \\r
+alphabuf.c \\r
+api1.c \\r
+api2.c \\r
+attrib.c \\r
+bitmap.c \\r
+blend.c \\r
+bresenhm.c \\r
+clip.c \\r
+context.c \\r
+copypix.c \\r
+dd.c \\r
+depth.c \\r
+draw.c \\r
+drawpix.c \\r
+enable.c \\r
+eval2.c \\r
+feedback.c \\r
+fog.c \\r
+fortran.c \\r
+get.c \\r
+hash.c \\r
+glx.c \\r
+interp.c \\r
+light.c \\r
+lines.c \\r
+list.c \\r
+logic.c \\r
+masking.c \\r
+misc.c \\r
+osmesa.c \\r
+pb.c \\r
+pixel.c \\r
+points.c \\r
+polygons.c \\r
+readpix.c \\r
+scissor.c \\r
+span.c \\r
+stencil.c \\r
+svgamesa.c \\r
+texture.c \\r
+varray.c \\r
+vb.c \\r
+vertex.c \\r
+xfonts.c \\r
+xform.c \\r
+xmesa1.c \\r
+xmesa2.c \\r
+xmesa3.c\r
+\r
+OBJS = \\r
+accum.o \\r
+alpha.o \\r
+alphabuf.o \\r
+api1.o \\r
+api2.o \\r
+attrib.o \\r
+bitmap.o \\r
+blend.o \\r
+bresenhm.o \\r
+clip.o \\r
+context.o \\r
+copypix.o \\r
+dd.o \\r
+depth.o \\r
+draw.o \\r
+drawpix.o \\r
+enable.o \\r
+eval2.o \\r
+feedback.o \\r
+fog.o \\r
+fortran.o \\r
+get.o \\r
+hash.o \\r
+glx.o \\r
+interp.o \\r
+light.o \\r
+lines.o \\r
+list.o \\r
+logic.o \\r
+masking.o \\r
+misc.o \\r
+osmesa.o \\r
+pb.o \\r
+pixel.o \\r
+points.o \\r
+polygons.o \\r
+readpix.o \\r
+scissor.o \\r
+span.o \\r
+stencil.o \\r
+svgamesa.o \\r
+texture.o \\r
+varray.o \\r
+vb.o \\r
+vertex.o \\r
+xfonts.o \\r
+xform.o \\r
+xmesa1.o \\r
+xmesa2.o \\r
+xmesa3.o\r
+xmesa4.o\r
+\r
+LINTLIBS =\r
+\r
+#include <Library.tmpl>\r
+\r
+DependTarget()\r
+\r
+\1a
\ No newline at end of file
diff --git a/src/mesa/main/KNOWN_BUGS b/src/mesa/main/KNOWN_BUGS
new file mode 100644 (file)
index 0000000..9c9076b
--- /dev/null
@@ -0,0 +1,20 @@
+$Id: KNOWN_BUGS,v 1.1 1999/08/19 00:55:41 jtg Exp $
+
+
+Performance issues with EXT_point_parameters & quake2
+
+
+Broken drivers: 
+
+       --> After integration of the changes in kw3, only the X and FX
+drivers are known to work.  Windows and D3D are known to be broken,
+and all others are suspected to be broken.  Please test your driver
+and update this entry when more is known.
+
+
+
+Separate specular color interpolation isn't implemented for points and
+lines.  Also, will have to add specular color add to pb.c (pixel buffer
+code).
+
+
diff --git a/src/mesa/main/Makefile.DJ b/src/mesa/main/Makefile.DJ
new file mode 100644 (file)
index 0000000..27c3556
--- /dev/null
@@ -0,0 +1,95 @@
+# $Id: Makefile.DJ,v 1.1 1999/08/19 00:55:41 jtg Exp $
+
+# Makefile for core library for MS-DOS using djgpp
+
+# Mesa 3-D graphics library
+# Version:  3.1
+# Copyright (C) 1995-1998  Brian Paul
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the Free
+# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+# $Log: Makefile.DJ,v $
+# Revision 1.1  1999/08/19 00:55:41  jtg
+# Initial revision
+#
+# Revision 1.1  1999/01/01 14:35:09  brianp
+# Initial revision
+#
+
+
+
+##### MACROS #####
+
+VPATH = RCS
+
+INCDIR = ..\include
+LIBDIR = ..\lib
+
+# Want UniVBE (Display Doctor) Support, Scitech Software www.scitechsoft.com
+# Set -I to point to scitech include files.
+# Haven`t finished doing univbe version for djgpp
+#CFLAGS += -DUNIVBE -D__DOS__ -D__MSDOS32__ -IC:\scitech\include
+CFLAGS +=  -D__DOS__ -D__MSDOS32__
+
+CORE_SOURCES = accum.c alpha.c alphabuf.c api1.c api2.c apiext.c attrib.c \
+       bitmap.c blend.c clip.c colortab.c context.c copypix.c depth.c \
+       dlist.c drawpix.c enable.c eval.c feedback.c fog.c \
+       get.c hash.c image.c light.c lines.c logic.c masking.c matrix.c \
+       misc.c mmath.c mthreads.c pb.c pixel.c points.c pointers.c polygon.c \
+       quads.c rastpos.c readpix.c rect.c scissor.c shade.c span.c \
+       stencil.c teximage.c texobj.c texstate.c texture.c triangle.c \
+       varray.c winpos.c vb.c vbfill.c vbrender.c vbxform.c xform.c \
+       zoom.c
+
+DRIVER_SOURCES = DOS\dosmesa.c
+
+SOURCES = $(CORE_SOURCES) $(DRIVER_SOURCES)
+
+OBJECTS = $(SOURCES:.c=.o)
+
+#CFLAGS += -g
+
+##### RULES #####
+
+.c.o:
+       gcc -c -DDOSVGA -I$(INCDIR) $(CFLAGS) $<
+
+##### TARGETS #####
+
+GL_LIB = dosmesa.a
+
+default: $(LIBDIR)/$(GL_LIB)
+
+clean:
+       -del *.o
+
+MAKELIB = AR ruv
+RANLIB = ls
+
+# Make the library
+$(LIBDIR)/$(GL_LIB): $(OBJECTS)
+       $(MAKELIB) $(GL_LIB) $(OBJECTS)
+       copy $(GL_LIB) $(LIBDIR)\$(GL_LIB)
+
+include depend.dos
+#
+
+# Run 'make depend' to update the dependencies if you change what's included
+# by any source file.
+#
+dep: $(SOURCES)
+       makedep -fdepend -Y -I../include $(SOURCES)
+
diff --git a/src/mesa/main/Makefile.X11 b/src/mesa/main/Makefile.X11
new file mode 100644 (file)
index 0000000..e6419b5
--- /dev/null
@@ -0,0 +1,243 @@
+# $Id: Makefile.X11,v 1.1 1999/08/19 00:55:41 jtg Exp $
+
+# Mesa 3-D graphics library
+# Version:  3.1
+# Copyright (C) 1995-1999  Brian Paul
+
+# Makefile for core library
+
+
+##### MACROS #####
+
+VPATH = RCS
+
+INCDIR = ../include
+LIBDIR = ../lib
+
+CORE_SOURCES = \
+       accum.c \
+       alpha.c \
+       alphabuf.c \
+       api1.c \
+       api2.c \
+       apiext.c \
+       attrib.c \
+       bbox.c \
+       bitmap.c \
+       blend.c \
+       clip.c \
+       colortab.c \
+       config.c \
+       context.c \
+       copypix.c \
+       cva.c \
+       debug_xform.c \
+       depth.c \
+       dlist.c \
+       drawpix.c \
+       enable.c \
+       enums.c \
+       eval.c \
+       extensions.c \
+       feedback.c \
+       fog.c \
+       get.c \
+       hash.c \
+       image.c \
+       light.c \
+       lines.c \
+       logic.c \
+       masking.c \
+       matrix.c \
+       misc.c \
+       mmath.c \
+       mthreads.c \
+       pb.c \
+       pixel.c \
+       pipeline.c \
+       points.c \
+       pointers.c \
+       polygon.c \
+       quads.c \
+       rastpos.c \
+       readpix.c \
+       rect.c \
+       scissor.c \
+       shade.c \
+       span.c \
+       stages.c \
+       stencil.c \
+       teximage.c \
+       texobj.c \
+       texstate.c \
+       texture.c \
+       translate.c \
+       triangle.c \
+       varray.c \
+       vb.c \
+       vbcull.c \
+       vbfill.c \
+       vbindirect.c \
+       vbrender.c \
+       vbxform.c \
+       vector.c \
+       winpos.c \
+       xform.c \
+       zoom.c \
+       X86/x86.c \
+       X86/common_x86.c \
+       X86/3dnow.c
+
+DRIVER_SOURCES = \
+       X/glxapi.c \
+       X/fakeglx.c \
+       X/realglx.c \
+       X/xfonts.c \
+       X/xmesa1.c \
+       X/xmesa2.c \
+       X/xmesa3.c \
+       X/xmesa4.c \
+       OSmesa/osmesa.c \
+       SVGA/svgamesa.c \
+       FX/fxapi.c \
+       FX/fxclip.c \
+       FX/fxcva.c \
+       FX/fxdd.c \
+       FX/fxddspan.c \
+       FX/fxddtex.c \
+       FX/fxfastpath.c \
+       FX/fxpipeline.c \
+       FX/fxrender.c \
+       FX/fxsanity.c \
+       FX/fxsetup.c \
+       FX/fxtexman.c \
+       FX/fxtrifuncs.c \
+       FX/fxvsetup.c \
+       FX/fxglidew.c 
+#      GGI/ggimesa.c
+
+ASM_SOURCES = 
+
+ADDITIONAL_OBJ = 
+
+OBJECTS = $(ASM_SOURCES:.S=.o) \
+       $(CORE_SOURCES:.c=.o) \
+       $(DRIVER_SOURCES:.c=.o) \
+       $(ADDITIONAL_OBJ)
+
+
+#who put these here!?!
+#GL_LIB = libMesaGL.so
+#GLU_LIB = libMesaGLU.so
+#GLUT_LIB = libglut.so
+#CC = gcc
+#INCLUDES=-I. -I../include -I/usr/X11R6/include -I/usr/include/glide -I/usr/local/glide/include
+
+
+##### RULES #####
+
+.c.o:
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+
+.S.o:
+       $(CC) -c $(CFLAGS) $< -o $@
+
+
+# UGH! These rules shouldn't be needed but IRIX's make (and others?) needs them
+X/glxapi.o: X/glxapi.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+X/fakeglx.o: X/fakeglx.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+X/realglx.o: X/realglx.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+X/xfonts.o: X/xfonts.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+X/xmesa1.o: X/xmesa1.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+X/xmesa2.o: X/xmesa2.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+X/xmesa3.o: X/xmesa3.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+X/xmesa4.o: X/xmesa4.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+SVGA/svgamesa.o: SVGA/svgamesa.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+OSmesa/osmesa.o: OSmesa/osmesa.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+FX/fxapi.o: FX/fxapi.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+FX/fxclip.o: FX/fxclip.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+FX/fxcva.o: FX/fxcva.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+FX/fxdd.o: FX/fxdd.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+FX/fxddspan.o: FX/fxddspan.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+FX/fxddtex.o: FX/fxddtex.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+FX/fxfastpath.o: FX/fxfastpath.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+FX/fxpipeline.o: FX/fxpipeline.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+FX/fxrender.o: FX/fxrender.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+FX/fxsanity.o: FX/fxsanity.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+FX/fxsetup.o: FX/fxsetup.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+FX/fxtrifuncs.o: FX/fxtrifuncs.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+FX/fxtexman.o: FX/fxtexman.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+FX/fxvsetup.o: FX/fxvsetup.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+FX/fxglidew.o: FX/fxglidew.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+FX/X86/fx_3dnow_fastpath.o: FX/X86/fx_3dnow_fastpath.S FX/X86/fx_regoff.h
+FX/X86/fx_regoff.h: FX/X86/fx_gen_regoff
+       $< > $@
+FX/X86/fx_gen_regoff : FX/X86/fx_gen_regoff.c
+       $(CC) -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+GGI/ggimesa.o: GGI/ggimesa.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+X86/x86.o: X86/x86.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+X86/common_x86.o: X86/common_x86.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+X86/3dnow.o: X86/3dnow.c
+       $(CC) -c -I. -I$(INCDIR) $(CFLAGS) $< -o $@
+
+
+##### TARGETS #####
+
+#default:
+#      @echo "Specify a target configuration"
+
+clean:
+       -rm *.o *~ */*.o */*~
+
+targets: $(LIBDIR)/$(GL_LIB)
+
+# Make the library
+$(LIBDIR)/$(GL_LIB): $(OBJECTS)
+       $(MAKELIB) $(GL_LIB) $(MAJOR) $(MINOR) $(OBJECTS)
+       rm -f $(LIBDIR)/$(GL_LIB)*
+       mv $(GL_LIB)* $(LIBDIR)
+
+
+include ../Make-config
+
+include depend
+
+
+
+#
+# Run 'make dep' to update the dependencies if you change what's included
+# by any source file.
+# 
+dep: $(CORE_SOURCES) $(DRIVER_SOURCES)
+       makedepend -fdepend -Y -I../include -DGGI -DSVGA -DFX $(CORE_SOURCES) $(DRIVER_SOURCES)
+
+tags:
+       etags `find . -name \*.[ch]` `find ../include`
diff --git a/src/mesa/main/accum.c b/src/mesa/main/accum.c
new file mode 100644 (file)
index 0000000..29a8a13
--- /dev/null
@@ -0,0 +1,495 @@
+/* $Id: accum.c,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <assert.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include "accum.h"
+#include "context.h"
+#include "macros.h"
+#include "masking.h"
+#include "span.h"
+#include "types.h"
+#ifdef XFree86Server
+#include "GL/xf86glx.h"
+#endif
+#endif
+
+
+/*
+ * Accumulation buffer notes
+ *
+ * Normally, accumulation buffer values are GLshorts with values in
+ * [-32767, 32767] which represent floating point colors in [-1, 1],
+ * as suggested by the OpenGL specification.
+ *
+ * We optimize for the common case used for full-scene antialiasing:
+ *    // start with accum buffer cleared to zero
+ *    glAccum(GL_LOAD, w);   // or GL_ACCUM the first image
+ *    glAccum(GL_ACCUM, w);
+ *    ...
+ *    glAccum(GL_ACCUM, w);
+ *    glAccum(GL_RETURN, 1.0);
+ * That is, we start with an empty accumulation buffer and accumulate
+ * n images, each with weight w = 1/n.
+ * In this scenario, we can simply store unscaled integer values in
+ * the accum buffer instead of scaled integers.  We'll also keep track
+ * of the w value so when we do GL_RETURN we simply divide the accumulated
+ * values by n (=1/w).
+ * This lets us avoid _many_ int->float->int conversions.
+ */
+
+
+
+void gl_alloc_accum_buffer( GLcontext *ctx )
+{
+   GLint n;
+
+   if (ctx->Buffer->Accum) {
+      free( ctx->Buffer->Accum );
+      ctx->Buffer->Accum = NULL;
+   }
+
+   /* allocate accumulation buffer if not already present */
+   n = ctx->Buffer->Width * ctx->Buffer->Height * 4 * sizeof(GLaccum);
+   ctx->Buffer->Accum = (GLaccum *) malloc( n );
+   if (!ctx->Buffer->Accum) {
+      /* unable to setup accumulation buffer */
+      gl_error( ctx, GL_OUT_OF_MEMORY, "glAccum" );
+   }
+   ctx->IntegerAccumMode = GL_TRUE;
+   ctx->IntegerAccumScaler = 0.0;
+}
+
+
+
+void gl_ClearAccum( GLcontext *ctx,
+                    GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha )
+{
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glAccum");
+
+   ctx->Accum.ClearColor[0] = CLAMP( red, -1.0, 1.0 );
+   ctx->Accum.ClearColor[1] = CLAMP( green, -1.0, 1.0 );
+   ctx->Accum.ClearColor[2] = CLAMP( blue, -1.0, 1.0 );
+   ctx->Accum.ClearColor[3] = CLAMP( alpha, -1.0, 1.0 );
+}
+
+
+
+/*
+ * This is called when we fall out of optimized/unscaled accum buffer mode.
+ * That is, we convert each unscaled accum buffer value into a scaled value
+ * representing the range[-1, 1].
+ */
+static void rescale_accum( GLcontext *ctx )
+{
+   const GLuint n = ctx->Buffer->Width * ctx->Buffer->Height * 4;
+   const GLfloat s = ctx->IntegerAccumScaler * (32767.0 / 255.0);
+   GLaccum *accum = ctx->Buffer->Accum;
+   GLuint i;
+
+   assert(ctx->IntegerAccumMode);
+   assert(sizeof(GLchan) == 1);  /* if not true, 255.0 above must be fixed */
+   assert(accum);
+
+   for (i = 0; i < n; i++) {
+      accum[i] = (GLaccum) (accum[i] * s);
+   }
+
+   ctx->IntegerAccumMode = GL_FALSE;
+}
+
+
+
+void gl_Accum( GLcontext *ctx, GLenum op, GLfloat value )
+{
+   GLuint xpos, ypos, width, height, width4;
+   GLfloat acc_scale;
+   GLubyte rgba[MAX_WIDTH][4];
+   
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glAccum");
+
+   if (ctx->Visual->AccumBits==0 || !ctx->Buffer->Accum) {
+      /* No accumulation buffer! */
+      gl_warning(ctx, "Calling glAccum() without an accumulation buffer");
+      return;
+   }
+
+   if (sizeof(GLaccum)==1) {
+      acc_scale = 127.0;
+   }
+   else if (sizeof(GLaccum)==2) {
+      acc_scale = 32767.0;
+   }
+   else {
+      /* sizeof(GLaccum) > 2 (Cray) */
+      acc_scale = (float) SHRT_MAX;
+   }
+
+   if (ctx->NewState)
+      gl_update_state( ctx );
+
+   /* Determine region to operate upon. */
+   if (ctx->Scissor.Enabled) {
+      xpos = ctx->Scissor.X;
+      ypos = ctx->Scissor.Y;
+      width = ctx->Scissor.Width;
+      height = ctx->Scissor.Height;
+   }
+   else {
+      /* whole window */
+      xpos = 0;
+      ypos = 0;
+      width = ctx->Buffer->Width;
+      height = ctx->Buffer->Height;
+   }
+
+   width4 = 4 * width;
+
+   switch (op) {
+      case GL_ADD:
+         {
+           const GLaccum intVal = (GLaccum) (value * acc_scale);
+           GLuint j;
+            /* May have to leave optimized accum buffer mode */
+            if (ctx->IntegerAccumMode)
+               rescale_accum(ctx);
+           for (j = 0; j < height; j++) {
+              GLaccum * acc = ctx->Buffer->Accum + ypos * width4 + 4 * xpos;
+               GLuint i;
+              for (i = 0; i < width4; i++) {
+                  acc[i] += intVal;
+              }
+              ypos++;
+           }
+        }
+        break;
+
+      case GL_MULT:
+        {
+           GLuint j;
+            /* May have to leave optimized accum buffer mode */
+            if (ctx->IntegerAccumMode)
+               rescale_accum(ctx);
+           for (j = 0; j < height; j++) {
+              GLaccum *acc = ctx->Buffer->Accum + ypos * width4 + 4 * xpos;
+               GLuint i;
+              for (i = 0; i < width4; i++) {
+                  acc[i] = (GLaccum) ( (GLfloat) acc[i] * value );
+              }
+              ypos++;
+           }
+        }
+        break;
+
+      case GL_ACCUM:
+         (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Pixel.DriverReadBuffer );
+
+         /* May have to leave optimized accum buffer mode */
+         if (ctx->IntegerAccumScaler == 0.0 && value > 0.0 && value <= 1.0)
+            ctx->IntegerAccumScaler = value;
+         if (ctx->IntegerAccumMode && value != ctx->IntegerAccumScaler)
+            rescale_accum(ctx);
+            
+         if (ctx->IntegerAccumMode) {
+            /* simply add integer color values into accum buffer */
+            GLuint j;
+            GLaccum *acc = ctx->Buffer->Accum + ypos * width4 + xpos * 4;
+            assert(ctx->IntegerAccumScaler > 0.0);
+            assert(ctx->IntegerAccumScaler <= 1.0);
+            for (j = 0; j < height; j++) {
+               
+               GLuint i, i4;
+               gl_read_rgba_span(ctx, width, xpos, ypos, rgba);
+               for (i = i4 = 0; i < width; i++, i4+=4) {
+                  acc[i4+0] += rgba[i][RCOMP];
+                  acc[i4+1] += rgba[i][GCOMP];
+                  acc[i4+2] += rgba[i][BCOMP];
+                  acc[i4+3] += rgba[i][ACOMP];
+               }
+               acc += width4;
+               ypos++;
+            }
+         }
+         else {
+            /* scaled integer accum buffer */
+            const GLfloat rscale = value * acc_scale / 255.0;
+            const GLfloat gscale = value * acc_scale / 255.0;
+            const GLfloat bscale = value * acc_scale / 255.0;
+            const GLfloat ascale = value * acc_scale / 255.0;
+            GLuint j;
+            for (j=0;j<height;j++) {
+               GLaccum *acc = ctx->Buffer->Accum + ypos * width4 + xpos * 4;
+               GLuint i;
+               gl_read_rgba_span(ctx, width, xpos, ypos, rgba);
+               for (i=0;i<width;i++) {
+                  *acc += (GLaccum) ( (GLfloat) rgba[i][RCOMP] * rscale );  acc++;
+                  *acc += (GLaccum) ( (GLfloat) rgba[i][GCOMP] * gscale );  acc++;
+                  *acc += (GLaccum) ( (GLfloat) rgba[i][BCOMP] * bscale );  acc++;
+                  *acc += (GLaccum) ( (GLfloat) rgba[i][ACOMP] * ascale );  acc++;
+               }
+               ypos++;
+            }
+         }
+         (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Color.DriverDrawBuffer );
+        break;
+
+      case GL_LOAD:
+         (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Pixel.DriverReadBuffer );
+
+         /* This is a change to go into optimized accum buffer mode */
+         if (value > 0.0 && value <= 1.0) {
+            ctx->IntegerAccumMode = GL_TRUE;
+            ctx->IntegerAccumScaler = value;
+         }
+         else {
+            ctx->IntegerAccumMode = GL_FALSE;
+            ctx->IntegerAccumScaler = 0.0;
+         }
+
+         if (ctx->IntegerAccumMode) {
+            /* just copy values into accum buffer */
+            GLuint j;
+            GLaccum *acc = ctx->Buffer->Accum + ypos * width4 + xpos * 4;
+            assert(ctx->IntegerAccumScaler > 0.0);
+            assert(ctx->IntegerAccumScaler <= 1.0);
+            for (j = 0; j < height; j++) {
+               GLuint i, i4;
+               gl_read_rgba_span(ctx, width, xpos, ypos, rgba);
+               for (i = i4 = 0; i < width; i++, i4 += 4) {
+                  acc[i4+0] = rgba[i][RCOMP];
+                  acc[i4+1] = rgba[i][GCOMP];
+                  acc[i4+2] = rgba[i][BCOMP];
+                  acc[i4+3] = rgba[i][ACOMP];
+               }
+               acc += width4;
+               ypos++;
+            }
+         }
+         else {
+            /* scaled integer accum buffer */
+            const GLfloat rscale = value * acc_scale / 255.0;
+            const GLfloat gscale = value * acc_scale / 255.0;
+            const GLfloat bscale = value * acc_scale / 255.0;
+            const GLfloat ascale = value * acc_scale / 255.0;
+            GLuint i, j;
+            for (j = 0; j < height; j++) {
+               GLaccum *acc = ctx->Buffer->Accum + ypos * width4 + xpos * 4;
+               gl_read_rgba_span(ctx, width, xpos, ypos, rgba);
+               for (i=0;i<width;i++) {
+                  *acc++ = (GLaccum) ( (GLfloat) rgba[i][RCOMP] * rscale );
+                  *acc++ = (GLaccum) ( (GLfloat) rgba[i][GCOMP] * gscale );
+                  *acc++ = (GLaccum) ( (GLfloat) rgba[i][BCOMP] * bscale );
+                  *acc++ = (GLaccum) ( (GLfloat) rgba[i][ACOMP] * ascale );
+               }
+               ypos++;
+            }
+         }
+         (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Color.DriverDrawBuffer );
+        break;
+
+      case GL_RETURN:
+         /* May have to leave optimized accum buffer mode */
+         if (ctx->IntegerAccumMode && value != 1.0)
+            rescale_accum(ctx);
+
+         if (ctx->IntegerAccumMode) {
+            /* build lookup table to avoid integer divides */
+            GLint divisor = (GLint) ((1.0F / ctx->IntegerAccumScaler) + 0.5F);
+            static GLubyte divTable[32768];
+            static GLint prevDivisor = 0.0;
+            GLuint j;
+            if (divisor != prevDivisor) {
+               assert(divisor * 256 <= 32768);
+               for (j = 0; j < divisor * 256; j++)
+                  divTable[j] = j / divisor;
+               prevDivisor = divisor;
+            }
+
+            assert(ctx->IntegerAccumScaler > 0.0);
+            assert(ctx->IntegerAccumScaler <= 1.0);
+            for (j = 0; j < height; j++) {
+               const GLaccum *acc = ctx->Buffer->Accum + ypos * width4 + xpos*4;
+               GLuint i, i4;
+               for (i = i4 = 0; i < width; i++, i4 += 4) {
+                  ASSERT(acc[i4+0] < divisor * 256);
+                  ASSERT(acc[i4+1] < divisor * 256);
+                  ASSERT(acc[i4+2] < divisor * 256);
+                  ASSERT(acc[i4+3] < divisor * 256);
+                  rgba[i][RCOMP] = divTable[acc[i4+0]];
+                  rgba[i][GCOMP] = divTable[acc[i4+1]];
+                  rgba[i][BCOMP] = divTable[acc[i4+2]];
+                  rgba[i][ACOMP] = divTable[acc[i4+3]];
+               }
+               if (ctx->Color.SWmasking) {
+                  gl_mask_rgba_span( ctx, width, xpos, ypos, rgba );
+               }
+               (*ctx->Driver.WriteRGBASpan)( ctx, width, xpos, ypos, 
+                                             (const GLubyte (*)[4])rgba, NULL );
+               ypos++;
+            }
+         }
+         else {
+            const GLfloat rscale = value / acc_scale * 255.0F;
+            const GLfloat gscale = value / acc_scale * 255.0F;
+            const GLfloat bscale = value / acc_scale * 255.0F;
+            const GLfloat ascale = value / acc_scale * 255.0F;
+            GLuint i, j;
+            for (j=0;j<height;j++) {
+               const GLaccum *acc = ctx->Buffer->Accum + ypos * width4 + xpos*4;
+               for (i=0;i<width;i++) {
+                  GLint r, g, b, a;
+                  r = (GLint) ( (GLfloat) (*acc++) * rscale + 0.5F );
+                  g = (GLint) ( (GLfloat) (*acc++) * gscale + 0.5F );
+                  b = (GLint) ( (GLfloat) (*acc++) * bscale + 0.5F );
+                  a = (GLint) ( (GLfloat) (*acc++) * ascale + 0.5F );
+                  rgba[i][RCOMP] = CLAMP( r, 0, 255 );
+                  rgba[i][GCOMP] = CLAMP( g, 0, 255 );
+                  rgba[i][BCOMP] = CLAMP( b, 0, 255 );
+                  rgba[i][ACOMP] = CLAMP( a, 0, 255 );
+               }
+               if (ctx->Color.SWmasking) {
+                  gl_mask_rgba_span( ctx, width, xpos, ypos, rgba );
+               }
+               (*ctx->Driver.WriteRGBASpan)( ctx, width, xpos, ypos, 
+                                             (const GLubyte (*)[4])rgba, NULL );
+               ypos++;
+            }
+        }
+        break;
+
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glAccum" );
+   }
+}
+
+
+
+/*
+ * Clear the accumulation Buffer.
+ */
+void gl_clear_accum_buffer( GLcontext *ctx )
+{
+   GLuint buffersize;
+   GLfloat acc_scale;
+
+   if (ctx->Visual->AccumBits==0) {
+      /* No accumulation buffer! */
+      return;
+   }
+
+   if (sizeof(GLaccum)==1) {
+      acc_scale = 127.0;
+   }
+   else if (sizeof(GLaccum)==2) {
+      acc_scale = 32767.0;
+   }
+   else {
+      /* sizeof(GLaccum) > 2 (Cray) */
+      acc_scale = (float) SHRT_MAX;
+   }
+
+   /* number of pixels */
+   buffersize = ctx->Buffer->Width * ctx->Buffer->Height;
+
+   if (!ctx->Buffer->Accum) {
+      /* try to alloc accumulation buffer */
+      ctx->Buffer->Accum = (GLaccum *)
+                          malloc( buffersize * 4 * sizeof(GLaccum) );
+   }
+
+   if (ctx->Buffer->Accum) {
+      if (ctx->Scissor.Enabled) {
+        /* Limit clear to scissor box */
+        GLaccum r, g, b, a;
+        GLint i, j;
+         GLint width, height;
+         GLaccum *row;
+        r = (GLaccum) (ctx->Accum.ClearColor[0] * acc_scale);
+        g = (GLaccum) (ctx->Accum.ClearColor[1] * acc_scale);
+        b = (GLaccum) (ctx->Accum.ClearColor[2] * acc_scale);
+        a = (GLaccum) (ctx->Accum.ClearColor[3] * acc_scale);
+         /* size of region to clear */
+         width = 4 * (ctx->Buffer->Xmax - ctx->Buffer->Xmin + 1);
+         height = ctx->Buffer->Ymax - ctx->Buffer->Ymin + 1;
+         /* ptr to first element to clear */
+         row = ctx->Buffer->Accum
+               + 4 * (ctx->Buffer->Ymin * ctx->Buffer->Width
+                      + ctx->Buffer->Xmin);
+         for (j=0;j<height;j++) {
+            for (i=0;i<width;i+=4) {
+               row[i+0] = r;
+               row[i+1] = g;
+               row[i+2] = b;
+               row[i+3] = a;
+           }
+            row += 4 * ctx->Buffer->Width;
+        }
+      }
+      else {
+        /* clear whole buffer */
+        if (ctx->Accum.ClearColor[0]==0.0 &&
+            ctx->Accum.ClearColor[1]==0.0 &&
+            ctx->Accum.ClearColor[2]==0.0 &&
+            ctx->Accum.ClearColor[3]==0.0) {
+           /* Black */
+           MEMSET( ctx->Buffer->Accum, 0, buffersize * 4 * sizeof(GLaccum) );
+        }
+        else {
+           /* Not black */
+           GLaccum *acc, r, g, b, a;
+           GLuint i;
+
+           acc = ctx->Buffer->Accum;
+           r = (GLaccum) (ctx->Accum.ClearColor[0] * acc_scale);
+           g = (GLaccum) (ctx->Accum.ClearColor[1] * acc_scale);
+           b = (GLaccum) (ctx->Accum.ClearColor[2] * acc_scale);
+           a = (GLaccum) (ctx->Accum.ClearColor[3] * acc_scale);
+           for (i=0;i<buffersize;i++) {
+              *acc++ = r;
+              *acc++ = g;
+              *acc++ = b;
+              *acc++ = a;
+           }
+        }
+      }
+
+      /* update optimized accum state vars */
+      if (ctx->Accum.ClearColor[0] == 0.0 && ctx->Accum.ClearColor[1] == 0.0 &&
+          ctx->Accum.ClearColor[2] == 0.0 && ctx->Accum.ClearColor[3] == 0.0) {
+         ctx->IntegerAccumMode = GL_TRUE;
+         ctx->IntegerAccumScaler = 0.0;  /* denotes empty accum buffer */
+      }
+      else {
+         ctx->IntegerAccumMode = GL_FALSE;
+      }
+   }
+}
diff --git a/src/mesa/main/accum.h b/src/mesa/main/accum.h
new file mode 100644 (file)
index 0000000..dd641da
--- /dev/null
@@ -0,0 +1,51 @@
+/* $Id: accum.h,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+#ifndef ACCUM_H
+#define ACCUM_H
+
+
+#include "types.h"
+
+
+extern void gl_alloc_accum_buffer( GLcontext *ctx );
+
+
+extern void gl_Accum( GLcontext *ctx, GLenum op, GLfloat value );
+
+
+extern void gl_ClearAccum( GLcontext *ctx, GLfloat red, GLfloat green,
+                           GLfloat blue, GLfloat alpha );
+
+
+extern void gl_clear_accum_buffer( GLcontext *ctx );
+
+
+#endif
diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c
new file mode 100644 (file)
index 0000000..78f4d05
--- /dev/null
@@ -0,0 +1,863 @@
+/* $Id: attrib.c,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "attrib.h"
+#include "context.h"
+#include "enable.h"
+#include "enums.h"
+#include "macros.h"
+#include "misc.h"
+#include "simple_list.h"
+#include "texstate.h"
+#include "types.h"
+#ifdef XFree86Server
+#undef MISC_H
+#include "GL/xf86glx.h"
+#endif
+#endif
+
+
+#define MALLOC_STRUCT(T)  (struct T *) malloc( sizeof(struct T) )
+
+
+
+/*
+ * Allocate a new attribute state node.  These nodes have a
+ * "kind" value and a pointer to a struct of state data.
+ */
+static struct gl_attrib_node *new_attrib_node( GLbitfield kind )
+{
+   struct gl_attrib_node *an;
+
+   an = (struct gl_attrib_node *) malloc( sizeof(struct gl_attrib_node) );
+   if (an) {
+      an->kind = kind;
+   }
+   return an;
+}
+
+
+
+/*
+ * Copy texture object state from one texture object to another.
+ */
+static void copy_texobj_state( struct gl_texture_object *dest,
+                               const struct gl_texture_object *src )
+{
+   /*
+   dest->Name = src->Name;
+   dest->Dimensions = src->Dimensions;
+   */
+   dest->Priority = src->Priority;
+   dest->BorderColor[0] = src->BorderColor[0];
+   dest->BorderColor[1] = src->BorderColor[1];
+   dest->BorderColor[2] = src->BorderColor[2];
+   dest->BorderColor[3] = src->BorderColor[3];
+   dest->WrapS = src->WrapS;
+   dest->WrapT = src->WrapT;
+   dest->WrapR = src->WrapR;
+   dest->MinFilter = src->MinFilter;
+   dest->MagFilter = src->MagFilter;
+   dest->MinLod = src->MinLod;
+   dest->MaxLod = src->MaxLod;
+   dest->BaseLevel = src->BaseLevel;
+   dest->MaxLevel = src->MaxLevel;
+   dest->P = src->P;
+   dest->M = src->M;
+   dest->MinMagThresh = src->MinMagThresh;
+   memcpy( dest->Palette, src->Palette,
+           sizeof(GLubyte) * MAX_TEXTURE_PALETTE_SIZE * 4 );
+   dest->PaletteSize = src->PaletteSize;
+   dest->PaletteIntFormat = src->PaletteIntFormat;
+   dest->PaletteFormat = src->PaletteFormat;
+   dest->Complete = src->Complete;
+   dest->SampleFunc = src->SampleFunc;
+}
+
+
+
+void gl_PushAttrib( GLcontext* ctx, GLbitfield mask )
+{
+   struct gl_attrib_node *newnode;
+   struct gl_attrib_node *head;
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPushAttrib");
+
+   if (MESA_VERBOSE&VERBOSE_API)
+      fprintf(stderr, "glPushAttrib %x\n", mask);
+
+   if (ctx->AttribStackDepth>=MAX_ATTRIB_STACK_DEPTH) {
+      gl_error( ctx, GL_STACK_OVERFLOW, "glPushAttrib" );
+      return;
+   }
+
+   /* Build linked list of attribute nodes which save all attribute */
+   /* groups specified by the mask. */
+   head = NULL;
+
+   if (mask & GL_ACCUM_BUFFER_BIT) {
+      struct gl_accum_attrib *attr;
+      attr = MALLOC_STRUCT( gl_accum_attrib );
+      MEMCPY( attr, &ctx->Accum, sizeof(struct gl_accum_attrib) );
+      newnode = new_attrib_node( GL_ACCUM_BUFFER_BIT );
+      newnode->data = attr;
+      newnode->next = head;
+      head = newnode;
+   }
+
+   if (mask & GL_COLOR_BUFFER_BIT) {
+      struct gl_colorbuffer_attrib *attr;
+      attr = MALLOC_STRUCT( gl_colorbuffer_attrib );
+      MEMCPY( attr, &ctx->Color, sizeof(struct gl_colorbuffer_attrib) );
+      newnode = new_attrib_node( GL_COLOR_BUFFER_BIT );
+      newnode->data = attr;
+      newnode->next = head;
+      head = newnode;
+   }
+
+   if (mask & GL_CURRENT_BIT) {
+      struct gl_current_attrib *attr;
+      attr = MALLOC_STRUCT( gl_current_attrib );
+      MEMCPY( attr, &ctx->Current, sizeof(struct gl_current_attrib) );
+      newnode = new_attrib_node( GL_CURRENT_BIT );
+      newnode->data = attr;
+      newnode->next = head;
+      head = newnode;
+   }
+
+   if (mask & GL_DEPTH_BUFFER_BIT) {
+      struct gl_depthbuffer_attrib *attr;
+      attr = MALLOC_STRUCT( gl_depthbuffer_attrib );
+      MEMCPY( attr, &ctx->Depth, sizeof(struct gl_depthbuffer_attrib) );
+      newnode = new_attrib_node( GL_DEPTH_BUFFER_BIT );
+      newnode->data = attr;
+      newnode->next = head;
+      head = newnode;
+   }
+
+   if (mask & GL_ENABLE_BIT) {
+      struct gl_enable_attrib *attr;
+      GLuint i;
+      attr = MALLOC_STRUCT( gl_enable_attrib );
+      /* Copy enable flags from all other attributes into the enable struct. */
+      attr->AlphaTest = ctx->Color.AlphaEnabled;
+      attr->AutoNormal = ctx->Eval.AutoNormal;
+      attr->Blend = ctx->Color.BlendEnabled;
+      for (i=0;i<MAX_CLIP_PLANES;i++) {
+         attr->ClipPlane[i] = ctx->Transform.ClipEnabled[i];
+      }
+      attr->ColorMaterial = ctx->Light.ColorMaterialEnabled;
+      attr->CullFace = ctx->Polygon.CullFlag;
+      attr->DepthTest = ctx->Depth.Test;
+      attr->Dither = ctx->Color.DitherFlag;
+      attr->Fog = ctx->Fog.Enabled;
+      for (i=0;i<MAX_LIGHTS;i++) {
+         attr->Light[i] = ctx->Light.Light[i].Enabled;
+      }
+      attr->Lighting = ctx->Light.Enabled;
+      attr->LineSmooth = ctx->Line.SmoothFlag;
+      attr->LineStipple = ctx->Line.StippleFlag;
+      attr->IndexLogicOp = ctx->Color.IndexLogicOpEnabled;
+      attr->ColorLogicOp = ctx->Color.ColorLogicOpEnabled;
+      attr->Map1Color4 = ctx->Eval.Map1Color4;
+      attr->Map1Index = ctx->Eval.Map1Index;
+      attr->Map1Normal = ctx->Eval.Map1Normal;
+      attr->Map1TextureCoord1 = ctx->Eval.Map1TextureCoord1;
+      attr->Map1TextureCoord2 = ctx->Eval.Map1TextureCoord2;
+      attr->Map1TextureCoord3 = ctx->Eval.Map1TextureCoord3;
+      attr->Map1TextureCoord4 = ctx->Eval.Map1TextureCoord4;
+      attr->Map1Vertex3 = ctx->Eval.Map1Vertex3;
+      attr->Map1Vertex4 = ctx->Eval.Map1Vertex4;
+      attr->Map2Color4 = ctx->Eval.Map2Color4;
+      attr->Map2Index = ctx->Eval.Map2Index;
+      attr->Map2Normal = ctx->Eval.Map2Normal;
+      attr->Map2TextureCoord1 = ctx->Eval.Map2TextureCoord1;
+      attr->Map2TextureCoord2 = ctx->Eval.Map2TextureCoord2;
+      attr->Map2TextureCoord3 = ctx->Eval.Map2TextureCoord3;
+      attr->Map2TextureCoord4 = ctx->Eval.Map2TextureCoord4;
+      attr->Map2Vertex3 = ctx->Eval.Map2Vertex3;
+      attr->Map2Vertex4 = ctx->Eval.Map2Vertex4;
+      attr->Normalize = ctx->Transform.Normalize;
+      attr->PointSmooth = ctx->Point.SmoothFlag;
+      attr->PolygonOffsetPoint = ctx->Polygon.OffsetPoint;
+      attr->PolygonOffsetLine = ctx->Polygon.OffsetLine;
+      attr->PolygonOffsetFill = ctx->Polygon.OffsetFill;
+      attr->PolygonSmooth = ctx->Polygon.SmoothFlag;
+      attr->PolygonStipple = ctx->Polygon.StippleFlag;
+      attr->RescaleNormals = ctx->Transform.RescaleNormals;
+      attr->Scissor = ctx->Scissor.Enabled;
+      attr->Stencil = ctx->Stencil.Enabled;
+      attr->Texture = ctx->Texture.Enabled;
+      for (i=0; i<MAX_TEXTURE_UNITS; i++) {
+         attr->TexGen[i] = ctx->Texture.Unit[i].TexGenEnabled;
+      }
+      newnode = new_attrib_node( GL_ENABLE_BIT );
+      newnode->data = attr;
+      newnode->next = head;
+      head = newnode;
+   }
+
+   if (mask & GL_EVAL_BIT) {
+      struct gl_eval_attrib *attr;
+      attr = MALLOC_STRUCT( gl_eval_attrib );
+      MEMCPY( attr, &ctx->Eval, sizeof(struct gl_eval_attrib) );
+      newnode = new_attrib_node( GL_EVAL_BIT );
+      newnode->data = attr;
+      newnode->next = head;
+      head = newnode;
+   }
+
+   if (mask & GL_FOG_BIT) {
+      struct gl_fog_attrib *attr;
+      attr = MALLOC_STRUCT( gl_fog_attrib );
+      MEMCPY( attr, &ctx->Fog, sizeof(struct gl_fog_attrib) );
+      newnode = new_attrib_node( GL_FOG_BIT );
+      newnode->data = attr;
+      newnode->next = head;
+      head = newnode;
+   }
+
+   if (mask & GL_HINT_BIT) {
+      struct gl_hint_attrib *attr;
+      attr = MALLOC_STRUCT( gl_hint_attrib );
+      MEMCPY( attr, &ctx->Hint, sizeof(struct gl_hint_attrib) );
+      newnode = new_attrib_node( GL_HINT_BIT );
+      newnode->data = attr;
+      newnode->next = head;
+      head = newnode;
+   }
+
+   if (mask & GL_LIGHTING_BIT) {
+      struct gl_light_attrib *attr;
+      attr = MALLOC_STRUCT( gl_light_attrib );
+      MEMCPY( attr, &ctx->Light, sizeof(struct gl_light_attrib) );
+      newnode = new_attrib_node( GL_LIGHTING_BIT );
+      newnode->data = attr;
+      newnode->next = head;
+      head = newnode;
+   }
+
+   if (mask & GL_LINE_BIT) {
+      struct gl_line_attrib *attr;
+      attr = MALLOC_STRUCT( gl_line_attrib );
+      MEMCPY( attr, &ctx->Line, sizeof(struct gl_line_attrib) );
+      newnode = new_attrib_node( GL_LINE_BIT );
+      newnode->data = attr;
+      newnode->next = head;
+      head = newnode;
+   }
+
+   if (mask & GL_LIST_BIT) {
+      struct gl_list_attrib *attr;
+      attr = MALLOC_STRUCT( gl_list_attrib );
+      MEMCPY( attr, &ctx->List, sizeof(struct gl_list_attrib) );
+      newnode = new_attrib_node( GL_LIST_BIT );
+      newnode->data = attr;
+      newnode->next = head;
+      head = newnode;
+   }
+
+   if (mask & GL_PIXEL_MODE_BIT) {
+      struct gl_pixel_attrib *attr;
+      attr = MALLOC_STRUCT( gl_pixel_attrib );
+      MEMCPY( attr, &ctx->Pixel, sizeof(struct gl_pixel_attrib) );
+      newnode = new_attrib_node( GL_PIXEL_MODE_BIT );
+      newnode->data = attr;
+      newnode->next = head;
+      head = newnode;
+   }
+
+   if (mask & GL_POINT_BIT) {
+      struct gl_point_attrib *attr;
+      attr = MALLOC_STRUCT( gl_point_attrib );
+      MEMCPY( attr, &ctx->Point, sizeof(struct gl_point_attrib) );
+      newnode = new_attrib_node( GL_POINT_BIT );
+      newnode->data = attr;
+      newnode->next = head;
+      head = newnode;
+   }
+
+   if (mask & GL_POLYGON_BIT) {
+      struct gl_polygon_attrib *attr;
+      attr = MALLOC_STRUCT( gl_polygon_attrib );
+      MEMCPY( attr, &ctx->Polygon, sizeof(struct gl_polygon_attrib) );
+      newnode = new_attrib_node( GL_POLYGON_BIT );
+      newnode->data = attr;
+      newnode->next = head;
+      head = newnode;
+   }
+
+   if (mask & GL_POLYGON_STIPPLE_BIT) {
+      GLuint *stipple;
+      stipple = (GLuint *) malloc( 32*sizeof(GLuint) );
+      MEMCPY( stipple, ctx->PolygonStipple, 32*sizeof(GLuint) );
+      newnode = new_attrib_node( GL_POLYGON_STIPPLE_BIT );
+      newnode->data = stipple;
+      newnode->next = head;
+      head = newnode;
+   }
+
+   if (mask & GL_SCISSOR_BIT) {
+      struct gl_scissor_attrib *attr;
+      attr = MALLOC_STRUCT( gl_scissor_attrib );
+      MEMCPY( attr, &ctx->Scissor, sizeof(struct gl_scissor_attrib) );
+      newnode = new_attrib_node( GL_SCISSOR_BIT );
+      newnode->data = attr;
+      newnode->next = head;
+      head = newnode;
+   }
+
+   if (mask & GL_STENCIL_BUFFER_BIT) {
+      struct gl_stencil_attrib *attr;
+      attr = MALLOC_STRUCT( gl_stencil_attrib );
+      MEMCPY( attr, &ctx->Stencil, sizeof(struct gl_stencil_attrib) );
+      newnode = new_attrib_node( GL_STENCIL_BUFFER_BIT );
+      newnode->data = attr;
+      newnode->next = head;
+      head = newnode;
+   }
+
+   if (mask & GL_TEXTURE_BIT) {
+      struct gl_texture_attrib *attr;
+      GLuint u;
+      /* Take care of texture object reference counters */
+      for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
+        ctx->Texture.Unit[u].CurrentD[1]->RefCount++;
+        ctx->Texture.Unit[u].CurrentD[2]->RefCount++;
+        ctx->Texture.Unit[u].CurrentD[3]->RefCount++;
+      }
+      attr = MALLOC_STRUCT( gl_texture_attrib );
+      MEMCPY( attr, &ctx->Texture, sizeof(struct gl_texture_attrib) );
+      /* copy state of the currently bound texture objects */
+      for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
+         copy_texobj_state(&attr->Unit[u].Saved1D, attr->Unit[u].CurrentD[1]);
+         copy_texobj_state(&attr->Unit[u].Saved2D, attr->Unit[u].CurrentD[2]);
+         copy_texobj_state(&attr->Unit[u].Saved3D, attr->Unit[u].CurrentD[3]);
+      }
+      newnode = new_attrib_node( GL_TEXTURE_BIT );
+      newnode->data = attr;
+      newnode->next = head;
+      head = newnode;
+   }
+
+   if (mask & GL_TRANSFORM_BIT) {
+      struct gl_transform_attrib *attr;
+      attr = MALLOC_STRUCT( gl_transform_attrib );
+      MEMCPY( attr, &ctx->Transform, sizeof(struct gl_transform_attrib) );
+      newnode = new_attrib_node( GL_TRANSFORM_BIT );
+      newnode->data = attr;
+      newnode->next = head;
+      head = newnode;
+   }
+
+   if (mask & GL_VIEWPORT_BIT) {
+      struct gl_viewport_attrib *attr;
+      attr = MALLOC_STRUCT( gl_viewport_attrib );
+      MEMCPY( attr, &ctx->Viewport, sizeof(struct gl_viewport_attrib) );
+      newnode = new_attrib_node( GL_VIEWPORT_BIT );
+      newnode->data = attr;
+      newnode->next = head;
+      head = newnode;
+   }
+
+   ctx->AttribStack[ctx->AttribStackDepth] = head;
+   ctx->AttribStackDepth++;
+}
+
+
+
+/*
+ * This function is kind of long just because we have to call a lot
+ * of device driver functions to update device driver state.
+ */
+void gl_PopAttrib( GLcontext* ctx )
+{
+   struct gl_attrib_node *attr, *next;
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPopAttrib");
+
+
+   if (ctx->AttribStackDepth==0) {
+      gl_error( ctx, GL_STACK_UNDERFLOW, "glPopAttrib" );
+      return;
+   }
+
+   ctx->AttribStackDepth--;
+   attr = ctx->AttribStack[ctx->AttribStackDepth];
+
+   while (attr) {
+
+      if (MESA_VERBOSE&VERBOSE_API)
+        fprintf(stderr, "glPopAttrib %s\n", gl_lookup_enum_by_nr(attr->kind));
+
+      switch (attr->kind) {
+         case GL_ACCUM_BUFFER_BIT:
+            MEMCPY( &ctx->Accum, attr->data, sizeof(struct gl_accum_attrib) );
+            break;
+         case GL_COLOR_BUFFER_BIT:
+            {
+               GLenum oldDrawBuffer = ctx->Color.DrawBuffer;
+               GLenum oldAlphaFunc = ctx->Color.AlphaFunc;
+               GLubyte oldAlphaRef = ctx->Color.AlphaRef;
+               GLenum oldBlendSrc = ctx->Color.BlendSrcRGB;
+               GLenum oldBlendDst = ctx->Color.BlendDstRGB;
+               MEMCPY( &ctx->Color, attr->data,
+                       sizeof(struct gl_colorbuffer_attrib) );
+               if (ctx->Color.DrawBuffer != oldDrawBuffer) {
+                  gl_DrawBuffer(ctx, ctx->Color.DrawBuffer);
+               }
+               if ((ctx->Color.AlphaFunc != oldAlphaFunc ||
+                    ctx->Color.AlphaRef != oldAlphaRef) &&
+                   ctx->Driver.AlphaFunc)
+                  (*ctx->Driver.AlphaFunc)( ctx, ctx->Color.AlphaFunc,
+                                            ctx->Color.AlphaRef / 255.0F);
+               if ((ctx->Color.BlendSrcRGB != oldBlendSrc ||
+                    ctx->Color.BlendSrcRGB != oldBlendDst) &&
+                   ctx->Driver.BlendFunc)
+                  (*ctx->Driver.BlendFunc)( ctx, ctx->Color.BlendSrcRGB,
+                                            ctx->Color.BlendDstRGB);
+            }
+            break;
+         case GL_CURRENT_BIT:
+            MEMCPY( &ctx->Current, attr->data,
+                   sizeof(struct gl_current_attrib) );
+            break;
+         case GL_DEPTH_BUFFER_BIT:
+            {
+               GLenum oldDepthFunc = ctx->Depth.Func;
+               GLboolean oldDepthMask = ctx->Depth.Mask;
+               GLfloat oldDepthClear = ctx->Depth.Clear;
+               MEMCPY( &ctx->Depth, attr->data,
+                       sizeof(struct gl_depthbuffer_attrib) );
+               if (ctx->Depth.Func != oldDepthFunc && ctx->Driver.DepthFunc)
+                  (*ctx->Driver.DepthFunc)( ctx, ctx->Depth.Func );
+               if (ctx->Depth.Mask != oldDepthMask && ctx->Driver.DepthMask)
+                  (*ctx->Driver.DepthMask)( ctx, ctx->Depth.Mask );
+               if (ctx->Depth.Clear != oldDepthClear && ctx->Driver.ClearDepth)
+                  (*ctx->Driver.ClearDepth)( ctx, ctx->Depth.Clear );
+            }
+            break;
+         case GL_ENABLE_BIT:
+            {
+               const struct gl_enable_attrib *enable;
+               enable = (const struct gl_enable_attrib *) attr->data;
+
+#define TEST_AND_UPDATE(VALUE, NEWVALUE, ENUM)         \
+       if ((VALUE) != (NEWVALUE)) {                    \
+          gl_set_enable( ctx, ENUM, (NEWVALUE) );      \
+       }
+
+               TEST_AND_UPDATE(ctx->Color.AlphaEnabled, enable->AlphaTest, GL_ALPHA_TEST);
+               TEST_AND_UPDATE(ctx->Transform.Normalize, enable->AutoNormal, GL_NORMALIZE);
+               TEST_AND_UPDATE(ctx->Color.BlendEnabled, enable->Blend, GL_BLEND);
+               {
+                  GLuint i;
+                  for (i=0;i<MAX_CLIP_PLANES;i++) {
+                     if (ctx->Transform.ClipEnabled[i] != enable->ClipPlane[i])
+                        gl_set_enable( ctx, (GLenum) (GL_CLIP_PLANE0 + i), enable->ClipPlane[i] );
+                  }
+               }
+               TEST_AND_UPDATE(ctx->Light.ColorMaterialEnabled, enable->ColorMaterial, GL_COLOR_MATERIAL);
+               TEST_AND_UPDATE(ctx->Polygon.CullFlag, enable->CullFace, GL_CULL_FACE);
+               TEST_AND_UPDATE(ctx->Color.DitherFlag, enable->Dither, GL_DITHER);
+               TEST_AND_UPDATE(ctx->Fog.Enabled, enable->Fog, GL_FOG);
+               TEST_AND_UPDATE(ctx->Light.Enabled, enable->Lighting, GL_LIGHTING);
+               TEST_AND_UPDATE(ctx->Line.SmoothFlag, enable->LineSmooth, GL_LINE_SMOOTH);
+               TEST_AND_UPDATE(ctx->Line.StippleFlag, enable->LineStipple, GL_LINE_STIPPLE);
+               TEST_AND_UPDATE(ctx->Color.IndexLogicOpEnabled, enable->IndexLogicOp, GL_INDEX_LOGIC_OP);
+               TEST_AND_UPDATE(ctx->Color.ColorLogicOpEnabled, enable->ColorLogicOp, GL_COLOR_LOGIC_OP);
+               TEST_AND_UPDATE(ctx->Eval.Map1Color4, enable->Map1Color4, GL_MAP1_COLOR_4);
+               TEST_AND_UPDATE(ctx->Eval.Map1Index, enable->Map1Index, GL_MAP1_INDEX);
+               TEST_AND_UPDATE(ctx->Eval.Map1Normal, enable->Map1Normal, GL_MAP1_NORMAL);
+               TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord1, enable->Map1TextureCoord1, GL_MAP1_TEXTURE_COORD_1);
+               TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord2, enable->Map1TextureCoord2, GL_MAP1_TEXTURE_COORD_2);
+               TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord3, enable->Map1TextureCoord3, GL_MAP1_TEXTURE_COORD_3);
+               TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord4, enable->Map1TextureCoord4, GL_MAP1_TEXTURE_COORD_4);
+               TEST_AND_UPDATE(ctx->Eval.Map1Vertex3, enable->Map1Vertex3, GL_MAP1_VERTEX_3);
+               TEST_AND_UPDATE(ctx->Eval.Map1Vertex4, enable->Map1Vertex4, GL_MAP1_VERTEX_4);
+               TEST_AND_UPDATE(ctx->Eval.Map2Color4, enable->Map2Color4, GL_MAP2_COLOR_4);
+               TEST_AND_UPDATE(ctx->Eval.Map2Index, enable->Map2Index, GL_MAP2_INDEX);
+               TEST_AND_UPDATE(ctx->Eval.Map2Normal, enable->Map2Normal, GL_MAP2_NORMAL);
+               TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord1, enable->Map2TextureCoord1, GL_MAP2_TEXTURE_COORD_1);
+               TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord2, enable->Map2TextureCoord2, GL_MAP2_TEXTURE_COORD_2);
+               TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord3, enable->Map2TextureCoord3, GL_MAP2_TEXTURE_COORD_3);
+               TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord4, enable->Map2TextureCoord4, GL_MAP2_TEXTURE_COORD_4);
+               TEST_AND_UPDATE(ctx->Eval.Map2Vertex3, enable->Map2Vertex3, GL_MAP2_VERTEX_3);
+               TEST_AND_UPDATE(ctx->Eval.Map2Vertex4, enable->Map2Vertex4, GL_MAP2_VERTEX_4);
+               TEST_AND_UPDATE(ctx->Transform.Normalize, enable->Normalize, GL_NORMALIZE);
+               TEST_AND_UPDATE(ctx->Transform.RescaleNormals, enable->RescaleNormals, GL_RESCALE_NORMAL_EXT);
+               TEST_AND_UPDATE(ctx->Point.SmoothFlag, enable->PointSmooth, GL_POINT_SMOOTH);
+               TEST_AND_UPDATE(ctx->Polygon.OffsetPoint, enable->PolygonOffsetPoint, GL_POLYGON_OFFSET_POINT);
+               TEST_AND_UPDATE(ctx->Polygon.OffsetLine, enable->PolygonOffsetLine, GL_POLYGON_OFFSET_LINE);
+               TEST_AND_UPDATE(ctx->Polygon.OffsetFill, enable->PolygonOffsetFill, GL_POLYGON_OFFSET_FILL);
+               TEST_AND_UPDATE(ctx->Polygon.SmoothFlag, enable->PolygonSmooth, GL_POLYGON_SMOOTH);
+               TEST_AND_UPDATE(ctx->Polygon.StippleFlag, enable->PolygonStipple, GL_POLYGON_STIPPLE);
+               TEST_AND_UPDATE(ctx->Scissor.Enabled, enable->Scissor, GL_SCISSOR_TEST);
+               TEST_AND_UPDATE(ctx->Stencil.Enabled, enable->Stencil, GL_STENCIL_TEST);
+               if (ctx->Texture.Enabled != enable->Texture) {
+                  ctx->Texture.Enabled = enable->Texture;
+                  if (ctx->Driver.Enable) {
+                     if (ctx->Driver.ActiveTexture)
+                        (*ctx->Driver.ActiveTexture)( ctx, 0 );
+                     (*ctx->Driver.Enable)( ctx, GL_TEXTURE_1D, (GLboolean) (enable->Texture & TEXTURE0_1D) );
+                     (*ctx->Driver.Enable)( ctx, GL_TEXTURE_2D, (GLboolean) (enable->Texture & TEXTURE0_2D) );
+                     (*ctx->Driver.Enable)( ctx, GL_TEXTURE_3D, (GLboolean) (enable->Texture & TEXTURE0_3D) );
+                     if (ctx->Driver.ActiveTexture)
+                        (*ctx->Driver.ActiveTexture)( ctx, 1 );
+                     (*ctx->Driver.Enable)( ctx, GL_TEXTURE_1D, (GLboolean) (enable->Texture & TEXTURE1_1D) );
+                     (*ctx->Driver.Enable)( ctx, GL_TEXTURE_2D, (GLboolean) (enable->Texture & TEXTURE1_2D) );
+                     (*ctx->Driver.Enable)( ctx, GL_TEXTURE_3D, (GLboolean) (enable->Texture & TEXTURE1_3D) );
+                     if (ctx->Driver.ActiveTexture)
+                        (*ctx->Driver.ActiveTexture)( ctx, ctx->Texture.CurrentUnit );
+                  }
+               }
+#undef TEST_AND_UPDATE
+               {
+                  GLuint i;
+                  for (i=0; i<MAX_TEXTURE_UNITS; i++) {
+                     if (ctx->Texture.Unit[i].TexGenEnabled != enable->TexGen[i]) {
+                        ctx->Texture.Unit[i].TexGenEnabled = enable->TexGen[i];
+
+                       /* ctx->Enabled recalculated in state change
+                           processing */
+                       
+                        if (ctx->Driver.Enable) {
+                           if (ctx->Driver.ActiveTexture)
+                              (*ctx->Driver.ActiveTexture)( ctx, i );
+                           if (enable->TexGen[i] & S_BIT)
+                              (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_S, GL_TRUE);
+                           else
+                              (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_S, GL_FALSE);
+                           if (enable->TexGen[i] & T_BIT)
+                              (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_T, GL_TRUE);
+                           else
+                              (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_T, GL_FALSE);
+                           if (enable->TexGen[i] & R_BIT)
+                              (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_R, GL_TRUE);
+                           else
+                              (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_R, GL_FALSE);
+                           if (enable->TexGen[i] & Q_BIT)
+                              (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_Q, GL_TRUE);
+                           else
+                              (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_Q, GL_FALSE);
+                        }
+                     }
+                  }
+                  if (ctx->Driver.ActiveTexture)
+                     (*ctx->Driver.ActiveTexture)( ctx, ctx->Texture.CurrentUnit );
+               }
+            }
+            break;
+         case GL_EVAL_BIT:
+            MEMCPY( &ctx->Eval, attr->data, sizeof(struct gl_eval_attrib) );
+            break;
+         case GL_FOG_BIT:
+            {
+               GLboolean anyChange = (memcmp( &ctx->Fog, attr->data, sizeof(struct gl_fog_attrib) ) != 0);
+               MEMCPY( &ctx->Fog, attr->data, sizeof(struct gl_fog_attrib) );
+               if (anyChange && ctx->Driver.Fogfv) {
+                  const GLfloat mode = ctx->Fog.Mode;
+                  const GLfloat density = ctx->Fog.Density;
+                  const GLfloat start = ctx->Fog.Start;
+                  const GLfloat end = ctx->Fog.End;
+                  const GLfloat index = ctx->Fog.Index;
+                  (*ctx->Driver.Fogfv)( ctx, GL_FOG_MODE, &mode);
+                  (*ctx->Driver.Fogfv)( ctx, GL_FOG_DENSITY, &density );
+                  (*ctx->Driver.Fogfv)( ctx, GL_FOG_START, &start );
+                  (*ctx->Driver.Fogfv)( ctx, GL_FOG_END, &end );
+                  (*ctx->Driver.Fogfv)( ctx, GL_FOG_INDEX, &index );
+                  (*ctx->Driver.Fogfv)( ctx, GL_FOG_COLOR, ctx->Fog.Color );
+               }
+              ctx->Enabled &= ENABLE_FOG;
+              if (ctx->Fog.Enabled) ctx->Enabled |= ENABLE_FOG;
+            }
+            break;
+         case GL_HINT_BIT:
+            MEMCPY( &ctx->Hint, attr->data, sizeof(struct gl_hint_attrib) );
+            if (ctx->Driver.Hint) {
+               (*ctx->Driver.Hint)( ctx, GL_PERSPECTIVE_CORRECTION_HINT,
+                                    ctx->Hint.PerspectiveCorrection );
+               (*ctx->Driver.Hint)( ctx, GL_POINT_SMOOTH_HINT,
+                                    ctx->Hint.PointSmooth);
+               (*ctx->Driver.Hint)( ctx, GL_LINE_SMOOTH_HINT,
+                                    ctx->Hint.LineSmooth );
+               (*ctx->Driver.Hint)( ctx, GL_POLYGON_SMOOTH_HINT,
+                                    ctx->Hint.PolygonSmooth );
+               (*ctx->Driver.Hint)( ctx, GL_FOG_HINT, ctx->Hint.Fog );
+            }
+            break;
+         case GL_LIGHTING_BIT:
+            MEMCPY( &ctx->Light, attr->data, sizeof(struct gl_light_attrib) );
+            if (ctx->Driver.Enable) {
+               GLuint i;
+               for (i = 0; i < MAX_LIGHTS; i++) {
+                  GLenum light = (GLenum) (GL_LIGHT0 + i);
+                  (*ctx->Driver.Enable)( ctx, light, ctx->Light.Light[i].Enabled );
+               }
+               (*ctx->Driver.Enable)( ctx, GL_LIGHTING, ctx->Light.Enabled );
+            }
+           ctx->Enabled &= ENABLE_LIGHT;
+           if (ctx->Light.Enabled && !is_empty_list(&ctx->Light.EnabledList))
+              ctx->Enabled |= ENABLE_LIGHT;
+            break;
+         case GL_LINE_BIT:
+            MEMCPY( &ctx->Line, attr->data, sizeof(struct gl_line_attrib) );
+            if (ctx->Driver.Enable) {
+               (*ctx->Driver.Enable)( ctx, GL_LINE_SMOOTH, ctx->Line.SmoothFlag );
+               (*ctx->Driver.Enable)( ctx, GL_LINE_STIPPLE, ctx->Line.StippleFlag );
+            }
+            break;
+         case GL_LIST_BIT:
+            MEMCPY( &ctx->List, attr->data, sizeof(struct gl_list_attrib) );
+            break;
+         case GL_PIXEL_MODE_BIT:
+            MEMCPY( &ctx->Pixel, attr->data, sizeof(struct gl_pixel_attrib) );
+            break;
+         case GL_POINT_BIT:
+            MEMCPY( &ctx->Point, attr->data, sizeof(struct gl_point_attrib) );
+            if (ctx->Driver.Enable)
+               (*ctx->Driver.Enable)( ctx, GL_POINT_SMOOTH, ctx->Point.SmoothFlag );
+            break;
+         case GL_POLYGON_BIT:
+            {
+               GLenum oldFrontMode = ctx->Polygon.FrontMode;
+               GLenum oldBackMode = ctx->Polygon.BackMode;
+               MEMCPY( &ctx->Polygon, attr->data,
+                       sizeof(struct gl_polygon_attrib) );
+               if ((ctx->Polygon.FrontMode != oldFrontMode ||
+                    ctx->Polygon.BackMode != oldBackMode) &&
+                   ctx->Driver.PolygonMode) {
+                  (*ctx->Driver.PolygonMode)( ctx, GL_FRONT, ctx->Polygon.FrontMode);
+                  (*ctx->Driver.PolygonMode)( ctx, GL_BACK, ctx->Polygon.BackMode);
+               }
+              if (ctx->Driver.CullFace)
+                 ctx->Driver.CullFace( ctx, ctx->Polygon.CullFaceMode );
+
+              if (ctx->Driver.FrontFace)
+                 ctx->Driver.FrontFace( ctx, ctx->Polygon.FrontFace );
+
+               if (ctx->Driver.Enable)
+                  (*ctx->Driver.Enable)( ctx, GL_POLYGON_SMOOTH, ctx->Polygon.SmoothFlag );
+            }
+            break;
+        case GL_POLYGON_STIPPLE_BIT:
+           MEMCPY( ctx->PolygonStipple, attr->data, 32*sizeof(GLuint) );
+           break;
+         case GL_SCISSOR_BIT:
+            MEMCPY( &ctx->Scissor, attr->data,
+                   sizeof(struct gl_scissor_attrib) );
+            if (ctx->Driver.Enable)
+               (*ctx->Driver.Enable)( ctx, GL_SCISSOR_TEST, ctx->Scissor.Enabled );
+           if (ctx->Driver.Scissor)
+              ctx->Driver.Scissor( ctx, ctx->Scissor.X, ctx->Scissor.Y,
+                                   ctx->Scissor.Width, ctx->Scissor.Height );
+            break;
+         case GL_STENCIL_BUFFER_BIT:
+            MEMCPY( &ctx->Stencil, attr->data,
+                   sizeof(struct gl_stencil_attrib) );
+            if (ctx->Driver.StencilFunc)
+               (*ctx->Driver.StencilFunc)( ctx, ctx->Stencil.Function,
+                                   ctx->Stencil.Ref, ctx->Stencil.ValueMask);
+            if (ctx->Driver.StencilMask)
+               (*ctx->Driver.StencilMask)( ctx, ctx->Stencil.WriteMask );
+            if (ctx->Driver.StencilOp)
+               (*ctx->Driver.StencilOp)( ctx, ctx->Stencil.FailFunc,
+                              ctx->Stencil.ZFailFunc, ctx->Stencil.ZPassFunc);
+            if (ctx->Driver.ClearStencil)
+               (*ctx->Driver.ClearStencil)( ctx, ctx->Stencil.Clear );
+            if (ctx->Driver.Enable)
+               (*ctx->Driver.Enable)( ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled );
+            break;
+         case GL_TRANSFORM_BIT:
+            MEMCPY( &ctx->Transform, attr->data,
+                   sizeof(struct gl_transform_attrib) );
+            if (ctx->Driver.Enable) {
+               (*ctx->Driver.Enable)( ctx, GL_NORMALIZE, ctx->Transform.Normalize );
+               (*ctx->Driver.Enable)( ctx, GL_RESCALE_NORMAL_EXT, ctx->Transform.RescaleNormals );
+            }
+           ctx->Enabled &= ~(ENABLE_NORMALIZE|ENABLE_RESCALE);
+           if (ctx->Transform.Normalize) ctx->Enabled |= ENABLE_NORMALIZE;
+           if (ctx->Transform.RescaleNormals) ctx->Enabled |= ENABLE_RESCALE;
+            break;
+         case GL_TEXTURE_BIT:
+            /* Take care of texture object reference counters */
+            {
+               GLuint u;
+               for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
+                 ctx->Texture.Unit[u].CurrentD[1]->RefCount--;
+                 ctx->Texture.Unit[u].CurrentD[2]->RefCount--;
+                 ctx->Texture.Unit[u].CurrentD[3]->RefCount--;
+               }
+               MEMCPY( &ctx->Texture, attr->data,
+                       sizeof(struct gl_texture_attrib) );
+               /* restore state of the currently bound texture objects */
+               for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
+                  copy_texobj_state( ctx->Texture.Unit[u].CurrentD[1],
+                                     &(ctx->Texture.Unit[u].Saved1D) );
+                  copy_texobj_state( ctx->Texture.Unit[u].CurrentD[2],
+                                     &(ctx->Texture.Unit[u].Saved2D) );
+                  copy_texobj_state( ctx->Texture.Unit[u].CurrentD[3],
+                                     &(ctx->Texture.Unit[u].Saved3D) );
+                  gl_put_texobj_on_dirty_list( ctx, ctx->Texture.Unit[u].CurrentD[1] );
+                  gl_put_texobj_on_dirty_list( ctx, ctx->Texture.Unit[u].CurrentD[2] );
+                  gl_put_texobj_on_dirty_list( ctx, ctx->Texture.Unit[u].CurrentD[3] );
+
+               }
+            }
+            break;
+         case GL_VIEWPORT_BIT:
+            MEMCPY( &ctx->Viewport, attr->data,
+                   sizeof(struct gl_viewport_attrib) );
+            if (ctx->Driver.Viewport) {
+               (*ctx->Driver.Viewport)( ctx, ctx->Viewport.X, ctx->Viewport.Y,
+                                  ctx->Viewport.Width, ctx->Viewport.Height );
+            }
+            if (ctx->Driver.DepthRange) {
+               (*ctx->Driver.DepthRange)( ctx, ctx->Viewport.Near,
+                                          ctx->Viewport.Far );
+            }
+            break;
+         default:
+            gl_problem( ctx, "Bad attrib flag in PopAttrib");
+            break;
+      }
+
+      next = attr->next;
+      free( (void *) attr->data );
+      free( (void *) attr );
+      attr = next;
+   }
+
+   ctx->NewState = NEW_ALL;
+}
+
+
+#define GL_CLIENT_PACK_BIT (1<<20)
+#define GL_CLIENT_UNPACK_BIT (1<<21)
+
+
+void gl_PushClientAttrib( GLcontext *ctx, GLbitfield mask )
+{
+   struct gl_attrib_node *newnode;
+   struct gl_attrib_node *head;
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPushClientAttrib");
+
+   if (ctx->ClientAttribStackDepth>=MAX_CLIENT_ATTRIB_STACK_DEPTH) {
+      gl_error( ctx, GL_STACK_OVERFLOW, "glPushClientAttrib" );
+      return;
+   }
+
+   /* Build linked list of attribute nodes which save all attribute */
+   /* groups specified by the mask. */
+   head = NULL;
+
+   if (mask & GL_CLIENT_PIXEL_STORE_BIT) {
+      struct gl_pixelstore_attrib *attr;
+      /* packing attribs */
+      attr = MALLOC_STRUCT( gl_pixelstore_attrib );
+      MEMCPY( attr, &ctx->Pack, sizeof(struct gl_pixelstore_attrib) );
+      newnode = new_attrib_node( GL_CLIENT_PACK_BIT );
+      newnode->data = attr;
+      newnode->next = head;
+      head = newnode;
+      /* unpacking attribs */
+      attr = MALLOC_STRUCT( gl_pixelstore_attrib );
+      MEMCPY( attr, &ctx->Unpack, sizeof(struct gl_pixelstore_attrib) );
+      newnode = new_attrib_node( GL_CLIENT_UNPACK_BIT );
+      newnode->data = attr;
+      newnode->next = head;
+      head = newnode;
+   }
+   if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) {
+      struct gl_array_attrib *attr;
+      attr = MALLOC_STRUCT( gl_array_attrib );
+      MEMCPY( attr, &ctx->Array, sizeof(struct gl_array_attrib) );
+      newnode = new_attrib_node( GL_CLIENT_VERTEX_ARRAY_BIT );
+      newnode->data = attr;
+      newnode->next = head;
+      head = newnode;
+   }
+
+   ctx->ClientAttribStack[ctx->ClientAttribStackDepth] = head;
+   ctx->ClientAttribStackDepth++;
+}
+
+
+
+
+void gl_PopClientAttrib( GLcontext *ctx )
+{
+   struct gl_attrib_node *attr, *next;
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPopClientAttrib");
+
+   if (ctx->ClientAttribStackDepth==0) {
+      gl_error( ctx, GL_STACK_UNDERFLOW, "glPopClientAttrib" );
+      return;
+   }
+
+   ctx->ClientAttribStackDepth--;
+   attr = ctx->ClientAttribStack[ctx->ClientAttribStackDepth];
+
+   while (attr) {
+      switch (attr->kind) {
+         case GL_CLIENT_PACK_BIT:
+            MEMCPY( &ctx->Pack, attr->data,
+                    sizeof(struct gl_pixelstore_attrib) );
+            break;
+         case GL_CLIENT_UNPACK_BIT:
+            MEMCPY( &ctx->Unpack, attr->data,
+                    sizeof(struct gl_pixelstore_attrib) );
+            break;
+         case GL_CLIENT_VERTEX_ARRAY_BIT:
+            MEMCPY( &ctx->Array, attr->data,
+                   sizeof(struct gl_array_attrib) );
+            break;
+         default:
+            gl_problem( ctx, "Bad attrib flag in PopClientAttrib");
+            break;
+      }
+
+      next = attr->next;
+      free( (void *) attr->data );
+      free( (void *) attr );
+      attr = next;
+   }
+
+   ctx->NewState = NEW_ALL;
+}
+
diff --git a/src/mesa/main/attrib.h b/src/mesa/main/attrib.h
new file mode 100644 (file)
index 0000000..0661c26
--- /dev/null
@@ -0,0 +1,47 @@
+/* $Id: attrib.h,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+#ifndef ATTRIB_H
+#define ATTRIB_h
+
+
+#include "types.h"
+
+
+extern void gl_PushAttrib( GLcontext* ctx, GLbitfield mask );
+
+extern void gl_PopAttrib( GLcontext* ctx );
+
+extern void gl_PushClientAttrib( GLcontext *ctx, GLbitfield mask );
+
+extern void gl_PopClientAttrib( GLcontext *ctx );
+
+
+#endif
diff --git a/src/mesa/main/blend.c b/src/mesa/main/blend.c
new file mode 100644 (file)
index 0000000..10119ac
--- /dev/null
@@ -0,0 +1,812 @@
+/* $Id: blend.c,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "alphabuf.h"
+#include "blend.h"
+#include "context.h"
+#include "enums.h"
+#include "macros.h"
+#include "pb.h"
+#include "span.h"
+#include "types.h"
+#ifdef XFree86Server
+#include "GL/xf86glx.h"
+#endif
+#endif
+
+
+void gl_BlendFunc( GLcontext *ctx, GLenum sfactor, GLenum dfactor )
+{
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glBlendFunc");
+
+   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+      fprintf(stderr, "glBlendFunc %s %s\n",
+             gl_lookup_enum_by_nr(sfactor),
+             gl_lookup_enum_by_nr(dfactor));
+
+   switch (sfactor) {
+      case GL_ZERO:
+      case GL_ONE:
+      case GL_DST_COLOR:
+      case GL_ONE_MINUS_DST_COLOR:
+      case GL_SRC_ALPHA:
+      case GL_ONE_MINUS_SRC_ALPHA:
+      case GL_DST_ALPHA:
+      case GL_ONE_MINUS_DST_ALPHA:
+      case GL_SRC_ALPHA_SATURATE:
+      case GL_CONSTANT_COLOR:
+      case GL_ONE_MINUS_CONSTANT_COLOR:
+      case GL_CONSTANT_ALPHA:
+      case GL_ONE_MINUS_CONSTANT_ALPHA:
+         ctx->Color.BlendSrcRGB = ctx->Color.BlendSrcA = sfactor;
+         break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glBlendFunc(sfactor)" );
+         return;
+   }
+
+   switch (dfactor) {
+      case GL_ZERO:
+      case GL_ONE:
+      case GL_SRC_COLOR:
+      case GL_ONE_MINUS_SRC_COLOR:
+      case GL_SRC_ALPHA:
+      case GL_ONE_MINUS_SRC_ALPHA:
+      case GL_DST_ALPHA:
+      case GL_ONE_MINUS_DST_ALPHA:
+      case GL_CONSTANT_COLOR:
+      case GL_ONE_MINUS_CONSTANT_COLOR:
+      case GL_CONSTANT_ALPHA:
+      case GL_ONE_MINUS_CONSTANT_ALPHA:
+         ctx->Color.BlendDstRGB = ctx->Color.BlendDstA = dfactor;
+         break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glBlendFunc(dfactor)" );
+         return;
+   }
+
+   if (ctx->Driver.BlendFunc) {
+      (*ctx->Driver.BlendFunc)( ctx, sfactor, dfactor );
+   }
+
+   ctx->Color.BlendFunc = NULL;
+   ctx->NewState |= NEW_RASTER_OPS;
+}
+
+
+/* GL_INGR_blend_func_separate */
+void
+gl_BlendFuncSeparate( GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB,
+                      GLenum sfactorA, GLenum dfactorA )
+{
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glBlendFuncSeparate");
+
+   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+      fprintf(stderr, "glBlendFuncSeperate %s %s %s %s\n",
+             gl_lookup_enum_by_nr(sfactorRGB),
+             gl_lookup_enum_by_nr(dfactorRGB),
+             gl_lookup_enum_by_nr(sfactorA),
+             gl_lookup_enum_by_nr(dfactorA));
+
+   switch (sfactorRGB) {
+      case GL_ZERO:
+      case GL_ONE:
+      case GL_DST_COLOR:
+      case GL_ONE_MINUS_DST_COLOR:
+      case GL_SRC_ALPHA:
+      case GL_ONE_MINUS_SRC_ALPHA:
+      case GL_DST_ALPHA:
+      case GL_ONE_MINUS_DST_ALPHA:
+      case GL_SRC_ALPHA_SATURATE:
+      case GL_CONSTANT_COLOR:
+      case GL_ONE_MINUS_CONSTANT_COLOR:
+      case GL_CONSTANT_ALPHA:
+      case GL_ONE_MINUS_CONSTANT_ALPHA:
+         ctx->Color.BlendSrcRGB = sfactorRGB;
+         break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glBlendFuncSeparate(sfactorRGB)" );
+         return;
+   }
+
+   switch (dfactorRGB) {
+      case GL_ZERO:
+      case GL_ONE:
+      case GL_SRC_COLOR:
+      case GL_ONE_MINUS_SRC_COLOR:
+      case GL_SRC_ALPHA:
+      case GL_ONE_MINUS_SRC_ALPHA:
+      case GL_DST_ALPHA:
+      case GL_ONE_MINUS_DST_ALPHA:
+      case GL_CONSTANT_COLOR:
+      case GL_ONE_MINUS_CONSTANT_COLOR:
+      case GL_CONSTANT_ALPHA:
+      case GL_ONE_MINUS_CONSTANT_ALPHA:
+         ctx->Color.BlendDstRGB = dfactorRGB;
+         break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glBlendFuncSeparate(dfactorRGB)" );
+         return;
+   }
+
+   switch (sfactorA) {
+      case GL_ZERO:
+      case GL_ONE:
+      case GL_DST_COLOR:
+      case GL_ONE_MINUS_DST_COLOR:
+      case GL_SRC_ALPHA:
+      case GL_ONE_MINUS_SRC_ALPHA:
+      case GL_DST_ALPHA:
+      case GL_ONE_MINUS_DST_ALPHA:
+      case GL_SRC_ALPHA_SATURATE:
+      case GL_CONSTANT_COLOR:
+      case GL_ONE_MINUS_CONSTANT_COLOR:
+      case GL_CONSTANT_ALPHA:
+      case GL_ONE_MINUS_CONSTANT_ALPHA:
+         ctx->Color.BlendSrcA = sfactorA;
+         break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glBlendFuncSeparate(sfactorA)" );
+         return;
+   }
+
+   switch (dfactorA) {
+      case GL_ZERO:
+      case GL_ONE:
+      case GL_SRC_COLOR:
+      case GL_ONE_MINUS_SRC_COLOR:
+      case GL_SRC_ALPHA:
+      case GL_ONE_MINUS_SRC_ALPHA:
+      case GL_DST_ALPHA:
+      case GL_ONE_MINUS_DST_ALPHA:
+      case GL_CONSTANT_COLOR:
+      case GL_ONE_MINUS_CONSTANT_COLOR:
+      case GL_CONSTANT_ALPHA:
+      case GL_ONE_MINUS_CONSTANT_ALPHA:
+         ctx->Color.BlendDstA = dfactorA;
+         break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glBlendFuncSeparate(dfactorA)" );
+         return;
+   }
+
+   ctx->Color.BlendFunc = NULL;
+   ctx->NewState |= NEW_RASTER_OPS;
+}
+
+
+
+/* This is really an extension function! */
+void gl_BlendEquation( GLcontext *ctx, GLenum mode )
+{
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glBlendEquation");
+
+   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+      fprintf(stderr, "glBlendEquation %s\n",
+             gl_lookup_enum_by_nr(mode));
+
+
+   switch (mode) {
+      case GL_MIN_EXT:
+      case GL_MAX_EXT:
+      case GL_LOGIC_OP:
+      case GL_FUNC_ADD_EXT:
+      case GL_FUNC_SUBTRACT_EXT:
+      case GL_FUNC_REVERSE_SUBTRACT_EXT:
+         ctx->Color.BlendEquation = mode;
+         break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glBlendEquation" );
+         return;
+   }
+
+   /* This is needed to support 1.1's RGB logic ops AND
+    * 1.0's blending logicops.
+    */
+   if (mode==GL_LOGIC_OP && ctx->Color.BlendEnabled) {
+      ctx->Color.ColorLogicOpEnabled = GL_TRUE;
+   }
+   else {
+      ctx->Color.ColorLogicOpEnabled = GL_FALSE;
+   }
+
+   ctx->Color.BlendFunc = NULL;
+   ctx->NewState |= NEW_RASTER_OPS;
+}
+
+
+
+void gl_BlendColor( GLcontext *ctx, GLclampf red, GLclampf green,
+                   GLclampf blue, GLclampf alpha )
+{
+   ctx->Color.BlendColor[0] = CLAMP( red,   0.0, 1.0 );
+   ctx->Color.BlendColor[1] = CLAMP( green, 0.0, 1.0 );
+   ctx->Color.BlendColor[2] = CLAMP( blue,  0.0, 1.0 );
+   ctx->Color.BlendColor[3] = CLAMP( alpha, 0.0, 1.0 );
+}
+
+
+
+/*
+ * Common transparency blending mode.
+ */
+static void blend_transparency( GLcontext *ctx, GLuint n, const GLubyte mask[],
+                                GLubyte rgba[][4], CONST GLubyte dest[][4] )
+{
+   GLuint i;
+   ASSERT(ctx->Color.BlendEquation==GL_FUNC_ADD_EXT);
+   ASSERT(ctx->Color.BlendSrcRGB==GL_SRC_ALPHA);
+   ASSERT(ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA);
+   (void) ctx;
+
+   for (i=0;i<n;i++) {
+      if (mask[i]) {
+         GLint t = rgba[i][ACOMP];  /* t in [0,255] */
+         if (t == 0) {
+            rgba[i][RCOMP] = dest[i][RCOMP];
+            rgba[i][GCOMP] = dest[i][GCOMP];
+            rgba[i][BCOMP] = dest[i][BCOMP];
+            rgba[i][ACOMP] = dest[i][ACOMP];
+         }
+         else if (t == 255) {
+            /* no-op */
+         }
+         else {
+            GLint s = 255 - t;
+            GLint r = (rgba[i][RCOMP] * t + dest[i][RCOMP] * s) >> 8;
+            GLint g = (rgba[i][GCOMP] * t + dest[i][GCOMP] * s) >> 8;
+            GLint b = (rgba[i][BCOMP] * t + dest[i][BCOMP] * s) >> 8;
+            GLint a = (rgba[i][ACOMP] * t + dest[i][ACOMP] * s) >> 8;
+            ASSERT(r <= 255);
+            ASSERT(g <= 255);
+            ASSERT(b <= 255);
+            ASSERT(a <= 255);
+            rgba[i][RCOMP] = r;
+            rgba[i][GCOMP] = g;
+            rgba[i][BCOMP] = b;
+            rgba[i][ACOMP] = a;
+         }
+      }
+   }
+}
+
+
+
+/*
+ * Add src and dest.
+ */
+static void blend_add( GLcontext *ctx, GLuint n, const GLubyte mask[],
+                       GLubyte rgba[][4], CONST GLubyte dest[][4] )
+{
+   GLuint i;
+   ASSERT(ctx->Color.BlendEquation==GL_FUNC_ADD_EXT);
+   ASSERT(ctx->Color.BlendSrcRGB==GL_ONE);
+   ASSERT(ctx->Color.BlendDstRGB==GL_ONE);
+   (void) ctx;
+
+   for (i=0;i<n;i++) {
+      if (mask[i]) {
+         GLint r = rgba[i][RCOMP] + dest[i][RCOMP];
+         GLint g = rgba[i][GCOMP] + dest[i][GCOMP];
+         GLint b = rgba[i][BCOMP] + dest[i][BCOMP];
+         GLint a = rgba[i][ACOMP] + dest[i][ACOMP];
+         rgba[i][RCOMP] = MIN2( r, 255 );
+         rgba[i][GCOMP] = MIN2( g, 255 );
+         rgba[i][BCOMP] = MIN2( b, 255 );
+         rgba[i][ACOMP] = MIN2( a, 255 );
+      }
+   }
+}
+
+
+
+/*
+ * Blend min function  (for GL_EXT_blend_minmax)
+ */
+static void blend_min( GLcontext *ctx, GLuint n, const GLubyte mask[],
+                       GLubyte rgba[][4], CONST GLubyte dest[][4] )
+{
+   GLuint i;
+   ASSERT(ctx->Color.BlendEquation==GL_MIN_EXT);
+   (void) ctx;
+
+   for (i=0;i<n;i++) {
+      if (mask[i]) {
+         rgba[i][RCOMP] = MIN2( rgba[i][RCOMP], dest[i][RCOMP] );
+         rgba[i][GCOMP] = MIN2( rgba[i][GCOMP], dest[i][GCOMP] );
+         rgba[i][BCOMP] = MIN2( rgba[i][BCOMP], dest[i][BCOMP] );
+         rgba[i][ACOMP] = MIN2( rgba[i][ACOMP], dest[i][ACOMP] );
+      }
+   }
+}
+
+
+
+/*
+ * Blend max function  (for GL_EXT_blend_minmax)
+ */
+static void blend_max( GLcontext *ctx, GLuint n, const GLubyte mask[],
+                       GLubyte rgba[][4], CONST GLubyte dest[][4] )
+{
+   GLuint i;
+   ASSERT(ctx->Color.BlendEquation==GL_MAX_EXT);
+   (void) ctx;
+
+   for (i=0;i<n;i++) {
+      if (mask[i]) {
+         rgba[i][RCOMP] = MAX2( rgba[i][RCOMP], dest[i][RCOMP] );
+         rgba[i][GCOMP] = MAX2( rgba[i][GCOMP], dest[i][GCOMP] );
+         rgba[i][BCOMP] = MAX2( rgba[i][BCOMP], dest[i][BCOMP] );
+         rgba[i][ACOMP] = MAX2( rgba[i][ACOMP], dest[i][ACOMP] );
+      }
+   }
+}
+
+
+
+/*
+ * Modulate:  result = src * dest
+ */
+static void blend_modulate( GLcontext *ctx, GLuint n, const GLubyte mask[],
+                            GLubyte rgba[][4], CONST GLubyte dest[][4] )
+{
+   GLuint i;
+   (void) ctx;
+
+   for (i=0;i<n;i++) {
+      if (mask[i]) {
+         GLint r = (rgba[i][RCOMP] * dest[i][RCOMP]) >> 8;
+         GLint g = (rgba[i][GCOMP] * dest[i][GCOMP]) >> 8;
+         GLint b = (rgba[i][BCOMP] * dest[i][BCOMP]) >> 8;
+         GLint a = (rgba[i][ACOMP] * dest[i][ACOMP]) >> 8;
+         rgba[i][RCOMP] = r;
+         rgba[i][GCOMP] = g;
+         rgba[i][BCOMP] = b;
+         rgba[i][ACOMP] = a;
+      }
+   }
+}
+
+
+
+/*
+ * General case blend pixels.
+ * Input:  n - number of pixels
+ *         mask - the usual write mask
+ * In/Out:  rgba - the incoming and modified pixels
+ * Input:  dest - the pixels from the dest color buffer
+ */
+static void blend_general( GLcontext *ctx, GLuint n, const GLubyte mask[],
+                           GLubyte rgba[][4], CONST GLubyte dest[][4] )
+{
+   GLfloat rscale = 1.0F / 255.0F;
+   GLfloat gscale = 1.0F / 255.0F;
+   GLfloat bscale = 1.0F / 255.0F;
+   GLfloat ascale = 1.0F / 255.0F;
+   GLuint i;
+
+   for (i=0;i<n;i++) {
+      if (mask[i]) {
+         GLint Rs, Gs, Bs, As;  /* Source colors */
+         GLint Rd, Gd, Bd, Ad;  /* Dest colors */
+         GLfloat sR, sG, sB, sA;  /* Source scaling */
+         GLfloat dR, dG, dB, dA;  /* Dest scaling */
+         GLfloat r, g, b, a;
+
+         /* Source Color */
+         Rs = rgba[i][RCOMP];
+         Gs = rgba[i][GCOMP];
+         Bs = rgba[i][BCOMP];
+         As = rgba[i][ACOMP];
+
+         /* Frame buffer color */
+         Rd = dest[i][RCOMP];
+         Gd = dest[i][GCOMP];
+         Bd = dest[i][BCOMP];
+         Ad = dest[i][ACOMP];
+
+         /* Source RGB factor */
+         switch (ctx->Color.BlendSrcRGB) {
+            case GL_ZERO:
+               sR = sG = sB = 0.0F;
+               break;
+            case GL_ONE:
+               sR = sG = sB = 1.0F;
+               break;
+            case GL_DST_COLOR:
+               sR = (GLfloat) Rd * rscale;
+               sG = (GLfloat) Gd * gscale;
+               sB = (GLfloat) Bd * bscale;
+               break;
+            case GL_ONE_MINUS_DST_COLOR:
+               sR = 1.0F - (GLfloat) Rd * rscale;
+               sG = 1.0F - (GLfloat) Gd * gscale;
+               sB = 1.0F - (GLfloat) Bd * bscale;
+               break;
+            case GL_SRC_ALPHA:
+               sR = sG = sB = (GLfloat) As * ascale;
+               break;
+            case GL_ONE_MINUS_SRC_ALPHA:
+               sR = sG = sB = (GLfloat) 1.0F - (GLfloat) As * ascale;
+               break;
+            case GL_DST_ALPHA:
+               sR = sG = sB = (GLfloat) Ad * ascale;
+               break;
+            case GL_ONE_MINUS_DST_ALPHA:
+               sR = sG = sB = 1.0F - (GLfloat) Ad * ascale;
+               break;
+            case GL_SRC_ALPHA_SATURATE:
+               if (As < 1.0F - (GLfloat) Ad * ascale) {
+                  sR = sG = sB = (GLfloat) As * ascale;
+               }
+               else {
+                  sR = sG = sB = 1.0F - (GLfloat) Ad * ascale;
+               }
+               break;
+            case GL_CONSTANT_COLOR:
+               sR = ctx->Color.BlendColor[0];
+               sG = ctx->Color.BlendColor[1];
+               sB = ctx->Color.BlendColor[2];
+               break;
+            case GL_ONE_MINUS_CONSTANT_COLOR:
+               sR = 1.0F - ctx->Color.BlendColor[0];
+               sG = 1.0F - ctx->Color.BlendColor[1];
+               sB = 1.0F - ctx->Color.BlendColor[2];
+               break;
+            case GL_CONSTANT_ALPHA:
+               sR = sG = sB = ctx->Color.BlendColor[3];
+               break;
+            case GL_ONE_MINUS_CONSTANT_ALPHA:
+               sR = sG = sB = 1.0F - ctx->Color.BlendColor[3];
+               break;
+            default:
+               /* this should never happen */
+               gl_problem(ctx, "Bad blend source RGB factor in do_blend");
+              return;
+         }
+
+         /* Source Alpha factor */
+         switch (ctx->Color.BlendSrcA) {
+            case GL_ZERO:
+               sA = 0.0F;
+               break;
+            case GL_ONE:
+               sA = 1.0F;
+               break;
+            case GL_DST_COLOR:
+               sA = (GLfloat) Ad * ascale;
+               break;
+            case GL_ONE_MINUS_DST_COLOR:
+               sA = 1.0F - (GLfloat) Ad * ascale;
+               break;
+            case GL_SRC_ALPHA:
+               sA = (GLfloat) As * ascale;
+               break;
+            case GL_ONE_MINUS_SRC_ALPHA:
+               sA = (GLfloat) 1.0F - (GLfloat) As * ascale;
+               break;
+            case GL_DST_ALPHA:
+               sA =(GLfloat) Ad * ascale;
+               break;
+            case GL_ONE_MINUS_DST_ALPHA:
+               sA = 1.0F - (GLfloat) Ad * ascale;
+               break;
+            case GL_SRC_ALPHA_SATURATE:
+               sA = 1.0;
+               break;
+            case GL_CONSTANT_COLOR:
+               sA = ctx->Color.BlendColor[3];
+               break;
+            case GL_ONE_MINUS_CONSTANT_COLOR:
+               sA = 1.0F - ctx->Color.BlendColor[3];
+               break;
+            case GL_CONSTANT_ALPHA:
+               sA = ctx->Color.BlendColor[3];
+               break;
+            case GL_ONE_MINUS_CONSTANT_ALPHA:
+               sA = 1.0F - ctx->Color.BlendColor[3];
+               break;
+            default:
+               /* this should never happen */
+               gl_problem(ctx, "Bad blend source A factor in do_blend");
+         }
+
+         /* Dest RGB factor */
+         switch (ctx->Color.BlendDstRGB) {
+            case GL_ZERO:
+               dR = dG = dB = 0.0F;
+               break;
+            case GL_ONE:
+               dR = dG = dB = 1.0F;
+               break;
+            case GL_SRC_COLOR:
+               dR = (GLfloat) Rs * rscale;
+               dG = (GLfloat) Gs * gscale;
+               dB = (GLfloat) Bs * bscale;
+               break;
+            case GL_ONE_MINUS_SRC_COLOR:
+               dR = 1.0F - (GLfloat) Rs * rscale;
+               dG = 1.0F - (GLfloat) Gs * gscale;
+               dB = 1.0F - (GLfloat) Bs * bscale;
+               break;
+            case GL_SRC_ALPHA:
+               dR = dG = dB = (GLfloat) As * ascale;
+               break;
+            case GL_ONE_MINUS_SRC_ALPHA:
+               dR = dG = dB = (GLfloat) 1.0F - (GLfloat) As * ascale;
+               break;
+            case GL_DST_ALPHA:
+               dR = dG = dB = (GLfloat) Ad * ascale;
+               break;
+            case GL_ONE_MINUS_DST_ALPHA:
+               dR = dG = dB = 1.0F - (GLfloat) Ad * ascale;
+               break;
+            case GL_CONSTANT_COLOR:
+               dR = ctx->Color.BlendColor[0];
+               dG = ctx->Color.BlendColor[1];
+               dB = ctx->Color.BlendColor[2];
+               break;
+            case GL_ONE_MINUS_CONSTANT_COLOR:
+               dR = 1.0F - ctx->Color.BlendColor[0];
+               dG = 1.0F - ctx->Color.BlendColor[1];
+               dB = 1.0F - ctx->Color.BlendColor[2];
+               break;
+            case GL_CONSTANT_ALPHA:
+               dR = dG = dB = ctx->Color.BlendColor[3];
+               break;
+            case GL_ONE_MINUS_CONSTANT_ALPHA:
+               dR = dG = dB = 1.0F - ctx->Color.BlendColor[3] * ascale;
+               break;
+            default:
+               /* this should never happen */
+               gl_problem(ctx, "Bad blend dest RGB factor in do_blend");
+         }
+
+         /* Dest Alpha factor */
+         switch (ctx->Color.BlendDstA) {
+            case GL_ZERO:
+               dA = 0.0F;
+               break;
+            case GL_ONE:
+               dA = 1.0F;
+               break;
+            case GL_SRC_COLOR:
+               dA = (GLfloat) As * ascale;
+               break;
+            case GL_ONE_MINUS_SRC_COLOR:
+               dA = 1.0F - (GLfloat) As * ascale;
+               break;
+            case GL_SRC_ALPHA:
+               dA = (GLfloat) As * ascale;
+               break;
+            case GL_ONE_MINUS_SRC_ALPHA:
+               dA = (GLfloat) 1.0F - (GLfloat) As * ascale;
+               break;
+            case GL_DST_ALPHA:
+               dA = (GLfloat) Ad * ascale;
+               break;
+            case GL_ONE_MINUS_DST_ALPHA:
+               dA = 1.0F - (GLfloat) Ad * ascale;
+               break;
+            case GL_CONSTANT_COLOR:
+               dA = ctx->Color.BlendColor[3];
+               break;
+            case GL_ONE_MINUS_CONSTANT_COLOR:
+               dA = 1.0F - ctx->Color.BlendColor[3];
+               break;
+            case GL_CONSTANT_ALPHA:
+               dA = ctx->Color.BlendColor[3];
+               break;
+            case GL_ONE_MINUS_CONSTANT_ALPHA:
+               dA = 1.0F - ctx->Color.BlendColor[3] * ascale;
+               break;
+            default:
+               /* this should never happen */
+               gl_problem(ctx, "Bad blend dest A factor in do_blend");
+              return;
+         }
+
+         /* Due to round-off problems we have to clamp against zero. */
+         /* Optimization: we don't have to do this for all src & dst factors */
+         if (dA < 0.0F)  dA = 0.0F;
+         if (dR < 0.0F)  dR = 0.0F;
+         if (dG < 0.0F)  dG = 0.0F;
+         if (dB < 0.0F)  dB = 0.0F;
+         if (sA < 0.0F)  sA = 0.0F;
+         if (sR < 0.0F)  sR = 0.0F;
+         if (sG < 0.0F)  sG = 0.0F;
+         if (sB < 0.0F)  sB = 0.0F;
+
+         ASSERT( sR <= 1.0 );
+         ASSERT( sG <= 1.0 );
+         ASSERT( sB <= 1.0 );
+         ASSERT( sA <= 1.0 );
+         ASSERT( dR <= 1.0 );
+         ASSERT( dG <= 1.0 );
+         ASSERT( dB <= 1.0 );
+         ASSERT( dA <= 1.0 );
+
+         /* compute blended color */
+         if (ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) {
+            r = Rs * sR + Rd * dR;
+            g = Gs * sG + Gd * dG;
+            b = Bs * sB + Bd * dB;
+            a = As * sA + Ad * dA;
+         }
+         else if (ctx->Color.BlendEquation==GL_FUNC_SUBTRACT_EXT) {
+            r = Rs * sR - Rd * dR;
+            g = Gs * sG - Gd * dG;
+            b = Bs * sB - Bd * dB;
+            a = As * sA - Ad * dA;
+         }
+         else if (ctx->Color.BlendEquation==GL_FUNC_REVERSE_SUBTRACT_EXT) {
+            r = Rd * dR - Rs * sR;
+            g = Gd * dG - Gs * sG;
+            b = Bd * dB - Bs * sB;
+            a = Ad * dA - As * sA;
+         }
+
+         /* final clamping */
+         rgba[i][RCOMP] = (GLint) CLAMP( r, 0.0F, 255.0F );
+         rgba[i][GCOMP] = (GLint) CLAMP( g, 0.0F, 255.0F );
+         rgba[i][BCOMP] = (GLint) CLAMP( b, 0.0F, 255.0F );
+         rgba[i][ACOMP] = (GLint) CLAMP( a, 0.0F, 255.0F );
+      }
+   }
+}
+
+
+
+#if defined(USE_MMX_ASM)
+#include "X86/mmx.h"
+#include "X86/common_x86asm.h"
+#endif
+
+
+/*
+ * Analyze current blending parameters to pick fastest blending function.
+ * Result: the ctx->Color.BlendFunc pointer is updated.
+ */
+static void set_blend_function( GLcontext *ctx )
+{
+   const GLenum eq = ctx->Color.BlendEquation;
+   const GLenum srcRGB = ctx->Color.BlendSrcRGB;
+   const GLenum dstRGB = ctx->Color.BlendDstRGB;
+   const GLenum srcA = ctx->Color.BlendSrcA;
+   const GLenum dstA = ctx->Color.BlendDstA;
+
+#if defined(USE_MMX_ASM)
+   /* Hmm.  A table here would have 12^4 == way too many entries.
+    * Provide a hook for MMX instead.
+    */
+   if (gl_x86_cpu_features & GL_CPU_MMX) {
+      gl_mmx_set_blend_function (ctx);
+   } else
+#endif
+   if (srcRGB != srcA || dstRGB != dstA) {
+      ctx->Color.BlendFunc = blend_general;
+   }
+   else if (eq==GL_FUNC_ADD_EXT && srcRGB==GL_SRC_ALPHA
+       && dstRGB==GL_ONE_MINUS_SRC_ALPHA) {
+      ctx->Color.BlendFunc = blend_transparency;
+   }
+   else if (eq==GL_FUNC_ADD_EXT && srcRGB==GL_ONE && dstRGB==GL_ONE) {
+      ctx->Color.BlendFunc = blend_add;
+   }
+   else if (((eq==GL_FUNC_ADD_EXT || eq==GL_FUNC_REVERSE_SUBTRACT_EXT)
+             && (srcRGB==GL_ZERO && dstRGB==GL_SRC_COLOR))
+            ||
+            ((eq==GL_FUNC_ADD_EXT || eq==GL_FUNC_SUBTRACT_EXT)
+             && (srcRGB==GL_DST_COLOR && dstRGB==GL_ZERO))) {
+      ctx->Color.BlendFunc = blend_modulate;
+   }
+   else if (eq==GL_MIN_EXT) {
+      ctx->Color.BlendFunc = blend_min;
+   }
+   else if (eq==GL_MAX_EXT) {
+      ctx->Color.BlendFunc = blend_max;
+   }
+   else {
+      ctx->Color.BlendFunc = blend_general;
+   }
+}
+
+
+
+/*
+ * Apply the blending operator to a span of pixels.
+ * Input:  n - number of pixels in span
+ *         x, y - location of leftmost pixel in span in window coords.
+ *         mask - boolean mask indicating which pixels to blend.
+ * In/Out:  rgba - pixel values
+ */
+void gl_blend_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
+                   GLubyte rgba[][4], const GLubyte mask[] )
+{
+   GLubyte dest[MAX_WIDTH][4];
+
+   /* Check if device driver can do the work */
+   if (ctx->Color.BlendEquation==GL_LOGIC_OP && !ctx->Color.SWLogicOpEnabled) {
+      return;
+   }
+
+   /* Read span of current frame buffer pixels */
+   gl_read_rgba_span( ctx, n, x, y, dest );
+
+   if (!ctx->Color.BlendFunc)
+      set_blend_function(ctx);
+
+   (*ctx->Color.BlendFunc)( ctx, n, mask, rgba, (const GLubyte (*)[4])dest );
+}
+
+
+
+
+
+/*
+ * Apply the blending operator to an array of pixels.
+ * Input:  n - number of pixels in span
+ *         x, y - array of pixel locations
+ *         mask - boolean mask indicating which pixels to blend.
+ * In/Out:  rgba - pixel values
+ */
+void gl_blend_pixels( GLcontext *ctx,
+                      GLuint n, const GLint x[], const GLint y[],
+                     GLubyte rgba[][4], const GLubyte mask[] )
+{
+   GLubyte dest[PB_SIZE][4];
+
+   /* Check if device driver can do the work */
+   if (ctx->Color.BlendEquation==GL_LOGIC_OP && !ctx->Color.SWLogicOpEnabled) {
+      return;
+   }
+
+   /* Read pixels from current color buffer */
+   (*ctx->Driver.ReadRGBAPixels)( ctx, n, x, y, dest, mask );
+
+   if (ctx->RasterMask & ALPHABUF_BIT) {
+      gl_read_alpha_pixels( ctx, n, x, y, dest, mask );
+   }
+   else {
+      GLuint i;
+      for (i=0; i<n; i++) {
+         dest[i][ACOMP] = 255;
+      }
+   }
+
+   if (!ctx->Color.BlendFunc)
+      set_blend_function(ctx);
+
+   (*ctx->Color.BlendFunc)( ctx, n, mask, rgba, (const GLubyte (*)[4])dest );
+}
diff --git a/src/mesa/main/blend.h b/src/mesa/main/blend.h
new file mode 100644 (file)
index 0000000..837ea9d
--- /dev/null
@@ -0,0 +1,68 @@
+/* $Id: blend.h,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+#ifndef BLEND_H
+#define BLEND_H
+
+
+#include "types.h"
+
+
+
+extern void
+gl_blend_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
+               GLubyte rgba[][4], const GLubyte mask[] );
+
+
+extern void
+gl_blend_pixels( GLcontext *ctx,
+                 GLuint n, const GLint x[], const GLint y[],
+                 GLubyte rgba[][4], const GLubyte mask[] );
+
+
+extern void
+gl_BlendFunc( GLcontext *ctx, GLenum sfactor, GLenum dfactor );
+
+
+extern void
+gl_BlendFuncSeparate( GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB,
+                      GLenum sfactorA, GLenum dfactorA );
+
+
+extern void
+gl_BlendEquation( GLcontext *ctx, GLenum mode );
+
+
+extern void
+gl_BlendColor( GLcontext *ctx, GLclampf red, GLclampf green,
+               GLclampf blue, GLclampf alpha );
+
+
+#endif
diff --git a/src/mesa/main/clip.c b/src/mesa/main/clip.c
new file mode 100644 (file)
index 0000000..9feaf24
--- /dev/null
@@ -0,0 +1,460 @@
+/* $Id: clip.c,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <string.h>
+#include <stdlib.h>
+#include "clip.h"
+#include "context.h"
+#include "macros.h"
+#include "matrix.h"
+#include "mmath.h"
+#include "types.h"
+#include "vb.h"
+#include "xform.h"
+#ifdef XFree86Server
+#include "GL/xf86glx.h"
+#endif
+#endif
+
+
+
+
+/* Linear interpolation between A and B: */
+#define LINTERP( T, A, B )   ( (A) + (T) * ( (B) - (A) ) )
+
+
+
+#define INTERP_SZ( t, vec, to, a, b, sz )                      \
+do {                                                           \
+   switch (sz) {                                               \
+   case 4: vec[to][3] = LINTERP( t, vec[a][3], vec[b][3] );    \
+   case 3: vec[to][2] = LINTERP( t, vec[a][2], vec[b][2] );    \
+   case 2: vec[to][1] = LINTERP( t, vec[a][1], vec[b][1] );    \
+   case 1: vec[to][0] = LINTERP( t, vec[a][0], vec[b][0] );    \
+   }                                                           \
+} while(0)
+   
+
+
+
+#define CLIP_RGBA0    0x1
+#define CLIP_RGBA1    0x2
+#define CLIP_TEX0     0x4
+#define CLIP_TEX1     0x8
+#define CLIP_INDEX0   0x10
+#define CLIP_INDEX1   0x20
+#define CLIP_EDGE     0x40
+
+/* This is sparsely populated: */
+static clip_interp_func clip_interp_tab[0x80]; 
+
+#define IND 0
+#define NAME clip_nil
+#include "interp_tmp.h"
+
+#define IND (CLIP_RGBA0)
+#define NAME clipRGBA0
+#include "interp_tmp.h"
+
+#define IND (CLIP_RGBA0|CLIP_RGBA1)
+#define NAME clipRGBA0_RGBA1
+#include "interp_tmp.h"
+
+#define IND (CLIP_TEX0|CLIP_RGBA0)
+#define NAME clipTEX0_RGBA0
+#include "interp_tmp.h"
+
+#define IND (CLIP_TEX0|CLIP_RGBA0|CLIP_RGBA1)
+#define NAME clipTEX0_RGBA0_RGBA1
+#include "interp_tmp.h"
+
+#define IND (CLIP_TEX1|CLIP_TEX0|CLIP_RGBA0)
+#define NAME clipTEX1_TEX0_RGBA0
+#include "interp_tmp.h"
+
+#define IND (CLIP_TEX0)
+#define NAME clipTEX0
+#include "interp_tmp.h"
+
+#define IND (CLIP_TEX1|CLIP_TEX0)
+#define NAME clipTEX1_TEX0
+#include "interp_tmp.h"
+
+#define IND (CLIP_TEX1|CLIP_TEX0|CLIP_RGBA0|CLIP_RGBA1)
+#define NAME clipTEX1_TEX0_RGBA0_RGBA1
+#include "interp_tmp.h"
+
+#define IND (CLIP_INDEX0)
+#define NAME clipINDEX0
+#include "interp_tmp.h"
+
+#define IND (CLIP_INDEX0|CLIP_INDEX1)
+#define NAME clipINDEX0_INDEX1
+#include "interp_tmp.h"
+
+#define IND (CLIP_RGBA0|CLIP_EDGE)
+#define NAME clipRGBA0_EDGE
+#include "interp_tmp.h"
+
+#define IND (CLIP_RGBA0|CLIP_RGBA1|CLIP_EDGE)
+#define NAME clipRGBA0_RGBA1_EDGE
+#include "interp_tmp.h"
+
+#define IND (CLIP_TEX0|CLIP_RGBA0|CLIP_EDGE)
+#define NAME clipTEX0_RGBA0_EDGE
+#include "interp_tmp.h"
+
+#define IND (CLIP_TEX0|CLIP_RGBA0|CLIP_RGBA1|CLIP_EDGE)
+#define NAME clipTEX0_RGBA0_RGBA1_EDGE
+#include "interp_tmp.h"
+
+#define IND (CLIP_TEX1|CLIP_TEX0|CLIP_RGBA0|CLIP_EDGE)
+#define NAME clipTEX1_TEX0_RGBA0_EDGE
+#include "interp_tmp.h"
+
+#define IND (CLIP_TEX1|CLIP_TEX0|CLIP_RGBA0|CLIP_RGBA1|CLIP_EDGE)
+#define NAME clipTEX1_TEX0_RGBA0_RGBA1_EDGE
+#include "interp_tmp.h"
+
+#define IND (CLIP_INDEX0|CLIP_EDGE)
+#define NAME clipINDEX0_EDGE
+#include "interp_tmp.h"
+
+#define IND (CLIP_INDEX0|CLIP_INDEX1|CLIP_EDGE)
+#define NAME clipINDEX0_INDEX1_EDGE
+#include "interp_tmp.h"
+
+
+
+
+/**********************************************************************/
+/*                     Get/Set User clip-planes.                      */
+/**********************************************************************/
+
+
+
+void gl_ClipPlane( GLcontext* ctx, GLenum plane, const GLfloat *equation )
+{
+   GLint p;
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glClipPlane");
+
+   p = (GLint) plane - (GLint) GL_CLIP_PLANE0;
+   if (p<0 || p>=MAX_CLIP_PLANES) {
+      gl_error( ctx, GL_INVALID_ENUM, "glClipPlane" );
+      return;
+   }
+
+   /*
+    * The equation is transformed by the transpose of the inverse of the
+    * current modelview matrix and stored in the resulting eye coordinates.
+    *
+    * KW: Eqn is then transformed to the current clip space, where user
+    * clipping now takes place.  The clip-space equations are recalculated
+    * whenever the projection matrix changes.
+    */
+   if (ctx->ModelView.flags & MAT_DIRTY_ALL_OVER) {
+      gl_matrix_analyze( &ctx->ModelView );
+   }
+   gl_transform_vector( ctx->Transform.EyeUserPlane[p], equation,
+                       ctx->ModelView.inv );
+
+
+   if (ctx->Transform.ClipEnabled[p]) {
+      ctx->NewState |= NEW_USER_CLIP;
+
+      if (ctx->ProjectionMatrix.flags & MAT_DIRTY_ALL_OVER) {
+        gl_matrix_analyze( &ctx->ProjectionMatrix );
+      }
+      gl_transform_vector( ctx->Transform.ClipUserPlane[p], 
+                          ctx->Transform.EyeUserPlane[p], 
+                          ctx->ProjectionMatrix.inv );
+   }
+}
+
+
+void gl_update_userclip( GLcontext *ctx )
+{
+   GLuint p;
+   
+   for (p = 0 ; p < MAX_CLIP_PLANES ; p++) {
+      if (ctx->Transform.ClipEnabled[p]) {
+        gl_transform_vector( ctx->Transform.ClipUserPlane[p],
+                             ctx->Transform.EyeUserPlane[p],
+                             ctx->ProjectionMatrix.inv );
+      }
+   }
+}
+
+void gl_GetClipPlane( GLcontext* ctx, GLenum plane, GLdouble *equation )
+{
+   GLint p;
+
+   ASSERT_OUTSIDE_BEGIN_END(ctx, "glGetClipPlane");
+
+
+   p = (GLint) (plane - GL_CLIP_PLANE0);
+   if (p<0 || p>=MAX_CLIP_PLANES) {
+      gl_error( ctx, GL_INVALID_ENUM, "glGetClipPlane" );
+      return;
+   }
+
+   equation[0] = (GLdouble) ctx->Transform.EyeUserPlane[p][0];
+   equation[1] = (GLdouble) ctx->Transform.EyeUserPlane[p][1];
+   equation[2] = (GLdouble) ctx->Transform.EyeUserPlane[p][2];
+   equation[3] = (GLdouble) ctx->Transform.EyeUserPlane[p][3];
+}
+
+
+
+
+/**********************************************************************/
+/*                         View volume clipping.                      */
+/**********************************************************************/
+
+
+/*
+ * Clip a point against the view volume.
+ * Input:  v - vertex-vector describing the point to clip
+ * Return:  0 = outside view volume
+ *          1 = inside view volume
+ */
+GLuint gl_viewclip_point( const GLfloat v[] )
+{
+   if (   v[0] > v[3] || v[0] < -v[3]
+       || v[1] > v[3] || v[1] < -v[3]
+       || v[2] > v[3] || v[2] < -v[3] ) {
+      return 0;
+   }
+   else {
+      return 1;
+   }
+}
+
+/*
+ * Clip a point against the user clipping planes.
+ * Input:  v - vertex-vector describing the point to clip.
+ * Return:  0 = point was clipped
+ *          1 = point not clipped
+ */
+GLuint gl_userclip_point( GLcontext* ctx, const GLfloat v[] )
+{
+   GLuint p;
+
+   for (p=0;p<MAX_CLIP_PLANES;p++) {
+      if (ctx->Transform.ClipEnabled[p]) {
+        GLfloat dot = v[0] * ctx->Transform.ClipUserPlane[p][0]
+                    + v[1] * ctx->Transform.ClipUserPlane[p][1]
+                    + v[2] * ctx->Transform.ClipUserPlane[p][2]
+                    + v[3] * ctx->Transform.ClipUserPlane[p][3];
+         if (dot < 0.0F) {
+            return 0;
+         }
+      }
+   }
+
+   return 1;
+}
+
+
+
+
+clip_poly_func gl_poly_clip_tab[5];
+clip_line_func gl_line_clip_tab[5];
+
+
+#if defined(__i386__)
+#define NEGATIVE(x) ((*(int *)&x)<0)
+#else
+#define NEGATIVE(x) (x < 0)
+#endif
+
+#define W(i) coord[i][3]
+#define Z(i) coord[i][2]
+#define Y(i) coord[i][1]
+#define X(i) coord[i][0]
+#define SIZE 4
+#define TAG(x) x##_4
+#include "clip_funcs.h"
+
+
+#define W(i) 1.0
+#define Z(i) coord[i][2]
+#define Y(i) coord[i][1]
+#define X(i) coord[i][0]
+#define SIZE 3
+#define TAG(x) x##_3
+#include "clip_funcs.h"
+
+#define W(i) 1.0
+#define Z(i) 0.0
+#define Y(i) coord[i][1]
+#define X(i) coord[i][0]
+#define SIZE 2
+#define TAG(x) x##_2
+#include "clip_funcs.h"
+
+#define USER_CLIPTEST(NAME, SZ)                                                \
+static void NAME( struct vertex_buffer *VB )                           \
+{                                                                      \
+   GLcontext *ctx = VB->ctx;                                           \
+   GLubyte *clipMask = VB->ClipMask;                                   \
+   GLubyte *userClipMask = VB->UserClipMask;                           \
+   GLuint start = VB->Start;                                           \
+   GLuint count = VB->Count;                                           \
+   GLuint p, i;                                                                \
+   GLubyte bit;                                                                \
+                                                                       \
+                                                                       \
+   for (bit = 1, p = 0; p < MAX_CLIP_PLANES ; p++, bit *=2)            \
+      if (ctx->Transform.ClipEnabled[p]) {                             \
+        GLuint nr = 0;                                                 \
+        const GLfloat a = ctx->Transform.ClipUserPlane[p][0];          \
+        const GLfloat b = ctx->Transform.ClipUserPlane[p][1];          \
+        const GLfloat c = ctx->Transform.ClipUserPlane[p][2];          \
+        const GLfloat d = ctx->Transform.ClipUserPlane[p][3];          \
+         GLfloat *coord = VB->ClipPtr->start;                          \
+         GLuint stride = VB->ClipPtr->stride;                          \
+                                                                       \
+        for (i = start ; i < count ; i++, STRIDE_F(coord, stride)) {   \
+           GLfloat dp = coord[0] * a + coord[1] * b;                   \
+           if (SZ > 2) dp += coord[2] * c;                             \
+           if (SZ > 3) dp += coord[3] * d; else dp += d;               \
+                                                                       \
+           if (dp < 0) {                                               \
+              clipMask[i] |= CLIP_USER_BIT;                            \
+              userClipMask[i] |= bit;                                  \
+              nr++;                                                    \
+           }                                                           \
+        }                                                              \
+                                                                       \
+        if (nr > 0) {                                                  \
+           VB->ClipOrMask |= CLIP_USER_BIT;                            \
+           VB->CullMode |= CLIP_MASK_ACTIVE;                           \
+           if (nr == count - start) {                                  \
+              VB->ClipAndMask |= CLIP_USER_BIT;                        \
+              VB->Culled = 1;                                          \
+              return;                                                  \
+           }                                                           \
+        }                                                              \
+      }                                                                        \
+}
+
+
+USER_CLIPTEST(userclip2, 2)                   
+USER_CLIPTEST(userclip3, 3)                   
+USER_CLIPTEST(userclip4, 4)                   
+
+static void (*(usercliptab[5]))( struct vertex_buffer * ) = {
+   0,
+   0,
+   userclip2,
+   userclip3,
+   userclip4
+};
+
+void gl_user_cliptest( struct vertex_buffer *VB )
+{
+   usercliptab[VB->ClipPtr->size]( VB );
+}
+
+
+
+static clip_interp_func get_interp_func( GLcontext *ctx )
+{
+   GLuint mask = 0;
+
+   if (ctx->Visual->RGBAflag) 
+   {
+      if (ctx->Light.ShadeModel==GL_SMOOTH) 
+      {
+        mask |= CLIP_RGBA0;
+      
+        if (ctx->TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_SEPERATE_SPECULAR))
+           mask |= CLIP_RGBA1;
+      }
+
+      if (ctx->Texture.ReallyEnabled & 0xf0)
+        mask |= CLIP_TEX1|CLIP_TEX0;
+
+      if (ctx->Texture.ReallyEnabled & 0xf)
+        mask |= CLIP_TEX0;
+   }
+   else if (ctx->Light.ShadeModel==GL_SMOOTH) 
+   {
+      mask |= CLIP_INDEX0;
+      
+      if (ctx->TriangleCaps & DD_TRI_LIGHT_TWOSIDE) 
+        mask |= CLIP_INDEX1;
+   }
+
+   
+   return clip_interp_tab[mask];
+}
+
+
+void gl_update_clipmask( GLcontext *ctx )
+{
+   ctx->ClipInterpFunc = get_interp_func( ctx );
+}
+
+void gl_init_clip(void)
+{
+   init_clip_funcs_4();
+   init_clip_funcs_3();
+   init_clip_funcs_2();
+
+   clip_interp_tab[0] = clip_nil;
+   clip_interp_tab[CLIP_RGBA0] = clipRGBA0;
+   clip_interp_tab[CLIP_RGBA0|CLIP_RGBA1] = clipRGBA0_RGBA1;
+   clip_interp_tab[CLIP_TEX0|CLIP_RGBA0] = clipTEX0_RGBA0;
+   clip_interp_tab[CLIP_TEX0|CLIP_RGBA0|CLIP_RGBA1] = clipTEX0_RGBA0_RGBA1;
+   clip_interp_tab[CLIP_TEX1|CLIP_TEX0|CLIP_RGBA0] = clipTEX1_TEX0_RGBA0;
+   clip_interp_tab[CLIP_TEX1|CLIP_TEX0|CLIP_RGBA0|CLIP_RGBA1] = clipTEX1_TEX0_RGBA0_RGBA1;
+
+   clip_interp_tab[CLIP_TEX0] = clipTEX0;
+   clip_interp_tab[CLIP_TEX1|CLIP_TEX0] = clipTEX1_TEX0;
+
+   clip_interp_tab[CLIP_INDEX0] = clipINDEX0;
+   clip_interp_tab[CLIP_INDEX0|CLIP_INDEX1] = clipINDEX0_INDEX1;
+
+   clip_interp_tab[CLIP_RGBA0|CLIP_EDGE] = clipRGBA0_EDGE;
+   clip_interp_tab[CLIP_RGBA0|CLIP_RGBA1|CLIP_EDGE] = clipRGBA0_RGBA1_EDGE;
+   clip_interp_tab[CLIP_TEX0|CLIP_RGBA0|CLIP_EDGE] = clipTEX0_RGBA0_EDGE;
+   clip_interp_tab[CLIP_TEX0|CLIP_RGBA0|CLIP_RGBA1|CLIP_EDGE] = clipTEX0_RGBA0_RGBA1_EDGE;
+   clip_interp_tab[CLIP_TEX1|CLIP_TEX0|CLIP_RGBA0|CLIP_EDGE] = clipTEX1_TEX0_RGBA0_EDGE;
+   clip_interp_tab[CLIP_TEX1|CLIP_TEX0|CLIP_RGBA0|CLIP_RGBA1|CLIP_EDGE] = clipTEX1_TEX0_RGBA0_RGBA1_EDGE;
+   clip_interp_tab[CLIP_INDEX0|CLIP_EDGE] = clipINDEX0_EDGE;
+   clip_interp_tab[CLIP_INDEX0|CLIP_INDEX1|CLIP_EDGE] = clipINDEX0_INDEX1_EDGE;
+}
+
diff --git a/src/mesa/main/clip.h b/src/mesa/main/clip.h
new file mode 100644 (file)
index 0000000..03e09ca
--- /dev/null
@@ -0,0 +1,105 @@
+/* $Id: clip.h,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+#ifndef CLIP_H
+#define CLIP_H
+
+
+#include "types.h"
+
+
+
+#ifdef DEBUG
+#  define GL_VIEWCLIP_POINT( V )   gl_viewclip_point( V )
+#else
+#  define GL_VIEWCLIP_POINT( V )                       \
+     (    (V)[0] <= (V)[3] && (V)[0] >= -(V)[3]                \
+       && (V)[1] <= (V)[3] && (V)[1] >= -(V)[3]                \
+       && (V)[2] <= (V)[3] && (V)[2] >= -(V)[3] )
+#endif
+
+
+
+typedef GLuint (*clip_line_func)( struct vertex_buffer *VB, 
+                                 GLuint *i, GLuint *j,
+                                 GLubyte mask);
+typedef GLuint (*clip_poly_func)( struct vertex_buffer *VB,
+                                 GLuint n, GLuint vlist[],
+                                 GLubyte mask );
+
+
+extern clip_poly_func gl_poly_clip_tab[5];
+extern clip_line_func gl_line_clip_tab[5];
+
+extern void gl_init_clip(void);
+
+
+extern GLuint gl_viewclip_point( const GLfloat v[] );
+
+
+
+extern GLuint gl_userclip_point( GLcontext* ctx, const GLfloat v[] );
+
+
+extern void gl_user_cliptest( struct vertex_buffer *VB );
+
+
+extern void gl_ClipPlane( GLcontext* ctx,
+                          GLenum plane, const GLfloat *equation );
+
+extern void gl_GetClipPlane( GLcontext* ctx,
+                             GLenum plane, GLdouble *equation );
+
+
+/*
+ * Clipping interpolation functions
+ */
+
+extern void gl_clip_interp_all( struct vertex_buffer *VB, 
+                                GLuint dst, GLfloat t, GLuint in, GLuint out );
+
+extern void gl_clip_interp_color_tex( struct vertex_buffer *VB,
+                                GLuint dst, GLfloat t, GLuint in, GLuint out );
+
+extern void gl_clip_interp_tex( struct vertex_buffer *VB, 
+                                GLuint dst, GLfloat t, GLuint in, GLuint out );
+
+extern void gl_clip_interp_color( struct vertex_buffer *VB,
+                                GLuint dst, GLfloat t, GLuint in, GLuint out );
+
+extern void gl_clip_interp_none( struct vertex_buffer *VB,
+                                GLuint dst, GLfloat t, GLuint in, GLuint out );
+
+
+extern void gl_update_userclip( GLcontext *ctx );
+
+extern void gl_update_clipmask( GLcontext *ctx );
+
+#endif
diff --git a/src/mesa/main/colortab.c b/src/mesa/main/colortab.c
new file mode 100644 (file)
index 0000000..22d785b
--- /dev/null
@@ -0,0 +1,312 @@
+/* $Id: colortab.c,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include "colortab.h"
+#include "context.h"
+#include "macros.h"
+#ifdef XFree86Server
+#include "GL/xf86glx.h"
+#endif
+#endif
+
+
+
+/*
+ * Return GL_TRUE if k is a power of two, else return GL_FALSE.
+ */
+static GLboolean power_of_two( GLint k )
+{
+   GLint i, m = 1;
+   for (i=0; i<32; i++) {
+      if (k == m)
+         return GL_TRUE;
+      m = m << 1;
+   }
+   return GL_FALSE;
+}
+
+
+static GLint decode_internal_format( GLint format )
+{
+   switch (format) {
+      case GL_ALPHA:
+      case GL_ALPHA4:
+      case GL_ALPHA8:
+      case GL_ALPHA12:
+      case GL_ALPHA16:
+         return GL_ALPHA;
+      case 1:
+      case GL_LUMINANCE:
+      case GL_LUMINANCE4:
+      case GL_LUMINANCE8:
+      case GL_LUMINANCE12:
+      case GL_LUMINANCE16:
+         return GL_LUMINANCE;
+      case 2:
+      case GL_LUMINANCE_ALPHA:
+      case GL_LUMINANCE4_ALPHA4:
+      case GL_LUMINANCE6_ALPHA2:
+      case GL_LUMINANCE8_ALPHA8:
+      case GL_LUMINANCE12_ALPHA4:
+      case GL_LUMINANCE12_ALPHA12:
+      case GL_LUMINANCE16_ALPHA16:
+         return GL_LUMINANCE_ALPHA;
+      case GL_INTENSITY:
+      case GL_INTENSITY4:
+      case GL_INTENSITY8:
+      case GL_INTENSITY12:
+      case GL_INTENSITY16:
+         return GL_INTENSITY;
+      case 3:
+      case GL_RGB:
+      case GL_R3_G3_B2:
+      case GL_RGB4:
+      case GL_RGB5:
+      case GL_RGB8:
+      case GL_RGB10:
+      case GL_RGB12:
+      case GL_RGB16:
+         return GL_RGB;
+      case 4:
+      case GL_RGBA:
+      case GL_RGBA2:
+      case GL_RGBA4:
+      case GL_RGB5_A1:
+      case GL_RGBA8:
+      case GL_RGB10_A2:
+      case GL_RGBA12:
+      case GL_RGBA16:
+         return GL_RGBA;
+      default:
+         return -1;  /* error */
+   }
+}
+
+
+void gl_ColorTable( GLcontext *ctx, GLenum target,
+                    GLenum internalFormat, struct gl_image *table )
+{
+   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+   struct gl_texture_object *texObj;
+   GLboolean proxy = GL_FALSE;
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glColorTable");
+
+   if (decode_internal_format(internalFormat) < 0) {
+      gl_error( ctx, GL_INVALID_ENUM, "glColorTable(internalFormat)" );
+      return;
+   }
+
+   switch (target) {
+      case GL_TEXTURE_1D:
+         texObj = texUnit->CurrentD[1];
+         break;
+      case GL_TEXTURE_2D:
+         texObj = texUnit->CurrentD[2];
+         break;
+      case GL_TEXTURE_3D_EXT:
+         texObj = texUnit->CurrentD[3];
+         break;
+      case GL_PROXY_TEXTURE_1D:
+         texObj = ctx->Texture.Proxy1D;
+         proxy = GL_TRUE;
+         break;
+      case GL_PROXY_TEXTURE_2D:
+         texObj = ctx->Texture.Proxy2D;
+         proxy = GL_TRUE;
+         break;
+      case GL_PROXY_TEXTURE_3D_EXT:
+         texObj = ctx->Texture.Proxy3D;
+         proxy = GL_TRUE;
+         break;
+      case GL_SHARED_TEXTURE_PALETTE_EXT:
+         texObj = NULL;
+         break;
+      default:
+         gl_error(ctx, GL_INVALID_ENUM, "glColorTableEXT(target)");
+         return;
+   }
+
+   /* internalformat = just like glTexImage */
+
+   if (table->Width < 1 || table->Width > MAX_TEXTURE_PALETTE_SIZE
+       || !power_of_two(table->Width)) {
+      gl_error(ctx, GL_INVALID_VALUE, "glColorTableEXT(width)");
+      if (proxy) {
+         texObj->PaletteSize = 0;
+         texObj->PaletteIntFormat = (GLenum) 0;
+         texObj->PaletteFormat = (GLenum) 0;
+      }
+      return;
+   }
+
+   if (texObj) {
+      /* per-texture object palette */
+      texObj->PaletteSize = table->Width;
+      texObj->PaletteIntFormat = internalFormat;
+      texObj->PaletteFormat = (GLenum) decode_internal_format(internalFormat);
+      if (!proxy) {
+         MEMCPY(texObj->Palette, table->Data, table->Width*table->Components);
+         if (ctx->Driver.UpdateTexturePalette) {
+            (*ctx->Driver.UpdateTexturePalette)( ctx, texObj );
+         }
+      }
+   }
+   else {
+      /* shared texture palette */
+      ctx->Texture.PaletteSize = table->Width;
+      ctx->Texture.PaletteIntFormat = internalFormat;
+      ctx->Texture.PaletteFormat = (GLenum) decode_internal_format(internalFormat);
+      MEMCPY(ctx->Texture.Palette, table->Data, table->Width*table->Components);
+      if (ctx->Driver.UpdateTexturePalette) {
+         (*ctx->Driver.UpdateTexturePalette)( ctx, NULL );
+      }
+   }
+}
+
+
+
+void gl_ColorSubTable( GLcontext *ctx, GLenum target,
+                       GLsizei start, struct gl_image *data )
+{
+   /* XXX TODO */
+   gl_problem(ctx, "glColorSubTableEXT not implemented");
+   (void) target;
+   (void) start;
+   (void) data;
+}
+
+
+
+void gl_GetColorTable( GLcontext *ctx, GLenum target, GLenum format,
+                       GLenum type, GLvoid *table )
+{
+   ASSERT_OUTSIDE_BEGIN_END(ctx, "glGetBooleanv");
+
+   switch (target) {
+      case GL_TEXTURE_1D:
+         break;
+      case GL_TEXTURE_2D:
+         break;
+      case GL_TEXTURE_3D_EXT:
+         break;
+      case GL_SHARED_TEXTURE_PALETTE_EXT:
+         break;
+      default:
+         gl_error(ctx, GL_INVALID_ENUM, "glGetColorTableEXT(target)");
+         return;
+   }
+
+   gl_problem(ctx, "glGetColorTableEXT not implemented!");
+   (void) format;
+   (void) type;
+   (void) table;
+}
+
+
+
+void gl_GetColorTableParameterfv( GLcontext *ctx, GLenum target,
+                                  GLenum pname, GLfloat *params )
+{
+   GLint iparams[10];
+
+   gl_GetColorTableParameteriv( ctx, target, pname, iparams );
+   *params = (GLfloat) iparams[0];
+}
+
+
+
+void gl_GetColorTableParameteriv( GLcontext *ctx, GLenum target,
+                                  GLenum pname, GLint *params )
+{
+   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+   struct gl_texture_object *texObj;
+
+   ASSERT_OUTSIDE_BEGIN_END(ctx, "glGetColorTableParameter");
+
+   switch (target) {
+      case GL_TEXTURE_1D:
+         texObj = texUnit->CurrentD[1];
+         break;
+      case GL_TEXTURE_2D:
+         texObj = texUnit->CurrentD[2];
+         break;
+      case GL_TEXTURE_3D_EXT:
+         texObj = texUnit->CurrentD[3];
+         break;
+      case GL_SHARED_TEXTURE_PALETTE_EXT:
+         texObj = NULL;
+         break;
+      default:
+         gl_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameter(target)");
+         return;
+   }
+
+   switch (pname) {
+      case GL_COLOR_TABLE_FORMAT_EXT:
+         if (texObj)
+            *params = texObj->PaletteIntFormat;
+         else
+            *params = ctx->Texture.PaletteIntFormat;
+         break;
+      case GL_COLOR_TABLE_WIDTH_EXT:
+         if (texObj)
+            *params = texObj->PaletteSize;
+         else
+            *params = ctx->Texture.PaletteSize;
+         break;
+      case GL_COLOR_TABLE_RED_SIZE_EXT:
+         *params = 8;
+         break;
+      case GL_COLOR_TABLE_GREEN_SIZE_EXT:
+         *params = 8;
+         break;
+      case GL_COLOR_TABLE_BLUE_SIZE_EXT:
+         *params = 8;
+         break;
+      case GL_COLOR_TABLE_ALPHA_SIZE_EXT:
+         *params = 8;
+         break;
+      case GL_COLOR_TABLE_LUMINANCE_SIZE_EXT:
+         *params = 8;
+         break;
+      case GL_COLOR_TABLE_INTENSITY_SIZE_EXT:
+         *params = 8;
+         break;
+      default:
+         gl_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameter" );
+         return;
+   }
+}
+
+
diff --git a/src/mesa/main/colortab.h b/src/mesa/main/colortab.h
new file mode 100644 (file)
index 0000000..8e75f13
--- /dev/null
@@ -0,0 +1,55 @@
+/* $Id: colortab.h,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+#ifndef COLORTAB_H
+#define COLORTAB_H
+
+
+#include "types.h"
+
+
+extern void gl_ColorTable( GLcontext *ctx, GLenum target,
+                           GLenum internalformat,
+                           struct gl_image *table );
+
+extern void gl_ColorSubTable( GLcontext *ctx, GLenum target,
+                              GLsizei start, struct gl_image *data );
+
+extern void gl_GetColorTable( GLcontext *ctx, GLenum target, GLenum format,
+                              GLenum type, GLvoid *table );
+
+extern void gl_GetColorTableParameterfv( GLcontext *ctx, GLenum target,
+                                         GLenum pname, GLfloat *params );
+
+extern void gl_GetColorTableParameteriv( GLcontext *ctx, GLenum target,
+                                         GLenum pname, GLint *params );
+
+
+#endif
diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h
new file mode 100644 (file)
index 0000000..0b35aba
--- /dev/null
@@ -0,0 +1,222 @@
+/* $Id: config.h,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+
+/*
+ * Tunable configuration parameters.
+ */
+
+
+
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#ifdef HAVE_CONFIG_H
+#include "conf.h"
+#endif
+
+/*
+ *
+ * OpenGL implementation limits
+ *
+ */
+
+
+/* Maximum modelview matrix stack depth: */
+#define MAX_MODELVIEW_STACK_DEPTH 32
+
+/* Maximum projection matrix stack depth: */
+#define MAX_PROJECTION_STACK_DEPTH 32
+
+/* Maximum texture matrix stack depth: */
+#define MAX_TEXTURE_STACK_DEPTH 10
+
+/* Maximum attribute stack depth: */
+#define MAX_ATTRIB_STACK_DEPTH 16
+
+/* Maximum client attribute stack depth: */
+#define MAX_CLIENT_ATTRIB_STACK_DEPTH 16
+
+/* Maximum recursion depth of display list calls: */
+#define MAX_LIST_NESTING 64
+
+/* Maximum number of lights: */
+#define MAX_LIGHTS 8
+
+/* Maximum user-defined clipping planes: */
+#define MAX_CLIP_PLANES 6
+
+/* Maximum pixel map lookup table size: */
+#define MAX_PIXEL_MAP_TABLE 256
+
+/* Number of auxillary color buffers: */
+#define NUM_AUX_BUFFERS 0
+
+/* Maximum order (degree) of curves: */
+#ifdef AMIGA
+#   define MAX_EVAL_ORDER 12
+#else
+#   define MAX_EVAL_ORDER 30
+#endif
+
+/* Maximum Name stack depth */
+#define MAX_NAME_STACK_DEPTH 64
+
+/* Min and Max point sizes and granularity */
+#define MIN_POINT_SIZE 1.0
+#define MAX_POINT_SIZE 10.0
+#define POINT_SIZE_GRANULARITY 0.1
+
+/* Min and Max line widths and granularity */
+#define MIN_LINE_WIDTH 1.0
+#define MAX_LINE_WIDTH 10.0
+#define LINE_WIDTH_GRANULARITY 1.0
+
+/* Max texture palette size */
+#define MAX_TEXTURE_PALETTE_SIZE 256
+
+/* Number of texture levels */
+#define MAX_TEXTURE_LEVELS 12
+
+/* Number of texture units - GL_ARB_multitexture */
+#define MAX_TEXTURE_UNITS 2
+
+/* Maximum viewport size: */
+#define MAX_WIDTH 1600
+#define MAX_HEIGHT 1200
+
+/* Maxmimum size for CVA.  May be overridden by the drivers.  */
+#define MAX_ARRAY_LOCK_SIZE 3000
+
+
+/*
+ *
+ * Mesa-specific parameters
+ *
+ */
+
+
+/*
+ * Bits per accumulation buffer color component:  8 or 16
+ */
+#define ACCUM_BITS 16
+
+
+#ifdef MESAD3D
+   /* Mesa / Direct3D driver only */
+   extern float g_DepthScale, g_MaxDepth;
+#  define DEPTH_BITS   32
+#  define DEPTH_SCALE  g_DepthScale
+#  define MAX_DEPTH    g_MaxDepth
+#else
+   /*
+    * Bits per depth buffer value:  16 or 32
+    */
+#  define DEPTH_BITS 16
+#  if DEPTH_BITS==16
+#     define MAX_DEPTH 0xffff
+#     define DEPTH_SCALE 65535.0F
+#  elif DEPTH_BITS==32
+#     define MAX_DEPTH 0x3fffffff
+#     define DEPTH_SCALE ((GLfloat) MAX_DEPTH)
+#  else
+#     error "illegal number of depth bits"
+#  endif
+#endif
+
+
+/*
+ * Bits per stencil value:  8
+ */
+#define STENCIL_BITS 8
+
+
+/*
+ * Bits per color channel (must be 8 at this time!)
+ */
+#define CHAN_BITS 8
+
+
+
+/*
+ * Color channel component order
+ * (changes will almost certainly cause problems at this time)
+ */
+#define RCOMP 0
+#define GCOMP 1
+#define BCOMP 2
+#define ACOMP 3
+
+
+
+/* Vertex buffer size.  KW: no restrictions on the divisibility of
+ * this number, though things may go better for you if you choose a
+ * value of 12n + 3.  
+ */
+
+#define VB_START  3
+
+#if defined(FX) && !defined(MITS)
+#  define VB_MAX 72 + VB_START  /* better performance */
+#else
+#  define VB_MAX 480 + VB_START
+#endif
+
+/*
+ * Actual vertex buffer size.
+ *
+ * Arrays must also accomodate new vertices from clipping, and
+ * potential overflow from primitives which don't fit into neatly into
+ * VB_MAX vertices.  (This only happens when mixed primitives are
+ * sharing the vb).  
+ */
+#define VB_MAX_CLIPPED_VERTS (2 * (6 + MAX_CLIP_PLANES))
+#define VB_SIZE  (VB_MAX + VB_MAX_CLIPPED_VERTS)
+
+
+/*
+ *
+ * For X11 driver only:
+ *
+ */
+
+/*
+ * When defined, use 6x6x6 dithering instead of 5x9x5.
+ * 5x9x5 better for general colors, 6x6x6 better for grayscale.
+ */
+/*#define DITHER666*/
+
+
+
+typedef struct gl_context GLcontext;
+
+extern void gl_read_config_file( struct gl_context *ctx );
+
+#endif
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
new file mode 100644 (file)
index 0000000..55c7467
--- /dev/null
@@ -0,0 +1,2388 @@
+/* $Id: context.c,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ *
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/*
+ * If multi-threading is enabled (-DTHREADS) then each thread has it's
+ * own rendering context.  A thread obtains the pointer to its GLcontext
+ * with the gl_get_thread_context() function.  Otherwise, the global
+ * pointer, CC, points to the current context used by all threads in
+ * the address space.
+ */
+
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <assert.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "accum.h"
+#include "alphabuf.h"
+#include "api.h"
+#include "clip.h"
+#include "context.h"
+#include "cva.h"
+#include "depth.h"
+#include "dlist.h"
+#include "eval.h"
+#include "enums.h"
+#include "fog.h"
+#include "hash.h"
+#include "light.h"
+#include "lines.h"
+#include "dlist.h"
+#include "macros.h"
+#include "matrix.h"
+#include "mmath.h"
+#include "pb.h"
+#include "pipeline.h"
+#include "points.h"
+#include "pointers.h"
+#include "quads.h"
+#include "shade.h"
+#include "simple_list.h"
+#include "stencil.h"
+#include "stages.h"
+#include "triangle.h"
+#include "translate.h"
+#include "teximage.h"
+#include "texobj.h"
+#include "texstate.h"
+#include "texture.h"
+#include "types.h"
+#include "varray.h"
+#include "vb.h"
+#include "vbcull.h"
+#include "vbfill.h"
+#include "vbrender.h"
+#include "vbxform.h"
+#include "xform.h"
+#ifdef XFree86Server
+#include "GL/xf86glx.h"
+#endif
+#endif
+
+
+
+/**********************************************************************/
+/*****                  Context and Thread management             *****/
+/**********************************************************************/
+
+
+#ifdef THREADS
+
+#include "mthreads.h" /* Mesa platform independent threads interface */
+
+static MesaTSD mesa_ctx_tsd;
+
+static void mesa_ctx_thread_init() {
+  MesaInitTSD(&mesa_ctx_tsd);
+}
+
+GLcontext *gl_get_thread_context( void ) {
+  return (GLcontext *) MesaGetTSD(&mesa_ctx_tsd);
+}
+
+static void set_thread_context( GLcontext *ctx ) {
+  MesaSetTSD(&mesa_ctx_tsd, ctx, mesa_ctx_thread_init);
+}
+
+
+#else
+
+/* One Current Context pointer for all threads in the address space */
+GLcontext *CC = NULL;
+struct immediate *CURRENT_INPUT = NULL;
+
+#endif /*THREADS*/
+
+
+
+
+/**********************************************************************/
+/*****                   Profiling functions                      *****/
+/**********************************************************************/
+
+#ifdef PROFILE
+
+#include <sys/times.h>
+#include <sys/param.h>
+
+
+/*
+ * Return system time in seconds.
+ * NOTE:  this implementation may not be very portable!
+ */
+GLdouble gl_time( void )
+{
+   static GLdouble prev_time = 0.0;
+   static GLdouble time;
+   struct tms tm;
+   clock_t clk;
+
+   clk = times(&tm);
+
+#ifdef CLK_TCK
+   time = (double)clk / (double)CLK_TCK;
+#else
+   time = (double)clk / (double)HZ;
+#endif
+
+   if (time>prev_time) {
+      prev_time = time;
+      return time;
+   }
+   else {
+      return prev_time;
+   }
+}
+
+/*
+ * Reset the timing/profiling counters
+ */
+static void init_timings( GLcontext *ctx )
+{
+   ctx->BeginEndCount = 0;
+   ctx->BeginEndTime = 0.0;
+   ctx->VertexCount = 0;
+   ctx->VertexTime = 0.0;
+   ctx->PointCount = 0;
+   ctx->PointTime = 0.0;
+   ctx->LineCount = 0;
+   ctx->LineTime = 0.0;
+   ctx->PolygonCount = 0;
+   ctx->PolygonTime = 0.0;
+   ctx->ClearCount = 0;
+   ctx->ClearTime = 0.0;
+   ctx->SwapCount = 0;
+   ctx->SwapTime = 0.0;
+}
+
+
+/*
+ * Print the accumulated timing/profiling data.
+ */
+static void print_timings( GLcontext *ctx )
+{
+   GLdouble beginendrate;
+   GLdouble vertexrate;
+   GLdouble pointrate;
+   GLdouble linerate;
+   GLdouble polygonrate;
+   GLdouble overhead;
+   GLdouble clearrate;
+   GLdouble swaprate;
+   GLdouble avgvertices;
+
+   if (ctx->BeginEndTime>0.0) {
+      beginendrate = ctx->BeginEndCount / ctx->BeginEndTime;
+   }
+   else {
+      beginendrate = 0.0;
+   }
+   if (ctx->VertexTime>0.0) {
+      vertexrate = ctx->VertexCount / ctx->VertexTime;
+   }
+   else {
+      vertexrate = 0.0;
+   }
+   if (ctx->PointTime>0.0) {
+      pointrate = ctx->PointCount / ctx->PointTime;
+   }
+   else {
+      pointrate = 0.0;
+   }
+   if (ctx->LineTime>0.0) {
+      linerate = ctx->LineCount / ctx->LineTime;
+   }
+   else {
+      linerate = 0.0;
+   }
+   if (ctx->PolygonTime>0.0) {
+      polygonrate = ctx->PolygonCount / ctx->PolygonTime;
+   }
+   else {
+      polygonrate = 0.0;
+   }
+   if (ctx->ClearTime>0.0) {
+      clearrate = ctx->ClearCount / ctx->ClearTime;
+   }
+   else {
+      clearrate = 0.0;
+   }
+   if (ctx->SwapTime>0.0) {
+      swaprate = ctx->SwapCount / ctx->SwapTime;
+   }
+   else {
+      swaprate = 0.0;
+   }
+
+   if (ctx->BeginEndCount>0) {
+      avgvertices = (GLdouble) ctx->VertexCount / (GLdouble) ctx->BeginEndCount;
+   }
+   else {
+      avgvertices = 0.0;
+   }
+
+   overhead = ctx->BeginEndTime - ctx->VertexTime - ctx->PointTime
+              - ctx->LineTime - ctx->PolygonTime;
+
+
+   printf("                          Count   Time (s)    Rate (/s) \n");
+   printf("--------------------------------------------------------\n");
+   printf("glBegin/glEnd           %7d  %8.3f   %10.3f\n",
+          ctx->BeginEndCount, ctx->BeginEndTime, beginendrate);
+   printf("  vertexes transformed  %7d  %8.3f   %10.3f\n",
+          ctx->VertexCount, ctx->VertexTime, vertexrate );
+   printf("  points rasterized     %7d  %8.3f   %10.3f\n",
+          ctx->PointCount, ctx->PointTime, pointrate );
+   printf("  lines rasterized      %7d  %8.3f   %10.3f\n",
+          ctx->LineCount, ctx->LineTime, linerate );
+   printf("  polygons rasterized   %7d  %8.3f   %10.3f\n",
+          ctx->PolygonCount, ctx->PolygonTime, polygonrate );
+   printf("  overhead                       %8.3f\n", overhead );
+   printf("glClear                 %7d  %8.3f   %10.3f\n",
+          ctx->ClearCount, ctx->ClearTime, clearrate );
+   printf("SwapBuffers             %7d  %8.3f   %10.3f\n",
+          ctx->SwapCount, ctx->SwapTime, swaprate );
+   printf("\n");
+
+   printf("Average number of vertices per begin/end: %8.3f\n", avgvertices );
+}
+#endif
+
+
+
+
+
+/**********************************************************************/
+/*****       Context allocation, initialization, destroying       *****/
+/**********************************************************************/
+
+
+/*
+ * This function just calls all the various one-time-init functions in Mesa.
+ */
+static void one_time_init( void )
+{
+   static GLboolean alreadyCalled = GL_FALSE;
+   if (!alreadyCalled) {
+      gl_init_clip();
+      gl_init_eval();
+      gl_init_fog();
+      gl_init_math();
+      gl_init_lists();
+      gl_init_shade();
+      gl_init_texture();
+      gl_init_transformation();
+      gl_init_translate();
+      gl_init_vbrender();
+      gl_init_vbxform();
+      alreadyCalled = GL_TRUE;
+   }
+#if defined(DEBUG) && defined(__DATE__) && defined(__TIME__)
+   fprintf(stderr, "Mesa DEBUG build %s %s\n", __DATE__, __TIME__);
+#endif
+}
+
+
+/*
+ * Allocate and initialize a shared context state structure.
+ */
+static struct gl_shared_state *alloc_shared_state( void )
+{
+   GLuint i;
+   struct gl_shared_state *ss;
+   GLboolean outOfMemory;
+
+   ss = (struct gl_shared_state*) calloc( 1, sizeof(struct gl_shared_state) );
+   if (!ss)
+      return NULL;
+
+   ss->DisplayList = NewHashTable();
+
+   ss->TexObjects = NewHashTable();
+
+   /* Default Texture objects */
+   outOfMemory = GL_FALSE;
+   for (i=0;i<MAX_TEXTURE_UNITS;i++) {
+      GLuint d;
+      for (d = 1 ; d <= 3 ; d++) {
+        ss->DefaultD[d][i] = gl_alloc_texture_object(ss, 0, d);
+        if (!ss->DefaultD[d][i]) {
+           outOfMemory = GL_TRUE;
+           break;
+        }
+        ss->DefaultD[d][i]->RefCount++; /* don't free if not in use */
+      }
+   }
+
+   if (!ss->DisplayList || !ss->TexObjects || outOfMemory) {
+      /* Ran out of memory at some point.  Free everything and return NULL */
+      if (ss->DisplayList)
+         DeleteHashTable(ss->DisplayList);
+      if (ss->TexObjects)
+         DeleteHashTable(ss->TexObjects);
+      for (i=0;i<MAX_TEXTURE_UNITS;i++) {
+         if (ss->DefaultD[1][i])
+            gl_free_texture_object(ss, ss->DefaultD[1][i]);
+         if (ss->DefaultD[2][i])
+            gl_free_texture_object(ss, ss->DefaultD[2][i]);
+         if (ss->DefaultD[3][i])
+            gl_free_texture_object(ss, ss->DefaultD[3][i]);
+      }
+      free(ss);
+      return NULL;
+   }
+   else {
+      return ss;
+   }
+}
+
+
+/*
+ * Deallocate a shared state context and all children structures.
+ */
+static void free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
+{
+   /* Free display lists */
+   while (1) {
+      GLuint list = HashFirstEntry(ss->DisplayList);
+      if (list) {
+         gl_destroy_list(ctx, list);
+      }
+      else {
+         break;
+      }
+   }
+   DeleteHashTable(ss->DisplayList);
+
+   /* Free texture objects */
+   while (ss->TexObjectList)
+   {
+      if (ctx->Driver.DeleteTexture)
+         (*ctx->Driver.DeleteTexture)( ctx, ss->TexObjectList );
+      /* this function removes from linked list too! */
+      gl_free_texture_object(ss, ss->TexObjectList);
+   }
+   DeleteHashTable(ss->TexObjects);
+
+   free(ss);
+}
+
+
+
+
+
+
+/*
+ * Initialize the nth light.  Note that the defaults for light 0 are
+ * different than the other lights.
+ */
+static void init_light( struct gl_light *l, GLuint n )
+{
+   make_empty_list( l );
+
+   ASSIGN_4V( l->Ambient, 0.0, 0.0, 0.0, 1.0 );
+   if (n==0) {
+      ASSIGN_4V( l->Diffuse, 1.0, 1.0, 1.0, 1.0 );
+      ASSIGN_4V( l->Specular, 1.0, 1.0, 1.0, 1.0 );
+   }
+   else {
+      ASSIGN_4V( l->Diffuse, 0.0, 0.0, 0.0, 1.0 );
+      ASSIGN_4V( l->Specular, 0.0, 0.0, 0.0, 1.0 );
+   }
+   ASSIGN_4V( l->EyePosition, 0.0, 0.0, 1.0, 0.0 );
+   ASSIGN_3V( l->EyeDirection, 0.0, 0.0, -1.0 );
+   l->SpotExponent = 0.0;
+   gl_compute_spot_exp_table( l );
+   l->SpotCutoff = 180.0;
+   l->CosCutoff = 0.0;         /* KW: -ve values not admitted */
+   l->ConstantAttenuation = 1.0;
+   l->LinearAttenuation = 0.0;
+   l->QuadraticAttenuation = 0.0;
+   l->Enabled = GL_FALSE;
+}
+
+
+
+static void init_lightmodel( struct gl_lightmodel *lm )
+{
+   ASSIGN_4V( lm->Ambient, 0.2, 0.2, 0.2, 1.0 );
+   lm->LocalViewer = GL_FALSE;
+   lm->TwoSide = GL_FALSE;
+   lm->ColorControl = GL_SINGLE_COLOR;
+}
+
+
+static void init_material( struct gl_material *m )
+{
+   ASSIGN_4V( m->Ambient,  0.2, 0.2, 0.2, 1.0 );
+   ASSIGN_4V( m->Diffuse,  0.8, 0.8, 0.8, 1.0 );
+   ASSIGN_4V( m->Specular, 0.0, 0.0, 0.0, 1.0 );
+   ASSIGN_4V( m->Emission, 0.0, 0.0, 0.0, 1.0 );
+   m->Shininess = 0.0;
+   m->AmbientIndex = 0;
+   m->DiffuseIndex = 1;
+   m->SpecularIndex = 1;
+}
+
+
+
+static void init_texture_unit( GLcontext *ctx, GLuint unit )
+{
+   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+
+   texUnit->EnvMode = GL_MODULATE;
+   ASSIGN_4V( texUnit->EnvColor, 0.0, 0.0, 0.0, 0.0 );
+   texUnit->TexGenEnabled = 0;
+   texUnit->GenModeS = GL_EYE_LINEAR;
+   texUnit->GenModeT = GL_EYE_LINEAR;
+   texUnit->GenModeR = GL_EYE_LINEAR;
+   texUnit->GenModeQ = GL_EYE_LINEAR;
+   /* Yes, these plane coefficients are correct! */
+   ASSIGN_4V( texUnit->ObjectPlaneS, 1.0, 0.0, 0.0, 0.0 );
+   ASSIGN_4V( texUnit->ObjectPlaneT, 0.0, 1.0, 0.0, 0.0 );
+   ASSIGN_4V( texUnit->ObjectPlaneR, 0.0, 0.0, 0.0, 0.0 );
+   ASSIGN_4V( texUnit->ObjectPlaneQ, 0.0, 0.0, 0.0, 0.0 );
+   ASSIGN_4V( texUnit->EyePlaneS, 1.0, 0.0, 0.0, 0.0 );
+   ASSIGN_4V( texUnit->EyePlaneT, 0.0, 1.0, 0.0, 0.0 );
+   ASSIGN_4V( texUnit->EyePlaneR, 0.0, 0.0, 0.0, 0.0 );
+   ASSIGN_4V( texUnit->EyePlaneQ, 0.0, 0.0, 0.0, 0.0 );
+
+   texUnit->CurrentD[1] = ctx->Shared->DefaultD[1][unit];
+   texUnit->CurrentD[2] = ctx->Shared->DefaultD[2][unit];
+   texUnit->CurrentD[3] = ctx->Shared->DefaultD[3][unit];
+}
+
+
+static void init_fallback_arrays( GLcontext *ctx )
+{
+   struct gl_client_array *cl;
+   GLuint i;
+
+   cl = &ctx->Fallback.Normal;
+   cl->Size = 3;
+   cl->Type = GL_FLOAT;
+   cl->Stride = 0;
+   cl->StrideB = 0;
+   cl->Ptr = (void *) ctx->Current.Normal;
+   cl->Enabled = 1;
+
+   cl = &ctx->Fallback.Color;
+   cl->Size = 4;
+   cl->Type = GL_UNSIGNED_BYTE;
+   cl->Stride = 0;
+   cl->StrideB = 0;
+   cl->Ptr = (void *) ctx->Current.ByteColor;
+   cl->Enabled = 1;
+
+   cl = &ctx->Fallback.Index;
+   cl->Size = 1;
+   cl->Type = GL_UNSIGNED_INT;
+   cl->Stride = 0;
+   cl->StrideB = 0;
+   cl->Ptr = (void *) &ctx->Current.Index;
+   cl->Enabled = 1;
+
+   for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++) {
+      cl = &ctx->Fallback.TexCoord[i];
+      cl->Size = 4;
+      cl->Type = GL_FLOAT;
+      cl->Stride = 0;
+      cl->StrideB = 0;
+      cl->Ptr = (void *) ctx->Current.Texcoord[i];
+      cl->Enabled = 1;
+   }
+
+   cl = &ctx->Fallback.EdgeFlag;
+   cl->Size = 1;
+   cl->Type = GL_UNSIGNED_BYTE;
+   cl->Stride = 0;
+   cl->StrideB = 0;
+   cl->Ptr = (void *) &ctx->Current.EdgeFlag;
+   cl->Enabled = 1;
+}
+
+/* Initialize a 1-D evaluator map */
+static void init_1d_map( struct gl_1d_map *map, int n, const float *initial )
+{
+   map->Order = 1;
+   map->u1 = 0.0;
+   map->u2 = 1.0;
+   map->Points = (GLfloat *) malloc(n * sizeof(GLfloat));
+   if (map->Points) {
+      GLint i;
+      for (i=0;i<n;i++)
+         map->Points[i] = initial[i];
+   }
+   map->Retain = GL_FALSE;
+}
+
+
+/* Initialize a 2-D evaluator map */
+static void init_2d_map( struct gl_2d_map *map, int n, const float *initial )
+{
+   map->Uorder = 1;
+   map->Vorder = 1;
+   map->u1 = 0.0;
+   map->u2 = 1.0;
+   map->v1 = 0.0;
+   map->v2 = 1.0;
+   map->Points = (GLfloat *) malloc(n * sizeof(GLfloat));
+   if (map->Points) {
+      GLint i;
+      for (i=0;i<n;i++)
+         map->Points[i] = initial[i];
+   }
+   map->Retain = GL_FALSE;
+}
+
+
+
+/*
+ * Initialize a gl_context structure to default values.
+ */
+static void initialize_context( GLcontext *ctx )
+{
+   GLuint i, j;
+
+   if (ctx) {
+      /* Constants, may be overriden by device driver */
+      ctx->Const.MaxTextureLevels = MAX_TEXTURE_LEVELS;
+      ctx->Const.MaxTextureSize = 1 << (MAX_TEXTURE_LEVELS - 1);
+      ctx->Const.MaxTextureUnits = MAX_TEXTURE_UNITS;
+      ctx->Const.MaxArrayLockSize = MAX_ARRAY_LOCK_SIZE;
+
+
+      /* Modelview matrix */
+      gl_matrix_ctr( &ctx->ModelView );
+      gl_matrix_alloc_inv( &ctx->ModelView );
+
+      ctx->ModelViewStackDepth = 0;
+      for (i = 0 ; i < MAX_MODELVIEW_STACK_DEPTH ; i++) {
+        gl_matrix_ctr( &ctx->ModelViewStack[i] );
+        gl_matrix_alloc_inv( &ctx->ModelViewStack[i] );
+      }
+
+      /* Projection matrix - need inv for user clipping in clip space*/
+      gl_matrix_ctr( &ctx->ProjectionMatrix );
+      gl_matrix_alloc_inv( &ctx->ProjectionMatrix );
+
+      gl_matrix_ctr( &ctx->ModelProjectMatrix );
+      gl_matrix_ctr( &ctx->ModelProjectWinMatrix );
+      ctx->ModelProjectWinMatrixUptodate = GL_FALSE;
+
+      ctx->ProjectionStackDepth = 0;
+      ctx->NearFarStack[0][0] = 1.0; /* These values seem weird by make */
+      ctx->NearFarStack[0][1] = 0.0; /* sense mathematically. */
+
+      for (i = 0 ; i < MAX_PROJECTION_STACK_DEPTH ; i++) {
+        gl_matrix_ctr( &ctx->ProjectionStack[i] );
+        gl_matrix_alloc_inv( &ctx->ProjectionStack[i] );
+      }
+
+      /* Texture matrix */
+      for (i=0; i<MAX_TEXTURE_UNITS; i++) {
+        gl_matrix_ctr( &ctx->TextureMatrix[i] );
+        ctx->TextureStackDepth[i] = 0;
+        for (j = 0 ; j < MAX_TEXTURE_STACK_DEPTH ; j++) {
+           ctx->TextureStack[i][j].inv = 0;
+        }
+      }
+
+      /* Accumulate buffer group */
+      ASSIGN_4V( ctx->Accum.ClearColor, 0.0, 0.0, 0.0, 0.0 );
+
+      /* Color buffer group */
+      ctx->Color.IndexMask = 0xffffffff;
+      ctx->Color.ColorMask[0] = 0xff;
+      ctx->Color.ColorMask[1] = 0xff;
+      ctx->Color.ColorMask[2] = 0xff;
+      ctx->Color.ColorMask[3] = 0xff;
+      ctx->Color.SWmasking = GL_FALSE;
+      ctx->Color.ClearIndex = 0;
+      ASSIGN_4V( ctx->Color.ClearColor, 0.0, 0.0, 0.0, 0.0 );
+      ctx->Color.DrawBuffer = GL_FRONT;
+      ctx->Color.AlphaEnabled = GL_FALSE;
+      ctx->Color.AlphaFunc = GL_ALWAYS;
+      ctx->Color.AlphaRef = 0;
+      ctx->Color.BlendEnabled = GL_FALSE;
+      ctx->Color.BlendSrcRGB = GL_ONE;
+      ctx->Color.BlendDstRGB = GL_ZERO;
+      ctx->Color.BlendSrcA = GL_ONE;
+      ctx->Color.BlendDstA = GL_ZERO;
+      ctx->Color.BlendEquation = GL_FUNC_ADD_EXT;
+      ctx->Color.BlendFunc = NULL;  /* this pointer set only when needed */
+      ASSIGN_4V( ctx->Color.BlendColor, 0.0, 0.0, 0.0, 0.0 );
+      ctx->Color.IndexLogicOpEnabled = GL_FALSE;
+      ctx->Color.ColorLogicOpEnabled = GL_FALSE;
+      ctx->Color.SWLogicOpEnabled = GL_FALSE;
+      ctx->Color.LogicOp = GL_COPY;
+      ctx->Color.DitherFlag = GL_TRUE;
+      ctx->Color.MultiDrawBuffer = GL_FALSE;
+
+      /* Current group */
+      ASSIGN_4V( ctx->Current.ByteColor, 255, 255, 255, 255);
+      ctx->Current.Index = 1;
+      for (i=0; i<MAX_TEXTURE_UNITS; i++)
+         ASSIGN_4V( ctx->Current.Texcoord[i], 0.0, 0.0, 0.0, 1.0 );
+      ASSIGN_4V( ctx->Current.RasterPos, 0.0, 0.0, 0.0, 1.0 );
+      ctx->Current.RasterDistance = 0.0;
+      ASSIGN_4V( ctx->Current.RasterColor, 1.0, 1.0, 1.0, 1.0 );
+      ctx->Current.RasterIndex = 1;
+      for (i=0; i<MAX_TEXTURE_UNITS; i++)
+         ASSIGN_4V( ctx->Current.RasterMultiTexCoord[i], 0.0, 0.0, 0.0, 1.0 );
+      ctx->Current.RasterTexCoord = ctx->Current.RasterMultiTexCoord[0];
+      ctx->Current.RasterPosValid = GL_TRUE;
+      ctx->Current.EdgeFlag = GL_TRUE;
+      ASSIGN_3V( ctx->Current.Normal, 0.0, 0.0, 1.0 );
+      ctx->Current.Primitive = (GLenum) (GL_POLYGON + 1);
+
+      ctx->Current.Flag = (VERT_NORM|VERT_INDEX|VERT_RGBA|VERT_EDGE|
+                          VERT_TEX0_1|VERT_TEX1_1|VERT_MATERIAL);
+
+      init_fallback_arrays( ctx );
+
+      /* Depth buffer group */
+      ctx->Depth.Test = GL_FALSE;
+      ctx->Depth.Clear = 1.0;
+      ctx->Depth.Func = GL_LESS;
+      ctx->Depth.Mask = GL_TRUE;
+
+      /* Evaluators group */
+      ctx->Eval.Map1Color4 = GL_FALSE;
+      ctx->Eval.Map1Index = GL_FALSE;
+      ctx->Eval.Map1Normal = GL_FALSE;
+      ctx->Eval.Map1TextureCoord1 = GL_FALSE;
+      ctx->Eval.Map1TextureCoord2 = GL_FALSE;
+      ctx->Eval.Map1TextureCoord3 = GL_FALSE;
+      ctx->Eval.Map1TextureCoord4 = GL_FALSE;
+      ctx->Eval.Map1Vertex3 = GL_FALSE;
+      ctx->Eval.Map1Vertex4 = GL_FALSE;
+      ctx->Eval.Map2Color4 = GL_FALSE;
+      ctx->Eval.Map2Index = GL_FALSE;
+      ctx->Eval.Map2Normal = GL_FALSE;
+      ctx->Eval.Map2TextureCoord1 = GL_FALSE;
+      ctx->Eval.Map2TextureCoord2 = GL_FALSE;
+      ctx->Eval.Map2TextureCoord3 = GL_FALSE;
+      ctx->Eval.Map2TextureCoord4 = GL_FALSE;
+      ctx->Eval.Map2Vertex3 = GL_FALSE;
+      ctx->Eval.Map2Vertex4 = GL_FALSE;
+      ctx->Eval.AutoNormal = GL_FALSE;
+      ctx->Eval.MapGrid1un = 1;
+      ctx->Eval.MapGrid1u1 = 0.0;
+      ctx->Eval.MapGrid1u2 = 1.0;
+      ctx->Eval.MapGrid2un = 1;
+      ctx->Eval.MapGrid2vn = 1;
+      ctx->Eval.MapGrid2u1 = 0.0;
+      ctx->Eval.MapGrid2u2 = 1.0;
+      ctx->Eval.MapGrid2v1 = 0.0;
+      ctx->Eval.MapGrid2v2 = 1.0;
+
+      /* Evaluator data */
+      {
+         static GLfloat vertex[4] = { 0.0, 0.0, 0.0, 1.0 };
+         static GLfloat normal[3] = { 0.0, 0.0, 1.0 };
+         static GLfloat index[1] = { 1.0 };
+         static GLfloat color[4] = { 1.0, 1.0, 1.0, 1.0 };
+         static GLfloat texcoord[4] = { 0.0, 0.0, 0.0, 1.0 };
+
+         init_1d_map( &ctx->EvalMap.Map1Vertex3, 3, vertex );
+         init_1d_map( &ctx->EvalMap.Map1Vertex4, 4, vertex );
+         init_1d_map( &ctx->EvalMap.Map1Index, 1, index );
+         init_1d_map( &ctx->EvalMap.Map1Color4, 4, color );
+         init_1d_map( &ctx->EvalMap.Map1Normal, 3, normal );
+         init_1d_map( &ctx->EvalMap.Map1Texture1, 1, texcoord );
+         init_1d_map( &ctx->EvalMap.Map1Texture2, 2, texcoord );
+         init_1d_map( &ctx->EvalMap.Map1Texture3, 3, texcoord );
+         init_1d_map( &ctx->EvalMap.Map1Texture4, 4, texcoord );
+
+         init_2d_map( &ctx->EvalMap.Map2Vertex3, 3, vertex );
+         init_2d_map( &ctx->EvalMap.Map2Vertex4, 4, vertex );
+         init_2d_map( &ctx->EvalMap.Map2Index, 1, index );
+         init_2d_map( &ctx->EvalMap.Map2Color4, 4, color );
+         init_2d_map( &ctx->EvalMap.Map2Normal, 3, normal );
+         init_2d_map( &ctx->EvalMap.Map2Texture1, 1, texcoord );
+         init_2d_map( &ctx->EvalMap.Map2Texture2, 2, texcoord );
+         init_2d_map( &ctx->EvalMap.Map2Texture3, 3, texcoord );
+         init_2d_map( &ctx->EvalMap.Map2Texture4, 4, texcoord );
+      }
+
+      /* Fog group */
+      ctx->Fog.Enabled = GL_FALSE;
+      ctx->Fog.Mode = GL_EXP;
+      ASSIGN_4V( ctx->Fog.Color, 0.0, 0.0, 0.0, 0.0 );
+      ctx->Fog.Index = 0.0;
+      ctx->Fog.Density = 1.0;
+      ctx->Fog.Start = 0.0;
+      ctx->Fog.End = 1.0;
+
+      /* Hint group */
+      ctx->Hint.PerspectiveCorrection = GL_DONT_CARE;
+      ctx->Hint.PointSmooth = GL_DONT_CARE;
+      ctx->Hint.LineSmooth = GL_DONT_CARE;
+      ctx->Hint.PolygonSmooth = GL_DONT_CARE;
+      ctx->Hint.Fog = GL_DONT_CARE;
+
+      ctx->Hint.AllowDrawWin = GL_TRUE;
+      ctx->Hint.AllowDrawSpn = GL_TRUE;
+      ctx->Hint.AllowDrawMem = GL_TRUE;
+      ctx->Hint.StrictLighting = GL_TRUE;
+
+      /* Pipeline */
+      gl_pipeline_init( ctx );
+      gl_cva_init( ctx );
+
+      /* Extensions */
+      gl_extensions_ctr( ctx );
+
+      ctx->AllowVertexCull = 0;
+
+      /* Lighting group */
+      for (i=0;i<MAX_LIGHTS;i++) {
+        init_light( &ctx->Light.Light[i], i );
+      }
+      make_empty_list( &ctx->Light.EnabledList );
+
+      init_lightmodel( &ctx->Light.Model );
+      init_material( &ctx->Light.Material[0] );
+      init_material( &ctx->Light.Material[1] );
+      ctx->Light.ShadeModel = GL_SMOOTH;
+      ctx->Light.Enabled = GL_FALSE;
+      ctx->Light.ColorMaterialFace = GL_FRONT_AND_BACK;
+      ctx->Light.ColorMaterialMode = GL_AMBIENT_AND_DIFFUSE;
+      ctx->Light.ColorMaterialBitmask
+         = gl_material_bitmask( ctx,
+                               GL_FRONT_AND_BACK,
+                               GL_AMBIENT_AND_DIFFUSE, ~0, 0 );
+
+      ctx->Light.ColorMaterialEnabled = GL_FALSE;
+
+      /* Line group */
+      ctx->Line.SmoothFlag = GL_FALSE;
+      ctx->Line.StippleFlag = GL_FALSE;
+      ctx->Line.Width = 1.0;
+      ctx->Line.StipplePattern = 0xffff;
+      ctx->Line.StippleFactor = 1;
+
+      /* Display List group */
+      ctx->List.ListBase = 0;
+
+      /* Pixel group */
+      ctx->Pixel.RedBias = 0.0;
+      ctx->Pixel.RedScale = 1.0;
+      ctx->Pixel.GreenBias = 0.0;
+      ctx->Pixel.GreenScale = 1.0;
+      ctx->Pixel.BlueBias = 0.0;
+      ctx->Pixel.BlueScale = 1.0;
+      ctx->Pixel.AlphaBias = 0.0;
+      ctx->Pixel.AlphaScale = 1.0;
+      ctx->Pixel.ScaleOrBiasRGBA = GL_FALSE;
+      ctx->Pixel.DepthBias = 0.0;
+      ctx->Pixel.DepthScale = 1.0;
+      ctx->Pixel.IndexOffset = 0;
+      ctx->Pixel.IndexShift = 0;
+      ctx->Pixel.ZoomX = 1.0;
+      ctx->Pixel.ZoomY = 1.0;
+      ctx->Pixel.MapColorFlag = GL_FALSE;
+      ctx->Pixel.MapStencilFlag = GL_FALSE;
+      ctx->Pixel.MapStoSsize = 1;
+      ctx->Pixel.MapItoIsize = 1;
+      ctx->Pixel.MapItoRsize = 1;
+      ctx->Pixel.MapItoGsize = 1;
+      ctx->Pixel.MapItoBsize = 1;
+      ctx->Pixel.MapItoAsize = 1;
+      ctx->Pixel.MapRtoRsize = 1;
+      ctx->Pixel.MapGtoGsize = 1;
+      ctx->Pixel.MapBtoBsize = 1;
+      ctx->Pixel.MapAtoAsize = 1;
+      ctx->Pixel.MapStoS[0] = 0;
+      ctx->Pixel.MapItoI[0] = 0;
+      ctx->Pixel.MapItoR[0] = 0.0;
+      ctx->Pixel.MapItoG[0] = 0.0;
+      ctx->Pixel.MapItoB[0] = 0.0;
+      ctx->Pixel.MapItoA[0] = 0.0;
+      ctx->Pixel.MapItoR8[0] = 0;
+      ctx->Pixel.MapItoG8[0] = 0;
+      ctx->Pixel.MapItoB8[0] = 0;
+      ctx->Pixel.MapItoA8[0] = 0;
+      ctx->Pixel.MapRtoR[0] = 0.0;
+      ctx->Pixel.MapGtoG[0] = 0.0;
+      ctx->Pixel.MapBtoB[0] = 0.0;
+      ctx->Pixel.MapAtoA[0] = 0.0;
+
+      /* Point group */
+      ctx->Point.SmoothFlag = GL_FALSE;
+      ctx->Point.Size = 1.0;
+      ctx->Point.Params[0] = 1.0;
+      ctx->Point.Params[1] = 0.0;
+      ctx->Point.Params[2] = 0.0;
+      ctx->Point.Attenuated = GL_FALSE;
+      ctx->Point.MinSize = 0.0;
+      ctx->Point.MaxSize = (GLfloat) MAX_POINT_SIZE;
+      ctx->Point.Threshold = 1.0;
+
+      /* Polygon group */
+      ctx->Polygon.CullFlag = GL_FALSE;
+      ctx->Polygon.CullFaceMode = GL_BACK;
+      ctx->Polygon.FrontFace = GL_CCW;
+      ctx->Polygon.FrontBit = 0;
+      ctx->Polygon.FrontMode = GL_FILL;
+      ctx->Polygon.BackMode = GL_FILL;
+      ctx->Polygon.Unfilled = GL_FALSE;
+      ctx->Polygon.SmoothFlag = GL_FALSE;
+      ctx->Polygon.StippleFlag = GL_FALSE;
+      ctx->Polygon.OffsetFactor = 0.0F;
+      ctx->Polygon.OffsetUnits = 0.0F;
+      ctx->Polygon.OffsetPoint = GL_FALSE;
+      ctx->Polygon.OffsetLine = GL_FALSE;
+      ctx->Polygon.OffsetFill = GL_FALSE;
+
+      /* Polygon Stipple group */
+      MEMSET( ctx->PolygonStipple, 0xff, 32*sizeof(GLuint) );
+
+      /* Scissor group */
+      ctx->Scissor.Enabled = GL_FALSE;
+      ctx->Scissor.X = 0;
+      ctx->Scissor.Y = 0;
+      ctx->Scissor.Width = 0;
+      ctx->Scissor.Height = 0;
+
+      /* Stencil group */
+      ctx->Stencil.Enabled = GL_FALSE;
+      ctx->Stencil.Function = GL_ALWAYS;
+      ctx->Stencil.FailFunc = GL_KEEP;
+      ctx->Stencil.ZPassFunc = GL_KEEP;
+      ctx->Stencil.ZFailFunc = GL_KEEP;
+      ctx->Stencil.Ref = 0;
+      ctx->Stencil.ValueMask = 0xff;
+      ctx->Stencil.Clear = 0;
+      ctx->Stencil.WriteMask = 0xff;
+
+      /* Texture group */
+      ctx->Texture.CurrentUnit = 0;      /* multitexture */
+      ctx->Texture.CurrentTransformUnit = 0; /* multitexture */
+      ctx->Texture.Enabled = 0;
+
+      for (i=0; i<MAX_TEXTURE_UNITS; i++)
+         init_texture_unit( ctx, i );
+
+      ctx->Texture.SharedPalette = GL_FALSE;
+      ctx->Texture.Palette[0] = 255;
+      ctx->Texture.Palette[1] = 255;
+      ctx->Texture.Palette[2] = 255;
+      ctx->Texture.Palette[3] = 255;
+      ctx->Texture.PaletteSize = 1;
+      ctx->Texture.PaletteIntFormat = GL_RGBA;
+      ctx->Texture.PaletteFormat = GL_RGBA;
+
+      /* Transformation group */
+      ctx->Transform.MatrixMode = GL_MODELVIEW;
+      ctx->Transform.Normalize = GL_FALSE;
+      ctx->Transform.RescaleNormals = GL_FALSE;
+      for (i=0;i<MAX_CLIP_PLANES;i++) {
+        ctx->Transform.ClipEnabled[i] = GL_FALSE;
+         ASSIGN_4V( ctx->Transform.EyeUserPlane[i], 0.0, 0.0, 0.0, 0.0 );
+      }
+      ctx->Transform.AnyClip = GL_FALSE;
+
+      /* Viewport group */
+      ctx->Viewport.X = 0;
+      ctx->Viewport.Y = 0;
+      ctx->Viewport.Width = 0;
+      ctx->Viewport.Height = 0;
+      ctx->Viewport.Near = 0.0;
+      ctx->Viewport.Far = 1.0;
+      gl_matrix_ctr(&ctx->Viewport.WindowMap);
+
+#define Sz 10
+#define Tz 14
+      ctx->Viewport.WindowMap.m[Sz] = 0.5 * DEPTH_SCALE;
+      ctx->Viewport.WindowMap.m[Tz] = 0.5 * DEPTH_SCALE;
+#undef Sz
+#undef Tz
+
+      ctx->Viewport.WindowMap.flags = MAT_FLAG_GENERAL_SCALE|MAT_FLAG_TRANSLATION;
+      ctx->Viewport.WindowMap.type = MATRIX_3D_NO_ROT;
+
+      /* Vertex arrays */
+      ctx->Array.Vertex.Size = 4;
+      ctx->Array.Vertex.Type = GL_FLOAT;
+      ctx->Array.Vertex.Stride = 0;
+      ctx->Array.Vertex.StrideB = 0;
+      ctx->Array.Vertex.Ptr = NULL;
+      ctx->Array.Vertex.Enabled = GL_FALSE;
+      ctx->Array.Normal.Type = GL_FLOAT;
+      ctx->Array.Normal.Stride = 0;
+      ctx->Array.Normal.StrideB = 0;
+      ctx->Array.Normal.Ptr = NULL;
+      ctx->Array.Normal.Enabled = GL_FALSE;
+      ctx->Array.Color.Size = 4;
+      ctx->Array.Color.Type = GL_FLOAT;
+      ctx->Array.Color.Stride = 0;
+      ctx->Array.Color.StrideB = 0;
+      ctx->Array.Color.Ptr = NULL;
+      ctx->Array.Color.Enabled = GL_FALSE;
+      ctx->Array.Index.Type = GL_FLOAT;
+      ctx->Array.Index.Stride = 0;
+      ctx->Array.Index.StrideB = 0;
+      ctx->Array.Index.Ptr = NULL;
+      ctx->Array.Index.Enabled = GL_FALSE;
+      for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
+         ctx->Array.TexCoord[i].Size = 4;
+         ctx->Array.TexCoord[i].Type = GL_FLOAT;
+         ctx->Array.TexCoord[i].Stride = 0;
+         ctx->Array.TexCoord[i].StrideB = 0;
+         ctx->Array.TexCoord[i].Ptr = NULL;
+         ctx->Array.TexCoord[i].Enabled = GL_FALSE;
+      }
+      ctx->Array.TexCoordInterleaveFactor = 1;
+      ctx->Array.EdgeFlag.Stride = 0;
+      ctx->Array.EdgeFlag.StrideB = 0;
+      ctx->Array.EdgeFlag.Ptr = NULL;
+      ctx->Array.EdgeFlag.Enabled = GL_FALSE;
+      ctx->Array.ActiveTexture = 0;   /* GL_ARB_multitexture */
+
+      /* Pixel transfer */
+      ctx->Pack.Alignment = 4;
+      ctx->Pack.RowLength = 0;
+      ctx->Pack.SkipPixels = 0;
+      ctx->Pack.SkipRows = 0;
+      ctx->Pack.SwapBytes = GL_FALSE;
+      ctx->Pack.LsbFirst = GL_FALSE;
+      ctx->Unpack.Alignment = 4;
+      ctx->Unpack.RowLength = 0;
+      ctx->Unpack.SkipPixels = 0;
+      ctx->Unpack.SkipRows = 0;
+      ctx->Unpack.SwapBytes = GL_FALSE;
+      ctx->Unpack.LsbFirst = GL_FALSE;
+
+      /* Feedback */
+      ctx->Feedback.Type = GL_2D;   /* TODO: verify */
+      ctx->Feedback.Buffer = NULL;
+      ctx->Feedback.BufferSize = 0;
+      ctx->Feedback.Count = 0;
+
+      /* Selection/picking */
+      ctx->Select.Buffer = NULL;
+      ctx->Select.BufferSize = 0;
+      ctx->Select.BufferCount = 0;
+      ctx->Select.Hits = 0;
+      ctx->Select.NameStackDepth = 0;
+
+      /* Optimized Accum buffer */
+      ctx->IntegerAccumMode = GL_TRUE;
+      ctx->IntegerAccumScaler = 0.0;
+
+      /* multitexture */
+      ctx->TexCoordUnit = 0;
+
+      /* Renderer and client attribute stacks */
+      ctx->AttribStackDepth = 0;
+      ctx->ClientAttribStackDepth = 0;
+
+      /*** Miscellaneous ***/
+      ctx->NewState = NEW_ALL;
+      ctx->RenderMode = GL_RENDER;
+      ctx->StippleCounter = 0;
+      ctx->NeedNormals = GL_FALSE;
+      ctx->DoViewportMapping = GL_TRUE;
+
+      ctx->NeedEyeCoords = GL_FALSE;
+      ctx->NeedEyeNormals = GL_FALSE;
+      ctx->vb_proj_matrix = &ctx->ModelProjectMatrix;
+
+      /* Display list */
+      ctx->CallDepth = 0;
+      ctx->ExecuteFlag = GL_TRUE;
+      ctx->CompileFlag = GL_FALSE;
+      ctx->CurrentListPtr = NULL;
+      ctx->CurrentBlock = NULL;
+      ctx->CurrentListNum = 0;
+      ctx->CurrentPos = 0;
+
+      ctx->ErrorValue = (GLenum) GL_NO_ERROR;
+
+      ctx->CatchSignals = GL_TRUE;
+
+      /* For debug/development only */
+      ctx->NoRaster = getenv("MESA_NO_RASTER") ? GL_TRUE : GL_FALSE;
+
+      /* Dither disable */
+      ctx->NoDither = getenv("MESA_NO_DITHER") ? GL_TRUE : GL_FALSE;
+      if (ctx->NoDither) {
+         if (getenv("MESA_DEBUG")) {
+            fprintf(stderr, "MESA_NO_DITHER set - dithering disabled\n");
+         }
+         ctx->Color.DitherFlag = GL_FALSE;
+      }
+   }
+}
+
+
+
+/*
+ * Allocate a new GLvisual object.
+ * Input:  rgbFlag - GL_TRUE=RGB(A) mode, GL_FALSE=Color Index mode
+ *         alphaFlag - alloc software alpha buffers?
+ *         dbFlag - double buffering?
+ *         stereoFlag - stereo buffer?
+ *         depthFits - requested minimum bits per depth buffer value
+ *         stencilFits - requested minimum bits per stencil buffer value
+ *         accumFits - requested minimum bits per accum buffer component
+ *         indexFits - number of bits per pixel if rgbFlag==GL_FALSE
+ *         red/green/blue/alphaFits - number of bits per color component
+ *                                     in frame buffer for RGB(A) mode.
+ * Return:  pointer to new GLvisual or NULL if requested parameters can't
+ *          be met.
+ */
+GLvisual *gl_create_visual( GLboolean rgbFlag,
+                            GLboolean alphaFlag,
+                            GLboolean dbFlag,
+                            GLboolean stereoFlag,
+                            GLint depthBits,
+                            GLint stencilBits,
+                            GLint accumBits,
+                            GLint indexBits,
+                            GLint redBits,
+                            GLint greenBits,
+                            GLint blueBits,
+                            GLint alphaBits )
+{
+   GLvisual *vis;
+
+   if (depthBits > (GLint) (8*sizeof(GLdepth))) {
+      /* can't meet depth buffer requirements */
+      return NULL;
+   }
+   if (stencilBits > (GLint) (8*sizeof(GLstencil))) {
+      /* can't meet stencil buffer requirements */
+      return NULL;
+   }
+   if (accumBits > (GLint) (8*sizeof(GLaccum))) {
+      /* can't meet accum buffer requirements */
+      return NULL;
+   }
+
+   vis = (GLvisual *) calloc( 1, sizeof(GLvisual) );
+   if (!vis) {
+      return NULL;
+   }
+
+   vis->RGBAflag   = rgbFlag;
+   vis->DBflag     = dbFlag;
+   vis->StereoFlag = stereoFlag;
+   vis->RedBits    = redBits;
+   vis->GreenBits  = greenBits;
+   vis->BlueBits   = blueBits;
+   vis->AlphaBits  = alphaFlag ? 8*sizeof(GLubyte) : alphaBits;
+
+   vis->IndexBits   = indexBits;
+   vis->DepthBits   = (depthBits>0) ? 8*sizeof(GLdepth) : 0;
+   vis->AccumBits   = (accumBits>0) ? 8*sizeof(GLaccum) : 0;
+   vis->StencilBits = (stencilBits>0) ? 8*sizeof(GLstencil) : 0;
+
+   vis->SoftwareAlpha = alphaFlag;
+
+   return vis;
+}
+
+
+
+void gl_destroy_visual( GLvisual *vis )
+{
+   free( vis );
+}
+
+
+
+/*
+ * Allocate the proxy textures.  If we run out of memory part way through
+ * the allocations clean up and return GL_FALSE.
+ * Return:  GL_TRUE=success, GL_FALSE=failure
+ */
+static GLboolean alloc_proxy_textures( GLcontext *ctx )
+{
+   GLboolean out_of_memory;
+   GLint i;
+
+   ctx->Texture.Proxy1D = gl_alloc_texture_object(NULL, 0, 1);
+   if (!ctx->Texture.Proxy1D) {
+      return GL_FALSE;
+   }
+
+   ctx->Texture.Proxy2D = gl_alloc_texture_object(NULL, 0, 2);
+   if (!ctx->Texture.Proxy2D) {
+      gl_free_texture_object(NULL, ctx->Texture.Proxy1D);
+      return GL_FALSE;
+   }
+
+   ctx->Texture.Proxy3D = gl_alloc_texture_object(NULL, 0, 3);
+   if (!ctx->Texture.Proxy3D) {
+      gl_free_texture_object(NULL, ctx->Texture.Proxy1D);
+      gl_free_texture_object(NULL, ctx->Texture.Proxy2D);
+      return GL_FALSE;
+   }
+
+   out_of_memory = GL_FALSE;
+   for (i=0;i<MAX_TEXTURE_LEVELS;i++) {
+      ctx->Texture.Proxy1D->Image[i] = gl_alloc_texture_image();
+      ctx->Texture.Proxy2D->Image[i] = gl_alloc_texture_image();
+      ctx->Texture.Proxy3D->Image[i] = gl_alloc_texture_image();
+      if (!ctx->Texture.Proxy1D->Image[i]
+          || !ctx->Texture.Proxy2D->Image[i]
+          || !ctx->Texture.Proxy3D->Image[i]) {
+         out_of_memory = GL_TRUE;
+      }
+   }
+   if (out_of_memory) {
+      for (i=0;i<MAX_TEXTURE_LEVELS;i++) {
+         if (ctx->Texture.Proxy1D->Image[i]) {
+            gl_free_texture_image(ctx->Texture.Proxy1D->Image[i]);
+         }
+         if (ctx->Texture.Proxy2D->Image[i]) {
+            gl_free_texture_image(ctx->Texture.Proxy2D->Image[i]);
+         }
+         if (ctx->Texture.Proxy3D->Image[i]) {
+            gl_free_texture_image(ctx->Texture.Proxy3D->Image[i]);
+         }
+      }
+      gl_free_texture_object(NULL, ctx->Texture.Proxy1D);
+      gl_free_texture_object(NULL, ctx->Texture.Proxy2D);
+      gl_free_texture_object(NULL, ctx->Texture.Proxy3D);
+      return GL_FALSE;
+   }
+   else {
+      return GL_TRUE;
+   }
+}
+
+
+
+#define MALLOC_STRUCT(T)  (struct T *) malloc( sizeof(struct T) )
+
+/*
+ * Allocate and initialize a GLcontext structure.
+ * Input:  visual - a GLvisual pointer
+ *         sharelist - another context to share display lists with or NULL
+ *         driver_ctx - pointer to device driver's context state struct
+ * Return:  pointer to a new gl_context struct or NULL if error.
+ */
+GLcontext *gl_create_context( GLvisual *visual,
+                              GLcontext *share_list,
+                              void *driver_ctx,
+                              GLboolean direct )
+{
+   GLcontext *ctx;
+   GLuint i;
+
+   (void) direct;  /* not used */
+
+   /* do some implementation tests */
+   assert( sizeof(GLbyte) == 1 );
+   assert( sizeof(GLshort) >= 2 );
+   assert( sizeof(GLint) >= 4 );
+   assert( sizeof(GLubyte) == 1 );
+   assert( sizeof(GLushort) >= 2 );
+   assert( sizeof(GLuint) >= 4 );
+
+   /* misc one-time initializations */
+   one_time_init();
+
+   ctx = (GLcontext *) calloc( 1, sizeof(GLcontext) );
+   if (!ctx) {
+      return NULL;
+   }
+
+   ctx->DriverCtx = driver_ctx;
+   ctx->Visual = visual;
+   ctx->Buffer = NULL;
+
+   ctx->VB = gl_vb_create_for_immediate( ctx );
+   if (!ctx->VB) {
+      free( ctx );
+      return NULL;
+   }
+   ctx->input = ctx->VB->IM;
+
+   ctx->PB = gl_alloc_pb();
+   if (!ctx->PB) {
+      free( ctx->VB );
+      free( ctx );
+      return NULL;
+   }
+
+   if (share_list) {
+      /* share the group of display lists of another context */
+      ctx->Shared = share_list->Shared;
+   }
+   else {
+      /* allocate new group of display lists */
+      ctx->Shared = alloc_shared_state();
+      if (!ctx->Shared) {
+         free(ctx->VB);
+         free(ctx->PB);
+         free(ctx);
+         return NULL;
+      }
+   }
+   ctx->Shared->RefCount++;
+
+   initialize_context( ctx );
+   gl_reset_vb( ctx->VB );
+   gl_reset_input( ctx );
+
+
+   ctx->ShineTabList = MALLOC_STRUCT( gl_shine_tab );
+   make_empty_list( ctx->ShineTabList );
+
+   for (i = 0 ; i < 10 ; i++) {
+      struct gl_shine_tab *s = MALLOC_STRUCT( gl_shine_tab );
+      s->shininess = -1;
+      s->refcount = 0;
+      insert_at_tail( ctx->ShineTabList, s );
+   }
+
+   for (i = 0 ; i < 4 ; i++) {
+      ctx->ShineTable[i] = ctx->ShineTabList->prev;
+      ctx->ShineTable[i]->refcount++;
+   }
+
+   if (visual->DBflag) {
+      ctx->Color.DrawBuffer = GL_BACK;
+      ctx->Color.DriverDrawBuffer = GL_BACK_LEFT;
+      ctx->Color.DrawDestMask = BACK_LEFT_BIT;
+      ctx->Pixel.ReadBuffer = GL_BACK;
+      ctx->Pixel.DriverReadBuffer = GL_BACK_LEFT;
+   }
+   else {
+      ctx->Color.DrawBuffer = GL_FRONT;
+      ctx->Color.DriverDrawBuffer = GL_FRONT_LEFT;
+      ctx->Color.DrawDestMask = FRONT_LEFT_BIT;
+      ctx->Pixel.ReadBuffer = GL_FRONT;
+      ctx->Pixel.DriverReadBuffer = GL_FRONT_LEFT;
+   }
+
+#ifdef PROFILE
+   init_timings( ctx );
+#endif
+
+#ifdef GL_VERSION_1_1
+   if (!alloc_proxy_textures(ctx)) {
+      free_shared_state(ctx, ctx->Shared);
+      free(ctx->VB);
+      free(ctx->PB);
+      free(ctx);
+      return NULL;
+   }
+#endif
+
+   gl_init_api_function_pointers( ctx );
+   ctx->API = ctx->Exec;   /* GL_EXECUTE is default */
+
+   return ctx;
+}
+
+/* Just reads the config files...
+ */
+void gl_context_initialize( GLcontext *ctx )
+{
+   gl_read_config_file( ctx );
+}
+
+
+
+
+/*
+ * Destroy a gl_context structure.
+ */
+void gl_destroy_context( GLcontext *ctx )
+{
+   if (ctx) {
+
+      GLuint i;
+      struct gl_shine_tab *s, *tmps;
+
+#ifdef PROFILE
+      if (getenv("MESA_PROFILE")) {
+         print_timings( ctx );
+      }
+#endif
+
+      gl_matrix_dtr( &ctx->ModelView );
+      for (i = 0 ; i < MAX_MODELVIEW_STACK_DEPTH ; i++) {
+        gl_matrix_dtr( &ctx->ModelViewStack[i] );
+      }
+
+
+      free( ctx->PB );
+      free( ctx->VB );
+
+      ctx->Shared->RefCount--;
+      assert(ctx->Shared->RefCount>=0);
+      if (ctx->Shared->RefCount==0) {
+        /* free shared state */
+        free_shared_state( ctx, ctx->Shared );
+      }
+
+      foreach_s( s, tmps, ctx->ShineTabList ) {
+        free( s );
+      }
+      free( ctx->ShineTabList );
+
+      /* Free proxy texture objects */
+      gl_free_texture_object( NULL, ctx->Texture.Proxy1D );
+      gl_free_texture_object( NULL, ctx->Texture.Proxy2D );
+      gl_free_texture_object( NULL, ctx->Texture.Proxy3D );
+
+      /* Free evaluator data */
+      if (ctx->EvalMap.Map1Vertex3.Points)
+         free( ctx->EvalMap.Map1Vertex3.Points );
+      if (ctx->EvalMap.Map1Vertex4.Points)
+         free( ctx->EvalMap.Map1Vertex4.Points );
+      if (ctx->EvalMap.Map1Index.Points)
+         free( ctx->EvalMap.Map1Index.Points );
+      if (ctx->EvalMap.Map1Color4.Points)
+         free( ctx->EvalMap.Map1Color4.Points );
+      if (ctx->EvalMap.Map1Normal.Points)
+         free( ctx->EvalMap.Map1Normal.Points );
+      if (ctx->EvalMap.Map1Texture1.Points)
+         free( ctx->EvalMap.Map1Texture1.Points );
+      if (ctx->EvalMap.Map1Texture2.Points)
+         free( ctx->EvalMap.Map1Texture2.Points );
+      if (ctx->EvalMap.Map1Texture3.Points)
+         free( ctx->EvalMap.Map1Texture3.Points );
+      if (ctx->EvalMap.Map1Texture4.Points)
+         free( ctx->EvalMap.Map1Texture4.Points );
+
+      if (ctx->EvalMap.Map2Vertex3.Points)
+         free( ctx->EvalMap.Map2Vertex3.Points );
+      if (ctx->EvalMap.Map2Vertex4.Points)
+         free( ctx->EvalMap.Map2Vertex4.Points );
+      if (ctx->EvalMap.Map2Index.Points)
+         free( ctx->EvalMap.Map2Index.Points );
+      if (ctx->EvalMap.Map2Color4.Points)
+         free( ctx->EvalMap.Map2Color4.Points );
+      if (ctx->EvalMap.Map2Normal.Points)
+         free( ctx->EvalMap.Map2Normal.Points );
+      if (ctx->EvalMap.Map2Texture1.Points)
+         free( ctx->EvalMap.Map2Texture1.Points );
+      if (ctx->EvalMap.Map2Texture2.Points)
+         free( ctx->EvalMap.Map2Texture2.Points );
+      if (ctx->EvalMap.Map2Texture3.Points)
+         free( ctx->EvalMap.Map2Texture3.Points );
+      if (ctx->EvalMap.Map2Texture4.Points)
+         free( ctx->EvalMap.Map2Texture4.Points );
+
+      free( (void *) ctx );
+
+#ifndef THREADS
+      if (ctx==CC) {
+         CC = NULL;
+        CURRENT_INPUT = NULL;
+      }
+#endif
+
+   }
+}
+
+
+
+/*
+ * Create a new framebuffer.  A GLframebuffer is a struct which
+ * encapsulates the depth, stencil and accum buffers and related
+ * parameters.
+ * Input:  visual - a GLvisual pointer
+ * Return:  pointer to new GLframebuffer struct or NULL if error.
+ */
+GLframebuffer *gl_create_framebuffer( GLvisual *visual )
+{
+   GLframebuffer *buffer;
+
+   buffer = (GLframebuffer *) calloc( 1, sizeof(GLframebuffer) );
+   if (!buffer) {
+      return NULL;
+   }
+
+   buffer->Visual = visual;
+
+   return buffer;
+}
+
+
+
+/*
+ * Free a framebuffer struct and its buffers.
+ */
+void gl_destroy_framebuffer( GLframebuffer *buffer )
+{
+   if (buffer) {
+      if (buffer->Depth) {
+         free( buffer->Depth );
+      }
+      if (buffer->Accum) {
+         free( buffer->Accum );
+      }
+      if (buffer->Stencil) {
+         free( buffer->Stencil );
+      }
+      if (buffer->FrontLeftAlpha) {
+         free( buffer->FrontLeftAlpha );
+      }
+      if (buffer->BackLeftAlpha) {
+         free( buffer->BackLeftAlpha );
+      }
+      if (buffer->FrontRightAlpha) {
+         free( buffer->FrontRightAlpha );
+      }
+      if (buffer->BackRightAlpha) {
+         free( buffer->BackRightAlpha );
+      }
+      free(buffer);
+   }
+}
+
+
+
+/*
+ * Set the current context, binding the given frame buffer to the context.
+ */
+void gl_make_current( GLcontext *ctx, GLframebuffer *buffer )
+{
+   GET_CONTEXT;
+
+   /* Flush the old context
+    */
+   if (CC) {
+      ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(CC, "gl_make_current");
+   }
+
+#ifdef THREADS
+   /* TODO: unbind old buffer from context? */
+   set_thread_context( ctx );
+#else
+   if (CC && CC->Buffer) {
+      /* unbind frame buffer from context */
+      CC->Buffer = NULL;
+   }
+   CC = ctx;
+   if (ctx) {
+      SET_IMMEDIATE(ctx, ctx->input);
+   }
+#endif
+
+   if (MESA_VERBOSE) fprintf(stderr, "gl_make_current()\n");
+
+   if (ctx && buffer) {
+      /* TODO: check if ctx and buffer's visual match??? */
+      ctx->Buffer = buffer;      /* Bind the frame buffer to the context */
+      ctx->NewState = NEW_ALL;   /* just to be safe */
+      gl_update_state( ctx );
+   }
+}
+
+
+/*
+ * Return current context handle.
+ */
+GLcontext *gl_get_current_context( void )
+{
+#ifdef THREADS
+   return gl_get_thread_context();
+#else
+   return CC;
+#endif
+}
+
+
+
+/*
+ * Copy attribute groups from one context to another.
+ * Input:  src - source context
+ *         dst - destination context
+ *         mask - bitwise OR of GL_*_BIT flags
+ */
+void gl_copy_context( const GLcontext *src, GLcontext *dst, GLuint mask )
+{
+   if (mask & GL_ACCUM_BUFFER_BIT) {
+      MEMCPY( &dst->Accum, &src->Accum, sizeof(struct gl_accum_attrib) );
+   }
+   if (mask & GL_COLOR_BUFFER_BIT) {
+      MEMCPY( &dst->Color, &src->Color, sizeof(struct gl_colorbuffer_attrib) );
+   }
+   if (mask & GL_CURRENT_BIT) {
+      MEMCPY( &dst->Current, &src->Current, sizeof(struct gl_current_attrib) );
+   }
+   if (mask & GL_DEPTH_BUFFER_BIT) {
+      MEMCPY( &dst->Depth, &src->Depth, sizeof(struct gl_depthbuffer_attrib) );
+   }
+   if (mask & GL_ENABLE_BIT) {
+      /* no op */
+   }
+   if (mask & GL_EVAL_BIT) {
+      MEMCPY( &dst->Eval, &src->Eval, sizeof(struct gl_eval_attrib) );
+   }
+   if (mask & GL_FOG_BIT) {
+      MEMCPY( &dst->Fog, &src->Fog, sizeof(struct gl_fog_attrib) );
+   }
+   if (mask & GL_HINT_BIT) {
+      MEMCPY( &dst->Hint, &src->Hint, sizeof(struct gl_hint_attrib) );
+   }
+   if (mask & GL_LIGHTING_BIT) {
+      MEMCPY( &dst->Light, &src->Light, sizeof(struct gl_light_attrib) );
+/*       gl_reinit_light_attrib( &dst->Light ); */
+   }
+   if (mask & GL_LINE_BIT) {
+      MEMCPY( &dst->Line, &src->Line, sizeof(struct gl_line_attrib) );
+   }
+   if (mask & GL_LIST_BIT) {
+      MEMCPY( &dst->List, &src->List, sizeof(struct gl_list_attrib) );
+   }
+   if (mask & GL_PIXEL_MODE_BIT) {
+      MEMCPY( &dst->Pixel, &src->Pixel, sizeof(struct gl_pixel_attrib) );
+   }
+   if (mask & GL_POINT_BIT) {
+      MEMCPY( &dst->Point, &src->Point, sizeof(struct gl_point_attrib) );
+   }
+   if (mask & GL_POLYGON_BIT) {
+      MEMCPY( &dst->Polygon, &src->Polygon, sizeof(struct gl_polygon_attrib) );
+   }
+   if (mask & GL_POLYGON_STIPPLE_BIT) {
+      /* Use loop instead of MEMCPY due to problem with Portland Group's
+       * C compiler.  Reported by John Stone.
+       */
+      int i;
+      for (i=0;i<32;i++) {
+         dst->PolygonStipple[i] = src->PolygonStipple[i];
+      }
+   }
+   if (mask & GL_SCISSOR_BIT) {
+      MEMCPY( &dst->Scissor, &src->Scissor, sizeof(struct gl_scissor_attrib) );
+   }
+   if (mask & GL_STENCIL_BUFFER_BIT) {
+      MEMCPY( &dst->Stencil, &src->Stencil, sizeof(struct gl_stencil_attrib) );
+   }
+   if (mask & GL_TEXTURE_BIT) {
+      MEMCPY( &dst->Texture, &src->Texture, sizeof(struct gl_texture_attrib) );
+   }
+   if (mask & GL_TRANSFORM_BIT) {
+      MEMCPY( &dst->Transform, &src->Transform, sizeof(struct gl_transform_attrib) );
+   }
+   if (mask & GL_VIEWPORT_BIT) {
+      MEMCPY( &dst->Viewport, &src->Viewport, sizeof(struct gl_viewport_attrib) );
+   }
+}
+
+
+
+/*
+ * Someday a GLS library or OpenGL-like debugger may call this function
+ * to register it's own set of API entry points.
+ * Input: ctx - the context to set API pointers for
+ *        api - if NULL, restore original API pointers
+ *              else, set API function table to this table.
+ */
+void gl_set_api_table( GLcontext *ctx, const struct gl_api_table *api )
+{
+   if (api) {
+      MEMCPY( &ctx->API, api, sizeof(struct gl_api_table) );
+   }
+   else {
+      MEMCPY( &ctx->API, &ctx->Exec, sizeof(struct gl_api_table) );
+   }
+}
+
+
+
+
+/**********************************************************************/
+/*****                Miscellaneous functions                     *****/
+/**********************************************************************/
+
+
+/*
+ * This function is called when the Mesa user has stumbled into a code
+ * path which may not be implemented fully or correctly.
+ */
+void gl_problem( const GLcontext *ctx, const char *s )
+{
+   fprintf( stderr, "Mesa implementation error: %s\n", s );
+   fprintf( stderr, "Report to mesa-bugs@mesa3d.org\n" );
+   (void) ctx;
+}
+
+
+
+/*
+ * This is called to inform the user that he or she has tried to do
+ * something illogical or if there's likely a bug in their program
+ * (like enabled depth testing without a depth buffer).
+ */
+void gl_warning( const GLcontext *ctx, const char *s )
+{
+   GLboolean debug;
+#ifdef DEBUG
+   debug = GL_TRUE;
+#else
+   if (getenv("MESA_DEBUG")) {
+      debug = GL_TRUE;
+   }
+   else {
+      debug = GL_FALSE;
+   }
+#endif
+   if (debug) {
+      fprintf( stderr, "Mesa warning: %s\n", s );
+   }
+   (void) ctx;
+}
+
+
+
+void gl_compile_error( GLcontext *ctx, GLenum error, const char *s )
+{
+   if (ctx->CompileFlag)
+      gl_save_error( ctx, error, s );
+
+   if (ctx->ExecuteFlag)
+      gl_error( ctx, error, s );
+}
+
+
+/*
+ * This is Mesa's error handler.  Normally, all that's done is the updating
+ * of the current error value.  If Mesa is compiled with -DDEBUG or if the
+ * environment variable "MESA_DEBUG" is defined then a real error message
+ * is printed to stderr.
+ * Input:  error - the error value
+ *         s - a diagnostic string
+ */
+void gl_error( GLcontext *ctx, GLenum error, const char *s )
+{
+   GLboolean debug;
+
+#ifdef DEBUG
+   debug = GL_TRUE;
+#else
+   if (getenv("MESA_DEBUG")) {
+      debug = GL_TRUE;
+   }
+   else {
+      debug = GL_FALSE;
+   }
+#endif
+
+   if (debug) {
+      char errstr[1000];
+
+      switch (error) {
+        case GL_NO_ERROR:
+           strcpy( errstr, "GL_NO_ERROR" );
+           break;
+        case GL_INVALID_VALUE:
+           strcpy( errstr, "GL_INVALID_VALUE" );
+           break;
+        case GL_INVALID_ENUM:
+           strcpy( errstr, "GL_INVALID_ENUM" );
+           break;
+        case GL_INVALID_OPERATION:
+           strcpy( errstr, "GL_INVALID_OPERATION" );
+           break;
+        case GL_STACK_OVERFLOW:
+           strcpy( errstr, "GL_STACK_OVERFLOW" );
+           break;
+        case GL_STACK_UNDERFLOW:
+           strcpy( errstr, "GL_STACK_UNDERFLOW" );
+           break;
+        case GL_OUT_OF_MEMORY:
+           strcpy( errstr, "GL_OUT_OF_MEMORY" );
+           break;
+        default:
+           strcpy( errstr, "unknown" );
+           break;
+      }
+      fprintf( stderr, "Mesa user error: %s in %s\n", errstr, s );
+   }
+
+   if (ctx->ErrorValue==GL_NO_ERROR) {
+      ctx->ErrorValue = error;
+   }
+
+   /* Call device driver's error handler, if any.  This is used on the Mac. */
+   if (ctx->Driver.Error) {
+      (*ctx->Driver.Error)( ctx );
+   }
+}
+
+
+
+/*
+ * Execute a glGetError command
+ */
+GLenum gl_GetError( GLcontext *ctx )
+{
+   GLenum e = ctx->ErrorValue;
+
+   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL( ctx, "glGetError", 0);
+
+   if (MESA_VERBOSE & VERBOSE_API)
+      fprintf(stderr, "glGetError <-- %s\n", gl_lookup_enum_by_nr(e));
+
+   ctx->ErrorValue = (GLenum) GL_NO_ERROR;
+   return e;
+}
+
+
+
+void gl_ResizeBuffersMESA( GLcontext *ctx )
+{
+   GLuint buf_width, buf_height;
+
+   if (MESA_VERBOSE & VERBOSE_API)
+      fprintf(stderr, "glResizeBuffersMESA\n");
+
+   /* ask device driver for size of output buffer */
+   (*ctx->Driver.GetBufferSize)( ctx, &buf_width, &buf_height );
+
+   /* see if size of device driver's color buffer (window) has changed */
+   if (ctx->Buffer->Width == (GLint) buf_width &&
+       ctx->Buffer->Height == (GLint) buf_height)
+      return;
+
+   ctx->NewState |= NEW_RASTER_OPS;  /* to update scissor / window bounds */
+
+   /* save buffer size */
+   ctx->Buffer->Width = buf_width;
+   ctx->Buffer->Height = buf_height;
+
+   /* Reallocate other buffers if needed. */
+   if (ctx->Visual->DepthBits>0) {
+      /* reallocate depth buffer */
+      (*ctx->Driver.AllocDepthBuffer)( ctx );
+   }
+   if (ctx->Visual->StencilBits>0) {
+      /* reallocate stencil buffer */
+      gl_alloc_stencil_buffer( ctx );
+   }
+   if (ctx->Visual->AccumBits>0) {
+      /* reallocate accum buffer */
+      gl_alloc_accum_buffer( ctx );
+   }
+   if (ctx->Visual->SoftwareAlpha) {
+      gl_alloc_alpha_buffers( ctx );
+   }
+}
+
+
+
+
+/**********************************************************************/
+/*****                   State update logic                       *****/
+/**********************************************************************/
+
+
+/*
+ * Since the device driver may or may not support pixel logic ops we
+ * have to make some extensive tests to determine whether or not
+ * software-implemented logic operations have to be used.
+ */
+static void update_pixel_logic( GLcontext *ctx )
+{
+   if (ctx->Visual->RGBAflag) {
+      /* RGBA mode blending w/ Logic Op */
+      if (ctx->Color.ColorLogicOpEnabled) {
+        if (ctx->Driver.LogicOp
+             && (*ctx->Driver.LogicOp)( ctx, ctx->Color.LogicOp )) {
+           /* Device driver can do logic, don't have to do it in software */
+           ctx->Color.SWLogicOpEnabled = GL_FALSE;
+        }
+        else {
+           /* Device driver can't do logic op so we do it in software */
+           ctx->Color.SWLogicOpEnabled = GL_TRUE;
+        }
+      }
+      else {
+        /* no logic op */
+        if (ctx->Driver.LogicOp) {
+            (void) (*ctx->Driver.LogicOp)( ctx, GL_COPY );
+         }
+        ctx->Color.SWLogicOpEnabled = GL_FALSE;
+      }
+   }
+   else {
+      /* CI mode Logic Op */
+      if (ctx->Color.IndexLogicOpEnabled) {
+        if (ctx->Driver.LogicOp
+             && (*ctx->Driver.LogicOp)( ctx, ctx->Color.LogicOp )) {
+           /* Device driver can do logic, don't have to do it in software */
+           ctx->Color.SWLogicOpEnabled = GL_FALSE;
+        }
+        else {
+           /* Device driver can't do logic op so we do it in software */
+           ctx->Color.SWLogicOpEnabled = GL_TRUE;
+        }
+      }
+      else {
+        /* no logic op */
+        if (ctx->Driver.LogicOp) {
+            (void) (*ctx->Driver.LogicOp)( ctx, GL_COPY );
+         }
+        ctx->Color.SWLogicOpEnabled = GL_FALSE;
+      }
+   }
+}
+
+
+
+/*
+ * Check if software implemented RGBA or Color Index masking is needed.
+ */
+static void update_pixel_masking( GLcontext *ctx )
+{
+   if (ctx->Visual->RGBAflag) {
+      GLuint *colorMask = (GLuint *) ctx->Color.ColorMask;
+      if (*colorMask == 0xffffffff) {
+         /* disable masking */
+         if (ctx->Driver.ColorMask) {
+            (void) (*ctx->Driver.ColorMask)( ctx, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
+         }
+         ctx->Color.SWmasking = GL_FALSE;
+      }
+      else {
+         /* Ask driver to do color masking, if it can't then
+          * do it in software
+          */
+         GLboolean red   = ctx->Color.ColorMask[RCOMP] ? GL_TRUE : GL_FALSE;
+         GLboolean green = ctx->Color.ColorMask[GCOMP] ? GL_TRUE : GL_FALSE;
+         GLboolean blue  = ctx->Color.ColorMask[BCOMP] ? GL_TRUE : GL_FALSE;
+         GLboolean alpha = ctx->Color.ColorMask[ACOMP] ? GL_TRUE : GL_FALSE;
+         if (ctx->Driver.ColorMask
+             && (*ctx->Driver.ColorMask)( ctx, red, green, blue, alpha )) {
+            ctx->Color.SWmasking = GL_FALSE;
+         }
+         else {
+            ctx->Color.SWmasking = GL_TRUE;
+         }
+      }
+   }
+   else {
+      if (ctx->Color.IndexMask==0xffffffff) {
+         /* disable masking */
+         if (ctx->Driver.IndexMask) {
+            (void) (*ctx->Driver.IndexMask)( ctx, 0xffffffff );
+         }
+         ctx->Color.SWmasking = GL_FALSE;
+      }
+      else {
+         /* Ask driver to do index masking, if it can't then
+          * do it in software
+          */
+         if (ctx->Driver.IndexMask
+             && (*ctx->Driver.IndexMask)( ctx, ctx->Color.IndexMask )) {
+            ctx->Color.SWmasking = GL_FALSE;
+         }
+         else {
+            ctx->Color.SWmasking = GL_TRUE;
+         }
+      }
+   }
+}
+
+
+static void update_fog_mode( GLcontext *ctx )
+{
+   if (ctx->Fog.Enabled) {
+      if (ctx->Texture.Enabled)
+         ctx->FogMode = FOG_FRAGMENT;
+      else if (ctx->Hint.Fog == GL_NICEST)
+         ctx->FogMode = FOG_FRAGMENT;
+      else
+         ctx->FogMode = FOG_VERTEX;
+
+      if (ctx->Driver.GetParameteri)
+         if ((ctx->Driver.GetParameteri)( ctx, DD_HAVE_HARDWARE_FOG ))
+            ctx->FogMode = FOG_FRAGMENT;
+   }
+   else {
+      ctx->FogMode = FOG_NONE;
+   }
+}
+
+
+/*
+ * Recompute the value of ctx->RasterMask, etc. according to
+ * the current context.
+ */
+static void update_rasterflags( GLcontext *ctx )
+{
+   ctx->RasterMask = 0;
+
+   if (ctx->Color.AlphaEnabled)                ctx->RasterMask |= ALPHATEST_BIT;
+   if (ctx->Color.BlendEnabled)                ctx->RasterMask |= BLEND_BIT;
+   if (ctx->Depth.Test)                        ctx->RasterMask |= DEPTH_BIT;
+   if (ctx->FogMode==FOG_FRAGMENT)     ctx->RasterMask |= FOG_BIT;
+   if (ctx->Color.SWLogicOpEnabled)    ctx->RasterMask |= LOGIC_OP_BIT;
+   if (ctx->Scissor.Enabled)           ctx->RasterMask |= SCISSOR_BIT;
+   if (ctx->Stencil.Enabled)           ctx->RasterMask |= STENCIL_BIT;
+   if (ctx->Color.SWmasking)           ctx->RasterMask |= MASKING_BIT;
+
+   if (ctx->Visual->SoftwareAlpha && ctx->Color.ColorMask[ACOMP]
+       && ctx->Color.DrawBuffer != GL_NONE)
+      ctx->RasterMask |= ALPHABUF_BIT;
+
+   if (   ctx->Viewport.X<0
+       || ctx->Viewport.X + ctx->Viewport.Width > ctx->Buffer->Width
+       || ctx->Viewport.Y<0
+       || ctx->Viewport.Y + ctx->Viewport.Height > ctx->Buffer->Height) {
+      ctx->RasterMask |= WINCLIP_BIT;
+   }
+
+   /* If we're not drawing to exactly one color buffer set the
+    * MULTI_DRAW_BIT flag.  Also set it if we're drawing to no
+    * buffers or the RGBA or CI mask disables all writes.
+    */
+
+   ctx->TriangleCaps &= ~DD_MULTIDRAW;
+
+   if (ctx->Color.MultiDrawBuffer) {
+      ctx->RasterMask |= MULTI_DRAW_BIT;
+      ctx->TriangleCaps |= DD_MULTIDRAW;
+   }
+   else if (ctx->Color.DrawBuffer==GL_NONE) {
+      ctx->RasterMask |= MULTI_DRAW_BIT;
+      ctx->TriangleCaps |= DD_MULTIDRAW;
+   }
+   else if (ctx->Visual->RGBAflag && ctx->Color.ColorMask==0) {
+      /* all RGBA channels disabled */
+      ctx->RasterMask |= MULTI_DRAW_BIT;
+      ctx->TriangleCaps |= DD_MULTIDRAW;
+      ctx->Color.DrawDestMask = 0;
+   }
+   else if (!ctx->Visual->RGBAflag && ctx->Color.IndexMask==0) {
+      /* all color index bits disabled */
+      ctx->RasterMask |= MULTI_DRAW_BIT;
+      ctx->TriangleCaps |= DD_MULTIDRAW;
+      ctx->Color.DrawDestMask = 0;
+   }
+}
+
+
+void gl_print_state( const char *msg, GLuint state )
+{
+   fprintf(stderr,
+          "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
+          msg,
+          state,
+          (state & NEW_LIGHTING)         ? "lighting, " : "",
+          (state & NEW_RASTER_OPS)       ? "raster-ops, " : "",
+          (state & NEW_TEXTURING)        ? "texturing, " : "",
+          (state & NEW_POLYGON)          ? "polygon, " : "",
+          (state & NEW_DRVSTATE0)        ? "driver-0, " : "",
+          (state & NEW_DRVSTATE1)        ? "driver-1, " : "",
+          (state & NEW_DRVSTATE2)        ? "driver-2, " : "",
+          (state & NEW_DRVSTATE3)        ? "driver-3, " : "",
+          (state & NEW_MODELVIEW)        ? "modelview, " : "",
+          (state & NEW_PROJECTION)       ? "projection, " : "",
+          (state & NEW_TEXTURE_MATRIX)   ? "texture-matrix, " : "",
+          (state & NEW_USER_CLIP)        ? "user-clip, " : "",
+          (state & NEW_TEXTURE_ENV)      ? "texture-env, " : "",
+          (state & NEW_CLIENT_STATE)     ? "client-state, " : "",
+          (state & NEW_FOG)              ? "fog, " : "",
+          (state & NEW_NORMAL_TRANSFORM) ? "normal-transform, " : "",
+          (state & NEW_VIEWPORT)         ? "viewport, " : "",
+          (state & NEW_TEXTURE_ENABLE)   ? "texture-enable, " : "");
+}
+
+void gl_print_enable_flags( const char *msg, GLuint flags )
+{
+   fprintf(stderr,
+          "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s\n",
+          msg,
+          flags,
+          (flags & ENABLE_TEX0)       ? "tex-0, " : "",
+          (flags & ENABLE_TEX1)       ? "tex-1, " : "",
+          (flags & ENABLE_LIGHT)      ? "light, " : "",
+          (flags & ENABLE_FOG)        ? "fog, " : "",
+          (flags & ENABLE_USERCLIP)   ? "userclip, " : "",
+          (flags & ENABLE_TEXGEN0)    ? "tex-gen-0, " : "",
+          (flags & ENABLE_TEXGEN1)    ? "tex-gen-1, " : "",
+          (flags & ENABLE_TEXMAT0)    ? "tex-mat-0, " : "",
+          (flags & ENABLE_TEXMAT1)    ? "tex-mat-1, " : "",
+          (flags & ENABLE_NORMALIZE)  ? "normalize, " : "",
+          (flags & ENABLE_RESCALE)    ? "rescale, " : "");
+}
+
+
+/*
+ * If ctx->NewState is non-zero then this function MUST be called before
+ * rendering any primitive.  Basically, function pointers and miscellaneous
+ * flags are updated to reflect the current state of the state machine.
+ */
+void gl_update_state( GLcontext *ctx )
+{
+   GLuint i;
+
+   if (MESA_VERBOSE & VERBOSE_STATE)
+      gl_print_state("", ctx->NewState);
+
+   if (ctx->NewState & NEW_CLIENT_STATE)
+      gl_update_client_state( ctx );
+
+   if ((ctx->NewState & NEW_TEXTURE_ENABLE) &&
+       (ctx->Enabled & ENABLE_TEX_ANY) != ctx->Texture.Enabled)
+      ctx->NewState |= NEW_TEXTURING | NEW_RASTER_OPS;
+
+   if (ctx->NewState & NEW_TEXTURE_ENV) {
+      if (ctx->Texture.Unit[0].EnvMode == ctx->Texture.Unit[0].LastEnvMode &&
+         ctx->Texture.Unit[1].EnvMode == ctx->Texture.Unit[1].LastEnvMode)
+        ctx->NewState &= ~NEW_TEXTURE_ENV;
+      ctx->Texture.Unit[0].LastEnvMode = ctx->Texture.Unit[0].EnvMode;
+      ctx->Texture.Unit[1].LastEnvMode = ctx->Texture.Unit[1].EnvMode;
+   }
+
+   if ((ctx->NewState & ~(NEW_CLIENT_STATE|NEW_TEXTURE_ENABLE)) == 0)
+      goto finished;
+
+   if (ctx->NewState & NEW_TEXTURE_MATRIX) {
+      ctx->Enabled &= ~(ENABLE_TEXMAT0|ENABLE_TEXMAT1);
+
+      for (i=0; i < MAX_TEXTURE_UNITS; i++) {
+        if (ctx->TextureMatrix[i].flags & MAT_DIRTY_ALL_OVER)
+        {
+           gl_matrix_analyze( &ctx->TextureMatrix[i] );
+           ctx->TextureMatrix[i].flags &= ~MAT_DIRTY_DEPENDENTS;
+
+           if (ctx->Texture.Unit[i].Enabled &&
+               ctx->TextureMatrix[i].type != MATRIX_IDENTITY)
+              ctx->Enabled |= ENABLE_TEXMAT0 << i;
+        }
+      }
+   }
+
+   if (ctx->NewState & NEW_TEXTURING) {
+      ctx->Texture.NeedNormals = GL_FALSE;
+      gl_update_dirty_texobjs(ctx);
+      ctx->Enabled &= ~(ENABLE_TEXGEN0|ENABLE_TEXGEN1);
+      ctx->Texture.ReallyEnabled = 0;
+
+      for (i=0; i < MAX_TEXTURE_UNITS; i++) {
+        if (ctx->Texture.Unit[i].Enabled) {
+           gl_update_texture_unit( ctx, &ctx->Texture.Unit[i] );
+
+           ctx->Texture.ReallyEnabled |=
+              ctx->Texture.Unit[i].ReallyEnabled<<(i*4);
+
+           if (ctx->Texture.Unit[i].GenFlags != 0) {
+              ctx->Enabled |= ENABLE_TEXGEN0 << i;
+
+              if (ctx->Texture.Unit[i].GenFlags & TEXGEN_NEED_NORMALS)
+              {
+                 ctx->Texture.NeedNormals = GL_TRUE;
+                 ctx->Texture.NeedEyeCoords = GL_TRUE;
+              }
+
+              if (ctx->Texture.Unit[i].GenFlags & TEXGEN_NEED_EYE_COORD)
+              {
+                 ctx->Texture.NeedEyeCoords = GL_TRUE;
+              }
+           }
+        }
+      }
+
+      ctx->Texture.Enabled = ctx->Enabled & ENABLE_TEX_ANY;
+      ctx->NeedNormals = (ctx->Light.Enabled || ctx->Texture.NeedNormals);
+   }
+
+   if (ctx->NewState & (NEW_RASTER_OPS | NEW_LIGHTING)) {
+      if (ctx->NewState & NEW_RASTER_OPS) {
+        update_pixel_logic(ctx);
+        update_pixel_masking(ctx);
+        update_fog_mode(ctx);
+        update_rasterflags(ctx);
+        if (ctx->Driver.Dither) {
+           (*ctx->Driver.Dither)( ctx, ctx->Color.DitherFlag );
+        }
+
+        /* Check if incoming colors can be modified during rasterization */
+        if (ctx->Fog.Enabled ||
+            ctx->Texture.Enabled ||
+            ctx->Color.BlendEnabled ||
+            ctx->Color.SWmasking ||
+            ctx->Color.SWLogicOpEnabled) {
+           ctx->MutablePixels = GL_TRUE;
+        }
+        else {
+           ctx->MutablePixels = GL_FALSE;
+        }
+
+        /* update scissor region */
+
+        ctx->Buffer->Xmin = 0;
+        ctx->Buffer->Ymin = 0;
+        ctx->Buffer->Xmax = ctx->Buffer->Width-1;
+        ctx->Buffer->Ymax = ctx->Buffer->Height-1;
+        if (ctx->Scissor.Enabled) {
+           if (ctx->Scissor.X > ctx->Buffer->Xmin) {
+              ctx->Buffer->Xmin = ctx->Scissor.X;
+           }
+           if (ctx->Scissor.Y > ctx->Buffer->Ymin) {
+              ctx->Buffer->Ymin = ctx->Scissor.Y;
+           }
+           if (ctx->Scissor.X + ctx->Scissor.Width - 1 < ctx->Buffer->Xmax) {
+              ctx->Buffer->Xmax = ctx->Scissor.X + ctx->Scissor.Width - 1;
+           }
+           if (ctx->Scissor.Y + ctx->Scissor.Height - 1 < ctx->Buffer->Ymax) {
+              ctx->Buffer->Ymax = ctx->Scissor.Y + ctx->Scissor.Height - 1;
+           }
+        }
+
+        /*
+         * Update Device Driver interface
+         */
+        ctx->Driver.AllocDepthBuffer = gl_alloc_depth_buffer;
+        if (ctx->Depth.Mask) {
+           switch (ctx->Depth.Func) {
+           case GL_LESS:
+              ctx->Driver.DepthTestSpan = gl_depth_test_span_less;
+              ctx->Driver.DepthTestPixels = gl_depth_test_pixels_less;
+              break;
+           case GL_GREATER:
+              ctx->Driver.DepthTestSpan = gl_depth_test_span_greater;
+              ctx->Driver.DepthTestPixels = gl_depth_test_pixels_greater;
+              break;
+           default:
+              ctx->Driver.DepthTestSpan = gl_depth_test_span_generic;
+              ctx->Driver.DepthTestPixels = gl_depth_test_pixels_generic;
+           }
+        }
+        else {
+           ctx->Driver.DepthTestSpan = gl_depth_test_span_generic;
+           ctx->Driver.DepthTestPixels = gl_depth_test_pixels_generic;
+        }
+        ctx->Driver.ReadDepthSpanFloat = gl_read_depth_span_float;
+        ctx->Driver.ReadDepthSpanInt = gl_read_depth_span_int;
+      }
+
+      if (ctx->NewState & NEW_LIGHTING) {
+        ctx->TriangleCaps &= ~(DD_TRI_LIGHT_TWOSIDE|DD_EARLY_CULL);
+        if (ctx->Light.Enabled) {
+           if (ctx->Light.Model.TwoSide)
+              ctx->TriangleCaps |= (DD_TRI_LIGHT_TWOSIDE|DD_EARLY_CULL);
+           gl_update_lighting(ctx);
+        }
+      }
+   }
+
+   if (ctx->NewState & (NEW_POLYGON | NEW_LIGHTING)) {
+
+
+      if (ctx->NewState & NEW_POLYGON) {
+        /* Setup CullBits bitmask */
+        if (ctx->Polygon.CullFlag) {
+           switch(ctx->Polygon.CullFaceMode) {
+           case GL_FRONT:
+              ctx->Polygon.CullBits = 2;
+              break;
+           case GL_BACK:
+              ctx->Polygon.CullBits = 1;
+              break;
+           default:
+           case GL_FRONT_AND_BACK:
+              ctx->Polygon.CullBits = 3;
+              break;
+           }
+        }
+        else
+           ctx->Polygon.CullBits = 3;
+
+        /* Any Polygon offsets enabled? */
+        ctx->TriangleCaps &= ~DD_TRI_OFFSET;
+
+        if (ctx->Polygon.OffsetPoint ||
+            ctx->Polygon.OffsetLine ||
+            ctx->Polygon.OffsetFill)
+           ctx->TriangleCaps |= DD_TRI_OFFSET;
+
+        /* reset Z offsets now */
+        ctx->PointZoffset   = 0.0;
+        ctx->LineZoffset    = 0.0;
+        ctx->PolygonZoffset = 0.0;
+      }
+   }
+
+   if (ctx->NewState & ~(NEW_CLIENT_STATE|NEW_TEXTURE_ENABLE|
+                        NEW_DRIVER_STATE|NEW_USER_CLIP|
+                        NEW_POLYGON))
+      gl_update_clipmask(ctx);
+
+   if (ctx->NewState & (NEW_LIGHTING|
+                       NEW_RASTER_OPS|
+                       NEW_TEXTURING|
+                       NEW_TEXTURE_ENV|
+                       NEW_POLYGON|
+                       NEW_DRVSTATE0|
+                       NEW_DRVSTATE1|
+                       NEW_DRVSTATE2|
+                       NEW_DRVSTATE3|
+                       NEW_USER_CLIP))
+   {
+      ctx->IndirectTriangles = ctx->TriangleCaps & ~ctx->Driver.TriangleCaps;
+      ctx->IndirectTriangles |= DD_SW_RASTERIZE;
+
+      ctx->Driver.PointsFunc = NULL;
+      ctx->Driver.LineFunc = NULL;
+      ctx->Driver.TriangleFunc = NULL;
+      ctx->Driver.QuadFunc = NULL;
+      ctx->Driver.RectFunc = NULL;
+      ctx->Driver.RenderVBClippedTab = NULL;
+      ctx->Driver.RenderVBCulledTab = NULL;
+      ctx->Driver.RenderVBRawTab = NULL;
+
+      /*
+       * Here the driver sets up all the ctx->Driver function pointers to
+       * it's specific, private functions.
+       */
+      ctx->Driver.UpdateState(ctx);
+
+      /*
+       * In case the driver didn't hook in an optimized point, line or
+       * triangle function we'll now select "core/fallback" point, line
+       * and triangle functions.
+       */
+      if (ctx->IndirectTriangles & DD_SW_RASTERIZE) {
+        gl_set_point_function(ctx);
+        gl_set_line_function(ctx);
+        gl_set_triangle_function(ctx);
+        gl_set_quad_function(ctx);
+      }
+
+      gl_set_render_vb_function(ctx);
+   }
+
+   /* Should only be calc'd when !need_eye_coords and not culling.
+    */
+   if (ctx->NewState & (NEW_MODELVIEW|NEW_PROJECTION)) {
+      if (ctx->NewState & NEW_MODELVIEW) {
+        gl_matrix_analyze( &ctx->ModelView );
+        ctx->ProjectionMatrix.flags &= ~MAT_DIRTY_DEPENDENTS;
+      }
+
+      if (ctx->NewState & NEW_PROJECTION) {
+        gl_matrix_analyze( &ctx->ProjectionMatrix );
+        ctx->ProjectionMatrix.flags &= ~MAT_DIRTY_DEPENDENTS;
+
+        if (ctx->Transform.AnyClip) {
+           gl_update_userclip( ctx );
+        }
+      }
+
+      gl_calculate_model_project_matrix( ctx );
+      ctx->ModelProjectWinMatrixUptodate = 0;
+   }
+
+   /* Figure out whether we can light in object space or not.  If we
+    * can, find the current positions of the lights in object space
+    */
+   if ((ctx->Enabled & (ENABLE_POINT_ATTEN | ENABLE_LIGHT | 
+                       ENABLE_TEXGEN0 | ENABLE_TEXGEN1)) &&
+       (ctx->NewState & (NEW_LIGHTING | 
+                        NEW_MODELVIEW | 
+                        NEW_PROJECTION |
+                        NEW_TEXTURING |
+                        NEW_RASTER_OPS |
+                        NEW_USER_CLIP)))
+   {
+      GLboolean oldcoord, oldnorm;
+
+      oldcoord = ctx->NeedEyeCoords;
+      oldnorm = ctx->NeedEyeNormals;
+
+      ctx->NeedNormals = (ctx->Light.Enabled || ctx->Texture.NeedNormals);
+      ctx->NeedEyeCoords = ((ctx->Fog.Enabled && ctx->Hint.Fog != GL_NICEST) ||
+                           ctx->Point.Attenuated);
+      ctx->NeedEyeNormals = GL_FALSE;
+
+      if (ctx->Light.Enabled) {
+        if (ctx->Light.Flags & LIGHT_POSITIONAL) {
+           /* Need length for attenuation */
+           if (!TEST_MAT_FLAGS( &ctx->ModelView, MAT_FLAGS_LENGTH_PRESERVING))
+              ctx->NeedEyeCoords = GL_TRUE;
+        } else if (ctx->Light.NeedVertices) {
+           /* Need angle for spot calculations */
+           if (!TEST_MAT_FLAGS( &ctx->ModelView, MAT_FLAGS_ANGLE_PRESERVING))
+              ctx->NeedEyeCoords = GL_TRUE;
+        }
+        ctx->NeedEyeNormals = ctx->NeedEyeCoords;
+      }
+      if (ctx->Texture.Enabled || ctx->RenderMode==GL_FEEDBACK) {
+        if (ctx->Texture.NeedEyeCoords) ctx->NeedEyeCoords = GL_TRUE;
+        if (ctx->Texture.NeedNormals)
+           ctx->NeedNormals = ctx->NeedEyeNormals = GL_TRUE;
+      }
+
+      ctx->vb_proj_matrix = &ctx->ModelProjectMatrix;
+
+      if (ctx->NeedEyeCoords)
+        ctx->vb_proj_matrix = &ctx->ProjectionMatrix;
+
+      if (ctx->Light.Enabled) {
+        gl_update_lighting_function(ctx);
+
+        if ( (ctx->NewState & NEW_LIGHTING) ||
+             ((ctx->NewState & (NEW_MODELVIEW| NEW_PROJECTION)) &&
+              !ctx->NeedEyeCoords) ||
+             oldcoord != ctx->NeedEyeCoords ||
+             oldnorm != ctx->NeedEyeNormals) {
+           gl_compute_light_positions(ctx);
+        }
+
+        ctx->rescale_factor = 1.0F;
+
+        if (ctx->ModelView.flags & (MAT_FLAG_UNIFORM_SCALE |
+                                    MAT_FLAG_GENERAL_SCALE |
+                                    MAT_FLAG_GENERAL_3D |
+                                    MAT_FLAG_GENERAL) )
+
+        {
+           GLfloat *m = ctx->ModelView.inv;
+           GLfloat f = m[2]*m[2] + m[6]*m[6] + m[10]*m[10];
+           if (f > 1e-12 && (f-1)*(f-1) > 1e-12)
+              ctx->rescale_factor = 1.0/GL_SQRT(f);
+        }
+      }
+
+      gl_update_normal_transform( ctx );
+   }
+
+ finished:
+   gl_update_pipelines(ctx);
+   ctx->NewState = 0;
+}
diff --git a/src/mesa/main/context.h b/src/mesa/main/context.h
new file mode 100644 (file)
index 0000000..f136da4
--- /dev/null
@@ -0,0 +1,167 @@
+/* $Id: context.h,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+#ifndef CONTEXT_H
+#define CONTEXT_H
+
+
+#include "types.h"
+
+
+
+#ifdef THREADS
+   /*
+    * A seperate GLcontext for each thread
+    */
+   extern GLcontext *gl_get_thread_context( void );
+#else
+   /*
+    * All threads use same pointer to current context.
+    */
+   extern GLcontext *CC;
+   extern struct immediate *CURRENT_INPUT;
+#endif
+
+
+
+/*
+ * There are three Mesa datatypes which are meant to be used by device
+ * drivers:
+ *   GLcontext:  this contains the Mesa rendering state
+ *   GLvisual:  this describes the color buffer (rgb vs. ci), whether
+ *              or not there's a depth buffer, stencil buffer, etc.
+ *   GLframebuffer:  contains pointers to the depth buffer, stencil
+ *                   buffer, accum buffer and alpha buffers.
+ *
+ * These types should be encapsulated by corresponding device driver
+ * datatypes.  See xmesa.h and xmesaP.h for an example.
+ *
+ * In OOP terms, GLcontext, GLvisual, and GLframebuffer are base classes
+ * which the device driver must derive from.
+ *
+ * The following functions create and destroy these datatypes.
+ */
+
+
+/*
+ * Create/destroy a GLvisual.  A GLvisual is like a GLX visual.  It describes
+ * the colorbuffer, depth buffer, stencil buffer and accum buffer which will
+ * be used by the GL context and framebuffer.
+ */
+extern GLvisual *gl_create_visual( GLboolean rgbFlag,
+                                   GLboolean alphaFlag,
+                                   GLboolean dbFlag,
+                                   GLboolean stereoFlag,
+                                   GLint depthBits,
+                                   GLint stencilBits,
+                                   GLint accumBits,
+                                   GLint indexBits,
+                                   GLint redBits,
+                                   GLint greenBits,
+                                   GLint blueBits,
+                                   GLint alphaBits );
+
+extern void gl_destroy_visual( GLvisual *vis );
+
+
+/*
+ * Create/destroy a GLcontext.  A GLcontext is like a GLX context.  It
+ * contains the rendering state.
+ */
+extern GLcontext *gl_create_context( GLvisual *visual,
+                                     GLcontext *share_list,
+                                     void *driver_ctx,
+                                     GLboolean direct);
+
+extern void gl_destroy_context( GLcontext *ctx );
+
+/* Called by the driver after both the context and driver are fully
+ * initialized.  Currently just reads the config file.
+ */
+extern void gl_context_initialize( GLcontext *ctx );
+
+/*
+ * Create/destroy a GLframebuffer.  A GLframebuffer is like a GLX drawable.
+ * It bundles up the depth buffer, stencil buffer and accum buffers into a
+ * single entity.
+ */
+extern GLframebuffer *gl_create_framebuffer( GLvisual *visual );
+
+extern void gl_destroy_framebuffer( GLframebuffer *buffer );
+
+
+
+extern void gl_make_current( GLcontext *ctx, GLframebuffer *buffer );
+
+extern GLcontext *gl_get_current_context(void);
+
+extern void gl_copy_context(const GLcontext *src, GLcontext *dst, GLuint mask);
+
+extern void gl_set_api_table( GLcontext *ctx, const struct gl_api_table *api );
+
+
+
+/*
+ * GL_MESA_resize_buffers extension
+ */
+extern void gl_ResizeBuffersMESA( GLcontext *ctx );
+
+
+
+/*
+ * Miscellaneous
+ */
+
+extern void gl_problem( const GLcontext *ctx, const char *s );
+
+extern void gl_warning( const GLcontext *ctx, const char *s );
+
+extern void gl_error( GLcontext *ctx, GLenum error, const char *s );
+extern void gl_compile_error( GLcontext *ctx, GLenum error, const char *s );
+
+extern GLenum gl_GetError( GLcontext *ctx );
+
+
+extern void gl_update_state( GLcontext *ctx );
+
+
+/* for debugging */
+extern void gl_print_state( const char *msg, GLuint state );
+
+/* for debugging */
+extern void gl_print_enable_flags( const char *msg, GLuint flags );
+
+
+#ifdef PROFILE
+extern GLdouble gl_time( void );
+#endif
+
+
+#endif
diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
new file mode 100644 (file)
index 0000000..479d73e
--- /dev/null
@@ -0,0 +1,635 @@
+/* $Id: dd.h,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+#ifndef DD_INCLUDED
+#define DD_INCLUDED
+
+
+#include "macros.h"
+
+
+struct gl_pixelstore_attrib;
+
+
+struct vertex_buffer;
+struct immediate;
+struct gl_pipeline_stage;
+
+
+/* THIS FILE ONLY INCLUDED BY types.h !!!!! */
+
+
+/*
+ *                      Device Driver (DD) interface
+ *
+ *
+ * All device driver functions are accessed through pointers in the
+ * dd_function_table struct (defined below) which is stored in the GLcontext
+ * struct.  Since the device driver is strictly accessed trough a table of
+ * function pointers we can:
+ *   1. switch between a number of different device drivers at runtime.
+ *   2. use optimized functions dependant on current rendering state or
+ *      frame buffer configuration.
+ *
+ * The function pointers in the dd_function_table struct are divided into
+ * two groups:  mandatory and optional.
+ * Mandatory functions have to be implemented by every device driver.
+ * Optional functions may or may not be implemented by the device driver.
+ * The optional functions provide ways to take advantage of special hardware
+ * or optimized algorithms.
+ *
+ * The function pointers in the dd_function_table struct are first
+ * initialized in the "MakeCurrent" function.  The "MakeCurrent" function
+ * is a little different in each device driver.  See the X/Mesa, GLX, or
+ * OS/Mesa drivers for examples.
+ *
+ * Later, Mesa may call the dd_function_table's UpdateState() function.
+ * This function should initialize the dd_function_table's pointers again.
+ * The UpdateState() function is called whenever the core (GL) rendering
+ * state is changed in a way which may effect rasterization.  For example,
+ * the TriangleFunc() pointer may have to point to different functions
+ * depending on whether smooth or flat shading is enabled.
+ *
+ * Note that the first argument to every device driver function is a
+ * GLcontext *.  In turn, the GLcontext->DriverCtx pointer points to
+ * the driver-specific context struct.  See the X/Mesa or OS/Mesa interface
+ * for an example.
+ *
+ * For more information about writing a device driver see the ddsample.c
+ * file and other device drivers (xmesa[123].c, osmesa.c, etc) for examples.
+ *
+ *
+ * Look below in the dd_function_table struct definition for descriptions
+ * of each device driver function.
+ * 
+ *
+ * In the future more function pointers may be added for glReadPixels
+ * glCopyPixels, etc.
+ *
+ *
+ * Notes:
+ * ------
+ *   RGBA = red/green/blue/alpha
+ *   CI = color index (color mapped mode)
+ *   mono = all pixels have the same color or index
+ *
+ *   The write_ functions all take an array of mask flags which indicate
+ *   whether or not the pixel should be written.  One special case exists
+ *   in the write_color_span function: if the mask array is NULL, then
+ *   draw all pixels.  This is an optimization used for glDrawPixels().
+ *
+ * IN ALL CASES:
+ *      X coordinates start at 0 at the left and increase to the right
+ *      Y coordinates start at 0 at the bottom and increase upward
+ *
+ */
+
+
+
+
+/* Used by the GetParameteri device driver function */
+#define DD_HAVE_HARDWARE_FOG         3
+
+
+
+
+
+/*
+ * Device Driver function table.
+ */
+struct dd_function_table {
+
+   /**********************************************************************
+    *** Mandatory functions:  these functions must be implemented by   ***
+    *** every device driver.                                           ***
+    **********************************************************************/
+
+   const char * (*RendererString)(void);
+   /*
+    * Return a string which uniquely identifies this device driver.
+    * The string should contain no whitespace.  Examples: "X11" "OffScreen"
+    * "MSWindows" "SVGA".
+    * NOTE: This function will be obsolete in favor of GetString in the future!
+    */
+
+   void (*UpdateState)( GLcontext *ctx );
+   /*
+    * UpdateState() is called whenver Mesa thinks the device driver should
+    * update its state and/or the other pointers (such as PointsFunc,
+    * LineFunc, or TriangleFunc).
+    */
+
+   void (*ClearIndex)( GLcontext *ctx, GLuint index );
+   /*
+    * Called whenever glClearIndex() is called.  Set the index for clearing
+    * the color buffer.
+    */
+
+   void (*ClearColor)( GLcontext *ctx, GLubyte red, GLubyte green,
+                                        GLubyte blue, GLubyte alpha );
+   /*
+    * Called whenever glClearColor() is called.  Set the color for clearing
+    * the color buffer.
+    */
+
+   GLbitfield (*Clear)( GLcontext *ctx, GLbitfield mask, GLboolean all,
+                        GLint x, GLint y, GLint width, GLint height );
+   /* Clear the color/depth/stencil/accum buffer(s).
+    * 'mask' indicates which buffers need to be cleared.  Return a bitmask
+    *    indicating which buffers weren't cleared by the driver function.
+    * If 'all' is true then the clear the whole buffer, else clear the
+    *    region defined by (x,y,width,height).
+    */
+
+   void (*Index)( GLcontext *ctx, GLuint index );
+   /*
+    * Sets current color index for drawing flat-shaded primitives.
+    */
+
+   void (*Color)( GLcontext *ctx,
+                  GLubyte red, GLubyte green, GLubyte glue, GLubyte alpha );
+   /*
+    * Sets current color for drawing flat-shaded primitives.
+    */
+
+   GLboolean (*SetBuffer)( GLcontext *ctx, GLenum buffer );
+   /*
+    * Selects the color buffer(s) for reading and writing.
+    * The following values must be accepted when applicable:
+    *    GL_FRONT_LEFT - this buffer always exists
+    *    GL_BACK_LEFT - when double buffering
+    *    GL_FRONT_RIGHT - when using stereo
+    *    GL_BACK_RIGHT - when using stereo and double buffering
+    * The folowing values may optionally be accepted.  Return GL_TRUE
+    * if accepted, GL_FALSE if not accepted.  In practice, only drivers
+    * which can write to multiple color buffers at once should accept
+    * these values.
+    *    GL_FRONT - write to front left and front right if it exists
+    *    GL_BACK - write to back left and back right if it exists
+    *    GL_LEFT - write to front left and back left if it exists
+    *    GL_RIGHT - write to right left and back right if they exist
+    *    GL_FRONT_AND_BACK - write to all four buffers if they exist
+    *    GL_NONE - disable buffer write in device driver.
+    */
+
+   void (*GetBufferSize)( GLcontext *ctx,
+                          GLuint *width, GLuint *height );
+   /*
+    * Returns the width and height of the current color buffer.
+    */
+
+
+   /***
+    *** Functions for writing pixels to the frame buffer:
+    ***/
+
+   void (*WriteRGBASpan)( const GLcontext *ctx,
+                          GLuint n, GLint x, GLint y,
+                          CONST GLubyte rgba[][4], const GLubyte mask[] );
+   void (*WriteRGBSpan)( const GLcontext *ctx,
+                         GLuint n, GLint x, GLint y,
+                         CONST GLubyte rgb[][3], const GLubyte mask[] );
+   /* Write a horizontal run of RGB[A] pixels.  The later version is only
+    * used to accelerate GL_RGB, GL_UNSIGNED_BYTE glDrawPixels() calls.
+    */
+
+   void (*WriteMonoRGBASpan)( const GLcontext *ctx, GLuint n, GLint x, GLint y,
+                              const GLubyte mask[] );
+   /* Write a horizontal run of mono-RGBA pixels.
+    */
+
+   void (*WriteRGBAPixels)( const GLcontext *ctx,
+                            GLuint n, const GLint x[], const GLint y[],
+                            CONST GLubyte rgba[][4], const GLubyte mask[] );
+   /* Write array of RGBA pixels at random locations.
+    */
+
+   void (*WriteMonoRGBAPixels)( const GLcontext *ctx,
+                                GLuint n, const GLint x[], const GLint y[],
+                                const GLubyte mask[] );
+   /* Write an array of mono-RGBA pixels at random locations.
+    */
+
+   void (*WriteCI32Span)( const GLcontext *ctx, GLuint n, GLint x, GLint y,
+                          const GLuint index[], const GLubyte mask[] );
+   void (*WriteCI8Span)( const GLcontext *ctx, GLuint n, GLint x, GLint y,
+                         const GLubyte index[], const GLubyte mask[] );
+   /* Write a horizontal run of CI pixels.  32 or 8bpp.
+    */
+
+   void (*WriteMonoCISpan)( const GLcontext *ctx, GLuint n, GLint x, GLint y,
+                            const GLubyte mask[] );
+   /* Write a horizontal run of mono-CI pixels.
+    */
+
+   void (*WriteCI32Pixels)( const GLcontext *ctx,
+                            GLuint n, const GLint x[], const GLint y[],
+                            const GLuint index[], const GLubyte mask[] );
+   /*
+    * Write a random array of CI pixels.
+    */
+
+   void (*WriteMonoCIPixels)( const GLcontext *ctx,
+                              GLuint n, const GLint x[], const GLint y[],
+                              const GLubyte mask[] );
+   /*
+    * Write a random array of mono-CI pixels.
+    */
+
+
+   /***
+    *** Functions to read pixels from frame buffer:
+    ***/
+
+   void (*ReadCI32Span)( const GLcontext *ctx,
+                         GLuint n, GLint x, GLint y, GLuint index[] );
+   /* Read a horizontal run of color index pixels.
+    */
+
+   void (*ReadRGBASpan)( const GLcontext *ctx, GLuint n, GLint x, GLint y,
+                         GLubyte rgba[][4] );
+   /* Read a horizontal run of RGBA pixels.
+    */
+
+   void (*ReadCI32Pixels)( const GLcontext *ctx,
+                           GLuint n, const GLint x[], const GLint y[],
+                           GLuint indx[], const GLubyte mask[] );
+   /* Read a random array of CI pixels.
+    */
+
+   void (*ReadRGBAPixels)( const GLcontext *ctx,
+                           GLuint n, const GLint x[], const GLint y[],
+                           GLubyte rgba[][4], const GLubyte mask[] );
+   /* Read a random array of RGBA pixels.
+    */
+
+
+   /**********************************************************************
+    *** Optional functions:  these functions may or may not be         ***
+    *** implemented by the device driver.  If the device driver        ***
+    *** doesn't implement them it should never touch these pointers    ***
+    *** since Mesa will either set them to NULL or point them at a     ***
+    *** fall-back function.                                            ***
+    **********************************************************************/
+
+   const char * (*ExtensionString)( GLcontext *ctx );
+   /* Return a space-separated list of extensions for this driver.
+    * NOTE: This function will be obsolete in favor of GetString in the future!
+    */
+
+   const GLubyte * (*GetString)( GLcontext *ctx, GLenum name );
+   /* Return a string as needed by glGetString().
+    * NOTE: This will replace the ExtensionString and RendererString
+    * functions in the future!
+    */
+
+   void (*Finish)( GLcontext *ctx );
+   /*
+    * Called whenever glFinish() is called.
+    */
+
+   void (*Flush)( GLcontext *ctx );
+   /*
+    * Called whenever glFlush() is called.
+    */
+
+   GLboolean (*IndexMask)( GLcontext *ctx, GLuint mask );
+   /*
+    * Implements glIndexMask() if possible, else return GL_FALSE.
+    */
+
+   GLboolean (*ColorMask)( GLcontext *ctx,
+                           GLboolean rmask, GLboolean gmask,
+                           GLboolean bmask, GLboolean amask );
+   /*
+    * Implements glColorMask() if possible, else return GL_FALSE.
+    */
+
+   GLboolean (*LogicOp)( GLcontext *ctx, GLenum op );
+   /*
+    * Implements glLogicOp() if possible, else return GL_FALSE.
+    */
+
+   void (*Dither)( GLcontext *ctx, GLboolean enable );
+   /*
+    * Enable/disable dithering.
+    * NOTE: This function will be removed in the future in favor
+    * of the "Enable" driver function.
+    */
+
+   void (*Error)( GLcontext *ctx );
+   /*
+    * Called whenever an error is generated.  ctx->ErrorValue contains
+    * the error value.
+    */
+
+   void (*NearFar)( GLcontext *ctx, GLfloat nearVal, GLfloat farVal );
+   /*
+    * Called from glFrustum and glOrtho to tell device driver the
+    * near and far clipping plane Z values.  The 3Dfx driver, for example,
+    * uses this.
+    */
+
+   GLint (*GetParameteri)( const GLcontext *ctx, GLint param );
+   /* Query the device driver to get an integer parameter.
+    * Current parameters:
+    *     DD_MAX_TEXTURE_SIZE         return maximum texture size
+    *
+    *     DD_MAX_TEXTURES             number of texture sets/stages, usually 1
+    *
+    *     DD_HAVE_HARDWARE_FOG        the driver should return 1 (0 otherwise)
+    *                                 when the hardware support per fragment
+    *                                 fog for free (like the Voodoo Graphics)
+    *                                 so the Mesa core will start to ever use
+    *                                 per fragment fog
+    */
+
+
+   /***
+    *** For supporting hardware Z buffers:
+    ***/
+
+   void (*AllocDepthBuffer)( GLcontext *ctx );
+   /*
+    * Called when the depth buffer must be allocated or possibly resized.
+    */
+
+   GLuint (*DepthTestSpan)( GLcontext *ctx,
+                            GLuint n, GLint x, GLint y, const GLdepth z[],
+                            GLubyte mask[] );
+   void (*DepthTestPixels)( GLcontext *ctx,
+                            GLuint n, const GLint x[], const GLint y[],
+                            const GLdepth z[], GLubyte mask[] );
+   /*
+    * Apply the depth buffer test to an span/array of pixels and return
+    * an updated pixel mask.  This function is not used when accelerated
+    * point, line, polygon functions are used.
+    */
+
+   void (*ReadDepthSpanFloat)( GLcontext *ctx,
+                               GLuint n, GLint x, GLint y, GLfloat depth[]);
+   void (*ReadDepthSpanInt)( GLcontext *ctx,
+                             GLuint n, GLint x, GLint y, GLdepth depth[] );
+   /*
+    * Return depth values as integers for glReadPixels.
+    * Floats should be returned in the range [0,1].
+    * Ints (GLdepth) values should be in the range [0,MAXDEPTH].
+    */
+
+
+   /***
+    *** Accelerated point, line, polygon, glDrawPixels and glBitmap functions:
+    ***/
+
+   points_func   PointsFunc;
+   line_func     LineFunc;
+   triangle_func TriangleFunc;
+   quad_func     QuadFunc;
+   rect_func     RectFunc;    
+   
+
+   GLboolean (*DrawPixels)( GLcontext *ctx,
+                            GLint x, GLint y, GLsizei width, GLsizei height,
+                            GLenum format, GLenum type,
+                            const struct gl_pixelstore_attrib *unpack,
+                            const GLvoid *pixels );
+   /* Device driver hook for optimized glDrawPixels.  'unpack' describes how
+    * to unpack the source image data.
+    */
+
+   GLboolean (*Bitmap)( GLcontext *ctx,
+                        GLint x, GLint y, GLsizei width, GLsizei height,
+                        const struct gl_pixelstore_attrib *unpack,
+                        const GLubyte *bitmap );
+   /* Device driver hook for optimized glBitmap.  'unpack' describes how
+    * to unpack the source image data.
+    */
+
+   void (*RenderStart)( GLcontext *ctx );
+   void (*RenderFinish)( GLcontext *ctx );
+    /* KW: These replace Begin and End, and have more relaxed semantics.
+     * They are called prior-to and after one or more vb flush, and are
+     * thus decoupled from the gl_begin/gl_end pairs, which are possibly 
+     * more frequent.  If a begin/end pair covers >1 vertex buffer, these
+     * are called at most once for the pair. (a bit broken at present)
+     */
+
+   void (*RasterSetup)( struct vertex_buffer *VB, GLuint start, GLuint end );
+   /* This function, if not NULL, is called whenever new window coordinates
+    * are put in the vertex buffer.  The vertices in question are those n
+    * such that start <= n < end.
+    * The device driver can convert the window coords to its own specialized
+    * format.  The 3Dfx driver uses this.
+    *
+    * Note: Deprecated in favour of RegisterPipelineStages, below.
+    */
+
+
+   render_func *RenderVBClippedTab;
+   render_func *RenderVBCulledTab;
+   render_func *RenderVBRawTab;
+   /* These function tables allow the device driver to rasterize an
+    * entire begin/end group of primitives at once.  See the
+    * gl_render_vb() function in vbrender.c for more details.  
+    */
+
+
+   GLuint TriangleCaps;
+   /* Holds a list of the reasons why we might normally want to call
+    * render_triangle, but which are in fact implemented by the
+    * driver.  The FX driver sets this to DD_TRI_CULL, and will soon
+    * implement DD_TRI_OFFSET.
+    */
+
+
+   GLboolean (*MultipassFunc)( struct vertex_buffer *VB, GLuint passno );
+   /* Driver may request additional render passes by returning GL_TRUE
+    * when this function is called.  This function will be called
+    * after the first pass, and passes will be made until the function
+    * returns GL_FALSE.  If no function is registered, only one pass
+    * is made.  
+    * 
+    * This function will be first invoked with passno == 1.
+    */
+
+   /***
+    *** Texture mapping functions:
+    ***/
+
+   void (*TexEnv)( GLcontext *ctx, GLenum pname, const GLfloat *param );
+   /*
+    * Called whenever glTexEnv*() is called.
+    * Pname will be one of GL_TEXTURE_ENV_MODE or GL_TEXTURE_ENV_COLOR.
+    * If pname is GL_TEXTURE_ENV_MODE then param will be one
+    * of GL_MODULATE, GL_BLEND, GL_DECAL, or GL_REPLACE.
+    */
+
+   void (*TexImage)( GLcontext *ctx, GLenum target,
+                     struct gl_texture_object *tObj, GLint level,
+                     GLint internalFormat,
+                     const struct gl_texture_image *image );
+   /*
+    * Called whenever a texture object's image is changed.
+    *    texObject is the number of the texture object being changed.
+    *    level indicates the mipmap level.
+    *    internalFormat is the format in which the texture is to be stored.
+    *    image is a pointer to a gl_texture_image struct which contains
+    *       the actual image data.
+    */
+
+   void (*TexSubImage)( GLcontext *ctx, GLenum target,
+                        struct gl_texture_object *tObj, GLint level,
+                        GLint xoffset, GLint yoffset,
+                        GLsizei width, GLsizei height,
+                        GLint internalFormat,
+                        const struct gl_texture_image *image );
+   /*
+    * Called from glTexSubImage() to define a sub-region of a texture.
+    */
+
+   void (*TexParameter)( GLcontext *ctx, GLenum target,
+                         struct gl_texture_object *tObj,
+                         GLenum pname, const GLfloat *params );
+   /*
+    * Called whenever glTexParameter*() is called.
+    *    target is GL_TEXTURE_1D or GL_TEXTURE_2D
+    *    texObject is the texture object to modify
+    *    pname is one of GL_TEXTURE_MIN_FILTER, GL_TEXTURE_MAG_FILTER,
+    *       GL_TEXTURE_WRAP_S, GL_TEXTURE_WRAP_T, or GL_TEXTURE_BORDER_COLOR.
+    *    params is dependant on pname.  See man glTexParameter.
+    */
+
+   void (*BindTexture)( GLcontext *ctx, GLenum target,
+                        struct gl_texture_object *tObj );
+   /*
+    * Called whenever glBindTexture() is called.  This specifies which
+    * texture is to be the current one.  No dirty flags will be set.
+    */
+
+   void (*DeleteTexture)( GLcontext *ctx, struct gl_texture_object *tObj );
+   /*
+    * Called when a texture object is about to be deallocated.  Driver
+    * should free anything attached to the DriverData pointers.
+    */
+
+   void (*UpdateTexturePalette)( GLcontext *ctx,
+                                 struct gl_texture_object *tObj );
+   /*
+    * Called when the texture's color lookup table is changed.
+    * If tObj is NULL then the shared texture palette ctx->Texture.Palette
+    * was changed.
+    */
+
+   void (*UseGlobalTexturePalette)( GLcontext *ctx, GLboolean state );
+   /*
+    * Called via glEnable/Disable(GL_SHARED_TEXTURE_PALETTE_EXT)
+    */
+
+   void (*ActiveTexture)( GLcontext *ctx, GLuint texUnitNumber );
+   /*
+    * Called by glActiveTextureARB to set current texture unit.
+    */
+
+
+   /***
+    *** NEW in Mesa 3.x
+    ***/
+
+   void (*RegisterVB)( struct vertex_buffer *VB );
+   void (*UnregisterVB)( struct vertex_buffer *VB );
+   /* Do any processing (eg allocate memory) required to set up a new
+    * vertex_buffer.  
+    */
+
+
+   void (*ResetVB)( struct vertex_buffer *VB );
+   void (*ResetCvaVB)( struct vertex_buffer *VB, GLuint stages );
+   /* Do any reset operations necessary to the driver data associated
+    * with these vertex buffers.
+    */
+
+   GLuint RenderVectorFlags;
+   /* What do the render tables require of the vectors they deal
+    * with?  
+    */
+
+   GLuint (*RegisterPipelineStages)( struct gl_pipeline_stage *out,
+                                    const struct gl_pipeline_stage *in,
+                                    GLuint nr );
+   /* Register new pipeline stages, or modify existing ones.  See also
+    * the OptimizePipeline() functions.
+    */
+
+
+   GLboolean (*BuildPrecalcPipeline)( GLcontext *ctx );
+   GLboolean (*BuildEltPipeline)( GLcontext *ctx );
+   /* Perform the full pipeline build, or return false.
+    */
+
+
+   void (*OptimizePrecalcPipeline)( GLcontext *ctx, struct gl_pipeline *pipe );
+   void (*OptimizeImmediatePipeline)( GLcontext *ctx, struct gl_pipeline *pipe);
+   /* Check to see if a fast path exists for this combination of stages 
+    * in the precalc and immediate (elt) pipelines.
+    */
+
+
+   /*
+    * State-changing functions (drawing functions are above)
+    *
+    * These functions are called by their corresponding OpenGL API functions.
+    * They're ALSO called by the gl_PopAttrib() function!!!
+    * May add more functions like these to the device driver in the future.
+    * This should reduce the amount of state checking that
+    * the driver's UpdateState() function must do.
+    */
+   void (*AlphaFunc)(GLcontext *ctx, GLenum func, GLclampf ref);
+   void (*BlendFunc)(GLcontext *ctx, GLenum sfactor, GLenum dfactor);
+   void (*ClearDepth)(GLcontext *ctx, GLclampd d);
+   void (*CullFace)(GLcontext *ctx, GLenum mode);
+   void (*FrontFace)(GLcontext *ctx, GLenum mode);
+   void (*DepthFunc)(GLcontext *ctx, GLenum func);
+   void (*DepthMask)(GLcontext *ctx, GLboolean flag);
+   void (*DepthRange)(GLcontext *ctx, GLclampd nearval, GLclampd farval);
+   void (*Enable)(GLcontext* ctx, GLenum cap, GLboolean state);
+   void (*Fogfv)(GLcontext *ctx, GLenum pname, const GLfloat *params);
+   void (*Hint)(GLcontext *ctx, GLenum target, GLenum mode);
+   void (*PolygonMode)(GLcontext *ctx, GLenum face, GLenum mode);
+   void (*Scissor)(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h);
+   void (*ShadeModel)(GLcontext *ctx, GLenum mode);
+   void (*ClearStencil)(GLcontext *ctx, GLint s);
+   void (*StencilFunc)(GLcontext *ctx, GLenum func, GLint ref, GLuint mask);
+   void (*StencilMask)(GLcontext *ctx, GLuint mask);
+   void (*StencilOp)(GLcontext *ctx, GLenum fail, GLenum zfail, GLenum zpass);
+   void (*Viewport)(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h);
+};
+
+
+
+#endif
+
diff --git a/src/mesa/main/depth.c b/src/mesa/main/depth.c
new file mode 100644 (file)
index 0000000..6d5a2be
--- /dev/null
@@ -0,0 +1,879 @@
+/* $Id: depth.c,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/*
+ * Depth buffer functions
+ */
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "context.h"
+#include "enums.h"
+#include "depth.h"
+#include "macros.h"
+#include "types.h"
+#ifdef XFree86Server
+#include "GL/xf86glx.h"
+#endif
+#endif
+
+
+
+/**********************************************************************/
+/*****                          API Functions                     *****/
+/**********************************************************************/
+
+
+
+void gl_ClearDepth( GLcontext* ctx, GLclampd depth )
+{
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glClearDepth");
+   ctx->Depth.Clear = (GLfloat) CLAMP( depth, 0.0, 1.0 );
+   if (ctx->Driver.ClearDepth)
+      (*ctx->Driver.ClearDepth)( ctx, ctx->Depth.Clear );
+}
+
+
+
+void gl_DepthFunc( GLcontext* ctx, GLenum func )
+{
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDepthFunc");
+
+   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+      fprintf(stderr, "glDepthFunc %s\n", gl_lookup_enum_by_nr(func));
+
+
+   switch (func) {
+      case GL_NEVER:
+      case GL_LESS:    /* (default) pass if incoming z < stored z */
+      case GL_GEQUAL:
+      case GL_LEQUAL:
+      case GL_GREATER:
+      case GL_NOTEQUAL:
+      case GL_EQUAL:
+      case GL_ALWAYS:
+        if (ctx->Depth.Func != func) {
+           ctx->Depth.Func = func;
+           ctx->NewState |= NEW_RASTER_OPS;
+           if (ctx->Driver.DepthFunc) {
+              (*ctx->Driver.DepthFunc)( ctx, func );
+           }
+        }
+         break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glDepth.Func" );
+   }
+}
+
+
+
+void gl_DepthMask( GLcontext* ctx, GLboolean flag )
+{
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDepthMask");
+
+   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+      fprintf(stderr, "glDepthMask %d\n", flag);
+
+   /*
+    * GL_TRUE indicates depth buffer writing is enabled (default)
+    * GL_FALSE indicates depth buffer writing is disabled
+    */
+   if (ctx->Depth.Mask != flag) {
+      ctx->Depth.Mask = flag;
+      ctx->NewState |= NEW_RASTER_OPS;
+      if (ctx->Driver.DepthMask) {
+        (*ctx->Driver.DepthMask)( ctx, flag );
+      }
+   }
+}
+
+
+
+/**********************************************************************/
+/*****                   Depth Testing Functions                  *****/
+/**********************************************************************/
+
+
+/*
+ * Depth test horizontal spans of fragments.  These functions are called
+ * via ctx->Driver.depth_test_span only.
+ *
+ * Input:  n - number of pixels in the span
+ *         x, y - location of leftmost pixel in span in window coords
+ *         z - array [n] of integer depth values
+ * In/Out:  mask - array [n] of flags (1=draw pixel, 0=don't draw) 
+ * Return:  number of pixels which passed depth test
+ */
+
+
+/*
+ * glDepthFunc( any ) and glDepthMask( GL_TRUE or GL_FALSE ).
+ */
+GLuint gl_depth_test_span_generic( GLcontext* ctx,
+                                   GLuint n, GLint x, GLint y,
+                                   const GLdepth z[],
+                                   GLubyte mask[] )
+{
+   GLdepth *zptr = Z_ADDRESS( ctx, x, y );
+   GLubyte *m = mask;
+   GLuint i;
+   GLuint passed = 0;
+
+   /* switch cases ordered from most frequent to less frequent */
+   switch (ctx->Depth.Func) {
+      case GL_LESS:
+         if (ctx->Depth.Mask) {
+           /* Update Z buffer */
+           for (i=0; i<n; i++,zptr++,m++) {
+              if (*m) {
+                 if (z[i] < *zptr) {
+                    /* pass */
+                    *zptr = z[i];
+                    passed++;
+                 }
+                 else {
+                    /* fail */
+                    *m = 0;
+                 }
+              }
+           }
+        }
+        else {
+           /* Don't update Z buffer */
+           for (i=0; i<n; i++,zptr++,m++) {
+              if (*m) {
+                 if (z[i] < *zptr) {
+                    /* pass */
+                    passed++;
+                 }
+                 else {
+                    *m = 0;
+                 }
+              }
+           }
+        }
+        break;
+      case GL_LEQUAL:
+        if (ctx->Depth.Mask) {
+           /* Update Z buffer */
+           for (i=0;i<n;i++,zptr++,m++) {
+              if (*m) {
+                 if (z[i] <= *zptr) {
+                    *zptr = z[i];
+                    passed++;
+                 }
+                 else {
+                    *m = 0;
+                 }
+              }
+           }
+        }
+        else {
+           /* Don't update Z buffer */
+           for (i=0;i<n;i++,zptr++,m++) {
+              if (*m) {
+                 if (z[i] <= *zptr) {
+                    /* pass */
+                    passed++;
+                 }
+                 else {
+                    *m = 0;
+                 }
+              }
+           }
+        }
+        break;
+      case GL_GEQUAL:
+        if (ctx->Depth.Mask) {
+           /* Update Z buffer */
+           for (i=0;i<n;i++,zptr++,m++) {
+              if (*m) {
+                 if (z[i] >= *zptr) {
+                    *zptr = z[i];
+                    passed++;
+                 }
+                 else {
+                    *m = 0;
+                 }
+              }
+           }
+        }
+        else {
+           /* Don't update Z buffer */
+           for (i=0;i<n;i++,zptr++,m++) {
+              if (*m) {
+                 if (z[i] >= *zptr) {
+                    /* pass */
+                    passed++;
+                 }
+                 else {
+                    *m = 0;
+                 }
+              }
+           }
+        }
+        break;
+      case GL_GREATER:
+        if (ctx->Depth.Mask) {
+           /* Update Z buffer */
+           for (i=0;i<n;i++,zptr++,m++) {
+              if (*m) {
+                 if (z[i] > *zptr) {
+                    *zptr = z[i];
+                    passed++;
+                 }
+                 else {
+                    *m = 0;
+                 }
+              }
+           }
+        }
+        else {
+           /* Don't update Z buffer */
+           for (i=0;i<n;i++,zptr++,m++) {
+              if (*m) {
+                 if (z[i] > *zptr) {
+                    /* pass */
+                    passed++;
+                 }
+                 else {
+                    *m = 0;
+                 }
+              }
+           }
+        }
+        break;
+      case GL_NOTEQUAL:
+        if (ctx->Depth.Mask) {
+           /* Update Z buffer */
+           for (i=0;i<n;i++,zptr++,m++) {
+              if (*m) {
+                 if (z[i] != *zptr) {
+                    *zptr = z[i];
+                    passed++;
+                 }
+                 else {
+                    *m = 0;
+                 }
+              }
+           }
+        }
+        else {
+           /* Don't update Z buffer */
+           for (i=0;i<n;i++,zptr++,m++) {
+              if (*m) {
+                 if (z[i] != *zptr) {
+                    /* pass */
+                    passed++;
+                 }
+                 else {
+                    *m = 0;
+                 }
+              }
+           }
+        }
+        break;
+      case GL_EQUAL:
+        if (ctx->Depth.Mask) {
+           /* Update Z buffer */
+           for (i=0;i<n;i++,zptr++,m++) {
+              if (*m) {
+                 if (z[i] == *zptr) {
+                    *zptr = z[i];
+                    passed++;
+                 }
+                 else {
+                    *m =0;
+                 }
+              }
+           }
+        }
+        else {
+           /* Don't update Z buffer */
+           for (i=0;i<n;i++,zptr++,m++) {
+              if (*m) {
+                 if (z[i] == *zptr) {
+                    /* pass */
+                    passed++;
+                 }
+                 else {
+                    *m =0;
+                 }
+              }
+           }
+        }
+        break;
+      case GL_ALWAYS:
+        if (ctx->Depth.Mask) {
+           /* Update Z buffer */
+           for (i=0;i<n;i++,zptr++,m++) {
+              if (*m) {
+                 *zptr = z[i];
+                 passed++;
+              }
+           }
+        }
+        else {
+           /* Don't update Z buffer or mask */
+           passed = n;
+        }
+        break;
+      case GL_NEVER:
+        for (i=0;i<n;i++) {
+           mask[i] = 0;
+        }
+        break;
+      default:
+         gl_problem(ctx, "Bad depth func in gl_depth_test_span_generic");
+   } /*switch*/
+
+   return passed;
+}
+
+
+
+/*
+ * glDepthFunc(GL_LESS) and glDepthMask(GL_TRUE).
+ */
+GLuint gl_depth_test_span_less( GLcontext* ctx,
+                                GLuint n, GLint x, GLint y, const GLdepth z[],
+                                GLubyte mask[] )
+{
+   GLdepth *zptr = Z_ADDRESS( ctx, x, y );
+   GLuint i;
+   GLuint passed = 0;
+
+   for (i=0; i<n; i++) {
+      if (mask[i]) {
+         if (z[i] < zptr[i]) {
+            /* pass */
+            zptr[i] = z[i];
+            passed++;
+         }
+         else {
+            /* fail */
+            mask[i] = 0;
+         }
+      }
+   }
+   return passed;
+}
+
+
+/*
+ * glDepthFunc(GL_GREATER) and glDepthMask(GL_TRUE).
+ */
+GLuint gl_depth_test_span_greater( GLcontext* ctx,
+                                   GLuint n, GLint x, GLint y,
+                                   const GLdepth z[],
+                                   GLubyte mask[] )
+{
+   GLdepth *zptr = Z_ADDRESS( ctx, x, y );
+   GLuint i;
+   GLuint passed = 0;
+
+   for (i=0; i<n; i++) {
+      if (mask[i]) {
+         if (z[i] > zptr[i]) {
+            /* pass */
+            zptr[i] = z[i];
+            passed++;
+         }
+         else {
+            /* fail */
+            mask[i] = 0;
+         }
+      }
+   }
+   return passed;
+}
+
+
+
+/*
+ * Depth test an array of randomly positioned fragments.
+ */
+
+
+#define ZADDR_SETUP   GLdepth *depthbuffer = ctx->Buffer->Depth; \
+                      GLint width = ctx->Buffer->Width;
+
+#define ZADDR( X, Y )   (depthbuffer + (Y) * width + (X) )
+
+
+
+/*
+ * glDepthFunc( any ) and glDepthMask( GL_TRUE or GL_FALSE ).
+ */
+void gl_depth_test_pixels_generic( GLcontext* ctx,
+                                   GLuint n, const GLint x[], const GLint y[],
+                                   const GLdepth z[], GLubyte mask[] )
+{
+   register GLdepth *zptr;
+   register GLuint i;
+
+   /* switch cases ordered from most frequent to less frequent */
+   switch (ctx->Depth.Func) {
+      case GL_LESS:
+         if (ctx->Depth.Mask) {
+           /* Update Z buffer */
+           for (i=0; i<n; i++) {
+              if (mask[i]) {
+                 zptr = Z_ADDRESS(ctx,x[i],y[i]);
+                 if (z[i] < *zptr) {
+                    /* pass */
+                    *zptr = z[i];
+                 }
+                 else {
+                    /* fail */
+                    mask[i] = 0;
+                 }
+              }
+           }
+        }
+        else {
+           /* Don't update Z buffer */
+           for (i=0; i<n; i++) {
+              if (mask[i]) {
+                 zptr = Z_ADDRESS(ctx,x[i],y[i]);
+                 if (z[i] < *zptr) {
+                    /* pass */
+                 }
+                 else {
+                    /* fail */
+                    mask[i] = 0;
+                 }
+              }
+           }
+        }
+        break;
+      case GL_LEQUAL:
+         if (ctx->Depth.Mask) {
+           /* Update Z buffer */
+           for (i=0; i<n; i++) {
+              if (mask[i]) {
+                 zptr = Z_ADDRESS(ctx,x[i],y[i]);
+                 if (z[i] <= *zptr) {
+                    /* pass */
+                    *zptr = z[i];
+                 }
+                 else {
+                    /* fail */
+                    mask[i] = 0;
+                 }
+              }
+           }
+        }
+        else {
+           /* Don't update Z buffer */
+           for (i=0; i<n; i++) {
+              if (mask[i]) {
+                 zptr = Z_ADDRESS(ctx,x[i],y[i]);
+                 if (z[i] <= *zptr) {
+                    /* pass */
+                 }
+                 else {
+                    /* fail */
+                    mask[i] = 0;
+                 }
+              }
+           }
+        }
+        break;
+      case GL_GEQUAL:
+         if (ctx->Depth.Mask) {
+           /* Update Z buffer */
+           for (i=0; i<n; i++) {
+              if (mask[i]) {
+                 zptr = Z_ADDRESS(ctx,x[i],y[i]);
+                 if (z[i] >= *zptr) {
+                    /* pass */
+                    *zptr = z[i];
+                 }
+                 else {
+                    /* fail */
+                    mask[i] = 0;
+                 }
+              }
+           }
+        }
+        else {
+           /* Don't update Z buffer */
+           for (i=0; i<n; i++) {
+              if (mask[i]) {
+                 zptr = Z_ADDRESS(ctx,x[i],y[i]);
+                 if (z[i] >= *zptr) {
+                    /* pass */
+                 }
+                 else {
+                    /* fail */
+                    mask[i] = 0;
+                 }
+              }
+           }
+        }
+        break;
+      case GL_GREATER:
+         if (ctx->Depth.Mask) {
+           /* Update Z buffer */
+           for (i=0; i<n; i++) {
+              if (mask[i]) {
+                 zptr = Z_ADDRESS(ctx,x[i],y[i]);
+                 if (z[i] > *zptr) {
+                    /* pass */
+                    *zptr = z[i];
+                 }
+                 else {
+                    /* fail */
+                    mask[i] = 0;
+                 }
+              }
+           }
+        }
+        else {
+           /* Don't update Z buffer */
+           for (i=0; i<n; i++) {
+              if (mask[i]) {
+                 zptr = Z_ADDRESS(ctx,x[i],y[i]);
+                 if (z[i] > *zptr) {
+                    /* pass */
+                 }
+                 else {
+                    /* fail */
+                    mask[i] = 0;
+                 }
+              }
+           }
+        }
+        break;
+      case GL_NOTEQUAL:
+         if (ctx->Depth.Mask) {
+           /* Update Z buffer */
+           for (i=0; i<n; i++) {
+              if (mask[i]) {
+                 zptr = Z_ADDRESS(ctx,x[i],y[i]);
+                 if (z[i] != *zptr) {
+                    /* pass */
+                    *zptr = z[i];
+                 }
+                 else {
+                    /* fail */
+                    mask[i] = 0;
+                 }
+              }
+           }
+        }
+        else {
+           /* Don't update Z buffer */
+           for (i=0; i<n; i++) {
+              if (mask[i]) {
+                 zptr = Z_ADDRESS(ctx,x[i],y[i]);
+                 if (z[i] != *zptr) {
+                    /* pass */
+                 }
+                 else {
+                    /* fail */
+                    mask[i] = 0;
+                 }
+              }
+           }
+        }
+        break;
+      case GL_EQUAL:
+         if (ctx->Depth.Mask) {
+           /* Update Z buffer */
+           for (i=0; i<n; i++) {
+              if (mask[i]) {
+                 zptr = Z_ADDRESS(ctx,x[i],y[i]);
+                 if (z[i] == *zptr) {
+                    /* pass */
+                    *zptr = z[i];
+                 }
+                 else {
+                    /* fail */
+                    mask[i] = 0;
+                 }
+              }
+           }
+        }
+        else {
+           /* Don't update Z buffer */
+           for (i=0; i<n; i++) {
+              if (mask[i]) {
+                 zptr = Z_ADDRESS(ctx,x[i],y[i]);
+                 if (z[i] == *zptr) {
+                    /* pass */
+                 }
+                 else {
+                    /* fail */
+                    mask[i] = 0;
+                 }
+              }
+           }
+        }
+        break;
+      case GL_ALWAYS:
+        if (ctx->Depth.Mask) {
+           /* Update Z buffer */
+           for (i=0; i<n; i++) {
+              if (mask[i]) {
+                 zptr = Z_ADDRESS(ctx,x[i],y[i]);
+                 *zptr = z[i];
+              }
+           }
+        }
+        else {
+           /* Don't update Z buffer or mask */
+        }
+        break;
+      case GL_NEVER:
+        /* depth test never passes */
+        for (i=0;i<n;i++) {
+           mask[i] = 0;
+        }
+        break;
+      default:
+         gl_problem(ctx, "Bad depth func in gl_depth_test_pixels_generic");
+   } /*switch*/
+}
+
+
+
+/*
+ * glDepthFunc( GL_LESS ) and glDepthMask( GL_TRUE ).
+ */
+void gl_depth_test_pixels_less( GLcontext* ctx,
+                                GLuint n, const GLint x[], const GLint y[],
+                                const GLdepth z[], GLubyte mask[] )
+{
+   GLdepth *zptr;
+   GLuint i;
+
+   for (i=0; i<n; i++) {
+      if (mask[i]) {
+         zptr = Z_ADDRESS(ctx,x[i],y[i]);
+         if (z[i] < *zptr) {
+            /* pass */
+            *zptr = z[i];
+         }
+         else {
+            /* fail */
+            mask[i] = 0;
+         }
+      }
+   }
+}
+
+
+/*
+ * glDepthFunc( GL_GREATER ) and glDepthMask( GL_TRUE ).
+ */
+void gl_depth_test_pixels_greater( GLcontext* ctx,
+                                   GLuint n, const GLint x[], const GLint y[],
+                                   const GLdepth z[], GLubyte mask[] )
+{
+   GLdepth *zptr;
+   GLuint i;
+
+   for (i=0; i<n; i++) {
+      if (mask[i]) {
+         zptr = Z_ADDRESS(ctx,x[i],y[i]);
+         if (z[i] > *zptr) {
+            /* pass */
+            *zptr = z[i];
+         }
+         else {
+            /* fail */
+            mask[i] = 0;
+         }
+      }
+   }
+}
+
+
+
+
+/**********************************************************************/
+/*****                      Read Depth Buffer                     *****/
+/**********************************************************************/
+
+
+/*
+ * Return a span of depth values from the depth buffer as floats in [0,1].
+ * This function is only called through Driver.read_depth_span_float()
+ * Input:  n - how many pixels
+ *         x,y - location of first pixel
+ * Output:  depth - the array of depth values
+ */
+void gl_read_depth_span_float( GLcontext* ctx,
+                               GLuint n, GLint x, GLint y, GLfloat depth[] )
+{
+   GLdepth *zptr;
+   GLfloat scale;
+   GLuint i;
+
+   scale = 1.0F / DEPTH_SCALE;
+
+   if (ctx->Buffer->Depth) {
+      zptr = Z_ADDRESS( ctx, x, y );
+      for (i=0;i<n;i++) {
+        depth[i] = (GLfloat) zptr[i] * scale;
+      }
+   }
+   else {
+      for (i=0;i<n;i++) {
+        depth[i] = 0.0F;
+      }
+   }
+}
+
+
+/*
+ * Return a span of depth values from the depth buffer as integers in
+ * [0,MAX_DEPTH].
+ * This function is only called through Driver.read_depth_span_int()
+ * Input:  n - how many pixels
+ *         x,y - location of first pixel
+ * Output:  depth - the array of depth values
+ */
+void gl_read_depth_span_int( GLcontext* ctx,
+                             GLuint n, GLint x, GLint y, GLdepth depth[] )
+{
+   if (ctx->Buffer->Depth) {
+      GLdepth *zptr = Z_ADDRESS( ctx, x, y );
+      MEMCPY( depth, zptr, n * sizeof(GLdepth) );
+   }
+   else {
+      GLuint i;
+      for (i=0;i<n;i++) {
+        depth[i] = 0;
+      }
+   }
+}
+
+
+
+/**********************************************************************/
+/*****                Allocate and Clear Depth Buffer             *****/
+/**********************************************************************/
+
+
+
+/*
+ * Allocate a new depth buffer.  If there's already a depth buffer allocated
+ * it will be free()'d.  The new depth buffer will be uniniitalized.
+ * This function is only called through Driver.alloc_depth_buffer.
+ */
+void gl_alloc_depth_buffer( GLcontext* ctx )
+{
+   /* deallocate current depth buffer if present */
+   if (ctx->Buffer->Depth) {
+      free(ctx->Buffer->Depth);
+      ctx->Buffer->Depth = NULL;
+   }
+
+   /* allocate new depth buffer, but don't initialize it */
+   ctx->Buffer->Depth = (GLdepth *) malloc( ctx->Buffer->Width
+                                            * ctx->Buffer->Height
+                                            * sizeof(GLdepth) );
+   if (!ctx->Buffer->Depth) {
+      /* out of memory */
+      ctx->Depth.Test = GL_FALSE;
+      gl_error( ctx, GL_OUT_OF_MEMORY, "Couldn't allocate depth buffer" );
+   }
+}
+
+
+
+
+/*
+ * Clear the depth buffer.  If the depth buffer doesn't exist yet we'll
+ * allocate it now.
+ * This function is only called through Driver.clear_depth_buffer.
+ */
+void gl_clear_depth_buffer( GLcontext* ctx )
+{
+   GLdepth clear_value = (GLdepth) (ctx->Depth.Clear * DEPTH_SCALE);
+   
+   if (ctx->Visual->DepthBits==0 || !ctx->Buffer->Depth || !ctx->Depth.Mask) {
+      /* no depth buffer, or writing to it is disabled */
+      return;
+   }
+
+   /* The loops in this function have been written so the IRIX 5.3
+    * C compiler can unroll them.  Hopefully other compilers can too!
+    */
+
+   if (ctx->Scissor.Enabled) {
+      /* only clear scissor region */
+      GLint y;
+      for (y=ctx->Buffer->Ymin; y<=ctx->Buffer->Ymax; y++) {
+         GLdepth *d = Z_ADDRESS( ctx, ctx->Buffer->Xmin, y );
+         GLint n = ctx->Buffer->Xmax - ctx->Buffer->Xmin + 1;
+         do {
+            *d++ = clear_value;
+            n--;
+         } while (n);
+      }
+   }
+   else {
+      /* clear whole buffer */
+      if (sizeof(GLdepth)==2 && (clear_value&0xff)==(clear_value>>8)) {
+         /* lower and upper bytes of clear_value are same, use MEMSET */
+         MEMSET( ctx->Buffer->Depth, clear_value&0xff,
+                 2*ctx->Buffer->Width*ctx->Buffer->Height);
+      }
+      else {
+         GLdepth *d = ctx->Buffer->Depth;
+         GLint n = ctx->Buffer->Width * ctx->Buffer->Height;
+         while (n>=16) {
+            d[0] = clear_value;    d[1] = clear_value;
+            d[2] = clear_value;    d[3] = clear_value;
+            d[4] = clear_value;    d[5] = clear_value;
+            d[6] = clear_value;    d[7] = clear_value;
+            d[8] = clear_value;    d[9] = clear_value;
+            d[10] = clear_value;   d[11] = clear_value;
+            d[12] = clear_value;   d[13] = clear_value;
+            d[14] = clear_value;   d[15] = clear_value;
+            d += 16;
+            n -= 16;
+         }
+         while (n>0) {
+            *d++ = clear_value;
+            n--;
+         }
+      }
+   }
+}
+
+
+
diff --git a/src/mesa/main/depth.h b/src/mesa/main/depth.h
new file mode 100644 (file)
index 0000000..559afc6
--- /dev/null
@@ -0,0 +1,98 @@
+/* $Id: depth.h,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+#ifndef DEPTH_H
+#define DEPTH_H
+
+
+#include "types.h"
+
+
+/*
+ * Return the address of the Z-buffer value for window coordinate (x,y):
+ */
+#define Z_ADDRESS( CTX, X, Y )  \
+            ((CTX)->Buffer->Depth + (CTX)->Buffer->Width * (Y) + (X))
+
+
+
+
+extern GLuint
+gl_depth_test_span_generic( GLcontext* ctx, GLuint n, GLint x, GLint y,
+                            const GLdepth z[], GLubyte mask[] );
+
+extern GLuint
+gl_depth_test_span_less( GLcontext* ctx, GLuint n, GLint x, GLint y,
+                         const GLdepth z[], GLubyte mask[] );
+
+extern GLuint
+gl_depth_test_span_greater( GLcontext* ctx, GLuint n, GLint x, GLint y,
+                            const GLdepth z[], GLubyte mask[] );
+
+
+
+extern void
+gl_depth_test_pixels_generic( GLcontext* ctx,
+                              GLuint n, const GLint x[], const GLint y[],
+                              const GLdepth z[], GLubyte mask[] );
+
+extern void
+gl_depth_test_pixels_less( GLcontext* ctx,
+                           GLuint n, const GLint x[], const GLint y[],
+                           const GLdepth z[], GLubyte mask[] );
+
+extern void
+gl_depth_test_pixels_greater( GLcontext* ctx,
+                              GLuint n, const GLint x[], const GLint y[],
+                              const GLdepth z[], GLubyte mask[] );
+
+
+extern void gl_read_depth_span_float( GLcontext* ctx,
+                                      GLuint n, GLint x, GLint y,
+                                      GLfloat depth[] );
+
+
+extern void gl_read_depth_span_int( GLcontext* ctx, GLuint n, GLint x, GLint y,
+                                    GLdepth depth[] );
+
+
+extern void gl_alloc_depth_buffer( GLcontext* ctx );
+
+
+extern void gl_clear_depth_buffer( GLcontext* ctx );
+
+
+extern void gl_ClearDepth( GLcontext* ctx, GLclampd depth );
+
+extern void gl_DepthFunc( GLcontext* ctx, GLenum func );
+
+extern void gl_DepthMask( GLcontext* ctx, GLboolean flag );
+
+#endif
diff --git a/src/mesa/main/descrip.mms b/src/mesa/main/descrip.mms
new file mode 100644 (file)
index 0000000..d6ab057
--- /dev/null
@@ -0,0 +1,156 @@
+# Makefile for core library for VMS
+# contributed by Jouk Jansen  joukj@crys.chem.uva.nl
+# Last revision : 3 May 1999
+
+.first
+       define gl [-.include.gl]
+
+.include [-]mms-config.
+
+##### MACROS #####
+
+VPATH = RCS
+
+INCDIR = [-.include]
+LIBDIR = [-.lib]
+CFLAGS = /include=($(INCDIR),[])/define=(FBIND=1)
+
+CORE_SOURCES = accum.c alpha.c alphabuf.c api1.c api2.c apiext.c attrib.c \
+bitmap.c blend.c clip.c colortab.c context.c copypix.c depth.c \
+dlist.c drawpix.c enable.c eval.c feedback.c fog.c \
+get.c hash.c image.c light.c lines.c logic.c masking.c matrix.c \
+misc.c mmath.c mthreads.c pb.c pixel.c points.c pointers.c polygon.c \
+quads.c rastpos.c readpix.c rect.c scissor.c shade.c span.c \
+stencil.c teximage.c texobj.c texstate.c texture.c translate.c triangle.c \
+varray.c winpos.c vb.c vbcull.c vbfill.c vbrender.c vbxform.c xform.c \
+zoom.c bbox.c cva.c vector.c vbindirect.c config.c enums.c extensions.c \
+pipeline.c [.x86]x86.c
+
+DRIVER_SOURCES = [.x]glxapi.c [.x]fakeglx.c [.x]realglx.c [.x]xfonts.c \
+[.x]xmesa1.c [.x]xmesa2.c [.x]xmesa3.c [.x]xmesa4.c \
+[.osmesa]osmesa.c \
+[.svga]svgamesa.c \
+[.fx]fxapi.c [.fx]fxdd.c [.fx]fxddtex.c [.fx]fxvsetup.c [.fx]fxsetup.c \
+[.fx]fxtrifuncs.c \
+[.fx]fxrender.c [.fx]fxtexman.c [.fx]fxddspan.c [.fx]fxcva.c
+
+ASM_SOURCES =
+
+OBJECTS =\
+accum.obj,alpha.obj,alphabuf.obj,api1.obj,api2.obj,apiext.obj,attrib.obj,\
+bitmap.obj,blend.obj,clip.obj,colortab.obj,context.obj,copypix.obj,depth.obj,\
+dlist.obj,drawpix.obj,enable.obj,eval.obj,feedback.obj,fog.obj
+
+
+OBJECTS3=get.obj,hash.obj,image.obj,light.obj,lines.obj,logic.obj,masking.obj,matrix.obj,\
+misc.obj,mmath.obj,mthreads.obj,pb.obj,pixel.obj,points.obj,pointers.obj,polygon.obj,\
+quads.obj,rastpos.obj,readpix.obj,rect.obj,scissor.obj,shade.obj,span.obj
+
+
+OBJECTS4=stencil.obj,teximage.obj,texobj.obj,texstate.obj,texture.obj,translate.obj,\
+triangle.obj,varray.obj,winpos.obj,vb.obj,vbcull.obj,vbfill.obj,vbrender.obj
+
+OBJECTS6=vbxform.obj,xform.obj,zoom.obj,bbox.obj,cva.obj,vector.obj,vbindirect.obj,\
+       config.obj,enums.obj,extensions.obj,pipeline.obj,[.x86]x86.obj
+
+OBJECTS2=[.x]glxapi.obj,[.x]fakeglx.obj,[.x]realglx.obj,[.x]xfonts.obj,\
+[.x]xmesa1.obj,[.x]xmesa2.obj,[.x]xmesa3.obj,[.x]xmesa4.obj,\
+[.osmesa]osmesa.obj,\
+[.svga]svgamesa.obj
+
+OBJECTS5=[.fx]fxapi.obj,[.fx]fxdd.obj,[.fx]fxddtex.obj,[.fx]fxvsetup.obj,\
+[.fx]fxsetup.obj,\
+[.fx]fxtrifuncs.obj,\
+[.fx]fxrender.obj,[.fx]fxtexman.obj,[.fx]fxddspan.obj,[.fx]fxcva.obj
+
+##### RULES #####
+
+VERSION=Mesa V3.1
+
+##### TARGETS #####
+# Make the library
+$(LIBDIR)$(GL_LIB) : $(OBJECTS),$(OBJECTS2) $(OBJECTS3) $(OBJECTS4)\
+       $(OBJECTS5) $(OBJECTS6)
+.ifdef SHARE
+  @ WRITE_ SYS$OUTPUT "  generating mesagl1.opt"
+  @ OPEN_/WRITE FILE  mesagl1.opt
+  @ WRITE_ FILE "!"
+  @ WRITE_ FILE "! mesagl1.opt generated by DESCRIP.$(MMS_EXT)" 
+  @ WRITE_ FILE "!"
+  @ WRITE_ FILE "IDENTIFICATION=""$(VERSION)"""
+  @ WRITE_ FILE "GSMATCH=LEQUAL,3,1
+  @ WRITE_ FILE "$(OBJECTS)"
+  @ WRITE_ FILE "$(OBJECTS3)"
+  @ WRITE_ FILE "$(OBJECTS4)"
+  @ WRITE_ FILE "$(OBJECTS6)"
+  @ WRITE_ FILE "$(OBJECTS2)"
+  @ WRITE_ FILE "$(OBJECTS5)"
+  @ WRITE_ FILE "SYS$SHARE:DECW$XEXTLIBSHR/SHARE"
+  @ WRITE_ FILE "SYS$SHARE:DECW$XLIBSHR/SHARE"
+  @ CLOSE_ FILE
+  @ WRITE_ SYS$OUTPUT "  generating mesagl.map ..."
+  @ LINK_/NODEB/NOSHARE/NOEXE/MAP=mesagl.map/FULL mesagl1.opt/OPT
+  @ WRITE_ SYS$OUTPUT "  analyzing mesagl.map ..."
+  @ @[-.vms]ANALYZE_MAP.COM mesagl.map mesagl.opt
+  @ WRITE_ SYS$OUTPUT "  linking $(GL_LIB) ..."
+  @ LINK_/NODEB/SHARE=$(GL_LIB)/MAP=mesagl.map/FULL mesagl1.opt/opt,mesagl.opt/opt
+.else
+  @ $(MAKELIB) $(GL_LIB) $(OBJECTS)
+  @ library $(GL_LIB) $(OBJECTS2)
+  @ library $(GL_LIB) $(OBJECTS3)
+  @ library $(GL_LIB) $(OBJECTS4)
+  @ library $(GL_LIB) $(OBJECTS5)
+  @ library $(GL_LIB) $(OBJECTS6)
+.endif
+  @ rename $(GL_LIB)* $(LIBDIR)
+
+clean :
+       purge
+       delete *.obj;*
+
+triangle.obj : triangle.c
+
+[.x86]x86.obj : [.x86]x86.c
+       $(CC) $(CFLAGS) /obj=[.x86]x86.obj [.x86]x86.c
+[.x]glxapi.obj : [.x]glxapi.c
+       $(CC) $(CFLAGS) /obj=[.x]glxapi.obj [.x]glxapi.c
+[.x]fakeglx.obj : [.x]fakeglx.c
+       $(CC) $(CFLAGS) /obj=[.x]fakeglx.obj [.x]fakeglx.c
+[.x]realglx.obj : [.x]realglx.c
+       $(CC) $(CFLAGS) /obj=[.x]realglx.obj [.x]realglx.c
+[.x]xfonts.obj : [.x]xfonts.c
+       $(CC) $(CFLAGS) /obj=[.x]xfonts.obj [.x]xfonts.c
+[.x]xmesa1.obj : [.x]xmesa1.c
+       $(CC) $(CFLAGS) /obj=[.x]xmesa1.obj [.x]xmesa1.c
+[.x]xmesa2.obj : [.x]xmesa2.c
+       $(CC) $(CFLAGS) /obj=[.x]xmesa2.obj [.x]xmesa2.c
+[.x]xmesa3.obj : [.x]xmesa3.c
+       $(CC) $(CFLAGS) /obj=[.x]xmesa3.obj [.x]xmesa3.c
+[.x]xmesa4.obj : [.x]xmesa4.c
+       $(CC) $(CFLAGS) /obj=[.x]xmesa4.obj [.x]xmesa4.c
+[.osmesa]osmesa.obj : [.osmesa]osmesa.c
+       $(CC) $(CFLAGS) /obj=[.osmesa]osmesa.obj [.osmesa]osmesa.c
+[.svga]svgamesa.obj : [.svga]svgamesa.c
+       $(CC) $(CFLAGS) /obj=[.svga]svgamesa.obj [.svga]svgamesa.c
+[.fx]fxapi.obj : [.fx]fxapi.c
+       $(CC) $(CFLAGS) /obj=[.fx]fxapi.obj [.fx]fxapi.c
+[.fx]fxcva.obj : [.fx]fxcva.c
+       $(CC) $(CFLAGS) /obj=[.fx]fxcva.obj [.fx]fxcva.c
+[.fx]fxdd.obj : [.fx]fxdd.c
+       $(CC) $(CFLAGS) /obj=[.fx]fxdd.obj [.fx]fxdd.c
+[.fx]fxddtex.obj : [.fx]fxddtex.c
+       $(CC) $(CFLAGS) /obj=[.fx]fxddtex.obj [.fx]fxddtex.c
+[.fx]fxvsetup.obj : [.fx]fxvsetup.c
+       $(CC) $(CFLAGS) /obj=[.fx]fxvsetup.obj [.fx]fxvsetup.c
+[.fx]fxsetup.obj : [.fx]fxsetup.c
+       $(CC) $(CFLAGS) /obj=[.fx]fxsetup.obj [.fx]fxsetup.c
+[.fx]fxtrifuncs.obj : [.fx]fxtrifuncs.c
+       $(CC) $(CFLAGS) /obj=[.fx]fxtrifuncs.obj [.fx]fxtrifuncs.c
+[.fx]fxrender.obj : [.fx]fxrender.c
+       $(CC) $(CFLAGS) /obj=[.fx]fxrender.obj [.fx]fxrender.c
+[.fx]fxtexman.obj : [.fx]fxtexman.c
+       $(CC) $(CFLAGS) /obj=[.fx]fxtexman.obj [.fx]fxtexman.c
+[.fx]fxddspan.obj : [.fx]fxddspan.c
+       $(CC) $(CFLAGS) /obj=[.fx]fxddspan.obj [.fx]fxddspan.c
+
+.include mms_depend.
diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c
new file mode 100644 (file)
index 0000000..001de03
--- /dev/null
@@ -0,0 +1,3501 @@
+/* $Id: dlist.c,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "accum.h"
+#include "api.h"
+#include "alpha.h"
+#include "attrib.h"
+#include "bitmap.h"
+#include "bbox.h"
+#include "blend.h"
+#include "clip.h"
+#include "colortab.h"
+#include "context.h"
+#include "copypix.h"
+#include "depth.h"
+#include "drawpix.h"
+#include "enable.h"
+#include "enums.h"
+#include "eval.h"
+#include "feedback.h"
+#include "fog.h"
+#include "get.h"
+#include "hash.h"
+#include "image.h"
+#include "light.h"
+#include "lines.h"
+#include "dlist.h"
+#include "logic.h"
+#include "macros.h"
+#include "masking.h"
+#include "matrix.h"
+#include "misc.h"
+#include "pipeline.h"
+#include "pixel.h"
+#include "points.h"
+#include "polygon.h"
+#include "rastpos.h"
+#include "readpix.h"
+#include "rect.h"
+#include "scissor.h"
+#include "stencil.h"
+#include "texobj.h"
+#include "teximage.h"
+#include "texstate.h"
+#include "types.h"
+#include "varray.h"
+#include "vb.h"
+#include "vbfill.h"
+#include "vbxform.h"
+#include "winpos.h"
+#include "xform.h"
+#ifdef XFree86Server
+#undef MISC_H
+#include "GL/xf86glx.h"
+#endif
+#endif
+
+
+
+/*
+Functions which aren't compiled but executed immediately:
+       glIsList
+       glGenLists
+       glDeleteLists
+       glEndList
+       glFeedbackBuffer
+       glSelectBuffer
+       glRenderMode
+       glReadPixels
+       glPixelStore
+       glFlush
+       glFinish
+       glIsEnabled
+       glGet*
+
+Functions which cause errors if called while compiling a display list:
+       glNewList
+*/
+
+
+
+/*
+ * Display list instructions are stored as sequences of "nodes".  Nodes
+ * are allocated in blocks.  Each block has BLOCK_SIZE nodes.  Blocks
+ * are linked together with a pointer.
+ */
+
+
+/* How many nodes to allocate at a time: 
+ * - reduced now that we hold vertices etc. elsewhere.
+ */
+#define BLOCK_SIZE 64
+
+
+/*
+ * Display list opcodes.
+ *
+ * The fact that these identifiers are assigned consecutive
+ * integer values starting at 0 is very important, see InstSize array usage)
+ *
+ * KW: Commented out opcodes now handled by vertex-cassettes.
+ */
+typedef enum {
+       OPCODE_ACCUM,
+       OPCODE_ALPHA_FUNC,
+        OPCODE_BIND_TEXTURE,
+       OPCODE_BITMAP,
+       OPCODE_BLEND_COLOR,
+       OPCODE_BLEND_EQUATION,
+       OPCODE_BLEND_FUNC,
+       OPCODE_BLEND_FUNC_SEPARATE,
+        OPCODE_CALL_LIST,
+        OPCODE_CALL_LIST_OFFSET,
+       OPCODE_CLEAR,
+       OPCODE_CLEAR_ACCUM,
+       OPCODE_CLEAR_COLOR,
+       OPCODE_CLEAR_DEPTH,
+       OPCODE_CLEAR_INDEX,
+       OPCODE_CLEAR_STENCIL,
+        OPCODE_CLIP_PLANE,
+       OPCODE_COLOR_MASK,
+       OPCODE_COLOR_MATERIAL,
+       OPCODE_COLOR_TABLE,
+       OPCODE_COLOR_SUB_TABLE,
+       OPCODE_COPY_PIXELS,
+        OPCODE_COPY_TEX_IMAGE1D,
+        OPCODE_COPY_TEX_IMAGE2D,
+        OPCODE_COPY_TEX_IMAGE3D,
+        OPCODE_COPY_TEX_SUB_IMAGE1D,
+        OPCODE_COPY_TEX_SUB_IMAGE2D,
+        OPCODE_COPY_TEX_SUB_IMAGE3D,
+       OPCODE_CULL_FACE,
+       OPCODE_DEPTH_FUNC,
+       OPCODE_DEPTH_MASK,
+       OPCODE_DEPTH_RANGE,
+       OPCODE_DISABLE,
+       OPCODE_DRAW_BUFFER,
+       OPCODE_DRAW_PIXELS,
+       OPCODE_ENABLE,
+       OPCODE_EVALCOORD1,
+       OPCODE_EVALCOORD2,
+       OPCODE_EVALMESH1,
+       OPCODE_EVALMESH2,
+       OPCODE_EVALPOINT1,
+       OPCODE_EVALPOINT2,
+       OPCODE_FOG,
+       OPCODE_FRONT_FACE,
+       OPCODE_FRUSTUM,
+       OPCODE_HINT,
+       OPCODE_INDEX_MASK,
+       OPCODE_INIT_NAMES,
+       OPCODE_LIGHT,
+       OPCODE_LIGHT_MODEL,
+       OPCODE_LINE_STIPPLE,
+       OPCODE_LINE_WIDTH,
+       OPCODE_LIST_BASE,
+       OPCODE_LOAD_IDENTITY,
+       OPCODE_LOAD_MATRIX,
+       OPCODE_LOAD_NAME,
+       OPCODE_LOGIC_OP,
+       OPCODE_MAP1,
+       OPCODE_MAP2,
+       OPCODE_MAPGRID1,
+       OPCODE_MAPGRID2,
+       OPCODE_MATRIX_MODE,
+       OPCODE_MULT_MATRIX,
+       OPCODE_ORTHO,
+       OPCODE_PASSTHROUGH,
+       OPCODE_PIXEL_MAP,
+       OPCODE_PIXEL_TRANSFER,
+       OPCODE_PIXEL_ZOOM,
+       OPCODE_POINT_SIZE,
+        OPCODE_POINT_PARAMETERS,
+       OPCODE_POLYGON_MODE,
+        OPCODE_POLYGON_STIPPLE,
+       OPCODE_POLYGON_OFFSET,
+       OPCODE_POP_ATTRIB,
+       OPCODE_POP_MATRIX,
+       OPCODE_POP_NAME,
+       OPCODE_PRIORITIZE_TEXTURE,
+       OPCODE_PUSH_ATTRIB,
+       OPCODE_PUSH_MATRIX,
+       OPCODE_PUSH_NAME,
+       OPCODE_RASTER_POS,
+       OPCODE_RECTF,
+       OPCODE_READ_BUFFER,
+        OPCODE_SCALE,
+       OPCODE_SCISSOR,
+       OPCODE_SELECT_TEXTURE_SGIS,
+       OPCODE_SELECT_TEXTURE_COORD_SET,
+       OPCODE_SHADE_MODEL,
+       OPCODE_STENCIL_FUNC,
+       OPCODE_STENCIL_MASK,
+       OPCODE_STENCIL_OP,
+        OPCODE_TEXENV,
+        OPCODE_TEXGEN,
+        OPCODE_TEXPARAMETER,
+       OPCODE_TEX_IMAGE1D,
+       OPCODE_TEX_IMAGE2D,
+       OPCODE_TEX_IMAGE3D,
+       OPCODE_TEX_SUB_IMAGE1D,
+       OPCODE_TEX_SUB_IMAGE2D,
+       OPCODE_TEX_SUB_IMAGE3D,
+        OPCODE_TRANSLATE,
+       OPCODE_VIEWPORT,
+       OPCODE_WINDOW_POS,
+        /* GL_ARB_multitexture */
+        OPCODE_ACTIVE_TEXTURE,
+        OPCODE_CLIENT_ACTIVE_TEXTURE,
+       /* The following three are meta instructions */
+       OPCODE_ERROR,           /* raise compiled-in error */
+       OPCODE_VERTEX_CASSETTE, /* render prebuilt vertex buffer */
+       OPCODE_CONTINUE,
+       OPCODE_END_OF_LIST
+} OpCode;
+
+
+/*
+ * Each instruction in the display list is stored as a sequence of
+ * contiguous nodes in memory.
+ * Each node is the union of a variety of datatypes.
+ */
+union node {
+       OpCode          opcode;
+       GLboolean       b;
+       GLbitfield      bf;
+       GLubyte         ub;
+       GLshort         s;
+       GLushort        us;
+       GLint           i;
+       GLuint          ui;
+       GLenum          e;
+       GLfloat         f;
+       GLvoid          *data;
+       void            *next;  /* If prev node's opcode==OPCODE_CONTINUE */
+};
+
+
+
+/* Number of nodes of storage needed for each instruction: */
+static GLuint InstSize[ OPCODE_END_OF_LIST+1 ];
+
+
+
+/**********************************************************************/
+/*****                           Private                          *****/
+/**********************************************************************/
+
+
+/*
+ * Allocate space for a display list instruction.
+ * Input:  opcode - type of instruction
+ *         argcount - number of arguments following the instruction
+ * Return: pointer to first node in the instruction
+ */
+static Node *alloc_instruction( GLcontext *ctx, OpCode opcode, GLint argcount )
+{
+   Node *n, *newblock;
+   GLuint count = InstSize[opcode];
+
+   assert( (GLint) count == argcount+1 );
+
+   if (ctx->CurrentPos + count + 2 > BLOCK_SIZE) {
+      /* This block is full.  Allocate a new block and chain to it */
+      n = ctx->CurrentBlock + ctx->CurrentPos;
+      n[0].opcode = OPCODE_CONTINUE;
+      newblock = (Node *) malloc( sizeof(Node) * BLOCK_SIZE );
+      if (!newblock) {
+         gl_error( ctx, GL_OUT_OF_MEMORY, "Building display list" );
+         return NULL;
+      }
+      n[1].next = (Node *) newblock;
+      ctx->CurrentBlock = newblock;
+      ctx->CurrentPos = 0;
+   }
+
+   n = ctx->CurrentBlock + ctx->CurrentPos;
+   ctx->CurrentPos += count;
+
+   n[0].opcode = opcode;
+
+   return n;
+}
+
+
+
+/*
+ * Make an empty display list.  This is used by glGenLists() to
+ * reserver display list IDs.
+ */
+static Node *make_empty_list( void )
+{
+   Node *n = (Node *) malloc( sizeof(Node) );
+   n[0].opcode = OPCODE_END_OF_LIST;
+   return n;
+}
+
+
+
+/*
+ * Destroy all nodes in a display list.
+ * Input:  list - display list number
+ */
+void gl_destroy_list( GLcontext *ctx, GLuint list )
+{
+   Node *n, *block;
+   GLboolean done;
+
+   if (list==0)
+      return;
+
+   block = (Node *) HashLookup(ctx->Shared->DisplayList, list);
+   n = block;
+
+   done = block ? GL_FALSE : GL_TRUE;
+   while (!done) {
+      switch (n[0].opcode) {
+        /* special cases first */
+         case OPCODE_VERTEX_CASSETTE: 
+           if ( ! -- ((struct immediate *) n[1].data)->ref_count )
+              gl_immediate_free( (struct immediate *) n[1].data );
+           n += InstSize[n[0].opcode];
+           break;
+        case OPCODE_MAP1:
+           gl_free_control_points( ctx, n[1].e, (GLfloat *) n[6].data );
+           n += InstSize[n[0].opcode];
+           break;
+        case OPCODE_MAP2:
+           gl_free_control_points( ctx, n[1].e, (GLfloat *) n[10].data );
+           n += InstSize[n[0].opcode];
+           break;
+        case OPCODE_DRAW_PIXELS:
+           gl_free_image( (struct gl_image *) n[1].data );
+           n += InstSize[n[0].opcode];
+           break;
+        case OPCODE_BITMAP:
+           gl_free_image( (struct gl_image *) n[7].data );
+           n += InstSize[n[0].opcode];
+           break;
+         case OPCODE_COLOR_TABLE:
+            gl_free_image( (struct gl_image *) n[3].data );
+            n += InstSize[n[0].opcode];
+            break;
+         case OPCODE_COLOR_SUB_TABLE:
+            gl_free_image( (struct gl_image *) n[3].data );
+            n += InstSize[n[0].opcode];
+            break;
+         case OPCODE_POLYGON_STIPPLE:
+            free( n[1].data );
+           n += InstSize[n[0].opcode];
+            break;
+        case OPCODE_TEX_IMAGE1D:
+            gl_free_image( (struct gl_image *) n[8].data );
+            n += InstSize[n[0].opcode];
+           break;
+        case OPCODE_TEX_IMAGE2D:
+            gl_free_image( (struct gl_image *) n[9].data );
+            n += InstSize[n[0].opcode];
+           break;
+         case OPCODE_TEX_SUB_IMAGE1D:
+            {
+               struct gl_image *image;
+               image = (struct gl_image *) n[7].data;
+               gl_free_image( image );
+            }
+            break;
+         case OPCODE_TEX_SUB_IMAGE2D:
+            {
+               struct gl_image *image;
+               image = (struct gl_image *) n[9].data;
+               gl_free_image( image );
+            }
+            break;
+        case OPCODE_CONTINUE:
+           n = (Node *) n[1].next;
+           free( block );
+           block = n;
+           break;
+        case OPCODE_END_OF_LIST:
+           free( block );
+           done = GL_TRUE;
+           break;
+        default:
+           /* Most frequent case */
+           n += InstSize[n[0].opcode];
+           break;
+      }
+   }
+
+   HashRemove(ctx->Shared->DisplayList, list);
+}
+
+
+
+/*
+ * Translate the nth element of list from type to GLuint.
+ */
+static GLuint translate_id( GLsizei n, GLenum type, const GLvoid *list )
+{
+   GLbyte *bptr;
+   GLubyte *ubptr;
+   GLshort *sptr;
+   GLushort *usptr;
+   GLint *iptr;
+   GLuint *uiptr;
+   GLfloat *fptr;
+
+   switch (type) {
+      case GL_BYTE:
+         bptr = (GLbyte *) list;
+         return (GLuint) *(bptr+n);
+      case GL_UNSIGNED_BYTE:
+         ubptr = (GLubyte *) list;
+         return (GLuint) *(ubptr+n);
+      case GL_SHORT:
+         sptr = (GLshort *) list;
+         return (GLuint) *(sptr+n);
+      case GL_UNSIGNED_SHORT:
+         usptr = (GLushort *) list;
+         return (GLuint) *(usptr+n);
+      case GL_INT:
+         iptr = (GLint *) list;
+         return (GLuint) *(iptr+n);
+      case GL_UNSIGNED_INT:
+         uiptr = (GLuint *) list;
+         return (GLuint) *(uiptr+n);
+      case GL_FLOAT:
+         fptr = (GLfloat *) list;
+         return (GLuint) *(fptr+n);
+      case GL_2_BYTES:
+         ubptr = ((GLubyte *) list) + 2*n;
+         return (GLuint) *ubptr * 256 + (GLuint) *(ubptr+1);
+      case GL_3_BYTES:
+         ubptr = ((GLubyte *) list) + 3*n;
+         return (GLuint) *ubptr * 65536
+              + (GLuint) *(ubptr+1) * 256
+              + (GLuint) *(ubptr+2);
+      case GL_4_BYTES:
+         ubptr = ((GLubyte *) list) + 4*n;
+         return (GLuint) *ubptr * 16777216
+              + (GLuint) *(ubptr+1) * 65536
+              + (GLuint) *(ubptr+2) * 256
+              + (GLuint) *(ubptr+3);
+      default:
+         return 0;
+   }
+}
+
+
+
+
+/**********************************************************************/
+/*****                        Public                              *****/
+/**********************************************************************/
+
+void gl_init_lists( void )
+{
+   static int init_flag = 0;
+
+   if (init_flag==0) {
+      InstSize[OPCODE_ACCUM] = 3;
+      InstSize[OPCODE_ALPHA_FUNC] = 3;
+      InstSize[OPCODE_BIND_TEXTURE] = 3;
+      InstSize[OPCODE_BITMAP] = 8;
+      InstSize[OPCODE_BLEND_COLOR] = 5;
+      InstSize[OPCODE_BLEND_EQUATION] = 2;
+      InstSize[OPCODE_BLEND_FUNC] = 3;
+      InstSize[OPCODE_BLEND_FUNC_SEPARATE] = 5;
+      InstSize[OPCODE_CALL_LIST] = 2;
+      InstSize[OPCODE_CALL_LIST_OFFSET] = 2;
+      InstSize[OPCODE_CLEAR] = 2;
+      InstSize[OPCODE_CLEAR_ACCUM] = 5;
+      InstSize[OPCODE_CLEAR_COLOR] = 5;
+      InstSize[OPCODE_CLEAR_DEPTH] = 2;
+      InstSize[OPCODE_CLEAR_INDEX] = 2;
+      InstSize[OPCODE_CLEAR_STENCIL] = 2;
+      InstSize[OPCODE_CLIP_PLANE] = 6;
+      InstSize[OPCODE_COLOR_MASK] = 5;
+      InstSize[OPCODE_COLOR_MATERIAL] = 3;
+      InstSize[OPCODE_COLOR_TABLE] = 4;
+      InstSize[OPCODE_COLOR_SUB_TABLE] = 4;
+      InstSize[OPCODE_COPY_PIXELS] = 6;
+      InstSize[OPCODE_COPY_TEX_IMAGE1D] = 8;
+      InstSize[OPCODE_COPY_TEX_IMAGE2D] = 9;
+      InstSize[OPCODE_COPY_TEX_SUB_IMAGE1D] = 7;
+      InstSize[OPCODE_COPY_TEX_SUB_IMAGE2D] = 9;
+      InstSize[OPCODE_COPY_TEX_SUB_IMAGE3D] = 10;
+      InstSize[OPCODE_CULL_FACE] = 2;
+      InstSize[OPCODE_DEPTH_FUNC] = 2;
+      InstSize[OPCODE_DEPTH_MASK] = 2;
+      InstSize[OPCODE_DEPTH_RANGE] = 3;
+      InstSize[OPCODE_DISABLE] = 2;
+      InstSize[OPCODE_DRAW_BUFFER] = 2;
+      InstSize[OPCODE_DRAW_PIXELS] = 2;
+      InstSize[OPCODE_ENABLE] = 2;
+      InstSize[OPCODE_EVALCOORD1] = 2;
+      InstSize[OPCODE_EVALCOORD2] = 3;
+      InstSize[OPCODE_EVALMESH1] = 4;
+      InstSize[OPCODE_EVALMESH2] = 6;
+      InstSize[OPCODE_EVALPOINT1] = 2;
+      InstSize[OPCODE_EVALPOINT2] = 3;
+      InstSize[OPCODE_FOG] = 6;
+      InstSize[OPCODE_FRONT_FACE] = 2;
+      InstSize[OPCODE_FRUSTUM] = 7;
+      InstSize[OPCODE_HINT] = 3;
+      InstSize[OPCODE_INDEX_MASK] = 2;
+      InstSize[OPCODE_INIT_NAMES] = 1;
+      InstSize[OPCODE_LIGHT] = 7;
+      InstSize[OPCODE_LIGHT_MODEL] = 6;
+      InstSize[OPCODE_LINE_STIPPLE] = 3;
+      InstSize[OPCODE_LINE_WIDTH] = 2;
+      InstSize[OPCODE_LIST_BASE] = 2;
+      InstSize[OPCODE_LOAD_IDENTITY] = 1;
+      InstSize[OPCODE_LOAD_MATRIX] = 17;
+      InstSize[OPCODE_LOAD_NAME] = 2;
+      InstSize[OPCODE_LOGIC_OP] = 2;
+      InstSize[OPCODE_MAP1] = 7;
+      InstSize[OPCODE_MAP2] = 11;
+      InstSize[OPCODE_MAPGRID1] = 4;
+      InstSize[OPCODE_MAPGRID2] = 7;
+      InstSize[OPCODE_MATRIX_MODE] = 2;
+      InstSize[OPCODE_MULT_MATRIX] = 17;
+      InstSize[OPCODE_ORTHO] = 7;
+      InstSize[OPCODE_PASSTHROUGH] = 2;
+      InstSize[OPCODE_PIXEL_MAP] = 4;
+      InstSize[OPCODE_PIXEL_TRANSFER] = 3;
+      InstSize[OPCODE_PIXEL_ZOOM] = 3;
+      InstSize[OPCODE_POINT_SIZE] = 2;
+      InstSize[OPCODE_POINT_PARAMETERS] = 5;
+      InstSize[OPCODE_POLYGON_MODE] = 3;
+      InstSize[OPCODE_POLYGON_STIPPLE] = 2;
+      InstSize[OPCODE_POLYGON_OFFSET] = 3;
+      InstSize[OPCODE_POP_ATTRIB] = 1;
+      InstSize[OPCODE_POP_MATRIX] = 1;
+      InstSize[OPCODE_POP_NAME] = 1;
+      InstSize[OPCODE_PRIORITIZE_TEXTURE] = 3;
+      InstSize[OPCODE_PUSH_ATTRIB] = 2;
+      InstSize[OPCODE_PUSH_MATRIX] = 1;
+      InstSize[OPCODE_PUSH_NAME] = 2;
+      InstSize[OPCODE_RASTER_POS] = 5;
+      InstSize[OPCODE_RECTF] = 5;
+      InstSize[OPCODE_READ_BUFFER] = 2;
+      InstSize[OPCODE_SCALE] = 4;
+      InstSize[OPCODE_SCISSOR] = 5;
+      InstSize[OPCODE_STENCIL_FUNC] = 4;
+      InstSize[OPCODE_STENCIL_MASK] = 2;
+      InstSize[OPCODE_STENCIL_OP] = 4;
+      InstSize[OPCODE_SHADE_MODEL] = 2;
+      InstSize[OPCODE_TEXENV] = 7;
+      InstSize[OPCODE_TEXGEN] = 7;
+      InstSize[OPCODE_TEXPARAMETER] = 7;
+      InstSize[OPCODE_TEX_IMAGE1D] = 9;
+      InstSize[OPCODE_TEX_IMAGE2D] = 10;
+      InstSize[OPCODE_TEX_IMAGE3D] = 11;
+      InstSize[OPCODE_TEX_SUB_IMAGE1D] = 8;
+      InstSize[OPCODE_TEX_SUB_IMAGE2D] = 10;
+      InstSize[OPCODE_TEX_SUB_IMAGE3D] = 12;
+      InstSize[OPCODE_TRANSLATE] = 4;
+      InstSize[OPCODE_VIEWPORT] = 5;
+      InstSize[OPCODE_WINDOW_POS] = 5;
+      InstSize[OPCODE_CONTINUE] = 2;
+      InstSize[OPCODE_ERROR] = 3;
+      InstSize[OPCODE_VERTEX_CASSETTE] = 2;
+      InstSize[OPCODE_END_OF_LIST] = 1;
+      /* GL_ARB_multitexture */
+      InstSize[OPCODE_ACTIVE_TEXTURE] = 2;
+      InstSize[OPCODE_CLIENT_ACTIVE_TEXTURE] = 2;
+   }
+   init_flag = 1;
+}
+
+
+/*
+ * Display List compilation functions
+ */
+
+
+
+static void save_Accum( GLcontext *ctx, GLenum op, GLfloat value )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_ACCUM, 2 );
+   if (n) {
+      n[1].e = op;
+      n[2].f = value;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.Accum)( ctx, op, value );
+   }
+}
+
+
+static void save_AlphaFunc( GLcontext *ctx, GLenum func, GLclampf ref )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_ALPHA_FUNC, 2 );
+   if (n) {
+      n[1].e = func;
+      n[2].f = (GLfloat) ref;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.AlphaFunc)( ctx, func, ref );
+   }
+}
+
+static void save_BindTexture( GLcontext *ctx, GLenum target, GLuint texture )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_BIND_TEXTURE, 2 );
+   if (n) {
+      n[1].e = target;
+      n[2].ui = texture;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.BindTexture)( ctx, target, texture );
+   }
+}
+
+
+static void save_Bitmap( GLcontext *ctx,
+                         GLsizei width, GLsizei height,
+                         GLfloat xorig, GLfloat yorig,
+                         GLfloat xmove, GLfloat ymove,
+                         const GLubyte *bitmap,
+                         const struct gl_pixelstore_attrib *packing )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_BITMAP, 7 );
+   if (n) {
+      struct gl_image *image = gl_unpack_bitmap( ctx, width, height,
+                                                 bitmap, packing );
+      if (image) {
+         image->RefCount = 1;
+      }
+      n[1].i = (GLint) width;
+      n[2].i = (GLint) height;
+      n[3].f = xorig;
+      n[4].f = yorig;
+      n[5].f = xmove;
+      n[6].f = ymove;
+      n[7].data = (void *) image;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.Bitmap)( ctx, width, height,
+                           xorig, yorig, xmove, ymove, bitmap, packing );
+   }
+}
+
+
+static void save_BlendEquation( GLcontext *ctx, GLenum mode )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_BLEND_EQUATION, 1 );
+   if (n) {
+      n[1].e = mode;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.BlendEquation)( ctx, mode );
+   }
+}
+
+
+static void save_BlendFunc( GLcontext *ctx, GLenum sfactor, GLenum dfactor )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_BLEND_FUNC, 2 );
+   if (n) {
+      n[1].e = sfactor;
+      n[2].e = dfactor;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.BlendFunc)( ctx, sfactor, dfactor );
+   }
+}
+
+
+static void save_BlendFuncSeparate( GLcontext *ctx,
+                                GLenum sfactorRGB, GLenum dfactorRGB,
+                                GLenum sfactorA, GLenum dfactorA)
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_BLEND_FUNC_SEPARATE, 4 );
+   if (n) {
+      n[1].e = sfactorRGB;
+      n[2].e = dfactorRGB;
+      n[3].e = sfactorA;
+      n[4].e = dfactorA;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.BlendFuncSeparate)( ctx, sfactorRGB, dfactorRGB,
+                                      sfactorA, dfactorA);
+   }
+}
+
+
+static void save_BlendColor( GLcontext *ctx, GLfloat red, GLfloat green,
+                         GLfloat blue, GLfloat alpha )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_BLEND_COLOR, 4 );
+   if (n) {
+      n[1].f = red;
+      n[2].f = green;
+      n[3].f = blue;
+      n[4].f = alpha;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.BlendColor)( ctx, red, green, blue, alpha );
+   }
+}
+
+
+static void save_CallList( GLcontext *ctx, GLuint list )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_CALL_LIST, 1 );
+   if (n) {
+      n[1].ui = list;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.CallList)( ctx, list );
+   }
+}
+
+
+static void save_CallLists( GLcontext *ctx,
+                        GLsizei n, GLenum type, const GLvoid *lists )
+{
+   GLint i;
+   FLUSH_VB(ctx, "dlist");
+
+   for (i=0;i<n;i++) {
+      GLuint list = translate_id( i, type, lists );
+      Node *n = alloc_instruction( ctx, OPCODE_CALL_LIST_OFFSET, 1 );
+      if (n) {
+         n[1].ui = list;
+      }
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.CallLists)( ctx, n, type, lists );
+   }
+}
+
+
+static void save_Clear( GLcontext *ctx, GLbitfield mask )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_CLEAR, 1 );
+   if (n) {
+      n[1].bf = mask;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.Clear)( ctx, mask );
+   }
+}
+
+
+static void save_ClearAccum( GLcontext *ctx, GLfloat red, GLfloat green,
+                        GLfloat blue, GLfloat alpha )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_CLEAR_ACCUM, 4 );
+   if (n) {
+      n[1].f = red;
+      n[2].f = green;
+      n[3].f = blue;
+      n[4].f = alpha;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.ClearAccum)( ctx, red, green, blue, alpha );
+   }
+}
+
+
+static void save_ClearColor( GLcontext *ctx, GLclampf red, GLclampf green,
+                        GLclampf blue, GLclampf alpha )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_CLEAR_COLOR, 4 );
+   if (n) {
+      n[1].f = red;
+      n[2].f = green;
+      n[3].f = blue;
+      n[4].f = alpha;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.ClearColor)( ctx, red, green, blue, alpha );
+   }
+}
+
+
+static void save_ClearDepth( GLcontext *ctx, GLclampd depth )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_CLEAR_DEPTH, 1 );
+   if (n) {
+      n[1].f = (GLfloat) depth;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.ClearDepth)( ctx, depth );
+   }
+}
+
+
+static void save_ClearIndex( GLcontext *ctx, GLfloat c )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_CLEAR_INDEX, 1 );
+   if (n) {
+      n[1].f = c;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.ClearIndex)( ctx, c );
+   }
+}
+
+
+static void save_ClearStencil( GLcontext *ctx, GLint s )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_CLEAR_STENCIL, 1 );
+   if (n) {
+      n[1].i = s;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.ClearStencil)( ctx, s );
+   }
+}
+
+
+static void save_ClipPlane( GLcontext *ctx, GLenum plane, const GLfloat *equ )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_CLIP_PLANE, 5 );
+   if (n) {
+      n[1].e = plane;
+      n[2].f = equ[0];
+      n[3].f = equ[1];
+      n[4].f = equ[2];
+      n[5].f = equ[3];
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.ClipPlane)( ctx, plane, equ );
+   }
+}
+
+
+
+static void save_ColorMask( GLcontext *ctx, GLboolean red, GLboolean green,
+                        GLboolean blue, GLboolean alpha )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_COLOR_MASK, 4 );
+   if (n) {
+      n[1].b = red;
+      n[2].b = green;
+      n[3].b = blue;
+      n[4].b = alpha;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.ColorMask)( ctx, red, green, blue, alpha );
+   }
+}
+
+
+static void save_ColorMaterial( GLcontext *ctx, GLenum face, GLenum mode )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_COLOR_MATERIAL, 2 );
+   if (n) {
+      n[1].e = face;
+      n[2].e = mode;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.ColorMaterial)( ctx, face, mode );
+   }
+}
+
+
+static void save_ColorTable( GLcontext *ctx, GLenum target, GLenum internalFormat,
+                         struct gl_image *table )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_COLOR_TABLE, 3 );
+   if (n) {
+      n[1].e = target;
+      n[2].e = internalFormat;
+      n[3].data = (GLvoid *) table;
+      if (table) {
+         /* must retain this image */
+         table->RefCount = 1;
+      }
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.ColorTable)( ctx, target, internalFormat, table );
+   }
+}
+
+
+static void save_ColorSubTable( GLcontext *ctx, GLenum target,
+                            GLsizei start, struct gl_image *data )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_COLOR_SUB_TABLE, 3 );
+   if (n) {
+      n[1].e = target;
+      n[2].i = start;
+      n[3].data = (GLvoid *) data;
+      if (data) {
+         /* must retain this image */
+         data->RefCount = 1;
+      }
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.ColorSubTable)( ctx, target, start, data );
+   }
+}
+
+
+
+static void save_CopyPixels( GLcontext *ctx, GLint x, GLint y,
+                        GLsizei width, GLsizei height, GLenum type )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_COPY_PIXELS, 5 );
+   if (n) {
+      n[1].i = x;
+      n[2].i = y;
+      n[3].i = (GLint) width;
+      n[4].i = (GLint) height;
+      n[5].e = type;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.CopyPixels)( ctx, x, y, width, height, type );
+   }
+}
+
+
+
+static void save_CopyTexImage1D( GLcontext *ctx,
+                             GLenum target, GLint level,
+                             GLenum internalformat,
+                             GLint x, GLint y, GLsizei width,
+                             GLint border )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_COPY_TEX_IMAGE1D, 7 );
+   if (n) {
+      n[1].e = target;
+      n[2].i = level;
+      n[3].e = internalformat;
+      n[4].i = x;
+      n[5].i = y;
+      n[6].i = width;
+      n[7].i = border;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.CopyTexImage1D)( ctx, target, level, internalformat,
+                            x, y, width, border );
+   }
+}
+
+
+static void save_CopyTexImage2D( GLcontext *ctx,
+                             GLenum target, GLint level,
+                             GLenum internalformat,
+                             GLint x, GLint y, GLsizei width,
+                             GLsizei height, GLint border )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_COPY_TEX_IMAGE2D, 8 );
+   if (n) {
+      n[1].e = target;
+      n[2].i = level;
+      n[3].e = internalformat;
+      n[4].i = x;
+      n[5].i = y;
+      n[6].i = width;
+      n[7].i = height;
+      n[8].i = border;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.CopyTexImage2D)( ctx, target, level, internalformat,
+                            x, y, width, height, border );
+   }
+}
+
+
+
+static void save_CopyTexSubImage1D( GLcontext *ctx,
+                                GLenum target, GLint level,
+                                GLint xoffset, GLint x, GLint y,
+                                GLsizei width )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_COPY_TEX_SUB_IMAGE1D, 6 );
+   if (n) {
+      n[1].e = target;
+      n[2].i = level;
+      n[3].i = xoffset;
+      n[4].i = x;
+      n[5].i = y;
+      n[6].i = width;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.CopyTexSubImage1D)( ctx, target, level, xoffset, x, y, width );
+   }
+}
+
+
+static void save_CopyTexSubImage2D( GLcontext *ctx,
+                                GLenum target, GLint level,
+                                GLint xoffset, GLint yoffset,
+                                GLint x, GLint y,
+                                GLsizei width, GLint height )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_COPY_TEX_SUB_IMAGE2D, 8 );
+   if (n) {
+      n[1].e = target;
+      n[2].i = level;
+      n[3].i = xoffset;
+      n[4].i = yoffset;
+      n[5].i = x;
+      n[6].i = y;
+      n[7].i = width;
+      n[8].i = height;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.CopyTexSubImage2D)( ctx, target, level, xoffset, yoffset,
+                               x, y, width, height );
+   }
+}
+
+
+static void save_CopyTexSubImage3DEXT( GLcontext *ctx,
+                                   GLenum target, GLint level,
+                                   GLint xoffset, GLint yoffset, GLint zoffset,
+                                   GLint x, GLint y,
+                                   GLsizei width, GLint height )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_COPY_TEX_SUB_IMAGE3D, 9 );
+   if (n) {
+      n[1].e = target;
+      n[2].i = level;
+      n[3].i = xoffset;
+      n[4].i = yoffset;
+      n[5].i = zoffset;
+      n[6].i = x;
+      n[7].i = y;
+      n[8].i = width;
+      n[9].i = height;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.CopyTexSubImage3DEXT)( ctx, target, level, xoffset, yoffset, zoffset,
+                               x, y, width, height );
+   }
+}
+
+
+static void save_CullFace( GLcontext *ctx, GLenum mode )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_CULL_FACE, 1 );
+   if (n) {
+      n[1].e = mode;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.CullFace)( ctx, mode );
+   }
+}
+
+
+static void save_DepthFunc( GLcontext *ctx, GLenum func )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_DEPTH_FUNC, 1 );
+   if (n) {
+      n[1].e = func;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.DepthFunc)( ctx, func );
+   }
+}
+
+
+static void save_DepthMask( GLcontext *ctx, GLboolean mask )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_DEPTH_MASK, 1 );
+   if (n) {
+      n[1].b = mask;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.DepthMask)( ctx, mask );
+   }
+}
+
+
+static void save_DepthRange( GLcontext *ctx, GLclampd nearval, GLclampd farval )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_DEPTH_RANGE, 2 );
+   if (n) {
+      n[1].f = (GLfloat) nearval;
+      n[2].f = (GLfloat) farval;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.DepthRange)( ctx, nearval, farval );
+   }
+}
+
+
+static void save_Disable( GLcontext *ctx, GLenum cap )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_DISABLE, 1 );
+   if (n) {
+      n[1].e = cap;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.Disable)( ctx, cap );
+   }
+}
+
+
+static void save_DrawBuffer( GLcontext *ctx, GLenum mode )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_DRAW_BUFFER, 1 );
+   if (n) {
+      n[1].e = mode;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.DrawBuffer)( ctx, mode );
+   }
+}
+
+
+static void save_DrawPixels( GLcontext *ctx, struct gl_image *image )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_DRAW_PIXELS, 1 );
+   if (n) {
+      n[1].data = (GLvoid *) image;
+   }
+   if (image) {
+      image->RefCount = 1;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.DrawPixels)( ctx, image );
+   }
+}
+
+
+
+static void save_Enable( GLcontext *ctx, GLenum cap )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_ENABLE, 1 );
+   if (n) {
+      n[1].e = cap;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.Enable)( ctx, cap );
+   }
+}
+
+
+
+static void save_EvalMesh1( GLcontext *ctx,
+                        GLenum mode, GLint i1, GLint i2 )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_EVALMESH1, 3 );
+   if (n) {
+      n[1].e = mode;
+      n[2].i = i1;
+      n[3].i = i2;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.EvalMesh1)( ctx, mode, i1, i2 );
+   }
+}
+
+
+static void save_EvalMesh2( GLcontext *ctx, 
+                        GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_EVALMESH2, 5 );
+   if (n) {
+      n[1].e = mode;
+      n[2].i = i1;
+      n[3].i = i2;
+      n[4].i = j1;
+      n[5].i = j2;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.EvalMesh2)( ctx, mode, i1, i2, j1, j2 );
+   }
+}
+
+
+
+
+static void save_Fogfv( GLcontext *ctx, GLenum pname, const GLfloat *params )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_FOG, 5 );
+   if (n) {
+      n[1].e = pname;
+      n[2].f = params[0];
+      n[3].f = params[1];
+      n[4].f = params[2];
+      n[5].f = params[3];
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.Fogfv)( ctx, pname, params );
+   }
+}
+
+
+static void save_FrontFace( GLcontext *ctx, GLenum mode )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_FRONT_FACE, 1 );
+   if (n) {
+      n[1].e = mode;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.FrontFace)( ctx, mode );
+   }
+}
+
+
+static void save_Frustum( GLcontext *ctx, GLdouble left, GLdouble right,
+                      GLdouble bottom, GLdouble top,
+                      GLdouble nearval, GLdouble farval )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_FRUSTUM, 6 );
+   if (n) {
+      n[1].f = left;
+      n[2].f = right;
+      n[3].f = bottom;
+      n[4].f = top;
+      n[5].f = nearval;
+      n[6].f = farval;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.Frustum)( ctx, left, right, bottom, top, nearval, farval );
+   }
+}
+
+
+static GLboolean save_Hint( GLcontext *ctx, GLenum target, GLenum mode )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_HINT, 2 );
+   if (n) {
+      n[1].e = target;
+      n[2].e = mode;
+   }
+   if (ctx->ExecuteFlag) {
+      return (*ctx->Exec.Hint)( ctx, target, mode );
+   }
+   return GL_TRUE;             /* not queried */
+}
+
+
+
+static void save_IndexMask( GLcontext *ctx, GLuint mask )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_INDEX_MASK, 1 );
+   if (n) {
+      n[1].ui = mask;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.IndexMask)( ctx, mask );
+   }
+}
+
+
+static void save_InitNames( GLcontext *ctx )
+{
+   FLUSH_VB(ctx, "dlist");
+   (void) alloc_instruction( ctx, OPCODE_INIT_NAMES, 0 );
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.InitNames)( ctx );
+   }
+}
+
+
+static void save_Lightfv( GLcontext *ctx, GLenum light, GLenum pname,
+                      const GLfloat *params, GLint numparams )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_LIGHT, 6 );
+   if (OPCODE_LIGHT) {
+      GLint i;
+      n[1].e = light;
+      n[2].e = pname;
+      for (i=0;i<numparams;i++) {
+        n[3+i].f = params[i];
+      }
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.Lightfv)( ctx, light, pname, params, numparams );
+   }
+}
+
+
+static void save_LightModelfv( GLcontext *ctx,
+                           GLenum pname, const GLfloat *params )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_LIGHT_MODEL, 5 );
+   if (n) {
+      n[1].e = pname;
+      n[2].f = params[0];
+      n[3].f = params[1];
+      n[4].f = params[2];
+      n[5].f = params[3];
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.LightModelfv)( ctx, pname, params );
+   }
+}
+
+
+static void save_LineStipple( GLcontext *ctx, GLint factor, GLushort pattern )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_LINE_STIPPLE, 2 );
+   if (n) {
+      n[1].i = factor;
+      n[2].us = pattern;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.LineStipple)( ctx, factor, pattern );
+   }
+}
+
+
+static void save_LineWidth( GLcontext *ctx, GLfloat width )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_LINE_WIDTH, 1 );
+   if (n) {
+      n[1].f = width;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.LineWidth)( ctx, width );
+   }
+}
+
+
+static void save_ListBase( GLcontext *ctx, GLuint base )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_LIST_BASE, 1 );
+   if (n) {
+      n[1].ui = base;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.ListBase)( ctx, base );
+   }
+}
+
+
+static void save_LoadIdentity( GLcontext *ctx )
+{
+   FLUSH_VB(ctx, "dlist");
+   (void) alloc_instruction( ctx, OPCODE_LOAD_IDENTITY, 0 );
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.LoadIdentity)( ctx );
+   }
+}
+
+
+static void save_LoadMatrixf( GLcontext *ctx, const GLfloat *m )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_LOAD_MATRIX, 16 );
+   if (n) {
+      GLuint i;
+      for (i=0;i<16;i++) {
+        n[1+i].f = m[i];
+      }
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.LoadMatrixf)( ctx, m );
+   }
+}
+
+
+static void save_LoadName( GLcontext *ctx, GLuint name )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_LOAD_NAME, 1 );
+   if (n) {
+      n[1].ui = name;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.LoadName)( ctx, name );
+   }
+}
+
+
+static void save_LogicOp( GLcontext *ctx, GLenum opcode )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_LOGIC_OP, 1 );
+   if (n) {
+      n[1].e = opcode;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.LogicOp)( ctx, opcode );
+   }
+}
+
+
+static void save_Map1f( GLcontext *ctx,
+                   GLenum target, GLfloat u1, GLfloat u2, GLint stride,
+                  GLint order, const GLfloat *points, GLboolean retain )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_MAP1, 6 );
+   if (n) {
+      n[1].e = target;
+      n[2].f = u1;
+      n[3].f = u2;
+      n[4].i = stride;
+      n[5].i = order;
+      n[6].data = (void *) points;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.Map1f)( ctx, target, u1, u2, stride, order, points, GL_TRUE );
+   }
+   (void) retain;
+}
+
+
+static void save_Map2f( GLcontext *ctx, GLenum target,
+                    GLfloat u1, GLfloat u2, GLint ustride, GLint uorder,
+                    GLfloat v1, GLfloat v2, GLint vstride, GLint vorder,
+                    const GLfloat *points, GLboolean retain )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_MAP2, 10 );
+   if (n) {
+      n[1].e = target;
+      n[2].f = u1;
+      n[3].f = u2;
+      n[4].f = v1;
+      n[5].f = v2;
+      n[6].i = ustride;
+      n[7].i = vstride;
+      n[8].i = uorder;
+      n[9].i = vorder;
+      n[10].data = (void *) points;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.Map2f)( ctx, target,
+                        u1, u2, ustride, uorder,
+                        v1, v2, vstride, vorder, points, GL_TRUE );
+   }
+   (void) retain;
+}
+
+
+static void save_MapGrid1f( GLcontext *ctx, GLint un, GLfloat u1, GLfloat u2 )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_MAPGRID1, 3 );
+   if (n) {
+      n[1].i = un;
+      n[2].f = u1;
+      n[3].f = u2;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.MapGrid1f)( ctx, un, u1, u2 );
+   }
+}
+
+
+static void save_MapGrid2f( GLcontext *ctx, 
+                        GLint un, GLfloat u1, GLfloat u2,
+                       GLint vn, GLfloat v1, GLfloat v2 )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_MAPGRID2, 6 );
+   if (n) {
+      n[1].i = un;
+      n[2].f = u1;
+      n[3].f = u2;
+      n[4].i = vn;
+      n[5].f = v1;
+      n[6].f = v2;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.MapGrid2f)( ctx, un, u1, u2, vn, v1, v2 );
+   }
+}
+
+
+static void save_MatrixMode( GLcontext *ctx, GLenum mode )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_MATRIX_MODE, 1 );
+   if (n) {
+      n[1].e = mode;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.MatrixMode)( ctx, mode );
+   }
+}
+
+
+static void save_MultMatrixf( GLcontext *ctx, const GLfloat *m )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_MULT_MATRIX, 16 );
+   if (n) {
+      GLuint i;
+      for (i=0;i<16;i++) {
+        n[1+i].f = m[i];
+      }
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.MultMatrixf)( ctx, m );
+   }
+}
+
+
+static void save_NewList( GLcontext *ctx, GLuint list, GLenum mode )
+{
+   /* It's an error to call this function while building a display list */
+   gl_error( ctx, GL_INVALID_OPERATION, "glNewList" );
+   (void) list;
+   (void) mode;
+}
+
+
+
+static void save_Ortho( GLcontext *ctx, GLdouble left, GLdouble right,
+                    GLdouble bottom, GLdouble top,
+                    GLdouble nearval, GLdouble farval )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_ORTHO, 6 );
+   if (n) {
+      n[1].f = left;
+      n[2].f = right;
+      n[3].f = bottom;
+      n[4].f = top;
+      n[5].f = nearval;
+      n[6].f = farval;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.Ortho)( ctx, left, right, bottom, top, nearval, farval );
+   }
+}
+
+
+static void save_PixelMapfv( GLcontext *ctx,
+                         GLenum map, GLint mapsize, const GLfloat *values )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_PIXEL_MAP, 3 );
+   if (n) {
+      n[1].e = map;
+      n[2].i = mapsize;
+      n[3].data  = (void *) malloc( mapsize * sizeof(GLfloat) );
+      MEMCPY( n[3].data, (void *) values, mapsize * sizeof(GLfloat) );
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.PixelMapfv)( ctx, map, mapsize, values );
+   }
+}
+
+
+static void save_PixelTransferf( GLcontext *ctx, GLenum pname, GLfloat param )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_PIXEL_TRANSFER, 2 );
+   if (n) {
+      n[1].e = pname;
+      n[2].f = param;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.PixelTransferf)( ctx, pname, param );
+   }
+}
+
+
+static void save_PixelZoom( GLcontext *ctx, GLfloat xfactor, GLfloat yfactor )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_PIXEL_ZOOM, 2 );
+   if (n) {
+      n[1].f = xfactor;
+      n[2].f = yfactor;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.PixelZoom)( ctx, xfactor, yfactor );
+   }
+}
+
+
+static void save_PointParameterfvEXT( GLcontext *ctx, GLenum pname,
+                                  const GLfloat *params)
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_POINT_PARAMETERS, 4 );
+   if (n) {
+      n[1].e = pname;
+      n[2].f = params[0];
+      n[3].f = params[1];
+      n[4].f = params[2];
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.PointParameterfvEXT)( ctx, pname, params );
+   }
+}
+
+
+static void save_PointSize( GLcontext *ctx, GLfloat size )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_POINT_SIZE, 1 );
+   if (n) {
+      n[1].f = size;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.PointSize)( ctx, size );
+   }
+}
+
+
+static void save_PolygonMode( GLcontext *ctx, GLenum face, GLenum mode )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_POLYGON_MODE, 2 );
+   if (n) {
+      n[1].e = face;
+      n[2].e = mode;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.PolygonMode)( ctx, face, mode );
+   }
+}
+
+
+/*
+ * Polygon stipple must have been upacked already!
+ */
+static void save_PolygonStipple( GLcontext *ctx, const GLuint *pattern )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_POLYGON_STIPPLE, 1 );
+   if (n) {
+      void *data;
+      n[1].data = malloc( 32 * 4 );
+      data = n[1].data;   /* This needed for Acorn compiler */
+      MEMCPY( data, pattern, 32 * 4 );
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.PolygonStipple)( ctx, pattern );
+   }
+}
+
+
+static void save_PolygonOffset( GLcontext *ctx, GLfloat factor, GLfloat units )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_POLYGON_OFFSET, 2 );
+   if (n) {
+      n[1].f = factor;
+      n[2].f = units;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.PolygonOffset)( ctx, factor, units );
+   }
+}
+
+
+static void save_PopAttrib( GLcontext *ctx )
+{
+   FLUSH_VB(ctx, "dlist");
+   (void) alloc_instruction( ctx, OPCODE_POP_ATTRIB, 0 );
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.PopAttrib)( ctx );
+   }
+}
+
+
+static void save_PopMatrix( GLcontext *ctx )
+{
+   FLUSH_VB(ctx, "dlist");
+   (void) alloc_instruction( ctx, OPCODE_POP_MATRIX, 0 );
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.PopMatrix)( ctx );
+   }
+}
+
+
+static void save_PopName( GLcontext *ctx )
+{
+   FLUSH_VB(ctx, "dlist");
+   (void) alloc_instruction( ctx, OPCODE_POP_NAME, 0 );
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.PopName)( ctx );
+   }
+}
+
+
+static void save_PrioritizeTextures( GLcontext *ctx,
+                                 GLsizei num, const GLuint *textures,
+                                 const GLclampf *priorities )
+{
+   GLint i;
+   FLUSH_VB(ctx, "dlist");
+
+   for (i=0;i<num;i++) {
+      Node *n;
+      n = alloc_instruction( ctx,  OPCODE_PRIORITIZE_TEXTURE, 2 );
+      if (n) {
+         n[1].ui = textures[i];
+         n[2].f = priorities[i];
+      }
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.PrioritizeTextures)( ctx, num, textures, priorities );
+   }
+}
+
+
+static void save_PushAttrib( GLcontext *ctx, GLbitfield mask )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_PUSH_ATTRIB, 1 );
+   if (n) {
+      n[1].bf = mask;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.PushAttrib)( ctx, mask );
+   }
+}
+
+
+static void save_PushMatrix( GLcontext *ctx )
+{
+   FLUSH_VB(ctx, "dlist");
+   (void) alloc_instruction( ctx, OPCODE_PUSH_MATRIX, 0 );
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.PushMatrix)( ctx );
+   }
+}
+
+
+static void save_PushName( GLcontext *ctx, GLuint name )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_PUSH_NAME, 1 );
+   if (n) {
+      n[1].ui = name;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.PushName)( ctx, name );
+   }
+}
+
+
+static void save_RasterPos4f( GLcontext *ctx,
+                          GLfloat x, GLfloat y, GLfloat z, GLfloat w )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_RASTER_POS, 4 );
+   if (n) {
+      n[1].f = x;
+      n[2].f = y;
+      n[3].f = z;
+      n[4].f = w;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.RasterPos4f)( ctx, x, y, z, w );
+   }
+}
+
+
+static void save_PassThrough( GLcontext *ctx, GLfloat token )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_PASSTHROUGH, 1 );
+   if (n) {
+      n[1].f = token;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.PassThrough)( ctx, token );
+   }
+}
+
+
+static void save_ReadBuffer( GLcontext *ctx, GLenum mode )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_READ_BUFFER, 1 );
+   if (n) {
+      n[1].e = mode;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.ReadBuffer)( ctx, mode );
+   }
+}
+
+
+static void save_Rectf( GLcontext *ctx,
+                    GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_RECTF, 4 );
+   if (n) {
+      n[1].f = x1;
+      n[2].f = y1;
+      n[3].f = x2;
+      n[4].f = y2;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.Rectf)( ctx, x1, y1, x2, y2 );
+   }
+}
+
+
+static void save_Rotatef( GLcontext *ctx, GLfloat angle,
+                      GLfloat x, GLfloat y, GLfloat z )
+{
+   GLfloat m[16];
+   gl_rotation_matrix( angle, x, y, z, m );
+   save_MultMatrixf( ctx, m );  /* save and maybe execute */
+}
+
+
+static void save_Scalef( GLcontext *ctx, GLfloat x, GLfloat y, GLfloat z )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_SCALE, 3 );
+   if (n) {
+      n[1].f = x;
+      n[2].f = y;
+      n[3].f = z;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.Scalef)( ctx, x, y, z );
+   }
+}
+
+
+static void save_Scissor( GLcontext *ctx,
+                      GLint x, GLint y, GLsizei width, GLsizei height )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_SCISSOR, 4 );
+   if (n) {
+      n[1].i = x;
+      n[2].i = y;
+      n[3].i = width;
+      n[4].i = height;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.Scissor)( ctx, x, y, width, height );
+   }
+}
+
+
+static void save_ShadeModel( GLcontext *ctx, GLenum mode )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_SHADE_MODEL, 1 );
+   if (n) {
+      n[1].e = mode;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.ShadeModel)( ctx, mode );
+   }
+}
+
+
+static void save_StencilFunc( GLcontext *ctx, GLenum func, GLint ref, GLuint mask )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_STENCIL_FUNC, 3 );
+   if (n) {
+      n[1].e = func;
+      n[2].i = ref;
+      n[3].ui = mask;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.StencilFunc)( ctx, func, ref, mask );
+   }
+}
+
+
+static void save_StencilMask( GLcontext *ctx, GLuint mask )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_STENCIL_MASK, 1 );
+   if (n) {
+      n[1].ui = mask;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.StencilMask)( ctx, mask );
+   }
+}
+
+
+static void save_StencilOp( GLcontext *ctx,
+                        GLenum fail, GLenum zfail, GLenum zpass )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_STENCIL_OP, 3 );
+   if (n) {
+      n[1].e = fail;
+      n[2].e = zfail;
+      n[3].e = zpass;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.StencilOp)( ctx, fail, zfail, zpass );
+   }
+}
+
+
+
+
+static void save_TexEnvfv( GLcontext *ctx,
+                       GLenum target, GLenum pname, const GLfloat *params )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_TEXENV, 6 );
+   if (n) {
+      n[1].e = target;
+      n[2].e = pname;
+      n[3].f = params[0];
+      n[4].f = params[1];
+      n[5].f = params[2];
+      n[6].f = params[3];
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.TexEnvfv)( ctx, target, pname, params );
+   }
+}
+
+
+static void save_TexGenfv( GLcontext *ctx,
+                       GLenum coord, GLenum pname, const GLfloat *params )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_TEXGEN, 6 );
+   if (n) {
+      n[1].e = coord;
+      n[2].e = pname;
+      n[3].f = params[0];
+      n[4].f = params[1];
+      n[5].f = params[2];
+      n[6].f = params[3];
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.TexGenfv)( ctx, coord, pname, params );
+   }
+}
+
+
+static void save_TexParameterfv( GLcontext *ctx, GLenum target,
+                             GLenum pname, const GLfloat *params )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_TEXPARAMETER, 6 );
+   if (n) {
+      n[1].e = target;
+      n[2].e = pname;
+      n[3].f = params[0];
+      n[4].f = params[1];
+      n[5].f = params[2];
+      n[6].f = params[3];
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.TexParameterfv)( ctx, target, pname, params );
+   }
+}
+
+
+static void save_TexImage1D( GLcontext *ctx, GLenum target,
+                         GLint level, GLint components,
+                        GLsizei width, GLint border,
+                         GLenum format, GLenum type,
+                        struct gl_image *teximage )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_TEX_IMAGE1D, 8 );
+   if (n) {
+      n[1].e = target;
+      n[2].i = level;
+      n[3].i = components;
+      n[4].i = (GLint) width;
+      n[5].i = border;
+      n[6].e = format;
+      n[7].e = type;
+      n[8].data = teximage;
+      if (teximage) {
+         /* this prevents gl_TexImage2D() from freeing the image */
+         teximage->RefCount = 1;
+      }
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.TexImage1D)( ctx, target, level, components, width,
+                        border, format, type, teximage );
+   }
+}
+
+
+static void save_TexImage2D( GLcontext *ctx, GLenum target,
+                         GLint level, GLint components,
+                        GLsizei width, GLsizei height, GLint border,
+                         GLenum format, GLenum type,
+                        struct gl_image *teximage )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_TEX_IMAGE2D, 9 );
+   if (n) {
+      n[1].e = target;
+      n[2].i = level;
+      n[3].i = components;
+      n[4].i = (GLint) width;
+      n[5].i = (GLint) height;
+      n[6].i = border;
+      n[7].e = format;
+      n[8].e = type;
+      n[9].data = teximage;
+      if (teximage) {
+         /* this prevents gl_TexImage2D() from freeing the image */
+         teximage->RefCount = 1;
+      }
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.TexImage2D)( ctx, target, level, components, width,
+                        height, border, format, type, teximage );
+   }
+}
+
+
+static void save_TexImage3DEXT( GLcontext *ctx, GLenum target,
+                            GLint level, GLint components,
+                            GLsizei width, GLsizei height, GLsizei depth,
+                            GLint border,
+                            GLenum format, GLenum type,
+                            struct gl_image *teximage )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_TEX_IMAGE3D, 10 );
+   if (n) {
+      n[1].e = target;
+      n[2].i = level;
+      n[3].i = components;
+      n[4].i = (GLint) width;
+      n[5].i = (GLint) height;
+      n[6].i = (GLint) depth; 
+      n[7].i = border;
+      n[8].e = format;
+      n[9].e = type;
+      n[10].data = teximage;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.TexImage3DEXT)( ctx, target, level, components, width,
+                           height, depth, border, format, type, teximage );
+   }
+}
+
+
+static void save_TexSubImage1D( GLcontext *ctx,
+                            GLenum target, GLint level, GLint xoffset,
+                            GLsizei width, GLenum format, GLenum type,
+                            struct gl_image *image )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_TEX_SUB_IMAGE1D, 7 );
+   if (n) {
+      n[1].e = target;
+      n[2].i = level;
+      n[3].i = xoffset;
+      n[4].i = (GLint) width;
+      n[5].e = format;
+      n[6].e = type;
+      n[7].data = image;
+      if (image)
+         image->RefCount = 1;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.TexSubImage1D)( ctx, target, level, xoffset, width,
+                           format, type, image );
+   }
+}
+
+
+static void save_TexSubImage2D( GLcontext *ctx,
+                            GLenum target, GLint level,
+                            GLint xoffset, GLint yoffset,
+                            GLsizei width, GLsizei height,
+                            GLenum format, GLenum type,
+                            struct gl_image *image )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_TEX_SUB_IMAGE2D, 9 );
+   if (n) {
+      n[1].e = target;
+      n[2].i = level;
+      n[3].i = xoffset;
+      n[4].i = yoffset;
+      n[5].i = (GLint) width;
+      n[6].i = (GLint) height;
+      n[7].e = format;
+      n[8].e = type;
+      n[9].data = image;
+      if (image)
+         image->RefCount = 1;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.TexSubImage2D)( ctx, target, level, xoffset, yoffset,
+                           width, height, format, type, image );
+   }
+}
+
+
+static void save_TexSubImage3DEXT( GLcontext *ctx,
+                               GLenum target, GLint level,
+                               GLint xoffset, GLint yoffset,GLint zoffset,
+                               GLsizei width, GLsizei height, GLsizei depth,
+                               GLenum format, GLenum type,
+                               struct gl_image *image )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_TEX_SUB_IMAGE3D, 11 );
+   if (n) {
+      n[1].e = target;
+      n[2].i = level;
+      n[3].i = xoffset;
+      n[4].i = yoffset;
+      n[5].i = zoffset;
+      n[6].i = (GLint) width;
+      n[7].i = (GLint) height;
+      n[8].i = (GLint) depth;
+      n[9].e = format;
+      n[10].e = type;
+      n[11].data = image;
+      if (image)
+         image->RefCount = 1;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.TexSubImage3DEXT)( ctx, target, level, xoffset, yoffset, zoffset,
+                              width, height, depth, format, type, image );
+   }
+}
+
+
+static void save_Translatef( GLcontext *ctx, GLfloat x, GLfloat y, GLfloat z )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx,  OPCODE_TRANSLATE, 3 );
+   if (n) {
+      n[1].f = x;
+      n[2].f = y;
+      n[3].f = z;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.Translatef)( ctx, x, y, z );
+   }
+}
+
+
+
+static void save_Viewport( GLcontext *ctx,
+                       GLint x, GLint y, GLsizei width, GLsizei height )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx,  OPCODE_VIEWPORT, 4 );
+   if (n) {
+      n[1].i = x;
+      n[2].i = y;
+      n[3].i = (GLint) width;
+      n[4].i = (GLint) height;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.Viewport)( ctx, x, y, width, height );
+   }
+}
+
+
+static void save_WindowPos4fMESA( GLcontext *ctx,
+                              GLfloat x, GLfloat y, GLfloat z, GLfloat w )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx,  OPCODE_WINDOW_POS, 4 );
+   if (n) {
+      n[1].f = x;
+      n[2].f = y;
+      n[3].f = z;
+      n[4].f = w;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.WindowPos4fMESA)( ctx, x, y, z, w );
+   }
+}
+
+
+
+
+
+
+/* GL_ARB_multitexture */
+static void save_ActiveTexture( GLcontext *ctx, GLenum target )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_ACTIVE_TEXTURE, 1 );
+   if (n) {
+      n[1].e = target;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.ActiveTexture)( ctx, target );
+   }
+}
+
+
+/* GL_ARB_multitexture */
+static void save_ClientActiveTexture( GLcontext *ctx, GLenum target )
+{
+   Node *n;
+   FLUSH_VB(ctx, "dlist");
+   n = alloc_instruction( ctx, OPCODE_CLIENT_ACTIVE_TEXTURE, 1 );
+   if (n) {
+      n[1].e = target;
+   }
+   if (ctx->ExecuteFlag) {
+      (*ctx->Exec.ClientActiveTexture)( ctx, target );
+   }
+}
+
+
+
+
+
+void gl_compile_cassette( GLcontext *ctx )
+{
+   Node *n = alloc_instruction( ctx, OPCODE_VERTEX_CASSETTE, 1 );
+   struct immediate *new_im = gl_immediate_alloc(ctx);
+   struct immediate *im = ctx->input;
+   
+   if (!n || !new_im) {
+      if (n) free(n);
+      if (new_im) gl_immediate_free(new_im);
+      return;
+   }
+
+   /* Do some easy optimizations of the cassette.  If current value of
+    * clip volume hint is GL_FASTEST, we are not clipping anyway, so
+    * don't calculate the bounds.  But - they will not be calculated
+    * later even if the hint is changed, so this is a slightly odd
+    * behaviour.
+    */
+   if (ctx->Hint.ClipVolumeClipping != GL_FASTEST &&
+       im->v.Obj.size < 4 && 
+       im->Count > 15)
+   {
+      im->Bounds = (GLfloat (*)[3]) malloc(6 * sizeof(GLfloat));
+      (gl_calc_bound_tab[im->v.Obj.size])( im->Bounds, &im->v.Obj );
+   }
+
+
+   n[1].data = (void *)im;   
+   SET_IMMEDIATE( ctx, new_im );
+}
+
+/* KW: Compile commands  
+ * 
+ * Will appear in the list before the vertex buffer containing the
+ * command that provoked the error.  I don't see this as a problem.  
+ */
+void gl_save_error( GLcontext *ctx, GLenum error, const char *s )
+{
+   Node *n;
+   n = alloc_instruction( ctx, OPCODE_ERROR, 2 );
+   if (n) {
+      n[1].e = error;
+      n[2].data = (void *) s;
+   }
+   /* execute already done */
+}
+
+/**********************************************************************/
+/*                     Display list execution                         */
+/**********************************************************************/
+
+
+/*
+ * Execute a display list.  Note that the ListBase offset must have already
+ * been added before calling this function.  I.e. the list argument is
+ * the absolute list number, not relative to ListBase.
+ * Input:  list - display list number
+ */
+static void execute_list( GLcontext *ctx, GLuint list )
+{
+   Node *n;
+   GLboolean done;
+   OpCode opcode;
+
+   if (!gl_IsList(ctx,list))
+      return;
+
+/*    mesa_print_display_list( list ); */
+
+   ctx->CallDepth++;
+
+   n = (Node *) HashLookup(ctx->Shared->DisplayList, list);
+
+   done = GL_FALSE;
+   while (!done) {
+      opcode = n[0].opcode;
+
+      switch (opcode) {
+         case OPCODE_ERROR:
+           gl_error( ctx, n[1].e, (const char *) n[2].data ); 
+            break;
+         case OPCODE_VERTEX_CASSETTE:
+           if (ctx->NewState)
+              gl_update_state(ctx);
+           if (!ctx->CVA.elt.pipeline_valid)
+              gl_build_immediate_pipeline( ctx );
+           gl_fixup_cassette( ctx, (struct immediate *) n[1].data ); 
+           gl_execute_cassette( ctx, (struct immediate *) n[1].data ); 
+            break;
+         case OPCODE_ACCUM:
+           gl_Accum( ctx, n[1].e, n[2].f );
+           break;
+         case OPCODE_ALPHA_FUNC:
+           gl_AlphaFunc( ctx, n[1].e, n[2].f );
+           break;
+         case OPCODE_BIND_TEXTURE:
+            gl_BindTexture( ctx, n[1].e, n[2].ui );
+            break;
+        case OPCODE_BITMAP:
+            {
+               static struct gl_pixelstore_attrib defaultPacking = {
+                  1,            /* Alignment */
+                  0,            /* RowLength */
+                  0,            /* SkipPixels */
+                  0,            /* SkipRows */
+                  0,            /* ImageHeight */
+                  0,            /* SkipImages */
+                  GL_FALSE,     /* SwapBytes */
+                  GL_FALSE      /* LsbFirst */
+               };
+               const struct gl_image *image = (struct gl_image *) n[7].data;
+               const GLubyte *bitmap = image ? image->Data : NULL;
+               gl_Bitmap( ctx, (GLsizei) n[1].i, (GLsizei) n[2].i,
+                          n[3].f, n[4].f, n[5].f, n[6].f,
+                          bitmap, &defaultPacking );
+            }
+           break;
+        case OPCODE_BLEND_COLOR:
+           gl_BlendColor( ctx, n[1].f, n[2].f, n[3].f, n[4].f );
+           break;
+        case OPCODE_BLEND_EQUATION:
+           gl_BlendEquation( ctx, n[1].e );
+           break;
+        case OPCODE_BLEND_FUNC:
+           gl_BlendFunc( ctx, n[1].e, n[2].e );
+           break;
+        case OPCODE_BLEND_FUNC_SEPARATE:
+           gl_BlendFuncSeparate( ctx, n[1].e, n[2].e, n[3].e, n[4].e );
+           break;
+         case OPCODE_CALL_LIST:
+           /* Generated by glCallList(), don't add ListBase */
+            if (ctx->CallDepth<MAX_LIST_NESTING) {
+               execute_list( ctx, n[1].ui );
+            }
+            break;
+         case OPCODE_CALL_LIST_OFFSET:
+           /* Generated by glCallLists() so we must add ListBase */
+            if (ctx->CallDepth<MAX_LIST_NESTING) {
+               execute_list( ctx, ctx->List.ListBase + n[1].ui );
+            }
+            break;
+        case OPCODE_CLEAR:
+           gl_Clear( ctx, n[1].bf );
+           break;
+        case OPCODE_CLEAR_COLOR:
+           gl_ClearColor( ctx, n[1].f, n[2].f, n[3].f, n[4].f );
+           break;
+        case OPCODE_CLEAR_ACCUM:
+           gl_ClearAccum( ctx, n[1].f, n[2].f, n[3].f, n[4].f );
+           break;
+        case OPCODE_CLEAR_DEPTH:
+           gl_ClearDepth( ctx, (GLclampd) n[1].f );
+           break;
+        case OPCODE_CLEAR_INDEX:
+           gl_ClearIndex( ctx, n[1].ui );
+           break;
+        case OPCODE_CLEAR_STENCIL:
+           gl_ClearStencil( ctx, n[1].i );
+           break;
+         case OPCODE_CLIP_PLANE:
+            {
+               GLfloat equ[4];
+               equ[0] = n[2].f;
+               equ[1] = n[3].f;
+               equ[2] = n[4].f;
+               equ[3] = n[5].f;
+               gl_ClipPlane( ctx, n[1].e, equ );
+            }
+            break;
+        case OPCODE_COLOR_MASK:
+           gl_ColorMask( ctx, n[1].b, n[2].b, n[3].b, n[4].b );
+           break;
+        case OPCODE_COLOR_MATERIAL:
+           gl_ColorMaterial( ctx, n[1].e, n[2].e );
+           break;
+         case OPCODE_COLOR_TABLE:
+            gl_ColorTable( ctx, n[1].e, n[2].e, (struct gl_image *) n[3].data);
+            break;
+         case OPCODE_COLOR_SUB_TABLE:
+            gl_ColorSubTable( ctx, n[1].e, n[2].i,
+                              (struct gl_image *) n[3].data);
+            break;
+        case OPCODE_COPY_PIXELS:
+           gl_CopyPixels( ctx, n[1].i, n[2].i,
+                          (GLsizei) n[3].i, (GLsizei) n[4].i, n[5].e );
+           break;
+         case OPCODE_COPY_TEX_IMAGE1D:
+           gl_CopyTexImage1D( ctx, n[1].e, n[2].i, n[3].e, n[4].i,
+                               n[5].i, n[6].i, n[7].i );
+            break;
+         case OPCODE_COPY_TEX_IMAGE2D:
+           gl_CopyTexImage2D( ctx, n[1].e, n[2].i, n[3].e, n[4].i,
+                               n[5].i, n[6].i, n[7].i, n[8].i );
+            break;
+         case OPCODE_COPY_TEX_SUB_IMAGE1D:
+           gl_CopyTexSubImage1D( ctx, n[1].e, n[2].i, n[3].i, n[4].i,
+                                  n[5].i, n[6].i );
+            break;
+         case OPCODE_COPY_TEX_SUB_IMAGE2D:
+           gl_CopyTexSubImage2D( ctx, n[1].e, n[2].i, n[3].i, n[4].i,
+                                  n[5].i, n[6].i, n[7].i, n[8].i );
+            break;
+         case OPCODE_COPY_TEX_SUB_IMAGE3D:
+            gl_CopyTexSubImage3DEXT( ctx, n[1].e, n[2].i, n[3].i, n[4].i,
+                                     n[5].i, n[6].i, n[7].i, n[8].i , n[9].i);
+            break;
+        case OPCODE_CULL_FACE:
+           gl_CullFace( ctx, n[1].e );
+           break;
+        case OPCODE_DEPTH_FUNC:
+           gl_DepthFunc( ctx, n[1].e );
+           break;
+        case OPCODE_DEPTH_MASK:
+           gl_DepthMask( ctx, n[1].b );
+           break;
+        case OPCODE_DEPTH_RANGE:
+           gl_DepthRange( ctx, (GLclampd) n[1].f, (GLclampd) n[2].f );
+           break;
+        case OPCODE_DISABLE:
+           gl_Disable( ctx, n[1].e );
+           break;
+        case OPCODE_DRAW_BUFFER:
+           gl_DrawBuffer( ctx, n[1].e );
+           break;
+        case OPCODE_DRAW_PIXELS:
+           gl_DrawPixels( ctx, (struct gl_image *) n[1].data );
+           break;
+        case OPCODE_ENABLE:
+           gl_Enable( ctx, n[1].e );
+           break;
+        case OPCODE_EVALMESH1:
+           gl_EvalMesh1( ctx, n[1].e, n[2].i, n[3].i );
+           break;
+        case OPCODE_EVALMESH2:
+           gl_EvalMesh2( ctx, n[1].e, n[2].i, n[3].i, n[4].i, n[5].i );
+           break;
+        case OPCODE_FOG:
+           {
+              GLfloat p[4];
+              p[0] = n[2].f;
+              p[1] = n[3].f;
+              p[2] = n[4].f;
+              p[3] = n[5].f;
+              gl_Fogfv( ctx, n[1].e, p );
+           }
+           break;
+        case OPCODE_FRONT_FACE:
+           gl_FrontFace( ctx, n[1].e );
+           break;
+         case OPCODE_FRUSTUM:
+            gl_Frustum( ctx, n[1].f, n[2].f, n[3].f, n[4].f, n[5].f, n[6].f );
+            break;
+        case OPCODE_HINT:
+           gl_Hint( ctx, n[1].e, n[2].e );
+           break;
+        case OPCODE_INDEX_MASK:
+           gl_IndexMask( ctx, n[1].ui );
+           break;
+        case OPCODE_INIT_NAMES:
+           gl_InitNames( ctx );
+           break;
+         case OPCODE_LIGHT:
+           {
+              GLfloat p[4];
+              p[0] = n[3].f;
+              p[1] = n[4].f;
+              p[2] = n[5].f;
+              p[3] = n[6].f;
+              gl_Lightfv( ctx, n[1].e, n[2].e, p, 4 );
+           }
+           break;
+         case OPCODE_LIGHT_MODEL:
+           {
+              GLfloat p[4];
+              p[0] = n[2].f;
+              p[1] = n[3].f;
+              p[2] = n[4].f;
+              p[3] = n[5].f;
+              gl_LightModelfv( ctx, n[1].e, p );
+           }
+           break;
+        case OPCODE_LINE_STIPPLE:
+           gl_LineStipple( ctx, n[1].i, n[2].us );
+           break;
+        case OPCODE_LINE_WIDTH:
+           gl_LineWidth( ctx, n[1].f );
+           break;
+        case OPCODE_LIST_BASE:
+           gl_ListBase( ctx, n[1].ui );
+           break;
+        case OPCODE_LOAD_IDENTITY:
+            gl_LoadIdentity( ctx );
+            break;
+        case OPCODE_LOAD_MATRIX:
+           if (sizeof(Node)==sizeof(GLfloat)) {
+              gl_LoadMatrixf( ctx, &n[1].f );
+           }
+           else {
+              GLfloat m[16];
+              GLuint i;
+              for (i=0;i<16;i++) {
+                 m[i] = n[1+i].f;
+              }
+              gl_LoadMatrixf( ctx, m );
+           }
+           break;
+        case OPCODE_LOAD_NAME:
+           gl_LoadName( ctx, n[1].ui );
+           break;
+        case OPCODE_LOGIC_OP:
+           gl_LogicOp( ctx, n[1].e );
+           break;
+        case OPCODE_MAP1:
+           gl_Map1f( ctx, n[1].e, n[2].f, n[3].f,
+                      n[4].i, n[5].i, (GLfloat *) n[6].data, GL_TRUE );
+           break;
+        case OPCODE_MAP2:
+           gl_Map2f( ctx, n[1].e,
+                      n[2].f, n[3].f,  /* u1, u2 */
+                     n[6].i, n[8].i,  /* ustride, uorder */
+                     n[4].f, n[5].f,  /* v1, v2 */
+                     n[7].i, n[9].i,  /* vstride, vorder */
+                     (GLfloat *) n[10].data,
+                      GL_TRUE);
+           break;
+        case OPCODE_MAPGRID1:
+           gl_MapGrid1f( ctx, n[1].i, n[2].f, n[3].f );
+           break;
+        case OPCODE_MAPGRID2:
+           gl_MapGrid2f( ctx, n[1].i, n[2].f, n[3].f, n[4].i, n[5].f, n[6].f);
+           break;
+         case OPCODE_MATRIX_MODE:
+            gl_MatrixMode( ctx, n[1].e );
+            break;
+        case OPCODE_MULT_MATRIX:
+           if (sizeof(Node)==sizeof(GLfloat)) {
+              gl_MultMatrixf( ctx, &n[1].f );
+           }
+           else {
+              GLfloat m[16];
+              GLuint i;
+              for (i=0;i<16;i++) {
+                 m[i] = n[1+i].f;
+              }
+              gl_MultMatrixf( ctx, m );
+           }
+           break;
+         case OPCODE_ORTHO:
+            gl_Ortho( ctx, n[1].f, n[2].f, n[3].f, n[4].f, n[5].f, n[6].f );
+            break;
+        case OPCODE_PASSTHROUGH:
+           gl_PassThrough( ctx, n[1].f );
+           break;
+        case OPCODE_PIXEL_MAP:
+           gl_PixelMapfv( ctx, n[1].e, n[2].i, (GLfloat *) n[3].data );
+           break;
+        case OPCODE_PIXEL_TRANSFER:
+           gl_PixelTransferf( ctx, n[1].e, n[2].f );
+           break;
+        case OPCODE_PIXEL_ZOOM:
+           gl_PixelZoom( ctx, n[1].f, n[2].f );
+           break;
+        case OPCODE_POINT_SIZE:
+           gl_PointSize( ctx, n[1].f );
+           break;
+        case OPCODE_POINT_PARAMETERS:
+           {
+               GLfloat params[3];
+               params[0] = n[2].f;
+               params[1] = n[3].f;
+               params[2] = n[4].f;
+               gl_PointParameterfvEXT( ctx, n[1].e, params ); 
+           }
+           break;
+        case OPCODE_POLYGON_MODE:
+           gl_PolygonMode( ctx, n[1].e, n[2].e );
+           break;
+        case OPCODE_POLYGON_STIPPLE:
+           gl_PolygonStipple( ctx, (GLuint *) n[1].data );
+           break;
+        case OPCODE_POLYGON_OFFSET:
+           gl_PolygonOffset( ctx, n[1].f, n[2].f );
+           break;
+        case OPCODE_POP_ATTRIB:
+           gl_PopAttrib( ctx );
+           break;
+        case OPCODE_POP_MATRIX:
+           gl_PopMatrix( ctx );
+           break;
+        case OPCODE_POP_NAME:
+           gl_PopName( ctx );
+           break;
+        case OPCODE_PRIORITIZE_TEXTURE:
+            gl_PrioritizeTextures( ctx, 1, &n[1].ui, &n[2].f );
+           break;
+        case OPCODE_PUSH_ATTRIB:
+           gl_PushAttrib( ctx, n[1].bf );
+           break;
+        case OPCODE_PUSH_MATRIX:
+           gl_PushMatrix( ctx );
+           break;
+        case OPCODE_PUSH_NAME:
+           gl_PushName( ctx, n[1].ui );
+           break;
+        case OPCODE_RASTER_POS:
+            gl_RasterPos4f( ctx, n[1].f, n[2].f, n[3].f, n[4].f );
+           break;
+        case OPCODE_READ_BUFFER:
+           gl_ReadBuffer( ctx, n[1].e );
+           break;
+         case OPCODE_RECTF:
+            gl_Rectf( ctx, n[1].f, n[2].f, n[3].f, n[4].f );
+            break;
+         case OPCODE_SCALE:
+            gl_Scalef( ctx, n[1].f, n[2].f, n[3].f );
+            break;
+        case OPCODE_SCISSOR:
+           gl_Scissor( ctx, n[1].i, n[2].i, n[3].i, n[4].i );
+           break;
+        case OPCODE_SHADE_MODEL:
+           gl_ShadeModel( ctx, n[1].e );
+           break;
+        case OPCODE_STENCIL_FUNC:
+           gl_StencilFunc( ctx, n[1].e, n[2].i, n[3].ui );
+           break;
+        case OPCODE_STENCIL_MASK:
+           gl_StencilMask( ctx, n[1].ui );
+           break;
+        case OPCODE_STENCIL_OP:
+           gl_StencilOp( ctx, n[1].e, n[2].e, n[3].e );
+           break;
+         case OPCODE_TEXENV:
+            {
+               GLfloat params[4];
+               params[0] = n[3].f;
+               params[1] = n[4].f;
+               params[2] = n[5].f;
+               params[3] = n[6].f;
+               gl_TexEnvfv( ctx, n[1].e, n[2].e, params );
+            }
+            break;
+         case OPCODE_TEXGEN:
+            {
+               GLfloat params[4];
+               params[0] = n[3].f;
+               params[1] = n[4].f;
+               params[2] = n[5].f;
+               params[3] = n[6].f;
+               gl_TexGenfv( ctx, n[1].e, n[2].e, params );
+            }
+            break;
+         case OPCODE_TEXPARAMETER:
+            {
+               GLfloat params[4];
+               params[0] = n[3].f;
+               params[1] = n[4].f;
+               params[2] = n[5].f;
+               params[3] = n[6].f;
+               gl_TexParameterfv( ctx, n[1].e, n[2].e, params );
+            }
+            break;
+        case OPCODE_TEX_IMAGE1D:
+           gl_TexImage1D( ctx,
+                           n[1].e, /* target */
+                           n[2].i, /* level */
+                           n[3].i, /* components */
+                           n[4].i, /* width */
+                           n[5].e, /* border */
+                           n[6].e, /* format */
+                           n[7].e, /* type */
+                           (struct gl_image *) n[8].data );
+           break;
+        case OPCODE_TEX_IMAGE2D:
+           gl_TexImage2D( ctx,
+                           n[1].e, /* target */
+                           n[2].i, /* level */
+                           n[3].i, /* components */
+                           n[4].i, /* width */
+                           n[5].i, /* height */
+                           n[6].e, /* border */
+                           n[7].e, /* format */
+                           n[8].e, /* type */
+                           (struct gl_image *) n[9].data );
+           break;
+         case OPCODE_TEX_IMAGE3D:
+            gl_TexImage3DEXT( ctx,
+                              n[1].e, /* target */
+                              n[2].i, /* level */
+                              n[3].i, /* components */
+                              n[4].i, /* width */
+                              n[5].i, /* height */
+                              n[6].i, /* depth  */
+                              n[7].e, /* border */
+                              n[8].e, /* format */
+                              n[9].e, /* type */
+                              (struct gl_image *) n[10].data );
+            break;
+         case OPCODE_TEX_SUB_IMAGE1D:
+            gl_TexSubImage1D( ctx, n[1].e, n[2].i, n[3].i, n[4].i, n[5].e,
+                              n[6].e, (struct gl_image *) n[7].data );
+            break;
+         case OPCODE_TEX_SUB_IMAGE2D:
+            gl_TexSubImage2D( ctx, n[1].e, n[2].i, n[3].i, n[4].i, n[5].e,
+                              n[6].i, n[7].e, n[8].e,
+                              (struct gl_image *) n[9].data );
+            break;
+         case OPCODE_TEX_SUB_IMAGE3D:
+            gl_TexSubImage3DEXT( ctx, n[1].e, n[2].i, n[3].i, n[4].i, n[5].i,
+                                 n[6].i, n[7].i, n[8].i, n[9].e, n[10].e,
+                                 (struct gl_image *) n[11].data );
+            break;
+         case OPCODE_TRANSLATE:
+            gl_Translatef( ctx, n[1].f, n[2].f, n[3].f );
+            break;
+        case OPCODE_VIEWPORT:
+           gl_Viewport( ctx,
+                         n[1].i, n[2].i, (GLsizei) n[3].i, (GLsizei) n[4].i );
+           break;
+        case OPCODE_WINDOW_POS:
+            gl_WindowPos4fMESA( ctx, n[1].f, n[2].f, n[3].f, n[4].f );
+           break;
+         case OPCODE_ACTIVE_TEXTURE:  /* GL_ARB_multitexture */
+            gl_ActiveTexture( ctx, n[1].e );
+            break;
+         case OPCODE_CLIENT_ACTIVE_TEXTURE:  /* GL_ARB_multitexture */
+            gl_ClientActiveTexture( ctx, n[1].e );
+            break;
+        case OPCODE_CONTINUE:
+           n = (Node *) n[1].next;
+           break;
+        case OPCODE_END_OF_LIST:
+           done = GL_TRUE;
+           break;
+        default:
+            {
+               char msg[1000];
+               sprintf(msg, "Error in execute_list: opcode=%d", (int) opcode);
+               gl_problem( ctx, msg );
+            }
+            done = GL_TRUE;
+      }
+
+      /* increment n to point to next compiled command */
+      if (opcode!=OPCODE_CONTINUE) {
+        n += InstSize[opcode];
+      }
+
+   }
+   ctx->CallDepth--;
+}
+
+
+
+
+
+/**********************************************************************/
+/*                           GL functions                             */
+/**********************************************************************/
+
+
+
+
+/*
+ * Test if a display list number is valid.
+ */
+GLboolean gl_IsList( GLcontext *ctx, GLuint list )
+{
+   if (list > 0 && HashLookup(ctx->Shared->DisplayList, list)) {
+      return GL_TRUE;
+   }
+   else {
+      return GL_FALSE;
+   }
+}
+
+
+
+/*
+ * Delete a sequence of consecutive display lists.
+ */
+void gl_DeleteLists( GLcontext *ctx, GLuint list, GLsizei range )
+{
+   GLuint i;
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDeleteLists");
+   if (range<0) {
+      gl_error( ctx, GL_INVALID_VALUE, "glDeleteLists" );
+      return;
+   }
+   for (i=list;i<list+range;i++) {
+      gl_destroy_list( ctx, i );
+   }
+}
+
+
+
+/*
+ * Return a display list number, n, such that lists n through n+range-1
+ * are free.
+ */
+GLuint gl_GenLists( GLcontext *ctx, GLsizei range )
+{
+   GLuint base;
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH_WITH_RETVAL(ctx, "glGenLists", 0);
+   if (range<0) {
+      gl_error( ctx, GL_INVALID_VALUE, "glGenLists" );
+      return 0;
+   }
+   if (range==0) {
+      return 0;
+   }
+
+   base = HashFindFreeKeyBlock(ctx->Shared->DisplayList, range);
+   if (base) {
+      /* reserve the list IDs by with empty/dummy lists */
+      GLint i;
+      for (i=0; i<range; i++) {
+         HashInsert(ctx->Shared->DisplayList, base+i, make_empty_list());
+      }
+   }
+   return base;
+}
+
+
+
+/*
+ * Begin a new display list.
+ */
+void gl_NewList( GLcontext *ctx, GLuint list, GLenum mode )
+{
+   struct immediate *IM;
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glNewList");
+
+   if (MESA_VERBOSE&VERBOSE_API)
+      fprintf(stderr, "glNewList %u %s\n", list, gl_lookup_enum_by_nr(mode));
+
+   if (list==0) {
+      gl_error( ctx, GL_INVALID_VALUE, "glNewList" );
+      return;
+   }
+
+   if (mode!=GL_COMPILE && mode!=GL_COMPILE_AND_EXECUTE) {
+      gl_error( ctx, GL_INVALID_ENUM, "glNewList" );
+      return;
+   }
+
+   if (ctx->CurrentListPtr) {
+      /* already compiling a display list */
+      gl_error( ctx, GL_INVALID_OPERATION, "glNewList" );
+      return;
+   }
+
+   /* Allocate new display list */
+   ctx->CurrentListNum = list;
+   ctx->CurrentBlock = (Node *) malloc( sizeof(Node) * BLOCK_SIZE );
+   ctx->CurrentListPtr = ctx->CurrentBlock;
+   ctx->CurrentPos = 0;
+
+   IM = gl_immediate_alloc( ctx );
+   SET_IMMEDIATE( ctx, IM );
+   gl_reset_input( ctx );
+
+   ctx->CompileFlag = GL_TRUE;
+   ctx->CompileCVAFlag = GL_FALSE;
+   ctx->ExecuteFlag = (mode == GL_COMPILE_AND_EXECUTE);
+   ctx->API = ctx->Save;  /* Switch the API function pointers */
+}
+
+
+
+/*
+ * End definition of current display list.
+ */
+void gl_EndList( GLcontext *ctx )
+{
+   if (MESA_VERBOSE&VERBOSE_API)
+      fprintf(stderr, "glEndList\n");
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH( ctx, "glEndList" );
+
+   /* Check that a list is under construction */
+   if (!ctx->CurrentListPtr) {
+      gl_error( ctx, GL_INVALID_OPERATION, "glEndList" );
+      return;
+   }
+
+   (void) alloc_instruction( ctx, OPCODE_END_OF_LIST, 0 );
+
+
+
+   /* Destroy old list, if any */
+   gl_destroy_list(ctx, ctx->CurrentListNum);
+   /* Install the list */
+   HashInsert(ctx->Shared->DisplayList, ctx->CurrentListNum, ctx->CurrentListPtr);
+
+   ctx->CurrentListNum = 0;
+   ctx->CurrentListPtr = NULL;
+   ctx->ExecuteFlag = GL_TRUE;
+   ctx->CompileFlag = GL_FALSE;
+   /* ctx->CompileCVAFlag = ...; */
+
+   /* KW: Put back the old input pointer.
+    */
+   free( ctx->input );
+   SET_IMMEDIATE( ctx, ctx->VB->IM );
+
+   ctx->API = ctx->Exec;   /* Switch the API function pointers */
+}
+
+
+
+void gl_CallList( GLcontext *ctx, GLuint list )
+{
+   /* VERY IMPORTANT:  Save the CompileFlag status, turn it off, */
+   /* execute the display list, and restore the CompileFlag. */
+   GLboolean save_compile_flag;
+
+   if (MESA_VERBOSE&VERBOSE_API)
+      fprintf(stderr, "glCallList %u\n", list);
+
+
+   save_compile_flag = ctx->CompileFlag;   
+   ctx->CompileFlag = GL_FALSE;
+   
+   FLUSH_VB( ctx, "call list" );
+
+/*    mesa_print_display_list( list ); */
+
+   execute_list( ctx, list );
+   ctx->CompileFlag = save_compile_flag;
+
+   /* also restore API function pointers to point to "save" versions */
+   if (save_compile_flag)
+           ctx->API = ctx->Save;
+
+
+/*    RESET_IMMEDIATE( ctx );       */
+}
+
+
+
+/*
+ * Execute glCallLists:  call multiple display lists.
+ */
+void gl_CallLists( GLcontext *ctx,
+                   GLsizei n, GLenum type, const GLvoid *lists )
+{
+   GLuint list;
+   GLint i;
+   GLboolean save_compile_flag;
+
+   /* Save the CompileFlag status, turn it off, execute display list,
+    * and restore the CompileFlag.
+    */
+   save_compile_flag = ctx->CompileFlag;
+   ctx->CompileFlag = GL_FALSE;
+
+   FLUSH_VB( ctx, "call lists" );
+
+   for (i=0;i<n;i++) {
+      list = translate_id( i, type, lists );
+      execute_list( ctx, ctx->List.ListBase + list );
+   }
+
+   ctx->CompileFlag = save_compile_flag;
+
+   /* also restore API function pointers to point to "save" versions */
+   if (save_compile_flag)
+           ctx->API = ctx->Save;
+
+
+/*    RESET_IMMEDIATE( ctx ); */
+}
+
+
+
+/*
+ * Set the offset added to list numbers in glCallLists.
+ */
+void gl_ListBase( GLcontext *ctx, GLuint base )
+{
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glListBase");
+   ctx->List.ListBase = base;
+}
+
+
+
+
+
+
+/*
+ * Assign all the pointers in 'table' to point to Mesa's display list
+ * building functions.
+ */
+void gl_init_dlist_pointers( struct gl_api_table *table )
+{
+   table->Accum = save_Accum;
+   table->AlphaFunc = save_AlphaFunc;
+   table->AreTexturesResident = gl_AreTexturesResident;
+   table->BindTexture = save_BindTexture;
+   table->Bitmap = save_Bitmap;
+   table->BlendColor = save_BlendColor;
+   table->BlendEquation = save_BlendEquation;
+   table->BlendFunc = save_BlendFunc;
+   table->BlendFuncSeparate = save_BlendFuncSeparate;
+   table->CallList = save_CallList;
+   table->CallLists = save_CallLists;
+   table->Clear = save_Clear;
+   table->ClearAccum = save_ClearAccum;
+   table->ClearColor = save_ClearColor;
+   table->ClearDepth = save_ClearDepth;
+   table->ClearIndex = save_ClearIndex;
+   table->ClearStencil = save_ClearStencil;
+   table->ClipPlane = save_ClipPlane;
+   table->ColorMask = save_ColorMask;
+   table->ColorMaterial = save_ColorMaterial;
+   table->ColorTable = save_ColorTable;
+   table->ColorSubTable = save_ColorSubTable;
+   table->CopyPixels = save_CopyPixels;
+   table->CopyTexImage1D = save_CopyTexImage1D;
+   table->CopyTexImage2D = save_CopyTexImage2D;
+   table->CopyTexSubImage1D = save_CopyTexSubImage1D;
+   table->CopyTexSubImage2D = save_CopyTexSubImage2D;
+   table->CopyTexSubImage3DEXT = save_CopyTexSubImage3DEXT;
+   table->CullFace = save_CullFace;
+   table->DeleteLists = gl_DeleteLists;   /* NOT SAVED */
+   table->DeleteTextures = gl_DeleteTextures;  /* NOT SAVED */
+   table->DepthFunc = save_DepthFunc;
+   table->DepthMask = save_DepthMask;
+   table->DepthRange = save_DepthRange;
+   table->Disable = save_Disable;
+   table->DisableClientState = gl_DisableClientState;  /* NOT SAVED */
+   table->DrawBuffer = save_DrawBuffer;
+   table->DrawPixels = save_DrawPixels;
+   table->Enable = save_Enable;
+   table->Error = gl_save_error;
+   table->EnableClientState = gl_EnableClientState;   /* NOT SAVED */
+   table->EndList = gl_EndList;   /* NOT SAVED */
+   table->EvalMesh1 = save_EvalMesh1;
+   table->EvalMesh2 = save_EvalMesh2;
+   table->FeedbackBuffer = gl_FeedbackBuffer;   /* NOT SAVED */
+   table->Finish = gl_Finish;   /* NOT SAVED */
+   table->Flush = gl_Flush;   /* NOT SAVED */
+   table->Fogfv = save_Fogfv;
+   table->FrontFace = save_FrontFace;
+   table->Frustum = save_Frustum;
+   table->GenLists = gl_GenLists;   /* NOT SAVED */
+   table->GenTextures = gl_GenTextures;   /* NOT SAVED */
+
+   /* NONE OF THESE COMMANDS ARE COMPILED INTO DISPLAY LISTS */
+   table->GetBooleanv = gl_GetBooleanv;
+   table->GetClipPlane = gl_GetClipPlane;
+   table->GetColorTable = gl_GetColorTable;
+   table->GetColorTableParameteriv = gl_GetColorTableParameteriv;
+   table->GetDoublev = gl_GetDoublev;
+   table->GetError = gl_GetError;
+   table->GetFloatv = gl_GetFloatv;
+   table->GetIntegerv = gl_GetIntegerv;
+   table->GetString = gl_GetString;
+   table->GetLightfv = gl_GetLightfv;
+   table->GetLightiv = gl_GetLightiv;
+   table->GetMapdv = gl_GetMapdv;
+   table->GetMapfv = gl_GetMapfv;
+   table->GetMapiv = gl_GetMapiv;
+   table->GetMaterialfv = gl_GetMaterialfv;
+   table->GetMaterialiv = gl_GetMaterialiv;
+   table->GetPixelMapfv = gl_GetPixelMapfv;
+   table->GetPixelMapuiv = gl_GetPixelMapuiv;
+   table->GetPixelMapusv = gl_GetPixelMapusv;
+   table->GetPointerv = gl_GetPointerv;
+   table->GetPolygonStipple = gl_GetPolygonStipple;
+   table->GetTexEnvfv = gl_GetTexEnvfv;
+   table->GetTexEnviv = gl_GetTexEnviv;
+   table->GetTexGendv = gl_GetTexGendv;
+   table->GetTexGenfv = gl_GetTexGenfv;
+   table->GetTexGeniv = gl_GetTexGeniv;
+   table->GetTexImage = gl_GetTexImage;
+   table->GetTexLevelParameterfv = gl_GetTexLevelParameterfv;
+   table->GetTexLevelParameteriv = gl_GetTexLevelParameteriv;
+   table->GetTexParameterfv = gl_GetTexParameterfv;
+   table->GetTexParameteriv = gl_GetTexParameteriv;
+
+   table->Hint = save_Hint;
+   table->IndexMask = save_IndexMask;
+   table->InitNames = save_InitNames;
+   table->IsEnabled = gl_IsEnabled;   /* NOT SAVED */
+   table->IsTexture = gl_IsTexture;   /* NOT SAVED */
+   table->IsList = gl_IsList;   /* NOT SAVED */
+   table->LightModelfv = save_LightModelfv;
+   table->Lightfv = save_Lightfv;
+   table->LineStipple = save_LineStipple;
+   table->LineWidth = save_LineWidth;
+   table->ListBase = save_ListBase;
+   table->LoadIdentity = save_LoadIdentity;
+   table->LoadMatrixf = save_LoadMatrixf;
+   table->LoadName = save_LoadName;
+   table->LogicOp = save_LogicOp;
+   table->Map1f = save_Map1f;
+   table->Map2f = save_Map2f;
+   table->MapGrid1f = save_MapGrid1f;
+   table->MapGrid2f = save_MapGrid2f;
+   table->MatrixMode = save_MatrixMode;
+   table->MultMatrixf = save_MultMatrixf;
+   table->NewList = save_NewList;
+   table->Ortho = save_Ortho;
+   table->PointParameterfvEXT = save_PointParameterfvEXT;
+   table->PassThrough = save_PassThrough;
+   table->PixelMapfv = save_PixelMapfv;
+   table->PixelStorei = gl_PixelStorei;   /* NOT SAVED */
+   table->PixelTransferf = save_PixelTransferf;
+   table->PixelZoom = save_PixelZoom;
+   table->PointSize = save_PointSize;
+   table->PolygonMode = save_PolygonMode;
+   table->PolygonOffset = save_PolygonOffset;
+   table->PolygonStipple = save_PolygonStipple;
+   table->PopAttrib = save_PopAttrib;
+   table->PopClientAttrib = gl_PopClientAttrib;  /* NOT SAVED */
+   table->PopMatrix = save_PopMatrix;
+   table->PopName = save_PopName;
+   table->PrioritizeTextures = save_PrioritizeTextures;
+   table->PushAttrib = save_PushAttrib;
+   table->PushClientAttrib = gl_PushClientAttrib;  /* NOT SAVED */
+   table->PushMatrix = save_PushMatrix;
+   table->PushName = save_PushName;
+   table->RasterPos4f = save_RasterPos4f;
+   table->ReadBuffer = save_ReadBuffer;
+   table->ReadPixels = gl_ReadPixels;   /* NOT SAVED */
+   table->Rectf = save_Rectf;
+   table->RenderMode = gl_RenderMode;   /* NOT SAVED */
+   table->Rotatef = save_Rotatef;
+   table->Scalef = save_Scalef;
+   table->Scissor = save_Scissor;
+   table->SelectBuffer = gl_SelectBuffer;   /* NOT SAVED */
+   table->ShadeModel = save_ShadeModel;
+   table->StencilFunc = save_StencilFunc;
+   table->StencilMask = save_StencilMask;
+   table->StencilOp = save_StencilOp;
+   table->TexEnvfv = save_TexEnvfv;
+   table->TexGenfv = save_TexGenfv;
+   table->TexImage1D = save_TexImage1D;
+   table->TexImage2D = save_TexImage2D;
+   table->TexImage3DEXT = save_TexImage3DEXT;
+   table->TexSubImage1D = save_TexSubImage1D;
+   table->TexSubImage2D = save_TexSubImage2D;
+   table->TexSubImage3DEXT = save_TexSubImage3DEXT;
+   table->TexParameterfv = save_TexParameterfv;
+   table->Translatef = save_Translatef;
+   table->Viewport = save_Viewport;
+
+   /* GL_MESA_window_pos extension */
+   table->WindowPos4fMESA = save_WindowPos4fMESA;
+
+   /* GL_MESA_resize_buffers extension */
+   table->ResizeBuffersMESA = gl_ResizeBuffersMESA;
+
+   /* GL_ARB_multitexture */
+   table->ActiveTexture = save_ActiveTexture;
+   table->ClientActiveTexture = save_ClientActiveTexture;
+}
+
+
+
+/***
+ *** Debugging code
+ ***/
+static const char *enum_string( GLenum k )
+{
+   return gl_lookup_enum_by_nr( k );
+}
+
+
+/*
+ * Print the commands in a display list.  For debugging only.
+ * TODO: many commands aren't handled yet.
+ */
+static void print_list( GLcontext *ctx, FILE *f, GLuint list )
+{
+   Node *n;
+   GLboolean done;
+   OpCode opcode;
+
+   if (!glIsList(list)) {
+      fprintf(f,"%u is not a display list ID\n",list);
+      return;
+   }
+
+   n = (Node *) HashLookup(ctx->Shared->DisplayList, list);
+
+   fprintf( f, "START-LIST %u, address %p\n", list, (void*)n );
+
+   done = n ? GL_FALSE : GL_TRUE;
+   while (!done) {
+      opcode = n[0].opcode;
+
+      switch (opcode) {
+         case OPCODE_ACCUM:
+            fprintf(f,"accum %s %g\n", enum_string(n[1].e), n[2].f );
+           break;
+        case OPCODE_BITMAP:
+            fprintf(f,"Bitmap %d %d %g %g %g %g %p\n", n[1].i, n[2].i,
+                      n[3].f, n[4].f, n[5].f, n[6].f, (void *) n[7].data );
+           break;
+         case OPCODE_CALL_LIST:
+            fprintf(f,"CallList %d\n", (int) n[1].ui );
+            break;
+         case OPCODE_CALL_LIST_OFFSET:
+            fprintf(f,"CallList %d + offset %u = %u\n", (int) n[1].ui,
+                    ctx->List.ListBase, ctx->List.ListBase + n[1].ui );
+            break;
+        case OPCODE_DISABLE:
+            fprintf(f,"Disable %s\n", enum_string(n[1].e));
+           break;
+        case OPCODE_ENABLE:
+            fprintf(f,"Enable %s\n", enum_string(n[1].e));
+           break;
+         case OPCODE_FRUSTUM:
+            fprintf(f,"Frustum %g %g %g %g %g %g\n",
+                    n[1].f, n[2].f, n[3].f, n[4].f, n[5].f, n[6].f );
+            break;
+        case OPCODE_LINE_STIPPLE:
+           fprintf(f,"LineStipple %d %x\n", n[1].i, (int) n[2].us );
+           break;
+        case OPCODE_LOAD_IDENTITY:
+            fprintf(f,"LoadIdentity\n");
+           break;
+        case OPCODE_LOAD_MATRIX:
+            fprintf(f,"LoadMatrix\n");
+            fprintf(f,"  %8f %8f %8f %8f\n", n[1].f, n[5].f,  n[9].f, n[13].f);
+            fprintf(f,"  %8f %8f %8f %8f\n", n[2].f, n[6].f, n[10].f, n[14].f);
+            fprintf(f,"  %8f %8f %8f %8f\n", n[3].f, n[7].f, n[11].f, n[15].f);
+            fprintf(f,"  %8f %8f %8f %8f\n", n[4].f, n[8].f, n[12].f, n[16].f);
+           break;
+        case OPCODE_MULT_MATRIX:
+            fprintf(f,"MultMatrix (or Rotate)\n");
+            fprintf(f,"  %8f %8f %8f %8f\n", n[1].f, n[5].f,  n[9].f, n[13].f);
+            fprintf(f,"  %8f %8f %8f %8f\n", n[2].f, n[6].f, n[10].f, n[14].f);
+            fprintf(f,"  %8f %8f %8f %8f\n", n[3].f, n[7].f, n[11].f, n[15].f);
+            fprintf(f,"  %8f %8f %8f %8f\n", n[4].f, n[8].f, n[12].f, n[16].f);
+           break;
+         case OPCODE_ORTHO:
+            fprintf(f,"Ortho %g %g %g %g %g %g\n",
+                    n[1].f, n[2].f, n[3].f, n[4].f, n[5].f, n[6].f );
+            break;
+        case OPCODE_POP_ATTRIB:
+            fprintf(f,"PopAttrib\n");
+           break;
+        case OPCODE_POP_MATRIX:
+            fprintf(f,"PopMatrix\n");
+           break;
+        case OPCODE_POP_NAME:
+            fprintf(f,"PopName\n");
+           break;
+        case OPCODE_PUSH_ATTRIB:
+            fprintf(f,"PushAttrib %x\n", n[1].bf );
+           break;
+        case OPCODE_PUSH_MATRIX:
+            fprintf(f,"PushMatrix\n");
+           break;
+        case OPCODE_PUSH_NAME:
+            fprintf(f,"PushName %d\n", (int) n[1].ui );
+           break;
+        case OPCODE_RASTER_POS:
+            fprintf(f,"RasterPos %g %g %g %g\n", n[1].f, n[2].f,n[3].f,n[4].f);
+           break;
+         case OPCODE_RECTF:
+            fprintf( f, "Rectf %g %g %g %g\n", n[1].f, n[2].f, n[3].f, n[4].f);
+            break;
+         case OPCODE_SCALE:
+            fprintf(f,"Scale %g %g %g\n", n[1].f, n[2].f, n[3].f );
+            break;
+         case OPCODE_TRANSLATE:
+            fprintf(f,"Translate %g %g %g\n", n[1].f, n[2].f, n[3].f );
+            break;
+
+        /*
+         * meta opcodes/commands
+         */
+         case OPCODE_ERROR:
+            fprintf(f,"Error: %s %s\n", enum_string(n[1].e), (const char *)n[2].data );
+            break;
+        case OPCODE_VERTEX_CASSETTE:
+            fprintf(f,"VERTEX-CASSETTE, id %u, %u elements\n", 
+                   ((struct immediate *) n[1].data)->id,
+                   ((struct immediate *) n[1].data)->Count - VB_START );
+           break;
+        case OPCODE_CONTINUE:
+            fprintf(f,"DISPLAY-LIST-CONTINUE\n");
+           n = (Node *) n[1].next;
+           break;
+        case OPCODE_END_OF_LIST:
+            fprintf(f,"END-LIST %u\n", list);
+           done = GL_TRUE;
+           break;
+         default:
+            if (opcode < 0 || opcode > OPCODE_END_OF_LIST) {
+               fprintf(f,"ERROR IN DISPLAY LIST: opcode = %d, address = %p\n",
+                       opcode, (void*) n);
+               return;
+            }
+            else {
+               fprintf(f,"command %d, %u operands\n",opcode,InstSize[opcode]);
+            }
+      }
+
+      /* increment n to point to next compiled command */
+      if (opcode!=OPCODE_CONTINUE) {
+        n += InstSize[opcode];
+      }
+   }
+}
+
+
+
+
+
+
+
+
+/*
+ * Clients may call this function to help debug display list problems.
+ * This function is _ONLY_FOR_DEBUGGING_PURPOSES_.  It may be removed,
+ * changed, or break in the future without notice.
+ */
+void mesa_print_display_list( GLuint list )
+{
+   GET_CONTEXT;
+   print_list( CC, stdout, list );
+}
diff --git a/src/mesa/main/dlist.h b/src/mesa/main/dlist.h
new file mode 100644 (file)
index 0000000..c5a5918
--- /dev/null
@@ -0,0 +1,79 @@
+/* $Id: dlist.h,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+#ifndef DLIST_H
+#define DLIST_H
+
+
+#include "types.h"
+
+struct display_list {
+   union node *nodes;  
+   GLuint OrFlag;
+   struct gl_current_attrib outputs;
+};
+
+struct display_list_compilation {
+   struct display_list *list;
+   union node *current_block;
+   GLuint current_pos;
+};
+
+
+extern void gl_init_lists( void );
+
+extern void gl_destroy_list( GLcontext *ctx, GLuint list );
+
+extern void gl_CallList( GLcontext *ctx, GLuint list );
+
+extern void gl_CallLists( GLcontext *ctx,
+                          GLsizei n, GLenum type, const GLvoid *lists );
+
+extern void gl_DeleteLists( GLcontext *ctx, GLuint list, GLsizei range );
+
+extern void gl_EndList( GLcontext *ctx );
+
+extern GLuint gl_GenLists( GLcontext *ctx, GLsizei range );
+
+extern GLboolean gl_IsList( GLcontext *ctx, GLuint list );
+
+extern void gl_ListBase( GLcontext *ctx, GLuint base );
+
+extern void gl_NewList( GLcontext *ctx, GLuint list, GLenum mode );
+
+extern void gl_init_dlist_pointers( struct gl_api_table *table );
+
+
+extern void gl_compile_cassette( GLcontext *ctx );
+
+extern void gl_save_error( GLcontext *ctx, GLenum error, const char *s );
+
+
+#endif
diff --git a/src/mesa/main/drawpix.c b/src/mesa/main/drawpix.c
new file mode 100644 (file)
index 0000000..a78f345
--- /dev/null
@@ -0,0 +1,946 @@
+/* $Id: drawpix.c,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include "context.h"
+#include "drawpix.h"
+#include "feedback.h"
+#include "image.h"
+#include "macros.h"
+#include "mmath.h"
+#include "pixel.h"
+#include "span.h"
+#include "stencil.h"
+#include "types.h"
+#include "zoom.h"
+#ifdef XFree86Server
+#include "GL/xf86glx.h"
+#endif
+#endif
+
+
+
+/* TODO:  apply texture mapping to fragments */
+
+
+/*
+ * Try to do a fast glDrawPixels.  Conditions include:
+ *   not using a display list
+ *   simple pixel unpacking
+ *   no raster ops
+ *   etc....
+ * Return:  GL_TRUE if success, GL_FALSE if slow path must be used instead
+ */
+GLboolean gl_direct_DrawPixels( GLcontext *ctx,
+                                const struct gl_pixelstore_attrib *unpack,
+                                GLsizei width, GLsizei height,
+                                GLenum format, GLenum type,
+                                const GLvoid *pixels )
+{
+   GLubyte rgb[MAX_WIDTH][3];
+   GLubyte rgba[MAX_WIDTH][4];
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH_WITH_RETVAL(ctx, "glDrawPixels", 
+                                                 GL_FALSE);
+
+
+   if (!ctx->Current.RasterPosValid) {
+      /* no-op */
+      return GL_TRUE;
+   }
+
+   if (ctx->NewState) {
+      gl_update_state(ctx);
+   }
+
+   /* see if device driver can do the drawpix */
+   if (ctx->Driver.DrawPixels) {
+      GLint x = (GLint) (ctx->Current.RasterPos[0] + 0.5F);
+      GLint y = (GLint) (ctx->Current.RasterPos[1] + 0.5F);
+      if ((*ctx->Driver.DrawPixels)(ctx, x, y, width, height, format, type,
+                                    unpack, pixels))
+         return GL_TRUE;
+   }
+
+   if ((ctx->RasterMask&(~(SCISSOR_BIT|WINCLIP_BIT)))==0
+       && ctx->Pixel.RedBias==0.0 && ctx->Pixel.RedScale==1.0
+       && ctx->Pixel.GreenBias==0.0 && ctx->Pixel.GreenScale==1.0
+       && ctx->Pixel.BlueBias==0.0 && ctx->Pixel.BlueScale==1.0
+       && ctx->Pixel.AlphaBias==0.0 && ctx->Pixel.AlphaScale==1.0
+       && ctx->Pixel.IndexShift==0 && ctx->Pixel.IndexOffset==0
+       && ctx->Pixel.MapColorFlag==0
+       && unpack->Alignment==1
+       && !unpack->SwapBytes
+       && !unpack->LsbFirst) {
+
+      GLint destX = (GLint) (ctx->Current.RasterPos[0] + 0.5F);
+      GLint destY = (GLint) (ctx->Current.RasterPos[1] + 0.5F);
+      GLint drawWidth = width;           /* actual width drawn */
+      GLint drawHeight = height;         /* actual height drawn */
+      GLint skipPixels = unpack->SkipPixels;
+      GLint skipRows = unpack->SkipRows;
+      GLint rowLength;
+      GLdepth zSpan[MAX_WIDTH];  /* only used when zooming */
+      GLint zoomY0;
+
+      if (unpack->RowLength > 0)
+         rowLength = unpack->RowLength;
+      else
+         rowLength = width;
+
+      /* If we're not using pixel zoom then do all clipping calculations
+       * now.  Otherwise, we'll let the gl_write_zoomed_*_span() functions
+       * handle the clipping.
+       */
+      if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) {
+         /* horizontal clipping */
+         if (destX < ctx->Buffer->Xmin) {
+            skipPixels += (ctx->Buffer->Xmin - destX);
+            drawWidth  -= (ctx->Buffer->Xmin - destX);
+            destX = ctx->Buffer->Xmin;
+         }
+         if (destX + drawWidth > ctx->Buffer->Xmax)
+            drawWidth -= (destX + drawWidth - ctx->Buffer->Xmax - 1);
+         if (drawWidth <= 0)
+            return GL_TRUE;
+
+         /* vertical clipping */
+         if (destY < ctx->Buffer->Ymin) {
+            skipRows   += (ctx->Buffer->Ymin - destY);
+            drawHeight -= (ctx->Buffer->Ymin - destY);
+            destY = ctx->Buffer->Ymin;
+         }
+         if (destY + drawHeight > ctx->Buffer->Ymax)
+            drawHeight -= (destY + drawHeight - ctx->Buffer->Ymax - 1);
+         if (drawHeight <= 0)
+            return GL_TRUE;
+      }
+      else {
+         /* setup array of fragment Z value to pass to zoom function */
+         GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * DEPTH_SCALE);
+         GLint i;
+         assert(drawWidth < MAX_WIDTH);
+         for (i=0; i<drawWidth; i++)
+            zSpan[i] = z;
+
+         /* save Y value of first row */
+         zoomY0 = (GLint) (ctx->Current.RasterPos[1] + 0.5F);
+      }
+
+
+      /*
+       * Ready to draw!
+       * The window region at (destX, destY) of size (drawWidth, drawHeight)
+       * will be written to.
+       * We'll take pixel data from buffer pointed to by "pixels" but we'll
+       * skip "skipRows" rows and skip "skipPixels" pixels/row.
+       */
+
+      if (format==GL_RGBA && type==GL_UNSIGNED_BYTE) {
+         if (ctx->Visual->RGBAflag) {
+            GLubyte *src = (GLubyte *) pixels
+               + (skipRows * rowLength + skipPixels) * 4;
+            if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) {
+               /* no zooming */
+               GLint row;
+               for (row=0; row<drawHeight; row++) {
+                  (*ctx->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY,
+                                               (void *) src, NULL);
+                  src += rowLength * 4;
+                  destY++;
+               }
+            }
+            else {
+               /* with zooming */
+               GLint row;
+               for (row=0; row<drawHeight; row++) {
+                  gl_write_zoomed_rgba_span(ctx, drawWidth, destX, destY,
+                                            zSpan, (void *) src, zoomY0);
+                  src += rowLength * 4;
+                  destY++;
+               }
+            }
+         }
+         return GL_TRUE;
+      }
+      else if (format==GL_RGB && type==GL_UNSIGNED_BYTE) {
+         if (ctx->Visual->RGBAflag) {
+            GLubyte *src = (GLubyte *) pixels
+               + (skipRows * rowLength + skipPixels) * 3;
+            if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) {
+               GLint row;
+               for (row=0; row<drawHeight; row++) {
+                  (*ctx->Driver.WriteRGBSpan)(ctx, drawWidth, destX, destY,
+                                              (void *) src, NULL);
+                  src += rowLength * 3;
+                  destY++;
+               }
+            }
+            else {
+               /* with zooming */
+               GLint row;
+               for (row=0; row<drawHeight; row++) {
+                  gl_write_zoomed_rgb_span(ctx, drawWidth, destX, destY,
+                                           zSpan, (void *) src, zoomY0);
+                  src += rowLength * 3;
+                  destY++;
+               }
+            }
+         }
+         return GL_TRUE;
+      }
+      else if (format==GL_LUMINANCE && type==GL_UNSIGNED_BYTE) {
+         if (ctx->Visual->RGBAflag) {
+            GLubyte *src = (GLubyte *) pixels
+               + (skipRows * rowLength + skipPixels);
+            if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) {
+               /* no zooming */
+               GLint row;
+               assert(drawWidth < MAX_WIDTH);
+               for (row=0; row<drawHeight; row++) {
+                  GLint i;
+                 for (i=0;i<drawWidth;i++) {
+                     rgb[i][0] = src[i];
+                     rgb[i][1] = src[i];
+                     rgb[i][2] = src[i];
+                 }
+                  (*ctx->Driver.WriteRGBSpan)(ctx, drawWidth, destX, destY,
+                                              (void *) rgb, NULL);
+                  src += rowLength;
+                  destY++;
+               }
+            }
+            else {
+               /* with zooming */
+               GLint row;
+               assert(drawWidth < MAX_WIDTH);
+               for (row=0; row<drawHeight; row++) {
+                  GLint i;
+                 for (i=0;i<drawWidth;i++) {
+                     rgb[i][0] = src[i];
+                     rgb[i][1] = src[i];
+                     rgb[i][2] = src[i];
+                 }
+                  gl_write_zoomed_rgb_span(ctx, drawWidth, destX, destY,
+                                           zSpan, (void *) rgb, zoomY0);
+                  src += rowLength;
+                  destY++;
+               }
+            }
+         }
+         return GL_TRUE;
+      }
+      else if (format==GL_LUMINANCE_ALPHA && type==GL_UNSIGNED_BYTE) {
+         if (ctx->Visual->RGBAflag) {
+            GLubyte *src = (GLubyte *) pixels
+               + (skipRows * rowLength + skipPixels)*2;
+            if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) {
+               /* no zooming */
+               GLint row;
+               assert(drawWidth < MAX_WIDTH);
+               for (row=0; row<drawHeight; row++) {
+                  GLint i;
+                  GLubyte *ptr = src;
+                 for (i=0;i<drawWidth;i++) {
+                     rgba[i][0] = *ptr;
+                     rgba[i][1] = *ptr;
+                     rgba[i][2] = *ptr++;
+                     rgba[i][3] = *ptr++;
+                 }
+                  (*ctx->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY,
+                                               (void *) rgba, NULL);
+                  src += rowLength*2;
+                  destY++;
+               }
+            }
+            else {
+               /* with zooming */
+               GLint row;
+               assert(drawWidth < MAX_WIDTH);
+               for (row=0; row<drawHeight; row++) {
+                  GLubyte *ptr = src;
+                  GLint i;
+                 for (i=0;i<drawWidth;i++) {
+                     rgba[i][0] = *ptr;
+                     rgba[i][1] = *ptr;
+                     rgba[i][2] = *ptr++;
+                     rgba[i][3] = *ptr++;
+                 }
+                  gl_write_zoomed_rgba_span(ctx, drawWidth, destX, destY,
+                                            zSpan, (void *) rgba, zoomY0);
+                  src += rowLength*2;
+                  destY++;
+               }
+            }
+         }
+         return GL_TRUE;
+      }
+      else if (format==GL_COLOR_INDEX && type==GL_UNSIGNED_BYTE) {
+         GLubyte *src = (GLubyte *) pixels + skipRows * rowLength + skipPixels;
+         if (ctx->Visual->RGBAflag) {
+            /* convert CI data to RGBA */
+            if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) {
+               /* no zooming */
+               GLint row;
+               for (row=0; row<drawHeight; row++) {
+                  assert(drawWidth < MAX_WIDTH);
+                  gl_map_ci8_to_rgba(ctx, drawWidth, src, rgba);
+                  (*ctx->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY,
+                                               (const GLubyte (*)[4])rgba, 
+                                              NULL);
+                  src += rowLength;
+                  destY++;
+               }
+               return GL_TRUE;
+            }
+            else {
+               /* with zooming */
+               GLint row;
+               for (row=0; row<drawHeight; row++) {
+                  assert(drawWidth < MAX_WIDTH);
+                  gl_map_ci8_to_rgba(ctx, drawWidth, src, rgba);
+                  gl_write_zoomed_rgba_span(ctx, drawWidth, destX, destY,
+                                            zSpan, (void *) rgba, zoomY0);
+                  src += rowLength;
+                  destY++;
+               }
+               return GL_TRUE;
+            }
+         }
+         else {
+            /* write CI data to CI frame buffer */
+            GLint row;
+            if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) {
+               /* no zooming */
+               for (row=0; row<drawHeight; row++) {
+                  (*ctx->Driver.WriteCI8Span)(ctx, drawWidth, destX, destY,
+                                              src, NULL);
+                  src += rowLength;
+                  destY++;
+               }
+               return GL_TRUE;
+            }
+            else {
+               /* with zooming */
+               return GL_FALSE;
+            }
+         }
+      }
+      else {
+         /* can't handle this pixel format and/or data type here */
+         return GL_FALSE;
+      }
+   }
+   else {
+      /* can't do direct render, have to use slow path */
+      return GL_FALSE;
+   }
+}
+
+
+
+/*
+ * Do glDrawPixels of index pixels.
+ */
+static void draw_index_pixels( GLcontext *ctx, GLint x, GLint y,
+                               const struct gl_image *image )
+{
+   GLint width, height, widthInBytes;
+   const GLint desty = y;
+   GLint i, j;
+   GLdepth zspan[MAX_WIDTH];
+   const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
+
+   assert(image);
+   assert(image->Format == GL_COLOR_INDEX);
+
+   width = image->Width;
+   height = image->Height;
+   if (image->Type == GL_BITMAP)
+      widthInBytes = (width + 7) / 8;
+   else
+      widthInBytes = width;
+
+   /* Fragment depth values */
+   if (ctx->Depth.Test) {
+      GLdepth zval = (GLdepth) (ctx->Current.RasterPos[2] * DEPTH_SCALE);
+      for (i=0;i<width;i++) {
+        zspan[i] = zval;
+      }
+   }
+
+   /* process the image row by row */
+   for (i=0;i<height;i++,y++) {
+      GLuint ispan[MAX_WIDTH];
+
+      /* convert to uints */
+      switch (image->Type) {
+        case GL_UNSIGNED_BYTE:
+           {
+              GLubyte *src = (GLubyte *) image->Data + i * width;
+              for (j=0;j<width;j++) {
+                 ispan[j] = (GLuint) *src++;
+              }
+           }
+           break;
+        case GL_FLOAT:
+           {
+              GLfloat *src = (GLfloat *) image->Data + i * width;
+              for (j=0;j<width;j++) {
+                 ispan[j] = (GLuint) (GLint) *src++;
+              }
+           }
+           break;
+         case GL_BITMAP:
+            {
+              GLubyte *src = (GLubyte *) image->Data + i * widthInBytes;
+              for (j=0;j<width;j++) {
+                 ispan[j] = ( src[j >> 3] >> (7 - (j & 0x7)) ) & 1;
+              }
+            }
+            break;
+        default:
+           gl_problem( ctx, "draw_index_pixels type" );
+            return;
+      }
+
+      /* apply shift and offset */
+      if (ctx->Pixel.IndexOffset || ctx->Pixel.IndexShift) {
+         gl_shift_and_offset_ci( ctx, width, ispan );
+      }
+
+      if (ctx->Visual->RGBAflag) {
+        /* Convert index to RGBA and write to frame buffer */
+        GLubyte rgba[MAX_WIDTH][4];
+         gl_map_ci_to_rgba( ctx, width, ispan, rgba );
+         if (zoom) {
+            gl_write_zoomed_rgba_span( ctx, width, x, y, zspan, 
+                                      (const GLubyte (*)[4])rgba, desty );
+         }
+         else {
+            gl_write_rgba_span( ctx, width, x, y, zspan, rgba, GL_BITMAP );
+         }
+      }
+      else {
+        /* optionally apply index map then write to frame buffer */
+        if (ctx->Pixel.MapColorFlag) {
+            gl_map_ci(ctx, width, ispan);
+        }
+         if (zoom) {
+            gl_write_zoomed_index_span( ctx, width, x, y, zspan, ispan, desty );
+         }
+         else {
+            gl_write_index_span( ctx, width, x, y, zspan, ispan, GL_BITMAP );
+         }
+      }
+   }
+
+}
+
+
+
+/*
+ * Do glDrawPixels of stencil image.  The image datatype may either
+ * be GLubyte or GLbitmap.
+ */
+static void draw_stencil_pixels( GLcontext *ctx, GLint x, GLint y,
+                                 const struct gl_image *image )
+{
+   GLint widthInBytes, width, height;
+   const GLint desty = y;
+   GLint i;
+   const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
+
+   assert(image);
+   assert(image->Format == GL_STENCIL_INDEX);
+   assert(image->Type == GL_UNSIGNED_BYTE || image->Type == GL_BITMAP);
+
+   if (image->Type == GL_UNSIGNED_BYTE)
+      widthInBytes = image->Width;
+   else
+      widthInBytes = (image->Width + 7) / 8;
+   width = image->Width;
+   height = image->Height;
+
+   /* process the image row by row */
+   for (i=0;i<height;i++,y++) {
+      GLstencil *src = (GLstencil*)image->Data + i * widthInBytes;
+      GLstencil *stencilValues;
+      GLstencil stencilCopy[MAX_WIDTH];
+
+      if (image->Type == GL_BITMAP) {
+         /* convert bitmap data to GLubyte (0 or 1) data */
+         GLint j;
+         for (j = 0; j < width; j++) {
+            stencilCopy[j] = ( src[j >> 3] >> (7 - (j & 0x7)) ) & 1;
+         }
+         src = stencilCopy;
+      }
+
+      if (ctx->Pixel.IndexOffset || ctx->Pixel.IndexShift
+          || ctx->Pixel.MapStencilFlag) {
+
+         /* make copy of stencil values */
+         if (src != stencilCopy)
+            MEMCPY( stencilCopy, src, width * sizeof(GLstencil));
+
+         /* apply shift and offset */
+         if (ctx->Pixel.IndexOffset || ctx->Pixel.IndexShift) {
+            gl_shift_and_offset_stencil( ctx, width, stencilCopy );
+         }
+
+         /* mapping */
+         if (ctx->Pixel.MapStencilFlag) {
+            gl_map_stencil( ctx, width, stencilCopy );
+         }
+
+         stencilValues = stencilCopy;
+      }
+      else {
+         /* use stencil values in-place */
+         stencilValues = src;
+      }
+
+      /* write stencil values to stencil buffer */
+      if (zoom) {
+         gl_write_zoomed_stencil_span( ctx, (GLuint) width, x, y,
+                                       stencilValues, desty );
+      }
+      else {
+         gl_write_stencil_span( ctx, (GLuint) width, x, y, stencilValues );
+      }
+   }
+}
+
+
+
+/*
+ * Do a glDrawPixels of depth values.
+ */
+static void draw_depth_pixels( GLcontext *ctx, GLint x, GLint y,
+                               const struct gl_image *image )
+{
+   GLint width, height;
+   const GLint desty = y;
+   GLubyte rgba[MAX_WIDTH][4];
+   GLuint ispan[MAX_WIDTH];
+   const GLboolean bias_or_scale = ctx->Pixel.DepthBias!=0.0 || ctx->Pixel.DepthScale!=1.0;
+   const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
+
+   assert(image);
+   assert(image->Format == GL_DEPTH_COMPONENT);
+
+   width = image->Width;
+   height = image->Height;
+
+   /* Color or index */
+   if (ctx->Visual->RGBAflag) {
+      GLint r = (GLint) (ctx->Current.RasterColor[0] * 255.0F);
+      GLint g = (GLint) (ctx->Current.RasterColor[1] * 255.0F);
+      GLint b = (GLint) (ctx->Current.RasterColor[2] * 255.0F);
+      GLint a = (GLint) (ctx->Current.RasterColor[3] * 255.0F);
+      GLint i;
+      for (i=0; i<width; i++) {
+         rgba[i][RCOMP] = r;
+         rgba[i][GCOMP] = g;
+         rgba[i][BCOMP] = b;
+         rgba[i][ACOMP] = a;
+      }
+   }
+   else {
+      GLint i;
+      for (i=0;i<width;i++) {
+        ispan[i] = ctx->Current.RasterIndex;
+      }
+   }
+
+   if (image->Type==GL_UNSIGNED_SHORT && sizeof(GLdepth)==sizeof(GLushort)
+       && !bias_or_scale && !zoom && ctx->Visual->RGBAflag) {
+      /* Special case: directly write 16-bit depth values */
+      GLint j;
+      for (j=0;j<height;j++,y++) {
+         GLdepth *zptr = (GLdepth *) image->Data + j * width;
+         gl_write_rgba_span( ctx, width, x, y, zptr, rgba, GL_BITMAP );
+      }
+   }
+   else if (image->Type==GL_UNSIGNED_INT && sizeof(GLdepth)==sizeof(GLuint)
+       && !bias_or_scale && !zoom && ctx->Visual->RGBAflag) {
+      /* Special case: directly write 32-bit depth values */
+      GLint i, j;
+      /* Compute shift value to scale 32-bit uints down to depth values. */
+      GLuint shift = 0;
+      GLuint max = MAX_DEPTH;
+      while ((max&0x80000000)==0) {
+         max = max << 1;
+         shift++;
+      }
+      for (j=0;j<height;j++,y++) {
+         GLdepth zspan[MAX_WIDTH];
+         GLuint *zptr = (GLuint *) image->Data + j * width;
+         for (i=0;i<width;i++) {
+            zspan[i] = zptr[i] >> shift;
+         }
+         gl_write_rgba_span( ctx, width, x, y, zspan, rgba, GL_BITMAP );
+      }
+   }
+   else {
+      /* General case (slower) */
+      GLint i, j;
+
+      /* process image row by row */
+      for (i=0;i<height;i++,y++) {
+         GLfloat depth[MAX_WIDTH];
+         GLdepth zspan[MAX_WIDTH];
+
+         switch (image->Type) {
+            case GL_UNSIGNED_SHORT:
+               {
+                  GLushort *src = (GLushort *) image->Data + i * width;
+                  for (j=0;j<width;j++) {
+                     depth[j] = USHORT_TO_FLOAT( *src++ );
+                  }
+               }
+               break;
+            case GL_UNSIGNED_INT:
+               {
+                  GLuint *src = (GLuint *) image->Data + i * width;
+                  for (j=0;j<width;j++) {
+                     depth[j] = UINT_TO_FLOAT( *src++ );
+                  }
+               }
+               break;
+            case GL_FLOAT:
+               {
+                  GLfloat *src = (GLfloat *) image->Data + i * width;
+                  for (j=0;j<width;j++) {
+                     depth[j] = *src++;
+                  }
+               }
+               break;
+            default:
+               gl_problem(ctx, "Bad type in draw_depth_pixels");
+               return;
+         }
+
+         /* apply depth scale and bias */
+         if (ctx->Pixel.DepthScale!=1.0 || ctx->Pixel.DepthBias!=0.0) {
+            for (j=0;j<width;j++) {
+               depth[j] = depth[j] * ctx->Pixel.DepthScale + ctx->Pixel.DepthBias;
+            }
+         }
+
+         /* clamp depth values to [0,1] and convert from floats to integers */
+         for (j=0;j<width;j++) {
+            zspan[j] = (GLdepth) (CLAMP( depth[j], 0.0F, 1.0F ) * DEPTH_SCALE);
+         }
+
+         if (ctx->Visual->RGBAflag) {
+            if (zoom) {
+               gl_write_zoomed_rgba_span( ctx, width, x, y, zspan,
+                                          (const GLubyte (*)[4])rgba, desty );
+            }
+            else {
+               gl_write_rgba_span( ctx, width, x, y, zspan, rgba, GL_BITMAP );
+            }
+         }
+         else {
+            if (zoom) {
+               gl_write_zoomed_index_span( ctx, width, x, y, zspan,
+                                           ispan, GL_BITMAP );
+            }
+            else {
+               gl_write_index_span( ctx, width, x, y, zspan, ispan, GL_BITMAP );
+            }
+         }
+
+      }
+   }
+}
+
+
+
+/* Simple unpacking parameters: */
+static struct gl_pixelstore_attrib NoUnpack = {
+   1,            /* Alignment */
+   0,            /* RowLength */
+   0,            /* SkipPixels */
+   0,            /* SkipRows */
+   0,            /* ImageHeight */
+   0,            /* SkipImages */
+   GL_FALSE,     /* SwapBytes */
+   GL_FALSE      /* LsbFirst */
+};
+
+
+/*
+ * Do glDrawPixels of RGBA pixels.
+ */
+static void draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
+                              const struct gl_image *image )
+{
+   GLint width, height;
+   GLint i, j;
+   const GLint desty = y;
+   GLdepth zspan[MAX_WIDTH];
+   GLboolean quickDraw;
+   const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
+
+   assert(image);
+
+   /* Try an optimized glDrawPixels first */
+   if (gl_direct_DrawPixels(ctx, &NoUnpack, image->Width, image->Height,
+                            image->Format, image->Type, image->Data ))
+      return;
+
+   width = image->Width;
+   height = image->Height;
+
+   /* Fragment depth values */
+   if (ctx->Depth.Test) {
+      /* fill in array of z values */
+      GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * DEPTH_SCALE);
+      for (i=0;i<width;i++) {
+        zspan[i] = z;
+      }
+   }
+
+   if (ctx->RasterMask==0 && !zoom && x>=0 && y>=0
+       && x+width<=ctx->Buffer->Width && y+height<=ctx->Buffer->Height) {
+      quickDraw = GL_TRUE;
+   }
+   else {
+      quickDraw = GL_FALSE;
+   }
+
+   {
+      /* General solution */
+      GLboolean r_flag, g_flag, b_flag, a_flag, l_flag;
+      GLuint components;
+      GLubyte rgba[MAX_WIDTH][4];
+      GLfloat  rf[MAX_WIDTH];
+      GLfloat  gf[MAX_WIDTH];
+      GLfloat  bf[MAX_WIDTH];
+      DEFARRAY(GLfloat,af,MAX_WIDTH);
+      CHECKARRAY(af,return);
+
+      r_flag = g_flag = b_flag = a_flag = l_flag = GL_FALSE;
+      switch (image->Format) {
+        case GL_RED:
+           r_flag = GL_TRUE;
+           components = 1;
+           break;
+        case GL_GREEN:
+           g_flag = GL_TRUE;
+           components = 1;
+           break;
+        case GL_BLUE:
+           b_flag = GL_TRUE;
+           components = 1;
+           break;
+        case GL_ALPHA:
+           a_flag = GL_TRUE;
+           components = 1;
+           break;
+        case GL_RGB:
+           r_flag = g_flag = b_flag = GL_TRUE;
+           components = 3;
+           break;
+        case GL_LUMINANCE:
+           l_flag = GL_TRUE;
+           components = 1;
+           break;
+        case GL_LUMINANCE_ALPHA:
+           l_flag = a_flag = GL_TRUE;
+           components = 2;
+           break;
+        case GL_RGBA:
+           r_flag = g_flag = b_flag = a_flag = GL_TRUE;
+           components = 4;
+           break;
+         default:
+            gl_problem(ctx, "Bad type in draw_rgba_pixels");
+            goto cleanup;
+      }
+
+      /* process the image row by row */
+      for (i=0;i<height;i++,y++) {
+        /* convert to floats */
+        switch (image->Type) {
+           case GL_UNSIGNED_BYTE:
+              {
+                 GLubyte *src = (GLubyte *) image->Data + i * width * components;
+                 for (j=0;j<width;j++) {
+                    if (l_flag) {
+                       rf[j] = gf[j] = bf[j] = UBYTE_TO_FLOAT(*src++);
+                    }
+                    else {
+                       rf[j] = r_flag ? UBYTE_TO_FLOAT(*src++) : 0.0;
+                       gf[j] = g_flag ? UBYTE_TO_FLOAT(*src++) : 0.0;
+                       bf[j] = b_flag ? UBYTE_TO_FLOAT(*src++) : 0.0;
+                    }
+                    af[j] = a_flag ? UBYTE_TO_FLOAT(*src++) : 1.0;
+                 }
+              }
+              break;
+           case GL_FLOAT:
+              {
+                 GLfloat *src = (GLfloat *) image->Data + i * width * components;
+                 for (j=0;j<width;j++) {
+                    if (l_flag) {
+                       rf[j] = gf[j] = bf[j] = *src++;
+                    }
+                    else {
+                       rf[j] = r_flag ? *src++ : 0.0;
+                       gf[j] = g_flag ? *src++ : 0.0;
+                       bf[j] = b_flag ? *src++ : 0.0;
+                    }
+                    af[j] = a_flag ? *src++ : 1.0;
+                 }
+              }
+              break;
+           default:
+              gl_problem( ctx, "draw_rgba_pixels type" );
+               goto cleanup;
+        }
+
+        /* apply scale and bias */
+        if (ctx->Pixel.ScaleOrBiasRGBA) {
+            gl_scale_and_bias_color(ctx, width, rf, gf, bf, af);
+        }
+
+        /* apply pixel mappings */
+        if (ctx->Pixel.MapColorFlag) {
+            gl_map_color(ctx, width, rf, gf, bf, af);
+        }
+
+        /* convert to integers */
+        for (j=0;j<width;j++) {
+           rgba[j][RCOMP] = (GLint) (rf[j] * 255.0F);
+           rgba[j][GCOMP] = (GLint) (gf[j] * 255.0F);
+           rgba[j][BCOMP] = (GLint) (bf[j] * 255.0F);
+           rgba[j][ACOMP] = (GLint) (af[j] * 255.0F);
+        }
+
+        /* write to frame buffer */
+         if (quickDraw) {
+            (*ctx->Driver.WriteRGBASpan)( ctx, width, x, y, 
+                                         (const GLubyte (*)[4])rgba, NULL);
+         }
+         else if (zoom) {
+            gl_write_zoomed_rgba_span( ctx, width, x, y, zspan, 
+                                      (const GLubyte (*)[4])rgba, desty );
+         }
+         else {
+            gl_write_rgba_span( ctx, (GLuint) width, x, y, zspan, rgba, GL_BITMAP);
+         }
+      }
+cleanup:
+      UNDEFARRAY(af);
+   }
+}
+
+
+
+/*
+ * Execute glDrawPixels
+ */
+void gl_DrawPixels( GLcontext* ctx, struct gl_image *image )
+{
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDrawPixels");
+
+
+   if (gl_image_error_test( ctx, image, "glDrawPixels" ))
+      return;
+
+   if (ctx->RenderMode==GL_RENDER) {
+      GLint x, y;
+      if (!ctx->Current.RasterPosValid) {
+        return;
+      }
+
+      x = (GLint) (ctx->Current.RasterPos[0] + 0.5F);
+      y = (GLint) (ctx->Current.RasterPos[1] + 0.5F);
+
+      switch (image->Format) {
+        case GL_COLOR_INDEX:
+            draw_index_pixels( ctx, x, y, image );
+           break;
+        case GL_STENCIL_INDEX:
+           draw_stencil_pixels( ctx, x, y, image );
+           break;
+        case GL_DEPTH_COMPONENT:
+           draw_depth_pixels( ctx, x, y, image );
+           break;
+        case GL_RED:
+        case GL_GREEN:
+        case GL_BLUE:
+        case GL_ALPHA:
+        case GL_RGB:
+        case GL_LUMINANCE:
+        case GL_LUMINANCE_ALPHA:
+        case GL_RGBA:
+            draw_rgba_pixels( ctx, x, y, image );
+           break;
+        default:
+           gl_error( ctx, GL_INVALID_ENUM, "glDrawPixels" );
+            return;
+      }
+   }
+   else if (ctx->RenderMode==GL_FEEDBACK) {
+      if (ctx->Current.RasterPosValid) {
+         GLfloat color[4];
+        GLfloat texcoord[4], invq;
+        UBYTE_RGBA_TO_FLOAT_RGBA(color, ctx->Current.ByteColor);
+         invq = 1.0F / ctx->Current.Texcoord[0][3];
+         texcoord[0] = ctx->Current.Texcoord[0][0] * invq;
+         texcoord[1] = ctx->Current.Texcoord[0][1] * invq;
+         texcoord[2] = ctx->Current.Texcoord[0][2] * invq;
+         texcoord[3] = ctx->Current.Texcoord[0][3];
+         FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_DRAW_PIXEL_TOKEN );
+         gl_feedback_vertex( ctx,
+                             ctx->Current.RasterPos[0],
+                             ctx->Current.RasterPos[1],
+                             ctx->Current.RasterPos[2],
+                             ctx->Current.RasterPos[3],
+                             color, ctx->Current.Index, texcoord );
+      }
+   }
+   else if (ctx->RenderMode==GL_SELECT) {
+      if (ctx->Current.RasterPosValid) {
+         gl_update_hitflag( ctx, ctx->Current.RasterPos[2] );
+      }
+   }
+}
+
diff --git a/src/mesa/main/drawpix.h b/src/mesa/main/drawpix.h
new file mode 100644 (file)
index 0000000..cb517ce
--- /dev/null
@@ -0,0 +1,54 @@
+/* $Id: drawpix.h,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+#ifndef DRAWPIXELS_H
+#define DRAWPIXELS_H
+
+
+#include "types.h"
+
+
+extern GLboolean
+gl_direct_DrawPixels( GLcontext *ctx, 
+                      const struct gl_pixelstore_attrib *unpack,
+                      GLsizei width, GLsizei height,
+                      GLenum format, GLenum type, const GLvoid *pixels );
+
+
+#if 000
+extern void gl_DrawPixels( GLcontext *ctx, GLsizei width, GLsizei height,
+                           GLenum format, GLenum type, const GLvoid *pixels );
+#endif
+
+
+extern void gl_DrawPixels( GLcontext *ctx, struct gl_image *image );
+
+
+#endif
diff --git a/src/mesa/main/enable.c b/src/mesa/main/enable.c
new file mode 100644 (file)
index 0000000..7f661fb
--- /dev/null
@@ -0,0 +1,699 @@
+/* $Id: enable.c,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <string.h>
+#include <stdio.h>
+#include "context.h"
+#include "enable.h"
+#include "light.h"
+#include "macros.h"
+#include "matrix.h"
+#include "mmath.h"
+#include "simple_list.h"
+#include "types.h"
+#include "vbfill.h"
+#include "xform.h"
+#include "enums.h"
+#ifdef XFree86Server
+#include "GL/xf86glx.h"
+#endif
+#endif
+
+
+
+/*
+ * Perform glEnable and glDisable calls.
+ */
+void gl_set_enable( GLcontext *ctx, GLenum cap, GLboolean state )
+{
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH( ctx, "gl_enable/disable" );
+
+   if (MESA_VERBOSE & VERBOSE_API) 
+      fprintf(stderr, "%s %s (%x)\n", 
+             state ? "glEnable" : "glDisable",
+             gl_lookup_enum_by_nr(cap),
+             ctx->NewState);
+
+   switch (cap) {
+      case GL_ALPHA_TEST:
+         if (ctx->Color.AlphaEnabled!=state) {
+            ctx->Color.AlphaEnabled = state;
+            ctx->NewState |= NEW_RASTER_OPS;
+         }
+        break;
+      case GL_AUTO_NORMAL:
+        ctx->Eval.AutoNormal = state;
+        break;
+      case GL_BLEND:
+         if (ctx->Color.BlendEnabled!=state) {
+            ctx->Color.BlendEnabled = state;
+            /* The following needed to accomodate 1.0 RGB logic op blending */
+            if (ctx->Color.BlendEquation==GL_LOGIC_OP && state) {
+               ctx->Color.ColorLogicOpEnabled = GL_TRUE;
+            }
+            else {
+               ctx->Color.ColorLogicOpEnabled = GL_FALSE;
+            }
+            ctx->NewState |= NEW_RASTER_OPS;
+         }
+        break;
+      case GL_CLIP_PLANE0:
+      case GL_CLIP_PLANE1:
+      case GL_CLIP_PLANE2:
+      case GL_CLIP_PLANE3:
+      case GL_CLIP_PLANE4:
+      case GL_CLIP_PLANE5:
+        if (cap >= GL_CLIP_PLANE0 && 
+            cap <= GL_CLIP_PLANE5 &&
+            ctx->Transform.ClipEnabled[cap-GL_CLIP_PLANE0] != state) 
+        {
+           GLuint p = cap-GL_CLIP_PLANE0;
+
+           ctx->Transform.ClipEnabled[p] = state;
+           ctx->NewState |= NEW_USER_CLIP;
+
+           if (state) {
+              ctx->Enabled |= ENABLE_USERCLIP;
+              ctx->Transform.AnyClip++;
+              
+              if (ctx->ProjectionMatrix.flags & MAT_DIRTY_ALL_OVER) {
+                 gl_matrix_analyze( &ctx->ProjectionMatrix );
+              }
+              
+              gl_transform_vector( ctx->Transform.ClipUserPlane[p],
+                                   ctx->Transform.EyeUserPlane[p],
+                                   ctx->ProjectionMatrix.inv );
+           } else {
+              if (--ctx->Transform.AnyClip == 0)
+                 ctx->Enabled &= ~ENABLE_USERCLIP;            
+           }       
+        }
+        break;
+      case GL_COLOR_MATERIAL:
+         if (ctx->Light.ColorMaterialEnabled!=state) {
+            ctx->Light.ColorMaterialEnabled = state;
+           ctx->NewState |= NEW_LIGHTING;
+         }
+        break;
+      case GL_CULL_FACE:
+         if (ctx->Polygon.CullFlag!=state) {
+            ctx->Polygon.CullFlag = state;
+           ctx->TriangleCaps ^= DD_TRI_CULL;
+            ctx->NewState |= NEW_POLYGON;
+         }
+        break;
+      case GL_DEPTH_TEST:
+         if (state && ctx->Visual->DepthBits==0) {
+            gl_warning(ctx,"glEnable(GL_DEPTH_TEST) but no depth buffer");
+            return;
+         }
+        if (ctx->Depth.Test!=state) {
+            ctx->Depth.Test = state;
+            ctx->NewState |= NEW_RASTER_OPS;
+         }
+         break;
+      case GL_DITHER:
+         if (ctx->NoDither) {
+            /* MESA_NO_DITHER env var */
+            state = GL_FALSE;
+         }
+         if (ctx->Color.DitherFlag!=state) {
+            ctx->Color.DitherFlag = state;
+            ctx->NewState |= NEW_RASTER_OPS;
+         }
+        break;
+      case GL_FOG:
+        if (ctx->Fog.Enabled!=state) {
+            ctx->Fog.Enabled = state;
+           ctx->Enabled ^= ENABLE_FOG;
+            ctx->NewState |= NEW_FOG;
+         }
+        break;
+      case GL_LIGHT0:
+      case GL_LIGHT1:
+      case GL_LIGHT2:
+      case GL_LIGHT3:
+      case GL_LIGHT4:
+      case GL_LIGHT5:
+      case GL_LIGHT6:
+      case GL_LIGHT7:
+        if (ctx->Light.Light[cap-GL_LIGHT0].Enabled != state) 
+        {
+           ctx->Light.Light[cap-GL_LIGHT0].Enabled = state;
+
+           if (state) {
+              insert_at_tail(&ctx->Light.EnabledList, 
+                             &ctx->Light.Light[cap-GL_LIGHT0]);
+              if (ctx->Light.Enabled)
+                 ctx->Enabled |= ENABLE_LIGHT;
+           } else {
+              remove_from_list(&ctx->Light.Light[cap-GL_LIGHT0]);
+              if (is_empty_list(&ctx->Light.EnabledList))
+                 ctx->Enabled &= ~ENABLE_LIGHT;
+           }
+
+           ctx->NewState |= NEW_LIGHTING;
+        }
+         break;
+      case GL_LIGHTING:
+         if (ctx->Light.Enabled!=state) {
+            ctx->Light.Enabled = state;
+           ctx->Enabled &= ~ENABLE_LIGHT;
+           if (state && !is_empty_list(&ctx->Light.EnabledList))
+              ctx->Enabled |= ENABLE_LIGHT;
+            ctx->NewState |= NEW_LIGHTING;
+         }
+         break;
+      case GL_LINE_SMOOTH:
+        if (ctx->Line.SmoothFlag!=state) {
+            ctx->Line.SmoothFlag = state;
+            ctx->NewState |= NEW_RASTER_OPS;
+         }
+        break;
+      case GL_LINE_STIPPLE:
+        if (ctx->Line.StippleFlag!=state) {
+            ctx->Line.StippleFlag = state;
+           ctx->TriangleCaps ^= DD_LINE_STIPPLE;
+            ctx->NewState |= NEW_RASTER_OPS;
+         }
+        break;
+      case GL_INDEX_LOGIC_OP:
+         if (ctx->Color.IndexLogicOpEnabled!=state) {
+           ctx->Color.IndexLogicOpEnabled = state;
+            ctx->NewState |= NEW_RASTER_OPS;
+         }
+        break;
+      case GL_COLOR_LOGIC_OP:
+         if (ctx->Color.ColorLogicOpEnabled!=state) {
+           ctx->Color.ColorLogicOpEnabled = state;
+            ctx->NewState |= NEW_RASTER_OPS;
+         }
+        break;
+      case GL_MAP1_COLOR_4:
+        ctx->Eval.Map1Color4 = state;
+        break;
+      case GL_MAP1_INDEX:
+        ctx->Eval.Map1Index = state;
+        break;
+      case GL_MAP1_NORMAL:
+        ctx->Eval.Map1Normal = state;
+        break;
+      case GL_MAP1_TEXTURE_COORD_1:
+        ctx->Eval.Map1TextureCoord1 = state;
+        break;
+      case GL_MAP1_TEXTURE_COORD_2:
+        ctx->Eval.Map1TextureCoord2 = state;
+        break;
+      case GL_MAP1_TEXTURE_COORD_3:
+        ctx->Eval.Map1TextureCoord3 = state;
+        break;
+      case GL_MAP1_TEXTURE_COORD_4:
+        ctx->Eval.Map1TextureCoord4 = state;
+        break;
+      case GL_MAP1_VERTEX_3:
+        ctx->Eval.Map1Vertex3 = state;
+        break;
+      case GL_MAP1_VERTEX_4:
+        ctx->Eval.Map1Vertex4 = state;
+        break;
+      case GL_MAP2_COLOR_4:
+        ctx->Eval.Map2Color4 = state;
+        break;
+      case GL_MAP2_INDEX:
+        ctx->Eval.Map2Index = state;
+        break;
+      case GL_MAP2_NORMAL:
+        ctx->Eval.Map2Normal = state;
+        break;
+      case GL_MAP2_TEXTURE_COORD_1: 
+        ctx->Eval.Map2TextureCoord1 = state;
+        break;
+      case GL_MAP2_TEXTURE_COORD_2:
+        ctx->Eval.Map2TextureCoord2 = state;
+        break;
+      case GL_MAP2_TEXTURE_COORD_3:
+        ctx->Eval.Map2TextureCoord3 = state;
+        break;
+      case GL_MAP2_TEXTURE_COORD_4:
+        ctx->Eval.Map2TextureCoord4 = state;
+        break;
+      case GL_MAP2_VERTEX_3:
+        ctx->Eval.Map2Vertex3 = state;
+        break;
+      case GL_MAP2_VERTEX_4:
+        ctx->Eval.Map2Vertex4 = state;
+        break;
+      case GL_NORMALIZE:
+        if (ctx->Transform.Normalize != state) {
+           ctx->Transform.Normalize = state;
+           ctx->NewState |= NEW_NORMAL_TRANSFORM|NEW_LIGHTING;
+           ctx->Enabled ^= ENABLE_NORMALIZE;
+        }
+        break;
+      case GL_POINT_SMOOTH:
+        if (ctx->Point.SmoothFlag!=state) {
+            ctx->Point.SmoothFlag = state;
+            ctx->NewState |= NEW_RASTER_OPS;
+         }
+        break;
+      case GL_POLYGON_SMOOTH:
+        if (ctx->Polygon.SmoothFlag!=state) {
+            ctx->Polygon.SmoothFlag = state;
+            ctx->NewState |= NEW_RASTER_OPS;
+         }
+        break;
+      case GL_POLYGON_STIPPLE:
+        if (ctx->Polygon.StippleFlag!=state) {
+            ctx->Polygon.StippleFlag = state;
+           ctx->TriangleCaps ^= DD_TRI_STIPPLE;
+            ctx->NewState |= NEW_RASTER_OPS;
+         }
+        break;
+      case GL_POLYGON_OFFSET_POINT:
+         if (ctx->Polygon.OffsetPoint!=state) {
+            ctx->Polygon.OffsetPoint = state;
+            ctx->NewState |= NEW_POLYGON;
+         }
+         break;
+      case GL_POLYGON_OFFSET_LINE:
+         if (ctx->Polygon.OffsetLine!=state) {
+            ctx->Polygon.OffsetLine = state;
+            ctx->NewState |= NEW_POLYGON;
+         }
+         break;
+      case GL_POLYGON_OFFSET_FILL:
+      /*case GL_POLYGON_OFFSET_EXT:*/
+         if (ctx->Polygon.OffsetFill!=state) {
+            ctx->Polygon.OffsetFill = state;
+            ctx->NewState |= NEW_POLYGON;
+         }
+         break;
+      case GL_RESCALE_NORMAL_EXT:
+        if (ctx->Transform.RescaleNormals != state) {
+           ctx->Transform.RescaleNormals = state;
+           ctx->NewState |= NEW_NORMAL_TRANSFORM|NEW_LIGHTING;
+           ctx->Enabled ^= ENABLE_RESCALE;
+        }
+         break;
+      case GL_SCISSOR_TEST:
+         if (ctx->Scissor.Enabled!=state) {
+            ctx->Scissor.Enabled = state;
+            ctx->NewState |= NEW_RASTER_OPS;
+         }
+        break;
+      case GL_SHARED_TEXTURE_PALETTE_EXT:
+         ctx->Texture.SharedPalette = state;
+         if (ctx->Driver.UseGlobalTexturePalette)
+            (*ctx->Driver.UseGlobalTexturePalette)( ctx, state );
+         break;
+      case GL_STENCIL_TEST:
+        if (state && ctx->Visual->StencilBits==0) {
+            gl_warning(ctx, "glEnable(GL_STENCIL_TEST) but no stencil buffer");
+            return;
+        }
+        if (ctx->Stencil.Enabled!=state) {
+            ctx->Stencil.Enabled = state;
+            ctx->NewState |= NEW_RASTER_OPS;
+         }
+        break;
+      case GL_TEXTURE_1D:
+         if (ctx->Visual->RGBAflag) {
+           const GLuint curr = ctx->Texture.CurrentUnit;
+           const GLuint flag = TEXTURE0_1D << (curr * 4);
+            struct gl_texture_unit *texUnit = &ctx->Texture.Unit[curr];
+           ctx->NewState |= NEW_TEXTURE_ENABLE;
+            if (state) {
+              texUnit->Enabled |= TEXTURE0_1D;
+              ctx->Enabled |= flag;
+           }
+            else {
+               texUnit->Enabled &= ~TEXTURE0_1D;
+               ctx->Enabled &= ~flag;
+            }
+         }
+         break;
+      case GL_TEXTURE_2D:
+         if (ctx->Visual->RGBAflag) {
+           const GLuint curr = ctx->Texture.CurrentUnit;
+           const GLuint flag = TEXTURE0_2D << (curr * 4);
+            struct gl_texture_unit *texUnit = &ctx->Texture.Unit[curr];
+           ctx->NewState |= NEW_TEXTURE_ENABLE;
+            if (state) {
+              texUnit->Enabled |= TEXTURE0_2D;
+              ctx->Enabled |= flag;
+           }
+            else {
+               texUnit->Enabled &= ~TEXTURE0_2D;
+               ctx->Enabled &= ~flag;
+            }
+         }
+        break;
+      case GL_TEXTURE_3D:
+         if (ctx->Visual->RGBAflag) {
+           const GLuint curr = ctx->Texture.CurrentUnit;
+           const GLuint flag = TEXTURE0_3D << (curr * 4);
+            struct gl_texture_unit *texUnit = &ctx->Texture.Unit[curr];
+           ctx->NewState |= NEW_TEXTURE_ENABLE;
+            if (state) {
+              texUnit->Enabled |= TEXTURE0_3D;
+              ctx->Enabled |= flag;
+           }
+            else {
+               texUnit->Enabled &= ~TEXTURE0_3D;
+               ctx->Enabled &= ~flag;
+            }
+         }
+         break;
+      case GL_TEXTURE_GEN_Q:
+         {
+            struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+            if (state)
+               texUnit->TexGenEnabled |= Q_BIT;
+            else
+               texUnit->TexGenEnabled &= ~Q_BIT;
+            ctx->NewState |= NEW_TEXTURING;
+         }
+        break;
+      case GL_TEXTURE_GEN_R:
+         {
+            struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+            if (state)
+               texUnit->TexGenEnabled |= R_BIT;
+            else
+               texUnit->TexGenEnabled &= ~R_BIT;
+            ctx->NewState |= NEW_TEXTURING;
+         }
+        break;
+      case GL_TEXTURE_GEN_S:
+         {
+            struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+            if (state)
+               texUnit->TexGenEnabled |= S_BIT;
+            else
+               texUnit->TexGenEnabled &= ~S_BIT;
+            ctx->NewState |= NEW_TEXTURING;
+         }
+        break;
+      case GL_TEXTURE_GEN_T:
+         {
+            struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+            if (state)
+               texUnit->TexGenEnabled |= T_BIT;
+            else
+               texUnit->TexGenEnabled &= ~T_BIT;
+            ctx->NewState |= NEW_TEXTURING;
+         }
+        break;
+
+      /*
+       * CLIENT STATE!!!
+       */
+      case GL_VERTEX_ARRAY:
+         ctx->Array.Vertex.Enabled = state;
+         break;
+      case GL_NORMAL_ARRAY:
+         ctx->Array.Normal.Enabled = state;
+         break;
+      case GL_COLOR_ARRAY:
+         ctx->Array.Color.Enabled = state;
+         break;
+      case GL_INDEX_ARRAY:
+         ctx->Array.Index.Enabled = state;
+         break;
+      case GL_TEXTURE_COORD_ARRAY:
+         ctx->Array.TexCoord[ctx->TexCoordUnit].Enabled = state;
+         break;
+      case GL_EDGE_FLAG_ARRAY:
+         ctx->Array.EdgeFlag.Enabled = state;
+         break;
+
+      default:
+        if (state) {
+           gl_error( ctx, GL_INVALID_ENUM, "glEnable" );
+        }
+        else {
+           gl_error( ctx, GL_INVALID_ENUM, "glDisable" );
+        }
+         return;
+   }
+
+   if (ctx->Driver.Enable) {
+      (*ctx->Driver.Enable)( ctx, cap, state );
+   }
+}
+
+
+
+
+void gl_Enable( GLcontext* ctx, GLenum cap )
+{
+   gl_set_enable( ctx, cap, GL_TRUE );
+}
+
+
+
+void gl_Disable( GLcontext* ctx, GLenum cap )
+{
+   gl_set_enable( ctx, cap, GL_FALSE );
+}
+
+
+
+GLboolean gl_IsEnabled( GLcontext* ctx, GLenum cap )
+{
+   switch (cap) {
+      case GL_ALPHA_TEST:
+         return ctx->Color.AlphaEnabled;
+      case GL_AUTO_NORMAL:
+        return ctx->Eval.AutoNormal;
+      case GL_BLEND:
+         return ctx->Color.BlendEnabled;
+      case GL_CLIP_PLANE0:
+      case GL_CLIP_PLANE1:
+      case GL_CLIP_PLANE2:
+      case GL_CLIP_PLANE3:
+      case GL_CLIP_PLANE4:
+      case GL_CLIP_PLANE5:
+        return ctx->Transform.ClipEnabled[cap-GL_CLIP_PLANE0];
+      case GL_COLOR_MATERIAL:
+        return ctx->Light.ColorMaterialEnabled;
+      case GL_CULL_FACE:
+         return ctx->Polygon.CullFlag;
+      case GL_DEPTH_TEST:
+         return ctx->Depth.Test;
+      case GL_DITHER:
+        return ctx->Color.DitherFlag;
+      case GL_FOG:
+        return ctx->Fog.Enabled;
+      case GL_LIGHTING:
+         return ctx->Light.Enabled;
+      case GL_LIGHT0:
+      case GL_LIGHT1:
+      case GL_LIGHT2:
+      case GL_LIGHT3:
+      case GL_LIGHT4:
+      case GL_LIGHT5:
+      case GL_LIGHT6:
+      case GL_LIGHT7:
+         return ctx->Light.Light[cap-GL_LIGHT0].Enabled;
+      case GL_LINE_SMOOTH:
+        return ctx->Line.SmoothFlag;
+      case GL_LINE_STIPPLE:
+        return ctx->Line.StippleFlag;
+      case GL_INDEX_LOGIC_OP:
+        return ctx->Color.IndexLogicOpEnabled;
+      case GL_COLOR_LOGIC_OP:
+        return ctx->Color.ColorLogicOpEnabled;
+      case GL_MAP1_COLOR_4:
+        return ctx->Eval.Map1Color4;
+      case GL_MAP1_INDEX:
+        return ctx->Eval.Map1Index;
+      case GL_MAP1_NORMAL:
+        return ctx->Eval.Map1Normal;
+      case GL_MAP1_TEXTURE_COORD_1:
+        return ctx->Eval.Map1TextureCoord1;
+      case GL_MAP1_TEXTURE_COORD_2:
+        return ctx->Eval.Map1TextureCoord2;
+      case GL_MAP1_TEXTURE_COORD_3:
+        return ctx->Eval.Map1TextureCoord3;
+      case GL_MAP1_TEXTURE_COORD_4:
+        return ctx->Eval.Map1TextureCoord4;
+      case GL_MAP1_VERTEX_3:
+        return ctx->Eval.Map1Vertex3;
+      case GL_MAP1_VERTEX_4:
+        return ctx->Eval.Map1Vertex4;
+      case GL_MAP2_COLOR_4:
+        return ctx->Eval.Map2Color4;
+      case GL_MAP2_INDEX:
+        return ctx->Eval.Map2Index;
+      case GL_MAP2_NORMAL:
+        return ctx->Eval.Map2Normal;
+      case GL_MAP2_TEXTURE_COORD_1: 
+        return ctx->Eval.Map2TextureCoord1;
+      case GL_MAP2_TEXTURE_COORD_2:
+        return ctx->Eval.Map2TextureCoord2;
+      case GL_MAP2_TEXTURE_COORD_3:
+        return ctx->Eval.Map2TextureCoord3;
+      case GL_MAP2_TEXTURE_COORD_4:
+        return ctx->Eval.Map2TextureCoord4;
+      case GL_MAP2_VERTEX_3:
+        return ctx->Eval.Map2Vertex3;
+      case GL_MAP2_VERTEX_4:
+        return ctx->Eval.Map2Vertex4;
+      case GL_NORMALIZE:
+        return ctx->Transform.Normalize;
+      case GL_POINT_SMOOTH:
+        return ctx->Point.SmoothFlag;
+      case GL_POLYGON_SMOOTH:
+        return ctx->Polygon.SmoothFlag;
+      case GL_POLYGON_STIPPLE:
+        return ctx->Polygon.StippleFlag;
+      case GL_POLYGON_OFFSET_POINT:
+        return ctx->Polygon.OffsetPoint;
+      case GL_POLYGON_OFFSET_LINE:
+        return ctx->Polygon.OffsetLine;
+      case GL_POLYGON_OFFSET_FILL:
+      /*case GL_POLYGON_OFFSET_EXT:*/
+        return ctx->Polygon.OffsetFill;
+      case GL_RESCALE_NORMAL_EXT:
+         return ctx->Transform.RescaleNormals;
+      case GL_SCISSOR_TEST:
+        return ctx->Scissor.Enabled;
+      case GL_SHARED_TEXTURE_PALETTE_EXT:
+         return ctx->Texture.SharedPalette;
+      case GL_STENCIL_TEST:
+        return ctx->Stencil.Enabled;
+      case GL_TEXTURE_1D:
+         {
+            const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+            return (texUnit->Enabled & TEXTURE0_1D) ? GL_TRUE : GL_FALSE;
+         }
+      case GL_TEXTURE_2D:
+         {
+            const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+            return (texUnit->Enabled & TEXTURE0_2D) ? GL_TRUE : GL_FALSE;
+         }
+      case GL_TEXTURE_3D:
+         {
+            const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+            return (texUnit->Enabled & TEXTURE0_2D) ? GL_TRUE : GL_FALSE;
+         }
+      case GL_TEXTURE_GEN_Q:
+         {
+            const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+            return (texUnit->TexGenEnabled & Q_BIT) ? GL_TRUE : GL_FALSE;
+         }
+      case GL_TEXTURE_GEN_R:
+         {
+            const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+            return (texUnit->TexGenEnabled & R_BIT) ? GL_TRUE : GL_FALSE;
+         }
+      case GL_TEXTURE_GEN_S:
+         {
+            const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+            return (texUnit->TexGenEnabled & S_BIT) ? GL_TRUE : GL_FALSE;
+         }
+      case GL_TEXTURE_GEN_T:
+         {
+            const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+            return (texUnit->TexGenEnabled & T_BIT) ? GL_TRUE : GL_FALSE;
+         }
+
+      /*
+       * CLIENT STATE!!!
+       */
+      case GL_VERTEX_ARRAY:
+         return ctx->Array.Vertex.Enabled;
+      case GL_NORMAL_ARRAY:
+         return ctx->Array.Normal.Enabled;
+      case GL_COLOR_ARRAY:
+         return ctx->Array.Color.Enabled;
+      case GL_INDEX_ARRAY:
+         return ctx->Array.Index.Enabled;
+      case GL_TEXTURE_COORD_ARRAY:
+         return ctx->Array.TexCoord[ctx->TexCoordUnit].Enabled;
+      case GL_EDGE_FLAG_ARRAY:
+         return ctx->Array.EdgeFlag.Enabled;
+      default:
+        gl_error( ctx, GL_INVALID_ENUM, "glIsEnabled" );
+        return GL_FALSE;
+   }
+}
+
+
+
+
+static void gl_client_state( GLcontext *ctx, GLenum cap, GLboolean state )
+{
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH( ctx, 
+                                      (state 
+                                       ? "glEnableClientState" 
+                                       : "glDisableClientState") );
+
+   switch (cap) {
+      case GL_VERTEX_ARRAY:
+         ctx->Array.Vertex.Enabled = state;
+         break;
+      case GL_NORMAL_ARRAY:
+         ctx->Array.Normal.Enabled = state;
+         break;
+      case GL_COLOR_ARRAY:
+         ctx->Array.Color.Enabled = state;
+         break;
+      case GL_INDEX_ARRAY:
+         ctx->Array.Index.Enabled = state;
+         break;
+      case GL_TEXTURE_COORD_ARRAY:
+         ctx->Array.TexCoord[ctx->TexCoordUnit].Enabled = state;
+         break;
+      case GL_EDGE_FLAG_ARRAY:
+         ctx->Array.EdgeFlag.Enabled = state;
+         break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glEnable/DisableClientState" );
+   }
+
+   ctx->NewState |= NEW_CLIENT_STATE;
+}
+
+
+
+void gl_EnableClientState( GLcontext *ctx, GLenum cap )
+{
+   gl_client_state( ctx, cap, GL_TRUE );
+}
+
+
+
+void gl_DisableClientState( GLcontext *ctx, GLenum cap )
+{
+   gl_client_state( ctx, cap, GL_FALSE );
+}
+
diff --git a/src/mesa/main/enable.h b/src/mesa/main/enable.h
new file mode 100644 (file)
index 0000000..92a916a
--- /dev/null
@@ -0,0 +1,51 @@
+/* $Id: enable.h,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+#ifndef ENABLE_H
+#define ENABLE_H
+
+
+#include "types.h"
+
+
+extern void gl_set_enable( GLcontext* ctx, GLenum cap, GLboolean state );
+
+extern void gl_Disable( GLcontext* ctx, GLenum cap );
+
+extern void gl_Enable( GLcontext* ctx, GLenum cap );
+
+extern GLboolean gl_IsEnabled( GLcontext* ctx, GLenum cap );
+
+extern void gl_EnableClientState( GLcontext *ctx, GLenum cap );
+
+extern void gl_DisableClientState( GLcontext *ctx, GLenum cap );
+
+
+#endif
diff --git a/src/mesa/main/enums.c b/src/mesa/main/enums.c
new file mode 100644 (file)
index 0000000..69b520e
--- /dev/null
@@ -0,0 +1,893 @@
+/* $Id: enums.c,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include "GL/gl.h"
+#include "enums.h"
+#include <stdlib.h>
+#include <string.h>
+
+
+typedef struct { 
+   const char *c; 
+   int n; 
+} enum_elt;
+
+enum_elt all_enums[] = 
+{
+   /* Boolean values */
+   { "GL_FALSE", 0 },
+   { "GL_TRUE", 1 },
+
+   /* Data types */
+   { "GL_BYTE", 0x1400 },
+   { "GL_UNSIGNED_BYTE", 0x1401 },
+   { "GL_SHORT", 0x1402 },
+   { "GL_UNSIGNED_SHORT", 0x1403 },
+   { "GL_INT", 0x1404 },
+   { "GL_UNSIGNED_INT", 0x1405 },
+   { "GL_FLOAT", 0x1406 },
+   { "GL_DOUBLE", 0x140A },
+   { "GL_2_BYTES", 0x1407 },
+   { "GL_3_BYTES", 0x1408 },
+   { "GL_4_BYTES", 0x1409 },
+
+   /* Primitives */
+   { "GL_LINES", 0x0001 },
+   { "GL_POINTS", 0x0000 },
+   { "GL_LINE_STRIP", 0x0003 },
+   { "GL_LINE_LOOP", 0x0002 },
+   { "GL_TRIANGLES", 0x0004 },
+   { "GL_TRIANGLE_STRIP", 0x0005 },
+   { "GL_TRIANGLE_FAN", 0x0006 },
+   { "GL_QUADS", 0x0007 },
+   { "GL_QUAD_STRIP", 0x0008 },
+   { "GL_POLYGON", 0x0009 },
+   { "GL_EDGE_FLAG", 0x0B43 },
+
+   /* Vertex Arrays */
+   { "GL_VERTEX_ARRAY", 0x8074 },
+   { "GL_NORMAL_ARRAY", 0x8075 },
+   { "GL_COLOR_ARRAY", 0x8076 },
+   { "GL_INDEX_ARRAY", 0x8077 },
+   { "GL_TEXTURE_COORD_ARRAY", 0x8078 },
+   { "GL_EDGE_FLAG_ARRAY", 0x8079 },
+   { "GL_VERTEX_ARRAY_SIZE", 0x807A },
+   { "GL_VERTEX_ARRAY_TYPE", 0x807B },
+   { "GL_VERTEX_ARRAY_STRIDE", 0x807C },
+   { "GL_NORMAL_ARRAY_TYPE", 0x807E },
+   { "GL_NORMAL_ARRAY_STRIDE", 0x807F },
+   { "GL_COLOR_ARRAY_SIZE", 0x8081 },
+   { "GL_COLOR_ARRAY_TYPE", 0x8082 },
+   { "GL_COLOR_ARRAY_STRIDE", 0x8083 },
+   { "GL_INDEX_ARRAY_TYPE", 0x8085 },
+   { "GL_INDEX_ARRAY_STRIDE", 0x8086 },
+   { "GL_TEXTURE_COORD_ARRAY_SIZE", 0x8088 },
+   { "GL_TEXTURE_COORD_ARRAY_TYPE", 0x8089 },
+   { "GL_TEXTURE_COORD_ARRAY_STRIDE", 0x808A },
+   { "GL_EDGE_FLAG_ARRAY_STRIDE", 0x808C },
+   { "GL_VERTEX_ARRAY_POINTER", 0x808E },
+   { "GL_NORMAL_ARRAY_POINTER", 0x808F },
+   { "GL_COLOR_ARRAY_POINTER", 0x8090 },
+   { "GL_INDEX_ARRAY_POINTER", 0x8091 },
+   { "GL_TEXTURE_COORD_ARRAY_POINTER", 0x8092 },
+   { "GL_EDGE_FLAG_ARRAY_POINTER", 0x8093 },
+   { "GL_V2F", 0x2A20 },
+   { "GL_V3F", 0x2A21 },
+   { "GL_C4UB_V2F", 0x2A22 },
+   { "GL_C4UB_V3F", 0x2A23 },
+   { "GL_C3F_V3F", 0x2A24 },
+   { "GL_N3F_V3F", 0x2A25 },
+   { "GL_C4F_N3F_V3F", 0x2A26 },
+   { "GL_T2F_V3F", 0x2A27 },
+   { "GL_T4F_V4F", 0x2A28 },
+   { "GL_T2F_C4UB_V3F", 0x2A29 },
+   { "GL_T2F_C3F_V3F", 0x2A2A },
+   { "GL_T2F_N3F_V3F", 0x2A2B },
+   { "GL_T2F_C4F_N3F_V3F", 0x2A2C },
+   { "GL_T4F_C4F_N3F_V4F", 0x2A2D },
+
+   /* Matrix Mode */
+   { "GL_MATRIX_MODE", 0x0BA0 },
+   { "GL_MODELVIEW", 0x1700 },
+   { "GL_PROJECTION", 0x1701 },
+   { "GL_TEXTURE", 0x1702 },
+
+   /* Points */
+   { "GL_POINT_SMOOTH", 0x0B10 },
+   { "GL_POINT_SIZE", 0x0B11 },
+   { "GL_POINT_SIZE_GRANULARITY ", 0x0B13 },
+   { "GL_POINT_SIZE_RANGE", 0x0B12 },
+
+   /* Lines */
+   { "GL_LINE_SMOOTH", 0x0B20 },
+   { "GL_LINE_STIPPLE", 0x0B24 },
+   { "GL_LINE_STIPPLE_PATTERN", 0x0B25 },
+   { "GL_LINE_STIPPLE_REPEAT", 0x0B26 },
+   { "GL_LINE_WIDTH", 0x0B21 },
+   { "GL_LINE_WIDTH_GRANULARITY", 0x0B23 },
+   { "GL_LINE_WIDTH_RANGE", 0x0B22 },
+
+   /* Polygons */
+   { "GL_POINT", 0x1B00 },
+   { "GL_LINE", 0x1B01 },
+   { "GL_FILL", 0x1B02 },
+   { "GL_CCW", 0x0901 },
+   { "GL_CW", 0x0900 },
+   { "GL_FRONT", 0x0404 },
+   { "GL_BACK", 0x0405 },
+   { "GL_CULL_FACE", 0x0B44 },
+   { "GL_CULL_FACE_MODE", 0x0B45 },
+   { "GL_POLYGON_SMOOTH", 0x0B41 },
+   { "GL_POLYGON_STIPPLE", 0x0B42 },
+   { "GL_FRONT_FACE", 0x0B46 },
+   { "GL_POLYGON_MODE", 0x0B40 },
+   { "GL_POLYGON_OFFSET_FACTOR", 0x8038 },
+   { "GL_POLYGON_OFFSET_UNITS", 0x2A00 },
+   { "GL_POLYGON_OFFSET_POINT", 0x2A01 },
+   { "GL_POLYGON_OFFSET_LINE", 0x2A02 },
+   { "GL_POLYGON_OFFSET_FILL", 0x8037 },
+
+   /* Display Lists */
+   { "GL_COMPILE", 0x1300 },
+   { "GL_COMPILE_AND_EXECUTE", 0x1301 },
+   { "GL_LIST_BASE", 0x0B32 },
+   { "GL_LIST_INDEX", 0x0B33 },
+   { "GL_LIST_MODE", 0x0B30 },
+
+   /* Depth buffer */
+   { "GL_NEVER", 0x0200 },
+   { "GL_LESS", 0x0201 },
+   { "GL_GEQUAL", 0x0206 },
+   { "GL_LEQUAL", 0x0203 },
+   { "GL_GREATER", 0x0204 },
+   { "GL_NOTEQUAL", 0x0205 },
+   { "GL_EQUAL", 0x0202 },
+   { "GL_ALWAYS", 0x0207 },
+   { "GL_DEPTH_TEST", 0x0B71 },
+   { "GL_DEPTH_BITS", 0x0D56 },
+   { "GL_DEPTH_CLEAR_VALUE", 0x0B73 },
+   { "GL_DEPTH_FUNC", 0x0B74 },
+   { "GL_DEPTH_RANGE", 0x0B70 },
+   { "GL_DEPTH_WRITEMASK", 0x0B72 },
+   { "GL_DEPTH_COMPONENT", 0x1902 },
+
+   /* Lighting */
+   { "GL_LIGHTING", 0x0B50 },
+   { "GL_LIGHT0", 0x4000 },
+   { "GL_LIGHT1", 0x4001 },
+   { "GL_LIGHT2", 0x4002 },
+   { "GL_LIGHT3", 0x4003 },
+   { "GL_LIGHT4", 0x4004 },
+   { "GL_LIGHT5", 0x4005 },
+   { "GL_LIGHT6", 0x4006 },
+   { "GL_LIGHT7", 0x4007 },
+   { "GL_SPOT_EXPONENT", 0x1205 },
+   { "GL_SPOT_CUTOFF", 0x1206 },
+   { "GL_CONSTANT_ATTENUATION", 0x1207 },
+   { "GL_LINEAR_ATTENUATION", 0x1208 },
+   { "GL_QUADRATIC_ATTENUATION", 0x1209 },
+   { "GL_AMBIENT", 0x1200 },
+   { "GL_DIFFUSE", 0x1201 },
+   { "GL_SPECULAR", 0x1202 },
+   { "GL_SHININESS", 0x1601 },
+   { "GL_EMISSION", 0x1600 },
+   { "GL_POSITION", 0x1203 },
+   { "GL_SPOT_DIRECTION", 0x1204 },
+   { "GL_AMBIENT_AND_DIFFUSE", 0x1602 },
+   { "GL_COLOR_INDEXES", 0x1603 },
+   { "GL_LIGHT_MODEL_TWO_SIDE", 0x0B52 },
+   { "GL_LIGHT_MODEL_LOCAL_VIEWER", 0x0B51 },
+   { "GL_LIGHT_MODEL_AMBIENT", 0x0B53 },
+   { "GL_FRONT_AND_BACK", 0x0408 },
+   { "GL_SHADE_MODEL", 0x0B54 },
+   { "GL_FLAT", 0x1D00 },
+   { "GL_SMOOTH", 0x1D01 },
+   { "GL_COLOR_MATERIAL", 0x0B57 },
+   { "GL_COLOR_MATERIAL_FACE", 0x0B55 },
+   { "GL_COLOR_MATERIAL_PARAMETER", 0x0B56 },
+   { "GL_NORMALIZE", 0x0BA1 },
+
+   /* User clipping planes */
+   { "GL_CLIP_PLANE0", 0x3000 },
+   { "GL_CLIP_PLANE1", 0x3001 },
+   { "GL_CLIP_PLANE2", 0x3002 },
+   { "GL_CLIP_PLANE3", 0x3003 },
+   { "GL_CLIP_PLANE4", 0x3004 },
+   { "GL_CLIP_PLANE5", 0x3005 },
+
+   /* Accumulation buffer */
+   { "GL_ACCUM_RED_BITS", 0x0D58 },
+   { "GL_ACCUM_GREEN_BITS", 0x0D59 },
+   { "GL_ACCUM_BLUE_BITS", 0x0D5A },
+   { "GL_ACCUM_ALPHA_BITS", 0x0D5B },
+   { "GL_ACCUM_CLEAR_VALUE", 0x0B80 },
+   { "GL_ACCUM", 0x0100 },
+   { "GL_ADD", 0x0104 },
+   { "GL_LOAD", 0x0101 },
+   { "GL_MULT", 0x0103 },
+   { "GL_RETURN", 0x0102 },
+
+   /* Alpha testing */
+   { "GL_ALPHA_TEST", 0x0BC0 },
+   { "GL_ALPHA_TEST_REF", 0x0BC2 },
+   { "GL_ALPHA_TEST_FUNC", 0x0BC1 },
+
+   /* Blending */
+   { "GL_BLEND", 0x0BE2 },
+   { "GL_BLEND_SRC", 0x0BE1 },
+   { "GL_BLEND_DST", 0x0BE0 },
+   { "GL_ZERO", 0 },
+   { "GL_ONE", 1 },
+   { "GL_SRC_COLOR", 0x0300 },
+   { "GL_ONE_MINUS_SRC_COLOR", 0x0301 },
+   { "GL_DST_COLOR", 0x0306 },
+   { "GL_ONE_MINUS_DST_COLOR", 0x0307 },
+   { "GL_SRC_ALPHA", 0x0302 },
+   { "GL_ONE_MINUS_SRC_ALPHA", 0x0303 },
+   { "GL_DST_ALPHA", 0x0304 },
+   { "GL_ONE_MINUS_DST_ALPHA", 0x0305 },
+   { "GL_SRC_ALPHA_SATURATE", 0x0308 },
+   { "GL_CONSTANT_COLOR", 0x8001 },
+   { "GL_ONE_MINUS_CONSTANT_COLOR", 0x8002 },
+   { "GL_CONSTANT_ALPHA", 0x8003 },
+   { "GL_ONE_MINUS_CONSTANT_ALPHA", 0x8004 },
+
+   /* Render Mode */
+   { "GL_FEEDBACK", 0x1C01 },
+   { "GL_RENDER", 0x1C00 },
+   { "GL_SELECT", 0x1C02 },
+
+   /* Feedback */
+   { "GL_2D", 0x0600 },
+   { "GL_3D", 0x0601 },
+   { "GL_3D_COLOR", 0x0602 },
+   { "GL_3D_COLOR_TEXTURE", 0x0603 },
+   { "GL_4D_COLOR_TEXTURE", 0x0604 },
+   { "GL_POINT_TOKEN", 0x0701 },
+   { "GL_LINE_TOKEN", 0x0702 },
+   { "GL_LINE_RESET_TOKEN", 0x0707 },
+   { "GL_POLYGON_TOKEN", 0x0703 },
+   { "GL_BITMAP_TOKEN", 0x0704 },
+   { "GL_DRAW_PIXEL_TOKEN", 0x0705 },
+   { "GL_COPY_PIXEL_TOKEN", 0x0706 },
+   { "GL_PASS_THROUGH_TOKEN", 0x0700 },
+   { "GL_FEEDBACK_BUFFER_POINTER", 0x0DF0 },
+   { "GL_FEEDBACK_BUFFER_SIZE", 0x0DF1 },
+   { "GL_FEEDBACK_BUFFER_TYPE", 0x0DF2 },
+
+   /* Selection */
+   { "GL_SELECTION_BUFFER_POINTER", 0x0DF3 },
+   { "GL_SELECTION_BUFFER_SIZE", 0x0DF4 },
+
+   /* Fog */
+   { "GL_FOG", 0x0B60 },
+   { "GL_FOG_MODE", 0x0B65 },
+   { "GL_FOG_DENSITY", 0x0B62 },
+   { "GL_FOG_COLOR", 0x0B66 },
+   { "GL_FOG_INDEX", 0x0B61 },
+   { "GL_FOG_START", 0x0B63 },
+   { "GL_FOG_END", 0x0B64 },
+   { "GL_LINEAR", 0x2601 },
+   { "GL_EXP", 0x0800 },
+   { "GL_EXP2", 0x0801 },
+
+   /* Logic Ops */
+   { "GL_LOGIC_OP", 0x0BF1 },
+   { "GL_INDEX_LOGIC_OP", 0x0BF1 },
+   { "GL_COLOR_LOGIC_OP", 0x0BF2 },
+   { "GL_LOGIC_OP_MODE", 0x0BF0 },
+   { "GL_CLEAR", 0x1500 },
+   { "GL_SET", 0x150F },
+   { "GL_COPY", 0x1503 },
+   { "GL_COPY_INVERTED", 0x150C },
+   { "GL_NOOP", 0x1505 },
+   { "GL_INVERT", 0x150A },
+   { "GL_AND", 0x1501 },
+   { "GL_NAND", 0x150E },
+   { "GL_OR", 0x1507 },
+   { "GL_NOR", 0x1508 },
+   { "GL_XOR", 0x1506 },
+   { "GL_EQUIV", 0x1509 },
+   { "GL_AND_REVERSE", 0x1502 },
+   { "GL_AND_INVERTED", 0x1504 },
+   { "GL_OR_REVERSE", 0x150B },
+   { "GL_OR_INVERTED", 0x150D },
+
+   /* Stencil */
+   { "GL_STENCIL_TEST", 0x0B90 },
+   { "GL_STENCIL_WRITEMASK", 0x0B98 },
+   { "GL_STENCIL_BITS", 0x0D57 },
+   { "GL_STENCIL_FUNC", 0x0B92 },
+   { "GL_STENCIL_VALUE_MASK", 0x0B93 },
+   { "GL_STENCIL_REF", 0x0B97 },
+   { "GL_STENCIL_FAIL", 0x0B94 },
+   { "GL_STENCIL_PASS_DEPTH_PASS", 0x0B96 },
+   { "GL_STENCIL_PASS_DEPTH_FAIL", 0x0B95 },
+   { "GL_STENCIL_CLEAR_VALUE", 0x0B91 },
+   { "GL_STENCIL_INDEX", 0x1901 },
+   { "GL_KEEP", 0x1E00 },
+   { "GL_REPLACE", 0x1E01 },
+   { "GL_INCR", 0x1E02 },
+   { "GL_DECR", 0x1E03 },
+
+   /* Buffers, Pixel Drawing/Reading */
+   { "GL_NONE", 0 },
+   { "GL_LEFT", 0x0406 },
+   { "GL_RIGHT", 0x0407 },
+   { "GL_FRONT_LEFT", 0x0400 },
+   { "GL_FRONT_RIGHT", 0x0401 },
+   { "GL_BACK_LEFT", 0x0402 },
+   { "GL_BACK_RIGHT", 0x0403 },
+   { "GL_AUX0", 0x0409 },
+   { "GL_AUX1", 0x040A },
+   { "GL_AUX2", 0x040B },
+   { "GL_AUX3", 0x040C },
+   { "GL_COLOR_INDEX", 0x1900 },
+   { "GL_RED", 0x1903 },
+   { "GL_GREEN", 0x1904 },
+   { "GL_BLUE", 0x1905 },
+   { "GL_ALPHA", 0x1906 },
+   { "GL_LUMINANCE", 0x1909 },
+   { "GL_LUMINANCE_ALPHA", 0x190A },
+   { "GL_ALPHA_BITS", 0x0D55 },
+   { "GL_RED_BITS", 0x0D52 },
+   { "GL_GREEN_BITS", 0x0D53 },
+   { "GL_BLUE_BITS", 0x0D54 },
+   { "GL_INDEX_BITS", 0x0D51 },
+   { "GL_SUBPIXEL_BITS", 0x0D50 },
+   { "GL_AUX_BUFFERS", 0x0C00 },
+   { "GL_READ_BUFFER", 0x0C02 },
+   { "GL_DRAW_BUFFER", 0x0C01 },
+   { "GL_DOUBLEBUFFER", 0x0C32 },
+   { "GL_STEREO", 0x0C33 },
+   { "GL_BITMAP", 0x1A00 },
+   { "GL_COLOR", 0x1800 },
+   { "GL_DEPTH", 0x1801 },
+   { "GL_STENCIL", 0x1802 },
+   { "GL_DITHER", 0x0BD0 },
+   { "GL_RGB", 0x1907 },
+   { "GL_RGBA", 0x1908 },
+
+   /* Implementation limits */
+   { "GL_MAX_LIST_NESTING", 0x0B31 },
+   { "GL_MAX_ATTRIB_STACK_DEPTH", 0x0D35 },
+   { "GL_MAX_MODELVIEW_STACK_DEPTH", 0x0D36 },
+   { "GL_MAX_NAME_STACK_DEPTH", 0x0D37 },
+   { "GL_MAX_PROJECTION_STACK_DEPTH", 0x0D38 },
+   { "GL_MAX_TEXTURE_STACK_DEPTH", 0x0D39 },
+   { "GL_MAX_EVAL_ORDER", 0x0D30 },
+   { "GL_MAX_LIGHTS", 0x0D31 },
+   { "GL_MAX_CLIP_PLANES", 0x0D32 },
+   { "GL_MAX_TEXTURE_SIZE", 0x0D33 },
+   { "GL_MAX_PIXEL_MAP_TABLE", 0x0D34 },
+   { "GL_MAX_VIEWPORT_DIMS", 0x0D3A },
+   { "GL_MAX_CLIENT_ATTRIB_STACK_DEPTH", 0x0D3B },
+
+
+   { "GL_ATTRIB_STACK_DEPTH", 0x0BB0 },
+   { "GL_CLIENT_ATTRIB_STACK_DEPTH", 0x0BB1 },
+   { "GL_COLOR_CLEAR_VALUE", 0x0C22 },
+   { "GL_COLOR_WRITEMASK", 0x0C23 },
+   { "GL_CURRENT_INDEX", 0x0B01 },
+   { "GL_CURRENT_COLOR", 0x0B00 },
+   { "GL_CURRENT_NORMAL", 0x0B02 },
+   { "GL_CURRENT_RASTER_COLOR", 0x0B04 },
+   { "GL_CURRENT_RASTER_DISTANCE", 0x0B09 },
+   { "GL_CURRENT_RASTER_INDEX", 0x0B05 },
+   { "GL_CURRENT_RASTER_POSITION", 0x0B07 },
+   { "GL_CURRENT_RASTER_TEXTURE_COORDS", 0x0B06},
+   { "GL_CURRENT_RASTER_POSITION_VALID", 0x0B08 },
+   { "GL_CURRENT_TEXTURE_COORDS", 0x0B03 },
+   { "GL_INDEX_CLEAR_VALUE", 0x0C20 },
+   { "GL_INDEX_MODE", 0x0C30 },
+   { "GL_INDEX_WRITEMASK", 0x0C21 },
+   { "GL_MODELVIEW_MATRIX", 0x0BA6 },
+   { "GL_MODELVIEW_STACK_DEPTH", 0x0BA3 },
+   { "GL_NAME_STACK_DEPTH", 0x0D70 },
+   { "GL_PROJECTION_MATRIX", 0x0BA7 },
+   { "GL_PROJECTION_STACK_DEPTH", 0x0BA4 },
+   { "GL_RENDER_MODE", 0x0C40 },
+   { "GL_RGBA_MODE", 0x0C31 },
+   { "GL_TEXTURE_MATRIX", 0x0BA8 },
+   { "GL_TEXTURE_STACK_DEPTH", 0x0BA5 },
+   { "GL_VIEWPORT", 0x0BA2 },
+
+
+   /* Evaluators */
+   { "GL_AUTO_NORMAL", 0x0D80 },
+   { "GL_MAP1_COLOR_4", 0x0D90 },
+   { "GL_MAP1_GRID_DOMAIN", 0x0DD0 },
+   { "GL_MAP1_GRID_SEGMENTS", 0x0DD1 },
+   { "GL_MAP1_INDEX", 0x0D91 },
+   { "GL_MAP1_NORMAL", 0x0D92 },
+   { "GL_MAP1_TEXTURE_COORD_1", 0x0D93 },
+   { "GL_MAP1_TEXTURE_COORD_2", 0x0D94 },
+   { "GL_MAP1_TEXTURE_COORD_3", 0x0D95 },
+   { "GL_MAP1_TEXTURE_COORD_4", 0x0D96 },
+   { "GL_MAP1_VERTEX_3", 0x0D97 },
+   { "GL_MAP1_VERTEX_4", 0x0D98 },
+   { "GL_MAP2_COLOR_4", 0x0DB0 },
+   { "GL_MAP2_GRID_DOMAIN", 0x0DD2 },
+   { "GL_MAP2_GRID_SEGMENTS", 0x0DD3 },
+   { "GL_MAP2_INDEX", 0x0DB1 },
+   { "GL_MAP2_NORMAL", 0x0DB2 },
+   { "GL_MAP2_TEXTURE_COORD_1", 0x0DB3 },
+   { "GL_MAP2_TEXTURE_COORD_2", 0x0DB4 },
+   { "GL_MAP2_TEXTURE_COORD_3", 0x0DB5 },
+   { "GL_MAP2_TEXTURE_COORD_4", 0x0DB6 },
+   { "GL_MAP2_VERTEX_3", 0x0DB7 },
+   { "GL_MAP2_VERTEX_4", 0x0DB8 },
+   { "GL_COEFF", 0x0A00 },
+   { "GL_DOMAIN", 0x0A02 },
+   { "GL_ORDER", 0x0A01 },
+
+   /* Hints */
+   { "GL_FOG_HINT", 0x0C54 },
+   { "GL_LINE_SMOOTH_HINT", 0x0C52 },
+   { "GL_PERSPECTIVE_CORRECTION_HINT", 0x0C50 },
+   { "GL_POINT_SMOOTH_HINT", 0x0C51 },
+   { "GL_POLYGON_SMOOTH_HINT", 0x0C53 },
+   { "GL_DONT_CARE", 0x1100 },
+   { "GL_FASTEST", 0x1101 },
+   { "GL_NICEST", 0x1102 },
+
+   /* Scissor box */
+   { "GL_SCISSOR_TEST", 0x0C11 },
+   { "GL_SCISSOR_BOX", 0x0C10 },
+
+   /* Pixel Mode / Transfer */
+   { "GL_MAP_COLOR", 0x0D10 },
+   { "GL_MAP_STENCIL", 0x0D11 },
+   { "GL_INDEX_SHIFT", 0x0D12 },
+   { "GL_INDEX_OFFSET", 0x0D13 },
+   { "GL_RED_SCALE", 0x0D14 },
+   { "GL_RED_BIAS", 0x0D15 },
+   { "GL_GREEN_SCALE", 0x0D18 },
+   { "GL_GREEN_BIAS", 0x0D19 },
+   { "GL_BLUE_SCALE", 0x0D1A },
+   { "GL_BLUE_BIAS", 0x0D1B },
+   { "GL_ALPHA_SCALE", 0x0D1C },
+   { "GL_ALPHA_BIAS", 0x0D1D },
+   { "GL_DEPTH_SCALE", 0x0D1E },
+   { "GL_DEPTH_BIAS", 0x0D1F },
+   { "GL_PIXEL_MAP_S_TO_S_SIZE", 0x0CB1 },
+   { "GL_PIXEL_MAP_I_TO_I_SIZE", 0x0CB0 },
+   { "GL_PIXEL_MAP_I_TO_R_SIZE", 0x0CB2 },
+   { "GL_PIXEL_MAP_I_TO_G_SIZE", 0x0CB3 },
+   { "GL_PIXEL_MAP_I_TO_B_SIZE", 0x0CB4 },
+   { "GL_PIXEL_MAP_I_TO_A_SIZE", 0x0CB5 },
+   { "GL_PIXEL_MAP_R_TO_R_SIZE", 0x0CB6 },
+   { "GL_PIXEL_MAP_G_TO_G_SIZE", 0x0CB7 },
+   { "GL_PIXEL_MAP_B_TO_B_SIZE", 0x0CB8 },
+   { "GL_PIXEL_MAP_A_TO_A_SIZE", 0x0CB9 },
+   { "GL_PIXEL_MAP_S_TO_S", 0x0C71 },
+   { "GL_PIXEL_MAP_I_TO_I", 0x0C70 },
+   { "GL_PIXEL_MAP_I_TO_R", 0x0C72 },
+   { "GL_PIXEL_MAP_I_TO_G", 0x0C73 },
+   { "GL_PIXEL_MAP_I_TO_B", 0x0C74 },
+   { "GL_PIXEL_MAP_I_TO_A", 0x0C75 },
+   { "GL_PIXEL_MAP_R_TO_R", 0x0C76 },
+   { "GL_PIXEL_MAP_G_TO_G", 0x0C77 },
+   { "GL_PIXEL_MAP_B_TO_B", 0x0C78 },
+   { "GL_PIXEL_MAP_A_TO_A", 0x0C79 },
+   { "GL_PACK_ALIGNMENT", 0x0D05 },
+   { "GL_PACK_LSB_FIRST", 0x0D01 },
+   { "GL_PACK_ROW_LENGTH", 0x0D02 },
+   { "GL_PACK_SKIP_PIXELS", 0x0D04 },
+   { "GL_PACK_SKIP_ROWS", 0x0D03 },
+   { "GL_PACK_SWAP_BYTES", 0x0D00 },
+   { "GL_UNPACK_ALIGNMENT", 0x0CF5 },
+   { "GL_UNPACK_LSB_FIRST", 0x0CF1 },
+   { "GL_UNPACK_ROW_LENGTH", 0x0CF2 },
+   { "GL_UNPACK_SKIP_PIXELS", 0x0CF4 },
+   { "GL_UNPACK_SKIP_ROWS", 0x0CF3 },
+   { "GL_UNPACK_SWAP_BYTES", 0x0CF0 },
+   { "GL_ZOOM_X", 0x0D16 },
+   { "GL_ZOOM_Y", 0x0D17 },
+
+   /* Texture mapping */
+   { "GL_TEXTURE_ENV", 0x2300 },
+   { "GL_TEXTURE_ENV_MODE", 0x2200 },
+   { "GL_TEXTURE_1D", 0x0DE0 },
+   { "GL_TEXTURE_2D", 0x0DE1 },
+   { "GL_TEXTURE_WRAP_S", 0x2802 },
+   { "GL_TEXTURE_WRAP_T", 0x2803 },
+   { "GL_TEXTURE_MAG_FILTER", 0x2800 },
+   { "GL_TEXTURE_MIN_FILTER", 0x2801 },
+   { "GL_TEXTURE_ENV_COLOR", 0x2201 },
+   { "GL_TEXTURE_GEN_S", 0x0C60 },
+   { "GL_TEXTURE_GEN_T", 0x0C61 },
+   { "GL_TEXTURE_GEN_MODE", 0x2500 },
+   { "GL_TEXTURE_BORDER_COLOR", 0x1004 },
+   { "GL_TEXTURE_WIDTH", 0x1000 },
+   { "GL_TEXTURE_HEIGHT", 0x1001 },
+   { "GL_TEXTURE_BORDER", 0x1005 },
+   { "GL_TEXTURE_COMPONENTS", 0x1003 },
+   { "GL_TEXTURE_RED_SIZE", 0x805C },
+   { "GL_TEXTURE_GREEN_SIZE", 0x805D },
+   { "GL_TEXTURE_BLUE_SIZE", 0x805E },
+   { "GL_TEXTURE_ALPHA_SIZE", 0x805F },
+   { "GL_TEXTURE_LUMINANCE_SIZE", 0x8060 },
+   { "GL_TEXTURE_INTENSITY_SIZE", 0x8061 },
+   { "GL_NEAREST_MIPMAP_NEAREST", 0x2700 },
+   { "GL_NEAREST_MIPMAP_LINEAR", 0x2702 },
+   { "GL_LINEAR_MIPMAP_NEAREST", 0x2701 },
+   { "GL_LINEAR_MIPMAP_LINEAR", 0x2703 },
+   { "GL_OBJECT_LINEAR", 0x2401 },
+   { "GL_OBJECT_PLANE", 0x2501 },
+   { "GL_EYE_LINEAR", 0x2400 },
+   { "GL_EYE_PLANE", 0x2502 },
+   { "GL_SPHERE_MAP", 0x2402 },
+   { "GL_DECAL", 0x2101 },
+   { "GL_MODULATE", 0x2100 },
+   { "GL_NEAREST", 0x2600 },
+   { "GL_REPEAT", 0x2901 },
+   { "GL_CLAMP", 0x2900 },
+   { "GL_S", 0x2000 },
+   { "GL_T", 0x2001 },
+   { "GL_R", 0x2002 },
+   { "GL_Q", 0x2003 },
+   { "GL_TEXTURE_GEN_R", 0x0C62 },
+   { "GL_TEXTURE_GEN_Q", 0x0C63 },
+
+   /* GL 1.1 texturing */
+   { "GL_PROXY_TEXTURE_1D", 0x8063 },
+   { "GL_PROXY_TEXTURE_2D", 0x8064 },
+   { "GL_TEXTURE_PRIORITY", 0x8066 },
+   { "GL_TEXTURE_RESIDENT", 0x8067 },
+   { "GL_TEXTURE_BINDING_1D", 0x8068 },
+   { "GL_TEXTURE_BINDING_2D", 0x8069 },
+   { "GL_TEXTURE_INTERNAL_FORMAT", 0x1003 },
+
+   /* GL 1.2 texturing */
+   { "GL_PACK_SKIP_IMAGES", 0x806B },
+   { "GL_PACK_IMAGE_HEIGHT", 0x806C },
+   { "GL_UNPACK_SKIP_IMAGES", 0x806D },
+   { "GL_UNPACK_IMAGE_HEIGHT", 0x806E },
+   { "GL_TEXTURE_3D", 0x806F },
+   { "GL_PROXY_TEXTURE_3D", 0x8070 },
+   { "GL_TEXTURE_DEPTH", 0x8071 },
+   { "GL_TEXTURE_WRAP_R", 0x8072 },
+   { "GL_MAX_3D_TEXTURE_SIZE", 0x8073 },
+   { "GL_TEXTURE_BINDING_3D", 0x806A },
+
+   /* Internal texture formats (GL 1.1) */
+   { "GL_ALPHA4", 0x803B },
+   { "GL_ALPHA8", 0x803C },
+   { "GL_ALPHA12", 0x803D },
+   { "GL_ALPHA16", 0x803E },
+   { "GL_LUMINANCE4", 0x803F },
+   { "GL_LUMINANCE8", 0x8040 },
+   { "GL_LUMINANCE12", 0x8041 },
+   { "GL_LUMINANCE16", 0x8042 },
+   { "GL_LUMINANCE4_ALPHA4", 0x8043 },
+   { "GL_LUMINANCE6_ALPHA2", 0x8044 },
+   { "GL_LUMINANCE8_ALPHA8", 0x8045 },
+   { "GL_LUMINANCE12_ALPHA4", 0x8046 },
+   { "GL_LUMINANCE12_ALPHA12", 0x8047 },
+   { "GL_LUMINANCE16_ALPHA16", 0x8048 },
+   { "GL_INTENSITY", 0x8049 },
+   { "GL_INTENSITY4", 0x804A },
+   { "GL_INTENSITY8", 0x804B },
+   { "GL_INTENSITY12", 0x804C },
+   { "GL_INTENSITY16", 0x804D },
+   { "GL_R3_G3_B2", 0x2A10 },
+   { "GL_RGB4", 0x804F },
+   { "GL_RGB5", 0x8050 },
+   { "GL_RGB8", 0x8051 },
+   { "GL_RGB10", 0x8052 },
+   { "GL_RGB12", 0x8053 },
+   { "GL_RGB16", 0x8054 },
+   { "GL_RGBA2", 0x8055 },
+   { "GL_RGBA4", 0x8056 },
+   { "GL_RGB5_A1", 0x8057 },
+   { "GL_RGBA8", 0x8058 },
+   { "GL_RGB10_A2", 0x8059 },
+   { "GL_RGBA12", 0x805A },
+   { "GL_RGBA16", 0x805B },
+
+   /* Utility */
+   { "GL_VENDOR", 0x1F00 },
+   { "GL_RENDERER", 0x1F01 },
+   { "GL_VERSION", 0x1F02 },
+   { "GL_EXTENSIONS", 0x1F03 },
+
+   /* Errors */
+   { "GL_INVALID_VALUE", 0x0501 },
+   { "GL_INVALID_ENUM", 0x0500 },
+   { "GL_INVALID_OPERATION", 0x0502 },
+   { "GL_STACK_OVERFLOW", 0x0503 },
+   { "GL_STACK_UNDERFLOW", 0x0504 },
+   { "GL_OUT_OF_MEMORY", 0x0505 },
+
+   /*
+    * Extensions
+    */
+
+   { "GL_CONSTANT_COLOR_EXT", 0x8001 },
+   { "GL_ONE_MINUS_CONSTANT_COLOR_EXT", 0x8002 },
+   { "GL_CONSTANT_ALPHA_EXT", 0x8003 },
+   { "GL_ONE_MINUS_CONSTANT_ALPHA_EXT", 0x8004 },
+   { "GL_BLEND_EQUATION_EXT", 0x8009 },
+   { "GL_MIN_EXT", 0x8007 },
+   { "GL_MAX_EXT", 0x8008 },
+   { "GL_FUNC_ADD_EXT", 0x8006 },
+   { "GL_FUNC_SUBTRACT_EXT", 0x800A },
+   { "GL_FUNC_REVERSE_SUBTRACT_EXT", 0x800B },
+   { "GL_BLEND_COLOR_EXT", 0x8005 },
+
+   { "GL_POLYGON_OFFSET_EXT", 0x8037 },
+   { "GL_POLYGON_OFFSET_FACTOR_EXT", 0x8038 },
+   { "GL_POLYGON_OFFSET_BIAS_EXT", 0x8039 },
+
+
+   { "GL_VERTEX_ARRAY_EXT", 0x8074 },
+   { "GL_NORMAL_ARRAY_EXT", 0x8075 },
+   { "GL_COLOR_ARRAY_EXT", 0x8076 },
+   { "GL_INDEX_ARRAY_EXT", 0x8077 },
+   { "GL_TEXTURE_COORD_ARRAY_EXT", 0x8078 },
+   { "GL_EDGE_FLAG_ARRAY_EXT", 0x8079 },
+   { "GL_VERTEX_ARRAY_SIZE_EXT", 0x807A },
+   { "GL_VERTEX_ARRAY_TYPE_EXT", 0x807B },
+   { "GL_VERTEX_ARRAY_STRIDE_EXT", 0x807C },
+   { "GL_VERTEX_ARRAY_COUNT_EXT", 0x807D },
+   { "GL_NORMAL_ARRAY_TYPE_EXT", 0x807E },
+   { "GL_NORMAL_ARRAY_STRIDE_EXT", 0x807F },
+   { "GL_NORMAL_ARRAY_COUNT_EXT", 0x8080 },
+   { "GL_COLOR_ARRAY_SIZE_EXT", 0x8081 },
+   { "GL_COLOR_ARRAY_TYPE_EXT", 0x8082 },
+   { "GL_COLOR_ARRAY_STRIDE_EXT", 0x8083 },
+   { "GL_COLOR_ARRAY_COUNT_EXT", 0x8084 },
+   { "GL_INDEX_ARRAY_TYPE_EXT", 0x8085 },
+   { "GL_INDEX_ARRAY_STRIDE_EXT", 0x8086 },
+   { "GL_INDEX_ARRAY_COUNT_EXT", 0x8087 },
+   { "GL_TEXTURE_COORD_ARRAY_SIZE_EXT", 0x8088 },
+   { "GL_TEXTURE_COORD_ARRAY_TYPE_EXT", 0x8089 },
+   { "GL_TEXTURE_COORD_ARRAY_STRIDE_EXT", 0x808A },
+   { "GL_TEXTURE_COORD_ARRAY_COUNT_EXT", 0x808B },
+   { "GL_EDGE_FLAG_ARRAY_STRIDE_EXT", 0x808C },
+   { "GL_EDGE_FLAG_ARRAY_COUNT_EXT", 0x808D },
+   { "GL_VERTEX_ARRAY_POINTER_EXT", 0x808E },
+   { "GL_NORMAL_ARRAY_POINTER_EXT", 0x808F },
+   { "GL_COLOR_ARRAY_POINTER_EXT", 0x8090 },
+   { "GL_INDEX_ARRAY_POINTER_EXT", 0x8091 },
+   { "GL_TEXTURE_COORD_ARRAY_POINTER_EXT", 0x8092 },
+   { "GL_EDGE_FLAG_ARRAY_POINTER_EXT", 0x8093 },
+
+   { "GL_TEXTURE_PRIORITY_EXT", 0x8066 },
+   { "GL_TEXTURE_RESIDENT_EXT", 0x8067 },
+   { "GL_TEXTURE_1D_BINDING_EXT", 0x8068 },
+   { "GL_TEXTURE_2D_BINDING_EXT", 0x8069 },
+
+   { "GL_PACK_SKIP_IMAGES_EXT", 0x806B },
+   { "GL_PACK_IMAGE_HEIGHT_EXT", 0x806C },
+   { "GL_UNPACK_SKIP_IMAGES_EXT", 0x806D },
+   { "GL_UNPACK_IMAGE_HEIGHT_EXT", 0x806E },
+   { "GL_TEXTURE_3D_EXT", 0x806F },
+   { "GL_PROXY_TEXTURE_3D_EXT", 0x8070 },
+   { "GL_TEXTURE_DEPTH_EXT", 0x8071 },
+   { "GL_TEXTURE_WRAP_R_EXT", 0x8072 },
+   { "GL_MAX_3D_TEXTURE_SIZE_EXT", 0x8073 },
+   { "GL_TEXTURE_3D_BINDING_EXT", 0x806A },
+
+   { "GL_TABLE_TOO_LARGE_EXT", 0x8031 },
+   { "GL_COLOR_TABLE_FORMAT_EXT", 0x80D8 },
+   { "GL_COLOR_TABLE_WIDTH_EXT", 0x80D9 },
+   { "GL_COLOR_TABLE_RED_SIZE_EXT", 0x80DA },
+   { "GL_COLOR_TABLE_GREEN_SIZE_EXT", 0x80DB },
+   { "GL_COLOR_TABLE_BLUE_SIZE_EXT", 0x80DC },
+   { "GL_COLOR_TABLE_ALPHA_SIZE_EXT", 0x80DD },
+   { "GL_COLOR_TABLE_LUMINANCE_SIZE_EXT", 0x80DE },
+   { "GL_COLOR_TABLE_INTENSITY_SIZE_EXT", 0x80DF },
+   { "GL_TEXTURE_INDEX_SIZE_EXT", 0x80ED },
+   { "GL_COLOR_INDEX1_EXT", 0x80E2 },
+   { "GL_COLOR_INDEX2_EXT", 0x80E3 },
+   { "GL_COLOR_INDEX4_EXT", 0x80E4 },
+   { "GL_COLOR_INDEX8_EXT", 0x80E5 },
+   { "GL_COLOR_INDEX12_EXT", 0x80E6 },
+   { "GL_COLOR_INDEX16_EXT", 0x80E7 },
+
+   { "GL_SHARED_TEXTURE_PALETTE_EXT", 0x81FB },
+
+   { "GL_POINT_SIZE_MIN_EXT", 0x8126 },
+   { "GL_POINT_SIZE_MAX_EXT", 0x8127 },
+   { "GL_POINT_FADE_THRESHOLD_SIZE_EXT", 0x8128 },
+   { "GL_DISTANCE_ATTENUATION_EXT", 0x8129 },
+
+   { "GL_RESCALE_NORMAL_EXT", 0x803A },
+
+   { "GL_ABGR_EXT", 0x8000 },
+
+   { "GL_INCR_WRAP_EXT", 0x8507 },
+   { "GL_DECR_WRAP_EXT", 0x8508 },
+
+   { "GL_CLAMP_TO_EDGE_SGIS", 0x812F },
+
+   { "GL_BLEND_DST_RGB_INGR", 0x80C8 },
+   { "GL_BLEND_SRC_RGB_INGR", 0x80C9 },
+   { "GL_BLEND_DST_ALPHA_INGR", 0x80CA },
+   { "GL_BLEND_SRC_ALPHA_INGR", 0x80CB },
+
+   { "GL_RESCALE_NORMAL", 0x803A },
+   { "GL_CLAMP_TO_EDGE", 0x812F },
+   { "GL_MAX_ELEMENTS_VERTICES", 0xF0E8 },
+   { "GL_MAX_ELEMENTS_INDICES", 0xF0E9 },
+   { "GL_BGR", 0x80E0 },
+   { "GL_BGRA", 0x80E1 },
+   { "GL_UNSIGNED_BYTE_3_3_2", 0x8032 },
+   { "GL_UNSIGNED_BYTE_2_3_3_REV", 0x8362 },
+   { "GL_UNSIGNED_SHORT_5_6_5", 0x8363 },
+   { "GL_UNSIGNED_SHORT_5_6_5_REV", 0x8364 },
+   { "GL_UNSIGNED_SHORT_4_4_4_4", 0x8033 },
+   { "GL_UNSIGNED_SHORT_4_4_4_4_REV", 0x8365 },
+   { "GL_UNSIGNED_SHORT_5_5_5_1", 0x8034 },
+   { "GL_UNSIGNED_SHORT_1_5_5_5_REV", 0x8366 },
+   { "GL_UNSIGNED_INT_8_8_8_8", 0x8035 },
+   { "GL_UNSIGNED_INT_8_8_8_8_REV", 0x8367 },
+   { "GL_UNSIGNED_INT_10_10_10_2", 0x8036 },
+   { "GL_UNSIGNED_INT_2_10_10_10_REV", 0x8368 },
+   { "GL_LIGHT_MODEL_COLOR_CONTROL", 0x81F8 },
+   { "GL_SINGLE_COLOR", 0x81F9 },
+   { "GL_SEPARATE_SPECULAR_COLOR", 0x81FA },
+   { "GL_TEXTURE_MIN_LOD", 0x813A },
+   { "GL_TEXTURE_MAX_LOD", 0x813B },
+   { "GL_TEXTURE_BASE_LEVEL", 0x813C },
+   { "GL_TEXTURE_MAX_LEVEL", 0x813D },
+
+   { "GL_TEXTURE0_ARB", 0x84C0 },
+   { "GL_TEXTURE1_ARB", 0x84C1 },
+   { "GL_TEXTURE2_ARB", 0x84C2 },
+   { "GL_TEXTURE3_ARB", 0x84C3 },
+   { "GL_ACTIVE_TEXTURE_ARB", 0x84E0 },
+   { "GL_CLIENT_ACTIVE_TEXTURE_ARB", 0x84E1 },
+   { "GL_MAX_TEXTURE_UNITS_ARB", 0x84E2 },
+
+   { "GL_NORMAL_MAP_NV", 0x8511 },
+   { "GL_REFLECTION_MAP_NV", 0x8512 },
+
+   { "GL_PREFER_DOUBLEBUFFER_HINT_PGI", 107000 },
+   { "GL_STRICT_DEPTHFUNC_HINT_PGI", 107030 },
+   { "GL_STRICT_LIGHTING_HINT_PGI", 107031 },
+   { "GL_STRICT_SCISSOR_HINT_PGI", 107032 },
+   { "GL_FULL_STIPPLE_HINT_PGI", 107033 },
+   { "GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI", 107011 },
+   { "GL_NATIVE_GRAPHICS_END_HINT_PGI", 107012 },
+   { "GL_CONSERVE_MEMORY_HINT_PGI", 107005 },
+   { "GL_RECLAIM_MEMORY_HINT_PGI", 107006 },
+   { "GL_ALWAYS_FAST_HINT_PGI", 107020 },
+   { "GL_ALWAYS_SOFT_HINT_PGI", 107021 },
+   { "GL_ALLOW_DRAW_OBJ_HINT_PGI", 107022 },
+   { "GL_ALLOW_DRAW_WIN_HINT_PGI", 107023 },
+   { "GL_ALLOW_DRAW_FRG_HINT_PGI", 107024 },
+   { "GL_ALLOW_DRAW_SPN_HINT_PGI", 107024 },
+   { "GL_ALLOW_DRAW_MEM_HINT_PGI", 107025 },
+   { "GL_CLIP_NEAR_HINT_PGI", 107040 },
+   { "GL_CLIP_FAR_HINT_PGI", 107041 },
+   { "GL_WIDE_LINE_HINT_PGI", 107042 },
+   { "GL_BACK_NORMALS_HINT_PGI", 107043 },
+   { "GL_NATIVE_GRAPHICS_HANDLE_PGI", 107010 },
+
+   /* GL_EXT_compiled_vertex_array */
+   { "GL_ARRAY_ELEMENT_LOCK_FIRST_SGI", 0x81A8},
+   { "GL_ARRAY_ELEMENT_LOCK_COUNT_SGI", 0x81A9},
+
+   /* GL_EXT_clip_volume_hint */
+   { "GL_CLIP_VOLUME_CLIPPING_HINT_EXT", 0x80F0}
+
+};
+
+#define Elements(x) sizeof(x)/sizeof(*x)
+
+typedef int (GLWINAPIV *cfunc)(const void *, const void *);
+
+static enum_elt **index1 = 0;
+static int sorted = 0;
+
+static int compar_name( const enum_elt *a, const enum_elt *b ) 
+{
+   return strcmp(a->c, b->c);
+}
+
+
+/* note the extra level of indirection
+ */
+static int compar_nr( const enum_elt **a, const enum_elt **b ) 
+{
+   return (*a)->n - (*b)->n;
+}
+
+
+static void sort_enums( void )
+{
+   int i;
+   index1 = (enum_elt **)malloc( Elements(all_enums) * sizeof(enum_elt *) );
+   sorted = 1;
+
+   qsort( all_enums, Elements(all_enums), sizeof(*all_enums), 
+         (cfunc) compar_name );
+
+   for (i = 0 ; i < Elements(all_enums) ; i++) 
+      index1[i] = &all_enums[i];
+
+   qsort( index1, Elements(all_enums), sizeof(*index1), (cfunc) compar_nr );
+}
+
+
+
+int gl_lookup_enum_by_name( const char *symbol )
+{
+   enum_elt tmp;
+   enum_elt *e;
+
+   if (!sorted) 
+      sort_enums();
+
+   if (!symbol) 
+      return 0;
+
+   tmp.c = symbol;
+   e = (enum_elt *)bsearch( &tmp, all_enums, Elements(all_enums), 
+                           sizeof(*all_enums), (cfunc) compar_name );
+
+   return e ? e->n : -1;
+}
+
+
+const char *gl_lookup_enum_by_nr( int nr )
+{
+   enum_elt tmp, *e, **f;
+
+   if (!sorted) 
+      sort_enums();
+
+   tmp.n = nr;
+   e = &tmp;
+
+   f = (enum_elt **)bsearch( &e, index1, Elements(all_enums), 
+                            sizeof(*index1), (cfunc) compar_nr );
+
+   return f ? (*f)->c : "(unknown)";
+}
+
+
+#if 0
+int main()
+{
+   int i;
+   static const char *test[] = {
+      "GL_POLYGON",
+      "GL_TRUE",
+      "GL_BANANA",
+      "GL_REFLECTION_MAP_NV",
+   };
+
+   for (i = 0 ; i < Elements(test) ; i++) {
+      int d = gl_lookup_enum_by_name( test[i] );
+      printf("%s --> %d --> %s\n", test[i], d, gl_lookup_enum_by_nr( d ));
+   }       
+}
+#endif
diff --git a/src/mesa/main/enums.h b/src/mesa/main/enums.h
new file mode 100644 (file)
index 0000000..028c9b4
--- /dev/null
@@ -0,0 +1,34 @@
+/* $Id: enums.h,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef _ENUMS_H_
+#define _ENUMS_H_
+
+extern const char *gl_lookup_enum_by_nr( int nr );
+extern int gl_lookup_enum_by_name( const char *symbol );
+
+#endif
diff --git a/src/mesa/main/eval.c b/src/mesa/main/eval.c
new file mode 100644 (file)
index 0000000..74604a2
--- /dev/null
@@ -0,0 +1,2725 @@
+/* $Id: eval.c,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+/*
+ * eval.c was written by
+ * Bernd Barsuhn (bdbarsuh@cip.informatik.uni-erlangen.de) and
+ * Volker Weiss (vrweiss@cip.informatik.uni-erlangen.de).
+ *
+ * My original implementation of evaluators was simplistic and didn't
+ * compute surface normal vectors properly.  Bernd and Volker applied
+ * used more sophisticated methods to get better results.
+ *
+ * Thanks guys!
+ */
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include "context.h"
+#include "eval.h"
+#include "macros.h"
+#include "mmath.h"
+#include "types.h"
+#include "vbcull.h"
+#include "vbfill.h"
+#include "vbxform.h"
+#ifdef XFree86Server
+#include "GL/xf86glx.h"
+#endif
+#endif
+
+
+static GLfloat inv_tab[MAX_EVAL_ORDER];
+
+/*
+ * Do one-time initialization for evaluators.
+ */
+void gl_init_eval( void )
+{
+  static int init_flag = 0;
+  GLuint i;
+
+  /* Compute a table of nCr (combination) values used by the
+   * Bernstein polynomial generator.
+   */
+
+  /* KW: precompute 1/x for useful x.
+   */
+  if (init_flag==0) 
+  { 
+     for (i = 1 ; i < MAX_EVAL_ORDER ; i++)
+       inv_tab[i] = 1.0 / i;
+  }
+
+  init_flag = 1;
+}
+
+
+
+/*
+ * Horner scheme for Bezier curves
+ * 
+ * Bezier curves can be computed via a Horner scheme.
+ * Horner is numerically less stable than the de Casteljau
+ * algorithm, but it is faster. For curves of degree n 
+ * the complexity of Horner is O(n) and de Casteljau is O(n^2).
+ * Since stability is not important for displaying curve 
+ * points I decided to use the Horner scheme.
+ *
+ * A cubic Bezier curve with control points b0, b1, b2, b3 can be 
+ * written as
+ *
+ *        (([3]        [3]     )     [3]       )     [3]
+ * c(t) = (([0]*s*b0 + [1]*t*b1)*s + [2]*t^2*b2)*s + [3]*t^2*b3
+ *
+ *                                           [n]
+ * where s=1-t and the binomial coefficients [i]. These can 
+ * be computed iteratively using the identity:
+ *
+ * [n]               [n  ]             [n]
+ * [i] = (n-i+1)/i * [i-1]     and     [0] = 1
+ */
+
+
+static void
+horner_bezier_curve(const GLfloat *cp, GLfloat *out, GLfloat t,
+                    GLuint dim, GLuint order)
+{
+  GLfloat s, powert;
+  GLuint i, k, bincoeff;
+
+  if(order >= 2)
+  { 
+    bincoeff = order-1;
+    s = 1.0-t;
+
+    for(k=0; k<dim; k++)
+      out[k] = s*cp[k] + bincoeff*t*cp[dim+k];
+
+    for(i=2, cp+=2*dim, powert=t*t; i<order; i++, powert*=t, cp +=dim)
+    {
+      bincoeff *= order-i;
+      bincoeff *= inv_tab[i];
+
+      for(k=0; k<dim; k++)
+        out[k] = s*out[k] + bincoeff*powert*cp[k];
+    }
+  }
+  else /* order=1 -> constant curve */
+  { 
+    for(k=0; k<dim; k++)
+      out[k] = cp[k];
+  } 
+}
+
+/*
+ * Tensor product Bezier surfaces
+ *
+ * Again the Horner scheme is used to compute a point on a 
+ * TP Bezier surface. First a control polygon for a curve
+ * on the surface in one parameter direction is computed,
+ * then the point on the curve for the other parameter 
+ * direction is evaluated.
+ *
+ * To store the curve control polygon additional storage
+ * for max(uorder,vorder) points is needed in the 
+ * control net cn.
+ */
+
+static void
+horner_bezier_surf(GLfloat *cn, GLfloat *out, GLfloat u, GLfloat v,
+                   GLuint dim, GLuint uorder, GLuint vorder)
+{
+  GLfloat *cp = cn + uorder*vorder*dim;
+  GLuint i, uinc = vorder*dim;
+
+  if(vorder > uorder)
+  {
+    if(uorder >= 2)
+    { 
+      GLfloat s, poweru;
+      GLuint j, k, bincoeff;
+
+      /* Compute the control polygon for the surface-curve in u-direction */
+      for(j=0; j<vorder; j++)
+      {
+        GLfloat *ucp = &cn[j*dim];
+
+        /* Each control point is the point for parameter u on a */ 
+        /* curve defined by the control polygons in u-direction */
+       bincoeff = uorder-1;
+       s = 1.0-u;
+
+       for(k=0; k<dim; k++)
+         cp[j*dim+k] = s*ucp[k] + bincoeff*u*ucp[uinc+k];
+
+       for(i=2, ucp+=2*uinc, poweru=u*u; i<uorder; 
+            i++, poweru*=u, ucp +=uinc)
+       {
+         bincoeff *= uorder-i;
+          bincoeff *= inv_tab[i];
+
+         for(k=0; k<dim; k++)
+           cp[j*dim+k] = s*cp[j*dim+k] + bincoeff*poweru*ucp[k];
+       }
+      }
+        
+      /* Evaluate curve point in v */
+      horner_bezier_curve(cp, out, v, dim, vorder);
+    }
+    else /* uorder=1 -> cn defines a curve in v */
+      horner_bezier_curve(cn, out, v, dim, vorder);
+  }
+  else /* vorder <= uorder */
+  {
+    if(vorder > 1)
+    {
+      GLuint i;
+
+      /* Compute the control polygon for the surface-curve in u-direction */
+      for(i=0; i<uorder; i++, cn += uinc)
+      {
+       /* For constant i all cn[i][j] (j=0..vorder) are located */
+       /* on consecutive memory locations, so we can use        */
+       /* horner_bezier_curve to compute the control points     */
+
+       horner_bezier_curve(cn, &cp[i*dim], v, dim, vorder);
+      }
+
+      /* Evaluate curve point in u */
+      horner_bezier_curve(cp, out, u, dim, uorder);
+    }
+    else  /* vorder=1 -> cn defines a curve in u */
+      horner_bezier_curve(cn, out, u, dim, uorder);
+  }
+}
+
+/*
+ * The direct de Casteljau algorithm is used when a point on the
+ * surface and the tangent directions spanning the tangent plane
+ * should be computed (this is needed to compute normals to the
+ * surface). In this case the de Casteljau algorithm approach is
+ * nicer because a point and the partial derivatives can be computed 
+ * at the same time. To get the correct tangent length du and dv
+ * must be multiplied with the (u2-u1)/uorder-1 and (v2-v1)/vorder-1. 
+ * Since only the directions are needed, this scaling step is omitted.
+ *
+ * De Casteljau needs additional storage for uorder*vorder
+ * values in the control net cn.
+ */
+
+static void
+de_casteljau_surf(GLfloat *cn, GLfloat *out, GLfloat *du, GLfloat *dv,
+                  GLfloat u, GLfloat v, GLuint dim, 
+                  GLuint uorder, GLuint vorder)
+{
+  GLfloat *dcn = cn + uorder*vorder*dim;
+  GLfloat us = 1.0-u, vs = 1.0-v;
+  GLuint h, i, j, k;
+  GLuint minorder = uorder < vorder ? uorder : vorder;
+  GLuint uinc = vorder*dim;
+  GLuint dcuinc = vorder;
+  /* Each component is evaluated separately to save buffer space  */
+  /* This does not drasticaly decrease the performance of the     */
+  /* algorithm. If additional storage for (uorder-1)*(vorder-1)   */
+  /* points would be available, the components could be accessed  */
+  /* in the innermost loop which could lead to less cache misses. */
+
+#define CN(I,J,K) cn[(I)*uinc+(J)*dim+(K)] 
+#define DCN(I, J) dcn[(I)*dcuinc+(J)]
+  if(minorder < 3)
+  {
+    if(uorder==vorder)
+    {
+      for(k=0; k<dim; k++)
+      {
+       /* Derivative direction in u */
+       du[k] = vs*(CN(1,0,k) - CN(0,0,k)) +
+                v*(CN(1,1,k) - CN(0,1,k));
+
+       /* Derivative direction in v */
+       dv[k] = us*(CN(0,1,k) - CN(0,0,k)) + 
+                u*(CN(1,1,k) - CN(1,0,k));
+
+       /* bilinear de Casteljau step */
+        out[k] =  us*(vs*CN(0,0,k) + v*CN(0,1,k)) +
+                  u*(vs*CN(1,0,k) + v*CN(1,1,k));
+      }
+    }
+    else if(minorder == uorder)
+    {
+      for(k=0; k<dim; k++)
+      {
+       /* bilinear de Casteljau step */
+       DCN(1,0) =    CN(1,0,k) -   CN(0,0,k);
+       DCN(0,0) = us*CN(0,0,k) + u*CN(1,0,k);
+
+       for(j=0; j<vorder-1; j++)
+       {
+         /* for the derivative in u */
+         DCN(1,j+1) =    CN(1,j+1,k) -   CN(0,j+1,k);
+         DCN(1,j)   = vs*DCN(1,j)    + v*DCN(1,j+1);
+
+         /* for the `point' */
+         DCN(0,j+1) = us*CN(0,j+1,k) + u*CN(1,j+1,k);
+         DCN(0,j)   = vs*DCN(0,j)    + v*DCN(0,j+1);
+       }
+        
+       /* remaining linear de Casteljau steps until the second last step */
+       for(h=minorder; h<vorder-1; h++)
+         for(j=0; j<vorder-h; j++)
+         {
+           /* for the derivative in u */
+           DCN(1,j) = vs*DCN(1,j) + v*DCN(1,j+1);
+
+           /* for the `point' */
+           DCN(0,j) = vs*DCN(0,j) + v*DCN(0,j+1);
+         }
+
+       /* derivative direction in v */
+       dv[k] = DCN(0,1) - DCN(0,0);
+
+       /* derivative direction in u */
+       du[k] =   vs*DCN(1,0) + v*DCN(1,1);
+
+       /* last linear de Casteljau step */
+       out[k] =  vs*DCN(0,0) + v*DCN(0,1);
+      }
+    }
+    else /* minorder == vorder */
+    {
+      for(k=0; k<dim; k++)
+      {
+       /* bilinear de Casteljau step */
+       DCN(0,1) =    CN(0,1,k) -   CN(0,0,k);
+       DCN(0,0) = vs*CN(0,0,k) + v*CN(0,1,k);
+       for(i=0; i<uorder-1; i++)
+       {
+         /* for the derivative in v */
+         DCN(i+1,1) =    CN(i+1,1,k) -   CN(i+1,0,k);
+         DCN(i,1)   = us*DCN(i,1)    + u*DCN(i+1,1);
+
+         /* for the `point' */
+         DCN(i+1,0) = vs*CN(i+1,0,k) + v*CN(i+1,1,k);
+         DCN(i,0)   = us*DCN(i,0)    + u*DCN(i+1,0);
+       }
+        
+       /* remaining linear de Casteljau steps until the second last step */
+       for(h=minorder; h<uorder-1; h++)
+         for(i=0; i<uorder-h; i++)
+         {
+           /* for the derivative in v */
+           DCN(i,1) = us*DCN(i,1) + u*DCN(i+1,1);
+
+           /* for the `point' */
+           DCN(i,0) = us*DCN(i,0) + u*DCN(i+1,0);
+         }
+
+       /* derivative direction in u */
+       du[k] = DCN(1,0) - DCN(0,0);
+
+       /* derivative direction in v */
+       dv[k] =   us*DCN(0,1) + u*DCN(1,1);
+
+       /* last linear de Casteljau step */
+       out[k] =  us*DCN(0,0) + u*DCN(1,0);
+      }
+    }
+  }
+  else if(uorder == vorder)
+  {
+    for(k=0; k<dim; k++)
+    {
+      /* first bilinear de Casteljau step */
+      for(i=0; i<uorder-1; i++)
+      {
+       DCN(i,0) = us*CN(i,0,k) + u*CN(i+1,0,k);
+       for(j=0; j<vorder-1; j++)
+       {
+         DCN(i,j+1) = us*CN(i,j+1,k) + u*CN(i+1,j+1,k);
+         DCN(i,j)   = vs*DCN(i,j)    + v*DCN(i,j+1);
+       }
+      }
+
+      /* remaining bilinear de Casteljau steps until the second last step */
+      for(h=2; h<minorder-1; h++)
+       for(i=0; i<uorder-h; i++)
+       {
+         DCN(i,0) = us*DCN(i,0) + u*DCN(i+1,0);
+         for(j=0; j<vorder-h; j++)
+         {
+           DCN(i,j+1) = us*DCN(i,j+1) + u*DCN(i+1,j+1);
+           DCN(i,j)   = vs*DCN(i,j)   + v*DCN(i,j+1);
+         }
+       }
+
+      /* derivative direction in u */
+      du[k] = vs*(DCN(1,0) - DCN(0,0)) +
+              v*(DCN(1,1) - DCN(0,1));
+
+      /* derivative direction in v */
+      dv[k] = us*(DCN(0,1) - DCN(0,0)) + 
+              u*(DCN(1,1) - DCN(1,0));
+
+      /* last bilinear de Casteljau step */
+      out[k] =  us*(vs*DCN(0,0) + v*DCN(0,1)) +
+                u*(vs*DCN(1,0) + v*DCN(1,1));
+    }
+  }
+  else if(minorder == uorder)
+  {
+    for(k=0; k<dim; k++)
+    {
+      /* first bilinear de Casteljau step */
+      for(i=0; i<uorder-1; i++)
+      {
+       DCN(i,0) = us*CN(i,0,k) + u*CN(i+1,0,k);
+       for(j=0; j<vorder-1; j++)
+       {
+         DCN(i,j+1) = us*CN(i,j+1,k) + u*CN(i+1,j+1,k);
+         DCN(i,j)   = vs*DCN(i,j)    + v*DCN(i,j+1);
+       }
+      }
+
+      /* remaining bilinear de Casteljau steps until the second last step */
+      for(h=2; h<minorder-1; h++)
+       for(i=0; i<uorder-h; i++)
+       {
+         DCN(i,0) = us*DCN(i,0) + u*DCN(i+1,0);
+         for(j=0; j<vorder-h; j++)
+         {
+           DCN(i,j+1) = us*DCN(i,j+1) + u*DCN(i+1,j+1);
+           DCN(i,j)   = vs*DCN(i,j)   + v*DCN(i,j+1);
+         }
+       }
+
+      /* last bilinear de Casteljau step */
+      DCN(2,0) =    DCN(1,0) -   DCN(0,0);
+      DCN(0,0) = us*DCN(0,0) + u*DCN(1,0);
+      for(j=0; j<vorder-1; j++)
+      {
+       /* for the derivative in u */
+       DCN(2,j+1) =    DCN(1,j+1) -    DCN(0,j+1);
+       DCN(2,j)   = vs*DCN(2,j)    + v*DCN(2,j+1);
+       
+       /* for the `point' */
+       DCN(0,j+1) = us*DCN(0,j+1 ) + u*DCN(1,j+1);
+       DCN(0,j)   = vs*DCN(0,j)    + v*DCN(0,j+1);
+      }
+        
+      /* remaining linear de Casteljau steps until the second last step */
+      for(h=minorder; h<vorder-1; h++)
+       for(j=0; j<vorder-h; j++)
+       {
+         /* for the derivative in u */
+         DCN(2,j) = vs*DCN(2,j) + v*DCN(2,j+1);
+         
+         /* for the `point' */
+         DCN(0,j) = vs*DCN(0,j) + v*DCN(0,j+1);
+       }
+      
+      /* derivative direction in v */
+      dv[k] = DCN(0,1) - DCN(0,0);
+      
+      /* derivative direction in u */
+      du[k] =   vs*DCN(2,0) + v*DCN(2,1);
+      
+      /* last linear de Casteljau step */
+      out[k] =  vs*DCN(0,0) + v*DCN(0,1);
+    }
+  }
+  else /* minorder == vorder */
+  {
+    for(k=0; k<dim; k++)
+    {
+      /* first bilinear de Casteljau step */
+      for(i=0; i<uorder-1; i++)
+      {
+       DCN(i,0) = us*CN(i,0,k) + u*CN(i+1,0,k);
+       for(j=0; j<vorder-1; j++)
+       {
+         DCN(i,j+1) = us*CN(i,j+1,k) + u*CN(i+1,j+1,k);
+         DCN(i,j)   = vs*DCN(i,j)    + v*DCN(i,j+1);
+       }
+      }
+
+      /* remaining bilinear de Casteljau steps until the second last step */
+      for(h=2; h<minorder-1; h++)
+       for(i=0; i<uorder-h; i++)
+       {
+         DCN(i,0) = us*DCN(i,0) + u*DCN(i+1,0);
+         for(j=0; j<vorder-h; j++)
+         {
+           DCN(i,j+1) = us*DCN(i,j+1) + u*DCN(i+1,j+1);
+           DCN(i,j)   = vs*DCN(i,j)   + v*DCN(i,j+1);
+         }
+       }
+
+      /* last bilinear de Casteljau step */
+      DCN(0,2) =    DCN(0,1) -   DCN(0,0);
+      DCN(0,0) = vs*DCN(0,0) + v*DCN(0,1);
+      for(i=0; i<uorder-1; i++)
+      {
+       /* for the derivative in v */
+       DCN(i+1,2) =    DCN(i+1,1)  -   DCN(i+1,0);
+       DCN(i,2)   = us*DCN(i,2)    + u*DCN(i+1,2);
+       
+       /* for the `point' */
+       DCN(i+1,0) = vs*DCN(i+1,0)  + v*DCN(i+1,1);
+       DCN(i,0)   = us*DCN(i,0)    + u*DCN(i+1,0);
+      }
+      
+      /* remaining linear de Casteljau steps until the second last step */
+      for(h=minorder; h<uorder-1; h++)
+       for(i=0; i<uorder-h; i++)
+       {
+         /* for the derivative in v */
+         DCN(i,2) = us*DCN(i,2) + u*DCN(i+1,2);
+         
+         /* for the `point' */
+         DCN(i,0) = us*DCN(i,0) + u*DCN(i+1,0);
+       }
+      
+      /* derivative direction in u */
+      du[k] = DCN(1,0) - DCN(0,0);
+      
+      /* derivative direction in v */
+      dv[k] =   us*DCN(0,2) + u*DCN(1,2);
+      
+      /* last linear de Casteljau step */
+      out[k] =  us*DCN(0,0) + u*DCN(1,0);
+    }
+  }
+#undef DCN
+#undef CN
+}
+
+/*
+ * Return the number of components per control point for any type of
+ * evaluator.  Return 0 if bad target.
+ */
+
+static GLint components( GLenum target )
+{
+   switch (target) {
+      case GL_MAP1_VERTEX_3:           return 3;
+      case GL_MAP1_VERTEX_4:           return 4;
+      case GL_MAP1_INDEX:              return 1;
+      case GL_MAP1_COLOR_4:            return 4;
+      case GL_MAP1_NORMAL:             return 3;
+      case GL_MAP1_TEXTURE_COORD_1:    return 1;
+      case GL_MAP1_TEXTURE_COORD_2:    return 2;
+      case GL_MAP1_TEXTURE_COORD_3:    return 3;
+      case GL_MAP1_TEXTURE_COORD_4:    return 4;
+      case GL_MAP2_VERTEX_3:           return 3;
+      case GL_MAP2_VERTEX_4:           return 4;
+      case GL_MAP2_INDEX:              return 1;
+      case GL_MAP2_COLOR_4:            return 4;
+      case GL_MAP2_NORMAL:             return 3;
+      case GL_MAP2_TEXTURE_COORD_1:    return 1;
+      case GL_MAP2_TEXTURE_COORD_2:    return 2;
+      case GL_MAP2_TEXTURE_COORD_3:    return 3;
+      case GL_MAP2_TEXTURE_COORD_4:    return 4;
+      default:                         return 0;
+   }
+}
+
+
+/**********************************************************************/
+/***            Copy and deallocate control points                  ***/
+/**********************************************************************/
+
+
+/*
+ * Copy 1-parametric evaluator control points from user-specified 
+ * memory space to a buffer of contiguous control points.
+ * Input:  see glMap1f for details
+ * Return:  pointer to buffer of contiguous control points or NULL if out
+ *          of memory.
+ */
+GLfloat *gl_copy_map_points1f( GLenum target,
+                               GLint ustride, GLint uorder,
+                               const GLfloat *points )
+{
+   GLfloat *buffer, *p;
+   GLint i, k, size = components(target);
+
+   if (!points || size==0) {
+      return NULL;
+   }
+
+   buffer = (GLfloat *) malloc(uorder * size * sizeof(GLfloat));
+
+   if(buffer) 
+      for(i=0, p=buffer; i<uorder; i++, points+=ustride)
+       for(k=0; k<size; k++)
+         *p++ = points[k];
+
+   return buffer;
+}
+
+
+
+/*
+ * Same as above but convert doubles to floats.
+ */
+GLfloat *gl_copy_map_points1d( GLenum target,
+                               GLint ustride, GLint uorder,
+                               const GLdouble *points )
+{
+   GLfloat *buffer, *p;
+   GLint i, k, size = components(target);
+
+   if (!points || size==0) {
+      return NULL;
+   }
+
+   buffer = (GLfloat *) malloc(uorder * size * sizeof(GLfloat));
+
+   if(buffer)
+      for(i=0, p=buffer; i<uorder; i++, points+=ustride)
+       for(k=0; k<size; k++)
+         *p++ = (GLfloat) points[k];
+
+   return buffer;
+}
+
+
+
+/*
+ * Copy 2-parametric evaluator control points from user-specified 
+ * memory space to a buffer of contiguous control points.
+ * Additional memory is allocated to be used by the horner and
+ * de Casteljau evaluation schemes.
+ *
+ * Input:  see glMap2f for details
+ * Return:  pointer to buffer of contiguous control points or NULL if out
+ *          of memory.
+ */
+GLfloat *gl_copy_map_points2f( GLenum target,
+                               GLint ustride, GLint uorder,
+                               GLint vstride, GLint vorder,
+                               const GLfloat *points )
+{
+   GLfloat *buffer, *p;
+   GLint i, j, k, size, dsize, hsize;
+   GLint uinc;
+
+   size = components(target);
+
+   if (!points || size==0) {
+      return NULL;
+   }
+
+   /* max(uorder, vorder) additional points are used in      */
+   /* horner evaluation and uorder*vorder additional */
+   /* values are needed for de Casteljau                     */
+   dsize = (uorder == 2 && vorder == 2)? 0 : uorder*vorder;
+   hsize = (uorder > vorder ? uorder : vorder)*size;
+
+   if(hsize>dsize)
+     buffer = (GLfloat *) malloc((uorder*vorder*size+hsize)*sizeof(GLfloat));
+   else
+     buffer = (GLfloat *) malloc((uorder*vorder*size+dsize)*sizeof(GLfloat));
+
+   /* compute the increment value for the u-loop */
+   uinc = ustride - vorder*vstride;
+
+   if (buffer) 
+      for (i=0, p=buffer; i<uorder; i++, points += uinc)
+        for (j=0; j<vorder; j++, points += vstride)
+           for (k=0; k<size; k++)
+              *p++ = points[k];
+
+   return buffer;
+}
+
+
+
+/*
+ * Same as above but convert doubles to floats.
+ */
+GLfloat *gl_copy_map_points2d(GLenum target,
+                              GLint ustride, GLint uorder,
+                              GLint vstride, GLint vorder,
+                              const GLdouble *points )
+{
+   GLfloat *buffer, *p;
+   GLint i, j, k, size, hsize, dsize;
+   GLint uinc;
+
+   size = components(target);
+
+   if (!points || size==0) {
+      return NULL;
+   }
+
+   /* max(uorder, vorder) additional points are used in      */
+   /* horner evaluation and uorder*vorder additional */
+   /* values are needed for de Casteljau                     */
+   dsize = (uorder == 2 && vorder == 2)? 0 : uorder*vorder;
+   hsize = (uorder > vorder ? uorder : vorder)*size;
+
+   if(hsize>dsize)
+     buffer = (GLfloat *) malloc((uorder*vorder*size+hsize)*sizeof(GLfloat));
+   else
+     buffer = (GLfloat *) malloc((uorder*vorder*size+dsize)*sizeof(GLfloat));
+
+   /* compute the increment value for the u-loop */
+   uinc = ustride - vorder*vstride;
+
+   if (buffer) 
+      for (i=0, p=buffer; i<uorder; i++, points += uinc)
+        for (j=0; j<vorder; j++, points += vstride)
+           for (k=0; k<size; k++)
+              *p++ = (GLfloat) points[k];
+
+   return buffer;
+}
+
+
+/*
+ * This function is called by the display list deallocator function to
+ * specify that a given set of control points are no longer needed.
+ */
+void gl_free_control_points( GLcontext* ctx, GLenum target, GLfloat *data )
+{
+   struct gl_1d_map *map1 = NULL;
+   struct gl_2d_map *map2 = NULL;
+
+   switch (target) {
+      case GL_MAP1_VERTEX_3:
+         map1 = &ctx->EvalMap.Map1Vertex3;
+         break;
+      case GL_MAP1_VERTEX_4:
+         map1 = &ctx->EvalMap.Map1Vertex4;
+        break;
+      case GL_MAP1_INDEX:
+         map1 = &ctx->EvalMap.Map1Index;
+         break;
+      case GL_MAP1_COLOR_4:
+         map1 = &ctx->EvalMap.Map1Color4;
+         break;
+      case GL_MAP1_NORMAL:
+         map1 = &ctx->EvalMap.Map1Normal;
+        break;
+      case GL_MAP1_TEXTURE_COORD_1:
+         map1 = &ctx->EvalMap.Map1Texture1;
+        break;
+      case GL_MAP1_TEXTURE_COORD_2:
+         map1 = &ctx->EvalMap.Map1Texture2;
+        break;
+      case GL_MAP1_TEXTURE_COORD_3:
+         map1 = &ctx->EvalMap.Map1Texture3;
+        break;
+      case GL_MAP1_TEXTURE_COORD_4:
+         map1 = &ctx->EvalMap.Map1Texture4;
+        break;
+      case GL_MAP2_VERTEX_3:
+         map2 = &ctx->EvalMap.Map2Vertex3;
+        break;
+      case GL_MAP2_VERTEX_4:
+         map2 = &ctx->EvalMap.Map2Vertex4;
+        break;
+      case GL_MAP2_INDEX:
+         map2 = &ctx->EvalMap.Map2Index;
+        break;
+      case GL_MAP2_COLOR_4:
+         map2 = &ctx->EvalMap.Map2Color4;
+         break;
+      case GL_MAP2_NORMAL:
+         map2 = &ctx->EvalMap.Map2Normal;
+        break;
+      case GL_MAP2_TEXTURE_COORD_1:
+         map2 = &ctx->EvalMap.Map2Texture1;
+        break;
+      case GL_MAP2_TEXTURE_COORD_2:
+         map2 = &ctx->EvalMap.Map2Texture2;
+        break;
+      case GL_MAP2_TEXTURE_COORD_3:
+         map2 = &ctx->EvalMap.Map2Texture3;
+        break;
+      case GL_MAP2_TEXTURE_COORD_4:
+         map2 = &ctx->EvalMap.Map2Texture4;
+        break;
+      default:
+        gl_error( ctx, GL_INVALID_ENUM, "gl_free_control_points" );
+         return;
+   }
+
+   if (map1) {
+      if (data==map1->Points) {
+         /* The control points in the display list are currently */
+         /* being used so we can mark them as discard-able. */
+         map1->Retain = GL_FALSE;
+      }
+      else {
+         /* The control points in the display list are not currently */
+         /* being used. */
+         free( data );
+      }
+   }
+   if (map2) {
+      if (data==map2->Points) {
+         /* The control points in the display list are currently */
+         /* being used so we can mark them as discard-able. */
+         map2->Retain = GL_FALSE;
+      }
+      else {
+         /* The control points in the display list are not currently */
+         /* being used. */
+         free( data );
+      }
+   }
+
+}
+
+
+
+/**********************************************************************/
+/***                      API entry points                          ***/
+/**********************************************************************/
+
+
+/*
+ * Note that the array of control points must be 'unpacked' at this time.
+ * Input:  retain - if TRUE, this control point data is also in a display
+ *                  list and can't be freed until the list is freed.
+ */
+void gl_Map1f( GLcontext* ctx, GLenum target,
+               GLfloat u1, GLfloat u2, GLint stride,
+               GLint order, const GLfloat *points, GLboolean retain )
+{
+   GLint k;
+
+   if (!points) {
+      gl_error( ctx, GL_OUT_OF_MEMORY, "glMap1f" );
+      return;
+   }
+
+   /* may be a new stride after copying control points */
+   stride = components( target );
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glMap1");
+
+   if (u1==u2) {
+      gl_error( ctx, GL_INVALID_VALUE, "glMap1(u1,u2)" );
+      return;
+   }
+
+   if (order<1 || order>MAX_EVAL_ORDER) {
+      gl_error( ctx, GL_INVALID_VALUE, "glMap1(order)" );
+      return;
+   }
+
+   k = components( target );
+   if (k==0) {
+      gl_error( ctx, GL_INVALID_ENUM, "glMap1(target)" );
+   }
+
+   if (stride < k) {
+      gl_error( ctx, GL_INVALID_VALUE, "glMap1(stride)" );
+      return;
+   }
+
+   switch (target) {
+      case GL_MAP1_VERTEX_3:
+         ctx->EvalMap.Map1Vertex3.Order = order;
+        ctx->EvalMap.Map1Vertex3.u1 = u1;
+        ctx->EvalMap.Map1Vertex3.u2 = u2;
+        ctx->EvalMap.Map1Vertex3.du = 1.0 / (u2 - u1);
+        if (ctx->EvalMap.Map1Vertex3.Points
+             && !ctx->EvalMap.Map1Vertex3.Retain) {
+           free( ctx->EvalMap.Map1Vertex3.Points );
+        }
+        ctx->EvalMap.Map1Vertex3.Points = (GLfloat *) points;
+         ctx->EvalMap.Map1Vertex3.Retain = retain;
+        break;
+      case GL_MAP1_VERTEX_4:
+         ctx->EvalMap.Map1Vertex4.Order = order;
+        ctx->EvalMap.Map1Vertex4.u1 = u1;
+        ctx->EvalMap.Map1Vertex4.u2 = u2;
+        ctx->EvalMap.Map1Vertex4.du = 1.0 / (u2 - u1);
+        if (ctx->EvalMap.Map1Vertex4.Points
+             && !ctx->EvalMap.Map1Vertex4.Retain) {
+           free( ctx->EvalMap.Map1Vertex4.Points );
+        }
+        ctx->EvalMap.Map1Vertex4.Points = (GLfloat *) points;
+        ctx->EvalMap.Map1Vertex4.Retain = retain;
+        break;
+      case GL_MAP1_INDEX:
+         ctx->EvalMap.Map1Index.Order = order;
+        ctx->EvalMap.Map1Index.u1 = u1;
+        ctx->EvalMap.Map1Index.u2 = u2;
+        ctx->EvalMap.Map1Index.du = 1.0 / (u2 - u1);
+        if (ctx->EvalMap.Map1Index.Points
+             && !ctx->EvalMap.Map1Index.Retain) {
+           free( ctx->EvalMap.Map1Index.Points );
+        }
+        ctx->EvalMap.Map1Index.Points = (GLfloat *) points;
+        ctx->EvalMap.Map1Index.Retain = retain;
+        break;
+      case GL_MAP1_COLOR_4:
+         ctx->EvalMap.Map1Color4.Order = order;
+        ctx->EvalMap.Map1Color4.u1 = u1;
+        ctx->EvalMap.Map1Color4.u2 = u2;
+        ctx->EvalMap.Map1Color4.du = 1.0 / (u2 - u1);
+        if (ctx->EvalMap.Map1Color4.Points
+             && !ctx->EvalMap.Map1Color4.Retain) {
+           free( ctx->EvalMap.Map1Color4.Points );
+        }
+        ctx->EvalMap.Map1Color4.Points = (GLfloat *) points;
+        ctx->EvalMap.Map1Color4.Retain = retain;
+        break;
+      case GL_MAP1_NORMAL:
+         ctx->EvalMap.Map1Normal.Order = order;
+        ctx->EvalMap.Map1Normal.u1 = u1;
+        ctx->EvalMap.Map1Normal.u2 = u2;
+        ctx->EvalMap.Map1Normal.du = 1.0 / (u2 - u1);
+        if (ctx->EvalMap.Map1Normal.Points
+             && !ctx->EvalMap.Map1Normal.Retain) {
+           free( ctx->EvalMap.Map1Normal.Points );
+        }
+        ctx->EvalMap.Map1Normal.Points = (GLfloat *) points;
+        ctx->EvalMap.Map1Normal.Retain = retain;
+        break;
+      case GL_MAP1_TEXTURE_COORD_1:
+         ctx->EvalMap.Map1Texture1.Order = order;
+        ctx->EvalMap.Map1Texture1.u1 = u1;
+        ctx->EvalMap.Map1Texture1.u2 = u2;
+        ctx->EvalMap.Map1Texture1.du = 1.0 / (u2 - u1);
+        if (ctx->EvalMap.Map1Texture1.Points
+             && !ctx->EvalMap.Map1Texture1.Retain) {
+           free( ctx->EvalMap.Map1Texture1.Points );
+        }
+        ctx->EvalMap.Map1Texture1.Points = (GLfloat *) points;
+        ctx->EvalMap.Map1Texture1.Retain = retain;
+        break;
+      case GL_MAP1_TEXTURE_COORD_2:
+         ctx->EvalMap.Map1Texture2.Order = order;
+        ctx->EvalMap.Map1Texture2.u1 = u1;
+        ctx->EvalMap.Map1Texture2.u2 = u2;
+        ctx->EvalMap.Map1Texture2.du = 1.0 / (u2 - u1);
+        if (ctx->EvalMap.Map1Texture2.Points
+             && !ctx->EvalMap.Map1Texture2.Retain) {
+           free( ctx->EvalMap.Map1Texture2.Points );
+        }
+        ctx->EvalMap.Map1Texture2.Points = (GLfloat *) points;
+        ctx->EvalMap.Map1Texture2.Retain = retain;
+        break;
+      case GL_MAP1_TEXTURE_COORD_3:
+         ctx->EvalMap.Map1Texture3.Order = order;
+        ctx->EvalMap.Map1Texture3.u1 = u1;
+        ctx->EvalMap.Map1Texture3.u2 = u2;
+        ctx->EvalMap.Map1Texture3.du = 1.0 / (u2 - u1);
+        if (ctx->EvalMap.Map1Texture3.Points
+             && !ctx->EvalMap.Map1Texture3.Retain) {
+           free( ctx->EvalMap.Map1Texture3.Points );
+        }
+        ctx->EvalMap.Map1Texture3.Points = (GLfloat *) points;
+        ctx->EvalMap.Map1Texture3.Retain = retain;
+        break;
+      case GL_MAP1_TEXTURE_COORD_4:
+         ctx->EvalMap.Map1Texture4.Order = order;
+        ctx->EvalMap.Map1Texture4.u1 = u1;
+        ctx->EvalMap.Map1Texture4.u2 = u2;
+        ctx->EvalMap.Map1Texture4.du = 1.0 / (u2 - u1);
+        if (ctx->EvalMap.Map1Texture4.Points
+             && !ctx->EvalMap.Map1Texture4.Retain) {
+           free( ctx->EvalMap.Map1Texture4.Points );
+        }
+        ctx->EvalMap.Map1Texture4.Points = (GLfloat *) points;
+        ctx->EvalMap.Map1Texture4.Retain = retain;
+        break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glMap1(target)" );
+   }
+}
+
+
+
+
+/*
+ * Note that the array of control points must be 'unpacked' at this time.
+ * Input:  retain - if TRUE, this control point data is also in a display
+ *                  list and can't be freed until the list is freed.
+ */
+void gl_Map2f( GLcontext* ctx, GLenum target,
+             GLfloat u1, GLfloat u2, GLint ustride, GLint uorder,
+             GLfloat v1, GLfloat v2, GLint vstride, GLint vorder,
+             const GLfloat *points, GLboolean retain )
+{
+   GLint k;
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glMap2");
+
+   if (u1==u2) {
+      gl_error( ctx, GL_INVALID_VALUE, "glMap2(u1,u2)" );
+      return;
+   }
+
+   if (v1==v2) {
+      gl_error( ctx, GL_INVALID_VALUE, "glMap2(v1,v2)" );
+      return;
+   }
+
+   if (uorder<1 || uorder>MAX_EVAL_ORDER) {
+      gl_error( ctx, GL_INVALID_VALUE, "glMap2(uorder)" );
+      return;
+   }
+
+   if (vorder<1 || vorder>MAX_EVAL_ORDER) {
+      gl_error( ctx, GL_INVALID_VALUE, "glMap2(vorder)" );
+      return;
+   }
+
+   k = components( target );
+   if (k==0) {
+      gl_error( ctx, GL_INVALID_ENUM, "glMap2(target)" );
+   }
+
+   if (ustride < k) {
+      gl_error( ctx, GL_INVALID_VALUE, "glMap2(ustride)" );
+      return;
+   }
+   if (vstride < k) {
+      gl_error( ctx, GL_INVALID_VALUE, "glMap2(vstride)" );
+      return;
+   }
+
+   switch (target) {
+      case GL_MAP2_VERTEX_3:
+         ctx->EvalMap.Map2Vertex3.Uorder = uorder;
+        ctx->EvalMap.Map2Vertex3.u1 = u1;
+        ctx->EvalMap.Map2Vertex3.u2 = u2;
+        ctx->EvalMap.Map2Vertex3.du = 1.0 / (u2 - u1);
+         ctx->EvalMap.Map2Vertex3.Vorder = vorder;
+        ctx->EvalMap.Map2Vertex3.v1 = v1;
+        ctx->EvalMap.Map2Vertex3.v2 = v2;
+        ctx->EvalMap.Map2Vertex3.dv = 1.0 / (v2 - v1);
+        if (ctx->EvalMap.Map2Vertex3.Points
+             && !ctx->EvalMap.Map2Vertex3.Retain) {
+           free( ctx->EvalMap.Map2Vertex3.Points );
+        }
+        ctx->EvalMap.Map2Vertex3.Retain = retain;
+        ctx->EvalMap.Map2Vertex3.Points = (GLfloat *) points;
+        break;
+      case GL_MAP2_VERTEX_4:
+         ctx->EvalMap.Map2Vertex4.Uorder = uorder;
+        ctx->EvalMap.Map2Vertex4.u1 = u1;
+        ctx->EvalMap.Map2Vertex4.u2 = u2;
+        ctx->EvalMap.Map2Vertex4.du = 1.0 / (u2 - u1);
+         ctx->EvalMap.Map2Vertex4.Vorder = vorder;
+        ctx->EvalMap.Map2Vertex4.v1 = v1;
+        ctx->EvalMap.Map2Vertex4.v2 = v2;
+        ctx->EvalMap.Map2Vertex4.dv = 1.0 / (v2 - v1);
+        if (ctx->EvalMap.Map2Vertex4.Points
+             && !ctx->EvalMap.Map2Vertex4.Retain) {
+           free( ctx->EvalMap.Map2Vertex4.Points );
+        }
+        ctx->EvalMap.Map2Vertex4.Points = (GLfloat *) points;
+        ctx->EvalMap.Map2Vertex4.Retain = retain;
+        break;
+      case GL_MAP2_INDEX:
+         ctx->EvalMap.Map2Index.Uorder = uorder;
+        ctx->EvalMap.Map2Index.u1 = u1;
+        ctx->EvalMap.Map2Index.u2 = u2;
+        ctx->EvalMap.Map2Index.du = 1.0 / (u2 - u1);
+         ctx->EvalMap.Map2Index.Vorder = vorder;
+        ctx->EvalMap.Map2Index.v1 = v1;
+        ctx->EvalMap.Map2Index.v2 = v2;
+        ctx->EvalMap.Map2Index.dv = 1.0 / (v2 - v1);
+        if (ctx->EvalMap.Map2Index.Points
+             && !ctx->EvalMap.Map2Index.Retain) {
+           free( ctx->EvalMap.Map2Index.Points );
+        }
+        ctx->EvalMap.Map2Index.Retain = retain;
+        ctx->EvalMap.Map2Index.Points = (GLfloat *) points;
+        break;
+      case GL_MAP2_COLOR_4:
+         ctx->EvalMap.Map2Color4.Uorder = uorder;
+        ctx->EvalMap.Map2Color4.u1 = u1;
+        ctx->EvalMap.Map2Color4.u2 = u2;
+        ctx->EvalMap.Map2Color4.du = 1.0 / (u2 - u1);
+         ctx->EvalMap.Map2Color4.Vorder = vorder;
+        ctx->EvalMap.Map2Color4.v1 = v1;
+        ctx->EvalMap.Map2Color4.v2 = v2;
+        ctx->EvalMap.Map2Color4.dv = 1.0 / (v2 - v1);
+        if (ctx->EvalMap.Map2Color4.Points
+             && !ctx->EvalMap.Map2Color4.Retain) {
+           free( ctx->EvalMap.Map2Color4.Points );
+        }
+        ctx->EvalMap.Map2Color4.Retain = retain;
+        ctx->EvalMap.Map2Color4.Points = (GLfloat *) points;
+        break;
+      case GL_MAP2_NORMAL:
+         ctx->EvalMap.Map2Normal.Uorder = uorder;
+        ctx->EvalMap.Map2Normal.u1 = u1;
+        ctx->EvalMap.Map2Normal.u2 = u2;
+        ctx->EvalMap.Map2Normal.du = 1.0 / (u2 - u1);
+         ctx->EvalMap.Map2Normal.Vorder = vorder;
+        ctx->EvalMap.Map2Normal.v1 = v1;
+        ctx->EvalMap.Map2Normal.v2 = v2;
+        ctx->EvalMap.Map2Normal.dv = 1.0 / (v2 - v1);
+        if (ctx->EvalMap.Map2Normal.Points
+             && !ctx->EvalMap.Map2Normal.Retain) {
+           free( ctx->EvalMap.Map2Normal.Points );
+        }
+        ctx->EvalMap.Map2Normal.Retain = retain;
+        ctx->EvalMap.Map2Normal.Points = (GLfloat *) points;
+        break;
+      case GL_MAP2_TEXTURE_COORD_1:
+         ctx->EvalMap.Map2Texture1.Uorder = uorder;
+        ctx->EvalMap.Map2Texture1.u1 = u1;
+        ctx->EvalMap.Map2Texture1.u2 = u2;
+        ctx->EvalMap.Map2Texture1.du = 1.0 / (u2 - u1);
+         ctx->EvalMap.Map2Texture1.Vorder = vorder;
+        ctx->EvalMap.Map2Texture1.v1 = v1;
+        ctx->EvalMap.Map2Texture1.v2 = v2;
+        ctx->EvalMap.Map2Texture1.dv = 1.0 / (v2 - v1);
+        if (ctx->EvalMap.Map2Texture1.Points
+             && !ctx->EvalMap.Map2Texture1.Retain) {
+           free( ctx->EvalMap.Map2Texture1.Points );
+        }
+        ctx->EvalMap.Map2Texture1.Retain = retain;
+        ctx->EvalMap.Map2Texture1.Points = (GLfloat *) points;
+        break;
+      case GL_MAP2_TEXTURE_COORD_2:
+         ctx->EvalMap.Map2Texture2.Uorder = uorder;
+        ctx->EvalMap.Map2Texture2.u1 = u1;
+        ctx->EvalMap.Map2Texture2.u2 = u2;
+        ctx->EvalMap.Map2Texture2.du = 1.0 / (u2 - u1);
+         ctx->EvalMap.Map2Texture2.Vorder = vorder;
+        ctx->EvalMap.Map2Texture2.v1 = v1;
+        ctx->EvalMap.Map2Texture2.v2 = v2;
+        ctx->EvalMap.Map2Texture2.dv = 1.0 / (v2 - v1);
+        if (ctx->EvalMap.Map2Texture2.Points
+             && !ctx->EvalMap.Map2Texture2.Retain) {
+           free( ctx->EvalMap.Map2Texture2.Points );
+        }
+        ctx->EvalMap.Map2Texture2.Retain = retain;
+        ctx->EvalMap.Map2Texture2.Points = (GLfloat *) points;
+        break;
+      case GL_MAP2_TEXTURE_COORD_3:
+         ctx->EvalMap.Map2Texture3.Uorder = uorder;
+        ctx->EvalMap.Map2Texture3.u1 = u1;
+        ctx->EvalMap.Map2Texture3.u2 = u2;
+        ctx->EvalMap.Map2Texture3.du = 1.0 / (u2 - u1);
+         ctx->EvalMap.Map2Texture3.Vorder = vorder;
+        ctx->EvalMap.Map2Texture3.v1 = v1;
+        ctx->EvalMap.Map2Texture3.v2 = v2;
+        ctx->EvalMap.Map2Texture3.dv = 1.0 / (v2 - v1);
+        if (ctx->EvalMap.Map2Texture3.Points
+             && !ctx->EvalMap.Map2Texture3.Retain) {
+           free( ctx->EvalMap.Map2Texture3.Points );
+        }
+        ctx->EvalMap.Map2Texture3.Retain = retain;
+        ctx->EvalMap.Map2Texture3.Points = (GLfloat *) points;
+        break;
+      case GL_MAP2_TEXTURE_COORD_4:
+         ctx->EvalMap.Map2Texture4.Uorder = uorder;
+        ctx->EvalMap.Map2Texture4.u1 = u1;
+        ctx->EvalMap.Map2Texture4.u2 = u2;
+        ctx->EvalMap.Map2Texture4.du = 1.0 / (u2 - u1);
+         ctx->EvalMap.Map2Texture4.Vorder = vorder;
+        ctx->EvalMap.Map2Texture4.v1 = v1;
+        ctx->EvalMap.Map2Texture4.v2 = v2;
+        ctx->EvalMap.Map2Texture4.dv = 1.0 / (v2 - v1);
+        if (ctx->EvalMap.Map2Texture4.Points
+             && !ctx->EvalMap.Map2Texture4.Retain) {
+           free( ctx->EvalMap.Map2Texture4.Points );
+        }
+        ctx->EvalMap.Map2Texture4.Retain = retain;
+        ctx->EvalMap.Map2Texture4.Points = (GLfloat *) points;
+        break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glMap2(target)" );
+   }
+}
+
+
+   
+
+
+void gl_GetMapdv( GLcontext* ctx, GLenum target, GLenum query, GLdouble *v )
+{
+   GLint i, n;
+   GLfloat *data;
+
+   switch (query) {
+      case GL_COEFF:
+        switch (target) {
+           case GL_MAP1_COLOR_4:
+              data = ctx->EvalMap.Map1Color4.Points;
+              n = ctx->EvalMap.Map1Color4.Order * 4;
+              break;
+           case GL_MAP1_INDEX:
+              data = ctx->EvalMap.Map1Index.Points;
+              n = ctx->EvalMap.Map1Index.Order;
+              break;
+           case GL_MAP1_NORMAL:
+              data = ctx->EvalMap.Map1Normal.Points;
+              n = ctx->EvalMap.Map1Normal.Order * 3;
+              break;
+           case GL_MAP1_TEXTURE_COORD_1:
+              data = ctx->EvalMap.Map1Texture1.Points;
+              n = ctx->EvalMap.Map1Texture1.Order * 1;
+              break;
+           case GL_MAP1_TEXTURE_COORD_2:
+              data = ctx->EvalMap.Map1Texture2.Points;
+              n = ctx->EvalMap.Map1Texture2.Order * 2;
+              break;
+           case GL_MAP1_TEXTURE_COORD_3:
+              data = ctx->EvalMap.Map1Texture3.Points;
+              n = ctx->EvalMap.Map1Texture3.Order * 3;
+              break;
+           case GL_MAP1_TEXTURE_COORD_4:
+              data = ctx->EvalMap.Map1Texture4.Points;
+              n = ctx->EvalMap.Map1Texture4.Order * 4;
+              break;
+           case GL_MAP1_VERTEX_3:
+              data = ctx->EvalMap.Map1Vertex3.Points;
+              n = ctx->EvalMap.Map1Vertex3.Order * 3;
+              break;
+           case GL_MAP1_VERTEX_4:
+              data = ctx->EvalMap.Map1Vertex4.Points;
+              n = ctx->EvalMap.Map1Vertex4.Order * 4;
+              break;
+           case GL_MAP2_COLOR_4:
+              data = ctx->EvalMap.Map2Color4.Points;
+              n = ctx->EvalMap.Map2Color4.Uorder
+                 * ctx->EvalMap.Map2Color4.Vorder * 4;
+              break;
+           case GL_MAP2_INDEX:
+              data = ctx->EvalMap.Map2Index.Points;
+              n = ctx->EvalMap.Map2Index.Uorder
+                 * ctx->EvalMap.Map2Index.Vorder;
+              break;
+           case GL_MAP2_NORMAL:
+              data = ctx->EvalMap.Map2Normal.Points;
+              n = ctx->EvalMap.Map2Normal.Uorder
+                 * ctx->EvalMap.Map2Normal.Vorder * 3;
+              break;
+           case GL_MAP2_TEXTURE_COORD_1:
+              data = ctx->EvalMap.Map2Texture1.Points;
+              n = ctx->EvalMap.Map2Texture1.Uorder
+                 * ctx->EvalMap.Map2Texture1.Vorder * 1;
+              break;
+           case GL_MAP2_TEXTURE_COORD_2:
+              data = ctx->EvalMap.Map2Texture2.Points;
+              n = ctx->EvalMap.Map2Texture2.Uorder
+                 * ctx->EvalMap.Map2Texture2.Vorder * 2;
+              break;
+           case GL_MAP2_TEXTURE_COORD_3:
+              data = ctx->EvalMap.Map2Texture3.Points;
+              n = ctx->EvalMap.Map2Texture3.Uorder
+                 * ctx->EvalMap.Map2Texture3.Vorder * 3;
+              break;
+           case GL_MAP2_TEXTURE_COORD_4:
+              data = ctx->EvalMap.Map2Texture4.Points;
+              n = ctx->EvalMap.Map2Texture4.Uorder
+                 * ctx->EvalMap.Map2Texture4.Vorder * 4;
+              break;
+           case GL_MAP2_VERTEX_3:
+              data = ctx->EvalMap.Map2Vertex3.Points;
+              n = ctx->EvalMap.Map2Vertex3.Uorder
+                 * ctx->EvalMap.Map2Vertex3.Vorder * 3;
+              break;
+           case GL_MAP2_VERTEX_4:
+              data = ctx->EvalMap.Map2Vertex4.Points;
+              n = ctx->EvalMap.Map2Vertex4.Uorder
+                 * ctx->EvalMap.Map2Vertex4.Vorder * 4;
+              break;
+           default:
+              gl_error( ctx, GL_INVALID_ENUM, "glGetMapdv(target)" );
+              return;
+        }
+        if (data) {
+           for (i=0;i<n;i++) {
+              v[i] = data[i];
+           }
+        }
+         break;
+      case GL_ORDER:
+        switch (target) {
+           case GL_MAP1_COLOR_4:
+              *v = ctx->EvalMap.Map1Color4.Order;
+              break;
+           case GL_MAP1_INDEX:
+              *v = ctx->EvalMap.Map1Index.Order;
+              break;
+           case GL_MAP1_NORMAL:
+              *v = ctx->EvalMap.Map1Normal.Order;
+              break;
+           case GL_MAP1_TEXTURE_COORD_1:
+              *v = ctx->EvalMap.Map1Texture1.Order;
+              break;
+           case GL_MAP1_TEXTURE_COORD_2:
+              *v = ctx->EvalMap.Map1Texture2.Order;
+              break;
+           case GL_MAP1_TEXTURE_COORD_3:
+              *v = ctx->EvalMap.Map1Texture3.Order;
+              break;
+           case GL_MAP1_TEXTURE_COORD_4:
+              *v = ctx->EvalMap.Map1Texture4.Order;
+              break;
+           case GL_MAP1_VERTEX_3:
+              *v = ctx->EvalMap.Map1Vertex3.Order;
+              break;
+           case GL_MAP1_VERTEX_4:
+              *v = ctx->EvalMap.Map1Vertex4.Order;
+              break;
+           case GL_MAP2_COLOR_4:
+              v[0] = ctx->EvalMap.Map2Color4.Uorder;
+              v[1] = ctx->EvalMap.Map2Color4.Vorder;
+              break;
+           case GL_MAP2_INDEX:
+              v[0] = ctx->EvalMap.Map2Index.Uorder;
+              v[1] = ctx->EvalMap.Map2Index.Vorder;
+              break;
+           case GL_MAP2_NORMAL:
+              v[0] = ctx->EvalMap.Map2Normal.Uorder;
+              v[1] = ctx->EvalMap.Map2Normal.Vorder;
+              break;
+           case GL_MAP2_TEXTURE_COORD_1:
+              v[0] = ctx->EvalMap.Map2Texture1.Uorder;
+              v[1] = ctx->EvalMap.Map2Texture1.Vorder;
+              break;
+           case GL_MAP2_TEXTURE_COORD_2:
+              v[0] = ctx->EvalMap.Map2Texture2.Uorder;
+              v[1] = ctx->EvalMap.Map2Texture2.Vorder;
+              break;
+           case GL_MAP2_TEXTURE_COORD_3:
+              v[0] = ctx->EvalMap.Map2Texture3.Uorder;
+              v[1] = ctx->EvalMap.Map2Texture3.Vorder;
+              break;
+           case GL_MAP2_TEXTURE_COORD_4:
+              v[0] = ctx->EvalMap.Map2Texture4.Uorder;
+              v[1] = ctx->EvalMap.Map2Texture4.Vorder;
+              break;
+           case GL_MAP2_VERTEX_3:
+              v[0] = ctx->EvalMap.Map2Vertex3.Uorder;
+              v[1] = ctx->EvalMap.Map2Vertex3.Vorder;
+              break;
+           case GL_MAP2_VERTEX_4:
+              v[0] = ctx->EvalMap.Map2Vertex4.Uorder;
+              v[1] = ctx->EvalMap.Map2Vertex4.Vorder;
+              break;
+           default:
+              gl_error( ctx, GL_INVALID_ENUM, "glGetMapdv(target)" );
+              return;
+        }
+         break;
+      case GL_DOMAIN:
+        switch (target) {
+           case GL_MAP1_COLOR_4:
+              v[0] = ctx->EvalMap.Map1Color4.u1;
+              v[1] = ctx->EvalMap.Map1Color4.u2;
+              break;
+           case GL_MAP1_INDEX:
+              v[0] = ctx->EvalMap.Map1Index.u1;
+              v[1] = ctx->EvalMap.Map1Index.u2;
+              break;
+           case GL_MAP1_NORMAL:
+              v[0] = ctx->EvalMap.Map1Normal.u1;
+              v[1] = ctx->EvalMap.Map1Normal.u2;
+              break;
+           case GL_MAP1_TEXTURE_COORD_1:
+              v[0] = ctx->EvalMap.Map1Texture1.u1;
+              v[1] = ctx->EvalMap.Map1Texture1.u2;
+              break;
+           case GL_MAP1_TEXTURE_COORD_2:
+              v[0] = ctx->EvalMap.Map1Texture2.u1;
+              v[1] = ctx->EvalMap.Map1Texture2.u2;
+              break;
+           case GL_MAP1_TEXTURE_COORD_3:
+              v[0] = ctx->EvalMap.Map1Texture3.u1;
+              v[1] = ctx->EvalMap.Map1Texture3.u2;
+              break;
+           case GL_MAP1_TEXTURE_COORD_4:
+              v[0] = ctx->EvalMap.Map1Texture4.u1;
+              v[1] = ctx->EvalMap.Map1Texture4.u2;
+              break;
+           case GL_MAP1_VERTEX_3:
+              v[0] = ctx->EvalMap.Map1Vertex3.u1;
+              v[1] = ctx->EvalMap.Map1Vertex3.u2;
+              break;
+           case GL_MAP1_VERTEX_4:
+              v[0] = ctx->EvalMap.Map1Vertex4.u1;
+              v[1] = ctx->EvalMap.Map1Vertex4.u2;
+              break;
+           case GL_MAP2_COLOR_4:
+              v[0] = ctx->EvalMap.Map2Color4.u1;
+              v[1] = ctx->EvalMap.Map2Color4.u2;
+              v[2] = ctx->EvalMap.Map2Color4.v1;
+              v[3] = ctx->EvalMap.Map2Color4.v2;
+              break;
+           case GL_MAP2_INDEX:
+              v[0] = ctx->EvalMap.Map2Index.u1;
+              v[1] = ctx->EvalMap.Map2Index.u2;
+              v[2] = ctx->EvalMap.Map2Index.v1;
+              v[3] = ctx->EvalMap.Map2Index.v2;
+              break;
+           case GL_MAP2_NORMAL:
+              v[0] = ctx->EvalMap.Map2Normal.u1;
+              v[1] = ctx->EvalMap.Map2Normal.u2;
+              v[2] = ctx->EvalMap.Map2Normal.v1;
+              v[3] = ctx->EvalMap.Map2Normal.v2;
+              break;
+           case GL_MAP2_TEXTURE_COORD_1:
+              v[0] = ctx->EvalMap.Map2Texture1.u1;
+              v[1] = ctx->EvalMap.Map2Texture1.u2;
+              v[2] = ctx->EvalMap.Map2Texture1.v1;
+              v[3] = ctx->EvalMap.Map2Texture1.v2;
+              break;
+           case GL_MAP2_TEXTURE_COORD_2:
+              v[0] = ctx->EvalMap.Map2Texture2.u1;
+              v[1] = ctx->EvalMap.Map2Texture2.u2;
+              v[2] = ctx->EvalMap.Map2Texture2.v1;
+              v[3] = ctx->EvalMap.Map2Texture2.v2;
+              break;
+           case GL_MAP2_TEXTURE_COORD_3:
+              v[0] = ctx->EvalMap.Map2Texture3.u1;
+              v[1] = ctx->EvalMap.Map2Texture3.u2;
+              v[2] = ctx->EvalMap.Map2Texture3.v1;
+              v[3] = ctx->EvalMap.Map2Texture3.v2;
+              break;
+           case GL_MAP2_TEXTURE_COORD_4:
+              v[0] = ctx->EvalMap.Map2Texture4.u1;
+              v[1] = ctx->EvalMap.Map2Texture4.u2;
+              v[2] = ctx->EvalMap.Map2Texture4.v1;
+              v[3] = ctx->EvalMap.Map2Texture4.v2;
+              break;
+           case GL_MAP2_VERTEX_3:
+              v[0] = ctx->EvalMap.Map2Vertex3.u1;
+              v[1] = ctx->EvalMap.Map2Vertex3.u2;
+              v[2] = ctx->EvalMap.Map2Vertex3.v1;
+              v[3] = ctx->EvalMap.Map2Vertex3.v2;
+              break;
+           case GL_MAP2_VERTEX_4:
+              v[0] = ctx->EvalMap.Map2Vertex4.u1;
+              v[1] = ctx->EvalMap.Map2Vertex4.u2;
+              v[2] = ctx->EvalMap.Map2Vertex4.v1;
+              v[3] = ctx->EvalMap.Map2Vertex4.v2;
+              break;
+           default:
+              gl_error( ctx, GL_INVALID_ENUM, "glGetMapdv(target)" );
+        }
+         break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glGetMapdv(query)" );
+   }
+}
+
+
+void gl_GetMapfv( GLcontext* ctx, GLenum target, GLenum query, GLfloat *v )
+{
+   GLint i, n;
+   GLfloat *data;
+
+   switch (query) {
+      case GL_COEFF:
+        switch (target) {
+           case GL_MAP1_COLOR_4:
+              data = ctx->EvalMap.Map1Color4.Points;
+              n = ctx->EvalMap.Map1Color4.Order * 4;
+              break;
+           case GL_MAP1_INDEX:
+              data = ctx->EvalMap.Map1Index.Points;
+              n = ctx->EvalMap.Map1Index.Order;
+              break;
+           case GL_MAP1_NORMAL:
+              data = ctx->EvalMap.Map1Normal.Points;
+              n = ctx->EvalMap.Map1Normal.Order * 3;
+              break;
+           case GL_MAP1_TEXTURE_COORD_1:
+              data = ctx->EvalMap.Map1Texture1.Points;
+              n = ctx->EvalMap.Map1Texture1.Order * 1;
+              break;
+           case GL_MAP1_TEXTURE_COORD_2:
+              data = ctx->EvalMap.Map1Texture2.Points;
+              n = ctx->EvalMap.Map1Texture2.Order * 2;
+              break;
+           case GL_MAP1_TEXTURE_COORD_3:
+              data = ctx->EvalMap.Map1Texture3.Points;
+              n = ctx->EvalMap.Map1Texture3.Order * 3;
+              break;
+           case GL_MAP1_TEXTURE_COORD_4:
+              data = ctx->EvalMap.Map1Texture4.Points;
+              n = ctx->EvalMap.Map1Texture4.Order * 4;
+              break;
+           case GL_MAP1_VERTEX_3:
+              data = ctx->EvalMap.Map1Vertex3.Points;
+              n = ctx->EvalMap.Map1Vertex3.Order * 3;
+              break;
+           case GL_MAP1_VERTEX_4:
+              data = ctx->EvalMap.Map1Vertex4.Points;
+              n = ctx->EvalMap.Map1Vertex4.Order * 4;
+              break;
+           case GL_MAP2_COLOR_4:
+              data = ctx->EvalMap.Map2Color4.Points;
+              n = ctx->EvalMap.Map2Color4.Uorder
+                 * ctx->EvalMap.Map2Color4.Vorder * 4;
+              break;
+           case GL_MAP2_INDEX:
+              data = ctx->EvalMap.Map2Index.Points;
+              n = ctx->EvalMap.Map2Index.Uorder
+                 * ctx->EvalMap.Map2Index.Vorder;
+              break;
+           case GL_MAP2_NORMAL:
+              data = ctx->EvalMap.Map2Normal.Points;
+              n = ctx->EvalMap.Map2Normal.Uorder
+                 * ctx->EvalMap.Map2Normal.Vorder * 3;
+              break;
+           case GL_MAP2_TEXTURE_COORD_1:
+              data = ctx->EvalMap.Map2Texture1.Points;
+              n = ctx->EvalMap.Map2Texture1.Uorder
+                 * ctx->EvalMap.Map2Texture1.Vorder * 1;
+              break;
+           case GL_MAP2_TEXTURE_COORD_2:
+              data = ctx->EvalMap.Map2Texture2.Points;
+              n = ctx->EvalMap.Map2Texture2.Uorder
+                 * ctx->EvalMap.Map2Texture2.Vorder * 2;
+              break;
+           case GL_MAP2_TEXTURE_COORD_3:
+              data = ctx->EvalMap.Map2Texture3.Points;
+              n = ctx->EvalMap.Map2Texture3.Uorder
+                 * ctx->EvalMap.Map2Texture3.Vorder * 3;
+              break;
+           case GL_MAP2_TEXTURE_COORD_4:
+              data = ctx->EvalMap.Map2Texture4.Points;
+              n = ctx->EvalMap.Map2Texture4.Uorder
+                 * ctx->EvalMap.Map2Texture4.Vorder * 4;
+              break;
+           case GL_MAP2_VERTEX_3:
+              data = ctx->EvalMap.Map2Vertex3.Points;
+              n = ctx->EvalMap.Map2Vertex3.Uorder
+                 * ctx->EvalMap.Map2Vertex3.Vorder * 3;
+              break;
+           case GL_MAP2_VERTEX_4:
+              data = ctx->EvalMap.Map2Vertex4.Points;
+              n = ctx->EvalMap.Map2Vertex4.Uorder
+                 * ctx->EvalMap.Map2Vertex4.Vorder * 4;
+              break;
+           default:
+              gl_error( ctx, GL_INVALID_ENUM, "glGetMapfv(target)" );
+              return;
+        }
+        if (data) {
+           for (i=0;i<n;i++) {
+              v[i] = data[i];
+           }
+        }
+         break;
+      case GL_ORDER:
+        switch (target) {
+           case GL_MAP1_COLOR_4:
+              *v = ctx->EvalMap.Map1Color4.Order;
+              break;
+           case GL_MAP1_INDEX:
+              *v = ctx->EvalMap.Map1Index.Order;
+              break;
+           case GL_MAP1_NORMAL:
+              *v = ctx->EvalMap.Map1Normal.Order;
+              break;
+           case GL_MAP1_TEXTURE_COORD_1:
+              *v = ctx->EvalMap.Map1Texture1.Order;
+              break;
+           case GL_MAP1_TEXTURE_COORD_2:
+              *v = ctx->EvalMap.Map1Texture2.Order;
+              break;
+           case GL_MAP1_TEXTURE_COORD_3:
+              *v = ctx->EvalMap.Map1Texture3.Order;
+              break;
+           case GL_MAP1_TEXTURE_COORD_4:
+              *v = ctx->EvalMap.Map1Texture4.Order;
+              break;
+           case GL_MAP1_VERTEX_3:
+              *v = ctx->EvalMap.Map1Vertex3.Order;
+              break;
+           case GL_MAP1_VERTEX_4:
+              *v = ctx->EvalMap.Map1Vertex4.Order;
+              break;
+           case GL_MAP2_COLOR_4:
+              v[0] = ctx->EvalMap.Map2Color4.Uorder;
+              v[1] = ctx->EvalMap.Map2Color4.Vorder;
+              break;
+           case GL_MAP2_INDEX:
+              v[0] = ctx->EvalMap.Map2Index.Uorder;
+              v[1] = ctx->EvalMap.Map2Index.Vorder;
+              break;
+           case GL_MAP2_NORMAL:
+              v[0] = ctx->EvalMap.Map2Normal.Uorder;
+              v[1] = ctx->EvalMap.Map2Normal.Vorder;
+              break;
+           case GL_MAP2_TEXTURE_COORD_1:
+              v[0] = ctx->EvalMap.Map2Texture1.Uorder;
+              v[1] = ctx->EvalMap.Map2Texture1.Vorder;
+              break;
+           case GL_MAP2_TEXTURE_COORD_2:
+              v[0] = ctx->EvalMap.Map2Texture2.Uorder;
+              v[1] = ctx->EvalMap.Map2Texture2.Vorder;
+              break;
+           case GL_MAP2_TEXTURE_COORD_3:
+              v[0] = ctx->EvalMap.Map2Texture3.Uorder;
+              v[1] = ctx->EvalMap.Map2Texture3.Vorder;
+              break;
+           case GL_MAP2_TEXTURE_COORD_4:
+              v[0] = ctx->EvalMap.Map2Texture4.Uorder;
+              v[1] = ctx->EvalMap.Map2Texture4.Vorder;
+              break;
+           case GL_MAP2_VERTEX_3:
+              v[0] = ctx->EvalMap.Map2Vertex3.Uorder;
+              v[1] = ctx->EvalMap.Map2Vertex3.Vorder;
+              break;
+           case GL_MAP2_VERTEX_4:
+              v[0] = ctx->EvalMap.Map2Vertex4.Uorder;
+              v[1] = ctx->EvalMap.Map2Vertex4.Vorder;
+              break;
+           default:
+              gl_error( ctx, GL_INVALID_ENUM, "glGetMapfv(target)" );
+              return;
+        }
+         break;
+      case GL_DOMAIN:
+        switch (target) {
+           case GL_MAP1_COLOR_4:
+              v[0] = ctx->EvalMap.Map1Color4.u1;
+              v[1] = ctx->EvalMap.Map1Color4.u2;
+              break;
+           case GL_MAP1_INDEX:
+              v[0] = ctx->EvalMap.Map1Index.u1;
+              v[1] = ctx->EvalMap.Map1Index.u2;
+              break;
+           case GL_MAP1_NORMAL:
+              v[0] = ctx->EvalMap.Map1Normal.u1;
+              v[1] = ctx->EvalMap.Map1Normal.u2;
+              break;
+           case GL_MAP1_TEXTURE_COORD_1:
+              v[0] = ctx->EvalMap.Map1Texture1.u1;
+              v[1] = ctx->EvalMap.Map1Texture1.u2;
+              break;
+           case GL_MAP1_TEXTURE_COORD_2:
+              v[0] = ctx->EvalMap.Map1Texture2.u1;
+              v[1] = ctx->EvalMap.Map1Texture2.u2;
+              break;
+           case GL_MAP1_TEXTURE_COORD_3:
+              v[0] = ctx->EvalMap.Map1Texture3.u1;
+              v[1] = ctx->EvalMap.Map1Texture3.u2;
+              break;
+           case GL_MAP1_TEXTURE_COORD_4:
+              v[0] = ctx->EvalMap.Map1Texture4.u1;
+              v[1] = ctx->EvalMap.Map1Texture4.u2;
+              break;
+           case GL_MAP1_VERTEX_3:
+              v[0] = ctx->EvalMap.Map1Vertex3.u1;
+              v[1] = ctx->EvalMap.Map1Vertex3.u2;
+              break;
+           case GL_MAP1_VERTEX_4:
+              v[0] = ctx->EvalMap.Map1Vertex4.u1;
+              v[1] = ctx->EvalMap.Map1Vertex4.u2;
+              break;
+           case GL_MAP2_COLOR_4:
+              v[0] = ctx->EvalMap.Map2Color4.u1;
+              v[1] = ctx->EvalMap.Map2Color4.u2;
+              v[2] = ctx->EvalMap.Map2Color4.v1;
+              v[3] = ctx->EvalMap.Map2Color4.v2;
+              break;
+           case GL_MAP2_INDEX:
+              v[0] = ctx->EvalMap.Map2Index.u1;
+              v[1] = ctx->EvalMap.Map2Index.u2;
+              v[2] = ctx->EvalMap.Map2Index.v1;
+              v[3] = ctx->EvalMap.Map2Index.v2;
+              break;
+           case GL_MAP2_NORMAL:
+              v[0] = ctx->EvalMap.Map2Normal.u1;
+              v[1] = ctx->EvalMap.Map2Normal.u2;
+              v[2] = ctx->EvalMap.Map2Normal.v1;
+              v[3] = ctx->EvalMap.Map2Normal.v2;
+              break;
+           case GL_MAP2_TEXTURE_COORD_1:
+              v[0] = ctx->EvalMap.Map2Texture1.u1;
+              v[1] = ctx->EvalMap.Map2Texture1.u2;
+              v[2] = ctx->EvalMap.Map2Texture1.v1;
+              v[3] = ctx->EvalMap.Map2Texture1.v2;
+              break;
+           case GL_MAP2_TEXTURE_COORD_2:
+              v[0] = ctx->EvalMap.Map2Texture2.u1;
+              v[1] = ctx->EvalMap.Map2Texture2.u2;
+              v[2] = ctx->EvalMap.Map2Texture2.v1;
+              v[3] = ctx->EvalMap.Map2Texture2.v2;
+              break;
+           case GL_MAP2_TEXTURE_COORD_3:
+              v[0] = ctx->EvalMap.Map2Texture3.u1;
+              v[1] = ctx->EvalMap.Map2Texture3.u2;
+              v[2] = ctx->EvalMap.Map2Texture3.v1;
+              v[3] = ctx->EvalMap.Map2Texture3.v2;
+              break;
+           case GL_MAP2_TEXTURE_COORD_4:
+              v[0] = ctx->EvalMap.Map2Texture4.u1;
+              v[1] = ctx->EvalMap.Map2Texture4.u2;
+              v[2] = ctx->EvalMap.Map2Texture4.v1;
+              v[3] = ctx->EvalMap.Map2Texture4.v2;
+              break;
+           case GL_MAP2_VERTEX_3:
+              v[0] = ctx->EvalMap.Map2Vertex3.u1;
+              v[1] = ctx->EvalMap.Map2Vertex3.u2;
+              v[2] = ctx->EvalMap.Map2Vertex3.v1;
+              v[3] = ctx->EvalMap.Map2Vertex3.v2;
+              break;
+           case GL_MAP2_VERTEX_4:
+              v[0] = ctx->EvalMap.Map2Vertex4.u1;
+              v[1] = ctx->EvalMap.Map2Vertex4.u2;
+              v[2] = ctx->EvalMap.Map2Vertex4.v1;
+              v[3] = ctx->EvalMap.Map2Vertex4.v2;
+              break;
+           default:
+              gl_error( ctx, GL_INVALID_ENUM, "glGetMapfv(target)" );
+        }
+         break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glGetMapfv(query)" );
+   }
+}
+
+
+void gl_GetMapiv( GLcontext* ctx, GLenum target, GLenum query, GLint *v )
+{
+   GLuint i, n;
+   GLfloat *data;
+
+   switch (query) {
+      case GL_COEFF:
+        switch (target) {
+           case GL_MAP1_COLOR_4:
+              data = ctx->EvalMap.Map1Color4.Points;
+              n = ctx->EvalMap.Map1Color4.Order * 4;
+              break;
+           case GL_MAP1_INDEX:
+              data = ctx->EvalMap.Map1Index.Points;
+              n = ctx->EvalMap.Map1Index.Order;
+              break;
+           case GL_MAP1_NORMAL:
+              data = ctx->EvalMap.Map1Normal.Points;
+              n = ctx->EvalMap.Map1Normal.Order * 3;
+              break;
+           case GL_MAP1_TEXTURE_COORD_1:
+              data = ctx->EvalMap.Map1Texture1.Points;
+              n = ctx->EvalMap.Map1Texture1.Order * 1;
+              break;
+           case GL_MAP1_TEXTURE_COORD_2:
+              data = ctx->EvalMap.Map1Texture2.Points;
+              n = ctx->EvalMap.Map1Texture2.Order * 2;
+              break;
+           case GL_MAP1_TEXTURE_COORD_3:
+              data = ctx->EvalMap.Map1Texture3.Points;
+              n = ctx->EvalMap.Map1Texture3.Order * 3;
+              break;
+           case GL_MAP1_TEXTURE_COORD_4:
+              data = ctx->EvalMap.Map1Texture4.Points;
+              n = ctx->EvalMap.Map1Texture4.Order * 4;
+              break;
+           case GL_MAP1_VERTEX_3:
+              data = ctx->EvalMap.Map1Vertex3.Points;
+              n = ctx->EvalMap.Map1Vertex3.Order * 3;
+              break;
+           case GL_MAP1_VERTEX_4:
+              data = ctx->EvalMap.Map1Vertex4.Points;
+              n = ctx->EvalMap.Map1Vertex4.Order * 4;
+              break;
+           case GL_MAP2_COLOR_4:
+              data = ctx->EvalMap.Map2Color4.Points;
+              n = ctx->EvalMap.Map2Color4.Uorder
+                 * ctx->EvalMap.Map2Color4.Vorder * 4;
+              break;
+           case GL_MAP2_INDEX:
+              data = ctx->EvalMap.Map2Index.Points;
+              n = ctx->EvalMap.Map2Index.Uorder
+                 * ctx->EvalMap.Map2Index.Vorder;
+              break;
+           case GL_MAP2_NORMAL:
+              data = ctx->EvalMap.Map2Normal.Points;
+              n = ctx->EvalMap.Map2Normal.Uorder
+                 * ctx->EvalMap.Map2Normal.Vorder * 3;
+              break;
+           case GL_MAP2_TEXTURE_COORD_1:
+              data = ctx->EvalMap.Map2Texture1.Points;
+              n = ctx->EvalMap.Map2Texture1.Uorder
+                 * ctx->EvalMap.Map2Texture1.Vorder * 1;
+              break;
+           case GL_MAP2_TEXTURE_COORD_2:
+              data = ctx->EvalMap.Map2Texture2.Points;
+              n = ctx->EvalMap.Map2Texture2.Uorder
+                 * ctx->EvalMap.Map2Texture2.Vorder * 2;
+              break;
+           case GL_MAP2_TEXTURE_COORD_3:
+              data = ctx->EvalMap.Map2Texture3.Points;
+              n = ctx->EvalMap.Map2Texture3.Uorder
+                 * ctx->EvalMap.Map2Texture3.Vorder * 3;
+              break;
+           case GL_MAP2_TEXTURE_COORD_4:
+              data = ctx->EvalMap.Map2Texture4.Points;
+              n = ctx->EvalMap.Map2Texture4.Uorder
+                 * ctx->EvalMap.Map2Texture4.Vorder * 4;
+              break;
+           case GL_MAP2_VERTEX_3:
+              data = ctx->EvalMap.Map2Vertex3.Points;
+              n = ctx->EvalMap.Map2Vertex3.Uorder
+                 * ctx->EvalMap.Map2Vertex3.Vorder * 3;
+              break;
+           case GL_MAP2_VERTEX_4:
+              data = ctx->EvalMap.Map2Vertex4.Points;
+              n = ctx->EvalMap.Map2Vertex4.Uorder
+                 * ctx->EvalMap.Map2Vertex4.Vorder * 4;
+              break;
+           default:
+              gl_error( ctx, GL_INVALID_ENUM, "glGetMapiv(target)" );
+              return;
+        }
+        if (data) {
+           for (i=0;i<n;i++) {
+              v[i] = ROUNDF(data[i]);
+           }
+        }
+         break;
+      case GL_ORDER:
+        switch (target) {
+           case GL_MAP1_COLOR_4:
+              *v = ctx->EvalMap.Map1Color4.Order;
+              break;
+           case GL_MAP1_INDEX:
+              *v = ctx->EvalMap.Map1Index.Order;
+              break;
+           case GL_MAP1_NORMAL:
+              *v = ctx->EvalMap.Map1Normal.Order;
+              break;
+           case GL_MAP1_TEXTURE_COORD_1:
+              *v = ctx->EvalMap.Map1Texture1.Order;
+              break;
+           case GL_MAP1_TEXTURE_COORD_2:
+              *v = ctx->EvalMap.Map1Texture2.Order;
+              break;
+           case GL_MAP1_TEXTURE_COORD_3:
+              *v = ctx->EvalMap.Map1Texture3.Order;
+              break;
+           case GL_MAP1_TEXTURE_COORD_4:
+              *v = ctx->EvalMap.Map1Texture4.Order;
+              break;
+           case GL_MAP1_VERTEX_3:
+              *v = ctx->EvalMap.Map1Vertex3.Order;
+              break;
+           case GL_MAP1_VERTEX_4:
+              *v = ctx->EvalMap.Map1Vertex4.Order;
+              break;
+           case GL_MAP2_COLOR_4:
+              v[0] = ctx->EvalMap.Map2Color4.Uorder;
+              v[1] = ctx->EvalMap.Map2Color4.Vorder;
+              break;
+           case GL_MAP2_INDEX:
+              v[0] = ctx->EvalMap.Map2Index.Uorder;
+              v[1] = ctx->EvalMap.Map2Index.Vorder;
+              break;
+           case GL_MAP2_NORMAL:
+              v[0] = ctx->EvalMap.Map2Normal.Uorder;
+              v[1] = ctx->EvalMap.Map2Normal.Vorder;
+              break;
+           case GL_MAP2_TEXTURE_COORD_1:
+              v[0] = ctx->EvalMap.Map2Texture1.Uorder;
+              v[1] = ctx->EvalMap.Map2Texture1.Vorder;
+              break;
+           case GL_MAP2_TEXTURE_COORD_2:
+              v[0] = ctx->EvalMap.Map2Texture2.Uorder;
+              v[1] = ctx->EvalMap.Map2Texture2.Vorder;
+              break;
+           case GL_MAP2_TEXTURE_COORD_3:
+              v[0] = ctx->EvalMap.Map2Texture3.Uorder;
+              v[1] = ctx->EvalMap.Map2Texture3.Vorder;
+              break;
+           case GL_MAP2_TEXTURE_COORD_4:
+              v[0] = ctx->EvalMap.Map2Texture4.Uorder;
+              v[1] = ctx->EvalMap.Map2Texture4.Vorder;
+              break;
+           case GL_MAP2_VERTEX_3:
+              v[0] = ctx->EvalMap.Map2Vertex3.Uorder;
+              v[1] = ctx->EvalMap.Map2Vertex3.Vorder;
+              break;
+           case GL_MAP2_VERTEX_4:
+              v[0] = ctx->EvalMap.Map2Vertex4.Uorder;
+              v[1] = ctx->EvalMap.Map2Vertex4.Vorder;
+              break;
+           default:
+              gl_error( ctx, GL_INVALID_ENUM, "glGetMapiv(target)" );
+              return;
+        }
+         break;
+      case GL_DOMAIN:
+        switch (target) {
+           case GL_MAP1_COLOR_4:
+              v[0] = ROUNDF(ctx->EvalMap.Map1Color4.u1);
+              v[1] = ROUNDF(ctx->EvalMap.Map1Color4.u2);
+              break;
+           case GL_MAP1_INDEX:
+              v[0] = ROUNDF(ctx->EvalMap.Map1Index.u1);
+              v[1] = ROUNDF(ctx->EvalMap.Map1Index.u2);
+              break;
+           case GL_MAP1_NORMAL:
+              v[0] = ROUNDF(ctx->EvalMap.Map1Normal.u1);
+              v[1] = ROUNDF(ctx->EvalMap.Map1Normal.u2);
+              break;
+           case GL_MAP1_TEXTURE_COORD_1:
+              v[0] = ROUNDF(ctx->EvalMap.Map1Texture1.u1);
+              v[1] = ROUNDF(ctx->EvalMap.Map1Texture1.u2);
+              break;
+           case GL_MAP1_TEXTURE_COORD_2:
+              v[0] = ROUNDF(ctx->EvalMap.Map1Texture2.u1);
+              v[1] = ROUNDF(ctx->EvalMap.Map1Texture2.u2);
+              break;
+           case GL_MAP1_TEXTURE_COORD_3:
+              v[0] = ROUNDF(ctx->EvalMap.Map1Texture3.u1);
+              v[1] = ROUNDF(ctx->EvalMap.Map1Texture3.u2);
+              break;
+           case GL_MAP1_TEXTURE_COORD_4:
+              v[0] = ROUNDF(ctx->EvalMap.Map1Texture4.u1);
+              v[1] = ROUNDF(ctx->EvalMap.Map1Texture4.u2);
+              break;
+           case GL_MAP1_VERTEX_3:
+              v[0] = ROUNDF(ctx->EvalMap.Map1Vertex3.u1);
+              v[1] = ROUNDF(ctx->EvalMap.Map1Vertex3.u2);
+              break;
+           case GL_MAP1_VERTEX_4:
+              v[0] = ROUNDF(ctx->EvalMap.Map1Vertex4.u1);
+              v[1] = ROUNDF(ctx->EvalMap.Map1Vertex4.u2);
+              break;
+           case GL_MAP2_COLOR_4:
+              v[0] = ROUNDF(ctx->EvalMap.Map2Color4.u1);
+              v[1] = ROUNDF(ctx->EvalMap.Map2Color4.u2);
+              v[2] = ROUNDF(ctx->EvalMap.Map2Color4.v1);
+              v[3] = ROUNDF(ctx->EvalMap.Map2Color4.v2);
+              break;
+           case GL_MAP2_INDEX:
+              v[0] = ROUNDF(ctx->EvalMap.Map2Index.u1);
+              v[1] = ROUNDF(ctx->EvalMap.Map2Index.u2);
+              v[2] = ROUNDF(ctx->EvalMap.Map2Index.v1);
+              v[3] = ROUNDF(ctx->EvalMap.Map2Index.v2);
+              break;
+           case GL_MAP2_NORMAL:
+              v[0] = ROUNDF(ctx->EvalMap.Map2Normal.u1);
+              v[1] = ROUNDF(ctx->EvalMap.Map2Normal.u2);
+              v[2] = ROUNDF(ctx->EvalMap.Map2Normal.v1);
+              v[3] = ROUNDF(ctx->EvalMap.Map2Normal.v2);
+              break;
+           case GL_MAP2_TEXTURE_COORD_1:
+              v[0] = ROUNDF(ctx->EvalMap.Map2Texture1.u1);
+              v[1] = ROUNDF(ctx->EvalMap.Map2Texture1.u2);
+              v[2] = ROUNDF(ctx->EvalMap.Map2Texture1.v1);
+              v[3] = ROUNDF(ctx->EvalMap.Map2Texture1.v2);
+              break;
+           case GL_MAP2_TEXTURE_COORD_2:
+              v[0] = ROUNDF(ctx->EvalMap.Map2Texture2.u1);
+              v[1] = ROUNDF(ctx->EvalMap.Map2Texture2.u2);
+              v[2] = ROUNDF(ctx->EvalMap.Map2Texture2.v1);
+              v[3] = ROUNDF(ctx->EvalMap.Map2Texture2.v2);
+              break;
+           case GL_MAP2_TEXTURE_COORD_3:
+              v[0] = ROUNDF(ctx->EvalMap.Map2Texture3.u1);
+              v[1] = ROUNDF(ctx->EvalMap.Map2Texture3.u2);
+              v[2] = ROUNDF(ctx->EvalMap.Map2Texture3.v1);
+              v[3] = ROUNDF(ctx->EvalMap.Map2Texture3.v2);
+              break;
+           case GL_MAP2_TEXTURE_COORD_4:
+              v[0] = ROUNDF(ctx->EvalMap.Map2Texture4.u1);
+              v[1] = ROUNDF(ctx->EvalMap.Map2Texture4.u2);
+              v[2] = ROUNDF(ctx->EvalMap.Map2Texture4.v1);
+              v[3] = ROUNDF(ctx->EvalMap.Map2Texture4.v2);
+              break;
+           case GL_MAP2_VERTEX_3:
+              v[0] = ROUNDF(ctx->EvalMap.Map2Vertex3.u1);
+              v[1] = ROUNDF(ctx->EvalMap.Map2Vertex3.u2);
+              v[2] = ROUNDF(ctx->EvalMap.Map2Vertex3.v1);
+              v[3] = ROUNDF(ctx->EvalMap.Map2Vertex3.v2);
+              break;
+           case GL_MAP2_VERTEX_4:
+              v[0] = ROUNDF(ctx->EvalMap.Map2Vertex4.u1);
+              v[1] = ROUNDF(ctx->EvalMap.Map2Vertex4.u2);
+              v[2] = ROUNDF(ctx->EvalMap.Map2Vertex4.v1);
+              v[3] = ROUNDF(ctx->EvalMap.Map2Vertex4.v2);
+              break;
+           default:
+              gl_error( ctx, GL_INVALID_ENUM, "glGetMapiv(target)" );
+        }
+         break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glGetMapiv(query)" );
+   }
+}
+
+
+
+void eval_points1( GLfloat outcoord[][4], 
+                  GLfloat coord[][4],
+                  const GLuint *flags,
+                  GLfloat du, GLfloat u1 )
+{
+   GLuint i;
+   for (i = VB_START ; !(flags[i] & VERT_END_VB) ; i++)
+      if (flags[i] & VERT_EVAL_P1) 
+        outcoord[i][0] = coord[i][0] * du + u1;
+      else if (flags[i] & VERT_EVAL_ANY) {
+        outcoord[i][0] = coord[i][0];
+        outcoord[i][1] = coord[i][1];
+      }
+}
+
+void eval_points2( GLfloat outcoord[][4], 
+                  GLfloat coord[][4],
+                  const GLuint *flags,
+                  GLfloat du, GLfloat u1,
+                  GLfloat dv, GLfloat v1 )
+{
+   GLuint i;
+   for (i = VB_START ; !(flags[i] & VERT_END_VB) ; i++)
+      if (flags[i] & VERT_EVAL_P2) {
+        outcoord[i][0] = coord[i][0] * du + u1;
+        outcoord[i][1] = coord[i][1] * dv + v1;
+      } else if (flags[i] & VERT_EVAL_ANY) {
+        outcoord[i][0] = coord[i][0];
+        outcoord[i][1] = coord[i][1];
+      }
+}
+
+
+static const GLubyte dirty_flags[5] = {
+   0,                          /* not possible */
+   VEC_DIRTY_0,
+   VEC_DIRTY_1, 
+   VEC_DIRTY_2, 
+   VEC_DIRTY_3
+};
+
+
+GLvector4f *eval1_4f( GLvector4f *dest, 
+                     GLfloat coord[][4], 
+                     const GLuint *flags, 
+                     GLuint dimension,
+                     struct gl_1d_map *map )
+{
+   const GLfloat u1 = map->u1;
+   const GLfloat du = map->du;
+   GLfloat (*to)[4] = dest->data;
+   GLuint i;
+   
+   for (i = VB_START ; !(flags[i] & VERT_END_VB) ; i++)
+      if (flags[i] & (VERT_EVAL_C1|VERT_EVAL_P1)) {
+        GLfloat u = (coord[i][0] - u1) * du;
+        ASSIGN_4V(to[i], 0,0,0,1);
+        horner_bezier_curve(map->Points, to[i], u, dimension, map->Order);
+      }
+
+   dest->count = i;
+   dest->size = MAX2(dest->size, dimension);
+   dest->flags |= dirty_flags[dimension];
+   return dest;
+}
+
+
+GLvector1ui *eval1_1ui( GLvector1ui *dest, 
+                      GLfloat coord[][4], 
+                      const GLuint *flags, 
+                      struct gl_1d_map *map )
+{
+   const GLfloat u1 = map->u1;
+   const GLfloat du = map->du;
+   GLuint *to = dest->data;
+   GLuint i;
+
+   for (i = VB_START ; !(flags[i] & VERT_END_VB) ; i++)
+      if (flags[i] & (VERT_EVAL_C1|VERT_EVAL_P1)) {
+        GLfloat u = (coord[i][0] - u1) * du;
+        GLfloat tmp;
+        horner_bezier_curve(map->Points, &tmp, u, 1, map->Order);
+        to[i] = (GLuint) (GLint) tmp;
+      }
+
+   dest->count = i;
+   return dest;
+}
+
+GLvector3f *eval1_norm( GLvector3f *dest, 
+                       GLfloat coord[][4],
+                       GLuint *flags, /* not const */
+                       struct gl_1d_map *map )
+{
+   const GLfloat u1 = map->u1;
+   const GLfloat du = map->du;
+   GLfloat (*to)[3] = dest->data;
+   GLuint i;
+
+   for (i = VB_START ; !(flags[i] & VERT_END_VB) ; i++)
+      if (flags[i] & (VERT_EVAL_C1|VERT_EVAL_P1)) {
+        GLfloat u = (coord[i][0] - u1) * du;
+        horner_bezier_curve(map->Points, to[i], u, 3, map->Order);
+        flags[i+1] |= VERT_NORM; /* reset */
+      }
+
+   dest->count = i;
+   return dest;
+}
+
+GLvector4ub *eval1_color( GLvector4ub *dest, 
+                         GLfloat coord[][4],
+                         GLuint *flags, /* not const */
+                         struct gl_1d_map *map )
+{   
+   const GLfloat u1 = map->u1;
+   const GLfloat du = map->du;
+   GLubyte (*to)[4] = dest->data;
+   GLuint i;
+
+   for (i = VB_START ; !(flags[i] & VERT_END_VB) ; i++)
+      if (flags[i] & (VERT_EVAL_C1|VERT_EVAL_P1)) {
+        GLfloat u = (coord[i][0] - u1) * du;
+        GLfloat fcolor[4];
+        horner_bezier_curve(map->Points, fcolor, u, 4, map->Order);
+        FLOAT_RGBA_TO_UBYTE_RGBA(to[i], fcolor);
+        flags[i+1] |= VERT_RGBA; /* reset */
+      }
+
+   dest->count = i;
+   return dest;
+}
+
+
+
+
+GLvector4f *eval2_obj_norm( GLvector4f *obj_ptr, 
+                           GLvector3f *norm_ptr,
+                           GLfloat coord[][4], 
+                           GLuint *flags, 
+                           GLuint dimension,
+                           struct gl_2d_map *map )
+{
+   const GLfloat u1 = map->u1;
+   const GLfloat du = map->du;
+   const GLfloat v1 = map->v1;
+   const GLfloat dv = map->dv;
+   GLfloat (*obj)[4] = obj_ptr->data;
+   GLfloat (*normal)[3] = norm_ptr->data;
+   GLuint i;
+   
+   for (i = VB_START ; !(flags[i] & VERT_END_VB) ; i++)
+      if (flags[i] & (VERT_EVAL_C2|VERT_EVAL_P2)) {
+        GLfloat u = (coord[i][0] - u1) * du;
+        GLfloat v = (coord[i][1] - v1) * dv;
+        GLfloat du[4], dv[4];
+
+        ASSIGN_4V(obj[i], 0,0,0,1);
+        de_casteljau_surf(map->Points, obj[i], du, dv, u, v, dimension,
+                          map->Uorder, map->Vorder);
+              
+        CROSS3(normal[i], du, dv);
+        NORMALIZE_3FV(normal[i]);
+        flags[i+1] |= VERT_NORM;
+      }
+   obj_ptr->count = i;
+   obj_ptr->size = MAX2(obj_ptr->size, dimension);
+   obj_ptr->flags |= dirty_flags[dimension];
+   return obj_ptr;
+}
+
+
+GLvector4f *eval2_4f( GLvector4f *dest, 
+                     GLfloat coord[][4], 
+                     const GLuint *flags, 
+                     GLuint dimension,
+                     struct gl_2d_map *map )
+{
+   const GLfloat u1 = map->u1;
+   const GLfloat du = map->du;
+   const GLfloat v1 = map->v1;
+   const GLfloat dv = map->dv;
+   GLfloat (*to)[4] = dest->data;
+   GLuint i;
+
+   for (i = VB_START ; !(flags[i] & VERT_END_VB) ; i++)
+      if (flags[i] & (VERT_EVAL_C2|VERT_EVAL_P2)) {
+        GLfloat u = (coord[i][0] - u1) * du;
+        GLfloat v = (coord[i][1] - v1) * dv;
+        horner_bezier_surf(map->Points, to[i], u, v, dimension,
+                           map->Uorder, map->Vorder);
+      }
+
+   dest->count = i;
+   dest->size = MAX2(dest->size, dimension);
+   dest->flags |= dirty_flags[dimension];
+   return dest;
+}
+
+
+GLvector3f *eval2_norm( GLvector3f *dest, 
+                       GLfloat coord[][4], 
+                       GLuint *flags, 
+                       struct gl_2d_map *map )
+{
+   const GLfloat u1 = map->u1;
+   const GLfloat du = map->du;
+   const GLfloat v1 = map->v1;
+   const GLfloat dv = map->dv;
+   GLfloat (*to)[3] = dest->data;
+   GLuint i;
+
+   for (i = VB_START ; !(flags[i] & VERT_END_VB) ; i++)
+      if (flags[i] & (VERT_EVAL_C2|VERT_EVAL_P2)) {
+        GLfloat u = (coord[i][0] - u1) * du;
+        GLfloat v = (coord[i][1] - v1) * dv;
+        horner_bezier_surf(map->Points, to[i], u, v, 3,
+                           map->Uorder, map->Vorder);
+        flags[i+1] |= VERT_NORM; /* reset */
+     }
+
+   dest->count = i;
+   return dest;
+}
+
+
+GLvector1ui *eval2_1ui( GLvector1ui *dest, 
+                      GLfloat coord[][4], 
+                      const GLuint *flags, 
+                      struct gl_2d_map *map )
+{
+   const GLfloat u1 = map->u1;
+   const GLfloat du = map->du;
+   const GLfloat v1 = map->v1;
+   const GLfloat dv = map->dv;
+   GLuint *to = dest->data;
+   GLuint i;
+
+   for (i = VB_START ; !(flags[i] & VERT_END_VB) ; i++)
+      if (flags[i] & (VERT_EVAL_C2|VERT_EVAL_P2)) {
+        GLfloat u = (coord[i][0] - u1) * du;
+        GLfloat v = (coord[i][1] - v1) * dv;
+        GLfloat tmp;
+        horner_bezier_surf(map->Points, &tmp, u, v, 1,
+                           map->Uorder, map->Vorder);
+
+        to[i] = (GLuint) (GLint) tmp;
+      }
+
+   dest->count = i;
+   return dest;
+}
+
+
+
+GLvector4ub *eval2_color( GLvector4ub *dest,
+                         GLfloat coord[][4], 
+                         GLuint *flags,
+                         struct gl_2d_map *map )
+{
+   const GLfloat u1 = map->u1;
+   const GLfloat du = map->du;
+   const GLfloat v1 = map->v1;
+   const GLfloat dv = map->dv;
+   GLubyte (*to)[4] = dest->data;
+   GLuint i;
+
+   for (i = VB_START ; !(flags[i] & VERT_END_VB) ; i++)
+      if (flags[i] & (VERT_EVAL_C2|VERT_EVAL_P2)) {
+        GLfloat u = (coord[i][0] - u1) * du;
+        GLfloat v = (coord[i][1] - v1) * dv;
+        GLfloat fcolor[4];
+        horner_bezier_surf(map->Points, fcolor, u, v, 4,
+                           map->Uorder, map->Vorder);
+        FLOAT_RGBA_TO_UBYTE_RGBA(to[i], fcolor);
+        flags[i+1] |= VERT_RGBA; /* reset */
+      }
+
+   dest->count = i;
+   return dest;
+}
+
+
+GLvector4f *copy_4f( GLvector4f *out, CONST GLvector4f *in, 
+                    const GLuint *flags)
+{
+   GLfloat (*to)[4] = out->data;
+   GLfloat (*from)[4] = in->data;
+   GLuint i;
+   
+   for ( i = VB_START ; !(flags[i] & VERT_END_VB) ; i++) 
+      if (!(flags[i] & VERT_EVAL_ANY)) 
+        COPY_4FV( to[i], from[i] );
+   
+   return out;
+}
+
+GLvector3f *copy_3f( GLvector3f *out, CONST GLvector3f *in, 
+                    const GLuint *flags)
+{
+   GLfloat (*to)[3] = out->data;
+   GLfloat (*from)[3] = in->data;
+   GLuint i;
+   
+   for ( i = VB_START ; !(flags[i] & VERT_END_VB) ; i++) 
+      if (!(flags[i] & VERT_EVAL_ANY)) 
+        COPY_3V( to[i], from[i] );
+   
+   return out;
+}
+
+GLvector4ub *copy_4ub( GLvector4ub *out, CONST GLvector4ub *in, 
+                      const GLuint *flags )
+{
+   GLubyte (*to)[4] = out->data;
+   GLubyte (*from)[4] = in->data;
+   GLuint i;
+   
+   for ( i = VB_START ; !(flags[i] & VERT_END_VB) ; i++) 
+      if (!(flags[i] & VERT_EVAL_ANY)) 
+        COPY_4UBV( to[i], from[i] );
+
+   return out;
+}
+
+GLvector1ui *copy_1ui( GLvector1ui *out, CONST GLvector1ui *in, 
+                      const GLuint *flags )
+{
+   GLuint *to = out->data;
+   CONST GLuint *from = in->data;
+   GLuint i;
+   
+   for ( i = VB_START ; !(flags[i] & VERT_END_VB) ; i++) 
+      if (!(flags[i] & VERT_EVAL_ANY)) 
+        to[i] = from[i];
+
+   return out;
+}
+
+
+/* KW: Rewrote this to perform eval on a whole buffer at once.
+ *     Only evaluates active data items, and avoids scribbling
+ *     the source buffer if we are running from a display list.
+ *
+ *     If the user (in this case looser) sends eval coordinates
+ *     or runs a display list containing eval coords with no
+ *     vertex maps enabled, we have to either copy all non-eval
+ *     data to a new buffer, or find a way of working around
+ *     the eval data.  I choose the second option.
+ *
+ * KW: This code not reached by cva - use IM to access storage.
+ */
+void gl_eval_vb( struct vertex_buffer *VB )
+{
+   struct immediate *IM = VB->IM;
+   GLcontext *ctx = VB->ctx;
+   GLuint req = ctx->CVA.elt.inputs;
+   GLfloat (*coord)[4] = VB->ObjPtr->data;
+   GLuint *flags = VB->Flag;
+   GLuint new_flags = 0;
+   
+
+   GLuint any_eval1 = VB->OrFlag & (VERT_EVAL_C1|VERT_EVAL_P1);
+   GLuint any_eval2 = VB->OrFlag & (VERT_EVAL_C2|VERT_EVAL_P2);
+   GLuint all_eval = VB->AndFlag & VERT_EVAL_ANY;
+
+   /* Handle the degenerate cases.
+    */
+   if (any_eval1 && !ctx->Eval.Map1Vertex4 && !ctx->Eval.Map1Vertex3) {
+      VB->PurgeFlags |= (VERT_EVAL_C1|VERT_EVAL_P1);
+      VB->EarlyCull = 0;
+      any_eval1 = GL_FALSE;
+   }
+  
+   if (any_eval2 && !ctx->Eval.Map2Vertex4 && !ctx->Eval.Map2Vertex3) {
+      VB->PurgeFlags |= (VERT_EVAL_C2|VERT_EVAL_P2);
+      VB->EarlyCull = 0;
+      any_eval2 = GL_FALSE;
+   }
+
+   /* KW: This really is a degenerate case - doing this disables
+    * culling, and causes dummy values for the missing vertices to be
+    * transformed and clip tested.  It also forces the individual
+    * cliptesting of each primitive in vb_render.  I wish there was a
+    * nice alternative, but I can't say I want to put effort into
+    * optimizing such a bad usage of the library - I'd much rather
+    * work on useful changes.
+    */
+   if (VB->PurgeFlags) {
+      if (!any_eval1 && !any_eval2 && all_eval) VB->Count = VB_START;
+      gl_purge_vertices( VB );
+      if (!any_eval1 && !any_eval2) return;
+   } else
+      VB->IndirectCount = VB->Count;
+
+   /* Translate points into coords.
+    */
+   if (any_eval1 && (VB->OrFlag & VERT_EVAL_P1)) 
+   {
+      eval_points1( IM->Obj, coord, flags, 
+                   ctx->Eval.MapGrid1du,
+                   ctx->Eval.MapGrid1u1);
+
+      coord = IM->Obj;
+   }
+
+   if (any_eval2 && (VB->OrFlag & VERT_EVAL_P2)) 
+   {
+      eval_points2( IM->Obj, coord, flags, 
+                   ctx->Eval.MapGrid2du,
+                   ctx->Eval.MapGrid2u1,
+                   ctx->Eval.MapGrid2dv,
+                   ctx->Eval.MapGrid2v1 );
+
+      coord = IM->Obj;
+   }
+
+   /* Perform the evaluations on active data elements.
+    */
+   if (req & VERT_INDEX) 
+   {
+      GLvector1ui  *in_index = VB->IndexPtr;
+      GLvector1ui  *out_index = &IM->v.Index;
+
+      if (ctx->Eval.Map1Index && any_eval1) 
+        VB->IndexPtr = eval1_1ui( out_index, coord, flags, 
+                                  &ctx->EvalMap.Map1Index );
+      
+      if (ctx->Eval.Map2Index && any_eval2)
+        VB->IndexPtr = eval2_1ui( out_index, coord, flags, 
+                                  &ctx->EvalMap.Map2Index );
+        
+      if (VB->IndexPtr != in_index) {
+        new_flags |= VERT_INDEX;
+        if (!all_eval)
+           VB->IndexPtr = copy_1ui( out_index, in_index, flags );
+      }
+   }
+
+   if (req & VERT_RGBA) 
+   {   
+      GLvector4ub  *in_color = VB->ColorPtr;
+      GLvector4ub  *out_color = &IM->v.Color;
+
+      if (ctx->Eval.Map1Color4 && any_eval1) 
+        VB->ColorPtr = eval1_color( out_color, coord, flags, 
+                                  &ctx->EvalMap.Map1Color4 );
+      
+      if (ctx->Eval.Map2Color4 && any_eval2)
+        VB->ColorPtr = eval2_color( out_color, coord, flags, 
+                                    &ctx->EvalMap.Map2Color4 );
+        
+      if (VB->ColorPtr != in_color) {
+        new_flags |= VERT_RGBA;
+        if (!all_eval)
+           VB->ColorPtr = copy_4ub( out_color, in_color, flags );
+      }
+
+      VB->Color[0] = VB->Color[1] = VB->ColorPtr;
+   }
+
+
+   if (req & VERT_NORM) 
+   {   
+      GLvector3f  *in_normal = VB->NormalPtr;
+      GLvector3f  *out_normal = &IM->v.Normal;
+
+      if (ctx->Eval.Map1Normal && any_eval1) 
+        VB->NormalPtr = eval1_norm( out_normal, coord, flags, 
+                                    &ctx->EvalMap.Map1Normal );
+      
+      if (ctx->Eval.Map2Normal && any_eval2)
+        VB->NormalPtr = eval2_norm( out_normal, coord, flags, 
+                                    &ctx->EvalMap.Map2Normal );
+        
+      if (VB->NormalPtr != in_normal) {
+        new_flags |= VERT_NORM;
+        if (!all_eval)
+           VB->NormalPtr = copy_3f( out_normal, in_normal, flags );
+      }
+   }
+
+     
+   if (req & VERT_TEX_ANY(0)) 
+   {
+      GLvector4f *tc = VB->TexCoordPtr[0];
+      GLvector4f *in = tc;
+      GLvector4f *out = &IM->v.TexCoord[0];
+
+      if (any_eval1) {
+        if (ctx->Eval.Map1TextureCoord4) 
+           tc = eval1_4f( out, coord, flags, 4, &ctx->EvalMap.Map1Texture4);
+        else if (ctx->Eval.Map1TextureCoord3) 
+           tc = eval1_4f( out, coord, flags, 3, &ctx->EvalMap.Map1Texture3);
+        else if (ctx->Eval.Map1TextureCoord2) 
+           tc = eval1_4f( out, coord, flags, 2, &ctx->EvalMap.Map1Texture2);
+        else if (ctx->Eval.Map1TextureCoord1) 
+           tc = eval1_4f( out, coord, flags, 1, &ctx->EvalMap.Map1Texture1);
+      }
+
+      if (any_eval2) {
+        if (ctx->Eval.Map2TextureCoord4) 
+           tc = eval2_4f( out, coord, flags, 4, &ctx->EvalMap.Map2Texture4);
+        else if (ctx->Eval.Map2TextureCoord3) 
+           tc = eval2_4f( out, coord, flags, 3, &ctx->EvalMap.Map2Texture3);
+        else if (ctx->Eval.Map2TextureCoord2) 
+           tc = eval2_4f( out, coord, flags, 2, &ctx->EvalMap.Map2Texture2);
+        else if (ctx->Eval.Map2TextureCoord1) 
+           tc = eval2_4f( out, coord, flags, 1, &ctx->EvalMap.Map2Texture1);
+      }
+
+      if (tc != in) {
+        new_flags |= VERT_TEX_ANY(0); /* fix for sizes.. */
+        if (!all_eval)
+           tc = copy_4f( out, in, flags );
+      }
+
+      VB->TexCoordPtr[0] = tc;
+   }
+
+
+   {
+      GLvector4f *in = VB->ObjPtr;
+      GLvector4f *out = &IM->v.Obj;
+      GLvector4f *obj = in;
+   
+      if (any_eval1) {
+        if (ctx->Eval.Map1Vertex4) 
+           obj = eval1_4f( out, coord, flags, 4, &ctx->EvalMap.Map1Vertex4);
+        else 
+           obj = eval1_4f( out, coord, flags, 3, &ctx->EvalMap.Map1Vertex3);
+      }
+
+      if (any_eval2) {
+        if (ctx->Eval.Map2Vertex4) 
+        {
+           if (ctx->Eval.AutoNormal && (req & VERT_NORM)) 
+              obj = eval2_obj_norm( out, VB->NormalPtr, coord, flags, 4,
+                                   &ctx->EvalMap.Map2Vertex4 );
+           else
+              obj = eval2_4f( out, coord, flags, 4, 
+                              &ctx->EvalMap.Map2Vertex4);
+        }
+        else if (ctx->Eval.Map2Vertex3) 
+        {
+           if (ctx->Eval.AutoNormal && (req & VERT_NORM)) 
+              obj = eval2_obj_norm( out, VB->NormalPtr, coord, flags, 3,
+                                   &ctx->EvalMap.Map2Vertex3 );
+           else
+              obj = eval2_4f( out, coord, flags, 3, 
+                              &ctx->EvalMap.Map2Vertex3 );
+        }
+      }
+
+      if (obj != in && !all_eval)
+        obj = copy_4f( out, in, flags );
+
+      VB->ObjPtr = obj;
+   }
+
+   if (new_flags) {
+      GLuint *oldflags = VB->Flag;
+      GLuint *flags = VB->Flag = VB->EvaluatedFlags;
+      GLuint i;
+      GLuint count = VB->Count;
+
+      if (!flags) {
+        VB->EvaluatedFlags = (GLuint *)malloc(VB->Size * sizeof(GLuint));
+        flags = VB->Flag = VB->EvaluatedFlags;
+      }
+
+      if (all_eval) {
+        for (i = 0 ; i < count ; i++) 
+           flags[i] = oldflags[i] | new_flags;
+        VB->AndFlag |= new_flags; 
+      } else {
+        GLuint andflag = ~0;
+        for (i = 0 ; i < count ; i++) {
+           if (oldflags[i] & VERT_EVAL_ANY) 
+              flags[i] = oldflags[i] | new_flags;
+           andflag &= flags[i];
+        }
+        VB->AndFlag = andflag;
+      }
+   }
+}
+
+
+void gl_MapGrid1f( GLcontext* ctx, GLint un, GLfloat u1, GLfloat u2 )
+{
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glMapGrid1f");
+
+   if (un<1) {
+      gl_error( ctx, GL_INVALID_VALUE, "glMapGrid1f" );
+      return;
+   }
+   ctx->Eval.MapGrid1un = un;
+   ctx->Eval.MapGrid1u1 = u1;
+   ctx->Eval.MapGrid1u2 = u2;
+   ctx->Eval.MapGrid1du = (u2 - u1) / (GLfloat) un;
+}
+
+
+void gl_MapGrid2f( GLcontext* ctx, GLint un, GLfloat u1, GLfloat u2,
+                 GLint vn, GLfloat v1, GLfloat v2 )
+{
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glMapGrid2f");
+   if (un<1) {
+      gl_error( ctx, GL_INVALID_VALUE, "glMapGrid2f(un)" );
+      return;
+   }
+   if (vn<1) {
+      gl_error( ctx, GL_INVALID_VALUE, "glMapGrid2f(vn)" );
+      return;
+   }
+   ctx->Eval.MapGrid2un = un;
+   ctx->Eval.MapGrid2u1 = u1;
+   ctx->Eval.MapGrid2u2 = u2;
+   ctx->Eval.MapGrid2du = (u2 - u1) / (GLfloat) un;
+   ctx->Eval.MapGrid2vn = vn;
+   ctx->Eval.MapGrid2v1 = v1;
+   ctx->Eval.MapGrid2v2 = v2;
+   ctx->Eval.MapGrid2dv = (v2 - v1) / (GLfloat) vn;
+}
+
+
+
+void gl_EvalMesh1( GLcontext* ctx, GLenum mode, GLint i1, GLint i2 )
+{
+   GLint i;
+   GLfloat u, du;
+   GLenum prim;
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glEvalMesh1");
+
+   switch (mode) {
+      case GL_POINT:
+         prim = GL_POINTS;
+         break;
+      case GL_LINE:
+         prim = GL_LINE_STRIP;
+         break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glEvalMesh1(mode)" );
+         return;
+   }
+
+   /* No effect if vertex maps disabled.
+    */
+   if (!ctx->Eval.Map1Vertex4 && !ctx->Eval.Map1Vertex3) 
+      return;
+
+   du = ctx->Eval.MapGrid1du;
+   u = ctx->Eval.MapGrid1u1 + i1 * du;
+
+   /* KW: Could short-circuit this to avoid the immediate mechanism.
+    */
+   RESET_IMMEDIATE(ctx);
+
+   gl_Begin( ctx, prim );
+   for (i=i1;i<=i2;i++,u+=du) {
+      gl_EvalCoord1f( ctx, u );
+   }
+   gl_End(ctx);
+}
+
+
+
+void gl_EvalMesh2( GLcontext* ctx, 
+                  GLenum mode, 
+                  GLint i1, GLint i2, 
+                  GLint j1, GLint j2 )
+{
+   GLint i, j;
+   GLfloat u, du, v, dv, v1, u1;
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glEvalMesh2");
+
+   /* No effect if vertex maps disabled.
+    */
+   if (!ctx->Eval.Map2Vertex4 && !ctx->Eval.Map2Vertex3) 
+      return;
+
+   du = ctx->Eval.MapGrid2du;
+   dv = ctx->Eval.MapGrid2dv;
+   v1 = ctx->Eval.MapGrid2v1 + j1 * dv;
+   u1 = ctx->Eval.MapGrid2u1 + i1 * du;
+
+   RESET_IMMEDIATE(ctx);
+
+   switch (mode) {
+   case GL_POINT:
+      gl_Begin( ctx, GL_POINTS );
+      for (v=v1,j=j1;j<=j2;j++,v+=dv) {
+        for (u=u1,i=i1;i<=i2;i++,u+=du) {
+           gl_EvalCoord2f( ctx, u, v );
+        }
+      }
+      gl_End(ctx);
+      break;
+   case GL_LINE:
+      for (v=v1,j=j1;j<=j2;j++,v+=dv) {
+        gl_Begin( ctx, GL_LINE_STRIP );
+        for (u=u1,i=i1;i<=i2;i++,u+=du) {
+           gl_EvalCoord2f( ctx, u, v );
+        }
+        gl_End(ctx);
+      }
+      for (u=u1,i=i1;i<=i2;i++,u+=du) {
+        gl_Begin( ctx, GL_LINE_STRIP );
+        for (v=v1,j=j1;j<=j2;j++,v+=dv) {
+           gl_EvalCoord2f( ctx, u, v );
+        }
+        gl_End(ctx);
+      }
+      break;
+   case GL_FILL:
+      for (v=v1,j=j1;j<j2;j++,v+=dv) {
+        /* NOTE: a quad strip can't be used because the four */
+        /* can't be guaranteed to be coplanar! */
+        gl_Begin( ctx, GL_TRIANGLE_STRIP );
+        for (u=u1,i=i1;i<=i2;i++,u+=du) {
+           gl_EvalCoord2f( ctx, u, v );
+           gl_EvalCoord2f( ctx, u, v+dv );
+        }
+        gl_End(ctx);
+      }
+      break;
+   default:
+      gl_error( ctx, GL_INVALID_ENUM, "glEvalMesh2(mode)" );
+      return;
+   }
+}
+
diff --git a/src/mesa/main/eval.h b/src/mesa/main/eval.h
new file mode 100644 (file)
index 0000000..cde76b0
--- /dev/null
@@ -0,0 +1,95 @@
+/* $Id: eval.h,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef EVAL_H
+#define EVAL_H
+
+
+#include "types.h"
+
+
+extern void gl_init_eval( void );
+
+
+extern void gl_free_control_points( GLcontext *ctx,
+                                    GLenum target, GLfloat *data );
+
+
+extern GLfloat *gl_copy_map_points1f( GLenum target,
+                                      GLint ustride, GLint uorder,
+                                      const GLfloat *points );
+
+extern GLfloat *gl_copy_map_points1d( GLenum target,
+                                      GLint ustride, GLint uorder,
+                                      const GLdouble *points );
+
+extern GLfloat *gl_copy_map_points2f( GLenum target,
+                                      GLint ustride, GLint uorder,
+                                      GLint vstride, GLint vorder,
+                                      const GLfloat *points );
+
+extern GLfloat *gl_copy_map_points2d(GLenum target,
+                                     GLint ustride, GLint uorder,
+                                     GLint vstride, GLint vorder,
+                                     const GLdouble *points );
+
+
+extern void gl_Map1f( GLcontext* ctx,
+                      GLenum target, GLfloat u1, GLfloat u2, GLint stride,
+                      GLint order, const GLfloat *points, GLboolean retain );
+
+extern void gl_Map2f( GLcontext* ctx, GLenum target,
+                      GLfloat u1, GLfloat u2, GLint ustride, GLint uorder,
+                      GLfloat v1, GLfloat v2, GLint vstride, GLint vorder,
+                      const GLfloat *points, GLboolean retain );
+
+
+
+extern void gl_MapGrid1f( GLcontext* ctx, GLint un, GLfloat u1, GLfloat u2 );
+
+extern void gl_MapGrid2f( GLcontext* ctx,
+                          GLint un, GLfloat u1, GLfloat u2,
+                          GLint vn, GLfloat v1, GLfloat v2 );
+
+extern void gl_GetMapdv( GLcontext* ctx,
+                         GLenum target, GLenum query, GLdouble *v );
+
+extern void gl_GetMapfv( GLcontext* ctx,
+                         GLenum target, GLenum query, GLfloat *v );
+
+extern void gl_GetMapiv( GLcontext* ctx,
+                         GLenum target, GLenum query, GLint *v );
+
+extern void gl_EvalMesh1( GLcontext* ctx, GLenum mode, GLint i1, GLint i2 );
+
+extern void gl_EvalMesh2( GLcontext* ctx, GLenum mode,
+                          GLint i1, GLint i2, GLint j1, GLint j2 );
+
+extern void gl_eval_vb( struct vertex_buffer *VB );
+
+
+#endif
diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c
new file mode 100644 (file)
index 0000000..5568729
--- /dev/null
@@ -0,0 +1,196 @@
+/* $Id: extensions.c,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include <stdlib.h>
+#include "extensions.h"
+#include "simple_list.h"
+#include "types.h"
+
+#define MAX_EXT_NAMELEN 80
+#define MALLOC_STRUCT(T)  (struct T *) malloc( sizeof(struct T) )
+
+struct extension {
+   struct extension *next, *prev;
+   int enabled;
+   char name[MAX_EXT_NAMELEN+1];
+   void (*notify)( GLcontext *, GLboolean ); 
+};
+
+
+
+static struct { int enabled; const char *name; } default_extensions[] = {
+   { ALWAYS_ENABLED, "GL_EXT_blend_color" },
+   { ALWAYS_ENABLED, "GL_EXT_blend_minmax" },
+   { ALWAYS_ENABLED, "GL_EXT_blend_logic_op" },
+   { ALWAYS_ENABLED, "GL_EXT_blend_subtract" },
+   { ALWAYS_ENABLED, "GL_EXT_paletted_texture" },
+   { DEFAULT_ON,     "GL_EXT_point_parameters" },
+   { ALWAYS_ENABLED, "GL_EXT_polygon_offset" },
+   { ALWAYS_ENABLED, "GL_EXT_vertex_array" },
+   { ALWAYS_ENABLED, "GL_EXT_texture_object" },
+   { DEFAULT_ON,     "GL_EXT_texture3D" },
+   { ALWAYS_ENABLED, "GL_MESA_window_pos" },
+   { ALWAYS_ENABLED, "GL_MESA_resize_buffers" },
+   { ALWAYS_ENABLED, "GL_EXT_shared_texture_palette" },
+   { ALWAYS_ENABLED, "GL_EXT_rescale_normal" },
+   { ALWAYS_ENABLED, "GL_EXT_abgr" },
+   { ALWAYS_ENABLED, "GL_SGIS_texture_edge_clamp" },
+   { ALWAYS_ENABLED, "GL_EXT_stencil_wrap" },
+   { ALWAYS_ENABLED, "GL_INGR_blend_func_separate" },
+   { DEFAULT_ON,     "GL_ARB_multitexture" },
+   { ALWAYS_ENABLED, "GL_NV_texgen_reflection" },
+   { DEFAULT_ON,     "GL_PGI_misc_hints" },
+   { DEFAULT_ON,     "GL_EXT_compiled_vertex_array" },
+   { DEFAULT_OFF,    "GL_EXT_vertex_array_set" },
+   { DEFAULT_ON,     "GL_EXT_clip_volume_hint" },
+};
+
+
+int gl_extensions_add( GLcontext *ctx, 
+                      int state, 
+                      const char *name, 
+                      void (*notify)() )
+{
+   (void) notify;
+
+   if (ctx->Extensions.ext_string == 0) 
+   {
+      struct extension *t = MALLOC_STRUCT(extension);
+      t->enabled = state;
+      strncpy(t->name, name, MAX_EXT_NAMELEN);
+      t->name[MAX_EXT_NAMELEN] = 0;
+      t->notify = (void (*)(GLcontext *, GLboolean)) notify;
+      insert_at_tail( ctx->Extensions.ext_list, t );
+      return 0;
+   }
+   return 1;
+}
+
+
+static int set_extension( GLcontext *ctx, const char *name, GLuint state )
+{
+   struct extension *i;
+   foreach( i, ctx->Extensions.ext_list ) 
+      if (strncmp(i->name, name, MAX_EXT_NAMELEN) == 0) 
+        break;
+
+   if (i == ctx->Extensions.ext_list) return 1;
+
+   if (i->enabled && !(i->enabled & ALWAYS_ENABLED))
+   {
+      if (i->notify) i->notify( ctx, state );      
+      i->enabled = state;
+   }
+
+   return 0;
+}   
+
+
+int gl_extensions_enable( GLcontext *ctx, const char *name )
+{
+   if (ctx->Extensions.ext_string == 0) 
+      return set_extension( ctx, name, 1 );
+   return 1;
+}
+
+
+int gl_extensions_disable( GLcontext *ctx, const char *name )
+{
+   if (ctx->Extensions.ext_string == 0) 
+      return set_extension( ctx, name, 0 );
+   return 1;
+}
+      
+
+void gl_extensions_dtr( GLcontext *ctx )
+{
+   struct extension *i, *nexti;
+
+   if (ctx->Extensions.ext_string) {
+      free( ctx->Extensions.ext_string );
+      ctx->Extensions.ext_string = 0;
+   }
+
+   if (ctx->Extensions.ext_list) {
+      foreach_s( i, nexti, ctx->Extensions.ext_list ) {
+        free( i );
+      }
+   
+      free(ctx->Extensions.ext_list);
+      ctx->Extensions.ext_list = 0;
+   }      
+}
+
+
+void gl_extensions_ctr( GLcontext *ctx )
+{
+   GLuint i;
+
+   ctx->Extensions.ext_string = 0;
+   ctx->Extensions.ext_list = MALLOC_STRUCT(extension);
+   make_empty_list( ctx->Extensions.ext_list );
+
+   for (i = 0 ; i < Elements(default_extensions) ; i++) {
+      gl_extensions_add( ctx, 
+                        default_extensions[i].enabled,
+                        default_extensions[i].name,
+                        0 );
+   }
+}
+
+
+const char *gl_extensions_get_string( GLcontext *ctx )
+{
+   if (ctx->Extensions.ext_string == 0) 
+   {
+      struct extension *i;
+      char *str;
+      GLuint len = 0;
+      foreach (i, ctx->Extensions.ext_list) 
+        if (i->enabled)
+           len += strlen(i->name) + 1;
+      
+      if (len == 0) 
+        return "";
+
+      str = (char *)malloc(len * sizeof(char));
+      ctx->Extensions.ext_string = str;
+
+      foreach (i, ctx->Extensions.ext_list) 
+        if (i->enabled) {
+           strcpy(str, i->name);
+           str += strlen(str);
+           *str++ = ' ';
+        }
+
+      *(str-1) = 0;
+   }
+      
+   return ctx->Extensions.ext_string;
+}
+
+
diff --git a/src/mesa/main/extensions.h b/src/mesa/main/extensions.h
new file mode 100644 (file)
index 0000000..a19dc47
--- /dev/null
@@ -0,0 +1,56 @@
+/* $Id: extensions.h,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef _EXTENSIONS_H_
+#define _EXTENSIONS_H_
+
+struct gl_context;
+struct extension;
+
+struct gl_extensions {
+   char *ext_string;
+   struct extension *ext_list;
+};
+
+#define DEFAULT_OFF    0x0
+#define DEFAULT_ON     0x1
+#define ALWAYS_ENABLED 0x2
+
+/* Return 0 on success.
+ */
+extern int gl_extensions_add( struct gl_context *ctx, int state, 
+                             const char *name, void (*notify)() );
+
+extern int gl_extensions_enable( struct gl_context *ctx, const char *name );
+extern int gl_extensions_disable( struct gl_context *ctx, const char *name );
+extern void gl_extensions_dtr( struct gl_context *ctx );
+extern void gl_extensions_ctr( struct gl_context *ctx );
+extern const char *gl_extensions_get_string( struct gl_context *ctx );
+
+#endif
+
+
diff --git a/src/mesa/main/feedback.c b/src/mesa/main/feedback.c
new file mode 100644 (file)
index 0000000..4251aae
--- /dev/null
@@ -0,0 +1,395 @@
+/* $Id: feedback.c,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <assert.h>
+#include <stdio.h>
+#include "context.h"
+#include "enums.h"
+#include "feedback.h"
+#include "macros.h"
+#include "types.h"
+#ifdef XFree86Server
+#include "GL/xf86glx.h"
+#endif
+#endif
+
+
+
+#define FB_3D          0x01
+#define FB_4D          0x02
+#define FB_INDEX       0x04
+#define FB_COLOR       0x08
+#define FB_TEXTURE     0X10
+
+
+
+void
+gl_FeedbackBuffer( GLcontext *ctx, GLsizei size, GLenum type, GLfloat *buffer )
+{
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH( ctx, "glFeedbackBuffer" );
+
+   if (ctx->RenderMode==GL_FEEDBACK) {
+      gl_error( ctx, GL_INVALID_OPERATION, "glFeedbackBuffer" );
+      return;
+   }
+
+   if (size<0) {
+      gl_error( ctx, GL_INVALID_VALUE, "glFeedbackBuffer(size<0)" );
+      return;
+   }
+   if (!buffer) {
+      gl_error( ctx, GL_INVALID_VALUE, "glFeedbackBuffer(buffer==NULL)" );
+      ctx->Feedback.BufferSize = 0;
+      return;
+   }
+
+   switch (type) {
+      case GL_2D:
+        ctx->Feedback.Mask = 0;
+         ctx->Feedback.Type = type;
+        break;
+      case GL_3D:
+        ctx->Feedback.Mask = FB_3D;
+         ctx->Feedback.Type = type;
+        break;
+      case GL_3D_COLOR:
+        ctx->Feedback.Mask = FB_3D
+                           | (ctx->Visual->RGBAflag ? FB_COLOR : FB_INDEX);
+         ctx->Feedback.Type = type;
+        break;
+      case GL_3D_COLOR_TEXTURE:
+        ctx->Feedback.Mask = FB_3D
+                           | (ctx->Visual->RGBAflag ? FB_COLOR : FB_INDEX)
+                          | FB_TEXTURE;
+         ctx->Feedback.Type = type;
+        break;
+      case GL_4D_COLOR_TEXTURE:
+        ctx->Feedback.Mask = FB_3D | FB_4D
+                           | (ctx->Visual->RGBAflag ? FB_COLOR : FB_INDEX)
+                          | FB_TEXTURE;
+         ctx->Feedback.Type = type;
+        break;
+      default:
+        ctx->Feedback.Mask = 0;
+         gl_error( ctx, GL_INVALID_ENUM, "glFeedbackBuffer" );
+   }
+
+   ctx->Feedback.BufferSize = size;
+   ctx->Feedback.Buffer = buffer;
+   ctx->Feedback.Count = 0;
+}
+
+
+
+void gl_PassThrough( GLcontext *ctx, GLfloat token )
+{
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPassThrough");
+
+   if (ctx->RenderMode==GL_FEEDBACK) {
+      FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_PASS_THROUGH_TOKEN );
+      FEEDBACK_TOKEN( ctx, token );
+   }
+}
+
+
+
+/*
+ * Put a vertex into the feedback buffer.
+ */
+void gl_feedback_vertex( GLcontext *ctx,
+                         GLfloat x, GLfloat y, GLfloat z, GLfloat w,
+                        const GLfloat color[4], GLfloat index,
+                        const GLfloat texcoord[4] )
+{
+   FEEDBACK_TOKEN( ctx, x );
+   FEEDBACK_TOKEN( ctx, y );
+   if (ctx->Feedback.Mask & FB_3D) {
+      FEEDBACK_TOKEN( ctx, z );
+   }
+   if (ctx->Feedback.Mask & FB_4D) {
+      FEEDBACK_TOKEN( ctx, w );
+   }
+   if (ctx->Feedback.Mask & FB_INDEX) {
+      FEEDBACK_TOKEN( ctx, index );
+   }
+   if (ctx->Feedback.Mask & FB_COLOR) {
+      FEEDBACK_TOKEN( ctx, color[0] );
+      FEEDBACK_TOKEN( ctx, color[1] );
+      FEEDBACK_TOKEN( ctx, color[2] );
+      FEEDBACK_TOKEN( ctx, color[3] );
+   }
+   if (ctx->Feedback.Mask & FB_TEXTURE) {
+      FEEDBACK_TOKEN( ctx, texcoord[0] );
+      FEEDBACK_TOKEN( ctx, texcoord[1] );
+      FEEDBACK_TOKEN( ctx, texcoord[2] );
+      FEEDBACK_TOKEN( ctx, texcoord[3] );
+   }
+}
+
+
+
+/**********************************************************************/
+/*                              Selection                             */
+/**********************************************************************/
+
+
+/*
+ * NOTE: this function can't be put in a display list.
+ */
+void gl_SelectBuffer( GLcontext *ctx, GLsizei size, GLuint *buffer )
+{
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glSelectBuffer");
+   if (ctx->RenderMode==GL_SELECT) {
+      gl_error( ctx, GL_INVALID_OPERATION, "glSelectBuffer" );
+   }
+   ctx->Select.Buffer = buffer;
+   ctx->Select.BufferSize = size;
+   ctx->Select.BufferCount = 0;
+
+   ctx->Select.HitFlag = GL_FALSE;
+   ctx->Select.HitMinZ = 1.0;
+   ctx->Select.HitMaxZ = 0.0;
+}
+
+
+#define WRITE_RECORD( CTX, V )                                 \
+       if (CTX->Select.BufferCount < CTX->Select.BufferSize) { \
+          CTX->Select.Buffer[CTX->Select.BufferCount] = (V);   \
+       }                                                       \
+       CTX->Select.BufferCount++;
+
+
+
+void gl_update_hitflag( GLcontext *ctx, GLfloat z )
+{
+   ctx->Select.HitFlag = GL_TRUE;
+   if (z < ctx->Select.HitMinZ) {
+      ctx->Select.HitMinZ = z;
+   }
+   if (z > ctx->Select.HitMaxZ) {
+      ctx->Select.HitMaxZ = z;
+   }
+}
+
+
+
+static void write_hit_record( GLcontext *ctx )
+{
+   GLuint i;
+   GLuint zmin, zmax, zscale = (~0u);
+
+   /* HitMinZ and HitMaxZ are in [0,1].  Multiply these values by */
+   /* 2^32-1 and round to nearest unsigned integer. */
+
+   assert( ctx != NULL ); /* this line magically fixes a SunOS 5.x/gcc bug */
+   zmin = (GLuint) ((GLfloat) zscale * ctx->Select.HitMinZ);
+   zmax = (GLuint) ((GLfloat) zscale * ctx->Select.HitMaxZ);
+
+   WRITE_RECORD( ctx, ctx->Select.NameStackDepth );
+   WRITE_RECORD( ctx, zmin );
+   WRITE_RECORD( ctx, zmax );
+   for (i=0;i<ctx->Select.NameStackDepth;i++) {
+      WRITE_RECORD( ctx, ctx->Select.NameStack[i] );
+   }
+
+   ctx->Select.Hits++;
+   ctx->Select.HitFlag = GL_FALSE;
+   ctx->Select.HitMinZ = 1.0;
+   ctx->Select.HitMaxZ = -1.0;
+}
+
+
+
+void gl_InitNames( GLcontext *ctx )
+{
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glInitNames");
+   /* Record the hit before the HitFlag is wiped out again. */
+   if (ctx->RenderMode==GL_SELECT) {
+      if (ctx->Select.HitFlag) {
+         write_hit_record( ctx );
+      }
+   }
+   ctx->Select.NameStackDepth = 0;
+   ctx->Select.HitFlag = GL_FALSE;
+   ctx->Select.HitMinZ = 1.0;
+   ctx->Select.HitMaxZ = 0.0;
+}
+
+
+
+void gl_LoadName( GLcontext *ctx, GLuint name )
+{
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLoadName");
+   if (ctx->RenderMode!=GL_SELECT) {
+      return;
+   }
+   if (ctx->Select.NameStackDepth==0) {
+      gl_error( ctx, GL_INVALID_OPERATION, "glLoadName" );
+      return;
+   }
+   if (ctx->Select.HitFlag) {
+      write_hit_record( ctx );
+   }
+   if (ctx->Select.NameStackDepth<MAX_NAME_STACK_DEPTH) {
+      ctx->Select.NameStack[ctx->Select.NameStackDepth-1] = name;
+   }
+   else {
+      ctx->Select.NameStack[MAX_NAME_STACK_DEPTH-1] = name;
+   }
+}
+
+
+void gl_PushName( GLcontext *ctx, GLuint name )
+{
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPushName");
+   if (ctx->RenderMode!=GL_SELECT) {
+      return;
+   }
+   if (ctx->Select.HitFlag) {
+      write_hit_record( ctx );
+   }
+   if (ctx->Select.NameStackDepth<MAX_NAME_STACK_DEPTH) {
+      ctx->Select.NameStack[ctx->Select.NameStackDepth++] = name;
+   }
+   else {
+      gl_error( ctx, GL_STACK_OVERFLOW, "glPushName" );
+   }
+}
+
+
+
+void gl_PopName( GLcontext *ctx )
+{
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPopName");
+   if (ctx->RenderMode!=GL_SELECT) {
+      return;
+   }
+   if (ctx->Select.HitFlag) {
+      write_hit_record( ctx );
+   }
+   if (ctx->Select.NameStackDepth>0) {
+      ctx->Select.NameStackDepth--;
+   }
+   else {
+      gl_error( ctx, GL_STACK_UNDERFLOW, "glPopName" );
+   }
+}
+
+
+
+/**********************************************************************/
+/*                           Render Mode                              */
+/**********************************************************************/
+
+
+
+/*
+ * NOTE: this function can't be put in a display list.
+ */
+GLint gl_RenderMode( GLcontext *ctx, GLenum mode )
+{
+   GLint result;
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH_WITH_RETVAL(ctx, "glRenderMode", 0);
+
+   if (MESA_VERBOSE & VERBOSE_API)
+      fprintf(stderr, "glRenderMode %s\n", gl_lookup_enum_by_nr(mode));
+
+   ctx->TriangleCaps &= ~(DD_FEEDBACK|DD_SELECT);
+
+   switch (ctx->RenderMode) {
+      case GL_RENDER:
+        result = 0;
+        break;
+      case GL_SELECT:
+        if (ctx->Select.HitFlag) {
+           write_hit_record( ctx );
+        }
+        if (ctx->Select.BufferCount > ctx->Select.BufferSize) {
+           /* overflow */
+#ifdef DEBUG
+            gl_warning(ctx, "Feedback buffer overflow");
+#endif
+           result = -1;
+        }
+        else {
+           result = ctx->Select.Hits;
+        }
+        ctx->Select.BufferCount = 0;
+        ctx->Select.Hits = 0;
+        ctx->Select.NameStackDepth = 0;
+        break;
+      case GL_FEEDBACK:
+        if (ctx->Feedback.Count > ctx->Feedback.BufferSize) {
+           /* overflow */
+           result = -1;
+        }
+        else {
+           result = ctx->Feedback.Count;
+        }
+        ctx->Feedback.Count = 0;
+        break;
+      default:
+        gl_error( ctx, GL_INVALID_ENUM, "glRenderMode" );
+        return 0;
+   }
+
+   switch (mode) {
+      case GL_RENDER:
+         break;
+      case GL_SELECT:
+        ctx->TriangleCaps |= DD_SELECT;
+        if (ctx->Select.BufferSize==0) {
+           /* haven't called glSelectBuffer yet */
+           gl_error( ctx, GL_INVALID_OPERATION, "glRenderMode" );
+        }
+        break;
+      case GL_FEEDBACK:
+        ctx->TriangleCaps |= DD_FEEDBACK;
+        if (ctx->Feedback.BufferSize==0) {
+           /* haven't called glFeedbackBuffer yet */
+           gl_error( ctx, GL_INVALID_OPERATION, "glRenderMode" );
+        }
+        break;
+      default:
+        gl_error( ctx, GL_INVALID_ENUM, "glRenderMode" );
+        return 0;
+   }
+
+
+   ctx->RenderMode = mode;
+   ctx->NewState |= NEW_ALL;
+
+   return result;
+}
+
diff --git a/src/mesa/main/feedback.h b/src/mesa/main/feedback.h
new file mode 100644 (file)
index 0000000..99a4b7a
--- /dev/null
@@ -0,0 +1,74 @@
+/* $Id: feedback.h,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+#ifndef FEEDBACK_H
+#define FEEDBACK_H
+
+
+#include "types.h"
+
+
+#define FEEDBACK_TOKEN( CTX, T )                               \
+       if (CTX->Feedback.Count < CTX->Feedback.BufferSize) {   \
+          CTX->Feedback.Buffer[CTX->Feedback.Count] = (T);     \
+       }                                                       \
+       CTX->Feedback.Count++;
+
+
+extern void gl_feedback_vertex( GLcontext *ctx,
+                                GLfloat x, GLfloat y, GLfloat z, GLfloat w,
+                                const GLfloat color[4], GLfloat index,
+                                const GLfloat texcoord[4] );
+
+
+extern void gl_update_hitflag( GLcontext *ctx, GLfloat z );
+
+
+extern void gl_PassThrough( GLcontext *ctx, GLfloat token );
+
+extern void gl_FeedbackBuffer( GLcontext *ctx, GLsizei size,
+                               GLenum type, GLfloat *buffer );
+
+extern void gl_SelectBuffer( GLcontext *ctx, GLsizei size, GLuint *buffer );
+
+extern void gl_InitNames( GLcontext *ctx );
+
+extern void gl_LoadName( GLcontext *ctx, GLuint name );
+
+extern void gl_PushName( GLcontext *ctx, GLuint name );
+
+extern void gl_PopName( GLcontext *ctx );
+
+extern GLint gl_RenderMode( GLcontext *ctx, GLenum mode );
+
+
+
+#endif
+
diff --git a/src/mesa/main/fog.c b/src/mesa/main/fog.c
new file mode 100644 (file)
index 0000000..1579c8c
--- /dev/null
@@ -0,0 +1,327 @@
+/* $Id: fog.c,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <math.h>
+#include <stdlib.h>
+#include "context.h"
+#include "fog.h"
+#include "macros.h"
+#include "mmath.h"
+#include "types.h"
+#ifdef XFree86Server
+#include "GL/xf86glx.h"
+#endif
+#endif
+
+
+
+void gl_Fogfv( GLcontext *ctx, GLenum pname, const GLfloat *params )
+{
+   GLenum m;
+
+   switch (pname) {
+      case GL_FOG_MODE:
+         m = (GLenum) (GLint) *params;
+        if (m==GL_LINEAR || m==GL_EXP || m==GL_EXP2) {
+           ctx->Fog.Mode = m;
+        }
+        else {
+           gl_error( ctx, GL_INVALID_ENUM, "glFog" );
+            return;
+        }
+        break;
+      case GL_FOG_DENSITY:
+        if (*params<0.0) {
+           gl_error( ctx, GL_INVALID_VALUE, "glFog" );
+            return;
+        }
+        else {
+           ctx->Fog.Density = *params;
+        }
+        break;
+      case GL_FOG_START:
+#if 0
+         /* Prior to OpenGL 1.1, this was an error */
+         if (*params<0.0F) {
+            gl_error( ctx, GL_INVALID_VALUE, "glFog(GL_FOG_START)" );
+            return;
+         }
+#endif
+        ctx->Fog.Start = *params;
+        break;
+      case GL_FOG_END:
+#if 0
+         /* Prior to OpenGL 1.1, this was an error */
+         if (*params<0.0F) {
+            gl_error( ctx, GL_INVALID_VALUE, "glFog(GL_FOG_END)" );
+            return;
+         }
+#endif
+        ctx->Fog.End = *params;
+        break;
+      case GL_FOG_INDEX:
+        ctx->Fog.Index = *params;
+        break;
+      case GL_FOG_COLOR:
+        ctx->Fog.Color[0] = params[0];
+        ctx->Fog.Color[1] = params[1];
+        ctx->Fog.Color[2] = params[2];
+        ctx->Fog.Color[3] = params[3];
+         break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glFog" );
+         return;
+   }
+
+   if (ctx->Driver.Fogfv) {
+      (*ctx->Driver.Fogfv)( ctx, pname, params );
+   }
+
+   ctx->NewState |= NEW_FOG;
+}
+
+
+typedef void (*fog_func)( struct vertex_buffer *VB, GLuint side, 
+                         GLubyte flag );
+
+
+static fog_func fog_ci_tab[2];
+static fog_func fog_rgba_tab[2];
+
+/*
+ * Compute the fogged color for an array of vertices.
+ * Input:  n - number of vertices
+ *         v - array of vertices
+ *         color - the original vertex colors
+ * Output:  color - the fogged colors
+ * 
+ */
+#define TAG(x) x##_raw
+#define CULLCHECK
+#define IDX 0
+#include "fog_tmp.h"
+
+#define TAG(x) x##_masked
+#define CULLCHECK if (cullmask[i]&flag)
+#define IDX 1
+#include "fog_tmp.h"
+
+void gl_init_fog( void )
+{
+   init_fog_tab_masked();
+   init_fog_tab_raw();
+}
+
+/*
+ * Compute fog for the vertices in the vertex buffer.
+ */
+void gl_fog_vertices( struct vertex_buffer *VB )
+{
+   GLcontext *ctx = VB->ctx;
+   GLuint i = VB->CullMode & 1;
+
+   if (ctx->Visual->RGBAflag) {
+      /* Fog RGB colors */
+      if (ctx->TriangleCaps & DD_TRI_LIGHT_TWOSIDE) {
+        fog_rgba_tab[i]( VB, 0, VERT_FACE_FRONT );
+        fog_rgba_tab[i]( VB, 1, VERT_FACE_REAR );
+      } else {
+        fog_rgba_tab[i]( VB, 0, VERT_FACE_FRONT|VERT_FACE_REAR );
+      }
+   }
+   else {
+      /* Fog color indexes */
+      if (ctx->TriangleCaps & DD_TRI_LIGHT_TWOSIDE) {
+        fog_ci_tab[i]( VB, 0, VERT_FACE_FRONT );
+         fog_ci_tab[i]( VB, 1, VERT_FACE_REAR );
+      } else {
+        fog_ci_tab[i]( VB, 0, VERT_FACE_FRONT|VERT_FACE_REAR );
+      }
+   }
+}
+
+/*
+ * Apply fog to an array of RGBA pixels.
+ * Input:  n - number of pixels
+ *         z - array of integer depth values
+ *         red, green, blue, alpha - pixel colors
+ * Output:  red, green, blue, alpha - fogged pixel colors
+ */
+void gl_fog_rgba_pixels( const GLcontext *ctx,
+                         GLuint n, const GLdepth z[], GLubyte rgba[][4] )
+{
+   GLfloat c = ctx->ProjectionMatrix.m[10];
+   GLfloat d = ctx->ProjectionMatrix.m[14];
+   GLuint i;
+
+   GLfloat rFog = ctx->Fog.Color[0] * 255.0F;
+   GLfloat gFog = ctx->Fog.Color[1] * 255.0F;
+   GLfloat bFog = ctx->Fog.Color[2] * 255.0F;
+
+   GLfloat tz = ctx->Viewport.WindowMap.m[MAT_TZ];
+   GLfloat szInv = 1.0F / ctx->Viewport.WindowMap.m[MAT_SZ];
+
+   switch (ctx->Fog.Mode) {
+      case GL_LINEAR:
+         {
+            GLfloat fogEnd = ctx->Fog.End;
+            GLfloat fogScale = 1.0F / (ctx->Fog.End - ctx->Fog.Start);
+            for (i=0;i<n;i++) {
+               GLfloat ndcz = ((GLfloat) z[i] - tz) * szInv;
+               GLfloat eyez = -d / (c+ndcz);
+               GLfloat f, g;
+               if (eyez < 0.0)  eyez = -eyez;
+               f = (fogEnd - eyez) * fogScale;
+               f = CLAMP( f, 0.0F, 1.0F );
+               g = 1.0F - f;
+               rgba[i][RCOMP] = (GLint) (f * rgba[i][RCOMP] + g * rFog);
+               rgba[i][GCOMP] = (GLint) (f * rgba[i][GCOMP] + g * gFog);
+               rgba[i][BCOMP] = (GLint) (f * rgba[i][BCOMP] + g * bFog);
+            }
+         }
+        break;
+      case GL_EXP:
+        for (i=0;i<n;i++) {
+           GLfloat ndcz = ((GLfloat) z[i] - tz) * szInv;
+           GLfloat eyez = d / (c+ndcz);
+            GLfloat f, g;
+           if (eyez < 0.0)
+               eyez = -eyez;
+           f = exp( -ctx->Fog.Density * eyez );
+            g = 1.0F - f;
+            rgba[i][RCOMP] = (GLint) (f * rgba[i][RCOMP] + g * rFog);
+            rgba[i][GCOMP] = (GLint) (f * rgba[i][GCOMP] + g * gFog);
+            rgba[i][BCOMP] = (GLint) (f * rgba[i][BCOMP] + g * bFog);
+        }
+        break;
+      case GL_EXP2:
+         {
+            GLfloat negDensitySquared = -ctx->Fog.Density * ctx->Fog.Density;
+            for (i=0;i<n;i++) {
+               GLfloat ndcz = ((GLfloat) z[i] - tz) * szInv;
+               GLfloat eyez = d / (c+ndcz);
+               GLfloat f, g;
+               GLfloat tmp = negDensitySquared * eyez * eyez;
+#ifdef __alpha__
+               /* XXX this underflow check may be needed for other systems */
+               if (tmp < FLT_MIN_10_EXP)
+                  f = exp( FLT_MIN_10_EXP );
+               else
+#endif
+                  f = exp( tmp );
+               g = 1.0F - f;
+               rgba[i][RCOMP] = (GLint) (f * rgba[i][RCOMP] + g * rFog);
+               rgba[i][GCOMP] = (GLint) (f * rgba[i][GCOMP] + g * gFog);
+               rgba[i][BCOMP] = (GLint) (f * rgba[i][BCOMP] + g * bFog);
+            }
+         }
+        break;
+      default:
+         gl_problem(ctx, "Bad fog mode in gl_fog_rgba_pixels");
+         return;
+   }
+}
+
+
+
+
+/*
+ * Apply fog to an array of color index pixels.
+ * Input:  n - number of pixels
+ *         z - array of integer depth values
+ *         index - pixel color indexes
+ * Output:  index - fogged pixel color indexes
+ */
+void gl_fog_ci_pixels( const GLcontext *ctx,
+                       GLuint n, const GLdepth z[], GLuint index[] )
+{
+   GLfloat c = ctx->ProjectionMatrix.m[10];
+   GLfloat d = ctx->ProjectionMatrix.m[14];
+   GLuint i;
+
+   GLfloat tz = ctx->Viewport.WindowMap.m[MAT_TZ];
+   GLfloat szInv = 1.0F / ctx->Viewport.WindowMap.m[MAT_SZ];
+
+   switch (ctx->Fog.Mode) {
+      case GL_LINEAR:
+         {
+            GLfloat fogEnd = ctx->Fog.End;
+            GLfloat fogScale = 1.0F / (ctx->Fog.End - ctx->Fog.Start);
+            for (i=0;i<n;i++) {
+               GLfloat ndcz = ((GLfloat) z[i] - tz) * szInv;
+               GLfloat eyez = -d / (c+ndcz);
+               GLfloat f;
+               if (eyez < 0.0)  eyez = -eyez;
+               f = (fogEnd - eyez) * fogScale;
+               f = CLAMP( f, 0.0F, 1.0F );
+               index[i] = (GLuint) ((GLfloat) index[i] + (1.0F-f) * ctx->Fog.Index);
+            }
+        }
+        break;
+      case GL_EXP:
+         for (i=0;i<n;i++) {
+           GLfloat ndcz = ((GLfloat) z[i] - tz) * szInv;
+           GLfloat eyez = -d / (c+ndcz);
+            GLfloat f;
+           if (eyez < 0.0)
+               eyez = -eyez;
+           f = exp( -ctx->Fog.Density * eyez );
+           f = CLAMP( f, 0.0F, 1.0F );
+           index[i] = (GLuint) ((GLfloat) index[i] + (1.0F-f) * ctx->Fog.Index);
+        }
+        break;
+      case GL_EXP2:
+         {
+            GLfloat negDensitySquared = -ctx->Fog.Density * ctx->Fog.Density;
+            for (i=0;i<n;i++) {
+               GLfloat ndcz = ((GLfloat) z[i] - tz) * szInv;
+               GLfloat eyez = -d / (c+ndcz);
+               GLfloat tmp, f;
+               if (eyez < 0.0)
+                  eyez = -eyez;
+               tmp = negDensitySquared * eyez * eyez;
+#ifdef __alpha__
+               /* XXX this underflow check may be needed for other systems */
+               if (tmp < FLT_MIN_10_EXP)
+                  f = exp( FLT_MIN_10_EXP );
+               else
+#endif
+               f = exp( tmp );
+               f = CLAMP( f, 0.0F, 1.0F );
+               index[i] = (GLuint) ((GLfloat) index[i] + (1.0F-f) * ctx->Fog.Index);
+            }
+        }
+        break;
+      default:
+         gl_problem(ctx, "Bad fog mode in gl_fog_ci_pixels");
+         return;
+   }
+}
+
diff --git a/src/mesa/main/fog.h b/src/mesa/main/fog.h
new file mode 100644 (file)
index 0000000..cf9dceb
--- /dev/null
@@ -0,0 +1,51 @@
+/* $Id: fog.h,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+#ifndef FOG_H
+#define FOG_H
+
+
+#include "types.h"
+
+
+extern void gl_Fogfv( GLcontext *ctx, GLenum pname, const GLfloat *params );
+
+
+extern void gl_fog_vertices( struct vertex_buffer *VB );
+
+extern void gl_fog_rgba_pixels( const GLcontext *ctx,
+                                GLuint n, const GLdepth z[],
+                                GLubyte rgba[][4] );
+
+extern void gl_fog_ci_pixels( const GLcontext *ctx,
+                              GLuint n, const GLdepth z[], GLuint indx[] );
+
+
+extern void gl_init_fog( void );
+
+#endif
diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c
new file mode 100644 (file)
index 0000000..65a682c
--- /dev/null
@@ -0,0 +1,3692 @@
+/* $Id: get.c,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include "context.h"
+#include "enable.h"
+#include "enums.h"
+#include "get.h"
+#include "macros.h"
+#include "mmath.h"
+#include "types.h"
+#include "vb.h"
+#ifdef XFree86Server
+#include "GL/xf86glx.h"
+#endif
+#endif
+
+
+
+#define FLOAT_TO_BOOL(X)       ( (X)==0.0F ? GL_FALSE : GL_TRUE )
+#define INT_TO_BOOL(I)         ( (I)==0 ? GL_FALSE : GL_TRUE )
+#define ENUM_TO_BOOL(E)                ( (E)==0 ? GL_FALSE : GL_TRUE )
+
+#ifdef SPECIALCAST
+/* Needed for an Amiga compiler */
+#define ENUM_TO_FLOAT(X) ((GLfloat)(GLint)(X))
+#define ENUM_TO_DOUBLE(X) ((GLdouble)(GLint)(X))
+#else
+/* all other compilers */
+#define ENUM_TO_FLOAT(X) ((GLfloat)(X))
+#define ENUM_TO_DOUBLE(X) ((GLdouble)(X))
+#endif
+
+
+
+void gl_GetBooleanv( GLcontext *ctx, GLenum pname, GLboolean *params )
+{
+   GLuint i;
+   GLuint texUnit = ctx->Texture.CurrentUnit;
+   GLuint texTransformUnit = ctx->Texture.CurrentTransformUnit;
+   const struct gl_texture_unit *textureUnit = &ctx->Texture.Unit[texUnit];
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetBooleanv");
+
+   if (MESA_VERBOSE & VERBOSE_API) 
+      fprintf(stderr, "glGetBooleanv %s\n", gl_lookup_enum_by_nr(pname));
+
+   switch (pname) {
+      case GL_ACCUM_RED_BITS:
+      case GL_ACCUM_GREEN_BITS:
+      case GL_ACCUM_BLUE_BITS:
+      case GL_ACCUM_ALPHA_BITS:
+         *params = INT_TO_BOOL(ctx->Visual->AccumBits);
+         break;
+      case GL_ACCUM_CLEAR_VALUE:
+         params[0] = FLOAT_TO_BOOL(ctx->Accum.ClearColor[0]);
+         params[1] = FLOAT_TO_BOOL(ctx->Accum.ClearColor[1]);
+         params[2] = FLOAT_TO_BOOL(ctx->Accum.ClearColor[2]);
+         params[3] = FLOAT_TO_BOOL(ctx->Accum.ClearColor[3]);
+         break;
+      case GL_ALPHA_BIAS:
+         *params = FLOAT_TO_BOOL(ctx->Pixel.AlphaBias);
+         break;
+      case GL_ALPHA_BITS:
+         *params = INT_TO_BOOL(ctx->Visual->AlphaBits);
+         break;
+      case GL_ALPHA_SCALE:
+         *params = FLOAT_TO_BOOL(ctx->Pixel.AlphaScale);
+         break;
+      case GL_ALPHA_TEST:
+         *params = ctx->Color.AlphaEnabled;
+         break;
+      case GL_ALPHA_TEST_FUNC:
+         *params = ENUM_TO_BOOL(ctx->Color.AlphaFunc);
+         break;
+      case GL_ALPHA_TEST_REF:
+         *params = FLOAT_TO_BOOL((GLfloat) ctx->Color.AlphaRef / 255.0);
+         break;
+      case GL_ATTRIB_STACK_DEPTH:
+         *params = INT_TO_BOOL(ctx->AttribStackDepth);
+         break;
+      case GL_AUTO_NORMAL:
+         *params = ctx->Eval.AutoNormal;
+         break;
+      case GL_AUX_BUFFERS:
+         *params = (NUM_AUX_BUFFERS) ? GL_TRUE : GL_FALSE;
+         break;
+      case GL_BLEND:
+         *params = ctx->Color.BlendEnabled;
+         break;
+      case GL_BLEND_DST:
+         *params = ENUM_TO_BOOL(ctx->Color.BlendDstRGB);
+         break;
+      case GL_BLEND_SRC:
+         *params = ENUM_TO_BOOL(ctx->Color.BlendSrcRGB);
+         break;
+      case GL_BLEND_SRC_RGB_INGR:
+         *params = ENUM_TO_BOOL(ctx->Color.BlendSrcRGB);
+         break;
+      case GL_BLEND_DST_RGB_INGR:
+         *params = ENUM_TO_BOOL(ctx->Color.BlendDstRGB);
+         break;
+      case GL_BLEND_SRC_ALPHA_INGR:
+         *params = ENUM_TO_BOOL(ctx->Color.BlendSrcA);
+         break;
+      case GL_BLEND_DST_ALPHA_INGR:
+         *params = ENUM_TO_BOOL(ctx->Color.BlendDstA);
+         break;
+      case GL_BLEND_EQUATION_EXT:
+        *params = ENUM_TO_BOOL( ctx->Color.BlendEquation );
+        break;
+      case GL_BLEND_COLOR_EXT:
+        params[0] = FLOAT_TO_BOOL( ctx->Color.BlendColor[0] );
+        params[1] = FLOAT_TO_BOOL( ctx->Color.BlendColor[1] );
+        params[2] = FLOAT_TO_BOOL( ctx->Color.BlendColor[2] );
+        params[3] = FLOAT_TO_BOOL( ctx->Color.BlendColor[3] );
+        break;
+      case GL_BLUE_BIAS:
+         *params = FLOAT_TO_BOOL(ctx->Pixel.BlueBias);
+         break;
+      case GL_BLUE_BITS:
+         *params = INT_TO_BOOL( ctx->Visual->BlueBits );
+         break;
+      case GL_BLUE_SCALE:
+         *params = FLOAT_TO_BOOL(ctx->Pixel.BlueScale);
+         break;
+      case GL_CLIENT_ATTRIB_STACK_DEPTH:
+         *params = INT_TO_BOOL(ctx->ClientAttribStackDepth);
+         break;
+      case GL_CLIP_PLANE0:
+      case GL_CLIP_PLANE1:
+      case GL_CLIP_PLANE2:
+      case GL_CLIP_PLANE3:
+      case GL_CLIP_PLANE4:
+      case GL_CLIP_PLANE5:
+         *params = ctx->Transform.ClipEnabled[pname-GL_CLIP_PLANE0];
+         break;
+      case GL_COLOR_CLEAR_VALUE:
+         params[0] = FLOAT_TO_BOOL(ctx->Color.ClearColor[0]);
+         params[1] = FLOAT_TO_BOOL(ctx->Color.ClearColor[1]);
+         params[2] = FLOAT_TO_BOOL(ctx->Color.ClearColor[2]);
+         params[3] = FLOAT_TO_BOOL(ctx->Color.ClearColor[3]);
+         break;
+      case GL_COLOR_MATERIAL:
+         *params = ctx->Light.ColorMaterialEnabled;
+         break;
+      case GL_COLOR_MATERIAL_FACE:
+         *params = ENUM_TO_BOOL(ctx->Light.ColorMaterialFace);
+         break;
+      case GL_COLOR_MATERIAL_PARAMETER:
+         *params = ENUM_TO_BOOL(ctx->Light.ColorMaterialMode);
+         break;
+      case GL_COLOR_WRITEMASK:
+         params[0] = ctx->Color.ColorMask[RCOMP] ? GL_TRUE : GL_FALSE;
+         params[1] = ctx->Color.ColorMask[GCOMP] ? GL_TRUE : GL_FALSE;
+         params[2] = ctx->Color.ColorMask[BCOMP] ? GL_TRUE : GL_FALSE;
+         params[3] = ctx->Color.ColorMask[ACOMP] ? GL_TRUE : GL_FALSE;
+         break;
+      case GL_CULL_FACE:
+         *params = ctx->Polygon.CullFlag;
+         break;
+      case GL_CULL_FACE_MODE:
+         *params = ENUM_TO_BOOL(ctx->Polygon.CullFaceMode);
+         break;
+      case GL_CURRENT_COLOR:
+         params[0] = INT_TO_BOOL(ctx->Current.ByteColor[0]);
+         params[1] = INT_TO_BOOL(ctx->Current.ByteColor[1]);
+         params[2] = INT_TO_BOOL(ctx->Current.ByteColor[2]);
+         params[3] = INT_TO_BOOL(ctx->Current.ByteColor[3]);
+         break;
+      case GL_CURRENT_INDEX:
+         *params = INT_TO_BOOL(ctx->Current.Index);
+         break;
+      case GL_CURRENT_NORMAL:
+         params[0] = FLOAT_TO_BOOL(ctx->Current.Normal[0]);
+         params[1] = FLOAT_TO_BOOL(ctx->Current.Normal[1]);
+         params[2] = FLOAT_TO_BOOL(ctx->Current.Normal[2]);
+         break;
+      case GL_CURRENT_RASTER_COLOR:
+        params[0] = FLOAT_TO_BOOL(ctx->Current.RasterColor[0]);
+        params[1] = FLOAT_TO_BOOL(ctx->Current.RasterColor[1]);
+        params[2] = FLOAT_TO_BOOL(ctx->Current.RasterColor[2]);
+        params[3] = FLOAT_TO_BOOL(ctx->Current.RasterColor[3]);
+        break;
+      case GL_CURRENT_RASTER_DISTANCE:
+        *params = FLOAT_TO_BOOL(ctx->Current.RasterDistance);
+        break;
+      case GL_CURRENT_RASTER_INDEX:
+        *params = FLOAT_TO_BOOL(ctx->Current.RasterIndex);
+        break;
+      case GL_CURRENT_RASTER_POSITION:
+        params[0] = FLOAT_TO_BOOL(ctx->Current.RasterPos[0]);
+        params[1] = FLOAT_TO_BOOL(ctx->Current.RasterPos[1]);
+        params[2] = FLOAT_TO_BOOL(ctx->Current.RasterPos[2]);
+        params[3] = FLOAT_TO_BOOL(ctx->Current.RasterPos[3]);
+        break;
+      case GL_CURRENT_RASTER_TEXTURE_COORDS:
+         params[0] = FLOAT_TO_BOOL(ctx->Current.RasterMultiTexCoord[texTransformUnit][0]);
+         params[1] = FLOAT_TO_BOOL(ctx->Current.RasterMultiTexCoord[texTransformUnit][1]);
+         params[2] = FLOAT_TO_BOOL(ctx->Current.RasterMultiTexCoord[texTransformUnit][2]);
+         params[3] = FLOAT_TO_BOOL(ctx->Current.RasterMultiTexCoord[texTransformUnit][3]);
+        break;
+      case GL_CURRENT_RASTER_POSITION_VALID:
+         *params = ctx->Current.RasterPosValid;
+        break;
+      case GL_CURRENT_TEXTURE_COORDS:
+         params[0] = FLOAT_TO_BOOL(ctx->Current.Texcoord[texTransformUnit][0]);
+         params[1] = FLOAT_TO_BOOL(ctx->Current.Texcoord[texTransformUnit][1]);
+         params[2] = FLOAT_TO_BOOL(ctx->Current.Texcoord[texTransformUnit][2]);
+         params[3] = FLOAT_TO_BOOL(ctx->Current.Texcoord[texTransformUnit][3]);
+        break;
+      case GL_DEPTH_BIAS:
+         *params = FLOAT_TO_BOOL(ctx->Pixel.DepthBias);
+        break;
+      case GL_DEPTH_BITS:
+        *params = INT_TO_BOOL(ctx->Visual->DepthBits);
+        break;
+      case GL_DEPTH_CLEAR_VALUE:
+         *params = FLOAT_TO_BOOL(ctx->Depth.Clear);
+        break;
+      case GL_DEPTH_FUNC:
+         *params = ENUM_TO_BOOL(ctx->Depth.Func);
+        break;
+      case GL_DEPTH_RANGE:
+         params[0] = FLOAT_TO_BOOL(ctx->Viewport.Near);
+         params[1] = FLOAT_TO_BOOL(ctx->Viewport.Far);
+        break;
+      case GL_DEPTH_SCALE:
+         *params = FLOAT_TO_BOOL(ctx->Pixel.DepthScale);
+        break;
+      case GL_DEPTH_TEST:
+         *params = ctx->Depth.Test;
+        break;
+      case GL_DEPTH_WRITEMASK:
+        *params = ctx->Depth.Mask;
+        break;
+      case GL_DITHER:
+        *params = ctx->Color.DitherFlag;
+        break;
+      case GL_DOUBLEBUFFER:
+        *params = ctx->Visual->DBflag;
+        break;
+      case GL_DRAW_BUFFER:
+        *params = ENUM_TO_BOOL(ctx->Color.DrawBuffer);
+        break;
+      case GL_EDGE_FLAG:
+        *params = ctx->Current.EdgeFlag;
+        break;
+      case GL_FEEDBACK_BUFFER_SIZE:
+         /* TODO: is this right?  Or, return number of entries in buffer? */
+         *params = INT_TO_BOOL(ctx->Feedback.BufferSize);
+         break;
+      case GL_FEEDBACK_BUFFER_TYPE:
+         *params = INT_TO_BOOL(ctx->Feedback.Type);
+         break;
+      case GL_FOG:
+        *params = ctx->Fog.Enabled;
+        break;
+      case GL_FOG_COLOR:
+         params[0] = FLOAT_TO_BOOL(ctx->Fog.Color[0]);
+         params[1] = FLOAT_TO_BOOL(ctx->Fog.Color[1]);
+         params[2] = FLOAT_TO_BOOL(ctx->Fog.Color[2]);
+         params[3] = FLOAT_TO_BOOL(ctx->Fog.Color[3]);
+        break;
+      case GL_FOG_DENSITY:
+         *params = FLOAT_TO_BOOL(ctx->Fog.Density);
+        break;
+      case GL_FOG_END:
+         *params = FLOAT_TO_BOOL(ctx->Fog.End);
+        break;
+      case GL_FOG_HINT:
+        *params = ENUM_TO_BOOL(ctx->Hint.Fog);
+        break;
+      case GL_FOG_INDEX:
+        *params = FLOAT_TO_BOOL(ctx->Fog.Index);
+        break;
+      case GL_FOG_MODE:
+        *params = ENUM_TO_BOOL(ctx->Fog.Mode);
+        break;
+      case GL_FOG_START:
+         *params = FLOAT_TO_BOOL(ctx->Fog.End);
+        break;
+      case GL_FRONT_FACE:
+        *params = ENUM_TO_BOOL(ctx->Polygon.FrontFace);
+        break;
+      case GL_GREEN_BIAS:
+         *params = FLOAT_TO_BOOL(ctx->Pixel.GreenBias);
+        break;
+      case GL_GREEN_BITS:
+         *params = INT_TO_BOOL( ctx->Visual->GreenBits );
+        break;
+      case GL_GREEN_SCALE:
+         *params = FLOAT_TO_BOOL(ctx->Pixel.GreenScale);
+        break;
+      case GL_INDEX_BITS:
+         *params = INT_TO_BOOL( ctx->Visual->IndexBits );
+        break;
+      case GL_INDEX_CLEAR_VALUE:
+        *params = INT_TO_BOOL(ctx->Color.ClearIndex);
+        break;
+      case GL_INDEX_MODE:
+        *params = ctx->Visual->RGBAflag ? GL_FALSE : GL_TRUE;
+        break;
+      case GL_INDEX_OFFSET:
+        *params = INT_TO_BOOL(ctx->Pixel.IndexOffset);
+        break;
+      case GL_INDEX_SHIFT:
+        *params = INT_TO_BOOL(ctx->Pixel.IndexShift);
+        break;
+      case GL_INDEX_WRITEMASK:
+        *params = INT_TO_BOOL(ctx->Color.IndexMask);
+        break;
+      case GL_LIGHT0:
+      case GL_LIGHT1:
+      case GL_LIGHT2:
+      case GL_LIGHT3:
+      case GL_LIGHT4:
+      case GL_LIGHT5:
+      case GL_LIGHT6:
+      case GL_LIGHT7:
+        *params = ctx->Light.Light[pname-GL_LIGHT0].Enabled;
+        break;
+      case GL_LIGHTING:
+        *params = ctx->Light.Enabled;
+        break;
+      case GL_LIGHT_MODEL_AMBIENT:
+        params[0] = FLOAT_TO_BOOL(ctx->Light.Model.Ambient[0]);
+        params[1] = FLOAT_TO_BOOL(ctx->Light.Model.Ambient[1]);
+        params[2] = FLOAT_TO_BOOL(ctx->Light.Model.Ambient[2]);
+        params[3] = FLOAT_TO_BOOL(ctx->Light.Model.Ambient[3]);
+        break;
+      case GL_LIGHT_MODEL_COLOR_CONTROL:
+         params[0] = ENUM_TO_BOOL(ctx->Light.Model.ColorControl);
+         break;
+      case GL_LIGHT_MODEL_LOCAL_VIEWER:
+        *params = ctx->Light.Model.LocalViewer;
+        break;
+      case GL_LIGHT_MODEL_TWO_SIDE:
+        *params = ctx->Light.Model.TwoSide;
+        break;
+      case GL_LINE_SMOOTH:
+        *params = ctx->Line.SmoothFlag;
+        break;
+      case GL_LINE_SMOOTH_HINT:
+        *params = ENUM_TO_BOOL(ctx->Hint.LineSmooth);
+        break;
+      case GL_LINE_STIPPLE:
+        *params = ctx->Line.StippleFlag;
+        break;
+      case GL_LINE_STIPPLE_PATTERN:
+        *params = INT_TO_BOOL(ctx->Line.StipplePattern);
+        break;
+      case GL_LINE_STIPPLE_REPEAT:
+        *params = INT_TO_BOOL(ctx->Line.StippleFactor);
+        break;
+      case GL_LINE_WIDTH:
+        *params = FLOAT_TO_BOOL(ctx->Line.Width);
+        break;
+      case GL_LINE_WIDTH_GRANULARITY:
+        *params = FLOAT_TO_BOOL(LINE_WIDTH_GRANULARITY);
+        break;
+      case GL_LINE_WIDTH_RANGE:
+        params[0] = FLOAT_TO_BOOL(MIN_LINE_WIDTH);
+        params[1] = FLOAT_TO_BOOL(MAX_LINE_WIDTH);
+        break;
+      case GL_LIST_BASE:
+        *params = INT_TO_BOOL(ctx->List.ListBase);
+        break;
+      case GL_LIST_INDEX:
+        *params = INT_TO_BOOL( ctx->CurrentListNum );
+        break;
+      case GL_LIST_MODE:
+        *params = ENUM_TO_BOOL( ctx->ExecuteFlag
+                                 ? GL_COMPILE_AND_EXECUTE : GL_COMPILE );
+        break;
+      case GL_INDEX_LOGIC_OP:
+        *params = ctx->Color.IndexLogicOpEnabled;
+        break;
+      case GL_COLOR_LOGIC_OP:
+        *params = ctx->Color.ColorLogicOpEnabled;
+        break;
+      case GL_LOGIC_OP_MODE:
+        *params = ENUM_TO_BOOL(ctx->Color.LogicOp);
+        break;
+      case GL_MAP1_COLOR_4:
+        *params = ctx->Eval.Map1Color4;
+        break;
+      case GL_MAP1_GRID_DOMAIN:
+        params[0] = FLOAT_TO_BOOL(ctx->Eval.MapGrid1u1);
+        params[1] = FLOAT_TO_BOOL(ctx->Eval.MapGrid1u2);
+        break;
+      case GL_MAP1_GRID_SEGMENTS:
+        *params = INT_TO_BOOL(ctx->Eval.MapGrid1un);
+        break;
+      case GL_MAP1_INDEX:
+        *params = ctx->Eval.Map1Index;
+        break;
+      case GL_MAP1_NORMAL:
+        *params = ctx->Eval.Map1Normal;
+        break;
+      case GL_MAP1_TEXTURE_COORD_1:
+        *params = ctx->Eval.Map1TextureCoord1;
+        break;
+      case GL_MAP1_TEXTURE_COORD_2:
+        *params = ctx->Eval.Map1TextureCoord2;
+        break;
+      case GL_MAP1_TEXTURE_COORD_3:
+        *params = ctx->Eval.Map1TextureCoord3;
+        break;
+      case GL_MAP1_TEXTURE_COORD_4:
+        *params = ctx->Eval.Map1TextureCoord4;
+        break;
+      case GL_MAP1_VERTEX_3:
+        *params = ctx->Eval.Map1Vertex3;
+        break;
+      case GL_MAP1_VERTEX_4:
+        *params = ctx->Eval.Map1Vertex4;
+        break;
+      case GL_MAP2_COLOR_4:
+        *params = ctx->Eval.Map2Color4;
+        break;
+      case GL_MAP2_GRID_DOMAIN:
+        params[0] = FLOAT_TO_BOOL(ctx->Eval.MapGrid2u1);
+        params[1] = FLOAT_TO_BOOL(ctx->Eval.MapGrid2u2);
+        params[2] = FLOAT_TO_BOOL(ctx->Eval.MapGrid2v1);
+        params[3] = FLOAT_TO_BOOL(ctx->Eval.MapGrid2v2);
+        break;
+      case GL_MAP2_GRID_SEGMENTS:
+        params[0] = INT_TO_BOOL(ctx->Eval.MapGrid2un);
+        params[1] = INT_TO_BOOL(ctx->Eval.MapGrid2vn);
+        break;
+      case GL_MAP2_INDEX:
+        *params = ctx->Eval.Map2Index;
+        break;
+      case GL_MAP2_NORMAL:
+        *params = ctx->Eval.Map2Normal;
+        break;
+      case GL_MAP2_TEXTURE_COORD_1:
+        *params = ctx->Eval.Map2TextureCoord1;
+        break;
+      case GL_MAP2_TEXTURE_COORD_2:
+        *params = ctx->Eval.Map2TextureCoord2;
+        break;
+      case GL_MAP2_TEXTURE_COORD_3:
+        *params = ctx->Eval.Map2TextureCoord3;
+        break;
+      case GL_MAP2_TEXTURE_COORD_4:
+        *params = ctx->Eval.Map2TextureCoord4;
+        break;
+      case GL_MAP2_VERTEX_3:
+        *params = ctx->Eval.Map2Vertex3;
+        break;
+      case GL_MAP2_VERTEX_4:
+        *params = ctx->Eval.Map2Vertex4;
+        break;
+      case GL_MAP_COLOR:
+        *params = ctx->Pixel.MapColorFlag;
+        break;
+      case GL_MAP_STENCIL:
+        *params = ctx->Pixel.MapStencilFlag;
+        break;
+      case GL_MATRIX_MODE:
+        *params = ENUM_TO_BOOL( ctx->Transform.MatrixMode );
+        break;
+      case GL_MAX_ATTRIB_STACK_DEPTH:
+        *params = INT_TO_BOOL(MAX_ATTRIB_STACK_DEPTH);
+        break;
+      case GL_MAX_CLIENT_ATTRIB_STACK_DEPTH:
+         *params = INT_TO_BOOL( MAX_CLIENT_ATTRIB_STACK_DEPTH);
+         break;
+      case GL_MAX_CLIP_PLANES:
+        *params = INT_TO_BOOL(MAX_CLIP_PLANES);
+        break;
+      case GL_MAX_ELEMENTS_VERTICES:  /* GL_VERSION_1_2 */
+         *params = INT_TO_BOOL(VB_MAX);
+         break;
+      case GL_MAX_ELEMENTS_INDICES:   /* GL_VERSION_1_2 */
+         *params = INT_TO_BOOL(VB_MAX);
+         break;
+      case GL_MAX_EVAL_ORDER:
+        *params = INT_TO_BOOL(MAX_EVAL_ORDER);
+        break;
+      case GL_MAX_LIGHTS:
+        *params = INT_TO_BOOL(MAX_LIGHTS);
+        break;
+      case GL_MAX_LIST_NESTING:
+        *params = INT_TO_BOOL(MAX_LIST_NESTING);
+        break;
+      case GL_MAX_MODELVIEW_STACK_DEPTH:
+        *params = INT_TO_BOOL(MAX_MODELVIEW_STACK_DEPTH);
+        break;
+      case GL_MAX_NAME_STACK_DEPTH:
+        *params = INT_TO_BOOL(MAX_NAME_STACK_DEPTH);
+        break;
+      case GL_MAX_PIXEL_MAP_TABLE:
+        *params = INT_TO_BOOL(MAX_PIXEL_MAP_TABLE);
+        break;
+      case GL_MAX_PROJECTION_STACK_DEPTH:
+        *params = INT_TO_BOOL(MAX_PROJECTION_STACK_DEPTH);
+        break;
+      case GL_MAX_TEXTURE_SIZE:
+      case GL_MAX_3D_TEXTURE_SIZE:
+         *params = INT_TO_BOOL(ctx->Const.MaxTextureSize);
+        break;
+      case GL_MAX_TEXTURE_STACK_DEPTH:
+        *params = INT_TO_BOOL(MAX_TEXTURE_STACK_DEPTH);
+        break;
+      case GL_MAX_VIEWPORT_DIMS:
+        params[0] = INT_TO_BOOL(MAX_WIDTH);
+        params[1] = INT_TO_BOOL(MAX_HEIGHT);
+        break;
+      case GL_MODELVIEW_MATRIX:
+        for (i=0;i<16;i++) {
+           params[i] = FLOAT_TO_BOOL(ctx->ModelView.m[i]);
+        }
+        break;
+      case GL_MODELVIEW_STACK_DEPTH:
+        *params = INT_TO_BOOL(ctx->ModelViewStackDepth + 1);
+        break;
+      case GL_NAME_STACK_DEPTH:
+        *params = INT_TO_BOOL(ctx->Select.NameStackDepth);
+        break;
+      case GL_NORMALIZE:
+        *params = ctx->Transform.Normalize;
+        break;
+      case GL_PACK_ALIGNMENT:
+        *params = INT_TO_BOOL(ctx->Pack.Alignment);
+        break;
+      case GL_PACK_LSB_FIRST:
+        *params = ctx->Pack.LsbFirst;
+        break;
+      case GL_PACK_ROW_LENGTH:
+        *params = INT_TO_BOOL(ctx->Pack.RowLength);
+        break;
+      case GL_PACK_SKIP_PIXELS:
+        *params = INT_TO_BOOL(ctx->Pack.SkipPixels);
+        break;
+      case GL_PACK_SKIP_ROWS:
+        *params = INT_TO_BOOL(ctx->Pack.SkipRows);
+        break;
+      case GL_PACK_SWAP_BYTES:
+        *params = ctx->Pack.SwapBytes;
+        break;
+      case GL_PACK_SKIP_IMAGES_EXT:
+         *params = ctx->Pack.SkipImages;
+         break;
+      case GL_PACK_IMAGE_HEIGHT_EXT:
+         *params = ctx->Pack.ImageHeight;
+         break;
+      case GL_PERSPECTIVE_CORRECTION_HINT:
+        *params = ENUM_TO_BOOL(ctx->Hint.PerspectiveCorrection);
+        break;
+      case GL_PIXEL_MAP_A_TO_A_SIZE:
+        *params = INT_TO_BOOL(ctx->Pixel.MapAtoAsize);
+        break;
+      case GL_PIXEL_MAP_B_TO_B_SIZE:
+        *params = INT_TO_BOOL(ctx->Pixel.MapBtoBsize);
+        break;
+      case GL_PIXEL_MAP_G_TO_G_SIZE:
+        *params = INT_TO_BOOL(ctx->Pixel.MapGtoGsize);
+        break;
+      case GL_PIXEL_MAP_I_TO_A_SIZE:
+        *params = INT_TO_BOOL(ctx->Pixel.MapItoAsize);
+        break;
+      case GL_PIXEL_MAP_I_TO_B_SIZE:
+        *params = INT_TO_BOOL(ctx->Pixel.MapItoBsize);
+        break;
+      case GL_PIXEL_MAP_I_TO_G_SIZE:
+        *params = INT_TO_BOOL(ctx->Pixel.MapItoGsize);
+        break;
+      case GL_PIXEL_MAP_I_TO_I_SIZE:
+        *params = INT_TO_BOOL(ctx->Pixel.MapItoIsize);
+        break;
+      case GL_PIXEL_MAP_I_TO_R_SIZE:
+        *params = INT_TO_BOOL(ctx->Pixel.MapItoRsize);
+        break;
+      case GL_PIXEL_MAP_R_TO_R_SIZE:
+        *params = INT_TO_BOOL(ctx->Pixel.MapRtoRsize);
+        break;
+      case GL_PIXEL_MAP_S_TO_S_SIZE:
+        *params = INT_TO_BOOL(ctx->Pixel.MapStoSsize);
+        break;
+      case GL_POINT_SIZE:
+        *params = FLOAT_TO_BOOL(ctx->Point.Size );
+        break;
+      case GL_POINT_SIZE_GRANULARITY:
+        *params = FLOAT_TO_BOOL(POINT_SIZE_GRANULARITY );
+        break;
+      case GL_POINT_SIZE_RANGE:
+        params[0] = FLOAT_TO_BOOL(MIN_POINT_SIZE );
+        params[1] = FLOAT_TO_BOOL(MAX_POINT_SIZE );
+        break;
+      case GL_POINT_SMOOTH:
+        *params = ctx->Point.SmoothFlag;
+        break;
+      case GL_POINT_SMOOTH_HINT:
+        *params = ENUM_TO_BOOL(ctx->Hint.PointSmooth);
+        break;
+      case GL_POINT_SIZE_MIN_EXT:
+        *params = FLOAT_TO_BOOL(ctx->Point.MinSize);
+        break;
+      case GL_POINT_SIZE_MAX_EXT:
+        *params = FLOAT_TO_BOOL(ctx->Point.MaxSize);
+        break;
+      case GL_POINT_FADE_THRESHOLD_SIZE_EXT:
+        *params = FLOAT_TO_BOOL(ctx->Point.Threshold);
+        break;
+      case GL_DISTANCE_ATTENUATION_EXT:
+        params[0] = FLOAT_TO_BOOL(ctx->Point.Params[0]);
+        params[1] = FLOAT_TO_BOOL(ctx->Point.Params[1]);
+        params[2] = FLOAT_TO_BOOL(ctx->Point.Params[2]);
+        break;
+      case GL_POLYGON_MODE:
+        params[0] = ENUM_TO_BOOL(ctx->Polygon.FrontMode);
+        params[1] = ENUM_TO_BOOL(ctx->Polygon.BackMode);
+        break;
+#ifdef GL_EXT_polygon_offset
+      case GL_POLYGON_OFFSET_BIAS_EXT:
+         *params = FLOAT_TO_BOOL( ctx->Polygon.OffsetUnits );
+         break;
+#endif
+      case GL_POLYGON_OFFSET_FACTOR:
+         *params = FLOAT_TO_BOOL( ctx->Polygon.OffsetFactor );
+         break;
+      case GL_POLYGON_OFFSET_UNITS:
+         *params = FLOAT_TO_BOOL( ctx->Polygon.OffsetUnits );
+         break;
+      case GL_POLYGON_SMOOTH:
+        *params = ctx->Polygon.SmoothFlag;
+        break;
+      case GL_POLYGON_SMOOTH_HINT:
+        *params = ENUM_TO_BOOL(ctx->Hint.PolygonSmooth);
+        break;
+      case GL_POLYGON_STIPPLE:
+        *params = ctx->Polygon.StippleFlag;
+        break;
+      case GL_PROJECTION_MATRIX:
+        for (i=0;i<16;i++) {
+           params[i] = FLOAT_TO_BOOL(ctx->ProjectionMatrix.m[i]);
+        }
+        break;
+      case GL_PROJECTION_STACK_DEPTH:
+        *params = INT_TO_BOOL(ctx->ProjectionStackDepth + 1);
+        break;
+      case GL_READ_BUFFER:
+        *params = ENUM_TO_BOOL(ctx->Pixel.ReadBuffer);
+        break;
+      case GL_RED_BIAS:
+         *params = FLOAT_TO_BOOL(ctx->Pixel.RedBias);
+        break;
+      case GL_RED_BITS:
+         *params = INT_TO_BOOL( ctx->Visual->RedBits );
+        break;
+      case GL_RED_SCALE:
+         *params = FLOAT_TO_BOOL(ctx->Pixel.RedScale);
+        break;
+      case GL_RENDER_MODE:
+        *params = ENUM_TO_BOOL(ctx->RenderMode);
+        break;
+      case GL_RGBA_MODE:
+         *params = ctx->Visual->RGBAflag;
+        break;
+      case GL_SCISSOR_BOX:
+        params[0] = INT_TO_BOOL(ctx->Scissor.X);
+        params[1] = INT_TO_BOOL(ctx->Scissor.Y);
+        params[2] = INT_TO_BOOL(ctx->Scissor.Width);
+        params[3] = INT_TO_BOOL(ctx->Scissor.Height);
+        break;
+      case GL_SCISSOR_TEST:
+        *params = ctx->Scissor.Enabled;
+        break;
+      case GL_SELECTION_BUFFER_SIZE:
+         *params = INT_TO_BOOL(ctx->Select.BufferSize);
+         break;
+      case GL_SHADE_MODEL:
+        *params = ENUM_TO_BOOL(ctx->Light.ShadeModel);
+        break;
+      case GL_SHARED_TEXTURE_PALETTE_EXT:
+         *params = ctx->Texture.SharedPalette;
+         break;
+      case GL_STENCIL_BITS:
+        *params = INT_TO_BOOL(ctx->Visual->StencilBits);
+        break;
+      case GL_STENCIL_CLEAR_VALUE:
+        *params = INT_TO_BOOL(ctx->Stencil.Clear);
+        break;
+      case GL_STENCIL_FAIL:
+        *params = ENUM_TO_BOOL(ctx->Stencil.FailFunc);
+        break;
+      case GL_STENCIL_FUNC:
+        *params = ENUM_TO_BOOL(ctx->Stencil.Function);
+        break;
+      case GL_STENCIL_PASS_DEPTH_FAIL:
+        *params = ENUM_TO_BOOL(ctx->Stencil.ZFailFunc);
+        break;
+      case GL_STENCIL_PASS_DEPTH_PASS:
+        *params = ENUM_TO_BOOL(ctx->Stencil.ZPassFunc);
+        break;
+      case GL_STENCIL_REF:
+        *params = INT_TO_BOOL(ctx->Stencil.Ref);
+        break;
+      case GL_STENCIL_TEST:
+        *params = ctx->Stencil.Enabled;
+        break;
+      case GL_STENCIL_VALUE_MASK:
+        *params = INT_TO_BOOL(ctx->Stencil.ValueMask);
+        break;
+      case GL_STENCIL_WRITEMASK:
+        *params = INT_TO_BOOL(ctx->Stencil.WriteMask);
+        break;
+      case GL_STEREO:
+        *params = ctx->Visual->StereoFlag;
+        break;
+      case GL_SUBPIXEL_BITS:
+        *params = INT_TO_BOOL(0);  /* TODO */
+        break;
+      case GL_TEXTURE_1D:
+         *params = gl_IsEnabled( ctx, GL_TEXTURE_1D );
+        break;
+      case GL_TEXTURE_2D:
+         *params = gl_IsEnabled( ctx, GL_TEXTURE_2D );
+        break;
+      case GL_TEXTURE_3D:
+         *params = gl_IsEnabled( ctx, GL_TEXTURE_3D );
+        break;
+      case GL_TEXTURE_BINDING_1D:
+         *params = INT_TO_BOOL(textureUnit->CurrentD[1]->Name);
+          break;
+      case GL_TEXTURE_BINDING_2D:
+         *params = INT_TO_BOOL(textureUnit->CurrentD[2]->Name);
+          break;
+      case GL_TEXTURE_BINDING_3D:
+         *params = INT_TO_BOOL(textureUnit->CurrentD[3]->Name);
+          break;
+      case GL_TEXTURE_ENV_COLOR:
+         {
+            params[0] = FLOAT_TO_BOOL(textureUnit->EnvColor[0]);
+            params[1] = FLOAT_TO_BOOL(textureUnit->EnvColor[1]);
+            params[2] = FLOAT_TO_BOOL(textureUnit->EnvColor[2]);
+            params[3] = FLOAT_TO_BOOL(textureUnit->EnvColor[3]);
+         }
+        break;
+      case GL_TEXTURE_ENV_MODE:
+        *params = ENUM_TO_BOOL(textureUnit->EnvMode);
+        break;
+      case GL_TEXTURE_GEN_S:
+        *params = (textureUnit->TexGenEnabled & S_BIT) ? GL_TRUE : GL_FALSE;
+        break;
+      case GL_TEXTURE_GEN_T:
+        *params = (textureUnit->TexGenEnabled & T_BIT) ? GL_TRUE : GL_FALSE;
+        break;
+      case GL_TEXTURE_GEN_R:
+        *params = (textureUnit->TexGenEnabled & R_BIT) ? GL_TRUE : GL_FALSE;
+        break;
+      case GL_TEXTURE_GEN_Q:
+        *params = (textureUnit->TexGenEnabled & Q_BIT) ? GL_TRUE : GL_FALSE;
+        break;
+      case GL_TEXTURE_MATRIX:
+        for (i=0;i<16;i++) {
+           params[i] = 
+              FLOAT_TO_BOOL(ctx->TextureMatrix[texTransformUnit].m[i]);
+        }
+        break;
+      case GL_TEXTURE_STACK_DEPTH:
+        *params = INT_TO_BOOL(ctx->TextureStackDepth[texTransformUnit] + 1);
+        break;
+      case GL_UNPACK_ALIGNMENT:
+        *params = INT_TO_BOOL(ctx->Unpack.Alignment);
+        break;
+      case GL_UNPACK_LSB_FIRST:
+        *params = ctx->Unpack.LsbFirst;
+        break;
+      case GL_UNPACK_ROW_LENGTH:
+        *params = INT_TO_BOOL(ctx->Unpack.RowLength);
+        break;
+      case GL_UNPACK_SKIP_PIXELS:
+        *params = INT_TO_BOOL(ctx->Unpack.SkipPixels);
+        break;
+      case GL_UNPACK_SKIP_ROWS:
+        *params = INT_TO_BOOL(ctx->Unpack.SkipRows);
+        break;
+      case GL_UNPACK_SWAP_BYTES:
+        *params = ctx->Unpack.SwapBytes;
+        break;
+      case GL_UNPACK_SKIP_IMAGES_EXT:
+         *params = ctx->Unpack.SkipImages;
+         break;
+      case GL_UNPACK_IMAGE_HEIGHT_EXT:
+         *params = ctx->Unpack.ImageHeight;
+         break;
+      case GL_VIEWPORT:
+        params[0] = INT_TO_BOOL(ctx->Viewport.X);
+        params[1] = INT_TO_BOOL(ctx->Viewport.Y);
+        params[2] = INT_TO_BOOL(ctx->Viewport.Width);
+        params[3] = INT_TO_BOOL(ctx->Viewport.Height);
+        break;
+      case GL_ZOOM_X:
+        *params = FLOAT_TO_BOOL(ctx->Pixel.ZoomX);
+        break;
+      case GL_ZOOM_Y:
+        *params = FLOAT_TO_BOOL(ctx->Pixel.ZoomY);
+        break;
+      case GL_VERTEX_ARRAY_SIZE:
+         *params = INT_TO_BOOL(ctx->Array.Vertex.Size);
+         break;
+      case GL_VERTEX_ARRAY_TYPE:
+         *params = ENUM_TO_BOOL(ctx->Array.Vertex.Type);
+         break;
+      case GL_VERTEX_ARRAY_STRIDE:
+         *params = INT_TO_BOOL(ctx->Array.Vertex.Stride);
+         break;
+      case GL_VERTEX_ARRAY_COUNT_EXT:
+         *params = INT_TO_BOOL(0);
+         break;
+      case GL_NORMAL_ARRAY_TYPE:
+         *params = ENUM_TO_BOOL(ctx->Array.Normal.Type);
+         break;
+      case GL_NORMAL_ARRAY_STRIDE:
+         *params = INT_TO_BOOL(ctx->Array.Normal.Stride);
+         break;
+      case GL_NORMAL_ARRAY_COUNT_EXT:
+         *params = INT_TO_BOOL(0);
+         break;
+      case GL_COLOR_ARRAY_SIZE:
+         *params = INT_TO_BOOL(ctx->Array.Color.Size);
+         break;
+      case GL_COLOR_ARRAY_TYPE:
+         *params = ENUM_TO_BOOL(ctx->Array.Color.Type);
+         break;
+      case GL_COLOR_ARRAY_STRIDE:
+         *params = INT_TO_BOOL(ctx->Array.Color.Stride);
+         break;
+      case GL_COLOR_ARRAY_COUNT_EXT:
+         *params = INT_TO_BOOL(0);
+         break;
+      case GL_INDEX_ARRAY_TYPE:
+         *params = ENUM_TO_BOOL(ctx->Array.Index.Type);
+         break;
+      case GL_INDEX_ARRAY_STRIDE:
+         *params = INT_TO_BOOL(ctx->Array.Index.Stride);
+         break;
+      case GL_INDEX_ARRAY_COUNT_EXT:
+         *params = INT_TO_BOOL(0);
+         break;
+      case GL_TEXTURE_COORD_ARRAY_SIZE:
+         *params = INT_TO_BOOL(ctx->Array.TexCoord[texUnit].Size);
+         break;
+      case GL_TEXTURE_COORD_ARRAY_TYPE:
+         *params = ENUM_TO_BOOL(ctx->Array.TexCoord[texUnit].Type);
+         break;
+      case GL_TEXTURE_COORD_ARRAY_STRIDE:
+         *params = INT_TO_BOOL(ctx->Array.TexCoord[texUnit].Stride);
+         break;
+      case GL_TEXTURE_COORD_ARRAY_COUNT_EXT:
+         *params = INT_TO_BOOL(0);
+         break;
+      case GL_EDGE_FLAG_ARRAY_STRIDE:
+         *params = INT_TO_BOOL(ctx->Array.EdgeFlag.Stride);
+         break;
+      case GL_EDGE_FLAG_ARRAY_EXT:
+         *params = INT_TO_BOOL(0);
+         break;
+
+      case GL_MAX_TEXTURE_UNITS_ARB:
+         *params = ctx->Const.MaxTextureUnits;
+         break;
+      case GL_ACTIVE_TEXTURE_ARB:
+         *params = INT_TO_BOOL(GL_TEXTURE0_ARB + ctx->Texture.CurrentUnit);
+         break;
+      case GL_CLIENT_ACTIVE_TEXTURE_ARB:
+         *params = INT_TO_BOOL(GL_TEXTURE0_ARB + ctx->Array.ActiveTexture);
+         break;
+
+
+      /* GL_PGI_misc_hints */
+      case GL_STRICT_DEPTHFUNC_HINT_PGI:
+        *params = ENUM_TO_BOOL(GL_NICEST);
+         break;
+      case GL_STRICT_LIGHTING_HINT_PGI:
+        *params = ENUM_TO_BOOL(ctx->Hint.StrictLighting);
+        break;
+      case GL_STRICT_SCISSOR_HINT_PGI:
+      case GL_FULL_STIPPLE_HINT_PGI:
+        *params = ENUM_TO_BOOL(GL_TRUE);
+        break;
+      case GL_CONSERVE_MEMORY_HINT_PGI:
+        *params = ENUM_TO_BOOL(GL_FALSE);
+        break;
+      case GL_ALWAYS_FAST_HINT_PGI:
+        *params = (GLboolean) (ctx->Hint.AllowDrawWin == GL_TRUE &&
+                             ctx->Hint.AllowDrawSpn == GL_FALSE && 
+                             ctx->Hint.AllowDrawMem == GL_FALSE);
+        break;
+      case GL_ALWAYS_SOFT_HINT_PGI:
+        *params = (GLboolean) (ctx->Hint.AllowDrawWin == GL_TRUE &&
+                             ctx->Hint.AllowDrawSpn == GL_TRUE && 
+                             ctx->Hint.AllowDrawMem == GL_TRUE);
+        break;
+      case GL_ALLOW_DRAW_OBJ_HINT_PGI:
+        *params = (GLboolean) GL_TRUE;
+        break;
+      case GL_ALLOW_DRAW_WIN_HINT_PGI:
+        *params = (GLboolean) ctx->Hint.AllowDrawWin;
+        break;
+      case GL_ALLOW_DRAW_SPN_HINT_PGI:
+        *params = (GLboolean) ctx->Hint.AllowDrawSpn;
+        break;
+      case GL_ALLOW_DRAW_MEM_HINT_PGI:
+        *params = (GLboolean) ctx->Hint.AllowDrawMem;
+        break;
+      case GL_CLIP_NEAR_HINT_PGI:
+      case GL_CLIP_FAR_HINT_PGI:
+        *params = ENUM_TO_BOOL(GL_TRUE);
+        break;
+      case GL_WIDE_LINE_HINT_PGI:
+        *params = ENUM_TO_BOOL(GL_DONT_CARE);
+        break;
+      case GL_BACK_NORMALS_HINT_PGI:
+        *params = ENUM_TO_BOOL(GL_TRUE);
+        break;
+      case GL_NATIVE_GRAPHICS_HANDLE_PGI:
+        *params = 0;
+        break;
+      default:
+        printf("invalid enum: %x\n", pname);
+         gl_error( ctx, GL_INVALID_ENUM, "glGetBooleanv" );
+   }
+}
+
+
+
+
+void gl_GetDoublev( GLcontext *ctx, GLenum pname, GLdouble *params )
+{
+   GLuint i;
+   GLuint texUnit = ctx->Texture.CurrentUnit;
+   GLuint texTransformUnit = ctx->Texture.CurrentTransformUnit;
+   const struct gl_texture_unit *textureUnit = &ctx->Texture.Unit[texUnit];
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetDoublev");
+
+   if (MESA_VERBOSE & VERBOSE_API) 
+      fprintf(stderr, "glGetDoublev %s\n", gl_lookup_enum_by_nr(pname));
+
+   switch (pname) {
+      case GL_ACCUM_RED_BITS:
+      case GL_ACCUM_GREEN_BITS:
+      case GL_ACCUM_BLUE_BITS:
+      case GL_ACCUM_ALPHA_BITS:
+         *params = (GLdouble) ctx->Visual->AccumBits;
+         break;
+      case GL_ACCUM_CLEAR_VALUE:
+         params[0] = (GLdouble) ctx->Accum.ClearColor[0];
+         params[1] = (GLdouble) ctx->Accum.ClearColor[1];
+         params[2] = (GLdouble) ctx->Accum.ClearColor[2];
+         params[3] = (GLdouble) ctx->Accum.ClearColor[3];
+         break;
+      case GL_ALPHA_BIAS:
+         *params = (GLdouble) ctx->Pixel.AlphaBias;
+         break;
+      case GL_ALPHA_BITS:
+         *params = (GLdouble) ctx->Visual->AlphaBits;
+         break;
+      case GL_ALPHA_SCALE:
+         *params = (GLdouble) ctx->Pixel.AlphaScale;
+         break;
+      case GL_ALPHA_TEST:
+         *params = (GLdouble) ctx->Color.AlphaEnabled;
+         break;
+      case GL_ALPHA_TEST_FUNC:
+         *params = ENUM_TO_DOUBLE(ctx->Color.AlphaFunc);
+         break;
+      case GL_ALPHA_TEST_REF:
+         *params = (GLdouble) ctx->Color.AlphaRef / 255.0;
+         break;
+      case GL_ATTRIB_STACK_DEPTH:
+         *params = (GLdouble ) (ctx->AttribStackDepth);
+         break;
+      case GL_AUTO_NORMAL:
+         *params = (GLdouble) ctx->Eval.AutoNormal;
+         break;
+      case GL_AUX_BUFFERS:
+         *params = (GLdouble) NUM_AUX_BUFFERS;
+         break;
+      case GL_BLEND:
+         *params = (GLdouble) ctx->Color.BlendEnabled;
+         break;
+      case GL_BLEND_DST:
+         *params = ENUM_TO_DOUBLE(ctx->Color.BlendDstRGB);
+         break;
+      case GL_BLEND_SRC:
+         *params = ENUM_TO_DOUBLE(ctx->Color.BlendSrcRGB);
+         break;
+      case GL_BLEND_SRC_RGB_INGR:
+         *params = ENUM_TO_DOUBLE(ctx->Color.BlendSrcRGB);
+         break;
+      case GL_BLEND_DST_RGB_INGR:
+         *params = ENUM_TO_DOUBLE(ctx->Color.BlendDstRGB);
+         break;
+      case GL_BLEND_SRC_ALPHA_INGR:
+         *params = ENUM_TO_DOUBLE(ctx->Color.BlendSrcA);
+         break;
+      case GL_BLEND_DST_ALPHA_INGR:
+         *params = ENUM_TO_DOUBLE(ctx->Color.BlendDstA);
+         break;
+      case GL_BLEND_EQUATION_EXT:
+        *params = ENUM_TO_DOUBLE(ctx->Color.BlendEquation);
+        break;
+      case GL_BLEND_COLOR_EXT:
+        params[0] = (GLdouble) ctx->Color.BlendColor[0];
+        params[1] = (GLdouble) ctx->Color.BlendColor[1];
+        params[2] = (GLdouble) ctx->Color.BlendColor[2];
+        params[3] = (GLdouble) ctx->Color.BlendColor[3];
+        break;
+      case GL_BLUE_BIAS:
+         *params = (GLdouble) ctx->Pixel.BlueBias;
+         break;
+      case GL_BLUE_BITS:
+         *params = (GLdouble) ctx->Visual->BlueBits;
+         break;
+      case GL_BLUE_SCALE:
+         *params = (GLdouble) ctx->Pixel.BlueScale;
+         break;
+      case GL_CLIENT_ATTRIB_STACK_DEPTH:
+         *params = (GLdouble) (ctx->ClientAttribStackDepth);
+         break;
+      case GL_CLIP_PLANE0:
+      case GL_CLIP_PLANE1:
+      case GL_CLIP_PLANE2:
+      case GL_CLIP_PLANE3:
+      case GL_CLIP_PLANE4:
+      case GL_CLIP_PLANE5:
+         *params = (GLdouble) ctx->Transform.ClipEnabled[pname-GL_CLIP_PLANE0];
+         break;
+      case GL_COLOR_CLEAR_VALUE:
+         params[0] = (GLdouble) ctx->Color.ClearColor[0];
+         params[1] = (GLdouble) ctx->Color.ClearColor[1];
+         params[2] = (GLdouble) ctx->Color.ClearColor[2];
+         params[3] = (GLdouble) ctx->Color.ClearColor[3];
+         break;
+      case GL_COLOR_MATERIAL:
+         *params = (GLdouble) ctx->Light.ColorMaterialEnabled;
+         break;
+      case GL_COLOR_MATERIAL_FACE:
+         *params = ENUM_TO_DOUBLE(ctx->Light.ColorMaterialFace);
+         break;
+      case GL_COLOR_MATERIAL_PARAMETER:
+         *params = ENUM_TO_DOUBLE(ctx->Light.ColorMaterialMode);
+         break;
+      case GL_COLOR_WRITEMASK:
+         params[0] = ctx->Color.ColorMask[RCOMP] ? 1.0 : 0.0;
+         params[1] = ctx->Color.ColorMask[GCOMP] ? 1.0 : 0.0;
+         params[2] = ctx->Color.ColorMask[BCOMP] ? 1.0 : 0.0;
+         params[3] = ctx->Color.ColorMask[ACOMP] ? 1.0 : 0.0;
+         break;
+      case GL_CULL_FACE:
+         *params = (GLdouble) ctx->Polygon.CullFlag;
+         break;
+      case GL_CULL_FACE_MODE:
+         *params = ENUM_TO_DOUBLE(ctx->Polygon.CullFaceMode);
+         break;
+      case GL_CURRENT_COLOR:
+         params[0] = UBYTE_COLOR_TO_FLOAT_COLOR(ctx->Current.ByteColor[0]);
+         params[1] = UBYTE_COLOR_TO_FLOAT_COLOR(ctx->Current.ByteColor[1]);
+         params[2] = UBYTE_COLOR_TO_FLOAT_COLOR(ctx->Current.ByteColor[2]);
+         params[3] = UBYTE_COLOR_TO_FLOAT_COLOR(ctx->Current.ByteColor[3]);
+         break;
+      case GL_CURRENT_INDEX:
+         *params = (GLdouble) ctx->Current.Index;
+         break;
+      case GL_CURRENT_NORMAL:
+         params[0] = (GLdouble) ctx->Current.Normal[0];
+         params[1] = (GLdouble) ctx->Current.Normal[1];
+         params[2] = (GLdouble) ctx->Current.Normal[2];
+         break;
+      case GL_CURRENT_RASTER_COLOR:
+        params[0] = (GLdouble) ctx->Current.RasterColor[0];
+        params[1] = (GLdouble) ctx->Current.RasterColor[1];
+        params[2] = (GLdouble) ctx->Current.RasterColor[2];
+        params[3] = (GLdouble) ctx->Current.RasterColor[3];
+        break;
+      case GL_CURRENT_RASTER_DISTANCE:
+        params[0] = (GLdouble) ctx->Current.RasterDistance;
+        break;
+      case GL_CURRENT_RASTER_INDEX:
+        *params = (GLdouble) ctx->Current.RasterIndex;
+        break;
+      case GL_CURRENT_RASTER_POSITION:
+        params[0] = (GLdouble) ctx->Current.RasterPos[0];
+        params[1] = (GLdouble) ctx->Current.RasterPos[1];
+        params[2] = (GLdouble) ctx->Current.RasterPos[2];
+        params[3] = (GLdouble) ctx->Current.RasterPos[3];
+        break;
+      case GL_CURRENT_RASTER_TEXTURE_COORDS:
+        params[0] = (GLdouble) ctx->Current.RasterMultiTexCoord[texTransformUnit][0];
+        params[1] = (GLdouble) ctx->Current.RasterMultiTexCoord[texTransformUnit][1];
+        params[2] = (GLdouble) ctx->Current.RasterMultiTexCoord[texTransformUnit][2];
+        params[3] = (GLdouble) ctx->Current.RasterMultiTexCoord[texTransformUnit][3];
+        break;
+      case GL_CURRENT_RASTER_POSITION_VALID:
+        *params = (GLdouble) ctx->Current.RasterPosValid;
+        break;
+      case GL_CURRENT_TEXTURE_COORDS:
+        params[0] = (GLdouble) ctx->Current.Texcoord[texTransformUnit][0];
+        params[1] = (GLdouble) ctx->Current.Texcoord[texTransformUnit][1];
+        params[2] = (GLdouble) ctx->Current.Texcoord[texTransformUnit][2];
+        params[3] = (GLdouble) ctx->Current.Texcoord[texTransformUnit][3];
+        break;
+      case GL_DEPTH_BIAS:
+        *params = (GLdouble) ctx->Pixel.DepthBias;
+        break;
+      case GL_DEPTH_BITS:
+        *params = (GLdouble) ctx->Visual->DepthBits;
+        break;
+      case GL_DEPTH_CLEAR_VALUE:
+        *params = (GLdouble) ctx->Depth.Clear;
+        break;
+      case GL_DEPTH_FUNC:
+        *params = ENUM_TO_DOUBLE(ctx->Depth.Func);
+        break;
+      case GL_DEPTH_RANGE:
+         params[0] = (GLdouble) ctx->Viewport.Near;
+         params[1] = (GLdouble) ctx->Viewport.Far;
+        break;
+      case GL_DEPTH_SCALE:
+        *params = (GLdouble) ctx->Pixel.DepthScale;
+        break;
+      case GL_DEPTH_TEST:
+        *params = (GLdouble) ctx->Depth.Test;
+        break;
+      case GL_DEPTH_WRITEMASK:
+        *params = (GLdouble) ctx->Depth.Mask;
+        break;
+      case GL_DITHER:
+        *params = (GLdouble) ctx->Color.DitherFlag;
+        break;
+      case GL_DOUBLEBUFFER:
+        *params = (GLdouble) ctx->Visual->DBflag;
+        break;
+      case GL_DRAW_BUFFER:
+        *params = ENUM_TO_DOUBLE(ctx->Color.DrawBuffer);
+        break;
+      case GL_EDGE_FLAG:
+        *params = (GLdouble) ctx->Current.EdgeFlag;
+        break;
+      case GL_FEEDBACK_BUFFER_SIZE:
+         /* TODO: is this right?  Or, return number of entries in buffer? */
+         *params = (GLdouble) ctx->Feedback.BufferSize;
+         break;
+      case GL_FEEDBACK_BUFFER_TYPE:
+         *params = ENUM_TO_DOUBLE(ctx->Feedback.Type);
+         break;
+      case GL_FOG:
+        *params = (GLdouble) ctx->Fog.Enabled;
+        break;
+      case GL_FOG_COLOR:
+        params[0] = (GLdouble) ctx->Fog.Color[0];
+        params[1] = (GLdouble) ctx->Fog.Color[1];
+        params[2] = (GLdouble) ctx->Fog.Color[2];
+        params[3] = (GLdouble) ctx->Fog.Color[3];
+        break;
+      case GL_FOG_DENSITY:
+        *params = (GLdouble) ctx->Fog.Density;
+        break;
+      case GL_FOG_END:
+        *params = (GLdouble) ctx->Fog.End;
+        break;
+      case GL_FOG_HINT:
+        *params = ENUM_TO_DOUBLE(ctx->Hint.Fog);
+        break;
+      case GL_FOG_INDEX:
+        *params = (GLdouble) ctx->Fog.Index;
+        break;
+      case GL_FOG_MODE:
+        *params = ENUM_TO_DOUBLE(ctx->Fog.Mode);
+        break;
+      case GL_FOG_START:
+        *params = (GLdouble) ctx->Fog.Start;
+        break;
+      case GL_FRONT_FACE:
+        *params = ENUM_TO_DOUBLE(ctx->Polygon.FrontFace);
+        break;
+      case GL_GREEN_BIAS:
+         *params = (GLdouble) ctx->Pixel.GreenBias;
+         break;
+      case GL_GREEN_BITS:
+         *params = (GLdouble) ctx->Visual->GreenBits;
+         break;
+      case GL_GREEN_SCALE:
+         *params = (GLdouble) ctx->Pixel.GreenScale;
+         break;
+      case GL_INDEX_BITS:
+         *params = (GLdouble) ctx->Visual->IndexBits;
+        break;
+      case GL_INDEX_CLEAR_VALUE:
+         *params = (GLdouble) ctx->Color.ClearIndex;
+        break;
+      case GL_INDEX_MODE:
+        *params = ctx->Visual->RGBAflag ? 0.0 : 1.0;
+        break;
+      case GL_INDEX_OFFSET:
+        *params = (GLdouble) ctx->Pixel.IndexOffset;
+        break;
+      case GL_INDEX_SHIFT:
+        *params = (GLdouble) ctx->Pixel.IndexShift;
+        break;
+      case GL_INDEX_WRITEMASK:
+        *params = (GLdouble) ctx->Color.IndexMask;
+        break;
+      case GL_LIGHT0:
+      case GL_LIGHT1:
+      case GL_LIGHT2:
+      case GL_LIGHT3:
+      case GL_LIGHT4:
+      case GL_LIGHT5:
+      case GL_LIGHT6:
+      case GL_LIGHT7:
+        *params = (GLdouble) ctx->Light.Light[pname-GL_LIGHT0].Enabled;
+        break;
+      case GL_LIGHTING:
+        *params = (GLdouble) ctx->Light.Enabled;
+        break;
+      case GL_LIGHT_MODEL_AMBIENT:
+        params[0] = (GLdouble) ctx->Light.Model.Ambient[0];
+        params[1] = (GLdouble) ctx->Light.Model.Ambient[1];
+        params[2] = (GLdouble) ctx->Light.Model.Ambient[2];
+        params[3] = (GLdouble) ctx->Light.Model.Ambient[3];
+        break;
+      case GL_LIGHT_MODEL_COLOR_CONTROL:
+         params[0] = (GLdouble) ctx->Light.Model.ColorControl;
+         break;
+      case GL_LIGHT_MODEL_LOCAL_VIEWER:
+        *params = (GLdouble) ctx->Light.Model.LocalViewer;
+        break;
+      case GL_LIGHT_MODEL_TWO_SIDE:
+        *params = (GLdouble) ctx->Light.Model.TwoSide;
+        break;
+      case GL_LINE_SMOOTH:
+        *params = (GLdouble) ctx->Line.SmoothFlag;
+        break;
+      case GL_LINE_SMOOTH_HINT:
+        *params = ENUM_TO_DOUBLE(ctx->Hint.LineSmooth);
+        break;
+      case GL_LINE_STIPPLE:
+        *params = (GLdouble) ctx->Line.StippleFlag;
+        break;
+      case GL_LINE_STIPPLE_PATTERN:
+         *params = (GLdouble) ctx->Line.StipplePattern;
+         break;
+      case GL_LINE_STIPPLE_REPEAT:
+         *params = (GLdouble) ctx->Line.StippleFactor;
+         break;
+      case GL_LINE_WIDTH:
+        *params = (GLdouble) ctx->Line.Width;
+        break;
+      case GL_LINE_WIDTH_GRANULARITY:
+        *params = (GLdouble) LINE_WIDTH_GRANULARITY;
+        break;
+      case GL_LINE_WIDTH_RANGE:
+        params[0] = (GLdouble) MIN_LINE_WIDTH;
+        params[1] = (GLdouble) MAX_LINE_WIDTH;
+        break;
+      case GL_LIST_BASE:
+        *params = (GLdouble) ctx->List.ListBase;
+        break;
+      case GL_LIST_INDEX:
+        *params = (GLdouble) ctx->CurrentListNum;
+        break;
+      case GL_LIST_MODE:
+        *params = ctx->ExecuteFlag ? ENUM_TO_DOUBLE(GL_COMPILE_AND_EXECUTE)
+                                 : ENUM_TO_DOUBLE(GL_COMPILE);
+        break;
+      case GL_INDEX_LOGIC_OP:
+        *params = (GLdouble) ctx->Color.IndexLogicOpEnabled;
+        break;
+      case GL_COLOR_LOGIC_OP:
+        *params = (GLdouble) ctx->Color.ColorLogicOpEnabled;
+        break;
+      case GL_LOGIC_OP_MODE:
+         *params = ENUM_TO_DOUBLE(ctx->Color.LogicOp);
+        break;
+      case GL_MAP1_COLOR_4:
+        *params = (GLdouble) ctx->Eval.Map1Color4;
+        break;
+      case GL_MAP1_GRID_DOMAIN:
+        params[0] = (GLdouble) ctx->Eval.MapGrid1u1;
+        params[1] = (GLdouble) ctx->Eval.MapGrid1u2;
+        break;
+      case GL_MAP1_GRID_SEGMENTS:
+        *params = (GLdouble) ctx->Eval.MapGrid1un;
+        break;
+      case GL_MAP1_INDEX:
+        *params = (GLdouble) ctx->Eval.Map1Index;
+        break;
+      case GL_MAP1_NORMAL:
+        *params = (GLdouble) ctx->Eval.Map1Normal;
+        break;
+      case GL_MAP1_TEXTURE_COORD_1:
+        *params = (GLdouble) ctx->Eval.Map1TextureCoord1;
+        break;
+      case GL_MAP1_TEXTURE_COORD_2:
+        *params = (GLdouble) ctx->Eval.Map1TextureCoord2;
+        break;
+      case GL_MAP1_TEXTURE_COORD_3:
+        *params = (GLdouble) ctx->Eval.Map1TextureCoord3;
+        break;
+      case GL_MAP1_TEXTURE_COORD_4:
+        *params = (GLdouble) ctx->Eval.Map1TextureCoord4;
+        break;
+      case GL_MAP1_VERTEX_3:
+        *params = (GLdouble) ctx->Eval.Map1Vertex3;
+        break;
+      case GL_MAP1_VERTEX_4:
+        *params = (GLdouble) ctx->Eval.Map1Vertex4;
+        break;
+      case GL_MAP2_COLOR_4:
+        *params = (GLdouble) ctx->Eval.Map2Color4;
+        break;
+      case GL_MAP2_GRID_DOMAIN:
+        params[0] = (GLdouble) ctx->Eval.MapGrid2u1;
+        params[1] = (GLdouble) ctx->Eval.MapGrid2u2;
+        params[2] = (GLdouble) ctx->Eval.MapGrid2v1;
+        params[3] = (GLdouble) ctx->Eval.MapGrid2v2;
+        break;
+      case GL_MAP2_GRID_SEGMENTS:
+        params[0] = (GLdouble) ctx->Eval.MapGrid2un;
+        params[1] = (GLdouble) ctx->Eval.MapGrid2vn;
+        break;
+      case GL_MAP2_INDEX:
+        *params = (GLdouble) ctx->Eval.Map2Index;
+        break;
+      case GL_MAP2_NORMAL:
+        *params = (GLdouble) ctx->Eval.Map2Normal;
+        break;
+      case GL_MAP2_TEXTURE_COORD_1:
+        *params = (GLdouble) ctx->Eval.Map2TextureCoord1;
+        break;
+      case GL_MAP2_TEXTURE_COORD_2:
+        *params = (GLdouble) ctx->Eval.Map2TextureCoord2;
+        break;
+      case GL_MAP2_TEXTURE_COORD_3:
+        *params = (GLdouble) ctx->Eval.Map2TextureCoord3;
+        break;
+      case GL_MAP2_TEXTURE_COORD_4:
+        *params = (GLdouble) ctx->Eval.Map2TextureCoord4;
+        break;
+      case GL_MAP2_VERTEX_3:
+        *params = (GLdouble) ctx->Eval.Map2Vertex3;
+        break;
+      case GL_MAP2_VERTEX_4:
+        *params = (GLdouble) ctx->Eval.Map2Vertex4;
+        break;
+      case GL_MAP_COLOR:
+        *params = (GLdouble) ctx->Pixel.MapColorFlag;
+        break;
+      case GL_MAP_STENCIL:
+        *params = (GLdouble) ctx->Pixel.MapStencilFlag;
+        break;
+      case GL_MATRIX_MODE:
+        *params = ENUM_TO_DOUBLE(ctx->Transform.MatrixMode);
+        break;
+      case GL_MAX_ATTRIB_STACK_DEPTH:
+        *params = (GLdouble) MAX_ATTRIB_STACK_DEPTH;
+        break;
+      case GL_MAX_CLIENT_ATTRIB_STACK_DEPTH:
+         *params = (GLdouble) MAX_CLIENT_ATTRIB_STACK_DEPTH;
+         break;
+      case GL_MAX_CLIP_PLANES:
+        *params = (GLdouble) MAX_CLIP_PLANES;
+        break;
+      case GL_MAX_ELEMENTS_VERTICES:  /* GL_VERSION_1_2 */
+         *params = (GLdouble) VB_MAX;
+         break;
+      case GL_MAX_ELEMENTS_INDICES:   /* GL_VERSION_1_2 */
+         *params = (GLdouble) VB_MAX;
+         break;
+      case GL_MAX_EVAL_ORDER:
+        *params = (GLdouble) MAX_EVAL_ORDER;
+        break;
+      case GL_MAX_LIGHTS:
+        *params = (GLdouble) MAX_LIGHTS;
+        break;
+      case GL_MAX_LIST_NESTING:
+        *params = (GLdouble) MAX_LIST_NESTING;
+        break;
+      case GL_MAX_MODELVIEW_STACK_DEPTH:
+        *params = (GLdouble) MAX_MODELVIEW_STACK_DEPTH;
+        break;
+      case GL_MAX_NAME_STACK_DEPTH:
+        *params = (GLdouble) MAX_NAME_STACK_DEPTH;
+        break;
+      case GL_MAX_PIXEL_MAP_TABLE:
+        *params = (GLdouble) MAX_PIXEL_MAP_TABLE;
+        break;
+      case GL_MAX_PROJECTION_STACK_DEPTH:
+        *params = (GLdouble) MAX_PROJECTION_STACK_DEPTH;
+        break;
+      case GL_MAX_TEXTURE_SIZE:
+      case GL_MAX_3D_TEXTURE_SIZE:
+         *params = (GLdouble) ctx->Const.MaxTextureSize;
+        break;
+      case GL_MAX_TEXTURE_STACK_DEPTH:
+        *params = (GLdouble) MAX_TEXTURE_STACK_DEPTH;
+        break;
+      case GL_MAX_VIEWPORT_DIMS:
+         params[0] = (GLdouble) MAX_WIDTH;
+         params[1] = (GLdouble) MAX_HEIGHT;
+         break;
+      case GL_MODELVIEW_MATRIX:
+        for (i=0;i<16;i++) {
+           params[i] = (GLdouble) ctx->ModelView.m[i];
+        }
+        break;
+      case GL_MODELVIEW_STACK_DEPTH:
+        *params = (GLdouble) (ctx->ModelViewStackDepth + 1);
+        break;
+      case GL_NAME_STACK_DEPTH:
+        *params = (GLdouble) ctx->Select.NameStackDepth;
+        break;
+      case GL_NORMALIZE:
+        *params = (GLdouble) ctx->Transform.Normalize;
+        break;
+      case GL_PACK_ALIGNMENT:
+        *params = (GLdouble) ctx->Pack.Alignment;
+        break;
+      case GL_PACK_LSB_FIRST:
+        *params = (GLdouble) ctx->Pack.LsbFirst;
+        break;
+      case GL_PACK_ROW_LENGTH:
+        *params = (GLdouble) ctx->Pack.RowLength;
+        break;
+      case GL_PACK_SKIP_PIXELS:
+        *params = (GLdouble) ctx->Pack.SkipPixels;
+        break;
+      case GL_PACK_SKIP_ROWS:
+        *params = (GLdouble) ctx->Pack.SkipRows;
+        break;
+      case GL_PACK_SWAP_BYTES:
+        *params = (GLdouble) ctx->Pack.SwapBytes;
+        break;
+      case GL_PACK_SKIP_IMAGES_EXT:
+         *params = (GLdouble) ctx->Pack.SkipImages;
+         break;
+      case GL_PACK_IMAGE_HEIGHT_EXT:
+         *params = (GLdouble) ctx->Pack.ImageHeight;
+         break;
+      case GL_PERSPECTIVE_CORRECTION_HINT:
+        *params = ENUM_TO_DOUBLE(ctx->Hint.PerspectiveCorrection);
+        break;
+      case GL_PIXEL_MAP_A_TO_A_SIZE:
+        *params = (GLdouble) ctx->Pixel.MapAtoAsize;
+        break;
+      case GL_PIXEL_MAP_B_TO_B_SIZE:
+        *params = (GLdouble) ctx->Pixel.MapBtoBsize;
+        break;
+      case GL_PIXEL_MAP_G_TO_G_SIZE:
+        *params = (GLdouble) ctx->Pixel.MapGtoGsize;
+        break;
+      case GL_PIXEL_MAP_I_TO_A_SIZE:
+        *params = (GLdouble) ctx->Pixel.MapItoAsize;
+        break;
+      case GL_PIXEL_MAP_I_TO_B_SIZE:
+        *params = (GLdouble) ctx->Pixel.MapItoBsize;
+        break;
+      case GL_PIXEL_MAP_I_TO_G_SIZE:
+        *params = (GLdouble) ctx->Pixel.MapItoGsize;
+        break;
+      case GL_PIXEL_MAP_I_TO_I_SIZE:
+        *params = (GLdouble) ctx->Pixel.MapItoIsize;
+        break;
+      case GL_PIXEL_MAP_I_TO_R_SIZE:
+        *params = (GLdouble) ctx->Pixel.MapItoRsize;
+        break;
+      case GL_PIXEL_MAP_R_TO_R_SIZE:
+        *params = (GLdouble) ctx->Pixel.MapRtoRsize;
+        break;
+      case GL_PIXEL_MAP_S_TO_S_SIZE:
+        *params = (GLdouble) ctx->Pixel.MapStoSsize;
+        break;
+      case GL_POINT_SIZE:
+         *params = (GLdouble) ctx->Point.Size;
+         break;
+      case GL_POINT_SIZE_GRANULARITY:
+        *params = (GLdouble) POINT_SIZE_GRANULARITY;
+        break;
+      case GL_POINT_SIZE_RANGE:
+        params[0] = (GLdouble) MIN_POINT_SIZE;
+        params[1] = (GLdouble) MAX_POINT_SIZE;
+        break;
+      case GL_POINT_SMOOTH:
+        *params = (GLdouble) ctx->Point.SmoothFlag;
+        break;
+      case GL_POINT_SMOOTH_HINT:
+        *params = ENUM_TO_DOUBLE(ctx->Hint.PointSmooth);
+        break;
+      case GL_POINT_SIZE_MIN_EXT:
+        *params = (GLdouble) (ctx->Point.MinSize);
+        break;
+      case GL_POINT_SIZE_MAX_EXT:
+        *params = (GLdouble) (ctx->Point.MaxSize);
+        break;
+      case GL_POINT_FADE_THRESHOLD_SIZE_EXT:
+        *params = (GLdouble) (ctx->Point.Threshold);
+        break;
+      case GL_DISTANCE_ATTENUATION_EXT:
+        params[0] = (GLdouble) (ctx->Point.Params[0]);
+        params[1] = (GLdouble) (ctx->Point.Params[1]);
+        params[2] = (GLdouble) (ctx->Point.Params[2]);
+        break;
+      case GL_POLYGON_MODE:
+        params[0] = ENUM_TO_DOUBLE(ctx->Polygon.FrontMode);
+        params[1] = ENUM_TO_DOUBLE(ctx->Polygon.BackMode);
+        break;
+#ifdef GL_EXT_polygon_offset
+      case GL_POLYGON_OFFSET_BIAS_EXT:
+         *params = (GLdouble) ctx->Polygon.OffsetUnits;
+         break;
+#endif
+      case GL_POLYGON_OFFSET_FACTOR:
+         *params = (GLdouble) ctx->Polygon.OffsetFactor;
+         break;
+      case GL_POLYGON_OFFSET_UNITS:
+         *params = (GLdouble) ctx->Polygon.OffsetUnits;
+         break;
+      case GL_POLYGON_SMOOTH:
+        *params = (GLdouble) ctx->Polygon.SmoothFlag;
+        break;
+      case GL_POLYGON_SMOOTH_HINT:
+        *params = ENUM_TO_DOUBLE(ctx->Hint.PolygonSmooth);
+        break;
+      case GL_POLYGON_STIPPLE:
+         *params = (GLdouble) ctx->Polygon.StippleFlag;
+        break;
+      case GL_PROJECTION_MATRIX:
+        for (i=0;i<16;i++) {
+           params[i] = (GLdouble) ctx->ProjectionMatrix.m[i];
+        }
+        break;
+      case GL_PROJECTION_STACK_DEPTH:
+        *params = (GLdouble) (ctx->ProjectionStackDepth + 1);
+        break;
+      case GL_READ_BUFFER:
+        *params = ENUM_TO_DOUBLE(ctx->Pixel.ReadBuffer);
+        break;
+      case GL_RED_BIAS:
+         *params = (GLdouble) ctx->Pixel.RedBias;
+         break;
+      case GL_RED_BITS:
+         *params = (GLdouble) ctx->Visual->RedBits;
+         break;
+      case GL_RED_SCALE:
+         *params = (GLdouble) ctx->Pixel.RedScale;
+         break;
+      case GL_RENDER_MODE:
+        *params = ENUM_TO_DOUBLE(ctx->RenderMode);
+        break;
+      case GL_RGBA_MODE:
+        *params = (GLdouble) ctx->Visual->RGBAflag;
+        break;
+      case GL_SCISSOR_BOX:
+        params[0] = (GLdouble) ctx->Scissor.X;
+        params[1] = (GLdouble) ctx->Scissor.Y;
+        params[2] = (GLdouble) ctx->Scissor.Width;
+        params[3] = (GLdouble) ctx->Scissor.Height;
+        break;
+      case GL_SCISSOR_TEST:
+        *params = (GLdouble) ctx->Scissor.Enabled;
+        break;
+      case GL_SELECTION_BUFFER_SIZE:
+         *params = (GLdouble) ctx->Select.BufferSize;
+         break;
+      case GL_SHADE_MODEL:
+        *params = ENUM_TO_DOUBLE(ctx->Light.ShadeModel);
+        break;
+      case GL_SHARED_TEXTURE_PALETTE_EXT:
+         *params = (GLdouble) ctx->Texture.SharedPalette;
+         break;
+      case GL_STENCIL_BITS:
+         *params = (GLdouble) ctx->Visual->StencilBits;
+         break;
+      case GL_STENCIL_CLEAR_VALUE:
+        *params = (GLdouble) ctx->Stencil.Clear;
+        break;
+      case GL_STENCIL_FAIL:
+        *params = ENUM_TO_DOUBLE(ctx->Stencil.FailFunc);
+        break;
+      case GL_STENCIL_FUNC:
+        *params = ENUM_TO_DOUBLE(ctx->Stencil.Function);
+        break;
+      case GL_STENCIL_PASS_DEPTH_FAIL:
+        *params = ENUM_TO_DOUBLE(ctx->Stencil.ZFailFunc);
+        break;
+      case GL_STENCIL_PASS_DEPTH_PASS:
+        *params = ENUM_TO_DOUBLE(ctx->Stencil.ZPassFunc);
+        break;
+      case GL_STENCIL_REF:
+        *params = (GLdouble) ctx->Stencil.Ref;
+        break;
+      case GL_STENCIL_TEST:
+        *params = (GLdouble) ctx->Stencil.Enabled;
+        break;
+      case GL_STENCIL_VALUE_MASK:
+        *params = (GLdouble) ctx->Stencil.ValueMask;
+        break;
+      case GL_STENCIL_WRITEMASK:
+        *params = (GLdouble) ctx->Stencil.WriteMask;
+        break;
+      case GL_STEREO:
+        *params = (GLdouble) ctx->Visual->StereoFlag;
+        break;
+      case GL_SUBPIXEL_BITS:
+        *params = 0.0;   /* TODO */
+        break;
+      case GL_TEXTURE_1D:
+         *params = gl_IsEnabled(ctx, GL_TEXTURE_1D) ? 1.0 : 0.0;
+        break;
+      case GL_TEXTURE_2D:
+         *params = gl_IsEnabled(ctx, GL_TEXTURE_2D) ? 1.0 : 0.0;
+        break;
+      case GL_TEXTURE_3D:
+         *params = gl_IsEnabled(ctx, GL_TEXTURE_3D) ? 1.0 : 0.0;
+        break;
+      case GL_TEXTURE_BINDING_1D:
+         *params = (GLdouble) textureUnit->CurrentD[1]->Name;
+          break;
+      case GL_TEXTURE_BINDING_2D:
+         *params = (GLdouble) textureUnit->CurrentD[2]->Name;
+          break;
+      case GL_TEXTURE_BINDING_3D:
+         *params = (GLdouble) textureUnit->CurrentD[3]->Name;
+          break;
+      case GL_TEXTURE_ENV_COLOR:
+        params[0] = (GLdouble) textureUnit->EnvColor[0];
+        params[1] = (GLdouble) textureUnit->EnvColor[1];
+        params[2] = (GLdouble) textureUnit->EnvColor[2];
+        params[3] = (GLdouble) textureUnit->EnvColor[3];
+        break;
+      case GL_TEXTURE_ENV_MODE:
+        *params = ENUM_TO_DOUBLE(textureUnit->EnvMode);
+        break;
+      case GL_TEXTURE_GEN_S:
+        *params = (textureUnit->TexGenEnabled & S_BIT) ? 1.0 : 0.0;
+        break;
+      case GL_TEXTURE_GEN_T:
+        *params = (textureUnit->TexGenEnabled & T_BIT) ? 1.0 : 0.0;
+        break;
+      case GL_TEXTURE_GEN_R:
+        *params = (textureUnit->TexGenEnabled & R_BIT) ? 1.0 : 0.0;
+        break;
+      case GL_TEXTURE_GEN_Q:
+        *params = (textureUnit->TexGenEnabled & Q_BIT) ? 1.0 : 0.0;
+        break;
+      case GL_TEXTURE_MATRIX:
+         for (i=0;i<16;i++) {
+           params[i] = (GLdouble) ctx->TextureMatrix[texTransformUnit].m[i];
+        }
+        break;
+      case GL_TEXTURE_STACK_DEPTH:
+        *params = (GLdouble) (ctx->TextureStackDepth[texTransformUnit] + 1);
+        break;
+      case GL_UNPACK_ALIGNMENT:
+        *params = (GLdouble) ctx->Unpack.Alignment;
+        break;
+      case GL_UNPACK_LSB_FIRST:
+        *params = (GLdouble) ctx->Unpack.LsbFirst;
+        break;
+      case GL_UNPACK_ROW_LENGTH:
+        *params = (GLdouble) ctx->Unpack.RowLength;
+        break;
+      case GL_UNPACK_SKIP_PIXELS:
+        *params = (GLdouble) ctx->Unpack.SkipPixels;
+        break;
+      case GL_UNPACK_SKIP_ROWS:
+        *params = (GLdouble) ctx->Unpack.SkipRows;
+        break;
+      case GL_UNPACK_SWAP_BYTES:
+        *params = (GLdouble) ctx->Unpack.SwapBytes;
+        break;
+      case GL_UNPACK_SKIP_IMAGES_EXT:
+         *params = (GLdouble) ctx->Unpack.SkipImages;
+         break;
+      case GL_UNPACK_IMAGE_HEIGHT_EXT:
+         *params = (GLdouble) ctx->Unpack.ImageHeight;
+         break;
+      case GL_VIEWPORT:
+        params[0] = (GLdouble) ctx->Viewport.X;
+        params[1] = (GLdouble) ctx->Viewport.Y;
+        params[2] = (GLdouble) ctx->Viewport.Width;
+        params[3] = (GLdouble) ctx->Viewport.Height;
+        break;
+      case GL_ZOOM_X:
+        *params = (GLdouble) ctx->Pixel.ZoomX;
+        break;
+      case GL_ZOOM_Y:
+        *params = (GLdouble) ctx->Pixel.ZoomY;
+        break;
+      case GL_VERTEX_ARRAY_SIZE:
+         *params = (GLdouble) ctx->Array.Vertex.Size;
+         break;
+      case GL_VERTEX_ARRAY_TYPE:
+         *params = ENUM_TO_DOUBLE(ctx->Array.Vertex.Type);
+         break;
+      case GL_VERTEX_ARRAY_STRIDE:
+         *params = (GLdouble) ctx->Array.Vertex.Stride;
+         break;
+      case GL_VERTEX_ARRAY_COUNT_EXT:
+         *params = 0.0;
+         break;
+      case GL_NORMAL_ARRAY_TYPE:
+         *params = ENUM_TO_DOUBLE(ctx->Array.Normal.Type);
+         break;
+      case GL_NORMAL_ARRAY_STRIDE:
+         *params = (GLdouble) ctx->Array.Normal.Stride;
+         break;
+      case GL_NORMAL_ARRAY_COUNT_EXT:
+         *params = 0.0;
+         break;
+      case GL_COLOR_ARRAY_SIZE:
+         *params = (GLdouble) ctx->Array.Color.Size;
+         break;
+      case GL_COLOR_ARRAY_TYPE:
+         *params = ENUM_TO_DOUBLE(ctx->Array.Color.Type);
+         break;
+      case GL_COLOR_ARRAY_STRIDE:
+         *params = (GLdouble) ctx->Array.Color.Stride;
+         break;
+      case GL_COLOR_ARRAY_COUNT_EXT:
+         *params = 0.0;
+         break;
+      case GL_INDEX_ARRAY_TYPE:
+         *params = ENUM_TO_DOUBLE(ctx->Array.Index.Type);
+         break;
+      case GL_INDEX_ARRAY_STRIDE:
+         *params = (GLdouble) ctx->Array.Index.Stride;
+         break;
+      case GL_INDEX_ARRAY_COUNT_EXT:
+         *params = 0.0;
+         break;
+      case GL_TEXTURE_COORD_ARRAY_SIZE:
+         *params = (GLdouble) ctx->Array.TexCoord[texUnit].Size;
+         break;
+      case GL_TEXTURE_COORD_ARRAY_TYPE:
+         *params = ENUM_TO_DOUBLE(ctx->Array.TexCoord[texUnit].Type);
+         break;
+      case GL_TEXTURE_COORD_ARRAY_STRIDE:
+         *params = (GLdouble) ctx->Array.TexCoord[texUnit].Stride;
+         break;
+      case GL_TEXTURE_COORD_ARRAY_COUNT_EXT:
+         *params = 0.0;
+         break;
+      case GL_EDGE_FLAG_ARRAY_STRIDE:
+         *params = (GLdouble) ctx->Array.EdgeFlag.Stride;
+         break;
+      case GL_EDGE_FLAG_ARRAY_COUNT_EXT:
+         *params = 0.0;
+         break;
+
+      case GL_MAX_TEXTURE_UNITS_ARB:
+         *params = (GLdouble) ctx->Const.MaxTextureUnits;
+         break;
+      case GL_ACTIVE_TEXTURE_ARB:
+         *params = (GLdouble) (GL_TEXTURE0_ARB + ctx->Texture.CurrentUnit);
+         break;
+      case GL_CLIENT_ACTIVE_TEXTURE_ARB:
+         *params = (GLdouble) (GL_TEXTURE0_ARB + ctx->Array.ActiveTexture);
+         break;
+
+
+      /* GL_PGI_misc_hints */
+      case GL_STRICT_DEPTHFUNC_HINT_PGI:
+        *params = ENUM_TO_DOUBLE(GL_NICEST);
+         break;
+      case GL_STRICT_LIGHTING_HINT_PGI:
+        *params = ENUM_TO_DOUBLE(ctx->Hint.StrictLighting);
+        break;
+      case GL_STRICT_SCISSOR_HINT_PGI:
+      case GL_FULL_STIPPLE_HINT_PGI:
+        *params = ENUM_TO_DOUBLE(GL_TRUE);
+        break;
+      case GL_CONSERVE_MEMORY_HINT_PGI:
+        *params = ENUM_TO_DOUBLE(GL_FALSE);
+        break;
+      case GL_ALWAYS_FAST_HINT_PGI:
+        *params = (GLdouble) (ctx->Hint.AllowDrawWin == GL_TRUE &&
+                             ctx->Hint.AllowDrawSpn == GL_FALSE && 
+                             ctx->Hint.AllowDrawMem == GL_FALSE);
+        break;
+      case GL_ALWAYS_SOFT_HINT_PGI:
+        *params = (GLdouble) (ctx->Hint.AllowDrawWin == GL_TRUE &&
+                             ctx->Hint.AllowDrawSpn == GL_TRUE && 
+                             ctx->Hint.AllowDrawMem == GL_TRUE);
+        break;
+      case GL_ALLOW_DRAW_OBJ_HINT_PGI:
+        *params = (GLdouble) GL_TRUE;
+        break;
+      case GL_ALLOW_DRAW_WIN_HINT_PGI:
+        *params = (GLdouble) ctx->Hint.AllowDrawWin;
+        break;
+      case GL_ALLOW_DRAW_SPN_HINT_PGI:
+        *params = (GLdouble) ctx->Hint.AllowDrawSpn;
+        break;
+      case GL_ALLOW_DRAW_MEM_HINT_PGI:
+        *params = (GLdouble) ctx->Hint.AllowDrawMem;
+        break;
+      case GL_CLIP_NEAR_HINT_PGI:
+      case GL_CLIP_FAR_HINT_PGI:
+        *params = ENUM_TO_DOUBLE(GL_TRUE);
+        break;
+      case GL_WIDE_LINE_HINT_PGI:
+        *params = ENUM_TO_DOUBLE(GL_DONT_CARE);
+        break;
+      case GL_BACK_NORMALS_HINT_PGI:
+        *params = ENUM_TO_DOUBLE(GL_TRUE);
+        break;
+      case GL_NATIVE_GRAPHICS_HANDLE_PGI:
+        *params = 0;
+        break;
+
+
+
+      default:
+        printf("invalid enum: %x\n", pname);
+         gl_error( ctx, GL_INVALID_ENUM, "glGetDoublev" );
+   }
+}
+
+
+
+
+void gl_GetFloatv( GLcontext *ctx, GLenum pname, GLfloat *params )
+{
+   GLuint i;
+   GLuint texUnit = ctx->Texture.CurrentUnit;
+   GLuint texTransformUnit = ctx->Texture.CurrentTransformUnit;
+   const struct gl_texture_unit *textureUnit = &ctx->Texture.Unit[texUnit];
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetFloatv");
+
+   if (MESA_VERBOSE & VERBOSE_API) 
+      fprintf(stderr, "glGetFloatv %s\n", gl_lookup_enum_by_nr(pname));
+
+   switch (pname) {
+      case GL_ACCUM_RED_BITS:
+      case GL_ACCUM_GREEN_BITS:
+      case GL_ACCUM_BLUE_BITS:
+      case GL_ACCUM_ALPHA_BITS:
+         *params = (GLfloat) ctx->Visual->AccumBits;
+         break;
+      case GL_ACCUM_CLEAR_VALUE:
+         params[0] = ctx->Accum.ClearColor[0];
+         params[1] = ctx->Accum.ClearColor[1];
+         params[2] = ctx->Accum.ClearColor[2];
+         params[3] = ctx->Accum.ClearColor[3];
+         break;
+      case GL_ALPHA_BIAS:
+         *params = ctx->Pixel.AlphaBias;
+         break;
+      case GL_ALPHA_BITS:
+         *params = (GLfloat) ctx->Visual->AlphaBits;
+         break;
+      case GL_ALPHA_SCALE:
+         *params = ctx->Pixel.AlphaScale;
+         break;
+      case GL_ALPHA_TEST:
+         *params = (GLfloat) ctx->Color.AlphaEnabled;
+         break;
+      case GL_ALPHA_TEST_FUNC:
+         *params = ENUM_TO_FLOAT(ctx->Color.AlphaFunc);
+         break;
+      case GL_ALPHA_TEST_REF:
+         *params = (GLfloat) ctx->Color.AlphaRef / 255.0;
+         break;
+      case GL_ATTRIB_STACK_DEPTH:
+         *params = (GLfloat) (ctx->AttribStackDepth);
+         break;
+      case GL_AUTO_NORMAL:
+         *params = (GLfloat) ctx->Eval.AutoNormal;
+         break;
+      case GL_AUX_BUFFERS:
+         *params = (GLfloat) NUM_AUX_BUFFERS;
+         break;
+      case GL_BLEND:
+         *params = (GLfloat) ctx->Color.BlendEnabled;
+         break;
+      case GL_BLEND_DST:
+         *params = ENUM_TO_FLOAT(ctx->Color.BlendDstRGB);
+         break;
+      case GL_BLEND_SRC:
+         *params = ENUM_TO_FLOAT(ctx->Color.BlendSrcRGB);
+         break;
+      case GL_BLEND_SRC_RGB_INGR:
+         *params = ENUM_TO_FLOAT(ctx->Color.BlendSrcRGB);
+         break;
+      case GL_BLEND_DST_RGB_INGR:
+         *params = ENUM_TO_FLOAT(ctx->Color.BlendDstRGB);
+         break;
+      case GL_BLEND_SRC_ALPHA_INGR:
+         *params = ENUM_TO_FLOAT(ctx->Color.BlendSrcA);
+         break;
+      case GL_BLEND_DST_ALPHA_INGR:
+         *params = ENUM_TO_FLOAT(ctx->Color.BlendDstA);
+         break;
+      case GL_BLEND_EQUATION_EXT:
+        *params = ENUM_TO_FLOAT(ctx->Color.BlendEquation);
+        break;
+      case GL_BLEND_COLOR_EXT:
+        params[0] = ctx->Color.BlendColor[0];
+        params[1] = ctx->Color.BlendColor[1];
+        params[2] = ctx->Color.BlendColor[2];
+        params[3] = ctx->Color.BlendColor[3];
+        break;
+      case GL_BLUE_BIAS:
+         *params = ctx->Pixel.BlueBias;
+         break;
+      case GL_BLUE_BITS:
+         *params = (GLfloat) ctx->Visual->BlueBits;
+         break;
+      case GL_BLUE_SCALE:
+         *params = ctx->Pixel.BlueScale;
+         break;
+      case GL_CLIENT_ATTRIB_STACK_DEPTH:
+         *params = (GLfloat) (ctx->ClientAttribStackDepth);
+         break;
+      case GL_CLIP_PLANE0:
+      case GL_CLIP_PLANE1:
+      case GL_CLIP_PLANE2:
+      case GL_CLIP_PLANE3:
+      case GL_CLIP_PLANE4:
+      case GL_CLIP_PLANE5:
+         *params = (GLfloat) ctx->Transform.ClipEnabled[pname-GL_CLIP_PLANE0];
+         break;
+      case GL_COLOR_CLEAR_VALUE:
+         params[0] = (GLfloat) ctx->Color.ClearColor[0];
+         params[1] = (GLfloat) ctx->Color.ClearColor[1];
+         params[2] = (GLfloat) ctx->Color.ClearColor[2];
+         params[3] = (GLfloat) ctx->Color.ClearColor[3];
+         break;
+      case GL_COLOR_MATERIAL:
+         *params = (GLfloat) ctx->Light.ColorMaterialEnabled;
+         break;
+      case GL_COLOR_MATERIAL_FACE:
+         *params = ENUM_TO_FLOAT(ctx->Light.ColorMaterialFace);
+         break;
+      case GL_COLOR_MATERIAL_PARAMETER:
+         *params = ENUM_TO_FLOAT(ctx->Light.ColorMaterialMode);
+         break;
+      case GL_COLOR_WRITEMASK:
+         params[0] = ctx->Color.ColorMask[RCOMP] ? 1.0F : 0.0F;
+         params[1] = ctx->Color.ColorMask[GCOMP] ? 1.0F : 0.0F;
+         params[2] = ctx->Color.ColorMask[BCOMP] ? 1.0F : 0.0F;
+         params[3] = ctx->Color.ColorMask[ACOMP] ? 1.0F : 0.0F;
+         break;
+      case GL_CULL_FACE:
+         *params = (GLfloat) ctx->Polygon.CullFlag;
+         break;
+      case GL_CULL_FACE_MODE:
+         *params = ENUM_TO_FLOAT(ctx->Polygon.CullFaceMode);
+         break;
+      case GL_CURRENT_COLOR:
+        UBYTE_RGBA_TO_FLOAT_RGBA(params, ctx->Current.ByteColor);
+         break;
+      case GL_CURRENT_INDEX:
+         *params = (GLfloat) ctx->Current.Index;
+         break;
+      case GL_CURRENT_NORMAL:
+         params[0] = ctx->Current.Normal[0];
+         params[1] = ctx->Current.Normal[1];
+         params[2] = ctx->Current.Normal[2];
+         break;
+      case GL_CURRENT_RASTER_COLOR:
+        params[0] = ctx->Current.RasterColor[0];
+        params[1] = ctx->Current.RasterColor[1];
+        params[2] = ctx->Current.RasterColor[2];
+        params[3] = ctx->Current.RasterColor[3];
+        break;
+      case GL_CURRENT_RASTER_DISTANCE:
+        params[0] = ctx->Current.RasterDistance;
+        break;
+      case GL_CURRENT_RASTER_INDEX:
+        *params = (GLfloat) ctx->Current.RasterIndex;
+        break;
+      case GL_CURRENT_RASTER_POSITION:
+        params[0] = ctx->Current.RasterPos[0];
+        params[1] = ctx->Current.RasterPos[1];
+        params[2] = ctx->Current.RasterPos[2];
+        params[3] = ctx->Current.RasterPos[3];
+        break;
+      case GL_CURRENT_RASTER_TEXTURE_COORDS:
+        params[0] = ctx->Current.RasterMultiTexCoord[texTransformUnit][0];
+        params[1] = ctx->Current.RasterMultiTexCoord[texTransformUnit][1];
+        params[2] = ctx->Current.RasterMultiTexCoord[texTransformUnit][2];
+        params[3] = ctx->Current.RasterMultiTexCoord[texTransformUnit][3];
+        break;
+      case GL_CURRENT_RASTER_POSITION_VALID:
+        *params = (GLfloat) ctx->Current.RasterPosValid;
+        break;
+      case GL_CURRENT_TEXTURE_COORDS:
+        params[0] = (GLfloat) ctx->Current.Texcoord[texTransformUnit][0];
+        params[1] = (GLfloat) ctx->Current.Texcoord[texTransformUnit][1];
+        params[2] = (GLfloat) ctx->Current.Texcoord[texTransformUnit][2];
+        params[3] = (GLfloat) ctx->Current.Texcoord[texTransformUnit][3];
+        break;
+      case GL_DEPTH_BIAS:
+        *params = (GLfloat) ctx->Pixel.DepthBias;
+        break;
+      case GL_DEPTH_BITS:
+        *params = (GLfloat) ctx->Visual->DepthBits;
+        break;
+      case GL_DEPTH_CLEAR_VALUE:
+        *params = (GLfloat) ctx->Depth.Clear;
+        break;
+      case GL_DEPTH_FUNC:
+        *params = ENUM_TO_FLOAT(ctx->Depth.Func);
+        break;
+      case GL_DEPTH_RANGE:
+         params[0] = (GLfloat) ctx->Viewport.Near;
+         params[1] = (GLfloat) ctx->Viewport.Far;
+        break;
+      case GL_DEPTH_SCALE:
+        *params = (GLfloat) ctx->Pixel.DepthScale;
+        break;
+      case GL_DEPTH_TEST:
+        *params = (GLfloat) ctx->Depth.Test;
+        break;
+      case GL_DEPTH_WRITEMASK:
+        *params = (GLfloat) ctx->Depth.Mask;
+        break;
+      case GL_DITHER:
+        *params = (GLfloat) ctx->Color.DitherFlag;
+        break;
+      case GL_DOUBLEBUFFER:
+        *params = (GLfloat) ctx->Visual->DBflag;
+        break;
+      case GL_DRAW_BUFFER:
+        *params = ENUM_TO_FLOAT(ctx->Color.DrawBuffer);
+        break;
+      case GL_EDGE_FLAG:
+        *params = (GLfloat) ctx->Current.EdgeFlag;
+        break;
+      case GL_FEEDBACK_BUFFER_SIZE:
+         /* TODO: is this right?  Or, return number of entries in buffer? */
+         *params = (GLfloat) ctx->Feedback.BufferSize;
+         break;
+      case GL_FEEDBACK_BUFFER_TYPE:
+         *params = ENUM_TO_FLOAT(ctx->Feedback.Type);
+         break;
+      case GL_FOG:
+        *params = (GLfloat) ctx->Fog.Enabled;
+        break;
+      case GL_FOG_COLOR:
+        params[0] = ctx->Fog.Color[0];
+        params[1] = ctx->Fog.Color[1];
+        params[2] = ctx->Fog.Color[2];
+        params[3] = ctx->Fog.Color[3];
+        break;
+      case GL_FOG_DENSITY:
+        *params = ctx->Fog.Density;
+        break;
+      case GL_FOG_END:
+        *params = ctx->Fog.End;
+        break;
+      case GL_FOG_HINT:
+        *params = ENUM_TO_FLOAT(ctx->Hint.Fog);
+        break;
+      case GL_FOG_INDEX:
+        *params = ctx->Fog.Index;
+        break;
+      case GL_FOG_MODE:
+        *params = ENUM_TO_FLOAT(ctx->Fog.Mode);
+        break;
+      case GL_FOG_START:
+        *params = ctx->Fog.Start;
+        break;
+      case GL_FRONT_FACE:
+        *params = ENUM_TO_FLOAT(ctx->Polygon.FrontFace);
+        break;
+      case GL_GREEN_BIAS:
+         *params = (GLfloat) ctx->Pixel.GreenBias;
+         break;
+      case GL_GREEN_BITS:
+         *params = (GLfloat) ctx->Visual->GreenBits;
+         break;
+      case GL_GREEN_SCALE:
+         *params = (GLfloat) ctx->Pixel.GreenScale;
+         break;
+      case GL_INDEX_BITS:
+         *params = (GLfloat) ctx->Visual->IndexBits;
+        break;
+      case GL_INDEX_CLEAR_VALUE:
+         *params = (GLfloat) ctx->Color.ClearIndex;
+        break;
+      case GL_INDEX_MODE:
+        *params = ctx->Visual->RGBAflag ? 0.0F : 1.0F;
+        break;
+      case GL_INDEX_OFFSET:
+        *params = (GLfloat) ctx->Pixel.IndexOffset;
+        break;
+      case GL_INDEX_SHIFT:
+        *params = (GLfloat) ctx->Pixel.IndexShift;
+        break;
+      case GL_INDEX_WRITEMASK:
+        *params = (GLfloat) ctx->Color.IndexMask;
+        break;
+      case GL_LIGHT0:
+      case GL_LIGHT1:
+      case GL_LIGHT2:
+      case GL_LIGHT3:
+      case GL_LIGHT4:
+      case GL_LIGHT5:
+      case GL_LIGHT6:
+      case GL_LIGHT7:
+        *params = (GLfloat) ctx->Light.Light[pname-GL_LIGHT0].Enabled;
+        break;
+      case GL_LIGHTING:
+        *params = (GLfloat) ctx->Light.Enabled;
+        break;
+      case GL_LIGHT_MODEL_AMBIENT:
+        params[0] = ctx->Light.Model.Ambient[0];
+        params[1] = ctx->Light.Model.Ambient[1];
+        params[2] = ctx->Light.Model.Ambient[2];
+        params[3] = ctx->Light.Model.Ambient[3];
+        break;
+      case GL_LIGHT_MODEL_COLOR_CONTROL:
+         params[0] = ENUM_TO_FLOAT(ctx->Light.Model.ColorControl);
+         break;
+      case GL_LIGHT_MODEL_LOCAL_VIEWER:
+        *params = (GLfloat) ctx->Light.Model.LocalViewer;
+        break;
+      case GL_LIGHT_MODEL_TWO_SIDE:
+        *params = (GLfloat) ctx->Light.Model.TwoSide;
+        break;
+      case GL_LINE_SMOOTH:
+        *params = (GLfloat) ctx->Line.SmoothFlag;
+        break;
+      case GL_LINE_SMOOTH_HINT:
+        *params = ENUM_TO_FLOAT(ctx->Hint.LineSmooth);
+        break;
+      case GL_LINE_STIPPLE:
+        *params = (GLfloat) ctx->Line.StippleFlag;
+        break;
+      case GL_LINE_STIPPLE_PATTERN:
+         *params = (GLfloat) ctx->Line.StipplePattern;
+         break;
+      case GL_LINE_STIPPLE_REPEAT:
+         *params = (GLfloat) ctx->Line.StippleFactor;
+         break;
+      case GL_LINE_WIDTH:
+        *params = (GLfloat) ctx->Line.Width;
+        break;
+      case GL_LINE_WIDTH_GRANULARITY:
+        *params = (GLfloat) LINE_WIDTH_GRANULARITY;
+        break;
+      case GL_LINE_WIDTH_RANGE:
+        params[0] = (GLfloat) MIN_LINE_WIDTH;
+        params[1] = (GLfloat) MAX_LINE_WIDTH;
+        break;
+      case GL_LIST_BASE:
+        *params = (GLfloat) ctx->List.ListBase;
+        break;
+      case GL_LIST_INDEX:
+        *params = (GLfloat) ctx->CurrentListNum;
+        break;
+      case GL_LIST_MODE:
+        *params = ctx->ExecuteFlag ? ENUM_TO_FLOAT(GL_COMPILE_AND_EXECUTE)
+                                 : ENUM_TO_FLOAT(GL_COMPILE);
+        break;
+      case GL_INDEX_LOGIC_OP:
+        *params = (GLfloat) ctx->Color.IndexLogicOpEnabled;
+        break;
+      case GL_COLOR_LOGIC_OP:
+        *params = (GLfloat) ctx->Color.ColorLogicOpEnabled;
+        break;
+      case GL_LOGIC_OP_MODE:
+         *params = ENUM_TO_FLOAT(ctx->Color.LogicOp);
+        break;
+      case GL_MAP1_COLOR_4:
+        *params = (GLfloat) ctx->Eval.Map1Color4;
+        break;
+      case GL_MAP1_GRID_DOMAIN:
+        params[0] = ctx->Eval.MapGrid1u1;
+        params[1] = ctx->Eval.MapGrid1u2;
+        break;
+      case GL_MAP1_GRID_SEGMENTS:
+        *params = (GLfloat) ctx->Eval.MapGrid1un;
+        break;
+      case GL_MAP1_INDEX:
+        *params = (GLfloat) ctx->Eval.Map1Index;
+        break;
+      case GL_MAP1_NORMAL:
+        *params = (GLfloat) ctx->Eval.Map1Normal;
+        break;
+      case GL_MAP1_TEXTURE_COORD_1:
+        *params = (GLfloat) ctx->Eval.Map1TextureCoord1;
+        break;
+      case GL_MAP1_TEXTURE_COORD_2:
+        *params = (GLfloat) ctx->Eval.Map1TextureCoord2;
+        break;
+      case GL_MAP1_TEXTURE_COORD_3:
+        *params = (GLfloat) ctx->Eval.Map1TextureCoord3;
+        break;
+      case GL_MAP1_TEXTURE_COORD_4:
+        *params = (GLfloat) ctx->Eval.Map1TextureCoord4;
+        break;
+      case GL_MAP1_VERTEX_3:
+        *params = (GLfloat) ctx->Eval.Map1Vertex3;
+        break;
+      case GL_MAP1_VERTEX_4:
+        *params = (GLfloat) ctx->Eval.Map1Vertex4;
+        break;
+      case GL_MAP2_COLOR_4:
+        *params = (GLfloat) ctx->Eval.Map2Color4;
+        break;
+      case GL_MAP2_GRID_DOMAIN:
+        params[0] = ctx->Eval.MapGrid2u1;
+        params[1] = ctx->Eval.MapGrid2u2;
+        params[2] = ctx->Eval.MapGrid2v1;
+        params[3] = ctx->Eval.MapGrid2v2;
+        break;
+      case GL_MAP2_GRID_SEGMENTS:
+        params[0] = (GLfloat) ctx->Eval.MapGrid2un;
+        params[1] = (GLfloat) ctx->Eval.MapGrid2vn;
+        break;
+      case GL_MAP2_INDEX:
+        *params = (GLfloat) ctx->Eval.Map2Index;
+        break;
+      case GL_MAP2_NORMAL:
+        *params = (GLfloat) ctx->Eval.Map2Normal;
+        break;
+      case GL_MAP2_TEXTURE_COORD_1:
+        *params = ctx->Eval.Map2TextureCoord1;
+        break;
+      case GL_MAP2_TEXTURE_COORD_2:
+        *params = ctx->Eval.Map2TextureCoord2;
+        break;
+      case GL_MAP2_TEXTURE_COORD_3:
+        *params = ctx->Eval.Map2TextureCoord3;
+        break;
+      case GL_MAP2_TEXTURE_COORD_4:
+        *params = ctx->Eval.Map2TextureCoord4;
+        break;
+      case GL_MAP2_VERTEX_3:
+        *params = (GLfloat) ctx->Eval.Map2Vertex3;
+        break;
+      case GL_MAP2_VERTEX_4:
+        *params = (GLfloat) ctx->Eval.Map2Vertex4;
+        break;
+      case GL_MAP_COLOR:
+        *params = (GLfloat) ctx->Pixel.MapColorFlag;
+        break;
+      case GL_MAP_STENCIL:
+        *params = (GLfloat) ctx->Pixel.MapStencilFlag;
+        break;
+      case GL_MATRIX_MODE:
+        *params = ENUM_TO_FLOAT(ctx->Transform.MatrixMode);
+        break;
+      case GL_MAX_ATTRIB_STACK_DEPTH:
+        *params = (GLfloat) MAX_ATTRIB_STACK_DEPTH;
+        break;
+      case GL_MAX_CLIENT_ATTRIB_STACK_DEPTH:
+         *params = (GLfloat) MAX_CLIENT_ATTRIB_STACK_DEPTH;
+         break;
+      case GL_MAX_CLIP_PLANES:
+        *params = (GLfloat) MAX_CLIP_PLANES;
+        break;
+      case GL_MAX_ELEMENTS_VERTICES:  /* GL_VERSION_1_2 */
+         *params = (GLfloat) VB_MAX;
+         break;
+      case GL_MAX_ELEMENTS_INDICES:   /* GL_VERSION_1_2 */
+         *params = (GLfloat) VB_MAX;
+         break;
+      case GL_MAX_EVAL_ORDER:
+        *params = (GLfloat) MAX_EVAL_ORDER;
+        break;
+      case GL_MAX_LIGHTS:
+        *params = (GLfloat) MAX_LIGHTS;
+        break;
+      case GL_MAX_LIST_NESTING:
+        *params = (GLfloat) MAX_LIST_NESTING;
+        break;
+      case GL_MAX_MODELVIEW_STACK_DEPTH:
+        *params = (GLfloat) MAX_MODELVIEW_STACK_DEPTH;
+        break;
+      case GL_MAX_NAME_STACK_DEPTH:
+        *params = (GLfloat) MAX_NAME_STACK_DEPTH;
+        break;
+      case GL_MAX_PIXEL_MAP_TABLE:
+        *params = (GLfloat) MAX_PIXEL_MAP_TABLE;
+        break;
+      case GL_MAX_PROJECTION_STACK_DEPTH:
+        *params = (GLfloat) MAX_PROJECTION_STACK_DEPTH;
+        break;
+      case GL_MAX_TEXTURE_SIZE:
+      case GL_MAX_3D_TEXTURE_SIZE:
+         *params = (GLfloat) ctx->Const.MaxTextureSize;
+        break;
+      case GL_MAX_TEXTURE_STACK_DEPTH:
+        *params = (GLfloat) MAX_TEXTURE_STACK_DEPTH;
+        break;
+      case GL_MAX_VIEWPORT_DIMS:
+         params[0] = (GLfloat) MAX_WIDTH;
+         params[1] = (GLfloat) MAX_HEIGHT;
+         break;
+      case GL_MODELVIEW_MATRIX:
+        for (i=0;i<16;i++) {
+           params[i] = ctx->ModelView.m[i];
+        }
+        break;
+      case GL_MODELVIEW_STACK_DEPTH:
+        *params = (GLfloat) (ctx->ModelViewStackDepth + 1);
+        break;
+      case GL_NAME_STACK_DEPTH:
+        *params = (GLfloat) ctx->Select.NameStackDepth;
+        break;
+      case GL_NORMALIZE:
+        *params = (GLfloat) ctx->Transform.Normalize;
+        break;
+      case GL_PACK_ALIGNMENT:
+        *params = (GLfloat) ctx->Pack.Alignment;
+        break;
+      case GL_PACK_LSB_FIRST:
+        *params = (GLfloat) ctx->Pack.LsbFirst;
+        break;
+      case GL_PACK_ROW_LENGTH:
+        *params = (GLfloat) ctx->Pack.RowLength;
+        break;
+      case GL_PACK_SKIP_PIXELS:
+        *params = (GLfloat) ctx->Pack.SkipPixels;
+        break;
+      case GL_PACK_SKIP_ROWS:
+        *params = (GLfloat) ctx->Pack.SkipRows;
+        break;
+      case GL_PACK_SWAP_BYTES:
+        *params = (GLfloat) ctx->Pack.SwapBytes;
+        break;
+      case GL_PACK_SKIP_IMAGES_EXT:
+         *params = (GLfloat) ctx->Pack.SkipImages;
+         break;
+      case GL_PACK_IMAGE_HEIGHT_EXT:
+         *params = (GLfloat) ctx->Pack.ImageHeight;
+         break;
+      case GL_PERSPECTIVE_CORRECTION_HINT:
+        *params = ENUM_TO_FLOAT(ctx->Hint.PerspectiveCorrection);
+        break;
+      case GL_PIXEL_MAP_A_TO_A_SIZE:
+        *params = (GLfloat) ctx->Pixel.MapAtoAsize;
+        break;
+      case GL_PIXEL_MAP_B_TO_B_SIZE:
+        *params = (GLfloat) ctx->Pixel.MapBtoBsize;
+        break;
+      case GL_PIXEL_MAP_G_TO_G_SIZE:
+        *params = (GLfloat) ctx->Pixel.MapGtoGsize;
+        break;
+      case GL_PIXEL_MAP_I_TO_A_SIZE:
+        *params = (GLfloat) ctx->Pixel.MapItoAsize;
+        break;
+      case GL_PIXEL_MAP_I_TO_B_SIZE:
+        *params = (GLfloat) ctx->Pixel.MapItoBsize;
+        break;
+      case GL_PIXEL_MAP_I_TO_G_SIZE:
+        *params = (GLfloat) ctx->Pixel.MapItoGsize;
+        break;
+      case GL_PIXEL_MAP_I_TO_I_SIZE:
+        *params = (GLfloat) ctx->Pixel.MapItoIsize;
+        break;
+      case GL_PIXEL_MAP_I_TO_R_SIZE:
+        *params = (GLfloat) ctx->Pixel.MapItoRsize;
+        break;
+      case GL_PIXEL_MAP_R_TO_R_SIZE:
+        *params = (GLfloat) ctx->Pixel.MapRtoRsize;
+        break;
+      case GL_PIXEL_MAP_S_TO_S_SIZE:
+        *params = (GLfloat) ctx->Pixel.MapStoSsize;
+        break;
+      case GL_POINT_SIZE:
+         *params = (GLfloat) ctx->Point.Size;
+         break;
+      case GL_POINT_SIZE_GRANULARITY:
+        *params = (GLfloat) POINT_SIZE_GRANULARITY;
+        break;
+      case GL_POINT_SIZE_RANGE:
+        params[0] = (GLfloat) MIN_POINT_SIZE;
+        params[1] = (GLfloat) MAX_POINT_SIZE;
+        break;
+      case GL_POINT_SMOOTH:
+        *params = (GLfloat) ctx->Point.SmoothFlag;
+        break;
+      case GL_POINT_SMOOTH_HINT:
+        *params = ENUM_TO_FLOAT(ctx->Hint.PointSmooth);
+        break;
+      case GL_POINT_SIZE_MIN_EXT:
+        *params = (GLfloat) (ctx->Point.MinSize);
+        break;
+      case GL_POINT_SIZE_MAX_EXT:
+        *params = (GLfloat) (ctx->Point.MaxSize);
+        break;
+      case GL_POINT_FADE_THRESHOLD_SIZE_EXT:
+        *params = (GLfloat) (ctx->Point.Threshold);
+        break;
+      case GL_DISTANCE_ATTENUATION_EXT:
+        params[0] = (GLfloat) (ctx->Point.Params[0]);
+        params[1] = (GLfloat) (ctx->Point.Params[1]);
+        params[2] = (GLfloat) (ctx->Point.Params[2]);
+        break;
+      case GL_POLYGON_MODE:
+        params[0] = ENUM_TO_FLOAT(ctx->Polygon.FrontMode);
+        params[1] = ENUM_TO_FLOAT(ctx->Polygon.BackMode);
+        break;
+#ifdef GL_EXT_polygon_offset
+      case GL_POLYGON_OFFSET_BIAS_EXT:
+         *params = ctx->Polygon.OffsetUnits;
+         break;
+#endif
+      case GL_POLYGON_OFFSET_FACTOR:
+         *params = ctx->Polygon.OffsetFactor;
+         break;
+      case GL_POLYGON_OFFSET_UNITS:
+         *params = ctx->Polygon.OffsetUnits;
+         break;
+      case GL_POLYGON_SMOOTH:
+        *params = (GLfloat) ctx->Polygon.SmoothFlag;
+        break;
+      case GL_POLYGON_SMOOTH_HINT:
+        *params = ENUM_TO_FLOAT(ctx->Hint.PolygonSmooth);
+        break;
+      case GL_POLYGON_STIPPLE:
+         *params = (GLfloat) ctx->Polygon.StippleFlag;
+        break;
+      case GL_PROJECTION_MATRIX:
+        for (i=0;i<16;i++) {
+           params[i] = ctx->ProjectionMatrix.m[i];
+        }
+        break;
+      case GL_PROJECTION_STACK_DEPTH:
+        *params = (GLfloat) (ctx->ProjectionStackDepth + 1);
+        break;
+      case GL_READ_BUFFER:
+        *params = ENUM_TO_FLOAT(ctx->Pixel.ReadBuffer);
+        break;
+      case GL_RED_BIAS:
+         *params = ctx->Pixel.RedBias;
+         break;
+      case GL_RED_BITS:
+         *params = (GLfloat) ctx->Visual->RedBits;
+         break;
+      case GL_RED_SCALE:
+         *params = ctx->Pixel.RedScale;
+         break;
+      case GL_RENDER_MODE:
+        *params = ENUM_TO_FLOAT(ctx->RenderMode);
+        break;
+      case GL_RGBA_MODE:
+        *params = (GLfloat) ctx->Visual->RGBAflag;
+        break;
+      case GL_SCISSOR_BOX:
+        params[0] = (GLfloat) ctx->Scissor.X;
+        params[1] = (GLfloat) ctx->Scissor.Y;
+        params[2] = (GLfloat) ctx->Scissor.Width;
+        params[3] = (GLfloat) ctx->Scissor.Height;
+        break;
+      case GL_SCISSOR_TEST:
+        *params = (GLfloat) ctx->Scissor.Enabled;
+        break;
+      case GL_SELECTION_BUFFER_SIZE:
+         *params = (GLfloat) ctx->Select.BufferSize;
+         break;
+      case GL_SHADE_MODEL:
+        *params = ENUM_TO_FLOAT(ctx->Light.ShadeModel);
+        break;
+      case GL_SHARED_TEXTURE_PALETTE_EXT:
+         *params = (GLfloat) ctx->Texture.SharedPalette;
+         break;
+      case GL_STENCIL_BITS:
+         *params = (GLfloat) ctx->Visual->StencilBits;
+         break;
+      case GL_STENCIL_CLEAR_VALUE:
+        *params = (GLfloat) ctx->Stencil.Clear;
+        break;
+      case GL_STENCIL_FAIL:
+        *params = ENUM_TO_FLOAT(ctx->Stencil.FailFunc);
+        break;
+      case GL_STENCIL_FUNC:
+        *params = ENUM_TO_FLOAT(ctx->Stencil.Function);
+        break;
+      case GL_STENCIL_PASS_DEPTH_FAIL:
+        *params = ENUM_TO_FLOAT(ctx->Stencil.ZFailFunc);
+        break;
+      case GL_STENCIL_PASS_DEPTH_PASS:
+        *params = ENUM_TO_FLOAT(ctx->Stencil.ZPassFunc);
+        break;
+      case GL_STENCIL_REF:
+        *params = (GLfloat) ctx->Stencil.Ref;
+        break;
+      case GL_STENCIL_TEST:
+        *params = (GLfloat) ctx->Stencil.Enabled;
+        break;
+      case GL_STENCIL_VALUE_MASK:
+        *params = (GLfloat) ctx->Stencil.ValueMask;
+        break;
+      case GL_STENCIL_WRITEMASK:
+        *params = (GLfloat) ctx->Stencil.WriteMask;
+        break;
+      case GL_STEREO:
+        *params = (GLfloat) ctx->Visual->StereoFlag;
+        break;
+      case GL_SUBPIXEL_BITS:
+        *params = 0.0F;  /* TODO */
+        break;
+      case GL_TEXTURE_1D:
+         *params = gl_IsEnabled(ctx, GL_TEXTURE_1D) ? 1.0 : 0.0;
+        break;
+      case GL_TEXTURE_2D:
+         *params = gl_IsEnabled(ctx, GL_TEXTURE_2D) ? 1.0 : 0.0;
+        break;
+      case GL_TEXTURE_3D:
+         *params = gl_IsEnabled(ctx, GL_TEXTURE_3D) ? 1.0 : 0.0;
+        break;
+      case GL_TEXTURE_BINDING_1D:
+         *params = (GLfloat) textureUnit->CurrentD[1]->Name;
+          break;
+      case GL_TEXTURE_BINDING_2D:
+         *params = (GLfloat) textureUnit->CurrentD[2]->Name;
+          break;
+      case GL_TEXTURE_BINDING_3D:
+         *params = (GLfloat) textureUnit->CurrentD[2]->Name;
+          break;
+      case GL_TEXTURE_ENV_COLOR:
+        params[0] = textureUnit->EnvColor[0];
+        params[1] = textureUnit->EnvColor[1];
+        params[2] = textureUnit->EnvColor[2];
+        params[3] = textureUnit->EnvColor[3];
+        break;
+      case GL_TEXTURE_ENV_MODE:
+        *params = ENUM_TO_FLOAT(textureUnit->EnvMode);
+        break;
+      case GL_TEXTURE_GEN_S:
+        *params = (textureUnit->TexGenEnabled & S_BIT) ? 1.0 : 0.0;
+        break;
+      case GL_TEXTURE_GEN_T:
+        *params = (textureUnit->TexGenEnabled & T_BIT) ? 1.0 : 0.0;
+        break;
+      case GL_TEXTURE_GEN_R:
+        *params = (textureUnit->TexGenEnabled & R_BIT) ? 1.0 : 0.0;
+        break;
+      case GL_TEXTURE_GEN_Q:
+        *params = (textureUnit->TexGenEnabled & Q_BIT) ? 1.0 : 0.0;
+        break;
+      case GL_TEXTURE_MATRIX:
+         for (i=0;i<16;i++) {
+           params[i] = ctx->TextureMatrix[texTransformUnit].m[i];
+        }
+        break;
+      case GL_TEXTURE_STACK_DEPTH:
+        *params = (GLfloat) (ctx->TextureStackDepth[texTransformUnit] + 1);
+        break;
+      case GL_UNPACK_ALIGNMENT:
+        *params = (GLfloat) ctx->Unpack.Alignment;
+        break;
+      case GL_UNPACK_LSB_FIRST:
+        *params = (GLfloat) ctx->Unpack.LsbFirst;
+        break;
+      case GL_UNPACK_ROW_LENGTH:
+        *params = (GLfloat) ctx->Unpack.RowLength;
+        break;
+      case GL_UNPACK_SKIP_PIXELS:
+        *params = (GLfloat) ctx->Unpack.SkipPixels;
+        break;
+      case GL_UNPACK_SKIP_ROWS:
+        *params = (GLfloat) ctx->Unpack.SkipRows;
+        break;
+      case GL_UNPACK_SWAP_BYTES:
+        *params = (GLfloat) ctx->Unpack.SwapBytes;
+        break;
+      case GL_UNPACK_SKIP_IMAGES_EXT:
+         *params = (GLfloat) ctx->Unpack.SkipImages;
+         break;
+      case GL_UNPACK_IMAGE_HEIGHT_EXT:
+         *params = (GLfloat) ctx->Unpack.ImageHeight;
+         break;
+      case GL_VIEWPORT:
+        params[0] = (GLfloat) ctx->Viewport.X;
+        params[1] = (GLfloat) ctx->Viewport.Y;
+        params[2] = (GLfloat) ctx->Viewport.Width;
+        params[3] = (GLfloat) ctx->Viewport.Height;
+        break;
+      case GL_ZOOM_X:
+        *params = (GLfloat) ctx->Pixel.ZoomX;
+        break;
+      case GL_ZOOM_Y:
+        *params = (GLfloat) ctx->Pixel.ZoomY;
+        break;
+      case GL_VERTEX_ARRAY_SIZE:
+         *params = (GLfloat) ctx->Array.Vertex.Size;
+         break;
+      case GL_VERTEX_ARRAY_TYPE:
+         *params = ENUM_TO_FLOAT(ctx->Array.Vertex.Type);
+         break;
+      case GL_VERTEX_ARRAY_STRIDE:
+         *params = (GLfloat) ctx->Array.Vertex.Stride;
+         break;
+      case GL_VERTEX_ARRAY_COUNT_EXT:
+         *params = 0.0;
+         break;
+      case GL_NORMAL_ARRAY_TYPE:
+         *params = ENUM_TO_FLOAT(ctx->Array.Normal.Type);
+         break;
+      case GL_NORMAL_ARRAY_STRIDE:
+         *params = (GLfloat) ctx->Array.Normal.Stride;
+         break;
+      case GL_NORMAL_ARRAY_COUNT_EXT:
+         *params = 0.0;
+         break;
+      case GL_COLOR_ARRAY_SIZE:
+         *params = (GLfloat) ctx->Array.Color.Size;
+         break;
+      case GL_COLOR_ARRAY_TYPE:
+         *params = ENUM_TO_FLOAT(ctx->Array.Color.Type);
+         break;
+      case GL_COLOR_ARRAY_STRIDE:
+         *params = (GLfloat) ctx->Array.Color.Stride;
+         break;
+      case GL_COLOR_ARRAY_COUNT_EXT:
+         *params = 0.0;
+         break;
+      case GL_INDEX_ARRAY_TYPE:
+         *params = ENUM_TO_FLOAT(ctx->Array.Index.Type);
+         break;
+      case GL_INDEX_ARRAY_STRIDE:
+         *params = (GLfloat) ctx->Array.Index.Stride;
+         break;
+      case GL_INDEX_ARRAY_COUNT_EXT:
+         *params = 0.0;
+         break;
+      case GL_TEXTURE_COORD_ARRAY_SIZE:
+         *params = (GLfloat) ctx->Array.TexCoord[texUnit].Size;
+         break;
+      case GL_TEXTURE_COORD_ARRAY_TYPE:
+         *params = ENUM_TO_FLOAT(ctx->Array.TexCoord[texUnit].Type);
+         break;
+      case GL_TEXTURE_COORD_ARRAY_STRIDE:
+         *params = (GLfloat) ctx->Array.TexCoord[texUnit].Stride;
+         break;
+      case GL_TEXTURE_COORD_ARRAY_COUNT_EXT:
+         *params = 0.0;
+         break;
+      case GL_EDGE_FLAG_ARRAY_STRIDE:
+         *params = (GLfloat) ctx->Array.EdgeFlag.Stride;
+         break;
+      case GL_EDGE_FLAG_ARRAY_COUNT_EXT:
+         *params = 0.0;
+         break;
+
+      case GL_MAX_TEXTURE_UNITS_ARB:
+         *params = (GLfloat) ctx->Const.MaxTextureUnits;
+         break;
+      case GL_ACTIVE_TEXTURE_ARB:
+         *params = (GLfloat) (GL_TEXTURE0_ARB + ctx->Texture.CurrentUnit);
+         break;
+      case GL_CLIENT_ACTIVE_TEXTURE_ARB:
+         *params = (GLfloat) (GL_TEXTURE0_ARB + ctx->Array.ActiveTexture);
+         break;
+
+      /* GL_PGI_misc_hints */
+      case GL_STRICT_DEPTHFUNC_HINT_PGI:
+        *params = ENUM_TO_FLOAT(GL_NICEST);
+         break;
+      case GL_STRICT_LIGHTING_HINT_PGI:
+        *params = ENUM_TO_FLOAT(ctx->Hint.StrictLighting);
+        break;
+      case GL_STRICT_SCISSOR_HINT_PGI:
+      case GL_FULL_STIPPLE_HINT_PGI:
+        *params = ENUM_TO_FLOAT(GL_TRUE);
+        break;
+      case GL_CONSERVE_MEMORY_HINT_PGI:
+        *params = ENUM_TO_FLOAT(GL_FALSE);
+        break;
+      case GL_ALWAYS_FAST_HINT_PGI:
+        *params = (GLfloat) (ctx->Hint.AllowDrawWin == GL_TRUE &&
+                             ctx->Hint.AllowDrawSpn == GL_FALSE && 
+                             ctx->Hint.AllowDrawMem == GL_FALSE);
+        break;
+      case GL_ALWAYS_SOFT_HINT_PGI:
+        *params = (GLfloat) (ctx->Hint.AllowDrawWin == GL_TRUE &&
+                             ctx->Hint.AllowDrawSpn == GL_TRUE && 
+                             ctx->Hint.AllowDrawMem == GL_TRUE);
+        break;
+      case GL_ALLOW_DRAW_OBJ_HINT_PGI:
+        *params = (GLfloat) GL_TRUE;
+        break;
+      case GL_ALLOW_DRAW_WIN_HINT_PGI:
+        *params = (GLfloat) ctx->Hint.AllowDrawWin;
+        break;
+      case GL_ALLOW_DRAW_SPN_HINT_PGI:
+        *params = (GLfloat) ctx->Hint.AllowDrawSpn;
+        break;
+      case GL_ALLOW_DRAW_MEM_HINT_PGI:
+        *params = (GLfloat) ctx->Hint.AllowDrawMem;
+        break;
+      case GL_CLIP_NEAR_HINT_PGI:
+      case GL_CLIP_FAR_HINT_PGI:
+        *params = ENUM_TO_FLOAT(GL_TRUE);
+        break;
+      case GL_WIDE_LINE_HINT_PGI:
+        *params = ENUM_TO_FLOAT(GL_DONT_CARE);
+        break;
+      case GL_BACK_NORMALS_HINT_PGI:
+        *params = ENUM_TO_FLOAT(GL_TRUE);
+        break;
+      case GL_NATIVE_GRAPHICS_HANDLE_PGI:
+        *params = 0;
+        break;
+
+      default:
+        printf("invalid enum: %x\n", pname);
+         gl_error( ctx, GL_INVALID_ENUM, "glGetFloatv" );
+   }
+}
+
+
+
+
+void gl_GetIntegerv( GLcontext *ctx, GLenum pname, GLint *params )
+{
+   GLuint i;
+   GLuint texUnit = ctx->Texture.CurrentUnit;
+   GLuint texTransformUnit = ctx->Texture.CurrentTransformUnit;
+   const struct gl_texture_unit *textureUnit = &ctx->Texture.Unit[texUnit];
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetIntegerv");
+
+   if (MESA_VERBOSE & VERBOSE_API) 
+      fprintf(stderr, "glGetIntegerv %s\n", gl_lookup_enum_by_nr(pname));
+
+   switch (pname) {
+      case GL_ACCUM_RED_BITS:
+      case GL_ACCUM_GREEN_BITS:
+      case GL_ACCUM_BLUE_BITS:
+      case GL_ACCUM_ALPHA_BITS:
+         *params = (GLint) ctx->Visual->AccumBits;
+         break;
+      case GL_ACCUM_CLEAR_VALUE:
+         params[0] = FLOAT_TO_INT( ctx->Accum.ClearColor[0] );
+         params[1] = FLOAT_TO_INT( ctx->Accum.ClearColor[1] );
+         params[2] = FLOAT_TO_INT( ctx->Accum.ClearColor[2] );
+         params[3] = FLOAT_TO_INT( ctx->Accum.ClearColor[3] );
+         break;
+      case GL_ALPHA_BIAS:
+         *params = (GLint) ctx->Pixel.AlphaBias;
+         break;
+      case GL_ALPHA_BITS:
+         *params = ctx->Visual->AlphaBits;
+         break;
+      case GL_ALPHA_SCALE:
+         *params = (GLint) ctx->Pixel.AlphaScale;
+         break;
+      case GL_ALPHA_TEST:
+         *params = (GLint) ctx->Color.AlphaEnabled;
+         break;
+      case GL_ALPHA_TEST_REF:
+         *params = FLOAT_TO_INT( (GLfloat) ctx->Color.AlphaRef / 255.0 );
+         break;
+      case GL_ALPHA_TEST_FUNC:
+         *params = (GLint) ctx->Color.AlphaFunc;
+         break;
+      case GL_ATTRIB_STACK_DEPTH:
+         *params = (GLint) (ctx->AttribStackDepth);
+         break;
+      case GL_AUTO_NORMAL:
+         *params = (GLint) ctx->Eval.AutoNormal;
+         break;
+      case GL_AUX_BUFFERS:
+         *params = (GLint) NUM_AUX_BUFFERS;
+         break;
+      case GL_BLEND:
+         *params = (GLint) ctx->Color.BlendEnabled;
+         break;
+      case GL_BLEND_DST:
+         *params = (GLint) ctx->Color.BlendDstRGB;
+         break;
+      case GL_BLEND_SRC:
+         *params = (GLint) ctx->Color.BlendSrcRGB;
+         break;
+      case GL_BLEND_SRC_RGB_INGR:
+         *params = (GLint) ctx->Color.BlendSrcRGB;
+         break;
+      case GL_BLEND_DST_RGB_INGR:
+         *params = (GLint) ctx->Color.BlendDstRGB;
+         break;
+      case GL_BLEND_SRC_ALPHA_INGR:
+         *params = (GLint) ctx->Color.BlendSrcA;
+         break;
+      case GL_BLEND_DST_ALPHA_INGR:
+         *params = (GLint) ctx->Color.BlendDstA;
+         break;
+      case GL_BLEND_EQUATION_EXT:
+        *params = (GLint) ctx->Color.BlendEquation;
+        break;
+      case GL_BLEND_COLOR_EXT:
+        params[0] = FLOAT_TO_INT( ctx->Color.BlendColor[0] );
+        params[1] = FLOAT_TO_INT( ctx->Color.BlendColor[1] );
+        params[2] = FLOAT_TO_INT( ctx->Color.BlendColor[2] );
+        params[3] = FLOAT_TO_INT( ctx->Color.BlendColor[3] );
+        break;
+      case GL_BLUE_BIAS:
+         *params = (GLint) ctx->Pixel.BlueBias;
+         break;
+      case GL_BLUE_BITS:
+         *params = (GLint) ctx->Visual->BlueBits;
+         break;
+      case GL_BLUE_SCALE:
+         *params = (GLint) ctx->Pixel.BlueScale;
+         break;
+      case GL_CLIENT_ATTRIB_STACK_DEPTH:
+         *params = (GLint) (ctx->ClientAttribStackDepth);
+         break;
+      case GL_CLIP_PLANE0:
+      case GL_CLIP_PLANE1:
+      case GL_CLIP_PLANE2:
+      case GL_CLIP_PLANE3:
+      case GL_CLIP_PLANE4:
+      case GL_CLIP_PLANE5:
+         i = (GLint) (pname - GL_CLIP_PLANE0);
+         *params = (GLint) ctx->Transform.ClipEnabled[i];
+         break;
+      case GL_COLOR_CLEAR_VALUE:
+         params[0] = FLOAT_TO_INT( ctx->Color.ClearColor[0] );
+         params[1] = FLOAT_TO_INT( ctx->Color.ClearColor[1] );
+         params[2] = FLOAT_TO_INT( ctx->Color.ClearColor[2] );
+         params[3] = FLOAT_TO_INT( ctx->Color.ClearColor[3] );
+         break;
+      case GL_COLOR_MATERIAL:
+         *params = (GLint) ctx->Light.ColorMaterialEnabled;
+         break;
+      case GL_COLOR_MATERIAL_FACE:
+         *params = (GLint) ctx->Light.ColorMaterialFace;
+         break;
+      case GL_COLOR_MATERIAL_PARAMETER:
+         *params = (GLint) ctx->Light.ColorMaterialMode;
+         break;
+      case GL_COLOR_WRITEMASK:
+         params[0] = ctx->Color.ColorMask[RCOMP] ? 1 : 0;
+         params[1] = ctx->Color.ColorMask[GCOMP] ? 1 : 0;
+         params[2] = ctx->Color.ColorMask[BCOMP] ? 1 : 0;
+         params[3] = ctx->Color.ColorMask[ACOMP] ? 1 : 0;
+         break;
+      case GL_CULL_FACE:
+         *params = (GLint) ctx->Polygon.CullFlag;
+         break;
+      case GL_CULL_FACE_MODE:
+         *params = (GLint) ctx->Polygon.CullFaceMode;
+         break;
+      case GL_CURRENT_COLOR:
+         params[0] = FLOAT_TO_INT( UBYTE_COLOR_TO_FLOAT_COLOR( ctx->Current.ByteColor[0] ) );
+         params[1] = FLOAT_TO_INT( UBYTE_COLOR_TO_FLOAT_COLOR( ctx->Current.ByteColor[1] ) );
+         params[2] = FLOAT_TO_INT( UBYTE_COLOR_TO_FLOAT_COLOR( ctx->Current.ByteColor[2] ) );
+         params[3] = FLOAT_TO_INT( UBYTE_COLOR_TO_FLOAT_COLOR( ctx->Current.ByteColor[3] ) );
+         break;
+      case GL_CURRENT_INDEX:
+         *params = (GLint) ctx->Current.Index;
+         break;
+      case GL_CURRENT_NORMAL:
+         params[0] = FLOAT_TO_INT( ctx->Current.Normal[0] );
+         params[1] = FLOAT_TO_INT( ctx->Current.Normal[1] );
+         params[2] = FLOAT_TO_INT( ctx->Current.Normal[2] );
+         break;
+      case GL_CURRENT_RASTER_COLOR:
+        params[0] = FLOAT_TO_INT( ctx->Current.RasterColor[0] );
+        params[1] = FLOAT_TO_INT( ctx->Current.RasterColor[1] );
+        params[2] = FLOAT_TO_INT( ctx->Current.RasterColor[2] );
+        params[3] = FLOAT_TO_INT( ctx->Current.RasterColor[3] );
+        break;
+      case GL_CURRENT_RASTER_DISTANCE:
+        params[0] = (GLint) ctx->Current.RasterDistance;
+        break;
+      case GL_CURRENT_RASTER_INDEX:
+        *params = (GLint) ctx->Current.RasterIndex;
+        break;
+      case GL_CURRENT_RASTER_POSITION:
+        params[0] = (GLint) ctx->Current.RasterPos[0];
+        params[1] = (GLint) ctx->Current.RasterPos[1];
+        params[2] = (GLint) ctx->Current.RasterPos[2];
+        params[3] = (GLint) ctx->Current.RasterPos[3];
+        break;
+      case GL_CURRENT_RASTER_TEXTURE_COORDS:
+        params[0] = (GLint) ctx->Current.RasterMultiTexCoord[texTransformUnit][0];
+        params[1] = (GLint) ctx->Current.RasterMultiTexCoord[texTransformUnit][1];
+        params[2] = (GLint) ctx->Current.RasterMultiTexCoord[texTransformUnit][2];
+        params[3] = (GLint) ctx->Current.RasterMultiTexCoord[texTransformUnit][3];
+        break;
+      case GL_CURRENT_RASTER_POSITION_VALID:
+        *params = (GLint) ctx->Current.RasterPosValid;
+        break;
+      case GL_CURRENT_TEXTURE_COORDS:
+         params[0] = (GLint) ctx->Current.Texcoord[texTransformUnit][0];
+         params[1] = (GLint) ctx->Current.Texcoord[texTransformUnit][1];
+         params[2] = (GLint) ctx->Current.Texcoord[texTransformUnit][2];
+         params[3] = (GLint) ctx->Current.Texcoord[texTransformUnit][3];
+        break;
+      case GL_DEPTH_BIAS:
+         *params = (GLint) ctx->Pixel.DepthBias;
+        break;
+      case GL_DEPTH_BITS:
+        *params = ctx->Visual->DepthBits;
+        break;
+      case GL_DEPTH_CLEAR_VALUE:
+         *params = (GLint) ctx->Depth.Clear;
+        break;
+      case GL_DEPTH_FUNC:
+         *params = (GLint) ctx->Depth.Func;
+        break;
+      case GL_DEPTH_RANGE:
+         params[0] = (GLint) ctx->Viewport.Near;
+         params[1] = (GLint) ctx->Viewport.Far;
+        break;
+      case GL_DEPTH_SCALE:
+         *params = (GLint) ctx->Pixel.DepthScale;
+        break;
+      case GL_DEPTH_TEST:
+         *params = (GLint) ctx->Depth.Test;
+        break;
+      case GL_DEPTH_WRITEMASK:
+        *params = (GLint) ctx->Depth.Mask;
+        break;
+      case GL_DITHER:
+        *params = (GLint) ctx->Color.DitherFlag;
+        break;
+      case GL_DOUBLEBUFFER:
+        *params = (GLint) ctx->Visual->DBflag;
+        break;
+      case GL_DRAW_BUFFER:
+        *params = (GLint) ctx->Color.DrawBuffer;
+        break;
+      case GL_EDGE_FLAG:
+        *params = (GLint) ctx->Current.EdgeFlag;
+        break;
+      case GL_FEEDBACK_BUFFER_SIZE:
+         /* TODO: is this right?  Or, return number of entries in buffer? */
+         *params = ctx->Feedback.BufferSize;
+         break;
+      case GL_FEEDBACK_BUFFER_TYPE:
+         *params = ctx->Feedback.Type;
+         break;
+      case GL_FOG:
+        *params = (GLint) ctx->Fog.Enabled;
+        break;
+      case GL_FOG_COLOR:
+        params[0] = FLOAT_TO_INT( ctx->Fog.Color[0] );
+        params[1] = FLOAT_TO_INT( ctx->Fog.Color[1] );
+        params[2] = FLOAT_TO_INT( ctx->Fog.Color[2] );
+        params[3] = FLOAT_TO_INT( ctx->Fog.Color[3] );
+        break;
+      case GL_FOG_DENSITY:
+        *params = (GLint) ctx->Fog.Density;
+        break;
+      case GL_FOG_END:
+        *params = (GLint) ctx->Fog.End;
+        break;
+      case GL_FOG_HINT:
+        *params = (GLint) ctx->Hint.Fog;
+        break;
+      case GL_FOG_INDEX:
+        *params = (GLint) ctx->Fog.Index;
+        break;
+      case GL_FOG_MODE:
+        *params = (GLint) ctx->Fog.Mode;
+        break;
+      case GL_FOG_START:
+        *params = (GLint) ctx->Fog.Start;
+        break;
+      case GL_FRONT_FACE:
+        *params = (GLint) ctx->Polygon.FrontFace;
+        break;
+      case GL_GREEN_BIAS:
+         *params = (GLint) ctx->Pixel.GreenBias;
+         break;
+      case GL_GREEN_BITS:
+         *params = (GLint) ctx->Visual->GreenBits;
+         break;
+      case GL_GREEN_SCALE:
+         *params = (GLint) ctx->Pixel.GreenScale;
+         break;
+      case GL_INDEX_BITS:
+         *params = (GLint) ctx->Visual->IndexBits;
+         break;
+      case GL_INDEX_CLEAR_VALUE:
+         *params = (GLint) ctx->Color.ClearIndex;
+         break;
+      case GL_INDEX_MODE:
+        *params = ctx->Visual->RGBAflag ? 0 : 1;
+        break;
+      case GL_INDEX_OFFSET:
+        *params = ctx->Pixel.IndexOffset;
+        break;
+      case GL_INDEX_SHIFT:
+        *params = ctx->Pixel.IndexShift;
+        break;
+      case GL_INDEX_WRITEMASK:
+        *params = (GLint) ctx->Color.IndexMask;
+        break;
+      case GL_LIGHT0:
+      case GL_LIGHT1:
+      case GL_LIGHT2:
+      case GL_LIGHT3:
+      case GL_LIGHT4:
+      case GL_LIGHT5:
+      case GL_LIGHT6:
+      case GL_LIGHT7:
+        *params = (GLint) ctx->Light.Light[pname-GL_LIGHT0].Enabled;
+        break;
+      case GL_LIGHTING:
+        *params = (GLint) ctx->Light.Enabled;
+        break;
+      case GL_LIGHT_MODEL_AMBIENT:
+        params[0] = FLOAT_TO_INT( ctx->Light.Model.Ambient[0] );
+        params[1] = FLOAT_TO_INT( ctx->Light.Model.Ambient[1] );
+        params[2] = FLOAT_TO_INT( ctx->Light.Model.Ambient[2] );
+        params[3] = FLOAT_TO_INT( ctx->Light.Model.Ambient[3] );
+        break;
+      case GL_LIGHT_MODEL_COLOR_CONTROL:
+         params[0] = (GLint) ctx->Light.Model.ColorControl;
+         break;
+      case GL_LIGHT_MODEL_LOCAL_VIEWER:
+        *params = (GLint) ctx->Light.Model.LocalViewer;
+        break;
+      case GL_LIGHT_MODEL_TWO_SIDE:
+        *params = (GLint) ctx->Light.Model.TwoSide;
+        break;
+      case GL_LINE_SMOOTH:
+        *params = (GLint) ctx->Line.SmoothFlag;
+        break;
+      case GL_LINE_SMOOTH_HINT:
+        *params = (GLint) ctx->Hint.LineSmooth;
+        break;
+      case GL_LINE_STIPPLE:
+        *params = (GLint) ctx->Line.StippleFlag;
+        break;
+      case GL_LINE_STIPPLE_PATTERN:
+         *params = (GLint) ctx->Line.StipplePattern;
+         break;
+      case GL_LINE_STIPPLE_REPEAT:
+         *params = (GLint) ctx->Line.StippleFactor;
+         break;
+      case GL_LINE_WIDTH:
+        *params = (GLint) ctx->Line.Width;
+        break;
+      case GL_LINE_WIDTH_GRANULARITY:
+        *params = (GLint) LINE_WIDTH_GRANULARITY;
+        break;
+      case GL_LINE_WIDTH_RANGE:
+        params[0] = (GLint) MIN_LINE_WIDTH;
+        params[1] = (GLint) MAX_LINE_WIDTH;
+        break;
+      case GL_LIST_BASE:
+        *params = (GLint) ctx->List.ListBase;
+        break;
+      case GL_LIST_INDEX:
+        *params = (GLint) ctx->CurrentListNum;
+        break;
+      case GL_LIST_MODE:
+        *params = ctx->ExecuteFlag ? (GLint) GL_COMPILE_AND_EXECUTE
+                                 : (GLint) GL_COMPILE;
+        break;
+      case GL_INDEX_LOGIC_OP:
+        *params = (GLint) ctx->Color.IndexLogicOpEnabled;
+        break;
+      case GL_COLOR_LOGIC_OP:
+        *params = (GLint) ctx->Color.ColorLogicOpEnabled;
+        break;
+      case GL_LOGIC_OP_MODE:
+         *params = (GLint) ctx->Color.LogicOp;
+         break;
+      case GL_MAP1_COLOR_4:
+        *params = (GLint) ctx->Eval.Map1Color4;
+        break;
+      case GL_MAP1_GRID_DOMAIN:
+        params[0] = (GLint) ctx->Eval.MapGrid1u1;
+        params[1] = (GLint) ctx->Eval.MapGrid1u2;
+        break;
+      case GL_MAP1_GRID_SEGMENTS:
+        *params = (GLint) ctx->Eval.MapGrid1un;
+        break;
+      case GL_MAP1_INDEX:
+        *params = (GLint) ctx->Eval.Map1Index;
+        break;
+      case GL_MAP1_NORMAL:
+        *params = (GLint) ctx->Eval.Map1Normal;
+        break;
+      case GL_MAP1_TEXTURE_COORD_1:
+        *params = (GLint) ctx->Eval.Map1TextureCoord1;
+        break;
+      case GL_MAP1_TEXTURE_COORD_2:
+        *params = (GLint) ctx->Eval.Map1TextureCoord2;
+        break;
+      case GL_MAP1_TEXTURE_COORD_3:
+        *params = (GLint) ctx->Eval.Map1TextureCoord3;
+        break;
+      case GL_MAP1_TEXTURE_COORD_4:
+        *params = (GLint) ctx->Eval.Map1TextureCoord4;
+        break;
+      case GL_MAP1_VERTEX_3:
+        *params = (GLint) ctx->Eval.Map1Vertex3;
+        break;
+      case GL_MAP1_VERTEX_4:
+        *params = (GLint) ctx->Eval.Map1Vertex4;
+        break;
+      case GL_MAP2_COLOR_4:
+        *params = (GLint) ctx->Eval.Map2Color4;
+        break;
+      case GL_MAP2_GRID_DOMAIN:
+        params[0] = (GLint) ctx->Eval.MapGrid2u1;
+        params[1] = (GLint) ctx->Eval.MapGrid2u2;
+        params[2] = (GLint) ctx->Eval.MapGrid2v1;
+        params[3] = (GLint) ctx->Eval.MapGrid2v2;
+        break;
+      case GL_MAP2_GRID_SEGMENTS:
+        params[0] = (GLint) ctx->Eval.MapGrid2un;
+        params[1] = (GLint) ctx->Eval.MapGrid2vn;
+        break;
+      case GL_MAP2_INDEX:
+        *params = (GLint) ctx->Eval.Map2Index;
+        break;
+      case GL_MAP2_NORMAL:
+        *params = (GLint) ctx->Eval.Map2Normal;
+        break;
+      case GL_MAP2_TEXTURE_COORD_1:
+        *params = (GLint) ctx->Eval.Map2TextureCoord1;
+        break;
+      case GL_MAP2_TEXTURE_COORD_2:
+        *params = (GLint) ctx->Eval.Map2TextureCoord2;
+        break;
+      case GL_MAP2_TEXTURE_COORD_3:
+        *params = (GLint) ctx->Eval.Map2TextureCoord3;
+        break;
+      case GL_MAP2_TEXTURE_COORD_4:
+        *params = (GLint) ctx->Eval.Map2TextureCoord4;
+        break;
+      case GL_MAP2_VERTEX_3:
+        *params = (GLint) ctx->Eval.Map2Vertex3;
+        break;
+      case GL_MAP2_VERTEX_4:
+        *params = (GLint) ctx->Eval.Map2Vertex4;
+        break;
+      case GL_MAP_COLOR:
+        *params = (GLint) ctx->Pixel.MapColorFlag;
+        break;
+      case GL_MAP_STENCIL:
+        *params = (GLint) ctx->Pixel.MapStencilFlag;
+        break;
+      case GL_MATRIX_MODE:
+        *params = (GLint) ctx->Transform.MatrixMode;
+        break;
+      case GL_MAX_ATTRIB_STACK_DEPTH:
+         *params = (GLint) MAX_ATTRIB_STACK_DEPTH;
+         break;
+      case GL_MAX_CLIENT_ATTRIB_STACK_DEPTH:
+         *params = (GLint) MAX_CLIENT_ATTRIB_STACK_DEPTH;
+         break;
+      case GL_MAX_CLIP_PLANES:
+         *params = (GLint) MAX_CLIP_PLANES;
+         break;
+      case GL_MAX_ELEMENTS_VERTICES:  /* GL_VERSION_1_2 */
+         *params = VB_MAX;
+         break;
+      case GL_MAX_ELEMENTS_INDICES:   /* GL_VERSION_1_2 */
+         *params = VB_MAX;
+         break;
+      case GL_MAX_EVAL_ORDER:
+        *params = (GLint) MAX_EVAL_ORDER;
+        break;
+      case GL_MAX_LIGHTS:
+         *params = (GLint) MAX_LIGHTS;
+         break;
+      case GL_MAX_LIST_NESTING:
+         *params = (GLint) MAX_LIST_NESTING;
+         break;
+      case GL_MAX_MODELVIEW_STACK_DEPTH:
+         *params = (GLint) MAX_MODELVIEW_STACK_DEPTH;
+         break;
+      case GL_MAX_NAME_STACK_DEPTH:
+        *params = (GLint) MAX_NAME_STACK_DEPTH;
+        break;
+      case GL_MAX_PIXEL_MAP_TABLE:
+        *params = (GLint) MAX_PIXEL_MAP_TABLE;
+        break;
+      case GL_MAX_PROJECTION_STACK_DEPTH:
+         *params = (GLint) MAX_PROJECTION_STACK_DEPTH;
+         break;
+      case GL_MAX_TEXTURE_SIZE:
+      case GL_MAX_3D_TEXTURE_SIZE:
+         *params = ctx->Const.MaxTextureSize;
+        break;
+      case GL_MAX_TEXTURE_STACK_DEPTH:
+        *params = (GLint) MAX_TEXTURE_STACK_DEPTH;
+        break;
+      case GL_MAX_VIEWPORT_DIMS:
+         params[0] = (GLint) MAX_WIDTH;
+         params[1] = (GLint) MAX_HEIGHT;
+         break;
+      case GL_MODELVIEW_MATRIX:
+        for (i=0;i<16;i++) {
+           params[i] = (GLint) ctx->ModelView.m[i];
+        }
+        break;
+      case GL_MODELVIEW_STACK_DEPTH:
+        *params = (GLint) (ctx->ModelViewStackDepth + 1);
+        break;
+      case GL_NAME_STACK_DEPTH:
+        *params = (GLint) ctx->Select.NameStackDepth;
+        break;
+      case GL_NORMALIZE:
+        *params = (GLint) ctx->Transform.Normalize;
+        break;
+      case GL_PACK_ALIGNMENT:
+        *params = ctx->Pack.Alignment;
+        break;
+      case GL_PACK_LSB_FIRST:
+        *params = (GLint) ctx->Pack.LsbFirst;
+        break;
+      case GL_PACK_ROW_LENGTH:
+        *params = ctx->Pack.RowLength;
+        break;
+      case GL_PACK_SKIP_PIXELS:
+        *params = ctx->Pack.SkipPixels;
+        break;
+      case GL_PACK_SKIP_ROWS:
+        *params = ctx->Pack.SkipRows;
+        break;
+      case GL_PACK_SWAP_BYTES:
+        *params = (GLint) ctx->Pack.SwapBytes;
+        break;
+      case GL_PACK_SKIP_IMAGES_EXT:
+         *params = ctx->Pack.SkipImages;
+         break;
+      case GL_PACK_IMAGE_HEIGHT_EXT:
+         *params = ctx->Pack.ImageHeight;
+         break;
+      case GL_PERSPECTIVE_CORRECTION_HINT:
+        *params = (GLint) ctx->Hint.PerspectiveCorrection;
+        break;
+      case GL_PIXEL_MAP_A_TO_A_SIZE:
+        *params = ctx->Pixel.MapAtoAsize;
+        break;
+      case GL_PIXEL_MAP_B_TO_B_SIZE:
+        *params = ctx->Pixel.MapBtoBsize;
+        break;
+      case GL_PIXEL_MAP_G_TO_G_SIZE:
+        *params = ctx->Pixel.MapGtoGsize;
+        break;
+      case GL_PIXEL_MAP_I_TO_A_SIZE:
+        *params = ctx->Pixel.MapItoAsize;
+        break;
+      case GL_PIXEL_MAP_I_TO_B_SIZE:
+        *params = ctx->Pixel.MapItoBsize;
+        break;
+      case GL_PIXEL_MAP_I_TO_G_SIZE:
+        *params = ctx->Pixel.MapItoGsize;
+        break;
+      case GL_PIXEL_MAP_I_TO_I_SIZE:
+        *params = ctx->Pixel.MapItoIsize;
+        break;
+      case GL_PIXEL_MAP_I_TO_R_SIZE:
+        *params = ctx->Pixel.MapItoRsize;
+        break;
+      case GL_PIXEL_MAP_R_TO_R_SIZE:
+        *params = ctx->Pixel.MapRtoRsize;
+        break;
+      case GL_PIXEL_MAP_S_TO_S_SIZE:
+        *params = ctx->Pixel.MapStoSsize;
+        break;
+      case GL_POINT_SIZE:
+         *params = (GLint) ctx->Point.Size;
+         break;
+      case GL_POINT_SIZE_GRANULARITY:
+        *params = (GLint) POINT_SIZE_GRANULARITY;
+        break;
+      case GL_POINT_SIZE_RANGE:
+        params[0] = (GLint) MIN_POINT_SIZE;
+        params[1] = (GLint) MAX_POINT_SIZE;
+        break;
+      case GL_POINT_SMOOTH:
+        *params = (GLint) ctx->Point.SmoothFlag;
+        break;
+      case GL_POINT_SMOOTH_HINT:
+        *params = (GLint) ctx->Hint.PointSmooth;
+        break;
+      case GL_POINT_SIZE_MIN_EXT:
+        *params = (GLint) (ctx->Point.MinSize);
+        break;
+      case GL_POINT_SIZE_MAX_EXT:
+        *params = (GLint) (ctx->Point.MaxSize);
+        break;
+      case GL_POINT_FADE_THRESHOLD_SIZE_EXT:
+        *params = (GLint) (ctx->Point.Threshold);
+        break;
+      case GL_DISTANCE_ATTENUATION_EXT:
+        params[0] = (GLint) (ctx->Point.Params[0]);
+        params[1] = (GLint) (ctx->Point.Params[1]);
+        params[2] = (GLint) (ctx->Point.Params[2]);
+        break;
+      case GL_POLYGON_MODE:
+        params[0] = (GLint) ctx->Polygon.FrontMode;
+        params[1] = (GLint) ctx->Polygon.BackMode;
+        break;
+#ifdef GL_EXT_polygon_offset
+      case GL_POLYGON_OFFSET_BIAS_EXT:
+         *params = (GLint) ctx->Polygon.OffsetUnits;
+         break;
+#endif
+      case GL_POLYGON_OFFSET_FACTOR:
+         *params = (GLint) ctx->Polygon.OffsetFactor;
+         break;
+      case GL_POLYGON_OFFSET_UNITS:
+         *params = (GLint) ctx->Polygon.OffsetUnits;
+         break;
+      case GL_POLYGON_SMOOTH:
+        *params = (GLint) ctx->Polygon.SmoothFlag;
+        break;
+      case GL_POLYGON_SMOOTH_HINT:
+        *params = (GLint) ctx->Hint.PolygonSmooth;
+        break;
+      case GL_POLYGON_STIPPLE:
+         *params = (GLint) ctx->Polygon.StippleFlag;
+        break;
+      case GL_PROJECTION_MATRIX:
+        for (i=0;i<16;i++) {
+           params[i] = (GLint) ctx->ProjectionMatrix.m[i];
+        }
+        break;
+      case GL_PROJECTION_STACK_DEPTH:
+        *params = (GLint) (ctx->ProjectionStackDepth + 1);
+        break;
+      case GL_READ_BUFFER:
+        *params = (GLint) ctx->Pixel.ReadBuffer;
+        break;
+      case GL_RED_BIAS:
+         *params = (GLint) ctx->Pixel.RedBias;
+         break;
+      case GL_RED_BITS:
+         *params = (GLint) ctx->Visual->RedBits;
+         break;
+      case GL_RED_SCALE:
+         *params = (GLint) ctx->Pixel.RedScale;
+         break;
+      case GL_RENDER_MODE:
+        *params = (GLint) ctx->RenderMode;
+        break;
+      case GL_RGBA_MODE:
+        *params = (GLint) ctx->Visual->RGBAflag;
+        break;
+      case GL_SCISSOR_BOX:
+        params[0] = (GLint) ctx->Scissor.X;
+        params[1] = (GLint) ctx->Scissor.Y;
+        params[2] = (GLint) ctx->Scissor.Width;
+        params[3] = (GLint) ctx->Scissor.Height;
+        break;
+      case GL_SCISSOR_TEST:
+        *params = (GLint) ctx->Scissor.Enabled;
+        break;
+      case GL_SELECTION_BUFFER_SIZE:
+         *params = (GLint) ctx->Select.BufferSize;
+         break;
+      case GL_SHADE_MODEL:
+        *params = (GLint) ctx->Light.ShadeModel;
+        break;
+      case GL_SHARED_TEXTURE_PALETTE_EXT:
+         *params = (GLint) ctx->Texture.SharedPalette;
+         break;
+      case GL_STENCIL_BITS:
+         *params = ctx->Visual->StencilBits;
+         break;
+      case GL_STENCIL_CLEAR_VALUE:
+        *params = (GLint) ctx->Stencil.Clear;
+        break;
+      case GL_STENCIL_FAIL:
+        *params = (GLint) ctx->Stencil.FailFunc;
+        break;
+      case GL_STENCIL_FUNC:
+        *params = (GLint) ctx->Stencil.Function;
+        break;
+      case GL_STENCIL_PASS_DEPTH_FAIL:
+        *params = (GLint) ctx->Stencil.ZFailFunc;
+        break;
+      case GL_STENCIL_PASS_DEPTH_PASS:
+        *params = (GLint) ctx->Stencil.ZPassFunc;
+        break;
+      case GL_STENCIL_REF:
+        *params = (GLint) ctx->Stencil.Ref;
+        break;
+      case GL_STENCIL_TEST:
+        *params = (GLint) ctx->Stencil.Enabled;
+        break;
+      case GL_STENCIL_VALUE_MASK:
+        *params = (GLint) ctx->Stencil.ValueMask;
+        break;
+      case GL_STENCIL_WRITEMASK:
+        *params = (GLint) ctx->Stencil.WriteMask;
+        break;
+      case GL_STEREO:
+        *params = (GLint) ctx->Visual->StereoFlag;
+        break;
+      case GL_SUBPIXEL_BITS:
+        *params = 0;  /* TODO */
+        break;
+      case GL_TEXTURE_1D:
+         *params = gl_IsEnabled(ctx, GL_TEXTURE_1D) ? 1 : 0;
+        break;
+      case GL_TEXTURE_2D:
+         *params = gl_IsEnabled(ctx, GL_TEXTURE_2D) ? 1 : 0;
+        break;
+      case GL_TEXTURE_3D:
+         *params = gl_IsEnabled(ctx, GL_TEXTURE_3D) ? 1 : 0;
+        break;
+      case GL_TEXTURE_BINDING_1D:
+         *params = textureUnit->CurrentD[1]->Name;
+          break;
+      case GL_TEXTURE_BINDING_2D:
+         *params = textureUnit->CurrentD[2]->Name;
+          break;
+      case GL_TEXTURE_BINDING_3D:
+         *params = textureUnit->CurrentD[3]->Name;
+          break;
+      case GL_TEXTURE_ENV_COLOR:
+        params[0] = FLOAT_TO_INT( textureUnit->EnvColor[0] );
+        params[1] = FLOAT_TO_INT( textureUnit->EnvColor[1] );
+        params[2] = FLOAT_TO_INT( textureUnit->EnvColor[2] );
+        params[3] = FLOAT_TO_INT( textureUnit->EnvColor[3] );
+        break;
+      case GL_TEXTURE_ENV_MODE:
+        *params = (GLint) textureUnit->EnvMode;
+        break;
+      case GL_TEXTURE_GEN_S:
+        *params = (textureUnit->TexGenEnabled & S_BIT) ? 1 : 0;
+        break;
+      case GL_TEXTURE_GEN_T:
+        *params = (textureUnit->TexGenEnabled & T_BIT) ? 1 : 0;
+        break;
+      case GL_TEXTURE_GEN_R:
+        *params = (textureUnit->TexGenEnabled & R_BIT) ? 1 : 0;
+        break;
+      case GL_TEXTURE_GEN_Q:
+        *params = (textureUnit->TexGenEnabled & Q_BIT) ? 1 : 0;
+        break;
+      case GL_TEXTURE_MATRIX:
+         for (i=0;i<16;i++) {
+           params[i] = (GLint) ctx->TextureMatrix[texTransformUnit].m[i];
+        }
+        break;
+      case GL_TEXTURE_STACK_DEPTH:
+        *params = (GLint) (ctx->TextureStackDepth[texTransformUnit] + 1);
+        break;
+      case GL_UNPACK_ALIGNMENT:
+        *params = ctx->Unpack.Alignment;
+        break;
+      case GL_UNPACK_LSB_FIRST:
+        *params = (GLint) ctx->Unpack.LsbFirst;
+        break;
+      case GL_UNPACK_ROW_LENGTH:
+        *params = ctx->Unpack.RowLength;
+        break;
+      case GL_UNPACK_SKIP_PIXELS:
+        *params = ctx->Unpack.SkipPixels;
+        break;
+      case GL_UNPACK_SKIP_ROWS:
+        *params = ctx->Unpack.SkipRows;
+        break;
+      case GL_UNPACK_SWAP_BYTES:
+        *params = (GLint) ctx->Unpack.SwapBytes;
+        break;
+      case GL_UNPACK_SKIP_IMAGES_EXT:
+         *params = ctx->Unpack.SkipImages;
+         break;
+      case GL_UNPACK_IMAGE_HEIGHT_EXT:
+         *params = ctx->Unpack.ImageHeight;
+         break;
+      case GL_VIEWPORT:
+         params[0] = (GLint) ctx->Viewport.X;
+         params[1] = (GLint) ctx->Viewport.Y;
+         params[2] = (GLint) ctx->Viewport.Width;
+         params[3] = (GLint) ctx->Viewport.Height;
+         break;
+      case GL_ZOOM_X:
+        *params = (GLint) ctx->Pixel.ZoomX;
+        break;
+      case GL_ZOOM_Y:
+        *params = (GLint) ctx->Pixel.ZoomY;
+        break;
+      case GL_VERTEX_ARRAY_SIZE:
+         *params = ctx->Array.Vertex.Size;
+         break;
+      case GL_VERTEX_ARRAY_TYPE:
+         *params = ctx->Array.Vertex.Type;
+         break;
+      case GL_VERTEX_ARRAY_STRIDE:
+         *params = ctx->Array.Vertex.Stride;
+         break;
+      case GL_VERTEX_ARRAY_COUNT_EXT:
+         *params = 0;
+         break;
+      case GL_NORMAL_ARRAY_TYPE:
+         *params = ctx->Array.Normal.Type;
+         break;
+      case GL_NORMAL_ARRAY_STRIDE:
+         *params = ctx->Array.Normal.Stride;
+         break;
+      case GL_NORMAL_ARRAY_COUNT_EXT:
+         *params = 0;
+         break;
+      case GL_COLOR_ARRAY_SIZE:
+         *params = ctx->Array.Color.Size;
+         break;
+      case GL_COLOR_ARRAY_TYPE:
+         *params = ctx->Array.Color.Type;
+         break;
+      case GL_COLOR_ARRAY_STRIDE:
+         *params = ctx->Array.Color.Stride;
+         break;
+      case GL_COLOR_ARRAY_COUNT_EXT:
+         *params = 0;
+         break;
+      case GL_INDEX_ARRAY_TYPE:
+         *params = ctx->Array.Index.Type;
+         break;
+      case GL_INDEX_ARRAY_STRIDE:
+         *params = ctx->Array.Index.Stride;
+         break;
+      case GL_INDEX_ARRAY_COUNT_EXT:
+         *params = 0;
+         break;
+      case GL_TEXTURE_COORD_ARRAY_SIZE:
+         *params = ctx->Array.TexCoord[texUnit].Size;
+         break;
+      case GL_TEXTURE_COORD_ARRAY_TYPE:
+         *params = ctx->Array.TexCoord[texUnit].Type;
+         break;
+      case GL_TEXTURE_COORD_ARRAY_STRIDE:
+         *params = ctx->Array.TexCoord[texUnit].Stride;
+         break;
+      case GL_TEXTURE_COORD_ARRAY_COUNT_EXT:
+         *params = 0;
+         break;
+      case GL_EDGE_FLAG_ARRAY_STRIDE:
+         *params = ctx->Array.EdgeFlag.Stride;
+         break;
+      case GL_EDGE_FLAG_ARRAY_COUNT_EXT:
+         *params = 0;
+         break;
+
+      case GL_MAX_TEXTURE_UNITS_ARB:
+         *params = ctx->Const.MaxTextureUnits;
+         break;
+      case GL_ACTIVE_TEXTURE_ARB:
+         *params = GL_TEXTURE0_ARB + ctx->Texture.CurrentUnit;
+         break;
+      case GL_CLIENT_ACTIVE_TEXTURE_ARB:
+         *params = GL_TEXTURE0_ARB + ctx->Array.ActiveTexture;
+         break;
+
+
+      /* GL_PGI_misc_hints */
+      case GL_STRICT_DEPTHFUNC_HINT_PGI:
+        *params = (GL_NICEST);
+         break;
+      case GL_STRICT_LIGHTING_HINT_PGI:
+        *params = (ctx->Hint.StrictLighting);
+        break;
+      case GL_STRICT_SCISSOR_HINT_PGI:
+      case GL_FULL_STIPPLE_HINT_PGI:
+        *params = (GL_TRUE);
+        break;
+      case GL_CONSERVE_MEMORY_HINT_PGI:
+        *params = (GL_FALSE);
+        break;
+      case GL_ALWAYS_FAST_HINT_PGI:
+        *params = (ctx->Hint.AllowDrawWin == GL_TRUE &&
+                   ctx->Hint.AllowDrawSpn == GL_FALSE && 
+                   ctx->Hint.AllowDrawMem == GL_FALSE);
+        break;
+      case GL_ALWAYS_SOFT_HINT_PGI:
+        *params =  (ctx->Hint.AllowDrawWin == GL_TRUE &&
+                    ctx->Hint.AllowDrawSpn == GL_TRUE && 
+                    ctx->Hint.AllowDrawMem == GL_TRUE);
+        break;
+      case GL_ALLOW_DRAW_OBJ_HINT_PGI:
+        *params = GL_TRUE;
+        break;
+      case GL_ALLOW_DRAW_WIN_HINT_PGI:
+        *params = ctx->Hint.AllowDrawWin;
+        break;
+      case GL_ALLOW_DRAW_SPN_HINT_PGI:
+        *params = ctx->Hint.AllowDrawSpn;
+        break;
+      case GL_ALLOW_DRAW_MEM_HINT_PGI:
+        *params = ctx->Hint.AllowDrawMem;
+        break;
+      case GL_CLIP_NEAR_HINT_PGI:
+      case GL_CLIP_FAR_HINT_PGI:
+        *params = GL_TRUE;
+        break;
+      case GL_WIDE_LINE_HINT_PGI:
+        *params = GL_DONT_CARE;
+        break;
+      case GL_BACK_NORMALS_HINT_PGI:
+        *params = (GL_TRUE);
+        break;
+      case GL_NATIVE_GRAPHICS_HANDLE_PGI:
+        *params = 0;
+        break;
+
+      /* GL_EXT_compiled_vertex_array
+       */
+      case GL_ARRAY_ELEMENT_LOCK_FIRST_SGI:
+        *params = ctx->Array.LockFirst;
+        break;
+
+      case GL_ARRAY_ELEMENT_LOCK_COUNT_SGI:
+        *params = ctx->Array.LockCount;
+        break;
+        
+      default:
+        printf("invalid enum: %x\n", pname);
+         gl_error( ctx, GL_INVALID_ENUM, "glGetIntegerv" );
+   }
+}
+
+
+
+void gl_GetPointerv( GLcontext *ctx, GLenum pname, GLvoid **params )
+{
+   GLuint texUnit = ctx->Texture.CurrentUnit;
+   /*GLuint texTransformUnit = ctx->Texture.CurrentTransformUnit;*/
+
+   if (MESA_VERBOSE & VERBOSE_API) 
+      fprintf(stderr, "glGetPointerv %s\n", gl_lookup_enum_by_nr(pname));
+
+   switch (pname) {
+      case GL_VERTEX_ARRAY_POINTER:
+         *params = ctx->Array.Vertex.Ptr;
+         break;
+      case GL_NORMAL_ARRAY_POINTER:
+         *params = ctx->Array.Normal.Ptr;
+         break;
+      case GL_COLOR_ARRAY_POINTER:
+         *params = ctx->Array.Color.Ptr;
+         break;
+      case GL_INDEX_ARRAY_POINTER:
+         *params = ctx->Array.Index.Ptr;
+         break;
+      case GL_TEXTURE_COORD_ARRAY_POINTER:
+         *params = ctx->Array.TexCoord[texUnit].Ptr;
+         break;
+      case GL_EDGE_FLAG_ARRAY_POINTER:
+         *params = ctx->Array.EdgeFlag.Ptr;
+         break;
+      case GL_FEEDBACK_BUFFER_POINTER:
+         *params = ctx->Feedback.Buffer;
+         break;
+      case GL_SELECTION_BUFFER_POINTER:
+         *params = ctx->Select.Buffer;
+         break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glGetPointerv" );
+         return;
+   }
+}
diff --git a/src/mesa/main/get.h b/src/mesa/main/get.h
new file mode 100644 (file)
index 0000000..c4e5504
--- /dev/null
@@ -0,0 +1,48 @@
+/* $Id: get.h,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+#ifndef GET_H
+#define GET_H
+
+
+#include "types.h"
+
+
+extern void gl_GetBooleanv( GLcontext *ctx, GLenum pname, GLboolean *params );
+
+extern void gl_GetDoublev( GLcontext *ctx, GLenum pname, GLdouble *params );
+
+extern void gl_GetFloatv( GLcontext *ctx, GLenum pname, GLfloat *params );
+
+extern void gl_GetIntegerv( GLcontext *ctx, GLenum pname, GLint *params );
+
+
+#endif
+
diff --git a/src/mesa/main/hash.c b/src/mesa/main/hash.c
new file mode 100644 (file)
index 0000000..3d533c8
--- /dev/null
@@ -0,0 +1,295 @@
+/* $Id: hash.c,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "hash.h"
+#ifdef XFree86Server
+#include "GL/xf86glx.h"
+#endif
+#endif
+
+
+/*
+ * Generic hash table.  Only dependency is the GLuint datatype.
+ *
+ * This is used to implement display list and texture object lookup.
+ * NOTE: key=0 is illegal.
+ */
+
+
+#define TABLE_SIZE 1024
+
+struct HashEntry {
+   GLuint Key;
+   void *Data;
+   struct HashEntry *Next;
+};
+
+struct HashTable {
+   struct HashEntry *Table[TABLE_SIZE];
+   GLuint MaxKey;
+};
+
+
+
+/*
+ * Return pointer to a new, empty hash table.
+ */
+struct HashTable *NewHashTable(void)
+{
+   return (struct HashTable *) calloc(sizeof (struct HashTable), 1);
+}
+
+
+
+/*
+ * Delete a hash table.
+ */
+void DeleteHashTable(struct HashTable *table)
+{
+   GLuint i;
+   assert(table);
+   for (i=0;i<TABLE_SIZE;i++) {
+      struct HashEntry *entry = table->Table[i];
+      while (entry) {
+        struct HashEntry *next = entry->Next;
+        free(entry);
+        entry = next;
+      }
+   }
+   free(table);
+}
+
+
+
+/*
+ * Lookup an entry in the hash table.
+ * Input:  table - the hash table
+ *         key - the key
+ * Return:  user data pointer or NULL if key not in table
+ */
+void *HashLookup(const struct HashTable *table, GLuint key)
+{
+   GLuint pos;
+   const struct HashEntry *entry;
+
+   assert(table);
+   assert(key);
+
+   pos = key & (TABLE_SIZE-1);
+   entry = table->Table[pos];
+   while (entry) {
+      if (entry->Key == key) {
+        return entry->Data;
+      }
+      entry = entry->Next;
+   }
+   return NULL;
+}
+
+
+
+/*
+ * Insert into the hash table.  If an entry with this key already exists
+ * we'll replace the existing entry.
+ * Input:  table - the hash table
+ *         key - the key (not zero)
+ *         data - pointer to user data
+ */
+void HashInsert(struct HashTable *table, GLuint key, void *data)
+{
+   /* search for existing entry with this key */
+   GLuint pos;
+   struct HashEntry *entry;
+
+   assert(table);
+   assert(key);
+
+   if (key > table->MaxKey)
+      table->MaxKey = key;
+
+   pos = key & (TABLE_SIZE-1);
+   entry = table->Table[pos];
+   while (entry) {
+      if (entry->Key == key) {
+         /* replace entry's data */
+        entry->Data = data;
+        return;
+      }
+      entry = entry->Next;
+   }
+
+   /* alloc and insert new table entry */
+   entry = (struct HashEntry *) calloc(sizeof(struct HashEntry), 1);
+   entry->Key = key;
+   entry->Data = data;
+   entry->Next = table->Table[pos];
+   table->Table[pos] = entry;
+}
+
+
+
+/*
+ * Remove an entry from the hash table.
+ * Input:  table - the hash table
+ *         key - key of entry to remove
+ */
+void HashRemove(struct HashTable *table, GLuint key)
+{
+   GLuint pos;
+   struct HashEntry *entry, *prev;
+
+   assert(table);
+   assert(key);
+
+   pos = key & (TABLE_SIZE-1);
+   prev = NULL;
+   entry = table->Table[pos];
+   while (entry) {
+      if (entry->Key == key) {
+         /* found it! */
+         if (prev) {
+            prev->Next = entry->Next;
+         }
+         else {
+            table->Table[pos] = entry->Next;
+         }
+         free(entry);
+        return;
+      }
+      prev = entry;
+      entry = entry->Next;
+   }
+}
+
+
+
+/*
+ * Return the key of the "first" entry in the hash table.
+ * By calling this function until zero is returned we can get
+ * the keys of all entries in the table.
+ */
+GLuint HashFirstEntry(const struct HashTable *table)
+{
+   GLuint pos;
+   assert(table);
+   for (pos=0; pos < TABLE_SIZE; pos++) {
+      if (table->Table[pos])
+         return table->Table[pos]->Key;
+   }
+   return 0;
+}
+
+
+
+/*
+ * Dump contents of hash table for debugging.
+ */
+void HashPrint(const struct HashTable *table)
+{
+   GLuint i;
+   assert(table);
+   for (i=0;i<TABLE_SIZE;i++) {
+      const struct HashEntry *entry = table->Table[i];
+      while (entry) {
+        printf("%u %p\n", entry->Key, entry->Data);
+        entry = entry->Next;
+      }
+   }
+}
+
+
+
+/*
+ * Find a block of 'numKeys' adjacent unused hash keys.
+ * Input:  table - the hash table
+ *         numKeys - number of keys needed
+ * Return:  startint key of free block or 0 if failure
+ */
+GLuint HashFindFreeKeyBlock(const struct HashTable *table, GLuint numKeys)
+{
+   GLuint maxKey = ~((GLuint) 0);
+   if (maxKey - numKeys > table->MaxKey) {
+      /* the quick solution */
+      return table->MaxKey + 1;
+   }
+   else {
+      /* the slow solution */
+      GLuint freeCount = 0;
+      GLuint freeStart = 0;
+      GLuint key;
+      for (key=0; key!=maxKey; key++) {
+        if (HashLookup(table, key)) {
+           /* darn, this key is already in use */
+           freeCount = 0;
+           freeStart = key+1;
+        }
+        else {
+           /* this key not in use, check if we've found enough */
+           freeCount++;
+           if (freeCount == numKeys) {
+              return freeStart;
+           }
+        }
+      }
+      /* cannot allocate a block of numKeys consecutive keys */
+      return 0;
+   }
+}
+
+
+
+#ifdef HASH_TEST_HARNESS
+int main(int argc, char *argv[])
+{
+   int a, b, c;
+   struct HashTable *t;
+
+   printf("&a = %p\n", &a);
+   printf("&b = %p\n", &b);
+
+   t = NewHashTable();
+   HashInsert(t, 501, &a);
+   HashInsert(t, 10, &c);
+   HashInsert(t, 0xfffffff8, &b);
+   HashPrint(t);
+   printf("Find 501: %p\n", HashLookup(t,501));
+   printf("Find 1313: %p\n", HashLookup(t,1313));
+   printf("Find block of 100: %d\n", HashFindFreeKeyBlock(t, 100));
+   DeleteHashTable(t);
+
+   return 0;
+}
+#endif
diff --git a/src/mesa/main/hash.h b/src/mesa/main/hash.h
new file mode 100644 (file)
index 0000000..a38159c
--- /dev/null
@@ -0,0 +1,59 @@
+/* $Id: hash.h,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+#ifndef HASH_H
+#define HASH_H
+
+
+#include "GL/gl.h"
+
+
+struct HashTable;
+
+
+
+extern struct HashTable *NewHashTable(void);
+
+extern void DeleteHashTable(struct HashTable *table);
+
+extern void *HashLookup(const struct HashTable *table, GLuint key);
+
+extern void HashInsert(struct HashTable *table, GLuint key, void *data);
+
+extern void HashRemove(struct HashTable *table, GLuint key);
+
+extern GLuint HashFirstEntry(const struct HashTable *table);
+
+extern void HashPrint(const struct HashTable *table);
+
+extern GLuint HashFindFreeKeyBlock(const struct HashTable *table, GLuint numKeys);
+
+
+#endif
diff --git a/src/mesa/main/image.c b/src/mesa/main/image.c
new file mode 100644 (file)
index 0000000..46c33a6
--- /dev/null
@@ -0,0 +1,2417 @@
+/* $Id: image.c,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include "context.h"
+#include "image.h"
+#include "macros.h"
+#include "mmath.h"
+#include "pixel.h"
+#include "types.h"
+#ifdef XFree86Server
+#include "GL/xf86glx.h"
+#endif
+#endif
+
+
+
+/*
+ * Flip the 8 bits in each byte of the given array.
+ */
+void gl_flip_bytes( GLubyte *p, GLuint n )
+{
+   register GLuint i, a, b;
+
+   for (i=0;i<n;i++) {
+      b = (GLuint) p[i];
+      a = ((b & 0x01) << 7) |
+         ((b & 0x02) << 5) |
+         ((b & 0x04) << 3) |
+         ((b & 0x08) << 1) |
+         ((b & 0x10) >> 1) |
+         ((b & 0x20) >> 3) |
+         ((b & 0x40) >> 5) |
+         ((b & 0x80) >> 7);
+      p[i] = (GLubyte) a;
+   }
+}
+
+
+/*
+ * Flip the order of the 2 bytes in each word in the given array.
+ */
+void gl_swap2( GLushort *p, GLuint n )
+{
+   register GLuint i;
+
+   for (i=0;i<n;i++) {
+      p[i] = (p[i] >> 8) | ((p[i] << 8) & 0xff00);
+   }
+}
+
+
+
+/*
+ * Flip the order of the 4 bytes in each word in the given array.
+ */
+void gl_swap4( GLuint *p, GLuint n )
+{
+   register GLuint i, a, b;
+
+   for (i=0;i<n;i++) {
+      b = p[i];
+      a =  (b >> 24)
+       | ((b >> 8) & 0xff00)
+       | ((b << 8) & 0xff0000)
+       | ((b << 24) & 0xff000000);
+      p[i] = a;
+   }
+}
+
+
+
+
+/*
+ * Return the size, in bytes, of the given GL datatype.
+ * Return 0 if GL_BITMAP.
+ * Return -1 if invalid type enum.
+ */
+GLint gl_sizeof_type( GLenum type )
+{
+   switch (type) {
+      case GL_BITMAP:
+        return 0;
+      case GL_UNSIGNED_BYTE:
+         return sizeof(GLubyte);
+      case GL_BYTE:
+        return sizeof(GLbyte);
+      case GL_UNSIGNED_SHORT:
+        return sizeof(GLushort);
+      case GL_SHORT:
+        return sizeof(GLshort);
+      case GL_UNSIGNED_INT:
+        return sizeof(GLuint);
+      case GL_INT:
+        return sizeof(GLint);
+      case GL_FLOAT:
+        return sizeof(GLfloat);
+      default:
+         return -1;
+   }
+}
+
+
+/*
+ * Same as gl_sizeof_packed_type() but we also accept the
+ * packed pixel format datatypes.
+ */
+GLint gl_sizeof_packed_type( GLenum type )
+{
+   switch (type) {
+      case GL_BITMAP:
+        return 0;
+      case GL_UNSIGNED_BYTE:
+         return sizeof(GLubyte);
+      case GL_BYTE:
+        return sizeof(GLbyte);
+      case GL_UNSIGNED_SHORT:
+        return sizeof(GLushort);
+      case GL_SHORT:
+        return sizeof(GLshort);
+      case GL_UNSIGNED_INT:
+        return sizeof(GLuint);
+      case GL_INT:
+        return sizeof(GLint);
+      case GL_FLOAT:
+        return sizeof(GLfloat);
+      case GL_UNSIGNED_BYTE_3_3_2:
+         return sizeof(GLubyte);
+      case GL_UNSIGNED_BYTE_2_3_3_REV:
+         return sizeof(GLubyte);
+      case GL_UNSIGNED_SHORT_5_6_5:
+         return sizeof(GLshort);
+      case GL_UNSIGNED_SHORT_5_6_5_REV:
+         return sizeof(GLshort);
+      case GL_UNSIGNED_SHORT_4_4_4_4:
+         return sizeof(GLshort);
+      case GL_UNSIGNED_SHORT_4_4_4_4_REV:
+         return sizeof(GLshort);
+      case GL_UNSIGNED_SHORT_5_5_5_1:
+         return sizeof(GLshort);
+      case GL_UNSIGNED_SHORT_1_5_5_5_REV:
+         return sizeof(GLshort);
+      case GL_UNSIGNED_INT_8_8_8_8:
+         return sizeof(GLuint);
+      case GL_UNSIGNED_INT_8_8_8_8_REV:
+         return sizeof(GLuint);
+      case GL_UNSIGNED_INT_10_10_10_2:
+         return sizeof(GLuint);
+      case GL_UNSIGNED_INT_2_10_10_10_REV:
+         return sizeof(GLuint);
+      default:
+         return -1;
+   }
+}
+
+
+
+/*
+ * Return the number of components in a GL enum pixel type.
+ * Return -1 if bad format.
+ */
+GLint gl_components_in_format( GLenum format )
+{
+   switch (format) {
+      case GL_COLOR_INDEX:
+      case GL_COLOR_INDEX1_EXT:
+      case GL_COLOR_INDEX2_EXT:
+      case GL_COLOR_INDEX4_EXT:
+      case GL_COLOR_INDEX8_EXT:
+      case GL_COLOR_INDEX12_EXT:
+      case GL_COLOR_INDEX16_EXT:
+      case GL_STENCIL_INDEX:
+      case GL_DEPTH_COMPONENT:
+      case GL_RED:
+      case GL_GREEN:
+      case GL_BLUE:
+      case GL_ALPHA:
+      case GL_LUMINANCE:
+         return 1;
+      case GL_LUMINANCE_ALPHA:
+        return 2;
+      case GL_RGB:
+        return 3;
+      case GL_RGBA:
+        return 4;
+      case GL_BGR:
+        return 3;
+      case GL_BGRA:
+        return 4;
+      case GL_ABGR_EXT:
+         return 4;
+      default:
+         return -1;
+   }
+}
+
+
+/*
+ * Return bytes per pixel for given format and type
+ * Return -1 if bad format or type.
+ */
+GLint gl_bytes_per_pixel( GLenum format, GLenum type )
+{
+   GLint comps = gl_components_in_format( format );
+   if (comps < 0)
+      return -1;
+
+   switch (type) {
+      case GL_BITMAP:
+         return 0;  /* special case */
+      case GL_BYTE:
+      case GL_UNSIGNED_BYTE:
+         return comps * sizeof(GLubyte);
+      case GL_SHORT:
+      case GL_UNSIGNED_SHORT:
+         return comps * sizeof(GLshort);
+      case GL_INT:
+      case GL_UNSIGNED_INT:
+         return comps * sizeof(GLint);
+      case GL_FLOAT:
+         return comps * sizeof(GLfloat);
+      case GL_UNSIGNED_BYTE_3_3_2:
+      case GL_UNSIGNED_BYTE_2_3_3_REV:
+         if (format == GL_RGB || format == GL_BGR)
+            return sizeof(GLubyte);
+         else
+            return -1;  /* error */
+      case GL_UNSIGNED_SHORT_5_6_5:
+      case GL_UNSIGNED_SHORT_5_6_5_REV:
+         if (format == GL_RGB || format == GL_BGR)
+            return sizeof(GLshort);
+         else
+            return -1;  /* error */
+      case GL_UNSIGNED_SHORT_4_4_4_4:
+      case GL_UNSIGNED_SHORT_4_4_4_4_REV:
+      case GL_UNSIGNED_SHORT_5_5_5_1:
+      case GL_UNSIGNED_SHORT_1_5_5_5_REV:
+         if (format == GL_RGBA || format == GL_BGRA || format == GL_ABGR_EXT)
+            return sizeof(GLushort);
+         else
+            return -1;
+      case GL_UNSIGNED_INT_8_8_8_8:
+      case GL_UNSIGNED_INT_8_8_8_8_REV:
+      case GL_UNSIGNED_INT_10_10_10_2:
+      case GL_UNSIGNED_INT_2_10_10_10_REV:
+         if (format == GL_RGBA || format == GL_BGRA || format == GL_ABGR_EXT)
+            return sizeof(GLuint);
+         else
+            return -1;
+      default:
+         return -1;
+   }
+}
+
+
+/*
+ * Test if the given pixel format and type are legal.
+ * Return GL_TRUE for legal, GL_FALSE for illegal.
+ */
+GLboolean gl_is_legal_format_and_type( GLenum format, GLenum type )
+{
+   switch (format) {
+      case GL_COLOR_INDEX:
+      case GL_STENCIL_INDEX:
+         switch (type) {
+            case GL_BITMAP:
+            case GL_BYTE:
+            case GL_UNSIGNED_BYTE:
+            case GL_SHORT:
+            case GL_UNSIGNED_SHORT:
+            case GL_INT:
+            case GL_UNSIGNED_INT:
+            case GL_FLOAT:
+               return GL_TRUE;
+            default:
+               return GL_FALSE;
+         }
+      case GL_RED:
+      case GL_GREEN:
+      case GL_BLUE:
+      case GL_ALPHA:
+      case GL_LUMINANCE:
+      case GL_LUMINANCE_ALPHA:
+      case GL_DEPTH_COMPONENT:
+      case GL_BGR:
+         switch (type) {
+            case GL_BYTE:
+            case GL_UNSIGNED_BYTE:
+            case GL_SHORT:
+            case GL_UNSIGNED_SHORT:
+            case GL_INT:
+            case GL_UNSIGNED_INT:
+            case GL_FLOAT:
+               return GL_TRUE;
+            default:
+               return GL_FALSE;
+         }
+      case GL_RGB:
+         switch (type) {
+            case GL_BYTE:
+            case GL_UNSIGNED_BYTE:
+            case GL_SHORT:
+            case GL_UNSIGNED_SHORT:
+            case GL_INT:
+            case GL_UNSIGNED_INT:
+            case GL_FLOAT:
+            case GL_UNSIGNED_BYTE_3_3_2:
+            case GL_UNSIGNED_BYTE_2_3_3_REV:
+            case GL_UNSIGNED_SHORT_5_6_5:
+            case GL_UNSIGNED_SHORT_5_6_5_REV:
+               return GL_TRUE;
+            default:
+               return GL_FALSE;
+         }
+      case GL_RGBA:
+      case GL_BGRA:
+      case GL_ABGR_EXT:
+         switch (type) {
+            case GL_BYTE:
+            case GL_UNSIGNED_BYTE:
+            case GL_SHORT:
+            case GL_UNSIGNED_SHORT:
+            case GL_INT:
+            case GL_UNSIGNED_INT:
+            case GL_FLOAT:
+            case GL_UNSIGNED_SHORT_4_4_4_4:
+            case GL_UNSIGNED_SHORT_4_4_4_4_REV:
+            case GL_UNSIGNED_SHORT_5_5_5_1:
+            case GL_UNSIGNED_SHORT_1_5_5_5_REV:
+            case GL_UNSIGNED_INT_8_8_8_8:
+            case GL_UNSIGNED_INT_8_8_8_8_REV:
+            case GL_UNSIGNED_INT_10_10_10_2:
+            case GL_UNSIGNED_INT_2_10_10_10_REV:
+               return GL_TRUE;
+            default:
+               return GL_FALSE;
+         }
+      default:
+         ; /* fall-through */
+   }
+   return GL_FALSE;
+}
+
+
+
+/*
+ * Return the address of a pixel in an image (actually a volume).
+ * Pixel unpacking/packing parameters are observed according to 'packing'.
+ * Input:  image - start of image data
+ *         width, height - size of image
+ *         format - image format
+ *         type - pixel component type
+ *         packing - the pixelstore attributes
+ *         img - which image in the volume (0 for 1D or 2D images)
+ *         row, column - location of pixel in the image
+ * Return:  address of pixel at (image,row,column) in image or NULL if error.
+ */
+GLvoid *gl_pixel_addr_in_image( const struct gl_pixelstore_attrib *packing,
+                                const GLvoid *image, GLsizei width,
+                                GLsizei height, GLenum format, GLenum type,
+                                GLint img, GLint row, GLint column )
+{
+   GLint alignment;        /* 1, 2 or 4 */
+   GLint pixels_per_row;
+   GLint rows_per_image;
+   GLint skiprows;
+   GLint skippixels;
+   GLint skipimages;       /* for 3-D volume images */
+   GLubyte *pixel_addr;
+
+   alignment = packing->Alignment;
+   if (packing->RowLength > 0) {
+      pixels_per_row = packing->RowLength;
+   }
+   else {
+      pixels_per_row = width;
+   }
+   if (packing->ImageHeight > 0) {
+      rows_per_image = packing->ImageHeight;
+   }
+   else {
+      rows_per_image = height;
+   }
+   skiprows = packing->SkipRows;
+   skippixels = packing->SkipPixels;
+   skipimages = packing->SkipImages;
+
+   if (type==GL_BITMAP) {
+      /* BITMAP data */
+      GLint comp_per_pixel;   /* components per pixel */
+      GLint bytes_per_comp;   /* bytes per component */
+      GLint bytes_per_row;
+      GLint bytes_per_image;
+
+      /* Compute bytes per component */
+      bytes_per_comp = gl_sizeof_packed_type( type );
+      if (bytes_per_comp<0) {
+         return NULL;
+      }
+
+      /* Compute number of components per pixel */
+      comp_per_pixel = gl_components_in_format( format );
+      if (comp_per_pixel<0 && type != GL_BITMAP) {
+         return NULL;
+      }
+
+      bytes_per_row = alignment
+                    * CEILING( comp_per_pixel*pixels_per_row, 8*alignment );
+
+      bytes_per_image = bytes_per_row * rows_per_image;
+
+      pixel_addr = (GLubyte *) image
+                 + (skipimages + img) * bytes_per_image
+                 + (skiprows + row) * bytes_per_row
+                 + (skippixels + column) / 8;
+   }
+   else {
+      /* Non-BITMAP data */
+      GLint bytes_per_pixel, bytes_per_row, remainder, bytes_per_image;
+
+      bytes_per_pixel = gl_bytes_per_pixel( format, type );
+
+      /* The pixel type and format should have been error checked earlier */
+      assert(bytes_per_pixel > 0);
+
+      bytes_per_row = pixels_per_row * bytes_per_pixel;
+      remainder = bytes_per_row % alignment;
+      if (remainder > 0)
+         bytes_per_row += (alignment - remainder);
+
+      ASSERT(bytes_per_row % alignment == 0);
+
+      bytes_per_image = bytes_per_row * rows_per_image;
+
+      /* compute final pixel address */
+      pixel_addr = (GLubyte *) image
+                 + (skipimages + img) * bytes_per_image
+                 + (skiprows + row) * bytes_per_row
+                 + (skippixels + column) * bytes_per_pixel;
+   }
+
+   return (GLvoid *) pixel_addr;
+}
+
+
+
+/*
+ * Allocate a new gl_image.  All fields are initialized to zero.
+ */
+static struct gl_image *alloc_image( void )
+{
+   return (struct gl_image *) calloc(sizeof(struct gl_image), 1);
+}
+
+
+
+/*
+ * Allocate a new gl_image with the error flag set.
+ */
+static struct gl_image *alloc_error_image( GLint width, GLint height,
+                                           GLint depth, GLenum format,
+                                           GLenum type )
+{
+   struct gl_image *image = alloc_image();
+   if (image) {
+      image->Width = width;
+      image->Height = height;
+      image->Depth = depth;
+      image->Format = format;
+      image->Type = type;
+      image->ErrorFlag = GL_TRUE;
+   }
+   return image;
+}
+
+
+
+/*
+ * Free a gl_image.
+ */
+void gl_free_image( struct gl_image *image )
+{
+   if (image->Data) {
+      free(image->Data);
+   }
+   free(image);
+}
+
+
+
+/*
+ * Do error checking on an image.  If there's an error, register it and
+ * return GL_TRUE, else return GL_FALSE.
+ */
+GLboolean gl_image_error_test( GLcontext *ctx, const struct gl_image *image,
+                               const char *msg )
+{
+   if (!image) {
+      gl_error( ctx, GL_OUT_OF_MEMORY, msg );        
+      return GL_TRUE;
+   }
+   if (image->Width <= 0 || image->Height <= 0 || image->Depth <= 0) {
+      gl_error( ctx, GL_INVALID_VALUE, msg );
+      return GL_TRUE;
+   }
+   else {
+      return GL_FALSE;
+   }
+}
+
+
+
+/*
+ * Unpack a depth-buffer image storing values as GLshort, GLuint, or GLfloats.
+ * Input:  type - datatype of src depth image
+ * Return pointer to a new gl_image structure.
+ *
+ * Notes:  if the source image type is GLushort then the gl_image will
+ * also store GLushorts.  If the src image type is GLuint then the gl_image
+ * will also store GLuints.  For all other src image types the gl_image
+ * will store GLfloats.  The integer cases can later be optimized.
+ */
+static struct gl_image *
+unpack_depth_image( GLcontext *ctx, GLenum type, GLint width, GLint height,
+                    const GLvoid *pixels,
+                    const struct gl_pixelstore_attrib *packing)
+
+{
+   struct gl_image *image;
+   GLfloat *fDst;
+   GLushort *sDst;
+   GLuint *iDst;
+   GLint i, j;
+
+   image = alloc_image();
+   if (image) {
+      image->Width = width;
+      image->Height = height;
+      image->Depth = 1;
+      image->Components = 1;
+      image->Format = GL_DEPTH_COMPONENT;
+      if (type==GL_UNSIGNED_SHORT) {
+         image->Type = GL_UNSIGNED_SHORT;
+         image->Data = malloc( width * height * sizeof(GLushort));
+      }
+      else if (type==GL_UNSIGNED_INT) {
+         image->Type = GL_UNSIGNED_INT;
+         image->Data = malloc( width * height * sizeof(GLuint));
+      }
+      else {
+         image->Type = GL_FLOAT;
+         image->Data = malloc( width * height * sizeof(GLfloat));
+      }
+      image->RefCount = 0;
+      if (!image->Data)
+         return image;
+   }
+   else {
+      return NULL;
+   }
+
+   fDst = (GLfloat *) image->Data;
+   sDst = (GLushort *) image->Data;
+   iDst = (GLuint *) image->Data;
+
+   for (i=0;i<height;i++) {
+      GLvoid *src = gl_pixel_addr_in_image( packing, pixels,
+                                            width, height,
+                                            GL_DEPTH_COMPONENT, type,
+                                            0, i, 0 );
+      if (!src) {
+         return image;
+      }
+
+      switch (type) {
+         case GL_BYTE:
+            assert(image->Type == GL_FLOAT);
+            for (j=0; j<width; j++) {
+               *fDst++ = BYTE_TO_FLOAT(((GLbyte*)src)[j]);
+            }
+            break;
+         case GL_UNSIGNED_BYTE:
+            assert(image->Type == GL_FLOAT);
+            for (j=0; j<width; j++) {
+               *fDst++ = UBYTE_TO_FLOAT(((GLubyte*)src)[j]);
+            }
+            break;
+         case GL_UNSIGNED_SHORT:
+            assert(image->Type == GL_UNSIGNED_SHORT);
+            MEMCPY( sDst, src, width * sizeof(GLushort) );
+            if (packing->SwapBytes) {
+               gl_swap2( sDst, width );
+            }
+            sDst += width;
+            break;
+         case GL_SHORT:
+            assert(image->Type == GL_FLOAT);
+            if (packing->SwapBytes) {
+               for (j=0;j<width;j++) {
+                  GLshort value = ((GLshort*)src)[j];
+                  value = ((value >> 8) & 0xff) | ((value&0xff) << 8);
+                  *fDst++ = SHORT_TO_FLOAT(value);
+               }
+            }
+            else {
+               for (j=0;j<width;j++) {
+                  *fDst++ = SHORT_TO_FLOAT(((GLshort*)src)[j]);
+               }
+            }
+            break;
+         case GL_INT:
+            assert(image->Type == GL_FLOAT);
+            if (packing->SwapBytes) {
+               for (j=0;j<width;j++) {
+                  GLint value = ((GLint*)src)[j];
+                  value = ((value >> 24) & 0x000000ff) |
+                          ((value >> 8)  & 0x0000ff00) |
+                          ((value << 8)  & 0x00ff0000) |
+                          ((value << 24) & 0xff000000);
+                  *fDst++ = INT_TO_FLOAT(value);
+               }
+            }
+            else {
+               for (j=0;j<width;j++) {
+                  *fDst++ = INT_TO_FLOAT(((GLint*)src)[j]);
+               }
+            }
+            iDst += width;
+            break;
+         case GL_UNSIGNED_INT:
+            assert(image->Type == GL_UNSIGNED_INT);
+            MEMCPY( iDst, src, width * sizeof(GLuint) );
+            if (packing->SwapBytes) {
+               gl_swap4( iDst, width );
+            }
+            iDst += width;
+            break;
+         case GL_FLOAT:
+            assert(image->Type == GL_FLOAT);
+            MEMCPY( fDst, src, width * sizeof(GLfloat) );
+            if (packing->SwapBytes) {
+               gl_swap4( (GLuint*) fDst, width );
+            }
+            fDst += width;
+            break;
+         default:
+            gl_problem(ctx, "unpack_depth_image type" );
+            return image;
+      }
+   }
+
+   return image;
+}
+
+
+
+/*
+ * Unpack a stencil image.  Store as GLubytes in a gl_image structure.
+ * Return:  pointer to new gl_image structure.
+ */
+static struct gl_image *
+unpack_stencil_image( GLcontext *ctx, GLenum type, GLint width, GLint height,
+                      const GLvoid *pixels,
+                      const struct gl_pixelstore_attrib *packing )
+{
+   struct gl_image *image;
+   GLubyte *dst;
+   GLint i, j;
+
+   assert(sizeof(GLstencil) == sizeof(GLubyte));
+
+   image = alloc_image();
+   if (image) {
+      image->Width = width;
+      image->Height = height;
+      image->Depth = 1;
+      image->Components = 1;
+      image->Format = GL_STENCIL_INDEX;
+      image->Type = GL_UNSIGNED_BYTE;
+      image->Data = malloc( width * height * sizeof(GLubyte));
+      image->RefCount = 0;
+      if (!image->Data)
+         return image;
+   }
+   else {
+      return NULL;
+   }
+
+   dst = (GLubyte *) image->Data;
+
+   for (i=0;i<height;i++) {
+      GLvoid *src = gl_pixel_addr_in_image( packing, pixels,
+                                            width, height,
+                                            GL_STENCIL_INDEX, type,
+                                            0, i, 0 );
+      if (!src) {
+         return image;
+      }
+
+      switch (type) {
+         case GL_UNSIGNED_BYTE:
+         case GL_BYTE:
+            MEMCPY( dst, src, width * sizeof(GLubyte) );
+            dst += width * sizeof(GLubyte);
+            break;
+         case GL_UNSIGNED_SHORT:
+         case GL_SHORT:
+            if (packing->SwapBytes) {
+               /* grab upper byte */
+               for (j=0; j < width; j++) {
+                  *dst++ = (((GLushort*)src)[j] & 0xff00) >> 8;
+               }
+            }
+            else {
+               for (j=0; j < width; j++) {
+                  *dst++ = (((GLushort*)src)[j]) & 0xff;
+               }
+            }
+            break;
+         case GL_INT:
+            if (packing->SwapBytes) {
+               /* grab upper byte */
+               for (j=0; j < width; j++) {
+                  *dst++ = (((GLuint*)src)[j] & 0xff000000) >> 8;
+               }
+            }
+            else {
+               for (j=0; j < width; j++) {
+                  *dst++ = (((GLuint*)src)[j]) & 0xff;
+               }
+            }
+            break;
+         case GL_UNSIGNED_INT:
+            if (packing->SwapBytes) {
+               /* grab upper byte */
+               for (j=0; j < width; j++) {
+                  *dst++ = (((GLuint*)src)[j] & 0xff000000) >> 8;
+               }
+            }
+            else {
+               for (j=0; j < width; j++) {
+                  *dst++ = (((GLuint*)src)[j]) & 0xff;
+               }
+            }
+            break;
+         case GL_FLOAT:
+            if (packing->SwapBytes) {
+               for (j=0; j < width; j++) {
+                  GLfloat fvalue;
+                  GLint value = ((GLuint*)src)[j];
+                  value = ((value & 0xff000000) >> 24)
+                     | ((value & 0x00ff0000) >> 8)
+                     | ((value & 0x0000ff00) << 8)
+                     | ((value & 0x000000ff) << 24);
+                  fvalue = *((GLfloat*) &value);
+                  *dst++ = ((GLint) fvalue) & 0xff;
+               }
+            }
+            else {
+               for (j=0; j < width; j++) {
+                  GLfloat fvalue = ((GLfloat *)src)[j];
+                  *dst++ = ((GLint) fvalue) & 0xff;
+               }
+            }
+            break;
+         default:
+            gl_problem(ctx, "unpack_stencil_image type" );
+            return image;
+      }
+   }
+
+   return image;
+}
+
+
+
+/*
+ * Unpack a bitmap, return a new gl_image struct.
+ */
+static struct gl_image *
+unpack_bitmap( GLcontext *ctx, GLenum format, GLint width, GLint height,
+               const GLvoid *pixels,
+               const struct gl_pixelstore_attrib *packing )
+{
+   struct gl_image *image;
+   GLint bytes, i, width_in_bytes;
+   GLubyte *buffer, *dst;
+
+   assert(format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX);
+
+   /* Alloc dest storage */
+   bytes = ((width+7)/8 * height);
+   if (bytes>0 && pixels!=NULL) {
+      buffer = (GLubyte *) malloc( bytes );
+      if (!buffer) {
+         return NULL;
+      }
+      /* Copy/unpack pixel data to buffer */
+      width_in_bytes = CEILING( width, 8 );
+      dst = buffer;
+      for (i=0; i<height; i++) {
+         GLvoid *src = gl_pixel_addr_in_image( packing, pixels,
+                                               width, height,
+                                               GL_COLOR_INDEX, GL_BITMAP,
+                                               0, i, 0 );
+         if (!src) {
+            free(buffer);
+            return NULL;
+         }
+         MEMCPY( dst, src, width_in_bytes );
+         dst += width_in_bytes;
+      }
+      /* Bit flipping */
+      if (packing->LsbFirst) {
+         gl_flip_bytes( buffer, bytes );
+      }
+   }
+   else {
+      /* a 'null' bitmap */
+      buffer = NULL;
+   }
+   
+   image = alloc_image();
+   if (image) {
+      image->Width = width;
+      image->Height = height;
+      image->Depth = 1;
+      image->Components = 0;
+      image->Format = format;
+      image->Type = GL_BITMAP;
+      image->Data = buffer;
+      image->RefCount = 0;
+   }
+   else {
+      free( buffer );
+      return NULL;
+   }
+
+   return image;
+}
+
+
+
+/*
+ * Unpack a 32x32 pixel polygon stipple from user memory using the
+ * current pixel unpack settings.
+ */
+void gl_unpack_polygon_stipple( const GLcontext *ctx,
+                                const GLubyte *pattern, GLuint dest[32] )
+{
+   GLint i;
+   for (i = 0; i < 32; i++) {
+      GLubyte *src = (GLubyte *) gl_pixel_addr_in_image( &ctx->Unpack, pattern,
+                                  32, 32, GL_COLOR_INDEX, GL_BITMAP, 0, i, 0 );
+      dest[i] = (src[0] << 24)
+              | (src[1] << 16)
+              | (src[2] <<  8)
+              | (src[3]      );
+   }
+
+   /* Bit flipping within each byte */
+   if (ctx->Unpack.LsbFirst) {
+      gl_flip_bytes( (GLubyte *) dest, 32 * 4 );
+   }
+}
+
+
+
+/*
+ * Pack polygon stipple into user memory given current pixel packing
+ * settings.
+ */
+void gl_pack_polygon_stipple( const GLcontext *ctx,
+                              const GLuint pattern[32],
+                              GLubyte *dest )
+{
+   GLint i;
+   for (i = 0; i < 32; i++) {
+      GLubyte *dst = (GLubyte *) gl_pixel_addr_in_image( &ctx->Pack, dest,
+                                  32, 32, GL_COLOR_INDEX, GL_BITMAP, 0, i, 0 );
+      dst[0] = (pattern[i] >> 24) & 0xff;
+      dst[1] = (pattern[i] >> 16) & 0xff;
+      dst[2] = (pattern[i] >>  8) & 0xff;
+      dst[3] = (pattern[i]      ) & 0xff;
+
+      /* Bit flipping within each byte */
+      if (ctx->Pack.LsbFirst) {
+         gl_flip_bytes( (GLubyte *) dst, 4 );
+      }
+   }
+}
+
+
+
+/*
+ * Unpack an RGBA or CI image and store it as unsigned bytes
+ */
+static struct gl_image *
+unpack_ubyte_image( GLcontext *ctx, GLint width, GLint height,
+                    GLint depth, GLenum format, const GLvoid *pixels,
+                    const struct gl_pixelstore_attrib *packing )
+{
+   struct gl_image *image;
+   GLint width_in_bytes;
+   GLint components;
+   GLubyte *buffer, *dst;
+   GLint i, d;
+
+   components = gl_components_in_format( format );
+
+   width_in_bytes = width * components * sizeof(GLubyte);
+   buffer = (GLubyte *) malloc( height * width_in_bytes * depth );
+   if (!buffer) {
+      return NULL;
+   }
+
+   /* Copy/unpack pixel data to buffer */
+   dst = buffer;
+   for (d=0; d<depth; d++ ) {
+      for (i=0;i<height;i++) {
+         GLubyte *src = (GLubyte *) gl_pixel_addr_in_image( packing,
+                       pixels, width, height, format, GL_UNSIGNED_BYTE,
+                       d, i, 0 );
+         if (!src) {
+            free(buffer);
+            return NULL;
+         }
+         MEMCPY( dst, src, width_in_bytes );
+         dst += width_in_bytes;
+      }
+   }
+   
+   if (format == GL_BGR) {
+      /* swap order of every ubyte triplet from BGR to RGB */
+      for (i=0; i<width*height; i++) {
+         GLubyte b = buffer[i*3+0];
+         GLubyte r = buffer[i*3+2];
+         buffer[i*3+0] = r;
+         buffer[i*3+2] = b;
+      }
+   }
+   else if (format == GL_BGRA) {
+      /* swap order of every ubyte quadruplet from BGRA to RGBA */
+      for (i=0; i<width*height; i++) {
+         GLubyte b = buffer[i*4+0];
+         GLubyte r = buffer[i*4+2];
+         buffer[i*4+0] = r;
+         buffer[i*4+2] = b;
+      }
+   }
+   else if (format == GL_ABGR_EXT) {
+      /* swap order of every ubyte quadruplet from ABGR to RGBA */
+      for (i=0; i<width*height; i++) {
+         GLubyte a = buffer[i*4+0];
+         GLubyte b = buffer[i*4+1];
+         GLubyte g = buffer[i*4+2];
+         GLubyte r = buffer[i*4+3];
+         buffer[i*4+0] = r;
+         buffer[i*4+1] = g;
+         buffer[i*4+2] = b;
+         buffer[i*4+3] = a;
+      }
+   }
+
+
+   image = alloc_image();
+   if (image) {
+      image->Width = width;
+      image->Height = height;
+      image->Depth = depth;
+      image->Components = components;
+      if (format == GL_BGR)
+         image->Format = GL_RGB;
+      else if (format == GL_BGRA)
+         image->Format = GL_RGBA;
+      else if (format == GL_ABGR_EXT)
+         image->Format = GL_RGBA;
+      else
+         image->Format = format;
+      image->Type = GL_UNSIGNED_BYTE;
+      image->Data = buffer;
+      image->RefCount = 0;
+   }
+   else {
+      free( buffer );
+   }
+
+   return image;
+}
+
+
+
+/*
+ * Unpack a color image storing image as GLfloats
+ */
+static struct gl_image *
+unpack_float_image( GLcontext *ctx, GLint width, GLint height, GLint depth,
+                    GLenum format, GLenum type, const GLvoid *pixels,
+                    const struct gl_pixelstore_attrib *packing )
+{
+   struct gl_image *image;
+   GLfloat *dst;
+   GLint elems_per_row;
+   GLint components;
+   GLint i, j, d;
+   GLboolean normalize;
+
+   assert(type != GL_BITMAP);
+
+   components = gl_components_in_format( format );
+   assert(components > 0);  /* should have been caught earlier */
+
+   if (!gl_is_legal_format_and_type( format, type )) {
+      /* bad pixel type for format, make dummy image */
+      image = alloc_image();
+      if (image) {
+         image->Width = width;
+         image->Height = height;
+         image->Depth = depth;
+         image->Components = components;
+         image->Format = format;
+         image->Type = type;
+         image->Data = NULL;
+         image->RefCount = 0;
+      }
+      return image;
+   }
+
+   elems_per_row = width * components;
+
+   image = alloc_image();
+   if (image) {
+      image->Width = width;
+      image->Height = height;
+      image->Depth = depth;
+      image->Components = components;
+      if (format == GL_BGR)
+         image->Format = GL_RGB;
+      else if (format == GL_BGRA)
+         image->Format = GL_RGBA;
+      else if (format == GL_ABGR_EXT)
+         image->Format = GL_RGBA;
+      else
+         image->Format = format;
+      image->Type = GL_FLOAT;
+      image->Data = malloc( elems_per_row * height * depth * sizeof(GLfloat));
+      image->RefCount = 0;
+      if (!image->Data)
+         return image;
+   }
+   else {
+      return NULL;
+   }
+
+   normalize = (format != GL_COLOR_INDEX) && (format != GL_STENCIL_INDEX);
+
+   dst = (GLfloat *) image->Data;
+
+   for (d=0; d<depth; d++) {
+      for (i=0;i<height;i++) {
+         GLvoid *src = gl_pixel_addr_in_image( packing, pixels,
+                                               width, height,
+                                               format, type,
+                                               d, i, 0 );
+         if (!src) {
+            return image;
+         }
+
+         switch (type) {
+            case GL_UNSIGNED_BYTE:
+               {
+                  GLubyte *ubsrc = (GLubyte *) src;
+                  if (normalize) {
+                     for (j=0;j<elems_per_row;j++) {
+                        *dst++ = UBYTE_TO_FLOAT(ubsrc[j]);
+                     }
+                  }
+                  else {
+                     for (j=0;j<elems_per_row;j++) {
+                        *dst++ = (GLfloat) ubsrc[j];
+                     }
+                  }
+               }
+               break;
+            case GL_BYTE:
+               if (normalize) {
+                  for (j=0;j<elems_per_row;j++) {
+                     *dst++ = BYTE_TO_FLOAT(((GLbyte*)src)[j]);
+                  }
+               }
+               else {
+                  for (j=0;j<elems_per_row;j++) {
+                     *dst++ = (GLfloat) ((GLbyte*)src)[j];
+                  }
+               }
+               break;
+            case GL_UNSIGNED_SHORT:
+               if (packing->SwapBytes) {
+                  for (j=0;j<elems_per_row;j++) {
+                     GLushort value = ((GLushort*)src)[j];
+                     value = ((value >> 8) & 0xff) | ((value&0xff) << 8);
+                     if (normalize) {
+                        *dst++ = USHORT_TO_FLOAT(value);
+                     }
+                     else {
+                        *dst++ = (GLfloat) value;
+                     }
+                  }
+               }
+               else {
+                  if (normalize) {
+                     for (j=0;j<elems_per_row;j++) {
+                        *dst++ = USHORT_TO_FLOAT(((GLushort*)src)[j]);
+                     }
+                  }
+                  else {
+                     for (j=0;j<elems_per_row;j++) {
+                        *dst++ = (GLfloat) ((GLushort*)src)[j];
+                     }
+                  }
+               }
+               break;
+            case GL_SHORT:
+               if (packing->SwapBytes) {
+                  for (j=0;j<elems_per_row;j++) {
+                     GLshort value = ((GLshort*)src)[j];
+                     value = ((value >> 8) & 0xff) | ((value&0xff) << 8);
+                     if (normalize) {
+                        *dst++ = SHORT_TO_FLOAT(value);
+                     }
+                     else {
+                        *dst++ = (GLfloat) value;
+                     }
+                  }
+               }
+               else {
+                  if (normalize) {
+                     for (j=0;j<elems_per_row;j++) {
+                        *dst++ = SHORT_TO_FLOAT(((GLshort*)src)[j]);
+                     }
+                  }
+                  else {
+                     for (j=0;j<elems_per_row;j++) {
+                        *dst++ = (GLfloat) ((GLshort*)src)[j];
+                     }
+                  }
+               }
+               break;
+            case GL_UNSIGNED_INT:
+               if (packing->SwapBytes) {
+                  GLuint value;
+                  for (j=0;j<elems_per_row;j++) {
+                     value = ((GLuint*)src)[j];
+                     value = ((value & 0xff000000) >> 24)
+                           | ((value & 0x00ff0000) >> 8)
+                           | ((value & 0x0000ff00) << 8)
+                           | ((value & 0x000000ff) << 24);
+                     if (normalize) {
+                        *dst++ = UINT_TO_FLOAT(value);
+                     }
+                     else {
+                        *dst++ = (GLfloat) value;
+                     }
+                  }
+               }
+               else {
+                  if (normalize) {
+                     for (j=0;j<elems_per_row;j++) {
+                        *dst++ = UINT_TO_FLOAT(((GLuint*)src)[j]);
+                     }
+                  }
+                  else {
+                     for (j=0;j<elems_per_row;j++) {
+                        *dst++ = (GLfloat) ((GLuint*)src)[j];
+                     }
+                  }
+               }
+               break;
+            case GL_INT:
+               if (packing->SwapBytes) {
+                  GLint value;
+                  for (j=0;j<elems_per_row;j++) {
+                     value = ((GLint*)src)[j];
+                     value = ((value & 0xff000000) >> 24)
+                           | ((value & 0x00ff0000) >> 8)
+                           | ((value & 0x0000ff00) << 8)
+                           | ((value & 0x000000ff) << 24);
+                     if (normalize) {
+                        *dst++ = INT_TO_FLOAT(value);
+                     }
+                     else {
+                        *dst++ = (GLfloat) value;
+                     }
+                  }
+               }
+               else {
+                  if (normalize) {
+                     for (j=0;j<elems_per_row;j++) {
+                        *dst++ = INT_TO_FLOAT(((GLint*)src)[j]);
+                     }
+                  }
+                  else {
+                     for (j=0;j<elems_per_row;j++) {
+                        *dst++ = (GLfloat) ((GLint*)src)[j];
+                     }
+                  }
+               }
+               break;
+            case GL_FLOAT:
+               if (packing->SwapBytes) {
+                  GLint value;
+                  for (j=0;j<elems_per_row;j++) {
+                     value = ((GLuint*)src)[j];
+                     value = ((value & 0xff000000) >> 24)
+                           | ((value & 0x00ff0000) >> 8)
+                           | ((value & 0x0000ff00) << 8)
+                           | ((value & 0x000000ff) << 24);
+                     *dst++ = *((GLfloat*) &value);
+                  }
+               }
+               else {
+                  MEMCPY( dst, src, elems_per_row*sizeof(GLfloat) );
+                  dst += elems_per_row;
+               }
+               break;
+            case GL_UNSIGNED_BYTE_3_3_2:
+               {
+                  GLubyte *ubsrc = (GLubyte *) src;
+                  for (j=0;j<width;j++) {
+                     GLubyte p = ubsrc[j];
+                     *dst++ = ((p >> 5)      ) * (1.0F / 7.0F); /* red */
+                     *dst++ = ((p >> 2) & 0x7) * (1.0F / 7.0F); /* green */
+                     *dst++ = ((p     ) & 0x3) * (1.0F / 3.0F); /* blue */
+                  }
+               }
+               break;
+            case GL_UNSIGNED_BYTE_2_3_3_REV:
+               {
+                  GLubyte *ubsrc = (GLubyte *) src;
+                  for (j=0;j<width;j++) {
+                     GLubyte p = ubsrc[j];
+                     *dst++ = ((p     ) & 0x7) * (1.0F / 7.0F); /* red */
+                     *dst++ = ((p >> 3) & 0x7) * (1.0F / 7.0F); /* green */
+                     *dst++ = ((p >> 6)      ) * (1.0F / 3.0F); /* blue */
+                  }
+               }
+               break;
+            case GL_UNSIGNED_SHORT_5_6_5:
+               {
+                  GLushort *ussrc = (GLushort *) src;
+                  for (j=0;j<width;j++) {
+                     GLushort p = ussrc[j];
+                     *dst++ = ((p >> 11)       ) * (1.0F / 31.0F); /* red */
+                     *dst++ = ((p >>  5) & 0x3f) * (1.0F / 63.0F); /* green */
+                     *dst++ = ((p      ) & 0x1f) * (1.0F / 31.0F); /* blue */
+                  }
+               }
+               break;
+            case GL_UNSIGNED_SHORT_5_6_5_REV:
+               {
+                  GLushort *ussrc = (GLushort *) src;
+                  for (j=0;j<width;j++) {
+                     GLushort p = ussrc[j];
+                     *dst++ = ((p      ) & 0x1f) * (1.0F / 31.0F); /* red */
+                     *dst++ = ((p >>  5) & 0x3f) * (1.0F / 63.0F); /* green */
+                     *dst++ = ((p >> 11)       ) * (1.0F / 31.0F); /* blue */
+                  }
+               }
+               break;
+           case GL_UNSIGNED_SHORT_4_4_4_4:
+               {
+                  GLushort *ussrc = (GLushort *) src;
+                  for (j=0;j<width;j++) {
+                     GLushort p = ussrc[j];
+                     *dst++ = ((p >> 12)      ) * (1.0F / 15.0F); /* red */
+                     *dst++ = ((p >>  8) & 0xf) * (1.0F / 15.0F); /* green */
+                     *dst++ = ((p >>  4) & 0xf) * (1.0F / 15.0F); /* blue */
+                     *dst++ = ((p      ) & 0xf) * (1.0F / 15.0F); /* alpha */
+                  }
+               }
+               break;
+           case GL_UNSIGNED_SHORT_4_4_4_4_REV:
+               {
+                  GLushort *ussrc = (GLushort *) src;
+                  for (j=0;j<width;j++) {
+                     GLushort p = ussrc[j];
+                     *dst++ = ((p      ) & 0xf) * (1.0F / 15.0F); /* red */
+                     *dst++ = ((p >>  4) & 0xf) * (1.0F / 15.0F); /* green */
+                     *dst++ = ((p >>  8) & 0xf) * (1.0F / 15.0F); /* blue */
+                     *dst++ = ((p >> 12)      ) * (1.0F / 15.0F); /* alpha */
+                  }
+               }
+               break;
+           case GL_UNSIGNED_SHORT_5_5_5_1:
+               {
+                  GLushort *ussrc = (GLushort *) src;
+                  for (j=0;j<width;j++) {
+                     GLushort p = ussrc[j];
+                     *dst++ = ((p >> 11)       ) * (1.0F / 31.0F); /* red */
+                     *dst++ = ((p >>  6) & 0x1f) * (1.0F / 31.0F); /* green */
+                     *dst++ = ((p >>  1) & 0x1f) * (1.0F / 31.0F); /* blue */
+                     *dst++ = ((p      ) & 0x1)  * (1.0F /  1.0F); /* alpha */
+                  }
+               }
+               break;
+           case GL_UNSIGNED_SHORT_1_5_5_5_REV:
+               {
+                  GLushort *ussrc = (GLushort *) src;
+                  for (j=0;j<width;j++) {
+                     GLushort p = ussrc[j];
+                     *dst++ = ((p      ) & 0x1f) * (1.0F / 31.0F); /* red */
+                     *dst++ = ((p >>  5) & 0x1f) * (1.0F / 31.0F); /* green */
+                     *dst++ = ((p >> 10) & 0x1f) * (1.0F / 31.0F); /* blue */
+                     *dst++ = ((p >> 15)       ) * (1.0F /  1.0F); /* alpha */
+                  }
+               }
+               break;
+           case GL_UNSIGNED_INT_8_8_8_8:
+               {
+                  GLuint *uisrc = (GLuint *) src;
+                  for (j=0;j<width;j++) {
+                     GLuint p = uisrc[j];
+                     *dst++ = UBYTE_COLOR_TO_FLOAT_COLOR((p >> 24)       );
+                     *dst++ = UBYTE_COLOR_TO_FLOAT_COLOR((p >> 16) & 0xff);
+                     *dst++ = UBYTE_COLOR_TO_FLOAT_COLOR((p >>  8) & 0xff);
+                     *dst++ = UBYTE_COLOR_TO_FLOAT_COLOR((p      ) & 0xff);
+                  }
+               }
+               break;
+           case GL_UNSIGNED_INT_8_8_8_8_REV:
+               {
+                  GLuint *uisrc = (GLuint *) src;
+                  for (j=0;j<width;j++) {
+                     GLuint p = uisrc[j];
+                     *dst++ = UBYTE_COLOR_TO_FLOAT_COLOR((p      ) & 0xff);
+                     *dst++ = UBYTE_COLOR_TO_FLOAT_COLOR((p >>  8) & 0xff);
+                     *dst++ = UBYTE_COLOR_TO_FLOAT_COLOR((p >> 16) & 0xff);
+                     *dst++ = UBYTE_COLOR_TO_FLOAT_COLOR((p >> 24)       ); 
+                  }
+               }
+               break;
+           case GL_UNSIGNED_INT_10_10_10_2:
+               {
+                  GLuint *uisrc = (GLuint *) src;
+                  for (j=0;j<width;j++) {
+                     GLuint p = uisrc[j];
+                     *dst++ = ((p >> 22)        ) * (1.0F / 1023.0F); /* r */
+                     *dst++ = ((p >> 12) & 0x3ff) * (1.0F / 1023.0F); /* g */
+                     *dst++ = ((p >>  2) & 0x3ff) * (1.0F / 1023.0F); /* b */
+                     *dst++ = ((p      ) & 0x3  ) * (1.0F /    3.0F); /* a */
+                  }
+               }
+               break;
+           case GL_UNSIGNED_INT_2_10_10_10_REV:
+               {
+                  GLuint *uisrc = (GLuint *) src;
+                  for (j=0;j<width;j++) {
+                     GLuint p = uisrc[j];
+                     *dst++ = ((p      ) & 0x3ff) * (1.0F / 1023.0F); /* r*/
+                     *dst++ = ((p >> 10) & 0x3ff) * (1.0F / 1023.0F); /* g */
+                     *dst++ = ((p >> 20) & 0x3ff) * (1.0F / 1023.0F); /* b */
+                     *dst++ = ((p >> 30)        ) * (1.0F /    3.0F); /* a */
+                  }
+               }
+               break;
+            default:
+               gl_problem(ctx, "unpack_float_image type" );
+               return image;
+         }
+      }
+   }
+
+   if (format == GL_BGR) {
+      /* swap order of every float triplet from BGR to RGBA */
+      GLfloat *buffer = (GLfloat *) image->Data;
+      for (i=0; i<width*height*depth; i++) {
+         GLfloat b = buffer[i*3+0];
+         GLfloat r = buffer[i*3+2];
+         buffer[i*3+0] = r;
+         buffer[i*3+2] = b;
+      }
+   }
+   else if (format == GL_BGRA) {
+      /* swap order of every float quadruplet from BGRA to RGBA */
+      GLfloat *buffer = (GLfloat *) image->Data;
+      for (i=0; i<width*height*depth; i++) {
+         GLfloat b = buffer[i*4+0];
+         GLfloat r = buffer[i*4+2];
+         buffer[i*4+0] = r;
+         buffer[i*4+2] = b;
+      }
+   }
+   else if (format == GL_ABGR_EXT) {
+      /* swap order of every float quadruplet from ABGR to RGBA */
+      GLfloat *buffer = (GLfloat *) image->Data;
+      for (i=0; i<width*height*depth; i++) {
+         GLfloat a = buffer[i*4+0];
+         GLfloat b = buffer[i*4+1];
+         GLfloat g = buffer[i*4+2];
+         GLfloat r = buffer[i*4+3];
+         buffer[i*4+0] = r;
+         buffer[i*4+1] = g;
+         buffer[i*4+2] = b;
+         buffer[i*4+3] = a;
+      }
+   }
+
+   return image;
+}
+
+
+
+/*
+ * Unpack a bitmap image, using current glPixelStore parameters,
+ * making a new gl_image.
+ */
+struct gl_image *gl_unpack_bitmap( GLcontext *ctx,
+                                   GLsizei width, GLsizei height,
+                                   const GLubyte *bitmap,
+                                   const struct gl_pixelstore_attrib *packing )
+{
+   return gl_unpack_image( ctx, width, height,
+                           GL_COLOR_INDEX, GL_BITMAP, bitmap, packing );
+}
+
+
+
+/*
+ * Unpack a 2-D image from user's buffer.  Return pointer to new
+ * gl_image struct.
+ *
+ * Input:  width, height - size in pixels
+ *         format - format of incoming pixel data
+ *         type - datatype of incoming pixel data
+ *         pixels - pointer to unpacked image in user buffer
+ */
+struct gl_image *gl_unpack_image( GLcontext *ctx,
+                                  GLint width, GLint height,
+                                  GLenum format, GLenum type,
+                                  const GLvoid *pixels,
+                                  const struct gl_pixelstore_attrib *packing )
+{ 
+   return gl_unpack_image3D( ctx, width, height, 1,
+                             format, type, pixels, packing );
+}
+
+
+
+/* 
+ * Unpack a 1, 2 or 3-D image from user-supplied address, returning a
+ * pointer to a new gl_image struct.
+ * This function is always called by a higher-level unpack function such
+ * as gl_unpack_texsubimage() or gl_unpack_bitmap().
+ *
+ * Input:  width, height, depth - size in pixels
+ *         format - format of incoming pixel data
+ *         type - datatype of incoming pixel data
+ *         pixels - pointer to unpacked image.
+ */
+struct gl_image *gl_unpack_image3D( GLcontext *ctx,
+                                    GLint width, GLint height, GLint depth,
+                                    GLenum format, GLenum type,
+                                    const GLvoid *pixels,
+                                    const struct gl_pixelstore_attrib *packing)
+{
+   if (width <= 0 || height <= 0 || depth <= 0) {
+      return alloc_error_image(width, height, depth, format, type);
+   }
+
+   if (type==GL_BITMAP) {
+      if (format != GL_COLOR_INDEX && format != GL_STENCIL_INDEX) {
+         return alloc_error_image(width, height, depth, format, type);
+      }
+      else {
+         return unpack_bitmap( ctx, format, width, height, pixels, packing );
+      }
+   }
+   else if (format==GL_DEPTH_COMPONENT) {
+      /* TODO: pack as GLdepth values (GLushort or GLuint) */
+      return unpack_depth_image( ctx, type, width, height, pixels, packing );
+   }
+   else if (format==GL_STENCIL_INDEX) {
+      /* TODO: pack as GLstencil (GLubyte or GLushort) */
+      return unpack_stencil_image( ctx, type, width, height, pixels, packing );
+   }
+   else if (type==GL_UNSIGNED_BYTE) {
+      /* upack, convert to GLubytes */
+      return unpack_ubyte_image( ctx, width, height, depth, format, pixels, packing );
+   }
+   else {
+      /* upack, convert to floats */
+      return unpack_float_image( ctx, width, height, depth,
+                                 format, type, pixels, packing );
+   }
+
+   /* never get here */
+   /*return NULL;*/
+}
+
+
+/*
+ * Apply pixel-transfer operations (scale, bias, mapping) to a single row
+ * of a gl_image.  Put resulting color components into result array.
+ */
+void gl_scale_bias_map_image_data( const GLcontext *ctx,
+                                   const struct gl_image *image,
+                                   GLint row, GLubyte result[] )
+{
+   GLint start, i;
+
+   assert(ctx);
+   assert(image);
+   assert(result);
+   assert(row >= 0);
+
+   start = row * image->Width * image->Components;
+
+   for (i=0; i < image->Width; i++) {
+      GLint pos = start+i;
+      GLfloat red, green, blue, alpha;
+      if (image->Type == GL_UNSIGNED_BYTE) {
+         const GLubyte *data = (GLubyte *) image->Data;
+         switch (image->Format) {
+            case GL_RED:
+               red   = data[pos] * (1.0F/255.0F);
+               green = 0;
+               blue  = 0;
+               alpha = 0;
+               break;
+            case GL_RGB:
+               red   = data[pos*3+0] * (1.0F/255.0F);
+               green = data[pos*3+1] * (1.0F/255.0F);
+               blue  = data[pos*3+2] * (1.0F/255.0F);
+               alpha = 0;
+               break;
+            default:
+               gl_problem(ctx, "bad image format in gl_scale...image_data");
+               return;
+         }
+      }
+      else if (image->Type == GL_FLOAT) {
+         const GLubyte *data = (GLubyte *) image->Data;
+         switch (image->Format) {
+            case GL_RED:
+               red   = data[pos];
+               green = 0;
+               blue  = 0;
+               alpha = 0;
+               break;
+            case GL_RGB:
+               red   = data[pos*3+0];
+               green = data[pos*3+1];
+               blue  = data[pos*3+2];
+               alpha = 0;
+               break;
+            default:
+               gl_problem(ctx, "bad image format in gl_scale...image_data");
+               return;
+         }
+      }
+      else {
+         gl_problem(ctx, "Bad image type in gl_scale_...image_data");
+         return;
+      }
+
+      assert(red   >= 0.0 && red   <= 1.0);
+      assert(green >= 0.0 && green <= 1.0);
+      assert(blue  >= 0.0 && blue  <= 1.0);
+      assert(alpha >= 0.0 && alpha <= 1.0);
+
+      /*
+      if (scale or bias) {
+
+
+      }
+      if (mapping) {
+
+      }
+      */
+
+      result[i*4+0] = (GLubyte) (red   * 255.0);
+      result[i*4+1] = (GLubyte) (green * 255.0);
+      result[i*4+2] = (GLubyte) (blue  * 255.0);
+      result[i*4+3] = (GLubyte) (alpha * 255.0);
+   }
+}
+
+
+
+/*
+ * Pack the given RGBA span into client memory at 'dest' address
+ * in the given pixel format and type.
+ * Optionally apply the enabled pixel transfer ops.
+ * Pack into memory using the given packing params struct.
+ * This is used by glReadPixels and glGetTexImage?D()
+ * Input:  ctx - the context
+ *         n - number of pixels in the span
+ *         rgba - the pixels
+ *         format - dest packing format
+ *         type - dest packing datatype
+ *         destination - destination packing address
+ *         packing - pixel packing parameters
+ *         applyTransferOps - apply scale/bias/lookup-table ops?
+ */
+void gl_pack_rgba_span( const GLcontext *ctx,
+                        GLuint n, CONST GLubyte rgba[][4],
+                        GLenum format, GLenum type, GLvoid *destination,
+                        const struct gl_pixelstore_attrib *packing,
+                        GLboolean applyTransferOps )
+{
+   /* Test for optimized case first */
+   if (!ctx->Pixel.ScaleOrBiasRGBA && !ctx->Pixel.MapColorFlag &&
+       format == GL_RGBA && type == GL_UNSIGNED_BYTE) {
+      /* simple case */
+      MEMCPY( destination, rgba, n * 4 * sizeof(GLubyte) );
+   }
+   else {
+      GLfloat red[MAX_WIDTH], green[MAX_WIDTH], blue[MAX_WIDTH];
+      GLfloat alpha[MAX_WIDTH], luminance[MAX_WIDTH];
+      GLfloat rscale = 1.0F / 255.0F;
+      GLfloat gscale = 1.0F / 255.0F;
+      GLfloat bscale = 1.0F / 255.0F;
+      GLfloat ascale = 1.0F / 255.0F;
+      GLuint i;
+
+      assert( n < MAX_WIDTH );
+
+      /* convert color components to floating point */
+      for (i=0;i<n;i++) {
+         red[i]   = rgba[i][RCOMP] * rscale;
+         green[i] = rgba[i][GCOMP] * gscale;
+         blue[i]  = rgba[i][BCOMP] * bscale;
+         alpha[i] = rgba[i][ACOMP] * ascale;
+      }
+
+      /*
+       * Apply scale, bias and lookup-tables if enabled.
+       */
+      if (applyTransferOps) {
+         if (ctx->Pixel.ScaleOrBiasRGBA) {
+            gl_scale_and_bias_color( ctx, n, red, green, blue, alpha );
+         }
+         if (ctx->Pixel.MapColorFlag) {
+            gl_map_color( ctx, n, red, green, blue, alpha );
+         }
+      }
+
+      if (format==GL_LUMINANCE || format==GL_LUMINANCE_ALPHA) {
+         for (i=0;i<n;i++) {
+            GLfloat sum = red[i] + green[i] + blue[i];
+            luminance[i] = CLAMP( sum, 0.0F, 1.0F );
+         }
+      }
+
+      /*
+       * Pack/store the pixels.  Ugh!  Lots of cases!!!
+       */
+      switch (type) {
+         case GL_UNSIGNED_BYTE:
+            {
+               GLubyte *dst = (GLubyte *) destination;
+               switch (format) {
+                  case GL_RED:
+                     for (i=0;i<n;i++)
+                        dst[i] = FLOAT_TO_UBYTE(red[i]);
+                     break;
+                  case GL_GREEN:
+                     for (i=0;i<n;i++)
+                        dst[i] = FLOAT_TO_UBYTE(green[i]);
+                     break;
+                  case GL_BLUE:
+                     for (i=0;i<n;i++)
+                        dst[i] = FLOAT_TO_UBYTE(blue[i]);
+                     break;
+                  case GL_ALPHA:
+                     for (i=0;i<n;i++)
+                        dst[i] = FLOAT_TO_UBYTE(alpha[i]);
+                     break;
+                  case GL_LUMINANCE:
+                     for (i=0;i<n;i++)
+                        dst[i] = FLOAT_TO_UBYTE(luminance[i]);
+                     break;
+                  case GL_LUMINANCE_ALPHA:
+                     for (i=0;i<n;i++) {
+                        dst[i*2+0] = FLOAT_TO_UBYTE(luminance[i]);
+                        dst[i*2+1] = FLOAT_TO_UBYTE(alpha[i]);
+                     }
+                     break;
+                  case GL_RGB:
+                     for (i=0;i<n;i++) {
+                        dst[i*3+0] = FLOAT_TO_UBYTE(red[i]);
+                        dst[i*3+1] = FLOAT_TO_UBYTE(green[i]);
+                        dst[i*3+2] = FLOAT_TO_UBYTE(blue[i]);
+                     }
+                     break;
+                  case GL_RGBA:
+                     for (i=0;i<n;i++) {
+                        dst[i*4+0] = FLOAT_TO_UBYTE(red[i]);
+                        dst[i*4+1] = FLOAT_TO_UBYTE(green[i]);
+                        dst[i*4+2] = FLOAT_TO_UBYTE(blue[i]);
+                        dst[i*4+3] = FLOAT_TO_UBYTE(alpha[i]);
+                     }
+                     break;
+                  case GL_BGR:
+                     for (i=0;i<n;i++) {
+                        dst[i*3+0] = FLOAT_TO_UBYTE(blue[i]);
+                        dst[i*3+1] = FLOAT_TO_UBYTE(green[i]);
+                        dst[i*3+2] = FLOAT_TO_UBYTE(red[i]);
+                     }
+                     break;
+                  case GL_BGRA:
+                     for (i=0;i<n;i++) {
+                        dst[i*4+0] = FLOAT_TO_UBYTE(blue[i]);
+                        dst[i*4+1] = FLOAT_TO_UBYTE(green[i]);
+                        dst[i*4+2] = FLOAT_TO_UBYTE(red[i]);
+                        dst[i*4+3] = FLOAT_TO_UBYTE(alpha[i]);
+                     }
+                     break;
+                  case GL_ABGR_EXT:
+                     for (i=0;i<n;i++) {
+                        dst[i*4+0] = FLOAT_TO_UBYTE(alpha[i]);
+                        dst[i*4+1] = FLOAT_TO_UBYTE(blue[i]);
+                        dst[i*4+2] = FLOAT_TO_UBYTE(green[i]);
+                        dst[i*4+3] = FLOAT_TO_UBYTE(red[i]);
+                     }
+                     break;
+                  default:
+                     gl_problem(ctx, "bad format in gl_pack_rgba_span\n");
+               }
+           }
+           break;
+        case GL_BYTE:
+            {
+               GLbyte *dst = (GLbyte *) destination;
+               switch (format) {
+                  case GL_RED:
+                     for (i=0;i<n;i++)
+                        dst[i] = FLOAT_TO_BYTE(red[i]);
+                     break;
+                  case GL_GREEN:
+                     for (i=0;i<n;i++)
+                        dst[i] = FLOAT_TO_BYTE(green[i]);
+                     break;
+                  case GL_BLUE:
+                     for (i=0;i<n;i++)
+                        dst[i] = FLOAT_TO_BYTE(blue[i]);
+                     break;
+                  case GL_ALPHA:
+                     for (i=0;i<n;i++)
+                        dst[i] = FLOAT_TO_BYTE(alpha[i]);
+                     break;
+                  case GL_LUMINANCE:
+                     for (i=0;i<n;i++)
+                        dst[i] = FLOAT_TO_BYTE(luminance[i]);
+                     break;
+                  case GL_LUMINANCE_ALPHA:
+                     for (i=0;i<n;i++) {
+                        dst[i*2+0] = FLOAT_TO_BYTE(luminance[i]);
+                        dst[i*2+1] = FLOAT_TO_BYTE(alpha[i]);
+                     }
+                     break;
+                  case GL_RGB:
+                     for (i=0;i<n;i++) {
+                        dst[i*3+0] = FLOAT_TO_BYTE(red[i]);
+                        dst[i*3+1] = FLOAT_TO_BYTE(green[i]);
+                        dst[i*3+2] = FLOAT_TO_BYTE(blue[i]);
+                     }
+                     break;
+                  case GL_RGBA:
+                     for (i=0;i<n;i++) {
+                        dst[i*4+0] = FLOAT_TO_BYTE(red[i]);
+                        dst[i*4+1] = FLOAT_TO_BYTE(green[i]);
+                        dst[i*4+2] = FLOAT_TO_BYTE(blue[i]);
+                        dst[i*4+3] = FLOAT_TO_BYTE(alpha[i]);
+                     }
+                     break;
+                  case GL_BGR:
+                     for (i=0;i<n;i++) {
+                        dst[i*3+0] = FLOAT_TO_BYTE(blue[i]);
+                        dst[i*3+1] = FLOAT_TO_BYTE(green[i]);
+                        dst[i*3+2] = FLOAT_TO_BYTE(red[i]);
+                     }
+                     break;
+                  case GL_BGRA:
+                     for (i=0;i<n;i++) {
+                        dst[i*4+0] = FLOAT_TO_BYTE(blue[i]);
+                        dst[i*4+1] = FLOAT_TO_BYTE(green[i]);
+                        dst[i*4+2] = FLOAT_TO_BYTE(red[i]);
+                        dst[i*4+3] = FLOAT_TO_BYTE(alpha[i]);
+                     }
+                  case GL_ABGR_EXT:
+                     for (i=0;i<n;i++) {
+                        dst[i*4+0] = FLOAT_TO_BYTE(alpha[i]);
+                        dst[i*4+1] = FLOAT_TO_BYTE(blue[i]);
+                        dst[i*4+2] = FLOAT_TO_BYTE(green[i]);
+                        dst[i*4+3] = FLOAT_TO_BYTE(red[i]);
+                     }
+                     break;
+                  default:
+                     gl_problem(ctx, "bad format in gl_pack_rgba_span\n");
+               }
+            }
+           break;
+        case GL_UNSIGNED_SHORT:
+            {
+               GLushort *dst = (GLushort *) destination;
+               switch (format) {
+                  case GL_RED:
+                     for (i=0;i<n;i++)
+                        dst[i] = FLOAT_TO_USHORT(red[i]);
+                     break;
+                  case GL_GREEN:
+                     for (i=0;i<n;i++)
+                        dst[i] = FLOAT_TO_USHORT(green[i]);
+                     break;
+                  case GL_BLUE:
+                     for (i=0;i<n;i++)
+                        dst[i] = FLOAT_TO_USHORT(blue[i]);
+                     break;
+                  case GL_ALPHA:
+                     for (i=0;i<n;i++)
+                        dst[i] = FLOAT_TO_USHORT(alpha[i]);
+                     break;
+                  case GL_LUMINANCE:
+                     for (i=0;i<n;i++)
+                        dst[i] = FLOAT_TO_USHORT(luminance[i]);
+                     break;
+                  case GL_LUMINANCE_ALPHA:
+                     for (i=0;i<n;i++) {
+                        dst[i*2+0] = FLOAT_TO_USHORT(luminance[i]);
+                        dst[i*2+1] = FLOAT_TO_USHORT(alpha[i]);
+                     }
+                     break;
+                  case GL_RGB:
+                     for (i=0;i<n;i++) {
+                        dst[i*3+0] = FLOAT_TO_USHORT(red[i]);
+                        dst[i*3+1] = FLOAT_TO_USHORT(green[i]);
+                        dst[i*3+2] = FLOAT_TO_USHORT(blue[i]);
+                     }
+                     break;
+                  case GL_RGBA:
+                     for (i=0;i<n;i++) {
+                        dst[i*4+0] = FLOAT_TO_USHORT(red[i]);
+                        dst[i*4+1] = FLOAT_TO_USHORT(green[i]);
+                        dst[i*4+2] = FLOAT_TO_USHORT(blue[i]);
+                        dst[i*4+3] = FLOAT_TO_USHORT(alpha[i]);
+                     }
+                     break;
+                  case GL_BGR:
+                     for (i=0;i<n;i++) {
+                        dst[i*3+0] = FLOAT_TO_USHORT(blue[i]);
+                        dst[i*3+1] = FLOAT_TO_USHORT(green[i]);
+                        dst[i*3+2] = FLOAT_TO_USHORT(red[i]);
+                     }
+                     break;
+                  case GL_BGRA:
+                     for (i=0;i<n;i++) {
+                        dst[i*4+0] = FLOAT_TO_USHORT(blue[i]);
+                        dst[i*4+1] = FLOAT_TO_USHORT(green[i]);
+                        dst[i*4+2] = FLOAT_TO_USHORT(red[i]);
+                        dst[i*4+3] = FLOAT_TO_USHORT(alpha[i]);
+                     }
+                     break;
+                  case GL_ABGR_EXT:
+                     for (i=0;i<n;i++) {
+                        dst[i*4+0] = FLOAT_TO_USHORT(alpha[i]);
+                        dst[i*4+1] = FLOAT_TO_USHORT(blue[i]);
+                        dst[i*4+2] = FLOAT_TO_USHORT(green[i]);
+                        dst[i*4+3] = FLOAT_TO_USHORT(red[i]);
+                     }
+                     break;
+                  default:
+                     gl_problem(ctx, "bad format in gl_pack_rgba_span\n");
+               }
+               if (packing->SwapBytes) {
+                  gl_swap2( (GLushort *) dst, n );
+               }
+            }
+           break;
+        case GL_SHORT:
+            {
+               GLshort *dst = (GLshort *) destination;
+               switch (format) {
+                  case GL_RED:
+                     for (i=0;i<n;i++)
+                        dst[i] = FLOAT_TO_SHORT(red[i]);
+                     break;
+                  case GL_GREEN:
+                     for (i=0;i<n;i++)
+                        dst[i] = FLOAT_TO_SHORT(green[i]);
+                     break;
+                  case GL_BLUE:
+                     for (i=0;i<n;i++)
+                        dst[i] = FLOAT_TO_SHORT(blue[i]);
+                     break;
+                  case GL_ALPHA:
+                     for (i=0;i<n;i++)
+                        dst[i] = FLOAT_TO_SHORT(alpha[i]);
+                     break;
+                  case GL_LUMINANCE:
+                     for (i=0;i<n;i++)
+                        dst[i] = FLOAT_TO_SHORT(luminance[i]);
+                     break;
+                  case GL_LUMINANCE_ALPHA:
+                     for (i=0;i<n;i++) {
+                        dst[i*2+0] = FLOAT_TO_SHORT(luminance[i]);
+                        dst[i*2+1] = FLOAT_TO_SHORT(alpha[i]);
+                     }
+                     break;
+                  case GL_RGB:
+                     for (i=0;i<n;i++) {
+                        dst[i*3+0] = FLOAT_TO_SHORT(red[i]);
+                        dst[i*3+1] = FLOAT_TO_SHORT(green[i]);
+                        dst[i*3+2] = FLOAT_TO_SHORT(blue[i]);
+                     }
+                     break;
+                  case GL_RGBA:
+                     for (i=0;i<n;i++) {
+                        dst[i*4+0] = FLOAT_TO_SHORT(red[i]);
+                        dst[i*4+1] = FLOAT_TO_SHORT(green[i]);
+                        dst[i*4+2] = FLOAT_TO_SHORT(blue[i]);
+                        dst[i*4+3] = FLOAT_TO_SHORT(alpha[i]);
+                     }
+                     break;
+                  case GL_BGR:
+                     for (i=0;i<n;i++) {
+                        dst[i*3+0] = FLOAT_TO_SHORT(blue[i]);
+                        dst[i*3+1] = FLOAT_TO_SHORT(green[i]);
+                        dst[i*3+2] = FLOAT_TO_SHORT(red[i]);
+                     }
+                     break;
+                  case GL_BGRA:
+                     for (i=0;i<n;i++) {
+                        dst[i*4+0] = FLOAT_TO_SHORT(blue[i]);
+                        dst[i*4+1] = FLOAT_TO_SHORT(green[i]);
+                        dst[i*4+2] = FLOAT_TO_SHORT(red[i]);
+                        dst[i*4+3] = FLOAT_TO_SHORT(alpha[i]);
+                     }
+                  case GL_ABGR_EXT:
+                     for (i=0;i<n;i++) {
+                        dst[i*4+0] = FLOAT_TO_SHORT(alpha[i]);
+                        dst[i*4+1] = FLOAT_TO_SHORT(blue[i]);
+                        dst[i*4+2] = FLOAT_TO_SHORT(green[i]);
+                        dst[i*4+3] = FLOAT_TO_SHORT(red[i]);
+                     }
+                     break;
+                  default:
+                     gl_problem(ctx, "bad format in gl_pack_rgba_span\n");
+               }
+               if (packing->SwapBytes) {
+                  gl_swap2( (GLushort *) dst, n );
+               }
+            }
+           break;
+        case GL_UNSIGNED_INT:
+            {
+               GLuint *dst = (GLuint *) destination;
+               switch (format) {
+                  case GL_RED:
+                     for (i=0;i<n;i++)
+                        dst[i] = FLOAT_TO_UINT(red[i]);
+                     break;
+                  case GL_GREEN:
+                     for (i=0;i<n;i++)
+                        dst[i] = FLOAT_TO_UINT(green[i]);
+                     break;
+                  case GL_BLUE:
+                     for (i=0;i<n;i++)
+                        dst[i] = FLOAT_TO_UINT(blue[i]);
+                     break;
+                  case GL_ALPHA:
+                     for (i=0;i<n;i++)
+                        dst[i] = FLOAT_TO_UINT(alpha[i]);
+                     break;
+                  case GL_LUMINANCE:
+                     for (i=0;i<n;i++)
+                        dst[i] = FLOAT_TO_UINT(luminance[i]);
+                     break;
+                  case GL_LUMINANCE_ALPHA:
+                     for (i=0;i<n;i++) {
+                        dst[i*2+0] = FLOAT_TO_UINT(luminance[i]);
+                        dst[i*2+1] = FLOAT_TO_UINT(alpha[i]);
+                     }
+                     break;
+                  case GL_RGB:
+                     for (i=0;i<n;i++) {
+                        dst[i*3+0] = FLOAT_TO_UINT(red[i]);
+                        dst[i*3+1] = FLOAT_TO_UINT(green[i]);
+                        dst[i*3+2] = FLOAT_TO_UINT(blue[i]);
+                     }
+                     break;
+                  case GL_RGBA:
+                     for (i=0;i<n;i++) {
+                        dst[i*4+0] = FLOAT_TO_UINT(red[i]);
+                        dst[i*4+1] = FLOAT_TO_UINT(green[i]);
+                        dst[i*4+2] = FLOAT_TO_UINT(blue[i]);
+                        dst[i*4+3] = FLOAT_TO_UINT(alpha[i]);
+                     }
+                     break;
+                  case GL_BGR:
+                     for (i=0;i<n;i++) {
+                        dst[i*3+0] = FLOAT_TO_UINT(blue[i]);
+                        dst[i*3+1] = FLOAT_TO_UINT(green[i]);
+                        dst[i*3+2] = FLOAT_TO_UINT(red[i]);
+                     }
+                     break;
+                  case GL_BGRA:
+                     for (i=0;i<n;i++) {
+                        dst[i*4+0] = FLOAT_TO_UINT(blue[i]);
+                        dst[i*4+1] = FLOAT_TO_UINT(green[i]);
+                        dst[i*4+2] = FLOAT_TO_UINT(red[i]);
+                        dst[i*4+3] = FLOAT_TO_UINT(alpha[i]);
+                     }
+                     break;
+                  case GL_ABGR_EXT:
+                     for (i=0;i<n;i++) {
+                        dst[i*4+0] = FLOAT_TO_UINT(alpha[i]);
+                        dst[i*4+1] = FLOAT_TO_UINT(blue[i]);
+                        dst[i*4+2] = FLOAT_TO_UINT(green[i]);
+                        dst[i*4+3] = FLOAT_TO_UINT(red[i]);
+                     }
+                     break;
+                  default:
+                     gl_problem(ctx, "bad format in gl_pack_rgba_span\n");
+               }
+               if (packing->SwapBytes) {
+                  gl_swap4( (GLuint *) dst, n );
+               }
+            }
+           break;
+        case GL_INT:
+           {
+               GLint *dst = (GLint *) destination;
+               switch (format) {
+                  case GL_RED:
+                     for (i=0;i<n;i++)
+                        dst[i] = FLOAT_TO_INT(red[i]);
+                     break;
+                  case GL_GREEN:
+                     for (i=0;i<n;i++)
+                        dst[i] = FLOAT_TO_INT(green[i]);
+                     break;
+                  case GL_BLUE:
+                     for (i=0;i<n;i++)
+                        dst[i] = FLOAT_TO_INT(blue[i]);
+                     break;
+                  case GL_ALPHA:
+                     for (i=0;i<n;i++)
+                        dst[i] = FLOAT_TO_INT(alpha[i]);
+                     break;
+                  case GL_LUMINANCE:
+                     for (i=0;i<n;i++)
+                        dst[i] = FLOAT_TO_INT(luminance[i]);
+                     break;
+                  case GL_LUMINANCE_ALPHA:
+                     for (i=0;i<n;i++) {
+                        dst[i*2+0] = FLOAT_TO_INT(luminance[i]);
+                        dst[i*2+1] = FLOAT_TO_INT(alpha[i]);
+                     }
+                     break;
+                  case GL_RGB:
+                     for (i=0;i<n;i++) {
+                        dst[i*3+0] = FLOAT_TO_INT(red[i]);
+                        dst[i*3+1] = FLOAT_TO_INT(green[i]);
+                        dst[i*3+2] = FLOAT_TO_INT(blue[i]);
+                     }
+                     break;
+                  case GL_RGBA:
+                     for (i=0;i<n;i++) {
+                        dst[i*4+0] = FLOAT_TO_INT(red[i]);
+                        dst[i*4+1] = FLOAT_TO_INT(green[i]);
+                        dst[i*4+2] = FLOAT_TO_INT(blue[i]);
+                        dst[i*4+3] = FLOAT_TO_INT(alpha[i]);
+                     }
+                     break;
+                  case GL_BGR:
+                     for (i=0;i<n;i++) {
+                        dst[i*3+0] = FLOAT_TO_INT(blue[i]);
+                        dst[i*3+1] = FLOAT_TO_INT(green[i]);
+                        dst[i*3+2] = FLOAT_TO_INT(red[i]);
+                     }
+                     break;
+                  case GL_BGRA:
+                     for (i=0;i<n;i++) {
+                        dst[i*4+0] = FLOAT_TO_INT(blue[i]);
+                        dst[i*4+1] = FLOAT_TO_INT(green[i]);
+                        dst[i*4+2] = FLOAT_TO_INT(red[i]);
+                        dst[i*4+3] = FLOAT_TO_INT(alpha[i]);
+                     }
+                     break;
+                  case GL_ABGR_EXT:
+                     for (i=0;i<n;i++) {
+                        dst[i*4+0] = FLOAT_TO_INT(alpha[i]);
+                        dst[i*4+1] = FLOAT_TO_INT(blue[i]);
+                        dst[i*4+2] = FLOAT_TO_INT(green[i]);
+                        dst[i*4+3] = FLOAT_TO_INT(red[i]);
+                     }
+                     break;
+                  default:
+                     gl_problem(ctx, "bad format in gl_pack_rgba_span\n");
+               }
+              if (packing->SwapBytes) {
+                 gl_swap4( (GLuint *) dst, n );
+              }
+           }
+           break;
+        case GL_FLOAT:
+           {
+               GLfloat *dst = (GLfloat *) destination;
+               switch (format) {
+                  case GL_RED:
+                     for (i=0;i<n;i++)
+                        dst[i] = red[i];
+                     break;
+                  case GL_GREEN:
+                     for (i=0;i<n;i++)
+                        dst[i] = green[i];
+                     break;
+                  case GL_BLUE:
+                     for (i=0;i<n;i++)
+                        dst[i] = blue[i];
+                     break;
+                  case GL_ALPHA:
+                     for (i=0;i<n;i++)
+                        dst[i] = alpha[i];
+                     break;
+                  case GL_LUMINANCE:
+                     for (i=0;i<n;i++)
+                        dst[i] = luminance[i];
+                     break;
+                  case GL_LUMINANCE_ALPHA:
+                     for (i=0;i<n;i++) {
+                        dst[i*2+0] = luminance[i];
+                        dst[i*2+1] = alpha[i];
+                     }
+                     break;
+                  case GL_RGB:
+                     for (i=0;i<n;i++) {
+                        dst[i*3+0] = red[i];
+                        dst[i*3+1] = green[i];
+                        dst[i*3+2] = blue[i];
+                     }
+                     break;
+                  case GL_RGBA:
+                     for (i=0;i<n;i++) {
+                        dst[i*4+0] = red[i];
+                        dst[i*4+1] = green[i];
+                        dst[i*4+2] = blue[i];
+                        dst[i*4+3] = alpha[i];
+                     }
+                     break;
+                  case GL_BGR:
+                     for (i=0;i<n;i++) {
+                        dst[i*3+0] = blue[i];
+                        dst[i*3+1] = green[i];
+                        dst[i*3+2] = red[i];
+                     }
+                     break;
+                  case GL_BGRA:
+                     for (i=0;i<n;i++) {
+                        dst[i*4+0] = blue[i];
+                        dst[i*4+1] = green[i];
+                        dst[i*4+2] = red[i];
+                        dst[i*4+3] = alpha[i];
+                     }
+                     break;
+                  case GL_ABGR_EXT:
+                     for (i=0;i<n;i++) {
+                        dst[i*4+0] = alpha[i];
+                        dst[i*4+1] = blue[i];
+                        dst[i*4+2] = green[i];
+                        dst[i*4+3] = red[i];
+                     }
+                     break;
+                  default:
+                     gl_problem(ctx, "bad format in gl_pack_rgba_span\n");
+               }
+              if (packing->SwapBytes) {
+                 gl_swap4( (GLuint *) dst, n );
+              }
+           }
+           break;
+         case GL_UNSIGNED_BYTE_3_3_2:
+            if (format == GL_RGB) {
+               GLubyte *dst = (GLubyte *) destination;
+               for (i=0;i<n;i++) {
+                  dst[i] = (((GLint) (red[i]   * 7.0F)) << 5)
+                         | (((GLint) (green[i] * 7.0F)) << 2)
+                         | (((GLint) (blue[i]  * 3.0F))     );
+               }
+            }
+            break;
+         case GL_UNSIGNED_BYTE_2_3_3_REV:
+            if (format == GL_RGB) {
+               GLubyte *dst = (GLubyte *) destination;
+               for (i=0;i<n;i++) {
+                  dst[i] = (((GLint) (red[i]   * 7.0F))     )
+                         | (((GLint) (green[i] * 7.0F)) << 3)
+                         | (((GLint) (blue[i]  * 3.0F)) << 5);
+               }
+            }
+            break;
+         case GL_UNSIGNED_SHORT_5_6_5:
+            if (format == GL_RGB) {
+               GLushort *dst = (GLushort *) destination;
+               for (i=0;i<n;i++) {
+                  dst[i] = (((GLint) (red[i]   * 31.0F)) << 11)
+                         | (((GLint) (green[i] * 63.0F)) <<  5)
+                         | (((GLint) (blue[i]  * 31.0F))      );
+               }
+            }
+            break;
+         case GL_UNSIGNED_SHORT_5_6_5_REV:
+            if (format == GL_RGB) {
+               GLushort *dst = (GLushort *) destination;
+               for (i=0;i<n;i++) {
+                  dst[i] = (((GLint) (red[i]   * 31.0F))      )
+                         | (((GLint) (green[i] * 63.0F)) <<  5)
+                         | (((GLint) (blue[i]  * 31.0F)) << 11);
+               }
+            }
+            break;
+         case GL_UNSIGNED_SHORT_4_4_4_4:
+            if (format == GL_RGB) {
+               GLushort *dst = (GLushort *) destination;
+               for (i=0;i<n;i++) {
+                  dst[i] = (((GLint) (red[i]   * 15.0F)) << 12)
+                         | (((GLint) (green[i] * 15.0F)) <<  8)
+                         | (((GLint) (blue[i]  * 15.0F)) <<  4)
+                         | (((GLint) (alpha[i] * 15.0F))      );
+               }
+            }
+            break;
+         case GL_UNSIGNED_SHORT_4_4_4_4_REV:
+            if (format == GL_RGB) {
+               GLushort *dst = (GLushort *) destination;
+               for (i=0;i<n;i++) {
+                  dst[i] = (((GLint) (red[i]   * 15.0F))      )
+                         | (((GLint) (green[i] * 15.0F)) <<  4)
+                         | (((GLint) (blue[i]  * 15.0F)) <<  8)
+                         | (((GLint) (alpha[i] * 15.0F)) << 12);
+               }
+            }
+            break;
+         case GL_UNSIGNED_SHORT_5_5_5_1:
+            if (format == GL_RGB) {
+               GLushort *dst = (GLushort *) destination;
+               for (i=0;i<n;i++) {
+                  dst[i] = (((GLint) (red[i]   * 31.0F)) << 11)
+                         | (((GLint) (green[i] * 31.0F)) <<  6)
+                         | (((GLint) (blue[i]  * 31.0F)) <<  1)
+                         | (((GLint) (alpha[i] *  1.0F))      );
+               }
+            }
+            break;
+         case GL_UNSIGNED_SHORT_1_5_5_5_REV:
+            if (format == GL_RGB) {
+               GLushort *dst = (GLushort *) destination;
+               for (i=0;i<n;i++) {
+                  dst[i] = (((GLint) (red[i]   * 31.0F))      )
+                         | (((GLint) (green[i] * 31.0F)) <<  5)
+                         | (((GLint) (blue[i]  * 31.0F)) << 10)
+                         | (((GLint) (alpha[i] *  1.0F)) << 15);
+               }
+            }
+            break;
+         case GL_UNSIGNED_INT_8_8_8_8:
+            if (format == GL_RGBA) {
+               GLuint *dst = (GLuint *) destination;
+               for (i=0;i<n;i++) {
+                  dst[i] = (((GLuint) (red[i]   * 255.0F)) << 24)
+                         | (((GLuint) (green[i] * 255.0F)) << 16)
+                         | (((GLuint) (blue[i]  * 255.0F)) <<  8)
+                         | (((GLuint) (alpha[i] * 255.0F))      );
+               }
+            }
+            else if (format == GL_BGRA) {
+               GLuint *dst = (GLuint *) destination;
+               for (i=0;i<n;i++) {
+                  dst[i] = (((GLuint) (blue[i]  * 255.0F)) << 24)
+                         | (((GLuint) (green[i] * 255.0F)) << 16)
+                         | (((GLuint) (red[i]   * 255.0F)) <<  8)
+                         | (((GLuint) (alpha[i] * 255.0F))      );
+               }
+            }
+            else if (format == GL_ABGR_EXT) {
+               GLuint *dst = (GLuint *) destination;
+               for (i=0;i<n;i++) {
+                  dst[i] = (((GLuint) (alpha[i] * 255.0F)) << 24)
+                         | (((GLuint) (blue[i]  * 255.0F)) << 16)
+                         | (((GLuint) (green[i] * 255.0F)) <<  8)
+                         | (((GLuint) (red[i]   * 255.0F))      );
+               }
+            }
+            break;
+         case GL_UNSIGNED_INT_8_8_8_8_REV:
+            if (format == GL_RGBA) {
+               GLuint *dst = (GLuint *) destination;
+               for (i=0;i<n;i++) {
+                  dst[i] = (((GLuint) (red[i]   * 255.0F))      )
+                         | (((GLuint) (green[i] * 255.0F)) <<  8)
+                         | (((GLuint) (blue[i]  * 255.0F)) << 16)
+                         | (((GLuint) (alpha[i] * 255.0F)) << 24);
+               }
+            }
+            else if (format == GL_BGRA) {
+               GLuint *dst = (GLuint *) destination;
+               for (i=0;i<n;i++) {
+                  dst[i] = (((GLuint) (blue[i]  * 255.0F))      )
+                         | (((GLuint) (green[i] * 255.0F)) <<  8)
+                         | (((GLuint) (red[i]   * 255.0F)) << 16)
+                         | (((GLuint) (alpha[i] * 255.0F)) << 24);
+               }
+            }
+            else if (format == GL_ABGR_EXT) {
+               GLuint *dst = (GLuint *) destination;
+               for (i=0;i<n;i++) {
+                  dst[i] = (((GLuint) (alpha[i] * 255.0F))      )
+                         | (((GLuint) (blue[i]  * 255.0F)) <<  8)
+                         | (((GLuint) (green[i] * 255.0F)) << 16)
+                         | (((GLuint) (red[i]   * 255.0F)) << 24);
+               }
+            }
+            break;
+         case GL_UNSIGNED_INT_10_10_10_2:
+            if (format == GL_RGBA) {
+               GLuint *dst = (GLuint *) destination;
+               for (i=0;i<n;i++) {
+                  dst[i] = (((GLuint) (red[i]   * 1023.0F)) << 22)
+                         | (((GLuint) (green[i] * 1023.0F)) << 12)
+                         | (((GLuint) (blue[i]  * 1023.0F)) <<  2)
+                         | (((GLuint) (alpha[i] *    3.0F))      );
+               }
+            }
+            else if (format == GL_BGRA) {
+               GLuint *dst = (GLuint *) destination;
+               for (i=0;i<n;i++) {
+                  dst[i] = (((GLuint) (blue[i]  * 1023.0F)) << 22)
+                         | (((GLuint) (green[i] * 1023.0F)) << 12)
+                         | (((GLuint) (red[i]   * 1023.0F)) <<  2)
+                         | (((GLuint) (alpha[i] *    3.0F))      );
+               }
+            }
+            else if (format == GL_ABGR_EXT) {
+               GLuint *dst = (GLuint *) destination;
+               for (i=0;i<n;i++) {
+                  dst[i] = (((GLuint) (alpha[i] * 1023.0F)) << 22)
+                         | (((GLuint) (blue[i]  * 1023.0F)) << 12)
+                         | (((GLuint) (green[i] * 1023.0F)) <<  2)
+                         | (((GLuint) (red[i]   *    3.0F))      );
+               }
+            }
+            break;
+         case GL_UNSIGNED_INT_2_10_10_10_REV:
+            if (format == GL_RGBA) {
+               GLuint *dst = (GLuint *) destination;
+               for (i=0;i<n;i++) {
+                  dst[i] = (((GLuint) (red[i]   * 1023.0F))      )
+                         | (((GLuint) (green[i] * 1023.0F)) << 10)
+                         | (((GLuint) (blue[i]  * 1023.0F)) << 20)
+                         | (((GLuint) (alpha[i] *    3.0F)) << 30);
+               }
+            }
+            else if (format == GL_BGRA) {
+               GLuint *dst = (GLuint *) destination;
+               for (i=0;i<n;i++) {
+                  dst[i] = (((GLuint) (blue[i]  * 1023.0F))      )
+                         | (((GLuint) (green[i] * 1023.0F)) << 10)
+                         | (((GLuint) (red[i]   * 1023.0F)) << 20)
+                         | (((GLuint) (alpha[i] *    3.0F)) << 30);
+               }
+            }
+            else if (format == GL_ABGR_EXT) {
+               GLuint *dst = (GLuint *) destination;
+               for (i=0;i<n;i++) {
+                  dst[i] = (((GLuint) (alpha[i] * 1023.0F))      )
+                         | (((GLuint) (blue[i]  * 1023.0F)) << 10)
+                         | (((GLuint) (green[i] * 1023.0F)) << 20)
+                         | (((GLuint) (red[i]   *    3.0F)) << 30);
+               }
+            }
+            break;
+         default:
+            gl_problem( ctx, "bad type in gl_pack_rgba_span" );
+      }
+   }
+}
diff --git a/src/mesa/main/image.h b/src/mesa/main/image.h
new file mode 100644 (file)
index 0000000..3fd2ca8
--- /dev/null
@@ -0,0 +1,109 @@
+/* $Id: image.h,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+#ifndef IMAGE_H
+#define IMAGE_H
+
+
+#include "types.h"
+
+
+extern void gl_flip_bytes( GLubyte *p, GLuint n );
+
+
+extern void gl_swap2( GLushort *p, GLuint n );
+
+extern void gl_swap4( GLuint *p, GLuint n );
+
+
+extern GLint gl_sizeof_type( GLenum type );
+
+extern GLint gl_sizeof_packed_type( GLenum type );
+
+extern GLint gl_components_in_format( GLenum format );
+
+extern GLint gl_bytes_per_pixel( GLenum format, GLenum type );
+
+extern GLboolean gl_is_legal_format_and_type( GLenum format, GLenum type );
+
+
+extern GLvoid *
+gl_pixel_addr_in_image( const struct gl_pixelstore_attrib *packing,
+                        const GLvoid *image, GLsizei width,
+                        GLsizei height, GLenum format, GLenum type,
+                        GLint img, GLint row, GLint column );
+
+
+extern struct gl_image *
+gl_unpack_bitmap( GLcontext *ctx, GLsizei width, GLsizei height,
+                  const GLubyte *bitmap,
+                  const struct gl_pixelstore_attrib *packing );
+
+
+extern void gl_unpack_polygon_stipple( const GLcontext *ctx,
+                                       const GLubyte *pattern,
+                                       GLuint dest[32] );
+
+
+extern void gl_pack_polygon_stipple( const GLcontext *ctx,
+                                     const GLuint pattern[32],
+                                     GLubyte *dest );
+
+
+extern struct gl_image *
+gl_unpack_image( GLcontext *ctx, GLint width, GLint height,
+                 GLenum srcFormat, GLenum srcType, const GLvoid *pixels,
+                 const struct gl_pixelstore_attrib *packing );
+
+
+
+struct gl_image *
+gl_unpack_image3D( GLcontext *ctx, GLint width, GLint height,GLint depth,
+                   GLenum srcFormat, GLenum srcType, const GLvoid *pixels,
+                   const struct gl_pixelstore_attrib *packing );
+
+
+extern void
+gl_pack_rgba_span( const GLcontext *ctx,
+                   GLuint n, CONST GLubyte rgba[][4],
+                   GLenum format, GLenum type, GLvoid *dest,
+                   const struct gl_pixelstore_attrib *packing,
+                   GLboolean applyTransferOps );
+
+
+extern void gl_free_image( struct gl_image *image );
+
+
+extern GLboolean gl_image_error_test( GLcontext *ctx,
+                                      const struct gl_image *image,
+                                      const char *msg );
+
+
+#endif
diff --git a/src/mesa/main/light.c b/src/mesa/main/light.c
new file mode 100644 (file)
index 0000000..cc396f8
--- /dev/null
@@ -0,0 +1,1183 @@
+/* $Id: light.c,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <assert.h>
+#include <float.h>
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "context.h"
+#include "enums.h"
+#include "light.h"
+#include "macros.h"
+#include "matrix.h"
+#include "mmath.h"
+#include "simple_list.h"
+#include "types.h"
+#include "vb.h"
+#include "xform.h"
+#ifdef XFree86Server
+#include "GL/xf86glx.h"
+#endif
+#endif
+
+
+
+void gl_ShadeModel( GLcontext *ctx, GLenum mode )
+{
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glShadeModel");
+
+   if (MESA_VERBOSE & VERBOSE_API)
+      fprintf(stderr, "glShadeModel %s\n", gl_lookup_enum_by_nr(mode));
+
+   switch (mode) {
+      case GL_FLAT:
+      case GL_SMOOTH:
+         if (ctx->Light.ShadeModel!=mode) {
+            ctx->Light.ShadeModel = mode;
+           ctx->TriangleCaps ^= DD_FLATSHADE;
+            ctx->NewState |= NEW_RASTER_OPS;
+         }
+         break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glShadeModel" );
+   }
+
+   if (ctx->Driver.ShadeModel) 
+      (*ctx->Driver.ShadeModel)( ctx, mode );
+}
+
+
+
+void gl_Lightfv( GLcontext *ctx,
+                 GLenum light, GLenum pname, const GLfloat *params,
+                 GLint nparams )
+{
+   GLint l;
+
+   (void) nparams;
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLight");
+
+   l = (GLint) (light - GL_LIGHT0);
+
+   if (l<0 || l>=MAX_LIGHTS) {
+      gl_error( ctx, GL_INVALID_ENUM, "glLight" );
+      return;
+   }
+
+   switch (pname) {
+      case GL_AMBIENT:
+         COPY_4V( ctx->Light.Light[l].Ambient, params );
+         break;
+      case GL_DIFFUSE:
+         COPY_4V( ctx->Light.Light[l].Diffuse, params );
+         break;
+      case GL_SPECULAR:
+         COPY_4V( ctx->Light.Light[l].Specular, params );
+         break;
+      case GL_POSITION:
+        /* transform position by ModelView matrix */
+        TRANSFORM_POINT( ctx->Light.Light[l].EyePosition, 
+                         ctx->ModelView.m,
+                          params );
+         break;
+      case GL_SPOT_DIRECTION:
+        /* transform direction by inverse modelview */
+        if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) {
+           gl_matrix_analyze( &ctx->ModelView );
+        }
+        TRANSFORM_NORMAL( ctx->Light.Light[l].EyeDirection,
+                          params,
+                          ctx->ModelView.inv );
+         break;
+      case GL_SPOT_EXPONENT:
+         if (params[0]<0.0 || params[0]>128.0) {
+            gl_error( ctx, GL_INVALID_VALUE, "glLight" );
+            return;
+         }
+         if (ctx->Light.Light[l].SpotExponent != params[0]) {
+            ctx->Light.Light[l].SpotExponent = params[0];
+            gl_compute_spot_exp_table( &ctx->Light.Light[l] );
+         }
+         break;
+      case GL_SPOT_CUTOFF:
+         if ((params[0]<0.0 || params[0]>90.0) && params[0]!=180.0) {
+            gl_error( ctx, GL_INVALID_VALUE, "glLight" );
+            return;
+         }
+         ctx->Light.Light[l].SpotCutoff = params[0];
+         ctx->Light.Light[l].CosCutoff = cos(params[0]*DEG2RAD);
+         if (ctx->Light.Light[l].CosCutoff < 0) 
+           ctx->Light.Light[l].CosCutoff = 0;
+         break;
+      case GL_CONSTANT_ATTENUATION:
+         if (params[0]<0.0) {
+            gl_error( ctx, GL_INVALID_VALUE, "glLight" );
+            return;
+         }
+         ctx->Light.Light[l].ConstantAttenuation = params[0];
+         break;
+      case GL_LINEAR_ATTENUATION:
+         if (params[0]<0.0) {
+            gl_error( ctx, GL_INVALID_VALUE, "glLight" );
+            return;
+         }
+         ctx->Light.Light[l].LinearAttenuation = params[0];
+         break;
+      case GL_QUADRATIC_ATTENUATION:
+         if (params[0]<0.0) {
+            gl_error( ctx, GL_INVALID_VALUE, "glLight" );
+            return;
+         }
+         ctx->Light.Light[l].QuadraticAttenuation = params[0];
+         break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glLight" );
+         break;
+   }
+
+   ctx->NewState |= NEW_LIGHTING;
+}
+
+
+
+void gl_GetLightfv( GLcontext *ctx,
+                    GLenum light, GLenum pname, GLfloat *params )
+{
+   GLint l = (GLint) (light - GL_LIGHT0);
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetLight");
+
+   if (l<0 || l>=MAX_LIGHTS) {
+      gl_error( ctx, GL_INVALID_ENUM, "glGetLightfv" );
+      return;
+   }
+
+   switch (pname) {
+      case GL_AMBIENT:
+         COPY_4V( params, ctx->Light.Light[l].Ambient );
+         break;
+      case GL_DIFFUSE:
+         COPY_4V( params, ctx->Light.Light[l].Diffuse );
+         break;
+      case GL_SPECULAR:
+         COPY_4V( params, ctx->Light.Light[l].Specular );
+         break;
+      case GL_POSITION:
+         COPY_4V( params, ctx->Light.Light[l].EyePosition );
+         break;
+      case GL_SPOT_DIRECTION:
+         COPY_3V( params, ctx->Light.Light[l].EyeDirection );
+         break;
+      case GL_SPOT_EXPONENT:
+         params[0] = ctx->Light.Light[l].SpotExponent;
+         break;
+      case GL_SPOT_CUTOFF:
+         params[0] = ctx->Light.Light[l].SpotCutoff;
+         break;
+      case GL_CONSTANT_ATTENUATION:
+         params[0] = ctx->Light.Light[l].ConstantAttenuation;
+         break;
+      case GL_LINEAR_ATTENUATION:
+         params[0] = ctx->Light.Light[l].LinearAttenuation;
+         break;
+      case GL_QUADRATIC_ATTENUATION:
+         params[0] = ctx->Light.Light[l].QuadraticAttenuation;
+         break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glGetLightfv" );
+         break;
+   }
+}
+
+
+
+void gl_GetLightiv( GLcontext *ctx, GLenum light, GLenum pname, GLint *params )
+{
+   GLint l = (GLint) (light - GL_LIGHT0);
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetLight");
+
+   if (l<0 || l>=MAX_LIGHTS) {
+      gl_error( ctx, GL_INVALID_ENUM, "glGetLightiv" );
+      return;
+   }
+
+   switch (pname) {
+      case GL_AMBIENT:
+         params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[0]);
+         params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[1]);
+         params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[2]);
+         params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[3]);
+         break;
+      case GL_DIFFUSE:
+         params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[0]);
+         params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[1]);
+         params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[2]);
+         params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[3]);
+         break;
+      case GL_SPECULAR:
+         params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[0]);
+         params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[1]);
+         params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[2]);
+         params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[3]);
+         break;
+      case GL_POSITION:
+         params[0] = (GLint) ctx->Light.Light[l].EyePosition[0];
+         params[1] = (GLint) ctx->Light.Light[l].EyePosition[1];
+         params[2] = (GLint) ctx->Light.Light[l].EyePosition[2];
+         params[3] = (GLint) ctx->Light.Light[l].EyePosition[3];
+         break;
+      case GL_SPOT_DIRECTION:
+         params[0] = (GLint) ctx->Light.Light[l].EyeDirection[0];
+         params[1] = (GLint) ctx->Light.Light[l].EyeDirection[1];
+         params[2] = (GLint) ctx->Light.Light[l].EyeDirection[2];
+         break;
+      case GL_SPOT_EXPONENT:
+         params[0] = (GLint) ctx->Light.Light[l].SpotExponent;
+         break;
+      case GL_SPOT_CUTOFF:
+         params[0] = (GLint) ctx->Light.Light[l].SpotCutoff;
+         break;
+      case GL_CONSTANT_ATTENUATION:
+         params[0] = (GLint) ctx->Light.Light[l].ConstantAttenuation;
+         break;
+      case GL_LINEAR_ATTENUATION:
+         params[0] = (GLint) ctx->Light.Light[l].LinearAttenuation;
+         break;
+      case GL_QUADRATIC_ATTENUATION:
+         params[0] = (GLint) ctx->Light.Light[l].QuadraticAttenuation;
+         break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glGetLightiv" );
+         break;
+   }
+}
+
+
+
+/**********************************************************************/
+/***                        Light Model                             ***/
+/**********************************************************************/
+
+
+void gl_LightModelfv( GLcontext *ctx, GLenum pname, const GLfloat *params )
+{
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLightModel");
+
+   switch (pname) {
+      case GL_LIGHT_MODEL_AMBIENT:
+         COPY_4V( ctx->Light.Model.Ambient, params );
+         break;
+      case GL_LIGHT_MODEL_LOCAL_VIEWER:
+         if (params[0]==0.0)
+            ctx->Light.Model.LocalViewer = GL_FALSE;
+         else
+            ctx->Light.Model.LocalViewer = GL_TRUE;
+         break;
+      case GL_LIGHT_MODEL_TWO_SIDE:
+         if (params[0]==0.0) 
+            ctx->Light.Model.TwoSide = GL_FALSE;
+         else
+            ctx->Light.Model.TwoSide = GL_TRUE;
+         break;
+      case GL_LIGHT_MODEL_COLOR_CONTROL:
+        ctx->TriangleCaps &= ~DD_SEPERATE_SPECULAR;
+         if (params[0] == (GLfloat) GL_SINGLE_COLOR) 
+            ctx->Light.Model.ColorControl = GL_SINGLE_COLOR;
+         else if (params[0] == (GLfloat) GL_SEPARATE_SPECULAR_COLOR) {
+            ctx->Light.Model.ColorControl = GL_SEPARATE_SPECULAR_COLOR;
+           ctx->TriangleCaps |= DD_SEPERATE_SPECULAR;
+        } else
+            gl_error( ctx, GL_INVALID_ENUM, "glLightModel(param)" );
+         break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glLightModel" );
+         break;
+   }
+   ctx->NewState |= NEW_LIGHTING;
+}
+
+
+
+
+/********** MATERIAL **********/
+
+
+/*
+ * Given a face and pname value (ala glColorMaterial), compute a bitmask
+ * of the targeted material values.
+ */
+GLuint gl_material_bitmask( GLcontext *ctx, GLenum face, GLenum pname, 
+                           GLuint legal,
+                           const char *where )
+{
+   GLuint bitmask = 0;
+
+   /* Make a bitmask indicating what material attribute(s) we're updating */
+   switch (pname) {
+      case GL_EMISSION:
+         bitmask |= FRONT_EMISSION_BIT | BACK_EMISSION_BIT;
+         break;
+      case GL_AMBIENT:
+         bitmask |= FRONT_AMBIENT_BIT | BACK_AMBIENT_BIT;
+         break;
+      case GL_DIFFUSE:
+         bitmask |= FRONT_DIFFUSE_BIT | BACK_DIFFUSE_BIT;
+         break;
+      case GL_SPECULAR:
+         bitmask |= FRONT_SPECULAR_BIT | BACK_SPECULAR_BIT;
+         break;
+      case GL_SHININESS:
+         bitmask |= FRONT_SHININESS_BIT | BACK_SHININESS_BIT;
+         break;
+      case GL_AMBIENT_AND_DIFFUSE:
+         bitmask |= FRONT_AMBIENT_BIT | BACK_AMBIENT_BIT;
+         bitmask |= FRONT_DIFFUSE_BIT | BACK_DIFFUSE_BIT;
+         break;
+      case GL_COLOR_INDEXES:
+         bitmask |= FRONT_INDEXES_BIT  | BACK_INDEXES_BIT;
+         break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, where );
+         return 0;
+   }
+
+   if (face==GL_FRONT) {
+      bitmask &= FRONT_MATERIAL_BITS;
+   }
+   else if (face==GL_BACK) {
+      bitmask &= BACK_MATERIAL_BITS;
+   }
+   else if (face != GL_FRONT_AND_BACK) {
+      gl_error( ctx, GL_INVALID_ENUM, where );
+      return 0;
+   }
+   
+   if (bitmask & ~legal) {
+      gl_error( ctx, GL_INVALID_ENUM, where );
+      return 0;
+   }
+
+   return bitmask;
+}
+
+
+
+
+
+
+/*
+ * Check if the global material has to be updated with info that was
+ * associated with a vertex via glMaterial.
+ * This function is used when any material values get changed between
+ * glBegin/glEnd either by calling glMaterial() or by calling glColor()
+ * when GL_COLOR_MATERIAL is enabled.
+ *
+ * KW: Added code here to keep the precomputed variables uptodate.
+ *     This means we can use the faster shade functions when using
+ *     GL_COLOR_MATERIAL, and we can also now use the precomputed 
+ *     values in the slower shading functions, which further offsets
+ *     the cost of doing this here.
+ */
+void gl_update_material( GLcontext *ctx, 
+                        struct gl_material *src, 
+                        GLuint bitmask )
+{
+   struct gl_light *light, *list = &ctx->Light.EnabledList;
+   GLfloat tmp[4];
+
+   if (ctx->Light.ColorMaterialEnabled)
+      bitmask &= ~ctx->Light.ColorMaterialBitmask;
+
+   if (!bitmask) 
+      return;
+
+   if (bitmask & FRONT_AMBIENT_BIT) {
+      struct gl_material *mat = &ctx->Light.Material[0];
+      SUB_3V( tmp, src[0].Ambient, mat->Ambient );
+      ACC_SCALE_3V( ctx->Light.BaseColor[0], ctx->Light.Model.Ambient, tmp);
+      foreach (light, list) {
+        ACC_SCALE_3V( ctx->Light.BaseColor[0], light->Ambient, tmp );
+      }
+      COPY_4FV( mat->Ambient, src[0].Ambient );
+   }
+   if (bitmask & BACK_AMBIENT_BIT) {
+      struct gl_material *mat = &ctx->Light.Material[1];
+      SUB_3V( tmp, src[1].Ambient, mat->Ambient );
+      ACC_SCALE_3V( ctx->Light.BaseColor[1], ctx->Light.Model.Ambient, tmp);
+      foreach (light, list) {
+        ACC_SCALE_3V( ctx->Light.BaseColor[0], light->Ambient, tmp );
+      }
+      COPY_4FV( mat->Ambient, src[1].Ambient );
+   }
+   if (bitmask & FRONT_DIFFUSE_BIT) {
+      struct gl_material *mat = &ctx->Light.Material[0];
+      SUB_3V( tmp, src[0].Diffuse, mat->Diffuse );
+      foreach (light, list) {
+        ACC_SCALE_3V( light->MatDiffuse[0], light->Diffuse, tmp );
+      }
+      COPY_4FV( mat->Diffuse, src[0].Diffuse );
+      FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Light.BaseAlpha[0], mat->Diffuse[3]);
+   }
+   if (bitmask & BACK_DIFFUSE_BIT) {
+      struct gl_material *mat = &ctx->Light.Material[1];
+      SUB_3V( tmp, src[1].Diffuse, mat->Diffuse );
+      foreach (light, list) {
+        ACC_SCALE_3V( light->MatDiffuse[1], light->Diffuse, tmp );
+      }
+      COPY_4FV( mat->Diffuse, src[1].Diffuse );
+      FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Light.BaseAlpha[1], mat->Diffuse[3]);
+   }
+   if (bitmask & FRONT_SPECULAR_BIT) {
+      struct gl_material *mat = &ctx->Light.Material[0];
+      SUB_3V( tmp, src[0].Specular, mat->Specular );
+      foreach (light, list) {
+        if (light->Flags & LIGHT_SPECULAR) {
+           ACC_SCALE_3V( light->MatSpecular[0], light->Specular, tmp );
+           light->IsMatSpecular[0] = 
+              (LEN_SQUARED_3FV(light->MatSpecular[0]) > 1e-16);
+        }
+      }
+      COPY_4FV( mat->Specular, src[0].Specular );
+   }
+   if (bitmask & BACK_SPECULAR_BIT) {
+      struct gl_material *mat = &ctx->Light.Material[1];
+      SUB_3V( tmp, src[1].Specular, mat->Specular );
+      foreach (light, list) {
+        if (light->Flags & LIGHT_SPECULAR) {
+           ACC_SCALE_3V( light->MatSpecular[1], light->Specular, tmp );
+           light->IsMatSpecular[1] = 
+              (LEN_SQUARED_3FV(light->MatSpecular[1]) > 1e-16);
+        }
+      }
+      COPY_4FV( mat->Specular, src[1].Specular );
+   }
+   if (bitmask & FRONT_EMISSION_BIT) {
+      struct gl_material *mat = &ctx->Light.Material[0];
+      SUB_3V( tmp, src[0].Emission, mat->Emission );
+      ACC_3V( ctx->Light.BaseColor[0], tmp );
+      COPY_4FV( mat->Emission, src[0].Emission );
+   }
+   if (bitmask & BACK_EMISSION_BIT) {
+      struct gl_material *mat = &ctx->Light.Material[1];
+      SUB_3V( tmp, src[1].Emission, mat->Emission );
+      ACC_3V( ctx->Light.BaseColor[1], tmp );
+      COPY_4FV( mat->Emission, src[1].Emission );
+   }
+   if (bitmask & FRONT_SHININESS_BIT) {
+      GLfloat shininess = ctx->Light.Material[0].Shininess = src[0].Shininess;
+      gl_compute_shine_table( ctx, 0, shininess );
+      gl_compute_shine_table( ctx, 2, shininess * .5 );
+   }
+   if (bitmask & BACK_SHININESS_BIT) {
+      GLfloat shininess = ctx->Light.Material[1].Shininess = src[1].Shininess;
+      gl_compute_shine_table( ctx, 1, shininess );
+      gl_compute_shine_table( ctx, 3, shininess * .5 );
+   }
+   if (bitmask & FRONT_INDEXES_BIT) {
+      ctx->Light.Material[0].AmbientIndex = src[0].AmbientIndex;
+      ctx->Light.Material[0].DiffuseIndex = src[0].DiffuseIndex;
+      ctx->Light.Material[0].SpecularIndex = src[0].SpecularIndex;
+   }
+   if (bitmask & BACK_INDEXES_BIT) {
+      ctx->Light.Material[1].AmbientIndex = src[1].AmbientIndex;
+      ctx->Light.Material[1].DiffuseIndex = src[1].DiffuseIndex;
+      ctx->Light.Material[1].SpecularIndex = src[1].SpecularIndex;
+   }
+
+}
+
+
+
+
+
+
+void gl_update_color_material( GLcontext *ctx, 
+                              const GLubyte rgba[4] )
+{
+   struct gl_light *light, *list = &ctx->Light.EnabledList;
+   GLuint bitmask = ctx->Light.ColorMaterialBitmask;
+   GLfloat tmp[4], color[4];
+
+   UBYTE_RGBA_TO_FLOAT_RGBA( color, rgba );
+   
+   if (bitmask & FRONT_AMBIENT_BIT) {
+      struct gl_material *mat = &ctx->Light.Material[0];
+      SUB_3V( tmp, color, mat->Ambient );
+      ACC_SCALE_3V( ctx->Light.BaseColor[0], ctx->Light.Model.Ambient, tmp);
+      foreach (light, list) {
+        ACC_SCALE_3V( ctx->Light.BaseColor[0], light->Ambient, tmp );
+      }
+      COPY_4FV( mat->Ambient, color );
+   }
+
+   if (bitmask & BACK_AMBIENT_BIT) {
+      struct gl_material *mat = &ctx->Light.Material[1];
+      SUB_3V( tmp, color, mat->Ambient );
+      ACC_SCALE_3V( ctx->Light.BaseColor[1], ctx->Light.Model.Ambient, tmp);
+      foreach (light, list) {
+        ACC_SCALE_3V( ctx->Light.BaseColor[0], light->Ambient, tmp );
+      }
+      COPY_4FV( mat->Ambient, color );
+   }
+
+   if (bitmask & FRONT_DIFFUSE_BIT) {
+      struct gl_material *mat = &ctx->Light.Material[0];
+      SUB_3V( tmp, color, mat->Diffuse );
+      foreach (light, list) {
+        ACC_SCALE_3V( light->MatDiffuse[0], light->Diffuse, tmp );
+      }
+      COPY_4FV( mat->Diffuse, color );
+      FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Light.BaseAlpha[0], mat->Diffuse[3]);
+   }
+
+   if (bitmask & BACK_DIFFUSE_BIT) {
+      struct gl_material *mat = &ctx->Light.Material[1];
+      SUB_3V( tmp, color, mat->Diffuse );
+      foreach (light, list) {
+        ACC_SCALE_3V( light->MatDiffuse[1], light->Diffuse, tmp );
+      }
+      COPY_4FV( mat->Diffuse, color );
+      FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Light.BaseAlpha[1], mat->Diffuse[3]);
+   }
+
+   if (bitmask & FRONT_SPECULAR_BIT) {
+      struct gl_material *mat = &ctx->Light.Material[0];
+      SUB_3V( tmp, color, mat->Specular );
+      foreach (light, list) {
+        if (light->Flags & LIGHT_SPECULAR) {
+           ACC_SCALE_3V( light->MatSpecular[0], light->Specular, tmp );
+           light->IsMatSpecular[0] = 
+              (LEN_SQUARED_3FV(light->MatSpecular[0]) > 1e-16);
+        }
+      }
+      COPY_4FV( mat->Specular, color );
+   }
+   if (bitmask & BACK_SPECULAR_BIT) {
+      struct gl_material *mat = &ctx->Light.Material[1];
+      SUB_3V( tmp, color, mat->Specular );
+      foreach (light, list) {
+        if (light->Flags & LIGHT_SPECULAR) {
+           ACC_SCALE_3V( light->MatSpecular[1], light->Specular, tmp );
+           light->IsMatSpecular[1] = 
+              (LEN_SQUARED_3FV(light->MatSpecular[1]) > 1e-16);
+        }
+      }
+      COPY_4FV( mat->Specular, color );
+   }
+   if (bitmask & FRONT_EMISSION_BIT) {
+      struct gl_material *mat = &ctx->Light.Material[0];
+      SUB_3V( tmp, color, mat->Emission );
+      ACC_3V( ctx->Light.BaseColor[0], tmp );
+      COPY_4FV( mat->Emission, color );
+   }
+   if (bitmask & BACK_EMISSION_BIT) {
+      struct gl_material *mat = &ctx->Light.Material[1];
+      SUB_3V( tmp, color, mat->Emission );
+      ACC_3V( ctx->Light.BaseColor[1], tmp );
+      COPY_4FV( mat->Emission, color );
+   }
+}
+
+
+
+
+void gl_ColorMaterial( GLcontext *ctx, GLenum face, GLenum mode )
+{
+   GLuint bitmask;
+   GLuint legal = (FRONT_EMISSION_BIT | BACK_EMISSION_BIT |
+                  FRONT_SPECULAR_BIT | BACK_SPECULAR_BIT |
+                  FRONT_DIFFUSE_BIT  | BACK_DIFFUSE_BIT  |
+                  FRONT_AMBIENT_BIT  | BACK_AMBIENT_BIT);
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glColorMaterial");
+
+   bitmask = gl_material_bitmask( ctx, face, mode, legal, "glColorMaterial" );
+
+   if (bitmask != 0) {
+      ctx->Light.ColorMaterialBitmask = bitmask;
+      ctx->Light.ColorMaterialFace = face;
+      ctx->Light.ColorMaterialMode = mode;
+   }
+}
+
+
+
+/* KW:  This is now called directly (ie by name) from the glMaterial* 
+ *      API functions.
+ */
+void gl_Materialfv( GLcontext *ctx,
+                    GLenum face, GLenum pname, const GLfloat *params )
+{
+   struct immediate *IM;
+   struct gl_material *mat;
+   GLuint bitmask;
+   GLuint count;
+
+   bitmask = gl_material_bitmask( ctx, face, pname, ~0, "gl_Materialfv" );
+   if (bitmask == 0)
+      return;
+
+   IM = ctx->input;
+   count = IM->Count;
+
+   if (!(IM->Flag[count] & VERT_MATERIAL)) {
+      IM->Flag[count] |= VERT_MATERIAL;
+      IM->MaterialMask[count] = 0;
+   }
+
+   IM->MaterialMask[count] |= bitmask;
+   mat = IM->Material[count];
+   IM->LastMaterial = count;
+
+   if (bitmask & FRONT_AMBIENT_BIT) {
+      COPY_4FV( mat[0].Ambient, params );
+   }
+   if (bitmask & BACK_AMBIENT_BIT) {
+      COPY_4FV( mat[1].Ambient, params );
+   }
+   if (bitmask & FRONT_DIFFUSE_BIT) {
+      COPY_4FV( mat[0].Diffuse, params );
+   }
+   if (bitmask & BACK_DIFFUSE_BIT) {
+      COPY_4FV( mat[1].Diffuse, params );
+   }
+   if (bitmask & FRONT_SPECULAR_BIT) {
+      COPY_4FV( mat[0].Specular, params );
+   }
+   if (bitmask & BACK_SPECULAR_BIT) {
+      COPY_4FV( mat[1].Specular, params );
+   }
+   if (bitmask & FRONT_EMISSION_BIT) {
+      COPY_4FV( mat[0].Emission, params );
+   }
+   if (bitmask & BACK_EMISSION_BIT) {
+      COPY_4FV( mat[1].Emission, params );
+   }
+   if (bitmask & FRONT_SHININESS_BIT) {
+      GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F );
+      mat[0].Shininess = shininess;
+   }
+   if (bitmask & BACK_SHININESS_BIT) {
+      GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F );
+      mat[1].Shininess = shininess;
+   }
+   if (bitmask & FRONT_INDEXES_BIT) {
+      mat[0].AmbientIndex = params[0];
+      mat[0].DiffuseIndex = params[1];
+      mat[0].SpecularIndex = params[2];
+   }
+   if (bitmask & BACK_INDEXES_BIT) {
+      mat[1].AmbientIndex = params[0];
+      mat[1].DiffuseIndex = params[1];
+      mat[1].SpecularIndex = params[2];
+   }
+}
+
+
+
+
+void gl_GetMaterialfv( GLcontext *ctx,
+                       GLenum face, GLenum pname, GLfloat *params )
+{
+   GLuint f;
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetMaterialfv");
+
+   if (face==GL_FRONT) {
+      f = 0;
+   }
+   else if (face==GL_BACK) {
+      f = 1;
+   }
+   else {
+      gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(face)" );
+      return;
+   }
+   switch (pname) {
+      case GL_AMBIENT:
+         COPY_4FV( params, ctx->Light.Material[f].Ambient );
+         break;
+      case GL_DIFFUSE:
+         COPY_4FV( params, ctx->Light.Material[f].Diffuse );
+        break;
+      case GL_SPECULAR:
+         COPY_4FV( params, ctx->Light.Material[f].Specular );
+        break;
+      case GL_EMISSION:
+        COPY_4FV( params, ctx->Light.Material[f].Emission );
+        break;
+      case GL_SHININESS:
+        *params = ctx->Light.Material[f].Shininess;
+        break;
+      case GL_COLOR_INDEXES:
+        params[0] = ctx->Light.Material[f].AmbientIndex;
+        params[1] = ctx->Light.Material[f].DiffuseIndex;
+        params[2] = ctx->Light.Material[f].SpecularIndex;
+        break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" );
+   }
+}
+
+
+
+void gl_GetMaterialiv( GLcontext *ctx,
+                       GLenum face, GLenum pname, GLint *params )
+{
+   GLuint f;
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetMaterialiv");
+
+   if (face==GL_FRONT) {
+      f = 0;
+   }
+   else if (face==GL_BACK) {
+      f = 1;
+   }
+   else {
+      gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialiv(face)" );
+      return;
+   }
+   switch (pname) {
+      case GL_AMBIENT:
+         params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[0] );
+         params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[1] );
+         params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[2] );
+         params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[3] );
+         break;
+      case GL_DIFFUSE:
+         params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[0] );
+         params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[1] );
+         params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[2] );
+         params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[3] );
+        break;
+      case GL_SPECULAR:
+         params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[0] );
+         params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[1] );
+         params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[2] );
+         params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[3] );
+        break;
+      case GL_EMISSION:
+         params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[0] );
+         params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[1] );
+         params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[2] );
+         params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[3] );
+        break;
+      case GL_SHININESS:
+         *params = ROUNDF( ctx->Light.Material[f].Shininess );
+        break;
+      case GL_COLOR_INDEXES:
+        params[0] = ROUNDF( ctx->Light.Material[f].AmbientIndex );
+        params[1] = ROUNDF( ctx->Light.Material[f].DiffuseIndex );
+        params[2] = ROUNDF( ctx->Light.Material[f].SpecularIndex );
+        break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" );
+   }
+}
+
+
+
+
+/**********************************************************************/
+/*****                  Lighting computation                      *****/
+/**********************************************************************/
+
+
+/*
+ * Notes:
+ *   When two-sided lighting is enabled we compute the color (or index)
+ *   for both the front and back side of the primitive.  Then, when the
+ *   orientation of the facet is later learned, we can determine which
+ *   color (or index) to use for rendering.
+ *
+ *   KW: We now know orientation in advance and only shade for 
+ *       the side or sides which are actually required.
+ *
+ * Variables:
+ *   n = normal vector
+ *   V = vertex position
+ *   P = light source position
+ *   Pe = (0,0,0,1)
+ *
+ * Precomputed:
+ *   IF P[3]==0 THEN
+ *       // light at infinity
+ *       IF local_viewer THEN
+ *           VP_inf_norm = unit vector from V to P      // Precompute
+ *       ELSE 
+ *           // eye at infinity
+ *           h_inf_norm = Normalize( VP + <0,0,1> )     // Precompute
+ *       ENDIF
+ *   ENDIF
+ *
+ * Functions:
+ *   Normalize( v ) = normalized vector v
+ *   Magnitude( v ) = length of vector v
+ */
+
+
+
+/*
+ * Whenever the spotlight exponent for a light changes we must call
+ * this function to recompute the exponent lookup table.
+ */
+void gl_compute_spot_exp_table( struct gl_light *l )
+{
+   int i;
+   double exponent = l->SpotExponent;
+   double tmp = 0;
+   int clamp = 0;
+
+   l->SpotExpTable[0][0] = 0.0;
+
+   for (i=EXP_TABLE_SIZE-1;i>0;i--) {
+      if (clamp == 0) {
+         tmp = pow(i/(double)(EXP_TABLE_SIZE-1), exponent);
+         if (tmp < FLT_MIN*100.0) {
+            tmp = 0.0;
+            clamp = 1;
+         }
+      }
+      l->SpotExpTable[i][0] = tmp;
+   }
+   for (i=0;i<EXP_TABLE_SIZE-1;i++) {
+      l->SpotExpTable[i][1] = l->SpotExpTable[i+1][0] - l->SpotExpTable[i][0];
+   }
+   l->SpotExpTable[EXP_TABLE_SIZE-1][1] = 0.0;
+}
+
+
+
+
+/* Calculate a new shine table.  Doing this here saves a branch in
+ * lighting, and the cost of doing it early may be partially offset
+ * by keeping a MRU cache of shine tables for various shine values.
+ */
+static void compute_shine_table( struct gl_shine_tab *tab, GLfloat shininess )
+{
+   int i;
+   GLfloat *m = tab->tab;
+
+   m[0] = 0;
+   if (shininess == 0) {
+      for (i = 1 ; i <= SHINE_TABLE_SIZE ; i++)
+        m[i] = 1;
+   } else {
+      for (i = 1 ; i <= SHINE_TABLE_SIZE ; i++) {
+        double t = pow( i/(GLfloat)SHINE_TABLE_SIZE, shininess );
+        m[i] = 0;
+        if (t > 1e-20) m[i] = t;
+      }      
+   }
+
+   tab->shininess = shininess;
+}
+
+#define DISTSQR(a,b) ((a-b)*(a-b))
+
+void gl_compute_shine_table( GLcontext *ctx, GLuint i, GLfloat shininess )
+{
+   struct gl_shine_tab *list = ctx->ShineTabList;
+   struct gl_shine_tab *s;
+
+   foreach(s, list) 
+      if ( DISTSQR(s->shininess, shininess) < 1e-4 ) 
+        break;
+
+   if (s == list) 
+   {
+      foreach(s, list) 
+        if (s->refcount == 0) break;
+
+      compute_shine_table( s, shininess );
+   }
+
+   ctx->ShineTable[i]->refcount--;
+   ctx->ShineTable[i] = s;
+   move_to_tail( list, s );
+   s->refcount++;
+}
+
+
+
+
+void gl_reinit_light_attrib( GLcontext *ctx, struct gl_light_attrib *l )
+{
+   GLuint i;
+
+   if (ctx->ShineTable[0]->shininess != l->Material[0].Shininess) {
+      gl_compute_shine_table( ctx, 0, l->Material[0].Shininess );
+      gl_compute_shine_table( ctx, 2, l->Material[0].Shininess * .5 );
+   }
+
+   if (ctx->ShineTable[1]->shininess != l->Material[1].Shininess) {
+      gl_compute_shine_table( ctx, 1, l->Material[1].Shininess );
+      gl_compute_shine_table( ctx, 3, l->Material[1].Shininess * .5 );
+   }
+
+   make_empty_list( &l->EnabledList );
+   for (i = 0 ; i < MAX_LIGHTS ; i++) {
+      if (l->Light[i].Enabled) 
+        insert_at_tail( &l->EnabledList, &l->Light[i] );
+   }
+}
+
+
+
+/*
+ * Examine current lighting parameters to determine if the optimized lighting
+ * function can be used.
+ * Also, precompute some lighting values such as the products of light
+ * source and material ambient, diffuse and specular coefficients.
+ */
+void gl_update_lighting( GLcontext *ctx )
+{
+   struct gl_light *light;
+
+   ctx->Light.Flags = 0;
+
+   foreach(light, &ctx->Light.EnabledList) {
+
+      light->Flags = 0;
+
+      if (light->EyePosition[3] != 0.0F) 
+        light->Flags |= LIGHT_POSITIONAL;
+      
+      if (LEN_SQUARED_3FV(light->Specular) > 1e-16) 
+        light->Flags |= LIGHT_SPECULAR;
+      
+      if (light->SpotCutoff != 180.0F)
+        light->Flags |= LIGHT_SPOT;
+
+      ctx->Light.Flags |= light->Flags;
+   }
+
+   ctx->Light.NeedVertices = 
+      ((ctx->Light.Flags & (LIGHT_POSITIONAL|LIGHT_SPOT)) ||
+       (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) ||
+       (ctx->Light.Model.LocalViewer && (ctx->Light.Flags & LIGHT_SPECULAR)));
+
+
+   /* Precompute some shading values.
+    */
+   if (ctx->Visual->RGBAflag) 
+   {
+      GLuint sides = ((ctx->TriangleCaps & DD_TRI_LIGHT_TWOSIDE) ? 2 : 1);
+      GLuint side;
+      for (side=0; side < sides; side++) {
+        struct gl_material *mat = &ctx->Light.Material[side];
+        
+        COPY_3V(ctx->Light.BaseColor[side], mat->Emission);
+        ACC_SCALE_3V(ctx->Light.BaseColor[side], 
+                     ctx->Light.Model.Ambient,
+                     mat->Ambient);
+
+        FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Light.BaseAlpha[side],
+                                   ctx->Light.Material[side].Diffuse[3] );
+      }
+      
+      foreach (light, &ctx->Light.EnabledList) {        
+        for (side=0; side< sides; side++) {
+           struct gl_material *mat = &ctx->Light.Material[side];
+           SCALE_3V( light->MatDiffuse[side],  light->Diffuse, mat->Diffuse );
+           SCALE_3V( light->MatAmbient[side],  light->Ambient, mat->Ambient );
+           ACC_3V( ctx->Light.BaseColor[side], light->MatAmbient[side] ); 
+           if (light->Flags & LIGHT_SPECULAR)
+           {
+              SCALE_3V( light->MatSpecular[side], light->Specular,
+                        mat->Specular);
+              light->IsMatSpecular[side] = 
+                 (LEN_SQUARED_3FV(light->MatSpecular[side]) > 1e-16);
+           } 
+           else 
+              light->IsMatSpecular[side] = 0;
+        }
+      }
+   } 
+   else
+   {
+      static GLfloat ci[3] = { .30, .59, .11 };
+
+      foreach(light, &ctx->Light.EnabledList) {
+        light->dli = DOT3(ci, light->Diffuse);
+        light->sli = DOT3(ci, light->Specular);
+      }
+   }
+}
+
+/* Need to seriously restrict the circumstances under which these
+ * calc's are performed.
+ */
+void gl_compute_light_positions( GLcontext *ctx )
+{
+   struct gl_light *light;
+   
+   if (ctx->Light.NeedVertices && !ctx->Light.Model.LocalViewer) {
+      GLfloat eye_z[3] = { 0, 0, 1 };
+      if (!ctx->NeedEyeCoords) {
+        TRANSFORM_NORMAL( ctx->EyeZDir, eye_z, ctx->ModelView.m );
+      } else {
+        COPY_3V( ctx->EyeZDir, eye_z );
+      }
+   }
+
+   foreach (light, &ctx->Light.EnabledList) {
+
+      if (!ctx->NeedEyeCoords) {
+        TRANSFORM_POINT( light->Position, ctx->ModelView.inv, 
+                         light->EyePosition );
+      } else {
+        COPY_4FV( light->Position, light->EyePosition );
+      }
+
+      if (!(light->Flags & LIGHT_POSITIONAL))
+      {
+        /* VP (VP) = Normalize( Position ) */
+        COPY_3V( light->VP_inf_norm, light->Position );
+        NORMALIZE_3FV( light->VP_inf_norm );
+
+        if (!ctx->Light.Model.LocalViewer)
+        {
+           /* h_inf_norm = Normalize( V_to_P + <0,0,1> ) */
+           ADD_3V( light->h_inf_norm, light->VP_inf_norm, ctx->EyeZDir);
+           NORMALIZE_3FV( light->h_inf_norm );
+        }
+
+        light->VP_inf_spot_attenuation = 1.0;
+      }
+      
+      if (light->Flags & LIGHT_SPOT) 
+      {
+        if (ctx->NeedEyeNormals) {
+           COPY_3V( light->NormDirection, light->EyeDirection );
+        } else {
+           TRANSFORM_NORMAL( light->NormDirection, 
+                             light->EyeDirection,
+                             ctx->ModelView.m);
+        }
+
+        NORMALIZE_3FV( light->NormDirection );
+
+
+        /* Unlikely occurrance?
+         */
+        if (!(light->Flags & LIGHT_POSITIONAL)) {
+           GLfloat PV_dot_dir = - DOT3(light->VP_inf_norm, 
+                                       light->NormDirection);
+
+           if (PV_dot_dir > light->CosCutoff) {
+              double x = PV_dot_dir * (EXP_TABLE_SIZE-1);
+              int k = (int) x;
+              light->VP_inf_spot_attenuation = 
+                 (light->SpotExpTable[k][0] + 
+                  (x-k)*light->SpotExpTable[k][1]);
+           }
+           else 
+              light->VP_inf_spot_attenuation = 0;
+        }
+      }
+   }
+}
+
+
+
+
+
+void gl_update_normal_transform( GLcontext *ctx )
+{
+   GLuint new_flag = 0;
+   normal_func *last = ctx->NormalTransform;
+   
+   ctx->vb_rescale_factor = 1.0;
+
+   if (ctx->NeedEyeCoords) {
+      if (ctx->NeedNormals) {
+        GLuint transform = NORM_TRANSFORM_NO_ROT;
+
+        if (ctx->ModelView.flags & (MAT_FLAG_GENERAL |
+                                    MAT_FLAG_ROTATION |
+                                    MAT_FLAG_GENERAL_3D |
+                                    MAT_FLAG_PERSPECTIVE)) 
+           transform = NORM_TRANSFORM;
+
+           
+        new_flag = ctx->NewState & NEW_MODELVIEW;
+        ctx->vb_rescale_factor = ctx->rescale_factor;
+              
+        if (ctx->Transform.Normalize) 
+        {
+           ctx->NormalTransform = gl_normal_tab[transform | NORM_NORMALIZE];
+        } 
+        else if (ctx->Transform.RescaleNormals &&
+                 ctx->rescale_factor != 1.0)
+        {
+           ctx->NormalTransform = gl_normal_tab[transform | NORM_RESCALE];
+        }
+        else 
+        {
+           ctx->NormalTransform = gl_normal_tab[transform];
+        }
+      } else {
+        ctx->NormalTransform = 0;
+      }
+   }
+   else {
+      if (ctx->NeedNormals) {
+        ctx->vb_rescale_factor = 1.0/ctx->rescale_factor;
+
+        if (ctx->Transform.Normalize) 
+        {
+           ctx->NormalTransform = gl_normal_tab[NORM_NORMALIZE];
+        }
+        else if (!ctx->Transform.RescaleNormals &&
+                 ctx->rescale_factor != 1.0)
+        {
+           ctx->NormalTransform = gl_normal_tab[NORM_RESCALE];
+        }
+        else
+        {
+           ctx->NormalTransform = 0;
+        }
+      } else {
+        ctx->NormalTransform = 0;
+      }
+   }
+
+   if (last != ctx->NormalTransform || new_flag)
+      ctx->NewState |= NEW_NORMAL_TRANSFORM;
+}
+
diff --git a/src/mesa/main/light.h b/src/mesa/main/light.h
new file mode 100644 (file)
index 0000000..18d25e9
--- /dev/null
@@ -0,0 +1,103 @@
+/* $Id: light.h,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+#ifndef LIGHT_H
+#define LIGHT_H
+
+
+#include "types.h"
+
+struct gl_shine_tab {
+   struct gl_shine_tab *next, *prev;
+   GLfloat tab[SHINE_TABLE_SIZE+1];
+   GLfloat shininess;
+   GLuint refcount;
+};
+
+
+extern void gl_ShadeModel( GLcontext *ctx, GLenum mode );
+
+extern void gl_ColorMaterial( GLcontext *ctx, GLenum face, GLenum mode );
+
+extern void gl_Lightfv( GLcontext *ctx,
+                        GLenum light, GLenum pname, const GLfloat *params,
+                        GLint nparams );
+
+extern void gl_LightModelfv( GLcontext *ctx,
+                             GLenum pname, const GLfloat *params );
+
+
+extern GLuint gl_material_bitmask( GLcontext *ctx, 
+                                  GLenum face, GLenum pname, 
+                                  GLuint legal,
+                                  const char * );
+
+extern void gl_set_material( GLcontext *ctx, GLuint bitmask,
+                             const GLfloat *params);
+
+extern void gl_Materialfv( GLcontext *ctx,
+                           GLenum face, GLenum pname, const GLfloat *params );
+
+
+
+extern void gl_GetLightfv( GLcontext *ctx,
+                           GLenum light, GLenum pname, GLfloat *params );
+
+extern void gl_GetLightiv( GLcontext *ctx,
+                           GLenum light, GLenum pname, GLint *params );
+
+
+extern void gl_GetMaterialfv( GLcontext *ctx,
+                              GLenum face, GLenum pname, GLfloat *params );
+
+extern void gl_GetMaterialiv( GLcontext *ctx,
+                              GLenum face, GLenum pname, GLint *params );
+
+
+extern void gl_compute_spot_exp_table( struct gl_light *l );
+
+extern void gl_compute_shine_table( GLcontext *ctx, GLuint i, 
+                                   GLfloat shininess );
+
+extern void gl_update_lighting( GLcontext *ctx );
+
+extern void gl_compute_light_positions( GLcontext *ctx );
+
+extern void gl_update_normal_transform( GLcontext *ctx );
+
+extern void gl_update_material( GLcontext *ctx, 
+                               struct gl_material *m, 
+                               GLuint bitmask );
+
+extern void gl_update_color_material( GLcontext *ctx, const GLubyte rgba[4] );
+
+
+#endif
+
diff --git a/src/mesa/main/lines.c b/src/mesa/main/lines.c
new file mode 100644 (file)
index 0000000..ed671d7
--- /dev/null
@@ -0,0 +1,1146 @@
+/* $Id: lines.c,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <assert.h>
+#include "context.h"
+#include "depth.h"
+#include "feedback.h"
+#include "lines.h"
+#include "macros.h"
+#include "mmath.h"
+#include "pb.h"
+#include "texstate.h"
+#include "types.h"
+#include "vb.h"
+#ifdef XFree86Server
+#include "GL/xf86glx.h"
+#endif
+#endif
+
+
+
+void gl_LineWidth( GLcontext *ctx, GLfloat width )
+{
+   if (width<=0.0) {
+      gl_error( ctx, GL_INVALID_VALUE, "glLineWidth" );
+      return;
+   }
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLineWidth");
+   
+   if (ctx->Line.Width != width) {
+      ctx->Line.Width = width;
+      ctx->TriangleCaps &= ~DD_LINE_WIDTH;
+      if (width != 1.0) ctx->TriangleCaps |= DD_LINE_WIDTH;
+      ctx->NewState |= NEW_RASTER_OPS;
+   }
+}
+
+
+
+void gl_LineStipple( GLcontext *ctx, GLint factor, GLushort pattern )
+{
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLineStipple");
+   ctx->Line.StippleFactor = CLAMP( factor, 1, 256 );
+   ctx->Line.StipplePattern = pattern;
+   ctx->NewState |= NEW_RASTER_OPS;
+}
+
+
+
+/**********************************************************************/
+/*****                    Rasterization                           *****/
+/**********************************************************************/
+
+
+/*
+ * There are 4 pairs (RGBA, CI) of line drawing functions:
+ *   1. simple:  width=1 and no special rasterization functions (fastest)
+ *   2. flat:  width=1, non-stippled, flat-shaded, any raster operations
+ *   3. smooth:  width=1, non-stippled, smooth-shaded, any raster operations
+ *   4. general:  any other kind of line (slowest)
+ */
+
+
+/*
+ * All line drawing functions have the same arguments:
+ * v1, v2 - indexes of first and second endpoints into vertex buffer arrays
+ * pv     - provoking vertex: which vertex color/index to use for flat shading.
+ */
+
+
+
+static void feedback_line( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv )
+{
+   struct vertex_buffer *VB = ctx->VB;
+   GLfloat x1, y1, z1, w1;
+   GLfloat x2, y2, z2, w2;
+   GLfloat tex1[4], tex2[4], invq;
+   GLuint texUnit = ctx->Texture.CurrentTransformUnit;
+
+   x1 = VB->Win.data[v1][0];
+   y1 = VB->Win.data[v1][1];
+   z1 = VB->Win.data[v1][2] / DEPTH_SCALE;
+   w1 = (VB->ClipPtr->size == 4 ? VEC_ELT(VB->ClipPtr, GLfloat, v1)[3] : 1.0);
+
+   x2 = VB->Win.data[v2][0];
+   y2 = VB->Win.data[v2][1];
+   z2 = VB->Win.data[v2][2] / DEPTH_SCALE;
+   w2 = (VB->ClipPtr->size == 4 ? VEC_ELT(VB->ClipPtr, GLfloat, v2)[3] : 1.0);
+
+
+   if (VB->TexCoordPtr[texUnit]->size == 4) {      
+      invq = (VB->TexCoordPtr[texUnit]->data[v1][3]==0.0
+             ? 1.0
+             : 1.0F / VB->TexCoordPtr[texUnit]->data[v1][3]);
+
+      tex1[0] = VB->TexCoordPtr[texUnit]->data[v1][0] * invq;
+      tex1[1] = VB->TexCoordPtr[texUnit]->data[v1][1] * invq;
+      tex1[2] = VB->TexCoordPtr[texUnit]->data[v1][2] * invq;
+      tex1[3] = VB->TexCoordPtr[texUnit]->data[v1][3];
+
+      invq = (VB->TexCoordPtr[texUnit]->data[v2][3]==0.0
+             ? 1.0
+             : 1.0F / VB->TexCoordPtr[texUnit]->data[v2][3]);
+
+      tex2[0] = VB->TexCoordPtr[texUnit]->data[v2][0] * invq;
+      tex2[1] = VB->TexCoordPtr[texUnit]->data[v2][1] * invq;
+      tex2[2] = VB->TexCoordPtr[texUnit]->data[v2][2] * invq;
+      tex2[3] = VB->TexCoordPtr[texUnit]->data[v2][3];
+   } else {
+      ASSIGN_4V(tex1, 0,0,0,1);
+      ASSIGN_4V(tex2, 0,0,0,1);
+      COPY_SZ_4V(tex1, 
+                VB->TexCoordPtr[texUnit]->size,
+                VB->TexCoordPtr[texUnit]->data[v1]);
+      COPY_SZ_4V(tex2, 
+                VB->TexCoordPtr[texUnit]->size,
+                VB->TexCoordPtr[texUnit]->data[v2]);
+   }
+
+
+   if (ctx->StippleCounter==0) {
+      FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_LINE_RESET_TOKEN );
+   }
+   else {
+      FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_LINE_TOKEN );
+   }
+
+   {
+      GLfloat color[4];
+      GLubyte *ubc = VB->ColorPtr->data[pv];
+      GLuint index = VB->IndexPtr->data[pv];
+
+      UBYTE_RGBA_TO_FLOAT_RGBA( color, ubc );
+      gl_feedback_vertex( ctx, x1,y1,z1,w1, color, (GLfloat) index, tex1 );
+      gl_feedback_vertex( ctx, x2,y2,z2,w2, color, (GLfloat) index, tex2 );
+   }
+
+   ctx->StippleCounter++;
+}
+
+
+
+static void select_line( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv )
+{
+   (void) pv;
+   gl_update_hitflag( ctx, ctx->VB->Win.data[v1][2] / DEPTH_SCALE );
+   gl_update_hitflag( ctx, ctx->VB->Win.data[v2][2] / DEPTH_SCALE );
+}
+
+
+
+#if MAX_WIDTH > MAX_HEIGHT
+#  define MAXPOINTS MAX_WIDTH
+#else
+#  define MAXPOINTS MAX_HEIGHT
+#endif
+
+
+/* Flat, color index line */
+static void flat_ci_line( GLcontext *ctx,
+                          GLuint vert0, GLuint vert1, GLuint pvert )
+{
+   GLint count;
+   GLint *pbx = ctx->PB->x;
+   GLint *pby = ctx->PB->y;
+   PB_SET_INDEX( ctx, ctx->PB, ctx->VB->IndexPtr->data[pvert] );
+   count = ctx->PB->count;
+
+#define INTERP_XY 1
+
+#define PLOT(X,Y)              \
+       pbx[count] = X;         \
+       pby[count] = Y;         \
+       count++;
+
+#include "linetemp.h"
+
+   ctx->PB->count = count;
+   PB_CHECK_FLUSH( ctx, ctx->PB );
+}
+
+
+
+/* Flat, color index line with Z interpolation/testing */
+static void flat_ci_z_line( GLcontext *ctx,
+                            GLuint vert0, GLuint vert1, GLuint pvert )
+{
+   GLint count;
+   GLint *pbx = ctx->PB->x;
+   GLint *pby = ctx->PB->y;
+   GLdepth *pbz = ctx->PB->z;
+   PB_SET_INDEX( ctx, ctx->PB, ctx->VB->IndexPtr->data[pvert] );
+   count = ctx->PB->count;
+
+#define INTERP_XY 1
+#define INTERP_Z 1
+
+#define PLOT(X,Y)              \
+       pbx[count] = X;         \
+       pby[count] = Y;         \
+       pbz[count] = Z;         \
+       count++;
+
+#include "linetemp.h"
+
+   ctx->PB->count = count;
+   PB_CHECK_FLUSH( ctx, ctx->PB );
+}
+
+
+
+/* Flat-shaded, RGBA line */
+static void flat_rgba_line( GLcontext *ctx,
+                            GLuint vert0, GLuint vert1, GLuint pvert )
+{
+   GLint count;
+   GLint *pbx = ctx->PB->x;
+   GLint *pby = ctx->PB->y;
+   GLubyte *color = ctx->VB->ColorPtr->data[pvert];
+   PB_SET_COLOR( ctx, ctx->PB, color[0], color[1], color[2], color[3] );
+   count = ctx->PB->count;
+
+#define INTERP_XY 1
+
+#define PLOT(X,Y)              \
+       pbx[count] = X;         \
+       pby[count] = Y;         \
+       count++;
+
+#include "linetemp.h"
+
+   ctx->PB->count = count;
+   PB_CHECK_FLUSH( ctx, ctx->PB );
+}
+
+
+
+/* Flat-shaded, RGBA line with Z interpolation/testing */
+static void flat_rgba_z_line( GLcontext *ctx,
+                              GLuint vert0, GLuint vert1, GLuint pvert )
+{
+   GLint count;
+   GLint *pbx = ctx->PB->x;
+   GLint *pby = ctx->PB->y;
+   GLdepth *pbz = ctx->PB->z;
+   GLubyte *color = ctx->VB->ColorPtr->data[pvert];
+   PB_SET_COLOR( ctx, ctx->PB, color[0], color[1], color[2], color[3] );
+   count = ctx->PB->count;
+
+#define INTERP_XY 1
+#define INTERP_Z 1
+
+#define PLOT(X,Y)      \
+       pbx[count] = X; \
+       pby[count] = Y; \
+       pbz[count] = Z; \
+       count++;
+
+#include "linetemp.h"
+
+   ctx->PB->count = count;
+   PB_CHECK_FLUSH( ctx, ctx->PB );
+}
+
+
+
+/* Smooth shaded, color index line */
+static void smooth_ci_line( GLcontext *ctx,
+                            GLuint vert0, GLuint vert1, GLuint pvert )
+{
+   GLint count = ctx->PB->count;
+   GLint *pbx = ctx->PB->x;
+   GLint *pby = ctx->PB->y;
+   GLuint *pbi = ctx->PB->i;
+   (void) pvert;
+
+#define INTERP_XY 1
+#define INTERP_INDEX 1
+
+#define PLOT(X,Y)              \
+       pbx[count] = X;         \
+       pby[count] = Y;         \
+       pbi[count] = I;         \
+       count++;
+
+#include "linetemp.h"
+
+   ctx->PB->count = count;
+   PB_CHECK_FLUSH( ctx, ctx->PB );
+}
+
+
+
+/* Smooth shaded, color index line with Z interpolation/testing */
+static void smooth_ci_z_line( GLcontext *ctx,
+                              GLuint vert0, GLuint vert1, GLuint pvert )
+{
+   GLint count = ctx->PB->count;
+   GLint *pbx = ctx->PB->x;
+   GLint *pby = ctx->PB->y;
+   GLdepth *pbz = ctx->PB->z;
+   GLuint *pbi = ctx->PB->i;
+   (void) pvert;
+
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define INTERP_INDEX 1
+
+#define PLOT(X,Y)              \
+       pbx[count] = X;         \
+       pby[count] = Y;         \
+       pbz[count] = Z;         \
+       pbi[count] = I;         \
+       count++;
+
+#include "linetemp.h"
+
+   ctx->PB->count = count;
+   PB_CHECK_FLUSH( ctx, ctx->PB );
+}
+
+
+
+/* Smooth-shaded, RGBA line */
+static void smooth_rgba_line( GLcontext *ctx,
+                                     GLuint vert0, GLuint vert1, GLuint pvert )
+{
+   GLint count = ctx->PB->count;
+   GLint *pbx = ctx->PB->x;
+   GLint *pby = ctx->PB->y;
+   GLubyte (*pbrgba)[4] = ctx->PB->rgba;
+   (void) pvert;
+
+#define INTERP_XY 1
+#define INTERP_RGB 1
+#define INTERP_ALPHA 1
+
+#define PLOT(X,Y)                      \
+       pbx[count] = X;                 \
+       pby[count] = Y;                 \
+       pbrgba[count][RCOMP] = FixedToInt(r0);  \
+       pbrgba[count][GCOMP] = FixedToInt(g0);  \
+       pbrgba[count][BCOMP] = FixedToInt(b0);  \
+       pbrgba[count][ACOMP] = FixedToInt(a0);  \
+       count++;
+
+#include "linetemp.h"
+
+   ctx->PB->count = count;
+   PB_CHECK_FLUSH( ctx, ctx->PB );
+}
+
+
+
+/* Smooth-shaded, RGBA line with Z interpolation/testing */
+static void smooth_rgba_z_line( GLcontext *ctx,
+                                       GLuint vert0, GLuint vert1, GLuint pvert )
+{
+   GLint count = ctx->PB->count;
+   GLint *pbx = ctx->PB->x;
+   GLint *pby = ctx->PB->y;
+   GLdepth *pbz = ctx->PB->z;
+   GLubyte (*pbrgba)[4] = ctx->PB->rgba;
+   (void) pvert;
+
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define INTERP_RGB 1
+#define INTERP_ALPHA 1
+
+#define PLOT(X,Y)                      \
+       pbx[count] = X;                 \
+       pby[count] = Y;                 \
+       pbz[count] = Z;                 \
+       pbrgba[count][RCOMP] = FixedToInt(r0);  \
+       pbrgba[count][GCOMP] = FixedToInt(g0);  \
+       pbrgba[count][BCOMP] = FixedToInt(b0);  \
+       pbrgba[count][ACOMP] = FixedToInt(a0);  \
+       count++;
+
+#include "linetemp.h"
+
+   ctx->PB->count = count;
+   PB_CHECK_FLUSH( ctx, ctx->PB );
+}
+
+
+#define CHECK_FULL(count)                      \
+       if (count >= PB_SIZE-MAX_WIDTH) {       \
+          ctx->PB->count = count;              \
+          gl_flush_pb(ctx);                    \
+          count = ctx->PB->count;              \
+       }
+
+
+
+/* Smooth shaded, color index, any width, maybe stippled */
+static void general_smooth_ci_line( GLcontext *ctx,
+                                   GLuint vert0, GLuint vert1, GLuint pvert )
+{
+   GLint count = ctx->PB->count;
+   GLint *pbx = ctx->PB->x;
+   GLint *pby = ctx->PB->y;
+   GLdepth *pbz = ctx->PB->z;
+   GLuint *pbi = ctx->PB->i;
+   (void) pvert;
+
+   if (ctx->Line.StippleFlag) {
+      /* stippled */
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define INTERP_INDEX 1
+#define WIDE 1
+#define STIPPLE 1
+#define PLOT(X,Y)              \
+       pbx[count] = X;         \
+       pby[count] = Y;         \
+       pbz[count] = Z;         \
+       pbi[count] = I;         \
+       count++;                \
+       CHECK_FULL(count);
+#include "linetemp.h"
+   }
+   else {
+      /* unstippled */
+      if (ctx->Line.Width==2.0F) {
+         /* special case: unstippled and width=2 */
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define INTERP_INDEX 1
+#define XMAJOR_PLOT(X,Y)                       \
+       pbx[count] = X;  pbx[count+1] = X;      \
+       pby[count] = Y;  pby[count+1] = Y+1;    \
+       pbz[count] = Z;  pbz[count+1] = Z;      \
+       pbi[count] = I;  pbi[count+1] = I;      \
+       count += 2;                             \
+       CHECK_FULL(count);
+#define YMAJOR_PLOT(X,Y)                       \
+       pbx[count] = X;  pbx[count+1] = X+1;    \
+       pby[count] = Y;  pby[count+1] = Y;      \
+       pbz[count] = Z;  pbz[count+1] = Z;      \
+       pbi[count] = I;  pbi[count+1] = I;      \
+       count += 2;                             \
+       CHECK_FULL(count);
+#include "linetemp.h"
+      }
+      else {
+         /* unstippled, any width */
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define INTERP_INDEX 1
+#define WIDE 1
+#define PLOT(X,Y)              \
+       pbx[count] = X;         \
+       pby[count] = Y;         \
+       pbz[count] = Z;         \
+       pbi[count] = I;         \
+       count++;                \
+       CHECK_FULL(count);
+#include "linetemp.h"
+      }
+   }
+
+   ctx->PB->count = count;
+   PB_CHECK_FLUSH( ctx, ctx->PB );
+}
+
+
+/* Flat shaded, color index, any width, maybe stippled */
+static void general_flat_ci_line( GLcontext *ctx,
+                                  GLuint vert0, GLuint vert1, GLuint pvert )
+{
+   GLint count;
+   GLint *pbx = ctx->PB->x;
+   GLint *pby = ctx->PB->y;
+   GLdepth *pbz = ctx->PB->z;
+   PB_SET_INDEX( ctx, ctx->PB, ctx->VB->IndexPtr->data[pvert] );
+   count = ctx->PB->count;
+
+   if (ctx->Line.StippleFlag) {
+      /* stippled, any width */
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define WIDE 1
+#define STIPPLE 1
+#define PLOT(X,Y)              \
+       pbx[count] = X;         \
+       pby[count] = Y;         \
+       pbz[count] = Z;         \
+       count++;                \
+       CHECK_FULL(count);
+#include "linetemp.h"
+   }
+   else {
+      /* unstippled */
+      if (ctx->Line.Width==2.0F) {
+         /* special case: unstippled and width=2 */
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define XMAJOR_PLOT(X,Y)                       \
+       pbx[count] = X;  pbx[count+1] = X;      \
+       pby[count] = Y;  pby[count+1] = Y+1;    \
+       pbz[count] = Z;  pbz[count+1] = Z;      \
+       count += 2;                             \
+       CHECK_FULL(count);
+#define YMAJOR_PLOT(X,Y)                       \
+       pbx[count] = X;  pbx[count+1] = X+1;    \
+       pby[count] = Y;  pby[count+1] = Y;      \
+       pbz[count] = Z;  pbz[count+1] = Z;      \
+       count += 2;                             \
+       CHECK_FULL(count);
+#include "linetemp.h"
+      }
+      else {
+         /* unstippled, any width */
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define WIDE 1
+#define PLOT(X,Y)              \
+       pbx[count] = X;         \
+       pby[count] = Y;         \
+       pbz[count] = Z;         \
+       count++;                \
+       CHECK_FULL(count);
+#include "linetemp.h"
+      }
+   }
+
+   ctx->PB->count = count;
+   PB_CHECK_FLUSH( ctx, ctx->PB );
+}
+
+
+
+static void general_smooth_rgba_line( GLcontext *ctx,
+                                      GLuint vert0, GLuint vert1, GLuint pvert)
+{
+   GLint count = ctx->PB->count;
+   GLint *pbx = ctx->PB->x;
+   GLint *pby = ctx->PB->y;
+   GLdepth *pbz = ctx->PB->z;
+   GLubyte (*pbrgba)[4] = ctx->PB->rgba;
+   (void) pvert;
+
+   if (ctx->Line.StippleFlag) {
+      /* stippled */
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define INTERP_RGB 1
+#define INTERP_ALPHA 1
+#define WIDE 1
+#define STIPPLE 1
+#define PLOT(X,Y)                              \
+       pbx[count] = X;                         \
+       pby[count] = Y;                         \
+       pbz[count] = Z;                         \
+       pbrgba[count][RCOMP] = FixedToInt(r0);  \
+       pbrgba[count][GCOMP] = FixedToInt(g0);  \
+       pbrgba[count][BCOMP] = FixedToInt(b0);  \
+       pbrgba[count][ACOMP] = FixedToInt(a0);  \
+       count++;                                \
+       CHECK_FULL(count);
+#include "linetemp.h"
+   }
+   else {
+      /* unstippled */
+      if (ctx->Line.Width==2.0F) {
+         /* special case: unstippled and width=2 */
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define INTERP_RGB 1
+#define INTERP_ALPHA 1
+#define XMAJOR_PLOT(X,Y)                               \
+       pbx[count] = X;  pbx[count+1] = X;              \
+       pby[count] = Y;  pby[count+1] = Y+1;            \
+       pbz[count] = Z;  pbz[count+1] = Z;              \
+       pbrgba[count][RCOMP] = FixedToInt(r0);          \
+       pbrgba[count][GCOMP] = FixedToInt(g0);          \
+       pbrgba[count][BCOMP] = FixedToInt(b0);          \
+       pbrgba[count][ACOMP] = FixedToInt(a0);          \
+       pbrgba[count+1][RCOMP] = FixedToInt(r0);        \
+       pbrgba[count+1][GCOMP] = FixedToInt(g0);        \
+       pbrgba[count+1][BCOMP] = FixedToInt(b0);        \
+       pbrgba[count+1][ACOMP] = FixedToInt(a0);        \
+       count += 2;                                     \
+       CHECK_FULL(count);
+#define YMAJOR_PLOT(X,Y)                               \
+       pbx[count] = X;  pbx[count+1] = X+1;            \
+       pby[count] = Y;  pby[count+1] = Y;              \
+       pbz[count] = Z;  pbz[count+1] = Z;              \
+       pbrgba[count][RCOMP] = FixedToInt(r0);          \
+       pbrgba[count][GCOMP] = FixedToInt(g0);          \
+       pbrgba[count][BCOMP] = FixedToInt(b0);          \
+       pbrgba[count][ACOMP] = FixedToInt(a0);          \
+       pbrgba[count+1][RCOMP] = FixedToInt(r0);        \
+       pbrgba[count+1][GCOMP] = FixedToInt(g0);        \
+       pbrgba[count+1][BCOMP] = FixedToInt(b0);        \
+       pbrgba[count+1][ACOMP] = FixedToInt(a0);        \
+       count += 2;                                     \
+       CHECK_FULL(count);
+#include "linetemp.h"
+      }
+      else {
+         /* unstippled, any width */
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define INTERP_RGB 1
+#define INTERP_ALPHA 1
+#define WIDE 1
+#define PLOT(X,Y)                              \
+       pbx[count] = X;                         \
+       pby[count] = Y;                         \
+       pbz[count] = Z;                         \
+       pbrgba[count][RCOMP] = FixedToInt(r0);  \
+       pbrgba[count][GCOMP] = FixedToInt(g0);  \
+       pbrgba[count][BCOMP] = FixedToInt(b0);  \
+       pbrgba[count][ACOMP] = FixedToInt(a0);  \
+       count++;                                \
+       CHECK_FULL(count);
+#include "linetemp.h"
+      }
+   }
+
+   ctx->PB->count = count;
+   PB_CHECK_FLUSH( ctx, ctx->PB );
+}
+
+
+static void general_flat_rgba_line( GLcontext *ctx,
+                                    GLuint vert0, GLuint vert1, GLuint pvert )
+{
+   GLint count;
+   GLint *pbx = ctx->PB->x;
+   GLint *pby = ctx->PB->y;
+   GLdepth *pbz = ctx->PB->z;
+   GLubyte *color = ctx->VB->ColorPtr->data[pvert];
+   PB_SET_COLOR( ctx, ctx->PB, color[0], color[1], color[2], color[3] );
+   count = ctx->PB->count;
+
+   if (ctx->Line.StippleFlag) {
+      /* stippled */
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define WIDE 1
+#define STIPPLE 1
+#define PLOT(X,Y)                      \
+       pbx[count] = X;                 \
+       pby[count] = Y;                 \
+       pbz[count] = Z;                 \
+       count++;                        \
+       CHECK_FULL(count);
+#include "linetemp.h"
+   }
+   else {
+      /* unstippled */
+      if (ctx->Line.Width==2.0F) {
+         /* special case: unstippled and width=2 */
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define XMAJOR_PLOT(X,Y)                       \
+       pbx[count] = X;  pbx[count+1] = X;      \
+       pby[count] = Y;  pby[count+1] = Y+1;    \
+       pbz[count] = Z;  pbz[count+1] = Z;      \
+       count += 2;                             \
+       CHECK_FULL(count);
+#define YMAJOR_PLOT(X,Y)                       \
+       pbx[count] = X;  pbx[count+1] = X+1;    \
+       pby[count] = Y;  pby[count+1] = Y;      \
+       pbz[count] = Z;  pbz[count+1] = Z;      \
+       count += 2;                             \
+       CHECK_FULL(count);
+#include "linetemp.h"
+      }
+      else {
+         /* unstippled, any width */
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define WIDE 1
+#define PLOT(X,Y)                      \
+       pbx[count] = X;                 \
+       pby[count] = Y;                 \
+       pbz[count] = Z;                 \
+       count++;                        \
+       CHECK_FULL(count);
+#include "linetemp.h"
+      }
+   }
+
+   ctx->PB->count = count;
+   PB_CHECK_FLUSH( ctx, ctx->PB );
+}
+
+
+/* Flat-shaded, textured, any width, maybe stippled */
+static void flat_textured_line( GLcontext *ctx,
+                                GLuint vert0, GLuint vert1, GLuint pv )
+{
+   GLint count;
+   GLint *pbx = ctx->PB->x;
+   GLint *pby = ctx->PB->y;
+   GLdepth *pbz = ctx->PB->z;
+   GLfloat *pbs = ctx->PB->s[0];
+   GLfloat *pbt = ctx->PB->t[0];
+   GLfloat *pbu = ctx->PB->u[0];
+   GLubyte *color = ctx->VB->ColorPtr->data[pv];
+   PB_SET_COLOR( ctx, ctx->PB, color[0], color[1], color[2], color[3] );
+   count = ctx->PB->count;
+
+   if (ctx->Line.StippleFlag) {
+      /* stippled */
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define INTERP_STUV0 1
+#define WIDE 1
+#define STIPPLE 1
+#define PLOT(X,Y)                      \
+       {                               \
+          pbx[count] = X;              \
+          pby[count] = Y;              \
+          pbz[count] = Z;              \
+          pbs[count] = s;              \
+          pbt[count] = t;              \
+          pbu[count] = u;              \
+          count++;                     \
+          CHECK_FULL(count);           \
+       }
+#include "linetemp.h"
+   }
+   else {
+      /* unstippled */
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define INTERP_STUV0 1
+#define WIDE 1
+#define PLOT(X,Y)                      \
+       {                               \
+          pbx[count] = X;              \
+          pby[count] = Y;              \
+          pbz[count] = Z;              \
+          pbs[count] = s;              \
+          pbt[count] = t;              \
+          pbu[count] = u;              \
+          count++;                     \
+          CHECK_FULL(count);           \
+       }
+#include "linetemp.h"
+   }
+
+   ctx->PB->count = count;
+   PB_CHECK_FLUSH( ctx, ctx->PB );
+}
+
+
+
+/* Smooth-shaded, textured, any width, maybe stippled */
+static void smooth_textured_line( GLcontext *ctx,
+                                  GLuint vert0, GLuint vert1, GLuint pvert )
+{
+   GLint count = ctx->PB->count;
+   GLint *pbx = ctx->PB->x;
+   GLint *pby = ctx->PB->y;
+   GLdepth *pbz = ctx->PB->z;
+   GLfloat *pbs = ctx->PB->s[0];
+   GLfloat *pbt = ctx->PB->t[0];
+   GLfloat *pbu = ctx->PB->u[0];
+   GLubyte (*pbrgba)[4] = ctx->PB->rgba;
+   (void) pvert;
+
+   if (ctx->Line.StippleFlag) {
+      /* stippled */
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define INTERP_RGB 1
+#define INTERP_ALPHA 1
+#define INTERP_STUV0 1
+#define WIDE 1
+#define STIPPLE 1
+#define PLOT(X,Y)                                      \
+       {                                               \
+          pbx[count] = X;                              \
+          pby[count] = Y;                              \
+          pbz[count] = Z;                              \
+          pbs[count] = s;                              \
+          pbt[count] = t;                              \
+          pbu[count] = u;                              \
+          pbrgba[count][RCOMP] = FixedToInt(r0);       \
+          pbrgba[count][GCOMP] = FixedToInt(g0);       \
+          pbrgba[count][BCOMP] = FixedToInt(b0);       \
+          pbrgba[count][ACOMP] = FixedToInt(a0);       \
+          count++;                                     \
+          CHECK_FULL(count);                           \
+       }
+#include "linetemp.h"
+   }
+   else {
+      /* unstippled */
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define INTERP_RGB 1
+#define INTERP_ALPHA 1
+#define INTERP_STUV0 1
+#define WIDE 1
+#define PLOT(X,Y)                                      \
+       {                                               \
+          pbx[count] = X;                              \
+          pby[count] = Y;                              \
+          pbz[count] = Z;                              \
+          pbs[count] = s;                              \
+          pbt[count] = t;                              \
+          pbu[count] = u;                              \
+          pbrgba[count][RCOMP] = FixedToInt(r0);       \
+          pbrgba[count][GCOMP] = FixedToInt(g0);       \
+          pbrgba[count][BCOMP] = FixedToInt(b0);       \
+          pbrgba[count][ACOMP] = FixedToInt(a0);       \
+          count++;                                     \
+          CHECK_FULL(count);                           \
+       }
+#include "linetemp.h"
+   }
+
+   ctx->PB->count = count;
+   PB_CHECK_FLUSH( ctx, ctx->PB );
+}
+
+
+/* Smooth-shaded, multitextured, any width, maybe stippled, separate specular
+ * color interpolation.
+ */
+static void smooth_multitextured_line( GLcontext *ctx,
+                                   GLuint vert0, GLuint vert1, GLuint pvert )
+{
+   GLint count = ctx->PB->count;
+   GLint *pbx = ctx->PB->x;
+   GLint *pby = ctx->PB->y;
+   GLdepth *pbz = ctx->PB->z;
+   GLfloat *pbs = ctx->PB->s[0];
+   GLfloat *pbt = ctx->PB->t[0];
+   GLfloat *pbu = ctx->PB->u[0];
+   GLfloat *pbs1 = ctx->PB->s[1];
+   GLfloat *pbt1 = ctx->PB->t[1];
+   GLfloat *pbu1 = ctx->PB->u[1];
+   GLubyte (*pbrgba)[4] = ctx->PB->rgba;
+   GLubyte (*pbspec)[3] = ctx->PB->spec;
+   (void) pvert;
+
+   if (ctx->Line.StippleFlag) {
+      /* stippled */
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define INTERP_RGB 1
+#define INTERP_SPEC 1
+#define INTERP_ALPHA 1
+#define INTERP_STUV0 1
+#define INTERP_STUV1 1
+#define WIDE 1
+#define STIPPLE 1
+#define PLOT(X,Y)                                      \
+       {                                               \
+          pbx[count] = X;                              \
+          pby[count] = Y;                              \
+          pbz[count] = Z;                              \
+          pbs[count] = s;                              \
+          pbt[count] = t;                              \
+          pbu[count] = u;                              \
+          pbs1[count] = s1;                            \
+          pbt1[count] = t1;                            \
+          pbu1[count] = u1;                            \
+          pbrgba[count][RCOMP] = FixedToInt(r0);       \
+          pbrgba[count][GCOMP] = FixedToInt(g0);       \
+          pbrgba[count][BCOMP] = FixedToInt(b0);       \
+          pbrgba[count][ACOMP] = FixedToInt(a0);       \
+          pbspec[count][RCOMP] = FixedToInt(sr0);      \
+          pbspec[count][GCOMP] = FixedToInt(sg0);      \
+          pbspec[count][BCOMP] = FixedToInt(sb0);      \
+          count++;                                     \
+          CHECK_FULL(count);                           \
+       }
+#include "linetemp.h"
+   }
+   else {
+      /* unstippled */
+#define INTERP_XY 1
+#define INTERP_Z 1
+#define INTERP_RGB 1
+#define INTERP_SPEC 1
+#define INTERP_ALPHA 1
+#define INTERP_STUV0 1
+#define INTERP_STUV1 1
+#define WIDE 1
+#define PLOT(X,Y)                                      \
+       {                                               \
+          pbx[count] = X;                              \
+          pby[count] = Y;                              \
+          pbz[count] = Z;                              \
+          pbs[count] = s;                              \
+          pbt[count] = t;                              \
+          pbu[count] = u;                              \
+          pbs1[count] = s1;                            \
+          pbt1[count] = t1;                            \
+          pbu1[count] = u1;                            \
+          pbrgba[count][RCOMP] = FixedToInt(r0);       \
+          pbrgba[count][GCOMP] = FixedToInt(g0);       \
+          pbrgba[count][BCOMP] = FixedToInt(b0);       \
+          pbrgba[count][ACOMP] = FixedToInt(a0);       \
+          pbspec[count][RCOMP] = FixedToInt(sr0);      \
+          pbspec[count][GCOMP] = FixedToInt(sg0);      \
+          pbspec[count][BCOMP] = FixedToInt(sb0);      \
+          count++;                                     \
+          CHECK_FULL(count);                           \
+       }
+#include "linetemp.h"
+   }
+
+   ctx->PB->count = count;
+   PB_CHECK_FLUSH( ctx, ctx->PB );
+}
+
+
+/*
+ * Antialiased RGBA line
+ *
+ * This AA line function isn't terribly efficient but it's pretty
+ * straight-forward to understand.  Also, it doesn't exactly conform
+ * to the specification.
+ */
+static void aa_rgba_line( GLcontext *ctx,
+                          GLuint vert0, GLuint vert1, GLuint pvert )
+{
+#define INTERP_RGBA 1
+#define PLOT(x, y)  { PB_WRITE_RGBA_PIXEL( pb, (x), (y), z, red, green, blue, coverage ); }
+#include "lnaatemp.h"
+}
+
+/*
+ * Antialiased Textured RGBA line
+ *
+ * This AA line function isn't terribly efficient but it's pretty
+ * straight-forward to understand.  Also, it doesn't exactly conform
+ * to the specification.
+ */
+static void aa_tex_rgba_line( GLcontext *ctx,
+                              GLuint vert0, GLuint vert1, GLuint pvert )
+{
+#define INTERP_RGBA 1
+#define INTERP_STUV0 1
+#define PLOT(x, y)                                                     \
+   {                                                                   \
+      PB_WRITE_TEX_PIXEL( pb, (x), (y), z, red, green, blue, coverage, \
+                          s, t, u );                                   \
+   }
+#include "lnaatemp.h"
+}
+
+
+/*
+ * Antialiased Multitextured RGBA line
+ *
+ * This AA line function isn't terribly efficient but it's pretty
+ * straight-forward to understand.  Also, it doesn't exactly conform
+ * to the specification.
+ */
+static void aa_multitex_rgba_line( GLcontext *ctx,
+                                   GLuint vert0, GLuint vert1, GLuint pvert )
+{
+#define INTERP_RGBA 1
+#define INTERP_SPEC 1
+#define INTERP_STUV0 1
+#define INTERP_STUV1 1
+#define PLOT(x, y)                                                     \
+   {                                                                   \
+      PB_WRITE_MULTITEX_SPEC_PIXEL( pb, (x), (y), z,                   \
+            red, green, blue, coverage, specRed, specGreen, specBlue,  \
+            s, t, u, s1, t1, u1 );                                     \
+   }
+#include "lnaatemp.h"
+}
+
+
+/*
+ * Antialiased CI line.  Same comments for RGBA antialiased lines apply.
+ */
+static void aa_ci_line( GLcontext *ctx,
+                        GLuint vert0, GLuint vert1, GLuint pvert )
+{
+#define INTERP_INDEX 1
+#define PLOT(x, y)                                             \
+   {                                                           \
+      PB_WRITE_CI_PIXEL( pb, (x), (y), z, index + coverage );  \
+   }
+#include "lnaatemp.h"
+}
+
+
+/*
+ * Null rasterizer for measuring transformation speed.
+ */
+static void null_line( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv )
+{
+   (void) ctx;
+   (void) v1;
+   (void) v2;
+   (void) pv;
+}
+
+
+/*
+ * Determine which line drawing function to use given the current
+ * rendering context.
+ */
+void gl_set_line_function( GLcontext *ctx )
+{
+   GLboolean rgbmode = ctx->Visual->RGBAflag;
+   /* TODO: antialiased lines */
+
+   if (ctx->RenderMode==GL_RENDER) {
+      if (ctx->NoRaster) {
+         ctx->Driver.LineFunc = null_line;
+         return;
+      }
+      if (ctx->Driver.LineFunc) {
+         /* Device driver will draw lines. */
+        return;
+      }
+
+      if (ctx->Line.SmoothFlag) {
+         /* antialiased lines */
+         if (rgbmode) {
+            if (ctx->Texture.ReallyEnabled) {
+               if (ctx->Texture.ReallyEnabled >= TEXTURE1_1D
+                  || ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR)
+                  /* Multitextured! */
+                  ctx->Driver.LineFunc = aa_multitex_rgba_line;
+               else
+                  ctx->Driver.LineFunc = aa_tex_rgba_line;
+            } else {
+               ctx->Driver.LineFunc = aa_rgba_line;
+            }
+         }
+         else {
+            ctx->Driver.LineFunc = aa_ci_line;
+         }
+      }
+      else if (ctx->Texture.ReallyEnabled) {
+         if (ctx->Texture.ReallyEnabled >= TEXTURE1_1D
+             || ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR) {
+            /* multi-texture and/or separate specular color */
+            ctx->Driver.LineFunc = smooth_multitextured_line;
+         }
+         else {
+            if (ctx->Light.ShadeModel==GL_SMOOTH) {
+                ctx->Driver.LineFunc = smooth_textured_line;
+            }
+            else {
+                ctx->Driver.LineFunc = flat_textured_line;
+            }
+         }
+      }
+      else if (ctx->Line.Width!=1.0 || ctx->Line.StippleFlag
+               || ctx->Line.SmoothFlag) {
+         if (ctx->Light.ShadeModel==GL_SMOOTH) {
+            if (rgbmode)
+               ctx->Driver.LineFunc = general_smooth_rgba_line;
+            else
+               ctx->Driver.LineFunc = general_smooth_ci_line;
+         }
+         else {
+            if (rgbmode)
+               ctx->Driver.LineFunc = general_flat_rgba_line;
+            else
+               ctx->Driver.LineFunc = general_flat_ci_line;
+         }
+      }
+      else {
+        if (ctx->Light.ShadeModel==GL_SMOOTH) {
+           /* Width==1, non-stippled, smooth-shaded */
+            if (ctx->Depth.Test
+               || (ctx->Fog.Enabled && ctx->Hint.Fog==GL_NICEST)) {
+               if (rgbmode)
+                  ctx->Driver.LineFunc = smooth_rgba_z_line;
+               else
+                  ctx->Driver.LineFunc = smooth_ci_z_line;
+            }
+            else {
+               if (rgbmode)
+                  ctx->Driver.LineFunc = smooth_rgba_line;
+               else
+                  ctx->Driver.LineFunc = smooth_ci_line;
+            }
+        }
+         else {
+           /* Width==1, non-stippled, flat-shaded */
+            if (ctx->Depth.Test
+                || (ctx->Fog.Enabled && ctx->Hint.Fog==GL_NICEST)) {
+               if (rgbmode)
+                  ctx->Driver.LineFunc = flat_rgba_z_line;
+               else
+                  ctx->Driver.LineFunc = flat_ci_z_line;
+            }
+            else {
+               if (rgbmode)
+                  ctx->Driver.LineFunc = flat_rgba_line;
+               else
+                  ctx->Driver.LineFunc = flat_ci_line;
+            }
+         }
+      }
+   }
+   else if (ctx->RenderMode==GL_FEEDBACK) {
+      ctx->Driver.LineFunc = feedback_line;
+   }
+   else {
+      /* GL_SELECT mode */
+      ctx->Driver.LineFunc = select_line;
+   }
+}
+
diff --git a/src/mesa/main/lines.h b/src/mesa/main/lines.h
new file mode 100644 (file)
index 0000000..f85a7a4
--- /dev/null
@@ -0,0 +1,45 @@
+/* $Id: lines.h,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+#ifndef LINES_H
+#define LINES_H
+
+
+#include "types.h"
+
+
+extern void gl_LineWidth( GLcontext *ctx, GLfloat width );
+
+extern void gl_LineStipple( GLcontext *ctx, GLint factor, GLushort pattern );
+
+extern void gl_set_line_function( GLcontext *ctx );
+
+
+#endif
diff --git a/src/mesa/main/macros.h b/src/mesa/main/macros.h
new file mode 100644 (file)
index 0000000..61e8974
--- /dev/null
@@ -0,0 +1,546 @@
+/* $Id: macros.h,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+/*
+ * A collection of useful macros.
+ */
+
+
+#ifndef MACROS_H
+#define MACROS_H
+
+
+#include <math.h>
+#include <string.h>
+
+
+#ifdef DEBUG
+#  include <assert.h>
+#  define ASSERT(X)   assert(X)
+#else
+#  define ASSERT(X)
+#endif
+
+
+#if defined(__GNUC__) || defined(__MWERKS__)
+#define INLINE __inline__
+#elif defined(__MSC__)
+#define INLINE __inline
+#else
+#define INLINE
+#endif
+
+
+/* Stepping a GLfloat pointer by a byte stride 
+ */
+#define STRIDE_F(p, i)  (p = (GLfloat *)((GLubyte *)p + i))
+#define STRIDE_UI(p, i)  (p = (GLuint *)((GLubyte *)p + i))
+#define STRIDE_T(p, t, i)  (p = (t *)((GLubyte *)p + i))
+
+
+/* Limits: */
+#define MAX_GLUSHORT   0xffff
+#define MAX_GLUINT     0xffffffff
+
+
+#define ZERO_2V( DST ) (DST)[0] = (DST)[1] = 0
+#define ZERO_3V( DST ) (DST)[0] = (DST)[1] = (DST)[2] = 0
+#define ZERO_4V( DST ) (DST)[0] = (DST)[1] = (DST)[2] = (DST)[3] = 0
+
+
+/* Copy short vectors: */
+#define COPY_2V( DST, SRC )                    \
+do {                                           \
+   (DST)[0] = (SRC)[0];                                \
+   (DST)[1] = (SRC)[1];                                \
+} while (0)
+
+
+#define COPY_3V( DST, SRC )                    \
+do {                                           \
+   (DST)[0] = (SRC)[0];                                \
+   (DST)[1] = (SRC)[1];                                \
+   (DST)[2] = (SRC)[2];                                \
+} while (0)
+
+#define COPY_4V( DST, SRC )                    \
+do {                                           \
+   (DST)[0] = (SRC)[0];                                \
+   (DST)[1] = (SRC)[1];                                \
+   (DST)[2] = (SRC)[2];                                \
+   (DST)[3] = (SRC)[3];                                \
+} while (0)
+
+
+#define COPY_2FV( DST, SRC )                   \
+do {                                           \
+   const GLfloat *_tmp = (SRC);                        \
+   (DST)[0] = _tmp[0];                         \
+   (DST)[1] = _tmp[1];                         \
+} while (0)
+
+
+#define COPY_3FV( DST, SRC )                   \
+do {                                           \
+   const GLfloat *_tmp = (SRC);                        \
+   (DST)[0] = _tmp[0];                         \
+   (DST)[1] = _tmp[1];                         \
+   (DST)[2] = _tmp[2];                         \
+} while (0)
+
+#define COPY_4FV( DST, SRC )                   \
+do {                                           \
+   const GLfloat *_tmp = (SRC);                        \
+   (DST)[0] = _tmp[0];                         \
+   (DST)[1] = _tmp[1];                         \
+   (DST)[2] = _tmp[2];                         \
+   (DST)[3] = _tmp[3];                         \
+} while (0)
+
+
+
+#define COPY_SZ_4V(DST, SZ, SRC)               \
+do {                                           \
+   switch (SZ) {                               \
+   case 4: (DST)[3] = (SRC)[3];                        \
+   case 3: (DST)[2] = (SRC)[2];                        \
+   case 2: (DST)[1] = (SRC)[1];                        \
+   case 1: (DST)[0] = (SRC)[0];                        \
+   }                                           \
+} while(0)                        
+
+#define SUB_4V( DST, SRCA, SRCB )              \
+do {                                           \
+      (DST)[0] = (SRCA)[0] - (SRCB)[0];                \
+      (DST)[1] = (SRCA)[1] - (SRCB)[1];                \
+      (DST)[2] = (SRCA)[2] - (SRCB)[2];                \
+      (DST)[3] = (SRCA)[3] - (SRCB)[3];                \
+} while (0)
+
+#define ADD_4V( DST, SRCA, SRCB )              \
+do {                                           \
+      (DST)[0] = (SRCA)[0] + (SRCB)[0];                \
+      (DST)[1] = (SRCA)[1] + (SRCB)[1];                \
+      (DST)[2] = (SRCA)[2] + (SRCB)[2];                \
+      (DST)[3] = (SRCA)[3] + (SRCB)[3];                \
+} while (0)
+
+#define SCALE_4V( DST, SRCA, SRCB )            \
+do {                                           \
+      (DST)[0] = (SRCA)[0] * (SRCB)[0];                \
+      (DST)[1] = (SRCA)[1] * (SRCB)[1];                \
+      (DST)[2] = (SRCA)[2] * (SRCB)[2];                \
+      (DST)[3] = (SRCA)[3] * (SRCB)[3];                \
+} while (0)
+
+#define ACC_4V( DST, SRC )                     \
+do {                                           \
+      (DST)[0] += (SRC)[0];                            \
+      (DST)[1] += (SRC)[1];                            \
+      (DST)[2] += (SRC)[2];                            \
+      (DST)[3] += (SRC)[3];                            \
+} while (0)
+
+#define ACC_SCALE_4V( DST, SRCA, SRCB )                \
+do {                                           \
+      (DST)[0] += (SRCA)[0] * (SRCB)[0];               \
+      (DST)[1] += (SRCA)[1] * (SRCB)[1];               \
+      (DST)[2] += (SRCA)[2] * (SRCB)[2];               \
+      (DST)[3] += (SRCA)[3] * (SRCB)[3];               \
+} while (0)
+
+#define ACC_SCALE_SCALAR_4V( DST, S, SRCB )    \
+do {                                           \
+      (DST)[0] += S * (SRCB)[0];                       \
+      (DST)[1] += S * (SRCB)[1];                       \
+      (DST)[2] += S * (SRCB)[2];                       \
+      (DST)[3] += S * (SRCB)[3];                       \
+} while (0)
+
+#define SCALE_SCALAR_4V( DST, S, SRCB )                \
+do {                                           \
+      (DST)[0] = S * (SRCB)[0];                        \
+      (DST)[1] = S * (SRCB)[1];                        \
+      (DST)[2] = S * (SRCB)[2];                        \
+      (DST)[3] = S * (SRCB)[3];                        \
+} while (0)
+
+
+#define SELF_SCALE_SCALAR_4V( DST, S )         \
+do {                                           \
+      (DST)[0] *= S;                           \
+      (DST)[1] *= S;                           \
+      (DST)[2] *= S;                           \
+      (DST)[3] *= S;                           \
+} while (0)
+
+
+/*
+ * Similarly for 3-vectors.
+ */
+#define SUB_3V( DST, SRCA, SRCB )              \
+do {                                           \
+      (DST)[0] = (SRCA)[0] - (SRCB)[0];                \
+      (DST)[1] = (SRCA)[1] - (SRCB)[1];                \
+      (DST)[2] = (SRCA)[2] - (SRCB)[2];                \
+} while (0)
+
+#define ADD_3V( DST, SRCA, SRCB )              \
+do {                                           \
+      (DST)[0] = (SRCA)[0] + (SRCB)[0];                \
+      (DST)[1] = (SRCA)[1] + (SRCB)[1];                \
+      (DST)[2] = (SRCA)[2] + (SRCB)[2];                \
+} while (0)
+
+#define SCALE_3V( DST, SRCA, SRCB )            \
+do {                                           \
+      (DST)[0] = (SRCA)[0] * (SRCB)[0];                \
+      (DST)[1] = (SRCA)[1] * (SRCB)[1];                \
+      (DST)[2] = (SRCA)[2] * (SRCB)[2];                \
+} while (0)
+
+#define ACC_3V( DST, SRC )                     \
+do {                                           \
+      (DST)[0] += (SRC)[0];                    \
+      (DST)[1] += (SRC)[1];                    \
+      (DST)[2] += (SRC)[2];                    \
+} while (0)
+
+#define ACC_SCALE_3V( DST, SRCA, SRCB )                \
+do {                                           \
+      (DST)[0] += (SRCA)[0] * (SRCB)[0];       \
+      (DST)[1] += (SRCA)[1] * (SRCB)[1];       \
+      (DST)[2] += (SRCA)[2] * (SRCB)[2];       \
+} while (0)
+
+#define SCALE_SCALAR_3V( DST, S, SRCB )        \
+do {                                           \
+      (DST)[0] = S * (SRCB)[0];                        \
+      (DST)[1] = S * (SRCB)[1];                        \
+      (DST)[2] = S * (SRCB)[2];                        \
+} while (0)
+
+#define ACC_SCALE_SCALAR_3V( DST, S, SRCB )    \
+do {                                           \
+      (DST)[0] += S * (SRCB)[0];               \
+      (DST)[1] += S * (SRCB)[1];               \
+      (DST)[2] += S * (SRCB)[2];               \
+} while (0)
+
+#define SELF_SCALE_SCALAR_3V( DST, S )         \
+do {                                           \
+      (DST)[0] *= S;                           \
+      (DST)[1] *= S;                           \
+      (DST)[2] *= S;                           \
+} while (0)
+
+#define ACC_SCALAR_3V( DST, S )                \
+do {                                           \
+      (DST)[0] += S;                           \
+      (DST)[1] += S;                           \
+      (DST)[2] += S;                           \
+} while (0)
+
+/* And also for 2-vectors
+ */
+#define SUB_2V( DST, SRCA, SRCB )              \
+do {                                           \
+      (DST)[0] = (SRCA)[0] - (SRCB)[0];                \
+      (DST)[1] = (SRCA)[1] - (SRCB)[1];                \
+} while (0)
+
+#define ADD_2V( DST, SRCA, SRCB )              \
+do {                                           \
+      (DST)[0] = (SRCA)[0] + (SRCB)[0];                \
+      (DST)[1] = (SRCA)[1] + (SRCB)[1];                \
+} while (0)
+
+#define SCALE_2V( DST, SRCA, SRCB )            \
+do {                                           \
+      (DST)[0] = (SRCA)[0] * (SRCB)[0];                \
+      (DST)[1] = (SRCA)[1] * (SRCB)[1];                \
+} while (0)
+
+#define ACC_2V( DST, SRC )                     \
+do {                                           \
+      (DST)[0] += (SRC)[0];                    \
+      (DST)[1] += (SRC)[1];                    \
+} while (0)
+
+#define ACC_SCALE_2V( DST, SRCA, SRCB )                \
+do {                                           \
+      (DST)[0] += (SRCA)[0] * (SRCB)[0];       \
+      (DST)[1] += (SRCA)[1] * (SRCB)[1];       \
+} while (0)
+
+#define SCALE_SCALAR_2V( DST, S, SRCB )        \
+do {                                           \
+      (DST)[0] = S * (SRCB)[0];                        \
+      (DST)[1] = S * (SRCB)[1];                        \
+} while (0)
+
+#define ACC_SCALE_SCALAR_2V( DST, S, SRCB )    \
+do {                                           \
+      (DST)[0] += S * (SRCB)[0];               \
+      (DST)[1] += S * (SRCB)[1];               \
+} while (0)
+
+#define SELF_SCALE_SCALAR_2V( DST, S )         \
+do {                                           \
+      (DST)[0] *= S;                           \
+      (DST)[1] *= S;                           \
+} while (0)
+
+#define ACC_SCALAR_2V( DST, S )                \
+do {                                           \
+      (DST)[0] += S;                           \
+      (DST)[1] += S;                           \
+} while (0)
+
+
+
+/*
+ * Copy a vector of 4 GLubytes from SRC to DST.
+ */
+#define COPY_4UBV(DST, SRC)                    \
+do {                                           \
+   if (sizeof(GLuint)==4*sizeof(GLubyte)) {    \
+      *((GLuint*)(DST)) = *((GLuint*)(SRC));   \
+   }                                           \
+   else {                                      \
+      (DST)[0] = (SRC)[0];                     \
+      (DST)[1] = (SRC)[1];                     \
+      (DST)[2] = (SRC)[2];                     \
+      (DST)[3] = (SRC)[3];                     \
+   }                                           \
+} while (0)
+
+
+/* Assign scalers to short vectors: */
+#define ASSIGN_2V( V, V0, V1 )  \
+do { V[0] = V0;  V[1] = V1; } while(0)
+
+#define ASSIGN_3V( V, V0, V1, V2 )  \
+do { V[0] = V0;  V[1] = V1;  V[2] = V2; } while(0)
+
+#define ASSIGN_4V( V, V0, V1, V2, V3 )                 \
+do {                                           \
+    V[0] = V0;                                 \
+    V[1] = V1;                                 \
+    V[2] = V2;                                 \
+    V[3] = V3;                                         \
+} while(0)
+
+
+
+
+/* Absolute value (for Int, Float, Double): */
+#define ABSI(X)  ((X) < 0 ? -(X) : (X))
+#define ABSF(X)  ((X) < 0.0F ? -(X) : (X))
+#define ABSD(X)  ((X) < 0.0 ? -(X) : (X))
+
+
+
+/* Round a floating-point value to the nearest integer: */
+#define ROUNDF(X)  ( (X)<0.0F ? ((GLint) ((X)-0.5F)) : ((GLint) ((X)+0.5F)) )
+
+
+/* Compute ceiling of integer quotient of A divided by B: */
+#define CEILING( A, B )  ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 )
+
+
+/* Clamp X to [MIN,MAX]: */
+#define CLAMP( X, MIN, MAX )  ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) )
+
+/* Assign X to CLAMP(X, MIN, MAX) */
+#define CLAMP_SELF(x, mn, mx)  \
+   ( (x)<(mn) ? ((x) = (mn)) : ((x)>(mx) ? ((x)=(mx)) : (x)) )
+
+
+
+/* Min of two values: */
+#define MIN2( A, B )   ( (A)<(B) ? (A) : (B) )
+
+
+/* MAX of two values: */
+#define MAX2( A, B )   ( (A)>(B) ? (A) : (B) )
+
+/* Dot product of two 2-element vectors */
+#define DOT2( a, b )  ( (a)[0]*(b)[0] + (a)[1]*(b)[1] )
+
+/* Dot product of two 3-element vectors */
+#define DOT3( a, b )  ( (a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2] )
+
+
+/* Dot product of two 4-element vectors */
+#define DOT4( a, b )  ( (a)[0]*(b)[0] + (a)[1]*(b)[1] + \
+                       (a)[2]*(b)[2] + (a)[3]*(b)[3] )
+
+#define DOT4V(v,a,b,c,d) (v[0]*a + v[1]*b + v[2]*c + v[3]*d)
+
+
+#define CROSS3(n, u, v)                        \
+do {                                           \
+   (n)[0] = (u)[1]*(v)[2] - (u)[2]*(v)[1];     \
+   (n)[1] = (u)[2]*(v)[0] - (u)[0]*(v)[2];     \
+   (n)[2] = (u)[0]*(v)[1] - (u)[1]*(v)[0];     \
+} while (0)
+
+
+/*
+ * Integer / float conversion for colors, normals, etc.
+ */
+
+
+
+
+#define BYTE_TO_UBYTE(b)   (b < 0 ? 0 : (GLubyte) b)
+#define SHORT_TO_UBYTE(s)  (s < 0 ? 0 : (GLubyte) (s >> 7))
+#define USHORT_TO_UBYTE(s)              (GLubyte) (s >> 8)
+#define INT_TO_UBYTE(i)    (i < 0 ? 0 : (GLubyte) (i >> 23))
+#define UINT_TO_UBYTE(i)                (GLubyte) (i >> 24)
+
+
+
+
+/* Convert GLubyte in [0,255] to GLfloat in [0.0,1.0] */
+#define UBYTE_TO_FLOAT(B)      ((GLfloat) (B) * (1.0F / 255.0F))
+
+/* Convert GLfloat in [0.0,1.0] to GLubyte in [0,255] */
+#define FLOAT_TO_UBYTE(X)      ((GLubyte) (GLint) (((X)) * 255.0F))
+
+
+/* Convert GLbyte in [-128,127] to GLfloat in [-1.0,1.0] */
+#define BYTE_TO_FLOAT(B)       ((2.0F * (B) + 1.0F) * (1.0F/255.0F))
+
+/* Convert GLfloat in [-1.0,1.0] to GLbyte in [-128,127] */
+#define FLOAT_TO_BYTE(X)       ( (((GLint) (255.0F * (X))) - 1) / 2 )
+
+
+/* Convert GLushort in [0,65536] to GLfloat in [0.0,1.0] */
+#define USHORT_TO_FLOAT(S)     ((GLfloat) (S) * (1.0F / 65535.0F))
+
+/* Convert GLfloat in [0.0,1.0] to GLushort in [0,65536] */
+#define FLOAT_TO_USHORT(X)     ((GLushort) (GLint) ((X) * 65535.0F))
+
+
+/* Convert GLshort in [-32768,32767] to GLfloat in [-1.0,1.0] */
+#define SHORT_TO_FLOAT(S)      ((2.0F * (S) + 1.0F) * (1.0F/65535.0F))
+
+/* Convert GLfloat in [0.0,1.0] to GLshort in [-32768,32767] */
+#define FLOAT_TO_SHORT(X)      ( (((GLint) (65535.0F * (X))) - 1) / 2 )
+
+
+/* Convert GLuint in [0,4294967295] to GLfloat in [0.0,1.0] */
+#define UINT_TO_FLOAT(U)       ((GLfloat) (U) * (1.0F / 4294967295.0F))
+
+/* Convert GLfloat in [0.0,1.0] to GLuint in [0,4294967295] */
+#define FLOAT_TO_UINT(X)       ((GLuint) ((X) * 4294967295.0))
+
+
+/* Convert GLint in [-2147483648,2147483647] to GLfloat in [-1.0,1.0] */
+#define INT_TO_FLOAT(I)                ((2.0F * (I) + 1.0F) * (1.0F/4294967294.0F))
+
+/* Convert GLfloat in [-1.0,1.0] to GLint in [-2147483648,2147483647] */
+/* causes overflow:
+#define FLOAT_TO_INT(X)                ( (((GLint) (4294967294.0F * (X))) - 1) / 2 )
+*/
+/* a close approximation: */
+#define FLOAT_TO_INT(X)                ( (GLint) (2147483647.0 * (X)) )
+
+
+
+/* Memory copy: */
+#ifdef SUNOS4
+#define MEMCPY( DST, SRC, BYTES) \
+       memcpy( (char *) (DST), (char *) (SRC), (int) (BYTES) )
+#else
+#define MEMCPY( DST, SRC, BYTES) \
+       memcpy( (void *) (DST), (void *) (SRC), (size_t) (BYTES) )
+#endif
+
+
+/* Memory set: */
+#ifdef SUNOS4
+#define MEMSET( DST, VAL, N ) \
+       memset( (char *) (DST), (int) (VAL), (int) (N) )
+#else
+#define MEMSET( DST, VAL, N ) \
+       memset( (void *) (DST), (int) (VAL), (size_t) (N) )
+#endif
+
+
+/* MACs and BeOS don't support static larger than 32kb, so... */
+#if defined(macintosh) && !defined(__MRC__)
+  extern char *AGLAlloc(int size);
+  extern void AGLFree(char* ptr);
+#  define DEFARRAY(TYPE,NAME,SIZE)                     TYPE *NAME = (TYPE*)AGLAlloc(sizeof(TYPE)*(SIZE))
+#  define DEFMARRAY(TYPE,NAME,SIZE1,SIZE2)             TYPE (*NAME)[SIZE2] = (TYPE(*)[SIZE2])AGLAlloc(sizeof(TYPE)*(SIZE1)*(SIZE2))
+#  define CHECKARRAY(NAME,CMD)                         do {if (!(NAME)) {CMD;}} while (0) 
+#  define UNDEFARRAY(NAME)                             do {if ((NAME)) {AGLFree((char*)NAME);}  }while (0)
+#elif defined(__BEOS__)
+#  define DEFARRAY(TYPE,NAME,SIZE)                     TYPE *NAME = (TYPE*)malloc(sizeof(TYPE)*(SIZE))
+#  define DEFMARRAY(TYPE,NAME,SIZE1,SIZE2)             TYPE (*NAME)[SIZE2] = (TYPE(*)[SIZE2])malloc(sizeof(TYPE)*(SIZE1)*(SIZE2))
+#  define CHECKARRAY(NAME,CMD)                         do {if (!(NAME)) {CMD;}} while (0)
+#  define UNDEFARRAY(NAME)                             do {if ((NAME)) {free((char*)NAME);}  }while (0)
+#else
+#  define DEFARRAY(TYPE,NAME,SIZE)                     TYPE NAME[SIZE]
+#  define DEFMARRAY(TYPE,NAME,SIZE1,SIZE2)             TYPE NAME[SIZE1][SIZE2]
+#  define CHECKARRAY(NAME,CMD)                         do {} while(0)
+#  define UNDEFARRAY(NAME)
+#endif
+
+
+/* Some compilers don't like some of Mesa's const usage */
+#ifdef NO_CONST
+#  define CONST
+#else
+#  define CONST const
+#endif
+
+
+
+/* Pi */
+#ifndef M_PI
+#define M_PI (3.1415926)
+#endif
+
+
+/* Degrees to radians conversion: */
+#define DEG2RAD (M_PI/180.0)
+
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+
+
+#endif /*MACROS_H*/
diff --git a/src/mesa/main/matrix.c b/src/mesa/main/matrix.c
new file mode 100644 (file)
index 0000000..c645994
--- /dev/null
@@ -0,0 +1,1438 @@
+/* $Id: matrix.c,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+/*
+ * Matrix operations
+ *
+ *
+ * NOTES:
+ * 1. 4x4 transformation matrices are stored in memory in column major order.
+ * 2. Points/vertices are to be thought of as column vectors.
+ * 3. Transformation of a point p by a matrix M is: p' = M * p
+ *
+ */
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "context.h"
+#include "enums.h"
+#include "macros.h"
+#include "matrix.h"
+#include "mmath.h"
+#include "types.h"
+#ifdef XFree86Server
+#include "GL/xf86glx.h"
+#endif
+#endif
+
+
+static const char *types[] = {
+   "MATRIX_GENERAL",
+   "MATRIX_IDENTITY",
+   "MATRIX_3D_NO_ROT",
+   "MATRIX_PERSPECTIVE",
+   "MATRIX_2D",
+   "MATRIX_2D_NO_ROT",
+   "MATRIX_3D"
+};
+static void matmul4( GLfloat *product, const GLfloat *a, const GLfloat *b );
+
+
+static GLfloat Identity[16] = {
+   1.0, 0.0, 0.0, 0.0,
+   0.0, 1.0, 0.0, 0.0,
+   0.0, 0.0, 1.0, 0.0,
+   0.0, 0.0, 0.0, 1.0
+};
+
+
+static void print_matrix_floats( const GLfloat m[16] )
+{
+   int i;
+   for (i=0;i<4;i++) {
+      fprintf(stderr,"\t%f %f %f %f\n", m[i], m[4+i], m[8+i], m[12+i] );
+   }
+}
+
+void gl_print_matrix( const GLmatrix *m )
+{
+   fprintf(stderr, "Matrix type: %s, flags: %x\n", types[m->type], m->flags);
+   print_matrix_floats(m->m);
+#if 1
+   fprintf(stderr, "Inverse: \n");
+   if (m->inv) {
+      GLfloat prod[16];
+      print_matrix_floats(m->inv);
+      matmul4(prod, m->m, m->inv);
+      fprintf(stderr, "Mat * Inverse:\n");
+      print_matrix_floats(prod);
+  } else 
+      fprintf(stderr, "  - not available\n");
+#endif
+}
+
+
+
+/*
+ * This matmul was contributed by Thomas Malik 
+ *
+ * Perform a 4x4 matrix multiplication  (product = a x b).
+ * Input:  a, b - matrices to multiply
+ * Output:  product - product of a and b
+ * WARNING: (product != b) assumed
+ * NOTE:    (product == a) allowed    
+ *
+ * KW: 4*16 = 64 muls
+ */
+#define A(row,col)  a[(col<<2)+row]
+#define B(row,col)  b[(col<<2)+row]
+#define P(row,col)  product[(col<<2)+row]
+
+static void matmul4( GLfloat *product, const GLfloat *a, const GLfloat *b )
+{
+   GLint i;
+   for (i = 0; i < 4; i++) {
+      GLfloat ai0=A(i,0),  ai1=A(i,1),  ai2=A(i,2),  ai3=A(i,3);
+      P(i,0) = ai0 * B(0,0) + ai1 * B(1,0) + ai2 * B(2,0) + ai3 * B(3,0);
+      P(i,1) = ai0 * B(0,1) + ai1 * B(1,1) + ai2 * B(2,1) + ai3 * B(3,1);
+      P(i,2) = ai0 * B(0,2) + ai1 * B(1,2) + ai2 * B(2,2) + ai3 * B(3,2);
+      P(i,3) = ai0 * B(0,3) + ai1 * B(1,3) + ai2 * B(2,3) + ai3 * B(3,3);
+   }
+}
+
+
+
+
+/* Multiply two matrices known to occupy only the top three rows,
+ * such as typical modelling matrices, and ortho matrices.
+ *
+ * KW: 3*9 = 27 muls
+ */
+static void matmul34( GLfloat *product, const GLfloat *a, const GLfloat *b )
+{
+   GLint i;
+   for (i = 0; i < 3; i++) {
+      GLfloat ai0=A(i,0),  ai1=A(i,1),  ai2=A(i,2),  ai3=A(i,3);
+      P(i,0) = ai0 * B(0,0) + ai1 * B(1,0) + ai2 * B(2,0);
+      P(i,1) = ai0 * B(0,1) + ai1 * B(1,1) + ai2 * B(2,1);
+      P(i,2) = ai0 * B(0,2) + ai1 * B(1,2) + ai2 * B(2,2);
+      P(i,3) = ai0 * B(0,3) + ai1 * B(1,3) + ai2 * B(2,3) + ai3;
+   }
+   P(3,0) = 0;
+   P(3,1) = 0;
+   P(3,2) = 0;
+   P(3,3) = 1;
+}
+
+static void matmul4fd( GLfloat *product, const GLfloat *a, const GLdouble *b )
+{
+   GLint i;
+   for (i = 0; i < 4; i++) {
+      GLfloat ai0=A(i,0),  ai1=A(i,1),  ai2=A(i,2),  ai3=A(i,3);
+      P(i,0) = ai0 * B(0,0) + ai1 * B(1,0) + ai2 * B(2,0) + ai3 * B(3,0);
+      P(i,1) = ai0 * B(0,1) + ai1 * B(1,1) + ai2 * B(2,1) + ai3 * B(3,1);
+      P(i,2) = ai0 * B(0,2) + ai1 * B(1,2) + ai2 * B(2,2) + ai3 * B(3,2);
+      P(i,3) = ai0 * B(0,3) + ai1 * B(1,3) + ai2 * B(2,3) + ai3 * B(3,3);
+   }
+}
+
+#undef A
+#undef B
+#undef P
+
+
+
+#define SWAP_ROWS(a, b) { GLfloat *_tmp = a; (a)=(b); (b)=_tmp; }
+#define MAT(m,r,c) (m)[(c)*4+(r)]
+
+/*
+ * Compute inverse of 4x4 transformation matrix.
+ * Code contributed by Jacques Leroy jle@star.be
+ * Return GL_TRUE for success, GL_FALSE for failure (singular matrix)
+ */
+static GLboolean invert_matrix_general( GLmatrix *mat )
+{
+   const GLfloat *m = mat->m;
+   GLfloat *out = mat->inv;
+   GLfloat wtmp[4][8];
+   GLfloat m0, m1, m2, m3, s;
+   GLfloat *r0, *r1, *r2, *r3;
+  
+   r0 = wtmp[0], r1 = wtmp[1], r2 = wtmp[2], r3 = wtmp[3];
+  
+   r0[0] = MAT(m,0,0), r0[1] = MAT(m,0,1),
+   r0[2] = MAT(m,0,2), r0[3] = MAT(m,0,3),
+   r0[4] = 1.0, r0[5] = r0[6] = r0[7] = 0.0,
+  
+   r1[0] = MAT(m,1,0), r1[1] = MAT(m,1,1),
+   r1[2] = MAT(m,1,2), r1[3] = MAT(m,1,3),
+   r1[5] = 1.0, r1[4] = r1[6] = r1[7] = 0.0,
+  
+   r2[0] = MAT(m,2,0), r2[1] = MAT(m,2,1),
+   r2[2] = MAT(m,2,2), r2[3] = MAT(m,2,3),
+   r2[6] = 1.0, r2[4] = r2[5] = r2[7] = 0.0,
+  
+   r3[0] = MAT(m,3,0), r3[1] = MAT(m,3,1),
+   r3[2] = MAT(m,3,2), r3[3] = MAT(m,3,3),
+   r3[7] = 1.0, r3[4] = r3[5] = r3[6] = 0.0;
+  
+   /* choose pivot - or die */
+   if (fabs(r3[0])>fabs(r2[0])) SWAP_ROWS(r3, r2);
+   if (fabs(r2[0])>fabs(r1[0])) SWAP_ROWS(r2, r1);
+   if (fabs(r1[0])>fabs(r0[0])) SWAP_ROWS(r1, r0);
+   if (0.0 == r0[0])  return GL_FALSE;
+  
+   /* eliminate first variable     */
+   m1 = r1[0]/r0[0]; m2 = r2[0]/r0[0]; m3 = r3[0]/r0[0];
+   s = r0[1]; r1[1] -= m1 * s; r2[1] -= m2 * s; r3[1] -= m3 * s;
+   s = r0[2]; r1[2] -= m1 * s; r2[2] -= m2 * s; r3[2] -= m3 * s;
+   s = r0[3]; r1[3] -= m1 * s; r2[3] -= m2 * s; r3[3] -= m3 * s;
+   s = r0[4];
+   if (s != 0.0) { r1[4] -= m1 * s; r2[4] -= m2 * s; r3[4] -= m3 * s; }
+   s = r0[5];
+   if (s != 0.0) { r1[5] -= m1 * s; r2[5] -= m2 * s; r3[5] -= m3 * s; }
+   s = r0[6];
+   if (s != 0.0) { r1[6] -= m1 * s; r2[6] -= m2 * s; r3[6] -= m3 * s; }
+   s = r0[7];
+   if (s != 0.0) { r1[7] -= m1 * s; r2[7] -= m2 * s; r3[7] -= m3 * s; }
+  
+   /* choose pivot - or die */
+   if (fabs(r3[1])>fabs(r2[1])) SWAP_ROWS(r3, r2);
+   if (fabs(r2[1])>fabs(r1[1])) SWAP_ROWS(r2, r1);
+   if (0.0 == r1[1])  return GL_FALSE;
+  
+   /* eliminate second variable */
+   m2 = r2[1]/r1[1]; m3 = r3[1]/r1[1];
+   r2[2] -= m2 * r1[2]; r3[2] -= m3 * r1[2];
+   r2[3] -= m2 * r1[3]; r3[3] -= m3 * r1[3];
+   s = r1[4]; if (0.0 != s) { r2[4] -= m2 * s; r3[4] -= m3 * s; }
+   s = r1[5]; if (0.0 != s) { r2[5] -= m2 * s; r3[5] -= m3 * s; }
+   s = r1[6]; if (0.0 != s) { r2[6] -= m2 * s; r3[6] -= m3 * s; }
+   s = r1[7]; if (0.0 != s) { r2[7] -= m2 * s; r3[7] -= m3 * s; }
+  
+   /* choose pivot - or die */
+   if (fabs(r3[2])>fabs(r2[2])) SWAP_ROWS(r3, r2);
+   if (0.0 == r2[2])  return GL_FALSE;
+  
+   /* eliminate third variable */
+   m3 = r3[2]/r2[2];
+   r3[3] -= m3 * r2[3], r3[4] -= m3 * r2[4],
+   r3[5] -= m3 * r2[5], r3[6] -= m3 * r2[6],
+   r3[7] -= m3 * r2[7];
+  
+   /* last check */
+   if (0.0 == r3[3]) return GL_FALSE;
+  
+   s = 1.0/r3[3];              /* now back substitute row 3 */
+   r3[4] *= s; r3[5] *= s; r3[6] *= s; r3[7] *= s;
+  
+   m2 = r2[3];                 /* now back substitute row 2 */
+   s  = 1.0/r2[2];
+   r2[4] = s * (r2[4] - r3[4] * m2), r2[5] = s * (r2[5] - r3[5] * m2),
+   r2[6] = s * (r2[6] - r3[6] * m2), r2[7] = s * (r2[7] - r3[7] * m2);
+   m1 = r1[3];
+   r1[4] -= r3[4] * m1, r1[5] -= r3[5] * m1,
+   r1[6] -= r3[6] * m1, r1[7] -= r3[7] * m1;
+   m0 = r0[3];
+   r0[4] -= r3[4] * m0, r0[5] -= r3[5] * m0,
+   r0[6] -= r3[6] * m0, r0[7] -= r3[7] * m0;
+  
+   m1 = r1[2];                 /* now back substitute row 1 */
+   s  = 1.0/r1[1];
+   r1[4] = s * (r1[4] - r2[4] * m1), r1[5] = s * (r1[5] - r2[5] * m1),
+   r1[6] = s * (r1[6] - r2[6] * m1), r1[7] = s * (r1[7] - r2[7] * m1);
+   m0 = r0[2];
+   r0[4] -= r2[4] * m0, r0[5] -= r2[5] * m0,
+   r0[6] -= r2[6] * m0, r0[7] -= r2[7] * m0;
+  
+   m0 = r0[1];                 /* now back substitute row 0 */
+   s  = 1.0/r0[0];
+   r0[4] = s * (r0[4] - r1[4] * m0), r0[5] = s * (r0[5] - r1[5] * m0),
+   r0[6] = s * (r0[6] - r1[6] * m0), r0[7] = s * (r0[7] - r1[7] * m0);
+  
+   MAT(out,0,0) = r0[4]; MAT(out,0,1) = r0[5],
+   MAT(out,0,2) = r0[6]; MAT(out,0,3) = r0[7],
+   MAT(out,1,0) = r1[4]; MAT(out,1,1) = r1[5],
+   MAT(out,1,2) = r1[6]; MAT(out,1,3) = r1[7],
+   MAT(out,2,0) = r2[4]; MAT(out,2,1) = r2[5],
+   MAT(out,2,2) = r2[6]; MAT(out,2,3) = r2[7],
+   MAT(out,3,0) = r3[4]; MAT(out,3,1) = r3[5],
+   MAT(out,3,2) = r3[6]; MAT(out,3,3) = r3[7]; 
+  
+   return GL_TRUE;
+}
+#undef SWAP_ROWS
+
+/* Adapted from graphics gems II.
+ */  
+GLboolean invert_matrix_3d_general( GLmatrix *mat )
+{
+   const GLfloat *in = mat->m;
+   GLfloat *out = mat->inv;
+   GLfloat pos, neg, t;
+   GLfloat det;
+
+   /* Calculate the determinant of upper left 3x3 submatrix and
+    * determine if the matrix is singular. 
+    */
+   pos = neg = 0.0;
+   t =  MAT(in,0,0) * MAT(in,1,1) * MAT(in,2,2);
+   if (t >= 0.0) pos += t; else neg += t;
+
+   t =  MAT(in,1,0) * MAT(in,2,1) * MAT(in,0,2);
+   if (t >= 0.0) pos += t; else neg += t;
+
+   t =  MAT(in,2,0) * MAT(in,0,1) * MAT(in,1,2);
+   if (t >= 0.0) pos += t; else neg += t;
+
+   t = -MAT(in,2,0) * MAT(in,1,1) * MAT(in,0,2);
+   if (t >= 0.0) pos += t; else neg += t;
+
+   t = -MAT(in,1,0) * MAT(in,0,1) * MAT(in,2,2);
+   if (t >= 0.0) pos += t; else neg += t;
+
+   t = -MAT(in,0,0) * MAT(in,2,1) * MAT(in,1,2);
+   if (t >= 0.0) pos += t; else neg += t;
+
+   det = pos + neg;
+
+   if (det*det < 1e-25) 
+      return GL_FALSE;
+   
+   det = 1.0 / det;
+   MAT(out,0,0) = (  (MAT(in,1,1)*MAT(in,2,2) - MAT(in,2,1)*MAT(in,1,2) )*det);
+   MAT(out,0,1) = (- (MAT(in,0,1)*MAT(in,2,2) - MAT(in,2,1)*MAT(in,0,2) )*det);
+   MAT(out,0,2) = (  (MAT(in,0,1)*MAT(in,1,2) - MAT(in,1,1)*MAT(in,0,2) )*det);
+   MAT(out,1,0) = (- (MAT(in,1,0)*MAT(in,2,2) - MAT(in,2,0)*MAT(in,1,2) )*det);
+   MAT(out,1,1) = (  (MAT(in,0,0)*MAT(in,2,2) - MAT(in,2,0)*MAT(in,0,2) )*det);
+   MAT(out,1,2) = (- (MAT(in,0,0)*MAT(in,1,2) - MAT(in,1,0)*MAT(in,0,2) )*det);
+   MAT(out,2,0) = (  (MAT(in,1,0)*MAT(in,2,1) - MAT(in,2,0)*MAT(in,1,1) )*det);
+   MAT(out,2,1) = (- (MAT(in,0,0)*MAT(in,2,1) - MAT(in,2,0)*MAT(in,0,1) )*det);
+   MAT(out,2,2) = (  (MAT(in,0,0)*MAT(in,1,1) - MAT(in,1,0)*MAT(in,0,1) )*det);
+
+   /* Do the translation part */
+   MAT(out,0,3) = - (MAT(in,0,3) * MAT(out,0,0) +
+                    MAT(in,1,3) * MAT(out,0,1) +
+                    MAT(in,2,3) * MAT(out,0,2) );
+   MAT(out,1,3) = - (MAT(in,0,3) * MAT(out,1,0) +
+                    MAT(in,1,3) * MAT(out,1,1) +
+                    MAT(in,2,3) * MAT(out,1,2) );
+   MAT(out,2,3) = - (MAT(in,0,3) * MAT(out,2,0) +
+                    MAT(in,1,3) * MAT(out,2,1) +
+                    MAT(in,2,3) * MAT(out,2,2) );
+    
+   return GL_TRUE;
+}
+
+
+static GLboolean invert_matrix_3d( GLmatrix *mat )
+{
+   const GLfloat *in = mat->m;
+   GLfloat *out = mat->inv;
+
+   if (!TEST_MAT_FLAGS(mat, MAT_FLAGS_ANGLE_PRESERVING))
+   {
+      return invert_matrix_3d_general( mat );
+   }
+   
+   if (mat->flags & MAT_FLAG_UNIFORM_SCALE)
+   {
+      GLfloat  scale = (MAT(in,0,0) * MAT(in,0,0) +
+                       MAT(in,0,1) * MAT(in,0,1) +
+                       MAT(in,0,2) * MAT(in,0,2));
+
+      if (scale == 0.0) 
+         return GL_FALSE;
+
+      scale = 1.0 / scale;
+
+      /* Transpose and scale the 3 by 3 upper-left submatrix. */
+      MAT(out,0,0) = scale * MAT(in,0,0);
+      MAT(out,1,0) = scale * MAT(in,0,1);
+      MAT(out,2,0) = scale * MAT(in,0,2);
+      MAT(out,0,1) = scale * MAT(in,1,0);
+      MAT(out,1,1) = scale * MAT(in,1,1);
+      MAT(out,2,1) = scale * MAT(in,1,2);
+      MAT(out,0,2) = scale * MAT(in,2,0);
+      MAT(out,1,2) = scale * MAT(in,2,1);
+      MAT(out,2,2) = scale * MAT(in,2,2);
+   }
+   else if (mat->flags & MAT_FLAG_ROTATION)
+   {
+      /* Transpose the 3 by 3 upper-left submatrix. */
+      MAT(out,0,0) = MAT(in,0,0);
+      MAT(out,1,0) = MAT(in,0,1);
+      MAT(out,2,0) = MAT(in,0,2);
+      MAT(out,0,1) = MAT(in,1,0);
+      MAT(out,1,1) = MAT(in,1,1);
+      MAT(out,2,1) = MAT(in,1,2);
+      MAT(out,0,2) = MAT(in,2,0);
+      MAT(out,1,2) = MAT(in,2,1);
+      MAT(out,2,2) = MAT(in,2,2);
+   }
+   else /* pure translation */
+   {
+      MEMCPY( out, Identity, sizeof(Identity) );
+      MAT(out,0,3) = - MAT(in,0,3);
+      MAT(out,1,3) = - MAT(in,1,3);
+      MAT(out,2,3) = - MAT(in,2,3);
+      return GL_TRUE;
+   }
+    
+   if (mat->flags & MAT_FLAG_TRANSLATION)
+   {
+      /* Do the translation part */
+      MAT(out,0,3) = - (MAT(in,0,3) * MAT(out,0,0) +
+                       MAT(in,1,3) * MAT(out,0,1) +
+                       MAT(in,2,3) * MAT(out,0,2) );
+      MAT(out,1,3) = - (MAT(in,0,3) * MAT(out,1,0) +
+                       MAT(in,1,3) * MAT(out,1,1) +
+                       MAT(in,2,3) * MAT(out,1,2) );
+      MAT(out,2,3) = - (MAT(in,0,3) * MAT(out,2,0) +
+                       MAT(in,1,3) * MAT(out,2,1) +
+                       MAT(in,2,3) * MAT(out,2,2) );
+   }
+   else 
+   {
+      MAT(out,0,3) = MAT(out,1,3) = MAT(out,2,3) = 0.0;
+   }
+    
+   return GL_TRUE;
+}
+
+  
+
+static GLboolean invert_matrix_identity( GLmatrix *mat )
+{
+   MEMCPY( mat->inv, Identity, sizeof(Identity) );
+   return GL_TRUE;
+}
+
+
+static GLboolean invert_matrix_3d_no_rot( GLmatrix *mat )
+{
+   const GLfloat *in = mat->m;
+   GLfloat *out = mat->inv;
+
+   if (MAT(in,0,0) == 0 || MAT(in,1,1) == 0 || MAT(in,2,2) == 0 )       
+      return GL_FALSE;
+  
+   MEMCPY( out, Identity, 16 * sizeof(GLfloat) );
+   MAT(out,0,0) = 1.0 / MAT(in,0,0);
+   MAT(out,1,1) = 1.0 / MAT(in,1,1);
+   MAT(out,2,2) = 1.0 / MAT(in,2,2);
+
+   if (mat->flags & MAT_FLAG_TRANSLATION)
+   {
+      MAT(out,0,3) = - (MAT(in,0,3) * MAT(out,0,0));
+      MAT(out,1,3) = - (MAT(in,1,3) * MAT(out,1,1));
+      MAT(out,2,3) = - (MAT(in,2,3) * MAT(out,2,2));
+   }
+
+   return GL_TRUE;
+}
+
+
+static GLboolean invert_matrix_2d_no_rot( GLmatrix *mat )
+{
+   const GLfloat *in = mat->m;
+   GLfloat *out = mat->inv;
+
+   if (MAT(in,0,0) == 0 || MAT(in,1,1) == 0)       
+      return GL_FALSE;
+  
+   MEMCPY( out, Identity, 16 * sizeof(GLfloat) );
+   MAT(out,0,0) = 1.0 / MAT(in,0,0);
+   MAT(out,1,1) = 1.0 / MAT(in,1,1);
+
+   if (mat->flags & MAT_FLAG_TRANSLATION)
+   {
+      MAT(out,0,3) = - (MAT(in,0,3) * MAT(out,0,0));
+      MAT(out,1,3) = - (MAT(in,1,3) * MAT(out,1,1));
+   }
+
+   return GL_TRUE;
+}
+
+
+static GLboolean invert_matrix_perspective( GLmatrix *mat )
+{
+   const GLfloat *in = mat->m;
+   GLfloat *out = mat->inv;
+
+   if (MAT(in,2,3) == 0)
+      return GL_FALSE;
+
+   MEMCPY( out, Identity, 16 * sizeof(GLfloat) );
+
+   MAT(out,0,0) = 1.0 / MAT(in,0,0);
+   MAT(out,1,1) = 1.0 / MAT(in,1,1);
+
+   MAT(out,0,3) = MAT(in,0,2);
+   MAT(out,1,3) = MAT(in,1,2);
+
+   MAT(out,2,2) = 0;
+   MAT(out,2,3) = -1;
+
+   MAT(out,3,2) = 1.0 / MAT(in,2,3);
+   MAT(out,3,3) = MAT(in,2,2) * MAT(out,3,2);
+
+   return GL_TRUE;
+}
+
+
+typedef GLboolean (*inv_mat_func)( GLmatrix *mat );
+
+static inv_mat_func inv_mat_tab[7] = {
+   invert_matrix_general,
+   invert_matrix_identity,
+   invert_matrix_3d_no_rot,
+   invert_matrix_perspective,
+   invert_matrix_3d,           /* lazy! */
+   invert_matrix_2d_no_rot,
+   invert_matrix_3d
+};
+
+
+GLboolean gl_matrix_invert( GLmatrix *mat )
+{
+   if (inv_mat_tab[mat->type](mat)) {
+#if 0
+      GLmatrix m; m.inv = 0; m.type = 0; m.flags = 0;
+      matmul4( m.m, mat->m, mat->inv );
+      printf("inverted matrix of type %s:\n", types[mat->type]);
+      gl_print_matrix( mat );
+      gl_print_matrix( &m );
+#endif
+      return GL_TRUE;
+   } else {
+      MEMCPY( mat->inv, Identity, sizeof(Identity) );
+      return GL_FALSE;
+   }  
+}
+
+
+
+/*
+ * Generate a 4x4 transformation matrix from glRotate parameters.
+ */
+void gl_rotation_matrix( GLfloat angle, GLfloat x, GLfloat y, GLfloat z,
+                         GLfloat m[] )
+{
+   /* This function contributed by Erich Boleyn (erich@uruk.org) */
+   GLfloat mag, s, c;
+   GLfloat xx, yy, zz, xy, yz, zx, xs, ys, zs, one_c;
+
+   s = sin( angle * DEG2RAD );
+   c = cos( angle * DEG2RAD );
+
+   mag = GL_SQRT( x*x + y*y + z*z );
+
+   if (mag == 0.0) {
+      /* generate an identity matrix and return */
+      MEMCPY(m, Identity, sizeof(GLfloat)*16);
+      return;
+   }
+
+   x /= mag;
+   y /= mag;
+   z /= mag;
+
+#define M(row,col)  m[col*4+row]
+
+   /*
+    *     Arbitrary axis rotation matrix.
+    *
+    *  This is composed of 5 matrices, Rz, Ry, T, Ry', Rz', multiplied
+    *  like so:  Rz * Ry * T * Ry' * Rz'.  T is the final rotation
+    *  (which is about the X-axis), and the two composite transforms
+    *  Ry' * Rz' and Rz * Ry are (respectively) the rotations necessary
+    *  from the arbitrary axis to the X-axis then back.  They are
+    *  all elementary rotations.
+    *
+    *  Rz' is a rotation about the Z-axis, to bring the axis vector
+    *  into the x-z plane.  Then Ry' is applied, rotating about the
+    *  Y-axis to bring the axis vector parallel with the X-axis.  The
+    *  rotation about the X-axis is then performed.  Ry and Rz are
+    *  simply the respective inverse transforms to bring the arbitrary
+    *  axis back to it's original orientation.  The first transforms
+    *  Rz' and Ry' are considered inverses, since the data from the
+    *  arbitrary axis gives you info on how to get to it, not how
+    *  to get away from it, and an inverse must be applied.
+    *
+    *  The basic calculation used is to recognize that the arbitrary
+    *  axis vector (x, y, z), since it is of unit length, actually
+    *  represents the sines and cosines of the angles to rotate the
+    *  X-axis to the same orientation, with theta being the angle about
+    *  Z and phi the angle about Y (in the order described above)
+    *  as follows:
+    *
+    *  cos ( theta ) = x / sqrt ( 1 - z^2 )
+    *  sin ( theta ) = y / sqrt ( 1 - z^2 )
+    *
+    *  cos ( phi ) = sqrt ( 1 - z^2 )
+    *  sin ( phi ) = z
+    *
+    *  Note that cos ( phi ) can further be inserted to the above
+    *  formulas:
+    *
+    *  cos ( theta ) = x / cos ( phi )
+    *  sin ( theta ) = y / sin ( phi )
+    *
+    *  ...etc.  Because of those relations and the standard trigonometric
+    *  relations, it is pssible to reduce the transforms down to what
+    *  is used below.  It may be that any primary axis chosen will give the
+    *  same results (modulo a sign convention) using thie method.
+    *
+    *  Particularly nice is to notice that all divisions that might
+    *  have caused trouble when parallel to certain planes or
+    *  axis go away with care paid to reducing the expressions.
+    *  After checking, it does perform correctly under all cases, since
+    *  in all the cases of division where the denominator would have
+    *  been zero, the numerator would have been zero as well, giving
+    *  the expected result.
+    */
+
+   xx = x * x;
+   yy = y * y;
+   zz = z * z;
+   xy = x * y;
+   yz = y * z;
+   zx = z * x;
+   xs = x * s;
+   ys = y * s;
+   zs = z * s;
+   one_c = 1.0F - c;
+
+   M(0,0) = (one_c * xx) + c;
+   M(0,1) = (one_c * xy) - zs;
+   M(0,2) = (one_c * zx) + ys;
+   M(0,3) = 0.0F;
+
+   M(1,0) = (one_c * xy) + zs;
+   M(1,1) = (one_c * yy) + c;
+   M(1,2) = (one_c * yz) - xs;
+   M(1,3) = 0.0F;
+
+   M(2,0) = (one_c * zx) - ys;
+   M(2,1) = (one_c * yz) + xs;
+   M(2,2) = (one_c * zz) + c;
+   M(2,3) = 0.0F;
+
+   M(3,0) = 0.0F;
+   M(3,1) = 0.0F;
+   M(3,2) = 0.0F;
+   M(3,3) = 1.0F;
+
+#undef M
+}
+
+#define ZERO(x) (1<<x)
+#define ONE(x)  (1<<(x+16))
+
+#define MASK_NO_TRX      (ZERO(12) | ZERO(13) | ZERO(14))
+#define MASK_NO_2D_SCALE ( ONE(0)  | ONE(5))
+
+#define MASK_IDENTITY    ( ONE(0)  | ZERO(4)  | ZERO(8)  | ZERO(12) |\
+                         ZERO(1)  |  ONE(5)  | ZERO(9)  | ZERO(13) |\
+                         ZERO(2)  | ZERO(6)  |  ONE(10) | ZERO(14) |\
+                         ZERO(3)  | ZERO(7)  | ZERO(11) |  ONE(15) )
+
+#define MASK_2D_NO_ROT   (           ZERO(4)  | ZERO(8)  |           \
+                         ZERO(1)  |            ZERO(9)  |           \
+                         ZERO(2)  | ZERO(6)  |  ONE(10) | ZERO(14) |\
+                         ZERO(3)  | ZERO(7)  | ZERO(11) |  ONE(15) )
+
+#define MASK_2D          (                      ZERO(8)  |           \
+                                               ZERO(9)  |           \
+                         ZERO(2)  | ZERO(6)  |  ONE(10) | ZERO(14) |\
+                         ZERO(3)  | ZERO(7)  | ZERO(11) |  ONE(15) )
+
+
+#define MASK_3D_NO_ROT   (           ZERO(4)  | ZERO(8)  |           \
+                         ZERO(1)  |            ZERO(9)  |           \
+                         ZERO(2)  | ZERO(6)  |                      \
+                         ZERO(3)  | ZERO(7)  | ZERO(11) |  ONE(15) )
+
+#define MASK_3D          (                                           \
+                                                                    \
+                                                                    \
+                         ZERO(3)  | ZERO(7)  | ZERO(11) |  ONE(15) )
+
+
+#define MASK_PERSPECTIVE (           ZERO(4)  |            ZERO(12) |\
+                         ZERO(1)  |                       ZERO(13) |\
+                         ZERO(2)  | ZERO(6)  |                      \
+                         ZERO(3)  | ZERO(7)  |            ZERO(15) )
+
+#define SQ(x) ((x)*(x))
+  
+/* Determine type and flags from scratch.  This is expensive enough to
+ * only want to do it once.
+ */
+static void analyze_from_scratch( GLmatrix *mat )
+{
+   const GLfloat *m = mat->m;
+   GLuint mask = 0;
+   GLuint i;
+
+   for (i = 0 ; i < 16 ; i++) 
+   {
+      if (m[i] == 0.0) mask |= (1<<i);
+   }
+   
+   if (m[0] == 1.0F) mask |= (1<<16);
+   if (m[5] == 1.0F) mask |= (1<<21);
+   if (m[10] == 1.0F) mask |= (1<<26);
+   if (m[15] == 1.0F) mask |= (1<<31);
+
+   mat->flags &= ~MAT_FLAGS_GEOMETRY;
+
+   /* Check for translation - no-one really cares 
+    */
+   if ((mask & MASK_NO_TRX) != MASK_NO_TRX) 
+      mat->flags |= MAT_FLAG_TRANSLATION;      
+
+   /* Do the real work
+    */
+   if (mask == MASK_IDENTITY) {
+      mat->type = MATRIX_IDENTITY;
+   }
+   else if ((mask & MASK_2D_NO_ROT) == MASK_2D_NO_ROT)  
+   {
+      mat->type = MATRIX_2D_NO_ROT;
+      
+      if ((mask & MASK_NO_2D_SCALE) != MASK_NO_2D_SCALE)
+        mat->flags = MAT_FLAG_GENERAL_SCALE;
+   }
+   else if ((mask & MASK_2D) == MASK_2D)  
+   {
+      GLfloat mm = DOT2(m, m);
+      GLfloat m4m4 = DOT2(m+4,m+4);
+      GLfloat mm4 = DOT2(m,m+4);
+
+      mat->type = MATRIX_2D;
+
+      /* Check for scale */
+      if (SQ(mm-1) > SQ(1e-6) ||
+         SQ(m4m4-1) > SQ(1e-6)) 
+        mat->flags |= MAT_FLAG_GENERAL_SCALE;
+
+      /* Check for rotation */
+      if (SQ(mm4) > SQ(1e-6))
+        mat->flags |= MAT_FLAG_GENERAL_3D;
+      else
+        mat->flags |= MAT_FLAG_ROTATION;
+
+   }
+   else if ((mask & MASK_3D_NO_ROT) == MASK_3D_NO_ROT)
+   {
+      mat->type = MATRIX_3D_NO_ROT;
+
+      /* Check for scale */
+      if (SQ(m[0]-m[5]) < SQ(1e-6) && 
+         SQ(m[0]-m[10]) < SQ(1e-6)) {
+        if (SQ(m[0]-1.0) > SQ(1e-6))
+           mat->flags |= MAT_FLAG_UNIFORM_SCALE;
+      } else
+        mat->flags |= MAT_FLAG_GENERAL_SCALE;
+   }
+   else if ((mask & MASK_3D) == MASK_3D)
+   {
+      GLfloat c1 = DOT3(m,m);
+      GLfloat c2 = DOT3(m+4,m+4);
+      GLfloat c3 = DOT3(m+8,m+8);
+      GLfloat d1 = DOT3(m, m+4);
+      GLfloat cp[3];
+
+      mat->type = MATRIX_3D;
+
+      /* Check for scale */
+      if (SQ(c1-c2) < SQ(1e-6) && SQ(c1-c3) < SQ(1e-6)) {
+        if (SQ(c1-1.0) > SQ(1e-6))
+           mat->flags |= MAT_FLAG_UNIFORM_SCALE;
+        /* else no scale at all */
+      } else 
+        mat->flags |= MAT_FLAG_GENERAL_SCALE;
+
+      /* Check for rotation */
+      if (SQ(d1) < SQ(1e-6)) {
+        CROSS3( cp, m, m+4 );
+        SUB_3V( cp, cp, (m+8) );
+        if (LEN_SQUARED_3FV(cp) < SQ(1e-6)) 
+           mat->flags |= MAT_FLAG_ROTATION;
+        else
+           mat->flags |= MAT_FLAG_GENERAL_3D;
+      }
+      else
+        mat->flags |= MAT_FLAG_GENERAL_3D; /* shear, etc */
+   }
+   else if ((mask & MASK_PERSPECTIVE) == MASK_PERSPECTIVE && m[11]==-1.0F) 
+   {
+      mat->type = MATRIX_PERSPECTIVE;
+      mat->flags |= MAT_FLAG_GENERAL;
+   }
+   else {
+      mat->type = MATRIX_GENERAL;
+      mat->flags |= MAT_FLAG_GENERAL;
+   }
+}
+
+
+/* Analyse a matrix given that its flags are accurate - this is the
+ * more common operation, hopefully. 
+ */
+static void analyze_from_flags( GLmatrix *mat )
+{
+   const GLfloat *m = mat->m;
+
+   if (TEST_MAT_FLAGS(mat, 0)) {
+      mat->type = MATRIX_IDENTITY;
+   }
+   else if (TEST_MAT_FLAGS(mat, (MAT_FLAG_TRANSLATION |
+                                MAT_FLAG_UNIFORM_SCALE |
+                                MAT_FLAG_GENERAL_SCALE)))
+   {
+      if ( m[10]==1.0F && m[14]==0.0F ) {
+        mat->type = MATRIX_2D_NO_ROT;
+      }
+      else {
+        mat->type = MATRIX_3D_NO_ROT;
+      }
+   }
+   else if (TEST_MAT_FLAGS(mat, MAT_FLAGS_3D)) {
+      if (                                 m[ 8]==0.0F               
+            &&                             m[ 9]==0.0F
+            && m[2]==0.0F && m[6]==0.0F && m[10]==1.0F && m[14]==0.0F)
+      {
+        mat->type = MATRIX_2D;
+      }
+      else 
+      {
+        mat->type = MATRIX_3D;
+      }
+   }
+   else if (                 m[4]==0.0F                 && m[12]==0.0F
+            && m[1]==0.0F                               && m[13]==0.0F
+            && m[2]==0.0F && m[6]==0.0F
+            && m[3]==0.0F && m[7]==0.0F && m[11]==-1.0F && m[15]==0.0F) 
+   {
+      mat->type = MATRIX_PERSPECTIVE;
+   }
+   else {
+      mat->type = MATRIX_GENERAL;
+   }
+
+}
+
+
+void gl_matrix_analyze( GLmatrix *mat ) 
+{
+   if (mat->flags & MAT_DIRTY_TYPE) {
+      if (mat->flags & MAT_DIRTY_FLAGS) 
+        analyze_from_scratch( mat );
+      else
+        analyze_from_flags( mat );
+   }
+
+   if (mat->inv && (mat->flags & MAT_DIRTY_INVERSE)) {
+      gl_matrix_invert( mat );
+   }
+
+   mat->flags &= ~(MAT_DIRTY_FLAGS|
+                  MAT_DIRTY_TYPE|
+                  MAT_DIRTY_INVERSE);
+}
+
+
+#define GET_ACTIVE_MATRIX(ctx, mat, flags, where)                      \
+do {                                                                   \
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, where);                      \
+   if (MESA_VERBOSE&VERBOSE_API) fprintf(stderr, "%s\n", where);        \
+   switch (ctx->Transform.MatrixMode) {                                        \
+      case GL_MODELVIEW:                                               \
+        mat = &ctx->ModelView;                                         \
+        flags |= NEW_MODELVIEW;                                        \
+        break;                                                         \
+      case GL_PROJECTION:                                              \
+        mat = &ctx->ProjectionMatrix;                                  \
+        flags |= NEW_PROJECTION;                                       \
+        break;                                                         \
+      case GL_TEXTURE:                                                 \
+        mat = &ctx->TextureMatrix[ctx->Texture.CurrentTransformUnit];  \
+        flags |= NEW_TEXTURE_MATRIX;                                   \
+        break;                                                         \
+      default:                                                         \
+         gl_problem(ctx, where);                                       \
+   }                                                                   \
+} while (0)
+
+
+void gl_Frustum( GLcontext *ctx,
+                 GLdouble left, GLdouble right,
+                GLdouble bottom, GLdouble top,
+                GLdouble nearval, GLdouble farval )
+{
+   GLfloat x, y, a, b, c, d;
+   GLfloat m[16];
+   GLmatrix *mat = 0;
+
+   GET_ACTIVE_MATRIX( ctx,  mat, ctx->NewState, "glFrustrum" );
+
+   if (nearval<=0.0 || farval<=0.0) {
+      gl_error( ctx,  GL_INVALID_VALUE, "glFrustum(near or far)" );
+   }
+
+   x = (2.0*nearval) / (right-left);
+   y = (2.0*nearval) / (top-bottom);
+   a = (right+left) / (right-left);
+   b = (top+bottom) / (top-bottom);
+   c = -(farval+nearval) / ( farval-nearval);
+   d = -(2.0*farval*nearval) / (farval-nearval);  /* error? */
+
+#define M(row,col)  m[col*4+row]
+   M(0,0) = x;     M(0,1) = 0.0F;  M(0,2) = a;      M(0,3) = 0.0F;
+   M(1,0) = 0.0F;  M(1,1) = y;     M(1,2) = b;      M(1,3) = 0.0F;
+   M(2,0) = 0.0F;  M(2,1) = 0.0F;  M(2,2) = c;      M(2,3) = d;
+   M(3,0) = 0.0F;  M(3,1) = 0.0F;  M(3,2) = -1.0F;  M(3,3) = 0.0F;
+#undef M
+
+
+   gl_mat_mul_floats( mat, m, MAT_FLAG_PERSPECTIVE );
+
+
+   if (ctx->Transform.MatrixMode == GL_PROJECTION)
+   {
+      /* Need to keep a stack of near/far values in case the user push/pops
+       * the projection matrix stack so that we can call Driver.NearFar()
+       * after a pop.
+       */
+      ctx->NearFarStack[ctx->ProjectionStackDepth][0] = nearval;
+      ctx->NearFarStack[ctx->ProjectionStackDepth][1] = farval;
+      
+      if (ctx->Driver.NearFar) {
+        (*ctx->Driver.NearFar)( ctx, nearval, farval );
+      }
+   }
+}
+
+
+void gl_Ortho( GLcontext *ctx,
+               GLdouble left, GLdouble right,
+               GLdouble bottom, GLdouble top,
+               GLdouble nearval, GLdouble farval )
+{
+   GLfloat x, y, z;
+   GLfloat tx, ty, tz;
+   GLfloat m[16];
+   GLmatrix *mat = 0;
+
+   GET_ACTIVE_MATRIX( ctx,  mat, ctx->NewState, "glOrtho" );
+
+   x = 2.0 / (right-left);
+   y = 2.0 / (top-bottom);
+   z = -2.0 / (farval-nearval);
+   tx = -(right+left) / (right-left);
+   ty = -(top+bottom) / (top-bottom);
+   tz = -(farval+nearval) / (farval-nearval);
+
+#define M(row,col)  m[col*4+row]
+   M(0,0) = x;     M(0,1) = 0.0F;  M(0,2) = 0.0F;  M(0,3) = tx;
+   M(1,0) = 0.0F;  M(1,1) = y;     M(1,2) = 0.0F;  M(1,3) = ty;
+   M(2,0) = 0.0F;  M(2,1) = 0.0F;  M(2,2) = z;     M(2,3) = tz;
+   M(3,0) = 0.0F;  M(3,1) = 0.0F;  M(3,2) = 0.0F;  M(3,3) = 1.0F;
+#undef M
+
+   gl_mat_mul_floats( mat, m, (MAT_FLAG_GENERAL_SCALE|MAT_FLAG_TRANSLATION));
+
+   if (ctx->Driver.NearFar) {
+      (*ctx->Driver.NearFar)( ctx, nearval, farval );
+   }
+}
+
+
+void gl_MatrixMode( GLcontext *ctx, GLenum mode )
+{
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glMatrixMode");
+   switch (mode) {
+      case GL_MODELVIEW:
+      case GL_PROJECTION:
+      case GL_TEXTURE:
+         ctx->Transform.MatrixMode = mode;
+         break;
+      default:
+         gl_error( ctx,  GL_INVALID_ENUM, "glMatrixMode" );
+   }
+}
+
+
+
+void gl_PushMatrix( GLcontext *ctx )
+{
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPushMatrix");
+
+   if (MESA_VERBOSE&VERBOSE_API)
+      fprintf(stderr, "glPushMatrix %s\n", 
+             gl_lookup_enum_by_nr(ctx->Transform.MatrixMode));
+
+   switch (ctx->Transform.MatrixMode) {
+      case GL_MODELVIEW:
+         if (ctx->ModelViewStackDepth>=MAX_MODELVIEW_STACK_DEPTH-1) {
+            gl_error( ctx,  GL_STACK_OVERFLOW, "glPushMatrix");
+            return;
+         }
+         gl_matrix_copy( &ctx->ModelViewStack[ctx->ModelViewStackDepth++],
+                        &ctx->ModelView );
+         break;
+      case GL_PROJECTION:
+         if (ctx->ProjectionStackDepth>=MAX_PROJECTION_STACK_DEPTH) {
+            gl_error( ctx,  GL_STACK_OVERFLOW, "glPushMatrix");
+            return;
+         }
+         gl_matrix_copy( &ctx->ProjectionStack[ctx->ProjectionStackDepth++],
+                        &ctx->ProjectionMatrix );
+
+         /* Save near and far projection values */
+         ctx->NearFarStack[ctx->ProjectionStackDepth][0]
+            = ctx->NearFarStack[ctx->ProjectionStackDepth-1][0];
+         ctx->NearFarStack[ctx->ProjectionStackDepth][1]
+            = ctx->NearFarStack[ctx->ProjectionStackDepth-1][1];
+         break;
+      case GL_TEXTURE:
+         {
+            GLuint t = ctx->Texture.CurrentTransformUnit;
+            if (ctx->TextureStackDepth[t] >= MAX_TEXTURE_STACK_DEPTH) {
+               gl_error( ctx,  GL_STACK_OVERFLOW, "glPushMatrix");
+               return;
+            }
+           gl_matrix_copy( &ctx->TextureStack[t][ctx->TextureStackDepth[t]++],
+                           &ctx->TextureMatrix[t] );
+         }
+         break;
+      default:
+         gl_problem(ctx, "Bad matrix mode in gl_PushMatrix");
+   }
+}
+
+
+
+void gl_PopMatrix( GLcontext *ctx )
+{
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPopMatrix");
+
+   if (MESA_VERBOSE&VERBOSE_API)
+      fprintf(stderr, "glPopMatrix %s\n", 
+             gl_lookup_enum_by_nr(ctx->Transform.MatrixMode));
+
+   switch (ctx->Transform.MatrixMode) {
+      case GL_MODELVIEW:
+         if (ctx->ModelViewStackDepth==0) {
+            gl_error( ctx,  GL_STACK_UNDERFLOW, "glPopMatrix");
+            return;
+         }
+         gl_matrix_copy( &ctx->ModelView,
+                        &ctx->ModelViewStack[--ctx->ModelViewStackDepth] );
+        ctx->NewState |= NEW_MODELVIEW;
+         break;
+      case GL_PROJECTION:
+         if (ctx->ProjectionStackDepth==0) {
+            gl_error( ctx,  GL_STACK_UNDERFLOW, "glPopMatrix");
+            return;
+         }
+
+         gl_matrix_copy( &ctx->ProjectionMatrix,
+                        &ctx->ProjectionStack[--ctx->ProjectionStackDepth] );
+        ctx->NewState |= NEW_PROJECTION;
+
+         /* Device driver near/far values */
+         {
+            GLfloat nearVal = ctx->NearFarStack[ctx->ProjectionStackDepth][0];
+            GLfloat farVal  = ctx->NearFarStack[ctx->ProjectionStackDepth][1];
+            if (ctx->Driver.NearFar) {
+               (*ctx->Driver.NearFar)( ctx, nearVal, farVal );
+            }
+         }
+         break;
+      case GL_TEXTURE:
+         {
+            GLuint t = ctx->Texture.CurrentTransformUnit;
+            if (ctx->TextureStackDepth[t]==0) {
+               gl_error( ctx,  GL_STACK_UNDERFLOW, "glPopMatrix");
+               return;
+            }
+           gl_matrix_copy(&ctx->TextureMatrix[t],
+                          &ctx->TextureStack[t][--ctx->TextureStackDepth[t]]);
+         }
+         break;
+      default:
+         gl_problem(ctx, "Bad matrix mode in gl_PopMatrix");
+   }
+}
+
+
+
+void gl_LoadIdentity( GLcontext *ctx )
+{
+   GLmatrix *mat = 0;
+   GET_ACTIVE_MATRIX(ctx, mat, ctx->NewState, "glLoadIdentity");
+
+   MEMCPY( mat->m, Identity, 16*sizeof(GLfloat) );
+
+   if (mat->inv)
+      MEMCPY( mat->inv, Identity, 16*sizeof(GLfloat) );
+
+   mat->type = MATRIX_IDENTITY;
+   
+   /* Have to set this to dirty to make sure we recalculate the
+    * combined matrix later.  The update_matrix in this case is a
+    * shortcircuit anyway...
+    */
+   mat->flags = MAT_DIRTY_DEPENDENTS;  
+}
+
+
+void gl_LoadMatrixf( GLcontext *ctx, const GLfloat *m )
+{
+   GLmatrix *mat = 0;
+   GET_ACTIVE_MATRIX(ctx, mat, ctx->NewState, "glLoadMatrix");
+
+   MEMCPY( mat->m, m, 16*sizeof(GLfloat) );
+   mat->flags = (MAT_FLAG_GENERAL | MAT_DIRTY_ALL_OVER);
+
+   if (ctx->Transform.MatrixMode == GL_PROJECTION) {
+
+#define M(row,col)  m[col*4+row]
+      GLfloat c = M(2,2);
+      GLfloat d = M(2,3);
+#undef M
+      GLfloat n = (c ==  1.0 ? 0.0 : d / (c - 1.0));
+      GLfloat f = (c == -1.0 ? 1.0 : d / (c + 1.0));
+
+      /* Need to keep a stack of near/far values in case the user
+       * push/pops the projection matrix stack so that we can call
+       * Driver.NearFar() after a pop.
+       */
+      ctx->NearFarStack[ctx->ProjectionStackDepth][0] = n;
+      ctx->NearFarStack[ctx->ProjectionStackDepth][1] = f;
+
+      if (ctx->Driver.NearFar) {
+        (*ctx->Driver.NearFar)( ctx, n, f );
+      }
+   }
+}
+
+
+
+/*
+ * Multiply the active matrix by an arbitary matrix.
+ */
+void gl_MultMatrixf( GLcontext *ctx, const GLfloat *m )
+{
+   GLmatrix *mat = 0;
+   GET_ACTIVE_MATRIX( ctx,  mat, ctx->NewState, "glMultMatrix" );
+   matmul4( mat->m, mat->m, m );
+   mat->flags = (MAT_FLAG_GENERAL | MAT_DIRTY_ALL_OVER);
+}
+
+
+/*
+ * Multiply the active matrix by an arbitary matrix.  
+ */
+void gl_MultMatrixd( GLcontext *ctx, const GLdouble *m )
+{
+   GLmatrix *mat = 0;
+   GET_ACTIVE_MATRIX( ctx,  mat, ctx->NewState, "glMultMatrix" );
+   matmul4fd( mat->m, mat->m, m );
+   mat->flags = (MAT_FLAG_GENERAL | MAT_DIRTY_ALL_OVER);
+}
+
+
+
+
+/*
+ * Multiply a matrix by an array of floats with known properties.
+ */
+void gl_mat_mul_floats( GLmatrix *mat, const GLfloat *m, GLuint flags )
+{
+   mat->flags |= (flags |
+                 MAT_DIRTY_TYPE | 
+                 MAT_DIRTY_INVERSE | 
+                 MAT_DIRTY_DEPENDENTS);
+
+   if (TEST_MAT_FLAGS(mat, MAT_FLAGS_3D))
+      matmul34( mat->m, mat->m, m );
+   else 
+      matmul4( mat->m, mat->m, m );      
+
+}
+
+/*
+ * Multiply a matrix by an array of floats with known properties.
+ */
+void gl_mat_mul_mat( GLmatrix *mat, const GLmatrix *m )
+{
+   mat->flags |= (m->flags |
+                 MAT_DIRTY_TYPE | 
+                 MAT_DIRTY_INVERSE | 
+                 MAT_DIRTY_DEPENDENTS);
+
+   if (TEST_MAT_FLAGS(mat, MAT_FLAGS_3D))
+      matmul34( mat->m, mat->m, m->m );
+   else 
+      matmul4( mat->m, mat->m, m->m );      
+}
+
+
+
+/*
+ * Execute a glRotate call
+ */
+void gl_Rotatef( GLcontext *ctx,
+                 GLfloat angle, GLfloat x, GLfloat y, GLfloat z )
+{
+   GLfloat m[16];
+   if (angle != 0.0F) {
+      GLmatrix *mat = 0;
+      GET_ACTIVE_MATRIX( ctx,  mat, ctx->NewState, "glRotate" );
+
+      gl_rotation_matrix( angle, x, y, z, m );
+      gl_mat_mul_floats( mat, m, MAT_FLAG_ROTATION );
+   }
+}
+
+/*
+ * Execute a glScale call
+ */
+void gl_Scalef( GLcontext *ctx, GLfloat x, GLfloat y, GLfloat z )
+{
+   GLmatrix *mat = 0;
+   GLfloat *m;
+   GET_ACTIVE_MATRIX(ctx, mat, ctx->NewState, "glScale");
+
+   m = mat->m;
+   m[0] *= x;   m[4] *= y;   m[8]  *= z;
+   m[1] *= x;   m[5] *= y;   m[9]  *= z;
+   m[2] *= x;   m[6] *= y;   m[10] *= z;
+   m[3] *= x;   m[7] *= y;   m[11] *= z;
+
+   if (fabs(x - y) < 1e-8 && fabs(x - z) < 1e-8)
+      mat->flags |= MAT_FLAG_UNIFORM_SCALE;
+   else
+      mat->flags |= MAT_FLAG_GENERAL_SCALE;
+
+   mat->flags |= (MAT_DIRTY_TYPE | 
+                 MAT_DIRTY_INVERSE | 
+                 MAT_DIRTY_DEPENDENTS);
+}
+
+/*
+ * Execute a glTranslate call
+ */
+void gl_Translatef( GLcontext *ctx, GLfloat x, GLfloat y, GLfloat z )
+{
+   GLmatrix *mat = 0;
+   GLfloat *m;
+   GET_ACTIVE_MATRIX(ctx, mat, ctx->NewState, "glTranslate");
+   m = mat->m;
+   m[12] = m[0] * x + m[4] * y + m[8]  * z + m[12];
+   m[13] = m[1] * x + m[5] * y + m[9]  * z + m[13];
+   m[14] = m[2] * x + m[6] * y + m[10] * z + m[14];
+   m[15] = m[3] * x + m[7] * y + m[11] * z + m[15];
+
+   mat->flags |= (MAT_FLAG_TRANSLATION | 
+                 MAT_DIRTY_TYPE | 
+                 MAT_DIRTY_INVERSE | 
+                 MAT_DIRTY_DEPENDENTS);
+}
+
+
+/*
+ * Define a new viewport and reallocate auxillary buffers if the size of
+ * the window (color buffer) has changed.
+ */
+void gl_Viewport( GLcontext *ctx,
+                  GLint x, GLint y, GLsizei width, GLsizei height )
+{
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glViewport");
+
+   if (width<0 || height<0) {
+      gl_error( ctx,  GL_INVALID_VALUE, "glViewport" );
+      return;
+   }
+
+   if (MESA_VERBOSE & VERBOSE_API)
+      fprintf(stderr, "glViewport %d %d %d %d\n", x, y, width, height);
+   
+   /* clamp width, and height to implementation dependent range */
+   width  = CLAMP( width,  1, MAX_WIDTH );
+   height = CLAMP( height, 1, MAX_HEIGHT );
+
+   /* Save viewport */
+   ctx->Viewport.X = x;
+   ctx->Viewport.Width = width;
+   ctx->Viewport.Y = y;
+   ctx->Viewport.Height = height;
+
+   /* compute scale and bias values */
+   ctx->Viewport.WindowMap.m[MAT_SX] = (GLfloat) width / 2.0F;
+   ctx->Viewport.WindowMap.m[MAT_TX] = ctx->Viewport.WindowMap.m[MAT_SX] + x;
+   ctx->Viewport.WindowMap.m[MAT_SY] = (GLfloat) height / 2.0F;
+   ctx->Viewport.WindowMap.m[MAT_TY] = ctx->Viewport.WindowMap.m[MAT_SY] + y;
+
+   ctx->ModelProjectWinMatrixUptodate = GL_FALSE;
+   ctx->NewState |= NEW_VIEWPORT;
+
+   /* Check if window/buffer has been resized and if so, reallocate the
+    * ancillary buffers.
+    */
+   gl_ResizeBuffersMESA(ctx);
+
+
+   ctx->RasterMask &= WINCLIP_BIT;
+
+   if (   ctx->Viewport.X<0
+       || ctx->Viewport.X + ctx->Viewport.Width > ctx->Buffer->Width
+       || ctx->Viewport.Y<0
+       || ctx->Viewport.Y + ctx->Viewport.Height > ctx->Buffer->Height) {
+      ctx->RasterMask |= WINCLIP_BIT;
+   }
+
+
+   if (ctx->Driver.Viewport) {
+      (*ctx->Driver.Viewport)( ctx, x, y, width, height );
+   }
+}
+
+
+
+void gl_DepthRange( GLcontext *ctx, GLclampd nearval, GLclampd farval )
+{
+   /*
+    * nearval - specifies mapping of the near clipping plane to window
+    *   coordinates, default is 0
+    * farval - specifies mapping of the far clipping plane to window
+    *   coordinates, default is 1
+    *
+    * After clipping and div by w, z coords are in -1.0 to 1.0,
+    * corresponding to near and far clipping planes.  glDepthRange
+    * specifies a linear mapping of the normalized z coords in
+    * this range to window z coords.
+    */
+   GLfloat n, f;
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDepthRange");
+
+   if (MESA_VERBOSE&VERBOSE_API)
+      fprintf(stderr, "glDepthRange %f %f\n", nearval, farval); 
+
+   n = (GLfloat) CLAMP( nearval, 0.0, 1.0 );
+   f = (GLfloat) CLAMP( farval, 0.0, 1.0 );
+
+   ctx->Viewport.Near = n;
+   ctx->Viewport.Far = f;
+   ctx->Viewport.WindowMap.m[MAT_SZ] = DEPTH_SCALE * ((f - n) / 2.0);
+   ctx->Viewport.WindowMap.m[MAT_TZ] = DEPTH_SCALE * ((f - n) / 2.0 + n);
+
+   ctx->ModelProjectWinMatrixUptodate = GL_FALSE;
+
+   if (ctx->Driver.DepthRange) {
+      (*ctx->Driver.DepthRange)( ctx, nearval, farval );
+   }
+}
+
+
+void gl_calculate_model_project_matrix( GLcontext *ctx )
+{
+   gl_matrix_mul( &ctx->ModelProjectMatrix,
+                 &ctx->ProjectionMatrix,
+                 &ctx->ModelView );
+
+   gl_matrix_analyze( &ctx->ModelProjectMatrix );
+}
+
+
+void gl_matrix_ctr( GLmatrix *m )
+{
+   m->inv = 0;
+   MEMCPY( m->m, Identity, sizeof(Identity));
+   m->type = MATRIX_IDENTITY;
+   m->flags = MAT_DIRTY_DEPENDENTS;
+}
+
+void gl_matrix_dtr( GLmatrix *m )
+{
+   if (m->inv != 0) {
+      free(m->inv);
+      m->inv = 0;
+   }
+}
+
+void gl_matrix_alloc_inv( GLmatrix *m )
+{
+   if (m->inv == 0) {
+      m->inv = (GLfloat *)malloc(16*sizeof(GLfloat));
+      MEMCPY( m->inv, Identity, 16 * sizeof(GLfloat) );
+   }
+}
+
+void gl_matrix_copy( GLmatrix *to, const GLmatrix *from )
+{
+   MEMCPY( to->m, from->m, sizeof(Identity));
+   to->flags = from->flags | MAT_DIRTY_DEPENDENTS;
+   to->type = from->type;
+
+   if (to->inv != 0) {
+      if (from->inv == 0) {
+        gl_matrix_invert( to );
+      } else {
+        MEMCPY(to->inv, from->inv, sizeof(GLfloat)*16);
+      }
+   }
+}
+
+void gl_matrix_mul( GLmatrix *dest, const GLmatrix *a, const GLmatrix *b )
+{
+   dest->flags = (a->flags |
+                 b->flags |
+                 MAT_DIRTY_TYPE | 
+                 MAT_DIRTY_INVERSE | 
+                 MAT_DIRTY_DEPENDENTS);
+
+   if (TEST_MAT_FLAGS(dest, MAT_FLAGS_3D))
+      matmul34( dest->m, a->m, b->m );
+   else 
+      matmul4( dest->m, a->m, b->m );
+}
diff --git a/src/mesa/main/matrix.h b/src/mesa/main/matrix.h
new file mode 100644 (file)
index 0000000..f89993e
--- /dev/null
@@ -0,0 +1,115 @@
+/* $Id: matrix.h,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+#ifndef MATRIX_H
+#define MATRIX_H
+
+
+#include "GL/gl.h"
+#include "config.h"
+
+typedef struct {
+   GLfloat m[16];
+   GLfloat *inv;               /* optional */
+   GLuint flags;
+   GLuint type;
+} GLmatrix;
+
+#ifdef VMS
+#define gl_calculate_model_project_matrix gl_calculate_model_project_matr
+#endif
+
+
+extern void gl_rotation_matrix( GLfloat angle, GLfloat x, GLfloat y, GLfloat z,
+                                GLfloat m[] );
+
+
+
+extern void gl_Frustum( GLcontext *ctx,
+                        GLdouble left, GLdouble right,
+                        GLdouble bottom, GLdouble top,
+                        GLdouble nearval, GLdouble farval );
+
+extern void gl_Ortho( GLcontext *ctx,
+                      GLdouble left, GLdouble right,
+                      GLdouble bottom, GLdouble top,
+                      GLdouble nearval, GLdouble farval );
+
+extern void gl_PushMatrix( GLcontext *ctx );
+
+extern void gl_PopMatrix( GLcontext *ctx );
+
+extern void gl_LoadIdentity( GLcontext *ctx );
+
+extern void gl_LoadMatrixf( GLcontext *ctx, const GLfloat *m );
+
+extern void gl_MatrixMode( GLcontext *ctx, GLenum mode );
+
+extern void gl_MultMatrixf( GLcontext *ctx, const GLfloat *m );
+
+extern void gl_mat_mul_floats( GLmatrix *mat, const GLfloat *m, GLuint flags );
+extern void gl_mat_mul_mat( GLmatrix *mat, const GLmatrix *mat2 );
+
+extern void gl_Rotatef( GLcontext *ctx,
+                        GLfloat angle, GLfloat x, GLfloat y, GLfloat z );
+
+extern void gl_Scalef( GLcontext *ctx, GLfloat x, GLfloat y, GLfloat z );
+
+extern void gl_Translatef( GLcontext *ctx, GLfloat x, GLfloat y, GLfloat z );
+
+extern void gl_Viewport( GLcontext *ctx,
+                         GLint x, GLint y, GLsizei width, GLsizei height );
+
+extern void gl_DepthRange( GLcontext* ctx, GLclampd nearval, GLclampd farval );
+
+
+
+
+
+extern void gl_calculate_model_project_matrix( GLcontext *ctx );
+
+
+extern void gl_matrix_ctr( GLmatrix *m );
+
+extern void gl_matrix_dtr( GLmatrix *m );
+
+extern void gl_matrix_alloc_inv( GLmatrix *m );
+
+extern void gl_matrix_copy( GLmatrix *to, const GLmatrix *from );
+
+extern void gl_matrix_mul( GLmatrix *dest, 
+                          const GLmatrix *a, 
+                          const GLmatrix *b );
+
+extern void gl_matrix_analyze( GLmatrix *mat );
+
+
+
+#endif
diff --git a/src/mesa/main/mesa.conf b/src/mesa/main/mesa.conf
new file mode 100644 (file)
index 0000000..d24ee6b
--- /dev/null
@@ -0,0 +1,74 @@
+;; -*-lisp-*-
+;;
+;; KW: New mesa configuration file, syntax following a lisp style.
+;;
+;; valid syntax:
+;; 
+;; (include filename) 
+;;     - not implemented
+;;
+;; (config-mesa version configs)
+;;
+;; where:
+;;    version - is the version number of mesa for which the configuration
+;;    was written.  Future versions will use this to check for upwards
+;;    compatibility.  There is however no guarentee that old configurations
+;;    will continue to be respected.
+;;
+;;    configs - is a list of valid configuration lists, as specified by: 
+;;
+;;       (set-var variable value) - not implemented, use to augment env vars
+;;       (set-env variable value) - not implemented, use to augment env vars
+;;       (default-hint variable value)
+;;       (disable-extension name)
+;;
+;; Mesa will look for an environment variable MESA_CONFIG, and try to
+;; execute that profile.  Otherwise, it will fallback to the profile
+;; with the same name as the current mesa version.  As default
+;; profiles should normally be empty or near-empty, this should be
+;; sufficiently powerful.
+;;
+
+
+;; Default profile - should normally be an empty list of
+;; configurations.
+;;
+(config-mesa mesa3.1beta1 ())
+
+
+
+;; Really is an empty config.
+;;
+(config-mesa empty ())
+
+
+
+;; Turn off some compliance for the sake of speed.  
+;;
+(config-mesa quake2
+ (
+  ;; Quake2 likes this extension, but it really hurts performance if
+  ;; you don't also disable software fallbacks, below.  (And do
+  ;; something else to stop the eye-space calculations too...)
+  ;;
+  (disable-extension GL_EXT_point_parameters) 
+
+  ;; These hints are honoured only by the 3dfx driver - the X driver
+  ;; continues to function even if you specify hardware-only
+  ;; rendering.
+  ;;
+  ;(default-hint GL_ALLOW_DRAW_OBJ_HINT_PGI GL_TRUE)   ; wishful thinking
+  ;(default-hint GL_ALLOW_DRAW_WIN_HINT_PGI GL_TRUE)   ; allow 3dfx hardware...
+  ;(default-hint GL_ALLOW_DRAW_SPN_HINT_PGI GL_FALSE)  ; no software spans
+  ;(default-hint GL_ALLOW_DRAW_MEM_HINT_PGI GL_FALSE)  ; no softare pixels
+
+  ;; Lock in the hints specified above.
+  ;;
+  (disable-extension GL_PGI_misc_hints)))    
+
+
+
+  
+
+
+
diff --git a/src/mesa/main/pixel.c b/src/mesa/main/pixel.c
new file mode 100644 (file)
index 0000000..316c357
--- /dev/null
@@ -0,0 +1,774 @@
+/* $Id: pixel.c,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+/*
+ * glPixelStore, glPixelTransfer, glPixelMap, glPixelZoom, etc.
+ */
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "context.h"
+#include "macros.h"
+#include "pixel.h"
+#include "types.h"
+#ifdef XFree86Server
+#include "GL/xf86glx.h"
+#endif
+#endif
+
+
+
+/**********************************************************************/
+/*****                    glPixelZoom                             *****/
+/**********************************************************************/
+
+
+
+void gl_PixelZoom( GLcontext *ctx, GLfloat xfactor, GLfloat yfactor )
+{
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPixelZoom");
+
+   ctx->Pixel.ZoomX = xfactor;
+   ctx->Pixel.ZoomY = yfactor;
+}
+
+
+
+/**********************************************************************/
+/*****                    glPixelStore                            *****/
+/**********************************************************************/
+
+
+void gl_PixelStorei( GLcontext *ctx, GLenum pname, GLint param )
+{
+   /* NOTE: this call can't be compiled into the display list */
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPixelStore");
+
+
+   switch (pname) {
+      case GL_PACK_SWAP_BYTES:
+         ctx->Pack.SwapBytes = param ? GL_TRUE : GL_FALSE;
+        break;
+      case GL_PACK_LSB_FIRST:
+         ctx->Pack.LsbFirst = param ? GL_TRUE : GL_FALSE;
+        break;
+      case GL_PACK_ROW_LENGTH:
+        if (param<0) {
+           gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
+        }
+        else {
+           ctx->Pack.RowLength = param;
+        }
+        break;
+      case GL_PACK_IMAGE_HEIGHT:
+         if (param<0)
+            gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
+         else
+            ctx->Pack.ImageHeight = param;
+         break;
+      case GL_PACK_SKIP_PIXELS:
+        if (param<0) {
+           gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
+        }
+        else {
+           ctx->Pack.SkipPixels = param;
+        }
+        break;
+      case GL_PACK_SKIP_ROWS:
+        if (param<0) {
+           gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
+        }
+        else {
+           ctx->Pack.SkipRows = param;
+        }
+        break;
+      case GL_PACK_ALIGNMENT:
+         if (param==1 || param==2 || param==4 || param==8) {
+           ctx->Pack.Alignment = param;
+        }
+        else {
+           gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
+        }
+        break;
+      case GL_UNPACK_SWAP_BYTES:
+        ctx->Unpack.SwapBytes = param ? GL_TRUE : GL_FALSE;
+         break;
+      case GL_UNPACK_LSB_FIRST:
+        ctx->Unpack.LsbFirst = param ? GL_TRUE : GL_FALSE;
+        break;
+      case GL_UNPACK_ROW_LENGTH:
+        if (param<0) {
+           gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
+        }
+        else {
+           ctx->Unpack.RowLength = param;
+        }
+        break;
+      case GL_UNPACK_IMAGE_HEIGHT:
+         if (param<0)
+            gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
+         else
+            ctx->Unpack.ImageHeight = param;
+         break;
+      case GL_UNPACK_SKIP_PIXELS:
+        if (param<0) {
+           gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
+        }
+        else {
+           ctx->Unpack.SkipPixels = param;
+        }
+        break;
+      case GL_UNPACK_SKIP_ROWS:
+        if (param<0) {
+           gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
+        }
+        else {
+           ctx->Unpack.SkipRows = param;
+        }
+        break;
+      case GL_UNPACK_ALIGNMENT:
+         if (param==1 || param==2 || param==4 || param==8) {
+           ctx->Unpack.Alignment = param;
+        }
+        else {
+           gl_error( ctx, GL_INVALID_VALUE, "glPixelStore" );
+        }
+        break;
+      default:
+        gl_error( ctx, GL_INVALID_ENUM, "glPixelStore" );
+   }
+}
+
+
+
+
+
+/**********************************************************************/
+/*****                         glPixelMap                         *****/
+/**********************************************************************/
+
+
+
+void gl_PixelMapfv( GLcontext *ctx,
+                    GLenum map, GLint mapsize, const GLfloat *values )
+{
+   GLint i;
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPixelMapfv");
+
+
+   if (mapsize<0 || mapsize>MAX_PIXEL_MAP_TABLE) {
+      gl_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" );
+      return;
+   }
+
+   if (map>=GL_PIXEL_MAP_S_TO_S && map<=GL_PIXEL_MAP_I_TO_A) {
+      /* test that mapsize is a power of two */
+      GLuint p;
+      GLboolean ok = GL_FALSE;
+      for (p=1; p<=MAX_PIXEL_MAP_TABLE; p=p<<1) {
+        if ( (p&mapsize) == p ) {
+           ok = GL_TRUE;
+           break;
+        }
+      }
+      if (!ok) {
+        gl_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" );
+         return;
+      }
+   }
+
+   switch (map) {
+      case GL_PIXEL_MAP_S_TO_S:
+         ctx->Pixel.MapStoSsize = mapsize;
+         for (i=0;i<mapsize;i++) {
+           ctx->Pixel.MapStoS[i] = (GLint) values[i];
+        }
+        break;
+      case GL_PIXEL_MAP_I_TO_I:
+         ctx->Pixel.MapItoIsize = mapsize;
+         for (i=0;i<mapsize;i++) {
+           ctx->Pixel.MapItoI[i] = (GLint) values[i];
+        }
+        break;
+      case GL_PIXEL_MAP_I_TO_R:
+         ctx->Pixel.MapItoRsize = mapsize;
+         for (i=0;i<mapsize;i++) {
+            GLfloat val = CLAMP( values[i], 0.0, 1.0 );
+           ctx->Pixel.MapItoR[i] = val;
+           ctx->Pixel.MapItoR8[i] = (GLint) (val * 255.0F);
+        }
+        break;
+      case GL_PIXEL_MAP_I_TO_G:
+         ctx->Pixel.MapItoGsize = mapsize;
+         for (i=0;i<mapsize;i++) {
+            GLfloat val = CLAMP( values[i], 0.0, 1.0 );
+           ctx->Pixel.MapItoG[i] = val;
+           ctx->Pixel.MapItoG8[i] = (GLint) (val * 255.0F);
+        }
+        break;
+      case GL_PIXEL_MAP_I_TO_B:
+         ctx->Pixel.MapItoBsize = mapsize;
+         for (i=0;i<mapsize;i++) {
+            GLfloat val = CLAMP( values[i], 0.0, 1.0 );
+           ctx->Pixel.MapItoB[i] = val;
+           ctx->Pixel.MapItoB8[i] = (GLint) (val * 255.0F);
+        }
+        break;
+      case GL_PIXEL_MAP_I_TO_A:
+         ctx->Pixel.MapItoAsize = mapsize;
+         for (i=0;i<mapsize;i++) {
+            GLfloat val = CLAMP( values[i], 0.0, 1.0 );
+           ctx->Pixel.MapItoA[i] = val;
+           ctx->Pixel.MapItoA8[i] = (GLint) (val * 255.0F);
+        }
+        break;
+      case GL_PIXEL_MAP_R_TO_R:
+         ctx->Pixel.MapRtoRsize = mapsize;
+         for (i=0;i<mapsize;i++) {
+           ctx->Pixel.MapRtoR[i] = CLAMP( values[i], 0.0, 1.0 );
+        }
+        break;
+      case GL_PIXEL_MAP_G_TO_G:
+         ctx->Pixel.MapGtoGsize = mapsize;
+         for (i=0;i<mapsize;i++) {
+           ctx->Pixel.MapGtoG[i] = CLAMP( values[i], 0.0, 1.0 );
+        }
+        break;
+      case GL_PIXEL_MAP_B_TO_B:
+         ctx->Pixel.MapBtoBsize = mapsize;
+         for (i=0;i<mapsize;i++) {
+           ctx->Pixel.MapBtoB[i] = CLAMP( values[i], 0.0, 1.0 );
+        }
+        break;
+      case GL_PIXEL_MAP_A_TO_A:
+         ctx->Pixel.MapAtoAsize = mapsize;
+         for (i=0;i<mapsize;i++) {
+           ctx->Pixel.MapAtoA[i] = CLAMP( values[i], 0.0, 1.0 );
+        }
+        break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glPixelMapfv(map)" );
+   }
+}
+
+
+
+
+
+void gl_GetPixelMapfv( GLcontext *ctx, GLenum map, GLfloat *values )
+{
+   GLint i;
+
+   ASSERT_OUTSIDE_BEGIN_END(ctx, "glGetPixelMapfv");
+
+   switch (map) {
+      case GL_PIXEL_MAP_I_TO_I:
+         for (i=0;i<ctx->Pixel.MapItoIsize;i++) {
+           values[i] = (GLfloat) ctx->Pixel.MapItoI[i];
+        }
+        break;
+      case GL_PIXEL_MAP_S_TO_S:
+         for (i=0;i<ctx->Pixel.MapStoSsize;i++) {
+           values[i] = (GLfloat) ctx->Pixel.MapStoS[i];
+        }
+        break;
+      case GL_PIXEL_MAP_I_TO_R:
+         MEMCPY(values,ctx->Pixel.MapItoR,ctx->Pixel.MapItoRsize*sizeof(GLfloat));
+        break;
+      case GL_PIXEL_MAP_I_TO_G:
+         MEMCPY(values,ctx->Pixel.MapItoG,ctx->Pixel.MapItoGsize*sizeof(GLfloat));
+        break;
+      case GL_PIXEL_MAP_I_TO_B:
+         MEMCPY(values,ctx->Pixel.MapItoB,ctx->Pixel.MapItoBsize*sizeof(GLfloat));
+        break;
+      case GL_PIXEL_MAP_I_TO_A:
+         MEMCPY(values,ctx->Pixel.MapItoA,ctx->Pixel.MapItoAsize*sizeof(GLfloat));
+        break;
+      case GL_PIXEL_MAP_R_TO_R:
+         MEMCPY(values,ctx->Pixel.MapRtoR,ctx->Pixel.MapRtoRsize*sizeof(GLfloat));
+        break;
+      case GL_PIXEL_MAP_G_TO_G:
+         MEMCPY(values,ctx->Pixel.MapGtoG,ctx->Pixel.MapGtoGsize*sizeof(GLfloat));
+        break;
+      case GL_PIXEL_MAP_B_TO_B:
+         MEMCPY(values,ctx->Pixel.MapBtoB,ctx->Pixel.MapBtoBsize*sizeof(GLfloat));
+        break;
+      case GL_PIXEL_MAP_A_TO_A:
+         MEMCPY(values,ctx->Pixel.MapAtoA,ctx->Pixel.MapAtoAsize*sizeof(GLfloat));
+        break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glGetPixelMapfv" );
+   }
+}
+
+
+void gl_GetPixelMapuiv( GLcontext *ctx, GLenum map, GLuint *values )
+{
+   GLint i;
+
+   ASSERT_OUTSIDE_BEGIN_END(ctx, "glGetPixelMapfv");
+
+   switch (map) {
+      case GL_PIXEL_MAP_I_TO_I:
+         MEMCPY(values, ctx->Pixel.MapItoI, ctx->Pixel.MapItoIsize*sizeof(GLint));
+        break;
+      case GL_PIXEL_MAP_S_TO_S:
+         MEMCPY(values, ctx->Pixel.MapStoS, ctx->Pixel.MapStoSsize*sizeof(GLint));
+        break;
+      case GL_PIXEL_MAP_I_TO_R:
+        for (i=0;i<ctx->Pixel.MapItoRsize;i++) {
+           values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoR[i] );
+        }
+        break;
+      case GL_PIXEL_MAP_I_TO_G:
+        for (i=0;i<ctx->Pixel.MapItoGsize;i++) {
+           values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoG[i] );
+        }
+        break;
+      case GL_PIXEL_MAP_I_TO_B:
+        for (i=0;i<ctx->Pixel.MapItoBsize;i++) {
+           values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoB[i] );
+        }
+        break;
+      case GL_PIXEL_MAP_I_TO_A:
+        for (i=0;i<ctx->Pixel.MapItoAsize;i++) {
+           values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoA[i] );
+        }
+        break;
+      case GL_PIXEL_MAP_R_TO_R:
+        for (i=0;i<ctx->Pixel.MapRtoRsize;i++) {
+           values[i] = FLOAT_TO_UINT( ctx->Pixel.MapRtoR[i] );
+        }
+        break;
+      case GL_PIXEL_MAP_G_TO_G:
+        for (i=0;i<ctx->Pixel.MapGtoGsize;i++) {
+           values[i] = FLOAT_TO_UINT( ctx->Pixel.MapGtoG[i] );
+        }
+        break;
+      case GL_PIXEL_MAP_B_TO_B:
+        for (i=0;i<ctx->Pixel.MapBtoBsize;i++) {
+           values[i] = FLOAT_TO_UINT( ctx->Pixel.MapBtoB[i] );
+        }
+        break;
+      case GL_PIXEL_MAP_A_TO_A:
+        for (i=0;i<ctx->Pixel.MapAtoAsize;i++) {
+           values[i] = FLOAT_TO_UINT( ctx->Pixel.MapAtoA[i] );
+        }
+        break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glGetPixelMapfv" );
+   }
+}
+
+
+void gl_GetPixelMapusv( GLcontext *ctx, GLenum map, GLushort *values )
+{
+   GLint i;
+
+   ASSERT_OUTSIDE_BEGIN_END(ctx, "glGetPixelMapfv");
+
+   switch (map) {
+      case GL_PIXEL_MAP_I_TO_I:
+        for (i=0;i<ctx->Pixel.MapItoIsize;i++) {
+           values[i] = (GLushort) ctx->Pixel.MapItoI[i];
+        }
+        break;
+      case GL_PIXEL_MAP_S_TO_S:
+        for (i=0;i<ctx->Pixel.MapStoSsize;i++) {
+           values[i] = (GLushort) ctx->Pixel.MapStoS[i];
+        }
+        break;
+      case GL_PIXEL_MAP_I_TO_R:
+        for (i=0;i<ctx->Pixel.MapItoRsize;i++) {
+           values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoR[i] );
+        }
+        break;
+      case GL_PIXEL_MAP_I_TO_G:
+        for (i=0;i<ctx->Pixel.MapItoGsize;i++) {
+           values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoG[i] );
+        }
+        break;
+      case GL_PIXEL_MAP_I_TO_B:
+        for (i=0;i<ctx->Pixel.MapItoBsize;i++) {
+           values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoB[i] );
+        }
+        break;
+      case GL_PIXEL_MAP_I_TO_A:
+        for (i=0;i<ctx->Pixel.MapItoAsize;i++) {
+           values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoA[i] );
+        }
+        break;
+      case GL_PIXEL_MAP_R_TO_R:
+        for (i=0;i<ctx->Pixel.MapRtoRsize;i++) {
+           values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapRtoR[i] );
+        }
+        break;
+      case GL_PIXEL_MAP_G_TO_G:
+        for (i=0;i<ctx->Pixel.MapGtoGsize;i++) {
+           values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapGtoG[i] );
+        }
+        break;
+      case GL_PIXEL_MAP_B_TO_B:
+        for (i=0;i<ctx->Pixel.MapBtoBsize;i++) {
+           values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapBtoB[i] );
+        }
+        break;
+      case GL_PIXEL_MAP_A_TO_A:
+        for (i=0;i<ctx->Pixel.MapAtoAsize;i++) {
+           values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapAtoA[i] );
+        }
+        break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glGetPixelMapfv" );
+   }
+}
+
+
+
+/**********************************************************************/
+/*****                       glPixelTransfer                      *****/
+/**********************************************************************/
+
+
+/*
+ * Implements glPixelTransfer[fi] whether called immediately or from a
+ * display list.
+ */
+void gl_PixelTransferf( GLcontext *ctx, GLenum pname, GLfloat param )
+{
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPixelTransfer");
+
+
+   switch (pname) {
+      case GL_MAP_COLOR:
+         ctx->Pixel.MapColorFlag = param ? GL_TRUE : GL_FALSE;
+        break;
+      case GL_MAP_STENCIL:
+         ctx->Pixel.MapStencilFlag = param ? GL_TRUE : GL_FALSE;
+        break;
+      case GL_INDEX_SHIFT:
+         ctx->Pixel.IndexShift = (GLint) param;
+        break;
+      case GL_INDEX_OFFSET:
+         ctx->Pixel.IndexOffset = (GLint) param;
+        break;
+      case GL_RED_SCALE:
+         ctx->Pixel.RedScale = param;
+        break;
+      case GL_RED_BIAS:
+         ctx->Pixel.RedBias = param;
+        break;
+      case GL_GREEN_SCALE:
+         ctx->Pixel.GreenScale = param;
+        break;
+      case GL_GREEN_BIAS:
+         ctx->Pixel.GreenBias = param;
+        break;
+      case GL_BLUE_SCALE:
+         ctx->Pixel.BlueScale = param;
+        break;
+      case GL_BLUE_BIAS:
+         ctx->Pixel.BlueBias = param;
+        break;
+      case GL_ALPHA_SCALE:
+         ctx->Pixel.AlphaScale = param;
+        break;
+      case GL_ALPHA_BIAS:
+         ctx->Pixel.AlphaBias = param;
+        break;
+      case GL_DEPTH_SCALE:
+         ctx->Pixel.DepthScale = param;
+        break;
+      case GL_DEPTH_BIAS:
+         ctx->Pixel.DepthBias = param;
+        break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glPixelTransfer(pname)" );
+         return;
+   }
+
+   if (ctx->Pixel.RedScale!=1.0F   || ctx->Pixel.RedBias!=0.0F ||
+       ctx->Pixel.GreenScale!=1.0F || ctx->Pixel.GreenBias!=0.0F ||
+       ctx->Pixel.BlueScale!=1.0F  || ctx->Pixel.BlueBias!=0.0F ||
+       ctx->Pixel.AlphaScale!=1.0F || ctx->Pixel.AlphaBias!=0.0F) {
+      ctx->Pixel.ScaleOrBiasRGBA = GL_TRUE;
+   }
+   else {
+      ctx->Pixel.ScaleOrBiasRGBA = GL_FALSE;
+   }
+}
+
+
+
+
+/*
+ * Pixel processing functions
+ */
+
+
+/*
+ * Apply scale and bias factors to an array of RGBA pixels.
+ */
+void gl_scale_and_bias_color( const GLcontext *ctx, GLuint n,
+                              GLfloat red[], GLfloat green[],
+                              GLfloat blue[], GLfloat alpha[] )
+{
+   GLuint i;
+   for (i=0;i<n;i++) {
+      GLfloat r = red[i]   * ctx->Pixel.RedScale   + ctx->Pixel.RedBias;
+      GLfloat g = green[i] * ctx->Pixel.GreenScale + ctx->Pixel.GreenBias;
+      GLfloat b = blue[i]  * ctx->Pixel.BlueScale  + ctx->Pixel.BlueBias;
+      GLfloat a = alpha[i] * ctx->Pixel.AlphaScale + ctx->Pixel.AlphaBias;
+      red[i]   = CLAMP( r, 0.0F, 1.0F );
+      green[i] = CLAMP( g, 0.0F, 1.0F );
+      blue[i]  = CLAMP( b, 0.0F, 1.0F );
+      alpha[i] = CLAMP( a, 0.0F, 1.0F );
+   }
+}
+
+
+/*
+ * Apply scale and bias factors to an array of RGBA pixels.
+ */
+void gl_scale_and_bias_rgba( const GLcontext *ctx, GLuint n, GLubyte rgba[][4] )
+{
+   GLfloat rbias = ctx->Pixel.RedBias   * 255.0F;
+   GLfloat gbias = ctx->Pixel.GreenBias * 255.0F;
+   GLfloat bbias = ctx->Pixel.BlueBias  * 255.0F;
+   GLfloat abias = ctx->Pixel.AlphaBias * 255.0F;
+   GLuint i;
+   for (i=0;i<n;i++) {
+      GLint r = (GLint) (rgba[i][RCOMP] * ctx->Pixel.RedScale   + rbias);
+      GLint g = (GLint) (rgba[i][GCOMP] * ctx->Pixel.GreenScale + gbias);
+      GLint b = (GLint) (rgba[i][BCOMP] * ctx->Pixel.BlueScale  + bbias);
+      GLint a = (GLint) (rgba[i][ACOMP] * ctx->Pixel.AlphaScale + abias);
+      rgba[i][RCOMP] = CLAMP( r, 0, 255 );
+      rgba[i][GCOMP] = CLAMP( g, 0, 255 );
+      rgba[i][BCOMP] = CLAMP( b, 0, 255 );
+      rgba[i][ACOMP] = CLAMP( a, 0, 255 );
+   }
+}
+
+
+/*
+ * Apply pixel mapping to an array of RGBA pixels.
+ */
+void gl_map_rgba( const GLcontext *ctx, GLuint n, GLubyte rgba[][4] )
+{
+   GLfloat rscale = (ctx->Pixel.MapRtoRsize - 1) / 255.0F;
+   GLfloat gscale = (ctx->Pixel.MapGtoGsize - 1) / 255.0F;
+   GLfloat bscale = (ctx->Pixel.MapBtoBsize - 1) / 255.0F;
+   GLfloat ascale = (ctx->Pixel.MapAtoAsize - 1) / 255.0F;
+   GLuint i;
+   for (i=0;i<n;i++) {
+      GLint ir = (GLint) (rgba[i][RCOMP] * rscale);
+      GLint ig = (GLint) (rgba[i][GCOMP] * gscale);
+      GLint ib = (GLint) (rgba[i][BCOMP] * bscale);
+      GLint ia = (GLint) (rgba[i][ACOMP] * ascale);
+      rgba[i][RCOMP] = (GLint) (ctx->Pixel.MapRtoR[ir] * 255.0F);
+      rgba[i][GCOMP] = (GLint) (ctx->Pixel.MapGtoG[ig] * 255.0F);
+      rgba[i][BCOMP] = (GLint) (ctx->Pixel.MapBtoB[ib] * 255.0F);
+      rgba[i][ACOMP] = (GLint) (ctx->Pixel.MapAtoA[ia] * 255.0F);
+   }
+}
+
+
+/*
+ * Apply pixel mapping to an array of RGBA pixels.
+ */
+void gl_map_color( const GLcontext *ctx, GLuint n,
+                   GLfloat red[], GLfloat green[],
+                   GLfloat blue[], GLfloat alpha[] )
+{
+   GLfloat rscale = ctx->Pixel.MapRtoRsize-1;
+   GLfloat gscale = ctx->Pixel.MapGtoGsize-1;
+   GLfloat bscale = ctx->Pixel.MapBtoBsize-1;
+   GLfloat ascale = ctx->Pixel.MapAtoAsize-1;
+   GLuint i;
+   for (i=0;i<n;i++) {
+      red[i]   = ctx->Pixel.MapRtoR[ (GLint) (red[i]   * rscale) ];
+      green[i] = ctx->Pixel.MapGtoG[ (GLint) (green[i] * gscale) ];
+      blue[i]  = ctx->Pixel.MapBtoB[ (GLint) (blue[i]  * bscale) ];
+      alpha[i] = ctx->Pixel.MapAtoA[ (GLint) (alpha[i] * ascale) ];
+   }
+}
+
+
+
+/*
+ * Apply color index shift and offset to an array of pixels.
+ */
+void gl_shift_and_offset_ci( const GLcontext *ctx, GLuint n, GLuint indexes[] )
+{
+   GLint shift = ctx->Pixel.IndexShift;
+   GLint offset = ctx->Pixel.IndexOffset;
+   GLuint i;
+   if (shift > 0) {
+      for (i=0;i<n;i++) {
+         indexes[i] = (indexes[i] << shift) + offset;
+      }
+   }
+   else if (shift < 0) {
+      shift = -shift;
+      for (i=0;i<n;i++) {
+         indexes[i] = (indexes[i] >> shift) + offset;
+      }
+   }
+   else {
+      for (i=0;i<n;i++) {
+         indexes[i] = indexes[i] + offset;
+      }
+   }
+}
+
+
+/*
+ * Apply color index mapping to color indexes.
+ */
+void gl_map_ci( const GLcontext *ctx, GLuint n, GLuint index[] )
+{
+   GLuint mask = ctx->Pixel.MapItoIsize - 1;
+   GLuint i;
+   for (i=0;i<n;i++) {
+      index[i] = ctx->Pixel.MapItoI[ index[i] & mask ];
+   }
+}
+
+
+/*
+ * Map color indexes to rgb values.
+ */
+void gl_map_ci_to_rgba( const GLcontext *ctx, GLuint n, const GLuint index[],
+                        GLubyte rgba[][4] )
+{
+   GLuint rmask = ctx->Pixel.MapItoRsize - 1;
+   GLuint gmask = ctx->Pixel.MapItoGsize - 1;
+   GLuint bmask = ctx->Pixel.MapItoBsize - 1;
+   GLuint amask = ctx->Pixel.MapItoAsize - 1;
+   const GLubyte *rMap = ctx->Pixel.MapItoR8;
+   const GLubyte *gMap = ctx->Pixel.MapItoG8;
+   const GLubyte *bMap = ctx->Pixel.MapItoB8;
+   const GLubyte *aMap = ctx->Pixel.MapItoA8;
+   GLuint i;
+   for (i=0;i<n;i++) {
+      rgba[i][RCOMP] = rMap[index[i] & rmask];
+      rgba[i][GCOMP] = gMap[index[i] & gmask];
+      rgba[i][BCOMP] = bMap[index[i] & bmask];
+      rgba[i][ACOMP] = aMap[index[i] & amask];
+   }
+}
+
+
+/*
+ * Map 8-bit color indexes to rgb values.
+ */
+void gl_map_ci8_to_rgba( const GLcontext *ctx, GLuint n, const GLubyte index[],
+                         GLubyte rgba[][4] )
+{
+   GLuint rmask = ctx->Pixel.MapItoRsize - 1;
+   GLuint gmask = ctx->Pixel.MapItoGsize - 1;
+   GLuint bmask = ctx->Pixel.MapItoBsize - 1;
+   GLuint amask = ctx->Pixel.MapItoAsize - 1;
+   const GLubyte *rMap = ctx->Pixel.MapItoR8;
+   const GLubyte *gMap = ctx->Pixel.MapItoG8;
+   const GLubyte *bMap = ctx->Pixel.MapItoB8;
+   const GLubyte *aMap = ctx->Pixel.MapItoA8;
+   GLuint i;
+   for (i=0;i<n;i++) {
+      rgba[i][RCOMP] = rMap[index[i] & rmask];
+      rgba[i][GCOMP] = gMap[index[i] & gmask];
+      rgba[i][BCOMP] = bMap[index[i] & bmask];
+      rgba[i][ACOMP] = aMap[index[i] & amask];
+   }
+}
+
+
+void gl_map_ci_to_color( const GLcontext *ctx, GLuint n, const GLuint index[],
+                         GLfloat r[], GLfloat g[],
+                         GLfloat b[], GLfloat a[] )
+{
+   GLuint rmask = ctx->Pixel.MapItoRsize - 1;
+   GLuint gmask = ctx->Pixel.MapItoGsize - 1;
+   GLuint bmask = ctx->Pixel.MapItoBsize - 1;
+   GLuint amask = ctx->Pixel.MapItoAsize - 1;
+   GLuint i;
+   for (i=0;i<n;i++) {
+      r[i] = ctx->Pixel.MapItoR[index[i] & rmask];
+      g[i] = ctx->Pixel.MapItoG[index[i] & gmask];
+      b[i] = ctx->Pixel.MapItoB[index[i] & bmask];
+      a[i] = ctx->Pixel.MapItoA[index[i] & amask];
+   }
+}
+
+
+
+void gl_shift_and_offset_stencil( const GLcontext *ctx, GLuint n,
+                                  GLstencil stencil[] )
+{
+   GLuint i;
+   GLint shift = ctx->Pixel.IndexShift;
+   GLint offset = ctx->Pixel.IndexOffset;
+   if (shift > 0) {
+      for (i=0;i<n;i++) {
+         stencil[i] = (stencil[i] << shift) + offset;
+      }
+   }
+   else if (shift < 0) {
+      shift = -shift;
+      for (i=0;i<n;i++) {
+         stencil[i] = (stencil[i] >> shift) + offset;
+      }
+   }
+   else {
+      for (i=0;i<n;i++) {
+         stencil[i] = stencil[i] + offset;
+      }
+   }
+
+}
+
+
+
+void gl_map_stencil( const GLcontext *ctx, GLuint n, GLstencil stencil[] )
+{
+   GLuint mask = ctx->Pixel.MapStoSsize - 1;
+   GLuint i;
+   for (i=0;i<n;i++) {
+      stencil[i] = ctx->Pixel.MapStoS[ stencil[i] & mask ];
+   }
+}
+
diff --git a/src/mesa/main/pixel.h b/src/mesa/main/pixel.h
new file mode 100644 (file)
index 0000000..c592d06
--- /dev/null
@@ -0,0 +1,111 @@
+/* $Id: pixel.h,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+#ifndef PIXEL_H
+#define PIXEL_H
+
+
+#include "types.h"
+
+
+/*
+ * API functions
+ */
+
+
+extern void gl_GetPixelMapfv( GLcontext *ctx, GLenum map, GLfloat *values );
+
+extern void gl_GetPixelMapuiv( GLcontext *ctx, GLenum map, GLuint *values );
+
+extern void gl_GetPixelMapusv( GLcontext *ctx, GLenum map, GLushort *values );
+
+
+extern void gl_PixelMapfv( GLcontext *ctx,
+                           GLenum map, GLint mapsize, const GLfloat *values );
+
+extern void gl_PixelStorei( GLcontext *ctx, GLenum pname, GLint param );
+
+extern void gl_PixelTransferf( GLcontext *ctx, GLenum pname, GLfloat param );
+
+extern void gl_PixelZoom( GLcontext *ctx, GLfloat xfactor, GLfloat yfactor );
+
+
+/*
+ * Pixel processing functions
+ */
+
+extern void gl_scale_and_bias_color( const GLcontext *ctx, GLuint n,
+                                     GLfloat red[], GLfloat green[],
+                                     GLfloat blue[], GLfloat alpha[] );
+
+
+extern void gl_scale_and_bias_rgba( const GLcontext *ctx, GLuint n,
+                                    GLubyte rgba[][4] );
+
+
+extern void gl_map_rgba( const GLcontext *ctx, GLuint n, GLubyte rgba[][4] );
+
+
+extern void gl_map_color( const GLcontext *ctx, GLuint n,
+                          GLfloat red[], GLfloat green[],
+                          GLfloat blue[], GLfloat alpha[] );
+
+
+extern void gl_shift_and_offset_ci( const GLcontext *ctx, GLuint n,
+                                    GLuint indexes[] );
+
+
+extern void gl_map_ci( const GLcontext *ctx, GLuint n, GLuint index[] );
+
+
+extern void gl_map_ci_to_rgba( const GLcontext *ctx,
+                               GLuint n, const GLuint index[],
+                               GLubyte rgba[][4] );
+
+
+extern void gl_map_ci8_to_rgba( const GLcontext *ctx,
+                                GLuint n, const GLubyte index[],
+                                GLubyte rgba[][4] );
+
+
+extern void gl_map_ci_to_color( const GLcontext *ctx,
+                                GLuint n, const GLuint index[],
+                                GLfloat r[], GLfloat g[],
+                                GLfloat b[], GLfloat a[] );
+
+
+extern void gl_shift_and_offset_stencil( const GLcontext *ctx, GLuint n,
+                                         GLstencil indexes[] );
+
+
+extern void gl_map_stencil( const GLcontext *ctx, GLuint n, GLstencil index[] );
+
+
+#endif
diff --git a/src/mesa/main/points.c b/src/mesa/main/points.c
new file mode 100644 (file)
index 0000000..928acc8
--- /dev/null
@@ -0,0 +1,1344 @@
+/* $Id: points.c,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include "context.h"
+#include "feedback.h"
+#include "macros.h"
+#include "pb.h"
+#include "span.h"
+#include "texstate.h"
+#include "types.h"
+#include "vb.h"
+#include "mmath.h"
+#ifdef XFree86Server
+#include "GL/xf86glx.h"
+#endif
+#endif
+
+
+
+void gl_PointSize( GLcontext *ctx, GLfloat size )
+{
+   if (size<=0.0) {
+      gl_error( ctx, GL_INVALID_VALUE, "glPointSize" );
+      return;
+   }
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPointSize");
+
+   if (ctx->Point.Size != size) {
+      ctx->Point.Size = size;
+      ctx->TriangleCaps &= DD_POINT_SIZE;
+      if (size != 1.0) ctx->TriangleCaps |= DD_POINT_SIZE;
+      ctx->NewState |= NEW_RASTER_OPS;
+   }
+}
+
+
+
+void gl_PointParameterfvEXT( GLcontext *ctx, GLenum pname,
+                                    const GLfloat *params)
+{
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPointParameterfvEXT");
+   if(pname==GL_DISTANCE_ATTENUATION_EXT) {
+      GLboolean tmp = ctx->Point.Attenuated;
+      COPY_3V(ctx->Point.Params,params);
+      ctx->Point.Attenuated = (params[0] != 1.0 ||
+                              params[1] != 0.0 ||
+                              params[2] != 0.0);
+
+      if (tmp != ctx->Point.Attenuated) {
+        ctx->Enabled ^= ENABLE_POINT_ATTEN;
+        ctx->TriangleCaps ^= DD_POINT_ATTEN;
+        ctx->NewState |= NEW_RASTER_OPS;
+      }
+   } else {
+        if (*params<0.0 ) {
+            gl_error( ctx, GL_INVALID_VALUE, "glPointParameterfvEXT" );
+            return;
+        }
+        switch (pname) {
+            case GL_POINT_SIZE_MIN_EXT:
+                ctx->Point.MinSize=*params;
+                break;
+            case GL_POINT_SIZE_MAX_EXT:
+                ctx->Point.MaxSize=*params;
+                break;
+            case GL_POINT_FADE_THRESHOLD_SIZE_EXT:
+                ctx->Point.Threshold=*params;
+                break;
+            default:
+                gl_error( ctx, GL_INVALID_ENUM, "glPointParameterfvEXT" );
+                return;
+        }
+   }
+   ctx->NewState |= NEW_RASTER_OPS;
+}
+
+
+/**********************************************************************/
+/*****                    Rasterization                           *****/
+/**********************************************************************/
+
+
+/*
+ * There are 3 pairs (RGBA, CI) of point rendering functions:
+ *   1. simple:  size=1 and no special rasterization functions (fastest)
+ *   2. size1:  size=1 and any rasterization functions
+ *   3. general:  any size and rasterization functions (slowest)
+ *
+ * All point rendering functions take the same two arguments: first and
+ * last which specify that the points specified by VB[first] through
+ * VB[last] are to be rendered.
+ */
+
+
+
+/*
+ * Put points in feedback buffer.
+ */
+static void feedback_points( GLcontext *ctx, GLuint first, GLuint last )
+{
+   struct vertex_buffer *VB = ctx->VB;
+   GLuint texUnit = ctx->Texture.CurrentTransformUnit;
+   GLuint tsize = VB->TexCoordPtr[texUnit]->size;
+   GLuint i;
+   GLfloat texcoord[4];
+   
+   ASSIGN_4V(texcoord, 0,0,0,1);
+
+   for (i=first;i<=last;i++) {
+      if (VB->ClipMask[i]==0) {
+         GLfloat x, y, z, w, invq;
+         GLfloat color[4];
+         x = VB->Win.data[i][0];
+         y = VB->Win.data[i][1];
+         z = VB->Win.data[i][2] / DEPTH_SCALE;
+         w = VB->ClipPtr->data[i][3];
+
+        if (tsize == 4) {
+           invq = 1.0F / VB->TexCoordPtr[texUnit]->data[i][3];
+           texcoord[0] = VB->TexCoordPtr[texUnit]->data[i][0] * invq;
+           texcoord[1] = VB->TexCoordPtr[texUnit]->data[i][1] * invq;
+           texcoord[2] = VB->TexCoordPtr[texUnit]->data[i][2] * invq;
+           texcoord[3] = VB->TexCoordPtr[texUnit]->data[i][3];
+        } else {
+           COPY_SZ_4V(texcoord, tsize, VB->TexCoordPtr[texUnit]->data[i]);
+        }
+         FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_POINT_TOKEN );
+
+        UBYTE_RGBA_TO_FLOAT_RGBA( color, VB->ColorPtr->data[i] );
+
+         gl_feedback_vertex( ctx, x, y, z, w, color,
+                             (GLfloat) VB->IndexPtr->data[i], texcoord 
+);
+      }
+   }
+}
+
+
+
+/*
+ * Put points in selection buffer.
+ */
+static void select_points( GLcontext *ctx, GLuint first, GLuint last )
+{
+   struct vertex_buffer *VB = ctx->VB;
+   GLuint i;
+
+   for (i=first;i<=last;i++) {
+      if (VB->ClipMask[i]==0) {
+         gl_update_hitflag( ctx, VB->Win.data[i][2] / DEPTH_SCALE );
+      }
+   }
+}
+
+
+/*
+ * CI points with size == 1.0
+ */
+void size1_ci_points( GLcontext *ctx, GLuint first, GLuint last )
+{
+   struct vertex_buffer *VB = ctx->VB;
+   struct pixel_buffer *PB = ctx->PB;
+   GLfloat *win;
+   GLint *pbx = PB->x, *pby = PB->y;
+   GLdepth *pbz = PB->z;
+   GLuint *pbi = PB->i;
+   GLuint pbcount = PB->count;
+   GLuint i;
+
+   win = &VB->Win.data[first][0];
+   for (i=first;i<=last;i++) {
+      if (VB->ClipMask[i]==0) {
+         pbx[pbcount] = (GLint)  win[0];
+         pby[pbcount] = (GLint)  win[1];
+         pbz[pbcount] = (GLint) (win[2] + ctx->PointZoffset);
+         pbi[pbcount] = VB->IndexPtr->data[i];
+         pbcount++;
+      }
+      win += 3;
+   }
+   PB->count = pbcount;
+   PB_CHECK_FLUSH(ctx, PB);
+}
+
+
+
+/*
+ * RGBA points with size == 1.0
+ */
+static void size1_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
+{
+   struct vertex_buffer *VB = ctx->VB;
+   struct pixel_buffer *PB = ctx->PB;
+   GLuint i;
+
+   for (i=first;i<=last;i++) {
+      if (VB->ClipMask[i]==0) {
+         GLint x, y, z;
+         GLint red, green, blue, alpha;
+
+         x = (GLint)  VB->Win.data[i][0];
+         y = (GLint)  VB->Win.data[i][1];
+         z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
+
+         red   = VB->ColorPtr->data[i][0];
+         green = VB->ColorPtr->data[i][1];
+         blue  = VB->ColorPtr->data[i][2];
+         alpha = VB->ColorPtr->data[i][3];
+
+         PB_WRITE_RGBA_PIXEL( PB, x, y, z, red, green, blue, alpha );
+      }
+   }
+   PB_CHECK_FLUSH(ctx,PB);
+}
+
+
+
+/*
+ * General CI points.
+ */
+static void general_ci_points( GLcontext *ctx, GLuint first, GLuint last )
+{
+   struct vertex_buffer *VB = ctx->VB;
+   struct pixel_buffer *PB = ctx->PB;
+   GLuint i;
+   GLint isize = (GLint) (CLAMP(ctx->Point.Size,MIN_POINT_SIZE,MAX_POINT_SIZE) + 0.5F);
+   GLint radius = isize >> 1;
+
+   for (i=first;i<=last;i++) {
+      if (VB->ClipMask[i]==0) {
+         GLint x, y, z;
+         GLint x0, x1, y0, y1;
+         GLint ix, iy;
+
+         x = (GLint)  VB->Win.data[i][0];
+         y = (GLint)  VB->Win.data[i][1];
+         z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
+
+         if (isize & 1) {
+            /* odd size */
+            x0 = x - radius;
+            x1 = x + radius;
+            y0 = y - radius;
+            y1 = y + radius;
+         }
+         else {
+            /* even size */
+            x0 = (GLint) (x + 1.5F) - radius;
+            x1 = x0 + isize - 1;
+            y0 = (GLint) (y + 1.5F) - radius;
+            y1 = y0 + isize - 1;
+         }
+
+         PB_SET_INDEX( ctx, PB, VB->IndexPtr->data[i] );
+
+         for (iy=y0;iy<=y1;iy++) {
+            for (ix=x0;ix<=x1;ix++) {
+               PB_WRITE_PIXEL( PB, ix, iy, z );
+            }
+         }
+         PB_CHECK_FLUSH(ctx,PB);
+      }
+   }
+}
+
+
+/*
+ * General RGBA points.
+ */
+static void general_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
+{
+   struct vertex_buffer *VB = ctx->VB;
+   struct pixel_buffer *PB = ctx->PB;
+   GLuint i;
+   GLint isize = (GLint) (CLAMP(ctx->Point.Size,MIN_POINT_SIZE,MAX_POINT_SIZE) + 0.5F);
+   GLint radius = isize >> 1;
+
+   for (i=first;i<=last;i++) {
+      if (VB->ClipMask[i]==0) {
+         GLint x, y, z;
+         GLint x0, x1, y0, y1;
+         GLint ix, iy;
+
+         x = (GLint)  VB->Win.data[i][0];
+         y = (GLint)  VB->Win.data[i][1];
+         z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
+
+         if (isize & 1) {
+            /* odd size */
+            x0 = x - radius;
+            x1 = x + radius;
+            y0 = y - radius;
+            y1 = y + radius;
+         }
+         else {
+            /* even size */
+            x0 = (GLint) (x + 1.5F) - radius;
+            x1 = x0 + isize - 1;
+            y0 = (GLint) (y + 1.5F) - radius;
+            y1 = y0 + isize - 1;
+         }
+
+         PB_SET_COLOR( ctx, PB,
+                       VB->ColorPtr->data[i][0],
+                       VB->ColorPtr->data[i][1],
+                       VB->ColorPtr->data[i][2],
+                       VB->ColorPtr->data[i][3] );
+
+         for (iy=y0;iy<=y1;iy++) {
+            for (ix=x0;ix<=x1;ix++) {
+               PB_WRITE_PIXEL( PB, ix, iy, z );
+            }
+         }
+         PB_CHECK_FLUSH(ctx,PB);
+      }
+   }
+}
+
+
+
+
+/*
+ * Textured RGBA points.
+ */
+static void textured_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
+{
+   struct vertex_buffer *VB = ctx->VB;
+   struct pixel_buffer *PB = ctx->PB;
+   GLuint i;
+
+   for (i=first;i<=last;i++) {
+      if (VB->ClipMask[i]==0) {
+         GLint x, y, z;
+         GLint x0, x1, y0, y1;
+         GLint ix, iy;
+         GLint isize, radius;
+         GLint red, green, blue, alpha;
+         GLfloat s, t, u;
+
+         x = (GLint)  VB->Win.data[i][0];
+         y = (GLint)  VB->Win.data[i][1];
+         z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
+
+         isize = (GLint)
+                   (CLAMP(ctx->Point.Size,MIN_POINT_SIZE,MAX_POINT_SIZE) + 0.5F);
+         if (isize<1) {
+            isize = 1;
+         }
+         radius = isize >> 1;
+
+         if (isize & 1) {
+            /* odd size */
+            x0 = x - radius;
+            x1 = x + radius;
+            y0 = y - radius;
+            y1 = y + radius;
+         }
+         else {
+            /* even size */
+            x0 = (GLint) (x + 1.5F) - radius;
+            x1 = x0 + isize - 1;
+            y0 = (GLint) (y + 1.5F) - radius;
+            y1 = y0 + isize - 1;
+         }
+
+         red   = VB->ColorPtr->data[i][0];
+         green = VB->ColorPtr->data[i][1];
+         blue  = VB->ColorPtr->data[i][2];
+         alpha = VB->ColorPtr->data[i][3];
+        
+        switch (VB->TexCoordPtr[0]->size) {
+        case 4:
+           s = VB->TexCoordPtr[0]->data[i][0]/VB->TexCoordPtr[0]->data[i][3];
+           t = VB->TexCoordPtr[0]->data[i][1]/VB->TexCoordPtr[0]->data[i][3];
+           u = VB->TexCoordPtr[0]->data[i][2]/VB->TexCoordPtr[0]->data[i][3];
+           break;
+        case 3:
+           s = VB->TexCoordPtr[0]->data[i][0];
+           t = VB->TexCoordPtr[0]->data[i][1];
+           u = VB->TexCoordPtr[0]->data[i][2];
+           break;
+        case 2:
+           s = VB->TexCoordPtr[0]->data[i][0];
+           t = VB->TexCoordPtr[0]->data[i][1];
+           u = 0.0;
+           break;
+        case 1:
+           s = VB->TexCoordPtr[0]->data[i][0];
+           t = 0.0;
+           u = 0.0;
+           break;
+        }
+
+
+
+
+/*    don't think this is needed
+         PB_SET_COLOR( red, green, blue, alpha );
+*/
+
+         for (iy=y0;iy<=y1;iy++) {
+            for (ix=x0;ix<=x1;ix++) {
+               PB_WRITE_TEX_PIXEL( PB, ix, iy, z, red, green, blue, alpha, s, t, u );
+            }
+         }
+         PB_CHECK_FLUSH(ctx,PB);
+      }
+   }
+}
+
+
+/*
+ * Multitextured RGBA points.
+ */
+static void multitextured_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
+{
+   struct vertex_buffer *VB = ctx->VB;
+   struct pixel_buffer *PB = ctx->PB;
+   GLuint i;
+
+   for (i=first;i<=last;i++) {
+      if (VB->ClipMask[i]==0) {
+         GLint x, y, z;
+         GLint x0, x1, y0, y1;
+         GLint ix, iy;
+         GLint isize, radius;
+         GLint red, green, blue, alpha;
+         GLfloat s, t, u;
+         GLfloat s1, t1, u1;
+
+         x = (GLint)  VB->Win.data[i][0];
+         y = (GLint)  VB->Win.data[i][1];
+         z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
+
+         isize = (GLint)
+                   (CLAMP(ctx->Point.Size,MIN_POINT_SIZE,MAX_POINT_SIZE) + 0.5F);
+         if (isize<1) {
+            isize = 1;
+         }
+         radius = isize >> 1;
+
+         if (isize & 1) {
+            /* odd size */
+            x0 = x - radius;
+            x1 = x + radius;
+            y0 = y - radius;
+            y1 = y + radius;
+         }
+         else {
+            /* even size */
+            x0 = (GLint) (x + 1.5F) - radius;
+            x1 = x0 + isize - 1;
+            y0 = (GLint) (y + 1.5F) - radius;
+            y1 = y0 + isize - 1;
+         }
+
+         red   = VB->ColorPtr->data[i][0];
+         green = VB->ColorPtr->data[i][1];
+         blue  = VB->ColorPtr->data[i][2];
+         alpha = VB->ColorPtr->data[i][3];
+        
+        switch (VB->TexCoordPtr[0]->size) {
+        case 4:
+           s = VB->TexCoordPtr[0]->data[i][0]/VB->TexCoordPtr[0]->data[i][3];
+           t = VB->TexCoordPtr[0]->data[i][1]/VB->TexCoordPtr[0]->data[i][3];
+           u = VB->TexCoordPtr[0]->data[i][2]/VB->TexCoordPtr[0]->data[i][3];
+           break;
+        case 3:
+           s = VB->TexCoordPtr[0]->data[i][0];
+           t = VB->TexCoordPtr[0]->data[i][1];
+           u = VB->TexCoordPtr[0]->data[i][2];
+           break;
+        case 2:
+           s = VB->TexCoordPtr[0]->data[i][0];
+           t = VB->TexCoordPtr[0]->data[i][1];
+           u = 0.0;
+           break;
+        case 1:
+           s = VB->TexCoordPtr[0]->data[i][0];
+           t = 0.0;
+           u = 0.0;
+           break;
+        }
+
+        switch (VB->TexCoordPtr[1]->size) {
+        case 4:
+           s1 = VB->TexCoordPtr[1]->data[i][0]/VB->TexCoordPtr[1]->data[i][3];
+           t1 = VB->TexCoordPtr[1]->data[i][1]/VB->TexCoordPtr[1]->data[i][3];
+           u1 = VB->TexCoordPtr[1]->data[i][2]/VB->TexCoordPtr[1]->data[i][3];
+           break;
+        case 3:
+           s1 = VB->TexCoordPtr[1]->data[i][0];
+           t1 = VB->TexCoordPtr[1]->data[i][1];
+           u1 = VB->TexCoordPtr[1]->data[i][2];
+           break;
+        case 2:
+           s1 = VB->TexCoordPtr[1]->data[i][0];
+           t1 = VB->TexCoordPtr[1]->data[i][1];
+           u1 = 0.0;
+           break;
+        case 1:
+           s1 = VB->TexCoordPtr[1]->data[i][0];
+           t1 = 0.0;
+           u1 = 0.0;
+           break;
+        }
+
+         for (iy=y0;iy<=y1;iy++) {
+            for (ix=x0;ix<=x1;ix++) {
+               PB_WRITE_MULTITEX_PIXEL( PB, ix, iy, z, red, green, blue, alpha, s, t, u, s1, t1, u1 );
+            }
+         }
+         PB_CHECK_FLUSH(ctx,PB);
+      }
+   }
+}
+
+
+
+
+/*
+ * Antialiased points with or without texture mapping.
+ */
+static void antialiased_rgba_points( GLcontext *ctx,
+                                     GLuint first, GLuint last )
+{
+   struct vertex_buffer *VB = ctx->VB;
+   struct pixel_buffer *PB = ctx->PB;
+   GLuint i;
+   GLfloat radius, rmin, rmax, rmin2, rmax2, cscale;
+
+   radius = CLAMP( ctx->Point.Size, MIN_POINT_SIZE, MAX_POINT_SIZE ) * 0.5F;
+   rmin = radius - 0.7071F;  /* 0.7071 = sqrt(2)/2 */
+   rmax = radius + 0.7071F;
+   rmin2 = rmin*rmin;
+   rmax2 = rmax*rmax;
+   cscale = 256.0F / (rmax2-rmin2);
+
+   if (ctx->Texture.ReallyEnabled) {
+      for (i=first;i<=last;i++) {
+         if (VB->ClipMask[i]==0) {
+            GLint xmin, ymin, xmax, ymax;
+            GLint x, y, z;
+            GLint red, green, blue, alpha;
+            GLfloat s, t, u;
+            GLfloat s1, t1, u1;
+
+            xmin = (GLint) (VB->Win.data[i][0] - radius);
+            xmax = (GLint) (VB->Win.data[i][0] + radius);
+            ymin = (GLint) (VB->Win.data[i][1] - radius);
+            ymax = (GLint) (VB->Win.data[i][1] + radius);
+            z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
+
+            red   = VB->ColorPtr->data[i][0];
+            green = VB->ColorPtr->data[i][1];
+            blue  = VB->ColorPtr->data[i][2];
+
+           switch (VB->TexCoordPtr[0]->size) {
+           case 4:
+              s = (VB->TexCoordPtr[0]->data[i][0]/
+                   VB->TexCoordPtr[0]->data[i][3]);
+              t = (VB->TexCoordPtr[0]->data[i][1]/
+                   VB->TexCoordPtr[0]->data[i][3]);
+              u = (VB->TexCoordPtr[0]->data[i][2]/
+                   VB->TexCoordPtr[0]->data[i][3]);
+              break;
+           case 3:
+              s = VB->TexCoordPtr[0]->data[i][0];
+              t = VB->TexCoordPtr[0]->data[i][1];
+              u = VB->TexCoordPtr[0]->data[i][2];
+              break;
+           case 2:
+              s = VB->TexCoordPtr[0]->data[i][0];
+              t = VB->TexCoordPtr[0]->data[i][1];
+              u = 0.0;
+              break;
+           case 1:
+              s = VB->TexCoordPtr[0]->data[i][0];
+              t = 0.0;
+              u = 0.0;
+              break;
+           }
+
+           if (ctx->Texture.ReallyEnabled >= TEXTURE1_1D) {
+              /* Multitextured!  This is probably a slow enough path that
+                 there's no reason to specialize the multitexture case. */
+              switch (VB->TexCoordPtr[1]->size) {
+              case 4:
+                 s1 = ( VB->TexCoordPtr[1]->data[i][0] /  
+                        VB->TexCoordPtr[1]->data[i][3]);
+                 t1 = ( VB->TexCoordPtr[1]->data[i][1] / 
+                        VB->TexCoordPtr[1]->data[i][3]);
+                 u1 = ( VB->TexCoordPtr[1]->data[i][2] / 
+                        VB->TexCoordPtr[1]->data[i][3]);
+                 break;
+              case 3:
+                 s1 = VB->TexCoordPtr[1]->data[i][0];
+                 t1 = VB->TexCoordPtr[1]->data[i][1];
+                 u1 = VB->TexCoordPtr[1]->data[i][2];
+                 break;
+              case 2:
+                 s1 = VB->TexCoordPtr[1]->data[i][0];
+                 t1 = VB->TexCoordPtr[1]->data[i][1];
+                 u1 = 0.0;
+                 break;
+              case 1:
+                 s1 = VB->TexCoordPtr[1]->data[i][0];
+                 t1 = 0.0;
+                 u1 = 0.0;
+                 break;
+              }
+           }
+
+            for (y=ymin;y<=ymax;y++) {
+               for (x=xmin;x<=xmax;x++) {
+                  GLfloat dx = x/*+0.5F*/ - VB->Win.data[i][0];
+                  GLfloat dy = y/*+0.5F*/ - VB->Win.data[i][1];
+                  GLfloat dist2 = dx*dx + dy*dy;
+                  if (dist2<rmax2) {
+                     alpha = VB->ColorPtr->data[i][3];
+                     if (dist2>=rmin2) {
+                        GLint coverage = (GLint) (256.0F-(dist2-rmin2)*cscale);
+                        /* coverage is in [0,256] */
+                        alpha = (alpha * coverage) >> 8;
+                     }
+                     if (ctx->Texture.ReallyEnabled >= TEXTURE1_1D) {
+                        PB_WRITE_MULTITEX_PIXEL( PB, x,y,z, red, green, blue, 
+                                                alpha, s, t, u, s1, t1, u1 );
+                     } else {
+                        PB_WRITE_TEX_PIXEL( PB, x,y,z, red, green, blue, 
+                                           alpha, s, t, u );
+                     }
+                  }
+               }
+            }
+
+            PB_CHECK_FLUSH(ctx,PB);
+         }
+      }
+   }
+   else {
+      /* Not texture mapped */
+      for (i=first;i<=last;i++) {
+         if (VB->ClipMask[i]==0) {
+            GLint xmin, ymin, xmax, ymax;
+            GLint x, y, z;
+            GLint red, green, blue, alpha;
+
+            xmin = (GLint) (VB->Win.data[i][0] - radius);
+            xmax = (GLint) (VB->Win.data[i][0] + radius);
+            ymin = (GLint) (VB->Win.data[i][1] - radius);
+            ymax = (GLint) (VB->Win.data[i][1] + radius);
+            z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
+
+            red   = VB->ColorPtr->data[i][0];
+            green = VB->ColorPtr->data[i][1];
+            blue  = VB->ColorPtr->data[i][2];
+
+            for (y=ymin;y<=ymax;y++) {
+               for (x=xmin;x<=xmax;x++) {
+                  GLfloat dx = x/*+0.5F*/ - VB->Win.data[i][0];
+                  GLfloat dy = y/*+0.5F*/ - VB->Win.data[i][1];
+                  GLfloat dist2 = dx*dx + dy*dy;
+                  if (dist2<rmax2) {
+                     alpha = VB->ColorPtr->data[i][3];
+                     if (dist2>=rmin2) {
+                        GLint coverage = (GLint) (256.0F-(dist2-rmin2)*cscale);
+                        /* coverage is in [0,256] */
+                        alpha = (alpha * coverage) >> 8;
+                     }
+                     PB_WRITE_RGBA_PIXEL( PB, x, y, z, red, green, blue, 
+                                         alpha );
+                  }
+               }
+            }
+            PB_CHECK_FLUSH(ctx,PB);
+        }
+      }
+   }
+}
+
+
+
+/*
+ * Null rasterizer for measuring transformation speed.
+ */
+static void null_points( GLcontext *ctx, GLuint first, GLuint last )
+{
+   (void) ctx;
+   (void) first;
+   (void) last;
+}
+
+
+
+/* Definition of the functions for GL_EXT_point_parameters */
+
+/* Calculates the distance attenuation formula of a vector of points in
+ * eye space coordinates 
+ */
+static void dist3(GLfloat *out, GLuint first, GLuint last,
+                 const GLcontext *ctx, const GLvector4f *v)
+{
+   GLuint stride = v->stride;
+   GLfloat *p = VEC_ELT(v, GLfloat, first);
+   GLuint i;
+
+   for (i = first ; i <= last ; i++, STRIDE_F(p, stride) )
+   {
+      GLfloat dist = GL_SQRT(p[0]*p[0]+p[1]*p[1]+p[2]*p[2]);
+      out[i] = 1/(ctx->Point.Params[0]+ 
+                 dist * (ctx->Point.Params[1] +
+                         dist * ctx->Point.Params[2]));
+   }
+}
+
+static void dist2(GLfloat *out, GLuint first, GLuint last,
+                 const GLcontext *ctx, const GLvector4f *v)
+{
+   GLuint stride = v->stride;
+   GLfloat *p = VEC_ELT(v, GLfloat, first);
+   GLuint i;
+
+   for (i = first ; i <= last ; i++, STRIDE_F(p, stride) )
+   {
+      GLfloat dist = GL_SQRT(p[0]*p[0]+p[1]*p[1]);
+      out[i] = 1/(ctx->Point.Params[0]+ 
+                 dist * (ctx->Point.Params[1] +
+                         dist * ctx->Point.Params[2]));
+   }
+}
+
+
+typedef void (*dist_func)(GLfloat *out, GLuint first, GLuint last,
+                            const GLcontext *ctx, const GLvector4f *v);
+
+
+static dist_func eye_dist_tab[5] = {
+   0,
+   0,
+   dist2,
+   dist3,
+   dist3
+};
+
+
+static void clip_dist(GLfloat *out, GLuint first, GLuint last,
+                     const GLcontext *ctx, GLvector4f *clip)
+{
+   /* this is never called */
+   gl_problem(NULL, "clip_dist() called - dead code!\n");
+
+   (void) out;
+   (void) first;
+   (void) last;
+   (void) ctx;
+   (void) clip;
+
+#if 0
+   GLuint i;
+   const GLfloat *from = (GLfloat *)clip_vec->start;
+   const GLuint stride = clip_vec->stride;
+
+   for (i = first ; i <= last ; i++ )
+   {
+      GLfloat dist = win[i][2];
+      out[i] = 1/(ctx->Point.Params[0]+ 
+                 dist * (ctx->Point.Params[1] +
+                         dist * ctx->Point.Params[2]));
+   }
+#endif
+}
+
+
+
+/*
+ * Distance Attenuated General CI points.
+ */
+static void dist_atten_general_ci_points( GLcontext *ctx, GLuint first, 
+                                       GLuint last )
+{
+   struct vertex_buffer *VB = ctx->VB;
+   struct pixel_buffer *PB = ctx->PB;
+   GLuint i;
+   GLfloat psize,dsize;
+   GLfloat dist[VB_SIZE];
+   psize=CLAMP(ctx->Point.Size,MIN_POINT_SIZE,MAX_POINT_SIZE);
+
+   if (ctx->NeedEyeCoords)
+      (eye_dist_tab[VB->EyePtr->size])( dist, first, last, ctx, VB->EyePtr );
+   else 
+      clip_dist( dist, first, last, ctx, VB->ClipPtr );
+
+   for (i=first;i<=last;i++) {
+      if (VB->ClipMask[i]==0) {
+         GLint x, y, z;
+         GLint x0, x1, y0, y1;
+         GLint ix, iy;
+         GLint isize, radius;
+
+         x = (GLint)  VB->Win.data[i][0];
+         y = (GLint)  VB->Win.data[i][1];
+         z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
+
+         dsize=psize*dist[i];
+         if(dsize>=ctx->Point.Threshold) {
+            isize=(GLint) (MIN2(dsize,ctx->Point.MaxSize)+0.5F);
+         } else {
+            isize=(GLint) (MAX2(ctx->Point.Threshold,ctx->Point.MinSize)+0.5F);
+         }
+         radius = isize >> 1;
+
+         if (isize & 1) {
+            /* odd size */
+            x0 = x - radius;
+            x1 = x + radius;
+            y0 = y - radius;
+            y1 = y + radius;
+         }
+         else {
+            /* even size */
+            x0 = (GLint) (x + 1.5F) - radius;
+            x1 = x0 + isize - 1;
+            y0 = (GLint) (y + 1.5F) - radius;
+            y1 = y0 + isize - 1;
+         }
+
+         PB_SET_INDEX( ctx, PB, VB->IndexPtr->data[i] );
+
+         for (iy=y0;iy<=y1;iy++) {
+            for (ix=x0;ix<=x1;ix++) {
+               PB_WRITE_PIXEL( PB, ix, iy, z );
+            }
+         }
+         PB_CHECK_FLUSH(ctx,PB);
+      }
+   }
+}
+
+/*
+ * Distance Attenuated General RGBA points.
+ */
+static void dist_atten_general_rgba_points( GLcontext *ctx, GLuint first, 
+                               GLuint last )
+{
+   struct vertex_buffer *VB = ctx->VB;
+   struct pixel_buffer *PB = ctx->PB;
+   GLuint i;
+   GLubyte alpha;
+   GLfloat psize,dsize;
+   GLfloat dist[VB_SIZE];
+   psize=CLAMP(ctx->Point.Size,MIN_POINT_SIZE,MAX_POINT_SIZE);
+
+   if (ctx->NeedEyeCoords)
+      (eye_dist_tab[VB->EyePtr->size])( dist, first, last, ctx, VB->EyePtr );
+   else 
+      clip_dist( dist, first, last, ctx, VB->ClipPtr );
+
+   for (i=first;i<=last;i++) {
+      if (VB->ClipMask[i]==0) {
+         GLint x, y, z;
+         GLint x0, x1, y0, y1;
+         GLint ix, iy;
+         GLint isize, radius;
+
+         x = (GLint)  VB->Win.data[i][0];
+         y = (GLint)  VB->Win.data[i][1];
+         z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
+         dsize=psize*dist[i];
+         if (dsize >= ctx->Point.Threshold) {
+            isize = (GLint) (MIN2(dsize,ctx->Point.MaxSize)+0.5F);
+            alpha = VB->ColorPtr->data[i][3];
+         }
+         else {
+            isize = (GLint) (MAX2(ctx->Point.Threshold,ctx->Point.MinSize)+0.5F);
+            dsize /= ctx->Point.Threshold;
+            alpha = (GLint) (VB->ColorPtr->data[i][3]* (dsize*dsize));
+         }
+         radius = isize >> 1;
+
+         if (isize & 1) {
+            /* odd size */
+            x0 = x - radius;
+            x1 = x + radius;
+            y0 = y - radius;
+            y1 = y + radius;
+         }
+         else {
+            /* even size */
+            x0 = (GLint) (x + 1.5F) - radius;
+            x1 = x0 + isize - 1;
+            y0 = (GLint) (y + 1.5F) - radius;
+            y1 = y0 + isize - 1;
+         }
+
+         PB_SET_COLOR( ctx, PB,
+                       VB->ColorPtr->data[i][0],
+                       VB->ColorPtr->data[i][1],
+                       VB->ColorPtr->data[i][2],
+                       alpha );
+
+         for (iy=y0;iy<=y1;iy++) {
+            for (ix=x0;ix<=x1;ix++) {
+               PB_WRITE_PIXEL( PB, ix, iy, z );
+            }
+         }
+         PB_CHECK_FLUSH(ctx,PB);
+      }
+   }
+}
+
+/*
+ *  Distance Attenuated Textured RGBA points.
+ */
+static void dist_atten_textured_rgba_points( GLcontext *ctx, GLuint first, 
+                                       GLuint last )
+{
+   struct vertex_buffer *VB = ctx->VB;
+   struct pixel_buffer *PB = ctx->PB;
+   GLuint i;
+   GLfloat psize,dsize;
+   GLfloat dist[VB_SIZE];
+   psize=CLAMP(ctx->Point.Size,MIN_POINT_SIZE,MAX_POINT_SIZE);
+
+   if (ctx->NeedEyeCoords)
+      (eye_dist_tab[VB->EyePtr->size])( dist, first, last, ctx, VB->EyePtr );
+   else 
+      clip_dist( dist, first, last, ctx, VB->ClipPtr );
+
+   for (i=first;i<=last;i++) {
+      if (VB->ClipMask[i]==0) {
+         GLint x, y, z;
+         GLint x0, x1, y0, y1;
+         GLint ix, iy;
+         GLint isize, radius;
+         GLint red, green, blue, alpha;
+         GLfloat s, t, u;
+         GLfloat s1, t1, u1;
+
+         x = (GLint)  VB->Win.data[i][0];
+         y = (GLint)  VB->Win.data[i][1];
+         z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
+
+         dsize=psize*dist[i];
+         if(dsize>=ctx->Point.Threshold) {
+            isize=(GLint) (MIN2(dsize,ctx->Point.MaxSize)+0.5F);
+            alpha=VB->ColorPtr->data[i][3];
+         } else {
+            isize=(GLint) (MAX2(ctx->Point.Threshold,ctx->Point.MinSize)+0.5F);
+            dsize/=ctx->Point.Threshold;
+            alpha = (GLint) (VB->ColorPtr->data[i][3]* (dsize*dsize));
+         }
+
+         if (isize<1) {
+            isize = 1;
+         }
+         radius = isize >> 1;
+
+         if (isize & 1) {
+            /* odd size */
+            x0 = x - radius;
+            x1 = x + radius;
+            y0 = y - radius;
+            y1 = y + radius;
+         }
+         else {
+            /* even size */
+            x0 = (GLint) (x + 1.5F) - radius;
+            x1 = x0 + isize - 1;
+            y0 = (GLint) (y + 1.5F) - radius;
+            y1 = y0 + isize - 1;
+         }
+
+        red   = VB->ColorPtr->data[i][0];
+        green = VB->ColorPtr->data[i][1];
+        blue  = VB->ColorPtr->data[i][2];
+        
+        switch (VB->TexCoordPtr[0]->size) {
+        case 4:
+           s = (VB->TexCoordPtr[0]->data[i][0]/
+                VB->TexCoordPtr[0]->data[i][3]);
+           t = (VB->TexCoordPtr[0]->data[i][1]/
+                VB->TexCoordPtr[0]->data[i][3]);
+           u = (VB->TexCoordPtr[0]->data[i][2]/
+                VB->TexCoordPtr[0]->data[i][3]);
+           break;
+        case 3:
+           s = VB->TexCoordPtr[0]->data[i][0];
+           t = VB->TexCoordPtr[0]->data[i][1];
+           u = VB->TexCoordPtr[0]->data[i][2];
+           break;
+        case 2:
+           s = VB->TexCoordPtr[0]->data[i][0];
+           t = VB->TexCoordPtr[0]->data[i][1];
+           u = 0.0;
+           break;
+        case 1:
+           s = VB->TexCoordPtr[0]->data[i][0];
+           t = 0.0;
+           u = 0.0;
+           break;
+        }
+
+        if (ctx->Texture.ReallyEnabled >= TEXTURE1_1D) {
+           /* Multitextured!  This is probably a slow enough path that
+              there's no reason to specialize the multitexture case. */
+           switch (VB->TexCoordPtr[1]->size) {
+           case 4:
+              s1 = ( VB->TexCoordPtr[1]->data[i][0] /  
+                     VB->TexCoordPtr[1]->data[i][3] );
+              t1 = ( VB->TexCoordPtr[1]->data[i][1] / 
+                     VB->TexCoordPtr[1]->data[i][3] );
+              u1 = ( VB->TexCoordPtr[1]->data[i][2] / 
+                     VB->TexCoordPtr[1]->data[i][3] );
+              break;
+           case 3:
+              s1 = VB->TexCoordPtr[1]->data[i][0];
+              t1 = VB->TexCoordPtr[1]->data[i][1];
+              u1 = VB->TexCoordPtr[1]->data[i][2];
+              break;
+           case 2:
+              s1 = VB->TexCoordPtr[1]->data[i][0];
+              t1 = VB->TexCoordPtr[1]->data[i][1];
+              u1 = 0.0;
+              break;
+           case 1:
+              s1 = VB->TexCoordPtr[1]->data[i][0];
+              t1 = 0.0;
+              u1 = 0.0;
+              break;
+           }
+        }
+
+/*    don't think this is needed
+      PB_SET_COLOR( red, green, blue, alpha );
+*/
+  
+         for (iy=y0;iy<=y1;iy++) {
+            for (ix=x0;ix<=x1;ix++) {
+               if (ctx->Texture.ReallyEnabled >= TEXTURE1_1D) {
+                  PB_WRITE_MULTITEX_PIXEL( PB, ix, iy, z, red, green, blue, alpha, s, t, u, s1, t1, u1 );
+               } else {
+                  PB_WRITE_TEX_PIXEL( PB, ix, iy, z, red, green, blue, alpha, s, t, u );
+               }
+            }
+         }
+         PB_CHECK_FLUSH(ctx,PB);
+      }
+   }
+}
+
+/*
+ * Distance Attenuated Antialiased points with or without texture mapping.
+ */
+static void dist_atten_antialiased_rgba_points( GLcontext *ctx,
+                                     GLuint first, GLuint last )
+{
+   struct vertex_buffer *VB = ctx->VB;
+   struct pixel_buffer *PB = ctx->PB;
+   GLuint i;
+   GLfloat radius, rmin, rmax, rmin2, rmax2, cscale;
+   GLfloat psize,dsize,alphaf;
+   GLfloat dist[VB_SIZE];
+   psize=CLAMP(ctx->Point.Size,MIN_POINT_SIZE,MAX_POINT_SIZE);
+
+   if (ctx->NeedEyeCoords)
+      (eye_dist_tab[VB->EyePtr->size])( dist, first, last, ctx, VB->EyePtr );
+   else 
+      clip_dist( dist, first, last, ctx, VB->ClipPtr );
+
+   if (ctx->Texture.ReallyEnabled) {
+      for (i=first;i<=last;i++) {
+         if (VB->ClipMask[i]==0) {
+            GLint xmin, ymin, xmax, ymax;
+            GLint x, y, z;
+            GLint red, green, blue, alpha;
+            GLfloat s, t, u;
+            GLfloat s1, t1, u1;
+
+            dsize=psize*dist[i];
+            if(dsize>=ctx->Point.Threshold) {
+               radius=(MIN2(dsize,ctx->Point.MaxSize)*0.5F);
+               alphaf=1.0;
+            } else {
+               radius=(MAX2(ctx->Point.Threshold,ctx->Point.MinSize)*0.5F);
+               dsize/=ctx->Point.Threshold;
+               alphaf=(dsize*dsize);
+            }
+            rmin = radius - 0.7071F;  /* 0.7071 = sqrt(2)/2 */
+            rmax = radius + 0.7071F;
+            rmin2 = rmin*rmin;
+            rmax2 = rmax*rmax;
+            cscale = 256.0F / (rmax2-rmin2);
+
+            xmin = (GLint) (VB->Win.data[i][0] - radius);
+            xmax = (GLint) (VB->Win.data[i][0] + radius);
+            ymin = (GLint) (VB->Win.data[i][1] - radius);
+            ymax = (GLint) (VB->Win.data[i][1] + radius);
+            z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
+
+           red   = VB->ColorPtr->data[i][0];
+           green = VB->ColorPtr->data[i][1];
+           blue  = VB->ColorPtr->data[i][2];
+        
+           switch (VB->TexCoordPtr[0]->size) {
+           case 4:
+              s = (VB->TexCoordPtr[0]->data[i][0]/
+                   VB->TexCoordPtr[0]->data[i][3]);
+              t = (VB->TexCoordPtr[0]->data[i][1]/
+                   VB->TexCoordPtr[0]->data[i][3]);
+              u = (VB->TexCoordPtr[0]->data[i][2]/
+                   VB->TexCoordPtr[0]->data[i][3]);
+              break;
+           case 3:
+              s = VB->TexCoordPtr[0]->data[i][0];
+              t = VB->TexCoordPtr[0]->data[i][1];
+              u = VB->TexCoordPtr[0]->data[i][2];
+              break;
+           case 2:
+              s = VB->TexCoordPtr[0]->data[i][0];
+              t = VB->TexCoordPtr[0]->data[i][1];
+              u = 0.0;
+              break;
+           case 1:
+              s = VB->TexCoordPtr[0]->data[i][0];
+              t = 0.0;
+              u = 0.0;
+              break;
+           }
+
+           if (ctx->Texture.ReallyEnabled >= TEXTURE1_1D) {
+              /* Multitextured!  This is probably a slow enough path that
+                 there's no reason to specialize the multitexture case. */
+              switch (VB->TexCoordPtr[1]->size) {
+              case 4:
+                 s1 = ( VB->TexCoordPtr[1]->data[i][0] /  
+                        VB->TexCoordPtr[1]->data[i][3] );
+                 t1 = ( VB->TexCoordPtr[1]->data[i][1] / 
+                        VB->TexCoordPtr[1]->data[i][3] );
+                 u1 = ( VB->TexCoordPtr[1]->data[i][2] / 
+                        VB->TexCoordPtr[1]->data[i][3] );
+                 break;
+              case 3:
+                 s1 = VB->TexCoordPtr[1]->data[i][0];
+                 t1 = VB->TexCoordPtr[1]->data[i][1];
+                 u1 = VB->TexCoordPtr[1]->data[i][2];
+                 break;
+              case 2:
+                 s1 = VB->TexCoordPtr[1]->data[i][0];
+                 t1 = VB->TexCoordPtr[1]->data[i][1];
+                 u1 = 0.0;
+                 break;
+              case 1:
+                 s1 = VB->TexCoordPtr[1]->data[i][0];
+                 t1 = 0.0;
+                 u1 = 0.0;
+                 break;
+              }
+           }
+
+            for (y=ymin;y<=ymax;y++) {
+               for (x=xmin;x<=xmax;x++) {
+                  GLfloat dx = x/*+0.5F*/ - VB->Win.data[i][0];
+                  GLfloat dy = y/*+0.5F*/ - VB->Win.data[i][1];
+                  GLfloat dist2 = dx*dx + dy*dy;
+                  if (dist2<rmax2) {
+                     alpha = VB->ColorPtr->data[i][3];
+                     if (dist2>=rmin2) {
+                        GLint coverage = (GLint) (256.0F-(dist2-rmin2)*cscale);
+                        /* coverage is in [0,256] */
+                        alpha = (alpha * coverage) >> 8;
+                     }
+                     alpha = (GLint) (alpha * alphaf);
+                     if (ctx->Texture.ReallyEnabled >= TEXTURE1_1D) {
+                        PB_WRITE_MULTITEX_PIXEL( PB, x,y,z, red, green, blue, alpha, s, t, u, s1, t1, u1 );
+                     } else {
+                        PB_WRITE_TEX_PIXEL( PB, x,y,z, red, green, blue, alpha, s, t, u );
+                     }
+                  }
+               }
+            }
+            PB_CHECK_FLUSH(ctx,PB);
+         }
+      }
+   }
+   else {
+      /* Not texture mapped */
+      for (i=first;i<=last;i++) {
+         if (VB->ClipMask[i]==0) {
+            GLint xmin, ymin, xmax, ymax;
+            GLint x, y, z;
+            GLint red, green, blue, alpha;
+
+            dsize=psize*dist[i];
+            if(dsize>=ctx->Point.Threshold) {
+               radius=(MIN2(dsize,ctx->Point.MaxSize)*0.5F);
+               alphaf=1.0;
+            } else {
+               radius=(MAX2(ctx->Point.Threshold,ctx->Point.MinSize)*0.5F);
+               dsize/=ctx->Point.Threshold;
+               alphaf=(dsize*dsize);
+            }
+            rmin = radius - 0.7071F;  /* 0.7071 = sqrt(2)/2 */
+            rmax = radius + 0.7071F;
+            rmin2 = rmin*rmin;
+            rmax2 = rmax*rmax;
+            cscale = 256.0F / (rmax2-rmin2);
+
+            xmin = (GLint) (VB->Win.data[i][0] - radius);
+            xmax = (GLint) (VB->Win.data[i][0] + radius);
+            ymin = (GLint) (VB->Win.data[i][1] - radius);
+            ymax = (GLint) (VB->Win.data[i][1] + radius);
+            z = (GLint) (VB->Win.data[i][2] + ctx->PointZoffset);
+
+            red   = VB->ColorPtr->data[i][0];
+            green = VB->ColorPtr->data[i][1];
+            blue  = VB->ColorPtr->data[i][2];
+
+            for (y=ymin;y<=ymax;y++) {
+               for (x=xmin;x<=xmax;x++) {
+                  GLfloat dx = x/*+0.5F*/ - VB->Win.data[i][0];
+                  GLfloat dy = y/*+0.5F*/ - VB->Win.data[i][1];
+                  GLfloat dist2 = dx*dx + dy*dy;
+                  if (dist2<rmax2) {
+                    alpha = VB->ColorPtr->data[i][3];
+                     if (dist2>=rmin2) {
+                        GLint coverage = (GLint) (256.0F-(dist2-rmin2)*cscale);
+                        /* coverage is in [0,256] */
+                        alpha = (alpha * coverage) >> 8;
+                     }
+                     alpha = (GLint) (alpha * alphaf);
+                     PB_WRITE_RGBA_PIXEL( PB, x, y, z, red, green, blue, alpha )
+                       ;
+                  }
+               }
+            }
+            PB_CHECK_FLUSH(ctx,PB);
+        }
+      }
+   }
+}
+
+
+/*
+ * Examine the current context to determine which point drawing function
+ * should be used.
+ */
+void gl_set_point_function( GLcontext *ctx )
+{
+   GLboolean rgbmode = ctx->Visual->RGBAflag;
+
+   if (ctx->RenderMode==GL_RENDER) {
+      if (ctx->NoRaster) {
+         ctx->Driver.PointsFunc = null_points;
+         return;
+      }
+      if (ctx->Driver.PointsFunc) {
+         /* Device driver will draw points. */
+        ctx->IndirectTriangles &= ~DD_POINT_SW_RASTERIZE;
+        return;
+      }
+
+      if (!ctx->Point.Attenuated) {
+         if (ctx->Point.SmoothFlag && rgbmode) {
+            ctx->Driver.PointsFunc = antialiased_rgba_points;
+         }
+         else if (ctx->Texture.ReallyEnabled) {
+            if (ctx->Texture.ReallyEnabled >= TEXTURE1_1D) {
+              ctx->Driver.PointsFunc = multitextured_rgba_points;
+            }
+            else {
+               ctx->Driver.PointsFunc = textured_rgba_points;
+            }
+         }
+         else if (ctx->Point.Size==1.0) {
+            /* size=1, any raster ops */
+            if (rgbmode)
+               ctx->Driver.PointsFunc = size1_rgba_points;
+            else
+               ctx->Driver.PointsFunc = size1_ci_points;
+         }
+         else {
+           /* every other kind of point rendering */
+            if (rgbmode)
+               ctx->Driver.PointsFunc = general_rgba_points;
+            else
+               ctx->Driver.PointsFunc = general_ci_points;
+         }
+      } 
+      else if(ctx->Point.SmoothFlag && rgbmode) {
+         ctx->Driver.PointsFunc = dist_atten_antialiased_rgba_points;
+      }
+      else if (ctx->Texture.ReallyEnabled) {
+         ctx->Driver.PointsFunc = dist_atten_textured_rgba_points;
+      } 
+      else {
+         /* every other kind of point rendering */
+         if (rgbmode)
+            ctx->Driver.PointsFunc = dist_atten_general_rgba_points;
+         else
+            ctx->Driver.PointsFunc = dist_atten_general_ci_points;
+     }
+   }
+   else if (ctx->RenderMode==GL_FEEDBACK) {
+      ctx->Driver.PointsFunc = feedback_points;
+   }
+   else {
+      /* GL_SELECT mode */
+      ctx->Driver.PointsFunc = select_points;
+   }
+
+}
+
diff --git a/src/mesa/main/points.h b/src/mesa/main/points.h
new file mode 100644 (file)
index 0000000..a53ce9b
--- /dev/null
@@ -0,0 +1,45 @@
+/* $Id: points.h,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+#ifndef POINTS_H
+#define POINTS_H
+
+
+#include "types.h"
+
+
+extern void gl_PointSize( GLcontext *ctx, GLfloat size );
+
+extern void gl_set_point_function( GLcontext *ctx );
+
+extern void gl_PointParameterfvEXT( GLcontext *ctx, GLenum pname, 
+                                    const GLfloat *params );
+
+#endif
diff --git a/src/mesa/main/polygon.c b/src/mesa/main/polygon.c
new file mode 100644 (file)
index 0000000..8369003
--- /dev/null
@@ -0,0 +1,177 @@
+/* $Id: polygon.c,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "context.h"
+#include "image.h"
+#include "enums.h"
+#include "macros.h"
+#include "polygon.h"
+#include "types.h"
+#ifdef XFree86Server
+#include "GL/xf86glx.h"
+#endif
+#endif
+
+
+
+void gl_CullFace( GLcontext *ctx, GLenum mode )
+{
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glCullFace");
+
+   if (MESA_VERBOSE&VERBOSE_API)
+      fprintf(stderr, "glCullFace %s\n", gl_lookup_enum_by_nr(mode));
+
+   if (mode!=GL_FRONT && mode!=GL_BACK && mode!=GL_FRONT_AND_BACK) {
+      gl_error( ctx, GL_INVALID_ENUM, "glCullFace" );
+      return;
+   }
+
+   ctx->Polygon.CullFaceMode = mode;
+   ctx->NewState |= NEW_POLYGON;
+
+   if (ctx->Driver.CullFace)
+      ctx->Driver.CullFace( ctx, mode );
+}
+
+
+
+void gl_FrontFace( GLcontext *ctx, GLenum mode )
+{
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glFrontFace");
+
+   if (MESA_VERBOSE&VERBOSE_API)
+      fprintf(stderr, "glFrontFace %s\n", gl_lookup_enum_by_nr(mode));
+
+   if (mode!=GL_CW && mode!=GL_CCW) {
+      gl_error( ctx, GL_INVALID_ENUM, "glFrontFace" );
+      return;
+   }
+   ctx->Polygon.FrontFace = mode;
+   ctx->Polygon.FrontBit = (mode == GL_CW);
+
+   if (ctx->Driver.FrontFace)
+      ctx->Driver.FrontFace( ctx, mode );
+}
+
+
+
+void gl_PolygonMode( GLcontext *ctx, GLenum face, GLenum mode )
+{
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPolygonMode");
+
+   if (MESA_VERBOSE&VERBOSE_API)
+      fprintf(stderr, "glPolygonMode %s %s\n", 
+             gl_lookup_enum_by_nr(face),
+             gl_lookup_enum_by_nr(mode));
+
+   if (face!=GL_FRONT && face!=GL_BACK && face!=GL_FRONT_AND_BACK) {
+      gl_error( ctx, GL_INVALID_ENUM, "glPolygonMode(face)" );
+      return;
+   }
+   else if (mode!=GL_POINT && mode!=GL_LINE && mode!=GL_FILL) {
+      gl_error( ctx, GL_INVALID_ENUM, "glPolygonMode(mode)" );
+      return;
+   }
+
+   if (face==GL_FRONT || face==GL_FRONT_AND_BACK) {
+      ctx->Polygon.FrontMode = mode;
+   }
+   if (face==GL_BACK || face==GL_FRONT_AND_BACK) {
+      ctx->Polygon.BackMode = mode;
+   }
+
+   /* Compute a handy "shortcut" value: */
+   ctx->TriangleCaps &= ~DD_TRI_UNFILLED;
+   ctx->Polygon.Unfilled = GL_FALSE;
+
+   if (ctx->Polygon.FrontMode!=GL_FILL || ctx->Polygon.BackMode!=GL_FILL) {
+      ctx->Polygon.Unfilled = GL_TRUE;
+      ctx->TriangleCaps |= DD_TRI_UNFILLED;
+   }
+   else {
+      ctx->Polygon.Unfilled = GL_FALSE;
+   }
+
+   ctx->NewState |= (NEW_POLYGON | NEW_RASTER_OPS);
+
+   if (ctx->Driver.PolygonMode) {
+      (*ctx->Driver.PolygonMode)( ctx, face, mode );
+   }
+}
+
+
+
+/*
+ * NOTE:  stipple pattern has already been unpacked.
+ */
+void gl_PolygonStipple( GLcontext *ctx, const GLuint pattern[32] )
+{
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPolygonStipple");
+
+   if (MESA_VERBOSE&VERBOSE_API)
+      fprintf(stderr, "glPolygonStipple\n");
+
+   MEMCPY( ctx->PolygonStipple, pattern, 32 * 4 );
+
+   if (ctx->Polygon.StippleFlag) {
+      ctx->NewState |= NEW_RASTER_OPS;
+   }
+}
+
+
+
+void gl_GetPolygonStipple( GLcontext *ctx, GLubyte *dest )
+{
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPolygonOffset");
+
+   if (MESA_VERBOSE&VERBOSE_API)
+      fprintf(stderr, "glGetPolygonStipple\n");
+
+   gl_pack_polygon_stipple( ctx, ctx->PolygonStipple, dest );
+}
+
+
+
+void gl_PolygonOffset( GLcontext *ctx,
+                       GLfloat factor, GLfloat units )
+{
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPolygonOffset");
+
+   if (MESA_VERBOSE&VERBOSE_API)
+      fprintf(stderr, "glPolygonOffset %f %f\n", factor, units);
+
+   ctx->Polygon.OffsetFactor = factor;
+   ctx->Polygon.OffsetUnits = units;
+}
+
diff --git a/src/mesa/main/polygon.h b/src/mesa/main/polygon.h
new file mode 100644 (file)
index 0000000..ac591bb
--- /dev/null
@@ -0,0 +1,53 @@
+/* $Id: polygon.h,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+#ifndef POLYGON_H
+#define POLYGON_H
+
+
+#include "types.h"
+
+
+extern void gl_CullFace( GLcontext *ctx, GLenum mode );
+
+extern void gl_FrontFace( GLcontext *ctx, GLenum mode );
+
+extern void gl_PolygonMode( GLcontext *ctx, GLenum face, GLenum mode );
+
+extern void gl_PolygonOffset( GLcontext *ctx,
+                              GLfloat factor, GLfloat units );
+
+extern void gl_PolygonStipple( GLcontext *ctx, const GLuint pattern[32] );
+
+extern void gl_GetPolygonStipple( GLcontext *ctx, GLubyte *mask );
+
+
+#endif
+
diff --git a/src/mesa/main/rastpos.c b/src/mesa/main/rastpos.c
new file mode 100644 (file)
index 0000000..000af37
--- /dev/null
@@ -0,0 +1,227 @@
+/* $Id: rastpos.c,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <assert.h>
+#include "clip.h"
+#include "feedback.h"
+#include "light.h"
+#include "macros.h"
+#include "matrix.h"
+#include "mmath.h"
+#include "shade.h"
+#include "types.h"
+#include "xform.h"
+#include "context.h"
+#ifdef XFree86Server
+#include "GL/xf86glx.h"
+#endif
+#endif
+
+
+
+/*
+ * Caller:  context->API.RasterPos4f
+ */
+void gl_RasterPos4f( GLcontext *ctx,
+                     GLfloat x, GLfloat y, GLfloat z, GLfloat w )
+{
+   GLfloat v[4], eye[4], clip[4], ndc[3], d;
+
+   /* KW: Added this test, which is in the spec.  We can't do this
+    *     outside begin/end any more because the ctx->Current values
+    *     aren't uptodate during that period. 
+    */
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH( ctx, "glRasterPos" );
+
+   if (ctx->NewState)
+      gl_update_state( ctx );
+
+   ASSIGN_4V( v, x, y, z, w );
+   TRANSFORM_POINT( eye, ctx->ModelView.m, v );
+
+   /* raster color */
+   if (ctx->Light.Enabled) 
+   {
+      /*GLfloat *vert;*/
+      GLfloat *norm, eyenorm[3];
+      GLfloat *objnorm = ctx->Current.Normal;
+
+         /* Not needed???
+      vert = (ctx->NeedEyeCoords ? eye : v);
+         */
+
+      if (ctx->NeedEyeNormals) {
+        GLfloat *inv = ctx->ModelView.inv;
+        TRANSFORM_NORMAL( eyenorm, objnorm, inv );
+        norm = eyenorm;
+      } else {
+        norm = objnorm;
+      }
+
+      gl_shade_rastpos( ctx, v, norm, 
+                       ctx->Current.RasterColor,
+                       &ctx->Current.RasterIndex );
+
+   }
+   else {
+      /* use current color or index */
+      if (ctx->Visual->RGBAflag) {
+        UBYTE_RGBA_TO_FLOAT_RGBA(ctx->Current.RasterColor, 
+                                 ctx->Current.ByteColor);
+      }
+      else {
+        ctx->Current.RasterIndex = ctx->Current.Index;
+      }
+   }
+
+   /* compute raster distance */
+   ctx->Current.RasterDistance =
+                      GL_SQRT( eye[0]*eye[0] + eye[1]*eye[1] + eye[2]*eye[2] );
+
+   /* apply projection matrix:  clip = Proj * eye */
+   TRANSFORM_POINT( clip, ctx->ProjectionMatrix.m, eye );
+
+   /* clip to view volume */
+   if (gl_viewclip_point( clip )==0) {
+      ctx->Current.RasterPosValid = GL_FALSE;
+      return;
+   }
+
+   /* clip to user clipping planes */
+   if ( ctx->Transform.AnyClip &&
+       gl_userclip_point(ctx, clip) == 0) 
+   {
+      ctx->Current.RasterPosValid = GL_FALSE;
+      return;
+   }
+
+   /* ndc = clip / W */
+   ASSERT( clip[3]!=0.0 );
+   d = 1.0F / clip[3];
+   ndc[0] = clip[0] * d;
+   ndc[1] = clip[1] * d;
+   ndc[2] = clip[2] * d;
+
+   ctx->Current.RasterPos[0] = (ndc[0] * ctx->Viewport.WindowMap.m[MAT_SX] + 
+                               ctx->Viewport.WindowMap.m[MAT_TX]);
+   ctx->Current.RasterPos[1] = (ndc[1] * ctx->Viewport.WindowMap.m[MAT_SY] + 
+                               ctx->Viewport.WindowMap.m[MAT_TY]);
+   ctx->Current.RasterPos[2] = (ndc[2] * ctx->Viewport.WindowMap.m[MAT_SZ] + 
+                               ctx->Viewport.WindowMap.m[MAT_TZ]) / DEPTH_SCALE;
+   ctx->Current.RasterPos[3] = clip[3];
+   ctx->Current.RasterPosValid = GL_TRUE;
+
+   /* FOG??? */
+
+   {
+      GLuint texSet;
+      for (texSet=0; texSet<MAX_TEXTURE_UNITS; texSet++) {
+         COPY_4FV( ctx->Current.RasterMultiTexCoord[texSet],
+                  ctx->Current.Texcoord[texSet] );
+      }
+   }
+
+   if (ctx->RenderMode==GL_SELECT) {
+      gl_update_hitflag( ctx, ctx->Current.RasterPos[2] );
+   }
+
+}
+
+
+
+/*
+ * This is a MESA extension function.  Pretty much just like glRasterPos
+ * except we don't apply the modelview or projection matrices; specify a
+ * window coordinate directly.
+ * Caller:  context->API.WindowPos4fMESA pointer.
+ */
+void gl_windowpos( GLcontext *ctx, GLfloat x, GLfloat y, GLfloat z, GLfloat w )
+{
+   /* KW: Assume that like rasterpos, this must be outside begin/end.
+    */
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH( ctx, "glWindowPosMESA" );
+
+   /* set raster position */
+   ctx->Current.RasterPos[0] = x;
+   ctx->Current.RasterPos[1] = y;
+   ctx->Current.RasterPos[2] = CLAMP( z, 0.0F, 1.0F );
+   ctx->Current.RasterPos[3] = w;
+
+   ctx->Current.RasterPosValid = GL_TRUE;
+
+   /* raster color */
+   if (0 && ctx->Light.Enabled) {
+
+      /* KW: I don't see how this can work - would have to take the
+       *     inverse of the projection matrix or the combined
+       *     modelProjection matrix, transform point and normal, and
+       *     do the lighting.  Those inverses are not used for
+       *     anything else.  This is not an object-space lighting
+       *     issue - what this is trying to do is something like
+       *     clip-space or window-space lighting...
+       *
+       *     Anyway, since the implementation was never correct, I'm
+       *     not fixing it now - just use the unlit color. 
+       */
+
+      /* KW:  As a reprise, we now *do* keep the inverse of the projection
+       *      matrix, so it is not infeasible to try to swim up stream
+       *      in this manner.  I still don't want to implement it,
+       *      however.
+       */
+   }
+   else {
+      /* use current color or index */
+      if (ctx->Visual->RGBAflag) {
+        UBYTE_RGBA_TO_FLOAT_RGBA(ctx->Current.RasterColor, 
+                                 ctx->Current.ByteColor);
+      }
+      else {
+        ctx->Current.RasterIndex = ctx->Current.Index;
+      }
+   }
+
+   ctx->Current.RasterDistance = 0.0;
+
+   {
+      GLuint texSet;
+      for (texSet=0; texSet<MAX_TEXTURE_UNITS; texSet++) {
+         COPY_4FV( ctx->Current.RasterMultiTexCoord[texSet],
+                  ctx->Current.Texcoord[texSet] );
+      }
+   }
+
+   if (ctx->RenderMode==GL_SELECT) {
+      gl_update_hitflag( ctx, ctx->Current.RasterPos[2] );
+   }
+}
diff --git a/src/mesa/main/rastpos.h b/src/mesa/main/rastpos.h
new file mode 100644 (file)
index 0000000..44dfbab
--- /dev/null
@@ -0,0 +1,48 @@
+/* $Id: rastpos.h,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+#ifndef RASTPOS_H
+#define RASTPOS_H
+
+
+#include "types.h"
+
+
+extern void gl_RasterPos4f( GLcontext *ctx,
+                            GLfloat x, GLfloat y, GLfloat z, GLfloat w );
+
+
+extern void gl_windowpos( GLcontext *ctx,
+                          GLfloat x, GLfloat y, GLfloat z, GLfloat w );
+
+
+
+#endif
+
diff --git a/src/mesa/main/simple_list.h b/src/mesa/main/simple_list.h
new file mode 100644 (file)
index 0000000..994d955
--- /dev/null
@@ -0,0 +1,99 @@
+/* $Id: simple_list.h,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*  Simple macros for typesafe, intrusive lists.
+ *  (C) 1997, Keith Whitwell
+ *
+ *  Intended to work with a list sentinal which is created as an empty
+ *  list.  Insert & delete are O(1).  
+ */
+
+
+#ifndef _SIMPLE_LIST_H
+#define _SIMPLE_LIST_H
+
+#define remove_from_list(elem)                 \
+do {                                           \
+   (elem)->next->prev = (elem)->prev;          \
+   (elem)->prev->next = (elem)->next;          \
+} while (0)
+
+#define insert_at_head(list, elem)             \
+do {                                           \
+   (elem)->prev = list;                                \
+   (elem)->next = (list)->next;                        \
+   (list)->next->prev = elem;                  \
+   (list)->next = elem;                                \
+} while(0)
+
+#define insert_at_tail(list, elem)             \
+do {                                           \
+   (elem)->next = list;                                \
+   (elem)->prev = (list)->prev;                        \
+   (list)->prev->next = elem;                  \
+   (list)->prev = elem;                                \
+} while(0)
+
+#define move_to_head(list, elem)               \
+do {                                           \
+   remove_from_list(elem);                     \
+   insert_at_head(list, elem);                 \
+} while (0)
+
+#define move_to_tail(list, elem)               \
+do {                                           \
+   remove_from_list(elem);                     \
+   insert_at_tail(list, elem);                 \
+} while (0)
+
+
+#define make_empty_list(sentinal)              \
+do {                                           \
+   (sentinal)->next = sentinal;                        \
+   (sentinal)->prev = sentinal;                        \
+} while (0)
+
+
+#define first_elem(list)       ((list)->next)
+#define last_elem(list)        ((list)->prev)
+#define next_elem(elem)        ((elem)->next)
+#define prev_elem(elem)        ((elem)->prev)
+#define at_end(list, elem)     ((elem) == (list))
+#define is_empty_list(list)    ((list)->next == (list))
+
+#define foreach(ptr, list)     \
+        for( ptr=(list)->next ;  ptr!=list ;  ptr=(ptr)->next )
+
+/* Kludgey - Lets you unlink the current value during a list
+ *           traversal.  Useful for free()-ing a list, element
+ *           by element.
+ */
+#define foreach_s(ptr, t, list)   \
+        for(ptr=(list)->next,t=(ptr)->next; list != ptr; ptr=t, t=(t)->next)
+
+
+#endif
+
diff --git a/src/mesa/main/stencil.c b/src/mesa/main/stencil.c
new file mode 100644 (file)
index 0000000..69bd701
--- /dev/null
@@ -0,0 +1,1107 @@
+/* $Id: stencil.c,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <stdlib.h>
+#include <string.h>
+#include "context.h"
+#include "macros.h"
+#include "pb.h"
+#include "stencil.h"
+#include "types.h"
+#ifdef XFree86Server
+#include "GL/xf86glx.h"
+#endif
+#endif
+
+
+#if STENCIL_BITS==8
+#  define STENCIL_MAX 0xff
+#elif STENCIL_BITS==16
+#  define STENCIL_MAX 0xffff
+#else
+   illegal number of stencil bits
+#endif
+
+
+
+/*
+ * Return the address of a stencil buffer value given the window coords:
+ */
+#define STENCIL_ADDRESS(X,Y)  (ctx->Buffer->Stencil + ctx->Buffer->Width * (Y) + (X))
+
+
+void gl_ClearStencil( GLcontext *ctx, GLint s )
+{
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glClearStencil");
+   ctx->Stencil.Clear = (GLstencil) s;
+
+   if (ctx->Driver.ClearStencil) {
+      (*ctx->Driver.ClearStencil)( ctx, s );
+   }
+}
+
+
+
+void gl_StencilFunc( GLcontext *ctx, GLenum func, GLint ref, GLuint mask )
+{
+   GLint maxref;
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glStencilFunc");
+
+   switch (func) {
+      case GL_NEVER:
+      case GL_LESS:
+      case GL_LEQUAL:
+      case GL_GREATER:
+      case GL_GEQUAL:
+      case GL_EQUAL:
+      case GL_NOTEQUAL:
+      case GL_ALWAYS:
+         ctx->Stencil.Function = func;
+         break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glStencilFunc" );
+         return;
+   }
+
+   maxref = (1 << STENCIL_BITS) - 1;
+   ctx->Stencil.Ref = CLAMP( ref, 0, maxref );
+   ctx->Stencil.ValueMask = mask;
+
+   if (ctx->Driver.StencilFunc) {
+      (*ctx->Driver.StencilFunc)( ctx, func, ctx->Stencil.Ref, mask );
+   }
+}
+
+
+
+void gl_StencilMask( GLcontext *ctx, GLuint mask )
+{
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glStencilMask");
+   ctx->Stencil.WriteMask = (GLstencil) mask;
+
+   if (ctx->Driver.StencilMask) {
+      (*ctx->Driver.StencilMask)( ctx, mask );
+   }
+}
+
+
+
+void gl_StencilOp( GLcontext *ctx, GLenum fail, GLenum zfail, GLenum zpass )
+{
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glStencilOp");
+   switch (fail) {
+      case GL_KEEP:
+      case GL_ZERO:
+      case GL_REPLACE:
+      case GL_INCR:
+      case GL_DECR:
+      case GL_INVERT:
+      case GL_INCR_WRAP_EXT:
+      case GL_DECR_WRAP_EXT:
+         ctx->Stencil.FailFunc = fail;
+         break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glStencilOp" );
+         return;
+   }
+   switch (zfail) {
+      case GL_KEEP:
+      case GL_ZERO:
+      case GL_REPLACE:
+      case GL_INCR:
+      case GL_DECR:
+      case GL_INVERT:
+      case GL_INCR_WRAP_EXT:
+      case GL_DECR_WRAP_EXT:
+         ctx->Stencil.ZFailFunc = zfail;
+         break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glStencilOp" );
+         return;
+   }
+   switch (zpass) {
+      case GL_KEEP:
+      case GL_ZERO:
+      case GL_REPLACE:
+      case GL_INCR:
+      case GL_DECR:
+      case GL_INVERT:
+      case GL_INCR_WRAP_EXT:
+      case GL_DECR_WRAP_EXT:
+         ctx->Stencil.ZPassFunc = zpass;
+         break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glStencilOp" );
+         return;
+   }
+
+   if (ctx->Driver.StencilOp) {
+      (*ctx->Driver.StencilOp)( ctx, fail, zfail, zpass );
+   }
+}
+
+
+
+/* Stencil Logic:
+
+IF stencil test fails THEN
+   Don't write the pixel (RGBA,Z)
+   Execute FailOp
+ELSE
+   Write the pixel
+ENDIF
+
+Perform Depth Test
+
+IF depth test passes OR no depth buffer THEN
+   Execute ZPass
+   Write the pixel
+ELSE
+   Execute ZFail
+ENDIF
+
+*/
+
+
+
+
+/*
+ * Apply the given stencil operator for each pixel in the span whose
+ * mask flag is set.
+ * Input:  n - number of pixels in the span
+ *         x, y - location of leftmost pixel in the span
+ *         oper - the stencil buffer operator
+ *         mask - array [n] of flag:  1=apply operator, 0=don't apply operator
+ */
+static void apply_stencil_op_to_span( GLcontext *ctx,
+                                      GLuint n, GLint x, GLint y,
+                                     GLenum oper, GLubyte mask[] )
+{
+   const GLstencil ref = ctx->Stencil.Ref;
+   const GLstencil wrtmask = ctx->Stencil.WriteMask;
+   const GLstencil invmask = ~ctx->Stencil.WriteMask;
+   GLstencil *stencil = STENCIL_ADDRESS( x, y );
+   GLuint i;
+
+   switch (oper) {
+      case GL_KEEP:
+         /* do nothing */
+         break;
+      case GL_ZERO:
+        if (invmask==0) {
+           for (i=0;i<n;i++) {
+              if (mask[i]) {
+                 stencil[i] = 0;
+              }
+           }
+        }
+        else {
+           for (i=0;i<n;i++) {
+              if (mask[i]) {
+                 stencil[i] = stencil[i] & invmask;
+              }
+           }
+        }
+        break;
+      case GL_REPLACE:
+        if (invmask==0) {
+           for (i=0;i<n;i++) {
+              if (mask[i]) {
+                  stencil[i] = ref;
+              }
+           }
+        }
+        else {
+           for (i=0;i<n;i++) {
+              if (mask[i]) {
+                 GLstencil s = stencil[i];
+                 stencil[i] = (invmask & s ) | (wrtmask & ref);
+              }
+           }
+        }
+        break;
+      case GL_INCR:
+        if (invmask==0) {
+           for (i=0;i<n;i++) {
+              if (mask[i]) {
+                 GLstencil s = stencil[i];
+                 if (s < STENCIL_MAX) {
+                    stencil[i] = s+1;
+                 }
+              }
+           }
+        }
+        else {
+           for (i=0;i<n;i++) {
+              if (mask[i]) {
+                 /* VERIFY logic of adding 1 to a write-masked value */
+                 GLstencil s = stencil[i];
+                 if (s < STENCIL_MAX) {
+                    stencil[i] = (invmask & s) | (wrtmask & (s+1));
+                 }
+              }
+           }
+        }
+        break;
+      case GL_DECR:
+        if (invmask==0) {
+           for (i=0;i<n;i++) {
+              if (mask[i]) {
+                 GLstencil s = stencil[i];
+                 if (s>0) {
+                    stencil[i] = s-1;
+                 }
+              }
+           }
+        }
+        else {
+           for (i=0;i<n;i++) {
+              if (mask[i]) {
+                 /* VERIFY logic of subtracting 1 to a write-masked value */
+                 GLstencil s = stencil[i];
+                 if (s>0) {
+                    stencil[i] = (invmask & s) | (wrtmask & (s-1));
+                 }
+              }
+           }
+        }
+        break;
+      case GL_INCR_WRAP_EXT:
+        if (invmask==0) {
+           for (i=0;i<n;i++) {
+              if (mask[i]) {
+                  stencil[i]++;
+              }
+           }
+        }
+        else {
+           for (i=0;i<n;i++) {
+              if (mask[i]) {
+                  GLstencil s = stencil[i];
+                  stencil[i] = (invmask & s) | (wrtmask & (stencil[i]+1));
+              }
+           }
+        }
+        break;
+      case GL_DECR_WRAP_EXT:
+        if (invmask==0) {
+           for (i=0;i<n;i++) {
+              if (mask[i]) {
+                 stencil[i]--;
+              }
+           }
+        }
+        else {
+           for (i=0;i<n;i++) {
+              if (mask[i]) {
+                  GLstencil s = stencil[i];
+                  stencil[i] = (invmask & s) | (wrtmask & (stencil[i]-1));
+              }
+           }
+        }
+        break;
+      case GL_INVERT:
+        if (invmask==0) {
+           for (i=0;i<n;i++) {
+              if (mask[i]) {
+                 GLstencil s = stencil[i];
+                 stencil[i] = ~s;
+              }
+           }
+        }
+        else {
+           for (i=0;i<n;i++) {
+              if (mask[i]) {
+                 GLstencil s = stencil[i];
+                 stencil[i] = (invmask & s) | (wrtmask & ~s);
+              }
+           }
+        }
+        break;
+      default:
+         gl_problem(ctx, "Bad stencilop in apply_stencil_op_to_span");
+   }
+}
+
+
+
+
+/*
+ * Apply stencil test to a span of pixels before depth buffering.
+ * Input:  n - number of pixels in the span
+ *         x, y - coordinate of left-most pixel in the span
+ *         mask - array [n] of flag:  0=skip the pixel, 1=stencil the pixel
+ * Output:  mask - pixels which fail the stencil test will have their
+ *                 mask flag set to 0.
+ * Return:  0 = all pixels failed, 1 = zero or more pixels passed.
+ */
+GLint gl_stencil_span( GLcontext *ctx,
+                       GLuint n, GLint x, GLint y, GLubyte mask[] )
+{
+   GLubyte fail[MAX_WIDTH];
+   GLint allfail = 0;
+   GLuint i;
+   GLstencil r, s;
+   GLstencil *stencil;
+
+   stencil = STENCIL_ADDRESS( x, y );
+
+   /*
+    * Perform stencil test.  The results of this operation are stored
+    * in the fail[] array:
+    *   IF fail[i] is non-zero THEN
+    *       the stencil fail operator is to be applied
+    *   ELSE
+    *       the stencil fail operator is not to be applied
+    *   ENDIF
+    */
+   switch (ctx->Stencil.Function) {
+      case GL_NEVER:
+         /* always fail */
+         for (i=0;i<n;i++) {
+           if (mask[i]) {
+              mask[i] = 0;
+              fail[i] = 1;
+           }
+           else {
+              fail[i] = 0;
+           }
+        }
+        allfail = 1;
+        break;
+      case GL_LESS:
+        r = ctx->Stencil.Ref & ctx->Stencil.ValueMask;
+        for (i=0;i<n;i++) {
+           if (mask[i]) {
+              s = stencil[i] & ctx->Stencil.ValueMask;
+              if (r < s) {
+                 /* passed */
+                 fail[i] = 0;
+              }
+              else {
+                 fail[i] = 1;
+                 mask[i] = 0;
+              }
+           }
+           else {
+              fail[i] = 0;
+           }
+        }
+        break;
+      case GL_LEQUAL:
+        r = ctx->Stencil.Ref & ctx->Stencil.ValueMask;
+        for (i=0;i<n;i++) {
+           if (mask[i]) {
+              s = stencil[i] & ctx->Stencil.ValueMask;
+              if (r <= s) {
+                 /* pass */
+                 fail[i] = 0;
+              }
+              else {
+                 fail[i] = 1;
+                 mask[i] = 0;
+              }
+           }
+           else {
+              fail[i] = 0;
+           }
+        }
+        break;
+      case GL_GREATER:
+        r = ctx->Stencil.Ref & ctx->Stencil.ValueMask;
+        for (i=0;i<n;i++) {
+           if (mask[i]) {
+              s = stencil[i] & ctx->Stencil.ValueMask;
+              if (r > s) {
+                 /* passed */
+                 fail[i] = 0;
+              }
+              else {
+                 fail[i] = 1;
+                 mask[i] = 0;
+              }
+           }
+           else {
+              fail[i] = 0;
+           }
+        }
+        break;
+      case GL_GEQUAL:
+        r = ctx->Stencil.Ref & ctx->Stencil.ValueMask;
+        for (i=0;i<n;i++) {
+           if (mask[i]) {
+              s = stencil[i] & ctx->Stencil.ValueMask;
+              if (r >= s) {
+                 /* passed */
+                 fail[i] = 0;
+              }
+              else {
+                 fail[i] = 1;
+                 mask[i] = 0;
+              }
+           }
+           else {
+              fail[i] = 0;
+           }
+        }
+        break;
+      case GL_EQUAL:
+        r = ctx->Stencil.Ref & ctx->Stencil.ValueMask;
+        for (i=0;i<n;i++) {
+           if (mask[i]) {
+              s = stencil[i] & ctx->Stencil.ValueMask;
+              if (r == s) {
+                 /* passed */
+                 fail[i] = 0;
+              }
+              else {
+                 fail[i] = 1;
+                 mask[i] = 0;
+              }
+           }
+           else {
+              fail[i] = 0;
+           }
+        }
+        break;
+      case GL_NOTEQUAL:
+        r = ctx->Stencil.Ref & ctx->Stencil.ValueMask;
+        for (i=0;i<n;i++) {
+           if (mask[i]) {
+              s = stencil[i] & ctx->Stencil.ValueMask;
+              if (r != s) {
+                 /* passed */
+                 fail[i] = 0;
+              }
+              else {
+                 fail[i] = 1;
+                 mask[i] = 0;
+              }
+           }
+           else {
+              fail[i] = 0;
+           }
+        }
+        break;
+      case GL_ALWAYS:
+        /* always pass */
+        for (i=0;i<n;i++) {
+           fail[i] = 0;
+        }
+        break;
+      default:
+         gl_problem(ctx, "Bad stencil func in gl_stencil_span");
+         return 0;
+   }
+
+   apply_stencil_op_to_span( ctx, n, x, y, ctx->Stencil.FailFunc, fail );
+
+   return (allfail) ? 0 : 1;
+}
+
+
+
+
+/*
+ * Apply the combination depth-buffer/stencil operator to a span of pixels.
+ * Input:  n - number of pixels in the span
+ *         x, y - location of leftmost pixel in span
+ *         z - array [n] of z values
+ * Input:  mask - array [n] of flags  (1=test this pixel, 0=skip the pixel)
+ * Output:  mask - array [n] of flags (1=depth test passed, 0=failed) 
+ */
+void gl_depth_stencil_span( GLcontext *ctx,
+                            GLuint n, GLint x, GLint y, const GLdepth z[],
+                           GLubyte mask[] )
+{
+   if (ctx->Depth.Test==GL_FALSE) {
+      /*
+       * No depth buffer, just apply zpass stencil function to active pixels.
+       */
+      apply_stencil_op_to_span( ctx, n, x, y, ctx->Stencil.ZPassFunc, mask );
+   }
+   else {
+      /*
+       * Perform depth buffering, then apply zpass or zfail stencil function.
+       */
+      GLubyte passmask[MAX_WIDTH], failmask[MAX_WIDTH], oldmask[MAX_WIDTH];
+      GLuint i;
+
+      /* init pass and fail masks to zero, copy mask[] to oldmask[] */
+      for (i=0;i<n;i++) {
+        passmask[i] = failmask[i] = 0;
+         oldmask[i] = mask[i];
+      }
+
+      /* apply the depth test */
+      if (ctx->Driver.DepthTestSpan)
+         (*ctx->Driver.DepthTestSpan)( ctx, n, x, y, z, mask );
+
+      /* set the stencil pass/fail flags according to result of depth test */
+      for (i=0;i<n;i++) {
+         if (oldmask[i]) {
+            if (mask[i]) {
+               passmask[i] = 1;
+            }
+            else {
+               failmask[i] = 1;
+            }
+         }
+      }
+
+      /* apply the pass and fail operations */
+      apply_stencil_op_to_span( ctx, n, x, y, ctx->Stencil.ZFailFunc, failmask );
+      apply_stencil_op_to_span( ctx, n, x, y, ctx->Stencil.ZPassFunc, passmask );
+   }
+}
+
+
+
+
+/*
+ * Apply the given stencil operator for each pixel in the array whose
+ * mask flag is set.
+ * Input:  n - number of pixels in the span
+ *         x, y - array of [n] pixels
+ *         operator - the stencil buffer operator
+ *         mask - array [n] of flag:  1=apply operator, 0=don't apply operator
+ */
+static void apply_stencil_op_to_pixels( GLcontext *ctx,
+                                        GLuint n, const GLint x[],
+                                       const GLint y[],
+                                       GLenum oper, GLubyte mask[] )
+{
+   GLuint i;
+   GLstencil ref;
+   GLstencil wrtmask, invmask;
+
+   wrtmask = ctx->Stencil.WriteMask;
+   invmask = ~ctx->Stencil.WriteMask;
+
+   ref = ctx->Stencil.Ref;
+
+   switch (oper) {
+      case GL_KEEP:
+         /* do nothing */
+         break;
+      case GL_ZERO:
+        if (invmask==0) {
+           for (i=0;i<n;i++) {
+              if (mask[i]) {
+                  GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
+                  *sptr = 0;
+              }
+           }
+        }
+        else {
+           for (i=0;i<n;i++) {
+              if (mask[i]) {
+                  GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
+                 *sptr = invmask & *sptr;
+              }
+           }
+        }
+        break;
+      case GL_REPLACE:
+        if (invmask==0) {
+           for (i=0;i<n;i++) {
+              if (mask[i]) {
+                  GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
+                  *sptr = ref;
+              }
+           }
+        }
+        else {
+           for (i=0;i<n;i++) {
+              if (mask[i]) {
+                  GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
+                 *sptr = (invmask & *sptr ) | (wrtmask & ref);
+              }
+           }
+        }
+        break;
+      case GL_INCR:
+        if (invmask==0) {
+           for (i=0;i<n;i++) {
+              if (mask[i]) {
+                  GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
+                 if (*sptr < STENCIL_MAX) {
+                    *sptr = *sptr + 1;
+                 }
+              }
+           }
+        }
+        else {
+           for (i=0;i<n;i++) {
+              if (mask[i]) {
+                  GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
+                 if (*sptr < STENCIL_MAX) {
+                    *sptr = (invmask & *sptr) | (wrtmask & (*sptr+1));
+                 }
+              }
+           }
+        }
+        break;
+      case GL_DECR:
+        if (invmask==0) {
+           for (i=0;i<n;i++) {
+              if (mask[i]) {
+                  GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
+                 if (*sptr>0) {
+                    *sptr = *sptr - 1;
+                 }
+              }
+           }
+        }
+        else {
+           for (i=0;i<n;i++) {
+              if (mask[i]) {
+                  GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
+                 if (*sptr>0) {
+                    *sptr = (invmask & *sptr) | (wrtmask & (*sptr-1));
+                 }
+              }
+           }
+        }
+        break;
+      case GL_INCR_WRAP_EXT:
+        if (invmask==0) {
+           for (i=0;i<n;i++) {
+              if (mask[i]) {
+                  GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
+                  *sptr = *sptr + 1;
+              }
+           }
+        }
+        else {
+           for (i=0;i<n;i++) {
+              if (mask[i]) {
+                  GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
+                  *sptr = (invmask & *sptr) | (wrtmask & (*sptr+1));
+              }
+           }
+        }
+        break;
+      case GL_DECR_WRAP_EXT:
+        if (invmask==0) {
+           for (i=0;i<n;i++) {
+              if (mask[i]) {
+                  GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
+                  *sptr = *sptr - 1;
+              }
+           }
+        }
+        else {
+           for (i=0;i<n;i++) {
+              if (mask[i]) {
+                  GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
+                  *sptr = (invmask & *sptr) | (wrtmask & (*sptr-1));
+              }
+           }
+        }
+        break;
+      case GL_INVERT:
+        if (invmask==0) {
+           for (i=0;i<n;i++) {
+              if (mask[i]) {
+                  GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
+                  *sptr = ~*sptr;
+              }
+           }
+        }
+        else {
+           for (i=0;i<n;i++) {
+              if (mask[i]) {
+                  GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
+                  *sptr = (invmask & *sptr) | (wrtmask & ~*sptr);
+              }
+           }
+        }
+        break;
+      default:
+         gl_problem(ctx, "Bad stencilop in apply_stencil_op_to_pixels");
+   }
+}
+
+
+
+/*
+ * Apply stencil test to an array of pixels before depth buffering.
+ * Input:  n - number of pixels in the span
+ *         x, y - array of [n] pixels to stencil
+ *         mask - array [n] of flag:  0=skip the pixel, 1=stencil the pixel
+ * Output:  mask - pixels which fail the stencil test will have their
+ *                 mask flag set to 0.
+ * Return:  0 = all pixels failed, 1 = zero or more pixels passed.
+ */
+GLint gl_stencil_pixels( GLcontext *ctx,
+                         GLuint n, const GLint x[], const GLint y[],
+                        GLubyte mask[] )
+{
+   GLubyte fail[PB_SIZE];
+   GLstencil r, s;
+   GLuint i;
+   GLint allfail = 0;
+
+   /*
+    * Perform stencil test.  The results of this operation are stored
+    * in the fail[] array:
+    *   IF fail[i] is non-zero THEN
+    *       the stencil fail operator is to be applied
+    *   ELSE
+    *       the stencil fail operator is not to be applied
+    *   ENDIF
+    */
+
+   switch (ctx->Stencil.Function) {
+      case GL_NEVER:
+         /* always fail */
+         for (i=0;i<n;i++) {
+           if (mask[i]) {
+              mask[i] = 0;
+              fail[i] = 1;
+           }
+           else {
+              fail[i] = 0;
+           }
+        }
+        allfail = 1;
+        break;
+      case GL_LESS:
+        r = ctx->Stencil.Ref & ctx->Stencil.ValueMask;
+        for (i=0;i<n;i++) {
+           if (mask[i]) {
+               GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
+              s = *sptr & ctx->Stencil.ValueMask;
+              if (r < s) {
+                 /* passed */
+                 fail[i] = 0;
+              }
+              else {
+                 fail[i] = 1;
+                 mask[i] = 0;
+              }
+           }
+           else {
+              fail[i] = 0;
+           }
+        }
+        break;
+      case GL_LEQUAL:
+        r = ctx->Stencil.Ref & ctx->Stencil.ValueMask;
+        for (i=0;i<n;i++) {
+           if (mask[i]) {
+               GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
+              s = *sptr & ctx->Stencil.ValueMask;
+              if (r <= s) {
+                 /* pass */
+                 fail[i] = 0;
+              }
+              else {
+                 fail[i] = 1;
+                 mask[i] = 0;
+              }
+           }
+           else {
+              fail[i] = 0;
+           }
+        }
+        break;
+      case GL_GREATER:
+        r = ctx->Stencil.Ref & ctx->Stencil.ValueMask;
+        for (i=0;i<n;i++) {
+           if (mask[i]) {
+               GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
+              s = *sptr & ctx->Stencil.ValueMask;
+              if (r > s) {
+                 /* passed */
+                 fail[i] = 0;
+              }
+              else {
+                 fail[i] = 1;
+                 mask[i] = 0;
+              }
+           }
+           else {
+              fail[i] = 0;
+           }
+        }
+        break;
+      case GL_GEQUAL:
+        r = ctx->Stencil.Ref & ctx->Stencil.ValueMask;
+        for (i=0;i<n;i++) {
+           if (mask[i]) {
+               GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
+              s = *sptr & ctx->Stencil.ValueMask;
+              if (r >= s) {
+                 /* passed */
+                 fail[i] = 0;
+              }
+              else {
+                 fail[i] = 1;
+                 mask[i] = 0;
+              }
+           }
+           else {
+              fail[i] = 0;
+           }
+        }
+        break;
+      case GL_EQUAL:
+        r = ctx->Stencil.Ref & ctx->Stencil.ValueMask;
+        for (i=0;i<n;i++) {
+           if (mask[i]) {
+               GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
+              s = *sptr & ctx->Stencil.ValueMask;
+              if (r == s) {
+                 /* passed */
+                 fail[i] = 0;
+              }
+              else {
+                 fail[i] = 1;
+                 mask[i] = 0;
+              }
+           }
+           else {
+              fail[i] = 0;
+           }
+        }
+        break;
+      case GL_NOTEQUAL:
+        r = ctx->Stencil.Ref & ctx->Stencil.ValueMask;
+        for (i=0;i<n;i++) {
+           if (mask[i]) {
+               GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
+              s = *sptr & ctx->Stencil.ValueMask;
+              if (r != s) {
+                 /* passed */
+                 fail[i] = 0;
+              }
+              else {
+                 fail[i] = 1;
+                 mask[i] = 0;
+              }
+           }
+           else {
+              fail[i] = 0;
+           }
+        }
+        break;
+      case GL_ALWAYS:
+        /* always pass */
+        for (i=0;i<n;i++) {
+           fail[i] = 0;
+        }
+        break;
+      default:
+         gl_problem(ctx, "Bad stencil func in gl_stencil_pixels");
+         return 0;
+   }
+
+   apply_stencil_op_to_pixels( ctx, n, x, y, ctx->Stencil.FailFunc, fail );
+
+   return (allfail) ? 0 : 1;
+}
+
+
+
+
+/*
+ * Apply the combination depth-buffer/stencil operator to a span of pixels.
+ * Input:  n - number of pixels in the span
+ *         x, y - array of [n] pixels to stencil
+ *         z - array [n] of z values
+ * Input:  mask - array [n] of flags  (1=test this pixel, 0=skip the pixel)
+ * Output:  mask - array [n] of flags (1=depth test passed, 0=failed) 
+ */
+void gl_depth_stencil_pixels( GLcontext *ctx,
+                              GLuint n, const GLint x[], const GLint y[],
+                             const GLdepth z[], GLubyte mask[] )
+{
+   if (ctx->Depth.Test==GL_FALSE) {
+      /*
+       * No depth buffer, just apply zpass stencil function to active pixels.
+       */
+      apply_stencil_op_to_pixels( ctx, n, x, y, ctx->Stencil.ZPassFunc, mask );
+   }
+   else {
+      /*
+       * Perform depth buffering, then apply zpass or zfail stencil function.
+       */
+      GLubyte passmask[PB_SIZE], failmask[PB_SIZE], oldmask[PB_SIZE];
+      GLuint i;
+
+      /* init pass and fail masks to zero */
+      for (i=0;i<n;i++) {
+        passmask[i] = failmask[i] = 0;
+         oldmask[i] = mask[i];
+      }
+
+      /* apply the depth test */
+      if (ctx->Driver.DepthTestPixels)
+         (*ctx->Driver.DepthTestPixels)( ctx, n, x, y, z, mask );
+
+      /* set the stencil pass/fail flags according to result of depth test */
+      for (i=0;i<n;i++) {
+         if (oldmask[i]) {
+            if (mask[i]) {
+               passmask[i] = 1;
+            }
+            else {
+               failmask[i] = 1;
+            }
+         }
+      }
+
+      /* apply the pass and fail operations */
+      apply_stencil_op_to_pixels( ctx, n, x, y,
+                                  ctx->Stencil.ZFailFunc, failmask );
+      apply_stencil_op_to_pixels( ctx, n, x, y,
+                                  ctx->Stencil.ZPassFunc, passmask );
+   }
+
+}
+
+
+
+/*
+ * Return a span of stencil values from the stencil buffer.
+ * Input:  n - how many pixels
+ *         x,y - location of first pixel
+ * Output:  stencil - the array of stencil values
+ */
+void gl_read_stencil_span( GLcontext *ctx,
+                           GLuint n, GLint x, GLint y, GLstencil stencil[] )
+{
+   if (ctx->Buffer->Stencil) {
+      const GLstencil *s = STENCIL_ADDRESS( x, y );
+#if STENCIL_BITS == 8
+      MEMCPY( stencil, s, n * sizeof(GLstencil) );
+#else
+      GLuint i;
+      for (i=0;i<n;i++)
+         stencil[i] = s[i];
+#endif
+   }
+}
+
+
+
+/*
+ * Write a span of stencil values to the stencil buffer.
+ * Input:  n - how many pixels
+ *         x,y - location of first pixel
+ *         stencil - the array of stencil values
+ */
+void gl_write_stencil_span( GLcontext *ctx,
+                            GLuint n, GLint x, GLint y,
+                           const GLstencil stencil[] )
+{
+   if (ctx->Buffer->Stencil) {
+      GLstencil *s = STENCIL_ADDRESS( x, y );
+#if STENCIL_BITS == 8
+      MEMCPY( s, stencil, n * sizeof(GLstencil) );
+#else
+      GLuint i;
+      for (i=0;i<n;i++)
+         s[i] = stencil[i];
+#endif
+   }
+}
+
+
+
+/*
+ * Allocate a new stencil buffer.  If there's an old one it will be
+ * deallocated first.  The new stencil buffer will be uninitialized.
+ */
+void gl_alloc_stencil_buffer( GLcontext *ctx )
+{
+   GLuint buffersize = ctx->Buffer->Width * ctx->Buffer->Height;
+
+   /* deallocate current stencil buffer if present */
+   if (ctx->Buffer->Stencil) {
+      free(ctx->Buffer->Stencil);
+      ctx->Buffer->Stencil = NULL;
+   }
+
+   /* allocate new stencil buffer */
+   ctx->Buffer->Stencil = (GLstencil *) malloc(buffersize * sizeof(GLstencil));
+   if (!ctx->Buffer->Stencil) {
+      /* out of memory */
+      ctx->Stencil.Enabled = GL_FALSE;
+      gl_error( ctx, GL_OUT_OF_MEMORY, "gl_alloc_stencil_buffer" );
+   }
+}
+
+
+
+
+/*
+ * Clear the stencil buffer.  If the stencil buffer doesn't exist yet we'll
+ * allocate it now.
+ */
+void gl_clear_stencil_buffer( GLcontext *ctx )
+{
+   if (ctx->Visual->StencilBits==0 || !ctx->Buffer->Stencil) {
+      /* no stencil buffer */
+      return;
+   }
+
+   if (ctx->Scissor.Enabled) {
+      /* clear scissor region only */
+      GLint y;
+      GLint width = ctx->Buffer->Xmax - ctx->Buffer->Xmin + 1;
+      for (y=ctx->Buffer->Ymin; y<=ctx->Buffer->Ymax; y++) {
+         GLstencil *ptr = STENCIL_ADDRESS( ctx->Buffer->Xmin, y );
+#if STENCIL_BITS==8
+         MEMSET( ptr, ctx->Stencil.Clear, width * sizeof(GLstencil) );
+#else
+         GLint x;
+         for (x = 0; x < width; x++)
+            ptr[x] = ctx->Stencil.Clear;
+#endif
+      }
+   }
+   else {
+      /* clear whole stencil buffer */
+#if STENCIL_BITS==8
+      MEMSET( ctx->Buffer->Stencil, ctx->Stencil.Clear,
+              ctx->Buffer->Width * ctx->Buffer->Height * sizeof(GLstencil) );
+#else
+      GLuint i;
+      GLuint pixels = ctx->Buffer->Width * ctx->Buffer->Height;
+      GLstencil *buffer = ctx->Buffer->Stencil;
+      for (i = 0; i < pixels; i++)
+         ptr[i] = ctx->Stencil.Clear;
+#endif
+   }
+}
diff --git a/src/mesa/main/stencil.h b/src/mesa/main/stencil.h
new file mode 100644 (file)
index 0000000..989cd98
--- /dev/null
@@ -0,0 +1,88 @@
+/* $Id: stencil.h,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+#ifndef STENCIL_H
+#define STENCIL_H
+
+
+#include "types.h"
+
+
+extern void gl_ClearStencil( GLcontext *ctx, GLint s );
+
+
+extern void gl_StencilFunc( GLcontext *ctx, GLenum func,
+                            GLint ref, GLuint mask );
+
+
+extern void gl_StencilMask( GLcontext *ctx, GLuint mask );
+
+
+extern void gl_StencilOp( GLcontext *ctx, GLenum fail,
+                          GLenum zfail, GLenum zpass );
+
+
+
+extern GLint gl_stencil_span( GLcontext *ctx,
+                              GLuint n, GLint x, GLint y, GLubyte mask[] );
+
+
+extern void gl_depth_stencil_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
+                                  const GLdepth z[], GLubyte mask[] );
+
+
+extern GLint gl_stencil_pixels( GLcontext *ctx,
+                                GLuint n, const GLint x[], const GLint y[],
+                               GLubyte mask[] );
+
+
+extern void gl_depth_stencil_pixels( GLcontext *ctx,
+                                     GLuint n, const GLint x[],
+                                    const GLint y[], const GLdepth z[],
+                                    GLubyte mask[] );
+
+
+extern void gl_read_stencil_span( GLcontext *ctx,
+                                  GLuint n, GLint x, GLint y,
+                                 GLstencil stencil[] );
+
+
+extern void gl_write_stencil_span( GLcontext *ctx,
+                                   GLuint n, GLint x, GLint y,
+                                  const GLstencil stencil[] );
+
+
+extern void gl_alloc_stencil_buffer( GLcontext *ctx );
+
+
+extern void gl_clear_stencil_buffer( GLcontext *ctx );
+
+
+#endif
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
new file mode 100644 (file)
index 0000000..f2f301e
--- /dev/null
@@ -0,0 +1,2344 @@
+/* $Id: teximage.c,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "context.h"
+#include "image.h"
+#include "macros.h"
+#include "mmath.h"
+#include "span.h"
+#include "teximage.h"
+#include "texstate.h"
+#include "types.h"
+#ifdef XFree86Server
+#include "GL/xf86glx.h"
+#endif
+#endif
+
+
+/*
+ * NOTES:
+ *
+ * The internal texture storage convension is an array of N GLubytes
+ * where N = width * height * components.  There is no padding.
+ */
+
+
+
+
+/*
+ * Compute log base 2 of n.
+ * If n isn't an exact power of two return -1.
+ * If n<0 return -1.
+ */
+static int logbase2( int n )
+{
+   GLint i = 1;
+   GLint log2 = 0;
+
+   if (n<0) {
+      return -1;
+   }
+
+   while ( n > i ) {
+      i *= 2;
+      log2++;
+   }
+   if (i != n) {
+      return -1;
+   }
+   else {
+      return log2;
+   }
+}
+
+
+
+/*
+ * Given an internal texture format enum or 1, 2, 3, 4 return the
+ * corresponding _base_ internal format:  GL_ALPHA, GL_LUMINANCE,
+ * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA.  Return -1 if
+ * invalid enum.
+ */
+static GLint decode_internal_format( GLint format )
+{
+   switch (format) {
+      case GL_ALPHA:
+      case GL_ALPHA4:
+      case GL_ALPHA8:
+      case GL_ALPHA12:
+      case GL_ALPHA16:
+         return GL_ALPHA;
+      case 1:
+      case GL_LUMINANCE:
+      case GL_LUMINANCE4:
+      case GL_LUMINANCE8:
+      case GL_LUMINANCE12:
+      case GL_LUMINANCE16:
+         return GL_LUMINANCE;
+      case 2:
+      case GL_LUMINANCE_ALPHA:
+      case GL_LUMINANCE4_ALPHA4:
+      case GL_LUMINANCE6_ALPHA2:
+      case GL_LUMINANCE8_ALPHA8:
+      case GL_LUMINANCE12_ALPHA4:
+      case GL_LUMINANCE12_ALPHA12:
+      case GL_LUMINANCE16_ALPHA16:
+         return GL_LUMINANCE_ALPHA;
+      case GL_INTENSITY:
+      case GL_INTENSITY4:
+      case GL_INTENSITY8:
+      case GL_INTENSITY12:
+      case GL_INTENSITY16:
+         return GL_INTENSITY;
+      case 3:
+      case GL_RGB:
+      case GL_R3_G3_B2:
+      case GL_RGB4:
+      case GL_RGB5:
+      case GL_RGB8:
+      case GL_RGB10:
+      case GL_RGB12:
+      case GL_RGB16:
+         return GL_RGB;
+      case 4:
+      case GL_RGBA:
+      case GL_RGBA2:
+      case GL_RGBA4:
+      case GL_RGB5_A1:
+      case GL_RGBA8:
+      case GL_RGB10_A2:
+      case GL_RGBA12:
+      case GL_RGBA16:
+         return GL_RGBA;
+      case GL_COLOR_INDEX:
+      case GL_COLOR_INDEX1_EXT:
+      case GL_COLOR_INDEX2_EXT:
+      case GL_COLOR_INDEX4_EXT:
+      case GL_COLOR_INDEX8_EXT:
+      case GL_COLOR_INDEX12_EXT:
+      case GL_COLOR_INDEX16_EXT:
+         return GL_COLOR_INDEX;
+      default:
+         return -1;  /* error */
+   }
+}
+
+
+
+/*
+ * Given an internal texture format enum or 1, 2, 3, 4 return the
+ * corresponding _base_ internal format:  GL_ALPHA, GL_LUMINANCE,
+ * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA.  Return the
+ * number of components for the format.  Return -1 if invalid enum.
+ */
+static GLint components_in_intformat( GLint format )
+{
+   switch (format) {
+      case GL_ALPHA:
+      case GL_ALPHA4:
+      case GL_ALPHA8:
+      case GL_ALPHA12:
+      case GL_ALPHA16:
+         return 1;
+      case 1:
+      case GL_LUMINANCE:
+      case GL_LUMINANCE4:
+      case GL_LUMINANCE8:
+      case GL_LUMINANCE12:
+      case GL_LUMINANCE16:
+         return 1;
+      case 2:
+      case GL_LUMINANCE_ALPHA:
+      case GL_LUMINANCE4_ALPHA4:
+      case GL_LUMINANCE6_ALPHA2:
+      case GL_LUMINANCE8_ALPHA8:
+      case GL_LUMINANCE12_ALPHA4:
+      case GL_LUMINANCE12_ALPHA12:
+      case GL_LUMINANCE16_ALPHA16:
+         return 2;
+      case GL_INTENSITY:
+      case GL_INTENSITY4:
+      case GL_INTENSITY8:
+      case GL_INTENSITY12:
+      case GL_INTENSITY16:
+         return 1;
+      case 3:
+      case GL_RGB:
+      case GL_R3_G3_B2:
+      case GL_RGB4:
+      case GL_RGB5:
+      case GL_RGB8:
+      case GL_RGB10:
+      case GL_RGB12:
+      case GL_RGB16:
+         return 3;
+      case 4:
+      case GL_RGBA:
+      case GL_RGBA2:
+      case GL_RGBA4:
+      case GL_RGB5_A1:
+      case GL_RGBA8:
+      case GL_RGB10_A2:
+      case GL_RGBA12:
+      case GL_RGBA16:
+         return 4;
+      case GL_COLOR_INDEX:
+      case GL_COLOR_INDEX1_EXT:
+      case GL_COLOR_INDEX2_EXT:
+      case GL_COLOR_INDEX4_EXT:
+      case GL_COLOR_INDEX8_EXT:
+      case GL_COLOR_INDEX12_EXT:
+      case GL_COLOR_INDEX16_EXT:
+         return 1;
+      default:
+         return -1;  /* error */
+   }
+}
+
+
+
+struct gl_texture_image *gl_alloc_texture_image( void )
+{
+   return (struct gl_texture_image *) calloc( 1, sizeof(struct gl_texture_image) );
+}
+
+
+
+void gl_free_texture_image( struct gl_texture_image *teximage )
+{
+   if (teximage->Data) {
+      free( teximage->Data );
+   }
+   free( teximage );
+}
+
+
+
+/*
+ * Examine the texImage->Format field and set the Red, Green, Blue, etc
+ * texel component sizes to default values.
+ * These fields are set only here by core Mesa but device drivers may
+ * overwritting these fields to indicate true texel resolution.
+ */
+static void set_teximage_component_sizes( struct gl_texture_image *texImage )
+{
+   switch (texImage->Format) {
+      case GL_ALPHA:
+         texImage->RedBits = 0;
+         texImage->GreenBits = 0;
+         texImage->BlueBits = 0;
+         texImage->AlphaBits = 8;
+         texImage->IntensityBits = 0;
+         texImage->LuminanceBits = 0;
+         texImage->IndexBits = 0;
+         break;
+      case GL_LUMINANCE:
+         texImage->RedBits = 0;
+         texImage->GreenBits = 0;
+         texImage->BlueBits = 0;
+         texImage->AlphaBits = 0;
+         texImage->IntensityBits = 0;
+         texImage->LuminanceBits = 8;
+         texImage->IndexBits = 0;
+         break;
+      case GL_LUMINANCE_ALPHA:
+         texImage->RedBits = 0;
+         texImage->GreenBits = 0;
+         texImage->BlueBits = 0;
+         texImage->AlphaBits = 8;
+         texImage->IntensityBits = 0;
+         texImage->LuminanceBits = 8;
+         texImage->IndexBits = 0;
+         break;
+      case GL_INTENSITY:
+         texImage->RedBits = 0;
+         texImage->GreenBits = 0;
+         texImage->BlueBits = 0;
+         texImage->AlphaBits = 0;
+         texImage->IntensityBits = 8;
+         texImage->LuminanceBits = 0;
+         texImage->IndexBits = 0;
+         break;
+      case GL_RGB:
+         texImage->RedBits = 8;
+         texImage->GreenBits = 8;
+         texImage->BlueBits = 8;
+         texImage->AlphaBits = 0;
+         texImage->IntensityBits = 0;
+         texImage->LuminanceBits = 0;
+         texImage->IndexBits = 0;
+         break;
+      case GL_RGBA:
+         texImage->RedBits = 8;
+         texImage->GreenBits = 8;
+         texImage->BlueBits = 8;
+         texImage->AlphaBits = 8;
+         texImage->IntensityBits = 0;
+         texImage->LuminanceBits = 0;
+         texImage->IndexBits = 0;
+         break;
+      case GL_COLOR_INDEX:
+         texImage->RedBits = 0;
+         texImage->GreenBits = 0;
+         texImage->BlueBits = 0;
+         texImage->AlphaBits = 0;
+         texImage->IntensityBits = 0;
+         texImage->LuminanceBits = 0;
+         texImage->IndexBits = 8;
+         break;
+      default:
+         gl_problem(NULL, "unexpected format in set_teximage_component_sizes");
+   }
+}
+
+
+/* Need this to prevent an out-of-bounds memory access when using
+ * X86 optimized code.
+ */
+#ifdef USE_X86_ASM
+#  define EXTRA_BYTE 1
+#else
+#  define EXTRA_BYTE 0
+#endif
+
+
+/*
+ * Given a gl_image, apply the pixel transfer scale, bias, and mapping
+ * to produce a gl_texture_image.  Convert image data to GLubytes.
+ * Input:  image - the incoming gl_image
+ *         internalFormat - desired format of resultant texture
+ *         border - texture border width (0 or 1)
+ * Return:  pointer to a gl_texture_image or NULL if an error occurs.
+ */
+static struct gl_texture_image *
+image_to_texture( GLcontext *ctx, const struct gl_image *image,
+                  GLint internalFormat, GLint border )
+{
+   GLint components;
+   struct gl_texture_image *texImage;
+   GLint numPixels, pixel;
+   GLboolean scaleOrBias;
+
+   assert(image);
+   assert(image->Width>0);
+   assert(image->Height>0);
+   assert(image->Depth>0);
+
+   /*   internalFormat = decode_internal_format(internalFormat);*/
+   components = components_in_intformat(internalFormat);
+   numPixels = image->Width * image->Height * image->Depth;
+
+   texImage = gl_alloc_texture_image();
+   if (!texImage)
+      return NULL;
+
+   texImage->Format = (GLenum) decode_internal_format(internalFormat);
+   set_teximage_component_sizes( texImage );
+   texImage->IntFormat = (GLenum) internalFormat;
+   texImage->Border = border;
+   texImage->Width = image->Width;
+   texImage->Height = image->Height;
+   texImage->Depth = image->Depth;
+   texImage->WidthLog2 = logbase2(image->Width - 2*border);
+   if (image->Height==1)  /* 1-D texture */
+      texImage->HeightLog2 = 0;
+   else
+      texImage->HeightLog2 = logbase2(image->Height - 2*border);
+   if (image->Depth==1)   /* 2-D texture */
+      texImage->DepthLog2 = 0;
+   else
+      texImage->DepthLog2 = logbase2(image->Depth - 2*border);
+   texImage->Width2 = 1 << texImage->WidthLog2;
+   texImage->Height2 = 1 << texImage->HeightLog2;
+   texImage->Depth2 = 1 << texImage->DepthLog2;
+   texImage->MaxLog2 = MAX2( texImage->WidthLog2, texImage->HeightLog2 );
+   texImage->Data = (GLubyte *) malloc( numPixels * components + EXTRA_BYTE );
+
+   if (!texImage->Data) {
+      /* out of memory */
+      gl_free_texture_image( texImage );
+      return NULL;
+   }
+
+   /* Determine if scaling and/or biasing is needed */
+   if (ctx->Pixel.RedScale!=1.0F   || ctx->Pixel.RedBias!=0.0F ||
+       ctx->Pixel.GreenScale!=1.0F || ctx->Pixel.GreenBias!=0.0F ||
+       ctx->Pixel.BlueScale!=1.0F  || ctx->Pixel.BlueBias!=0.0F ||
+       ctx->Pixel.AlphaScale!=1.0F || ctx->Pixel.AlphaBias!=0.0F) {
+      scaleOrBias = GL_TRUE;
+   }
+   else {
+      scaleOrBias = GL_FALSE;
+   }
+
+   switch (image->Type) {
+      case GL_BITMAP:
+         {
+            GLint shift = ctx->Pixel.IndexShift;
+            GLint offset = ctx->Pixel.IndexOffset;
+            /* MapIto[RGBA]Size must be powers of two */
+            GLint rMask = ctx->Pixel.MapItoRsize-1;
+            GLint gMask = ctx->Pixel.MapItoGsize-1;
+            GLint bMask = ctx->Pixel.MapItoBsize-1;
+            GLint aMask = ctx->Pixel.MapItoAsize-1;
+            GLint i, j;
+            GLubyte *srcPtr = (GLubyte *) image->Data;
+
+            assert( image->Format==GL_COLOR_INDEX );
+
+            for (j=0; j<image->Height; j++) {
+               GLubyte bitMask = 128;
+               for (i=0; i<image->Width; i++) {
+                  GLint index;
+                  GLubyte red, green, blue, alpha;
+
+                  /* Fetch image color index */
+                  index = (*srcPtr & bitMask) ? 1 : 0;
+                  bitMask = bitMask >> 1;
+                  if (bitMask==0) {
+                     bitMask = 128;
+                     srcPtr++;
+                  }
+                  /* apply index shift and offset */
+                  if (shift>=0) {
+                     index = (index << shift) + offset;
+                  }
+                  else {
+                     index = (index >> -shift) + offset;
+                  }
+                  /* convert index to RGBA */
+                  red   = (GLint) (ctx->Pixel.MapItoR[index & rMask] * 255.0F);
+                  green = (GLint) (ctx->Pixel.MapItoG[index & gMask] * 255.0F);
+                  blue  = (GLint) (ctx->Pixel.MapItoB[index & bMask] * 255.0F);
+                  alpha = (GLint) (ctx->Pixel.MapItoA[index & aMask] * 255.0F);
+
+                  /* store texel (components are GLubytes in [0,255]) */
+                  pixel = j * image->Width + i;
+                  switch (texImage->Format) {
+                     case GL_ALPHA:
+                        texImage->Data[pixel] = alpha;
+                        break;
+                     case GL_LUMINANCE:
+                        texImage->Data[pixel] = red;
+                        break;
+                     case GL_LUMINANCE_ALPHA:
+                        texImage->Data[pixel*2+0] = red;
+                        texImage->Data[pixel*2+1] = alpha;
+                        break;
+                     case GL_INTENSITY:
+                        texImage->Data[pixel] = red;
+                        break;
+                     case GL_RGB:
+                        texImage->Data[pixel*3+0] = red;
+                        texImage->Data[pixel*3+1] = green;
+                        texImage->Data[pixel*3+2] = blue;
+                        break;
+                     case GL_RGBA:
+                        texImage->Data[pixel*4+0] = red;
+                        texImage->Data[pixel*4+1] = green;
+                        texImage->Data[pixel*4+2] = blue;
+                        texImage->Data[pixel*4+3] = alpha;
+                        break;
+                     default:
+                        gl_problem(ctx,"Bad format in image_to_texture");
+                        return NULL;
+                  }
+               }
+               if (bitMask!=128) {
+                  srcPtr++;
+               }
+            }
+         }
+         break;
+
+      case GL_UNSIGNED_BYTE:
+         if (image->Format == texImage->Format && !scaleOrBias && !ctx->Pixel.MapColorFlag) {
+            switch (image->Format) {
+               case GL_COLOR_INDEX:
+                  if (decode_internal_format(internalFormat)!=GL_COLOR_INDEX) {
+                     /* convert color index to RGBA */
+                     for (pixel=0; pixel<numPixels; pixel++) {
+                        GLint index = ((GLubyte*)image->Data)[pixel];
+                        index = (GLint) (255.0F * ctx->Pixel.MapItoR[index]);
+                        texImage->Data[pixel] = index;
+                     }
+                     numPixels = 0;
+                     break;
+                  }
+               case GL_ALPHA:
+               case GL_LUMINANCE:
+               case GL_INTENSITY:
+                  MEMCPY(texImage->Data, image->Data, numPixels * 1);
+                  numPixels = 0;
+                  break;
+               case GL_LUMINANCE_ALPHA:
+                  MEMCPY(texImage->Data, image->Data, numPixels * 2);
+                  numPixels = 0;
+                  break;
+               case GL_RGB:
+                  MEMCPY(texImage->Data, image->Data, numPixels * 3);
+                  numPixels = 0;
+                  break;
+               case GL_RGBA:
+                  MEMCPY(texImage->Data, image->Data, numPixels * 4);
+                  numPixels = 0;
+                  break;
+               default:
+                  break;
+            }
+         }
+         for (pixel=0; pixel<numPixels; pixel++) {
+            GLubyte red, green, blue, alpha;
+            switch (image->Format) {
+               case GL_COLOR_INDEX:
+                  if (decode_internal_format(internalFormat)==GL_COLOR_INDEX) {
+                     /* a paletted texture */
+                     GLint index = ((GLubyte*)image->Data)[pixel];
+                     red = index;
+                  }
+                  else {
+                     /* convert color index to RGBA */
+                     GLint index = ((GLubyte*)image->Data)[pixel];
+                     red   = (GLint) (255.0F * ctx->Pixel.MapItoR[index]);
+                     green = (GLint) (255.0F * ctx->Pixel.MapItoG[index]);
+                     blue  = (GLint) (255.0F * ctx->Pixel.MapItoB[index]);
+                     alpha = (GLint) (255.0F * ctx->Pixel.MapItoA[index]);
+                  }
+                  break;
+               case GL_RGB:
+                  /* Fetch image RGBA values */
+                  red   = ((GLubyte*) image->Data)[pixel*3+0];
+                  green = ((GLubyte*) image->Data)[pixel*3+1];
+                  blue  = ((GLubyte*) image->Data)[pixel*3+2];
+                  alpha = 255;
+                  break;
+               case GL_RGBA:
+                  red   = ((GLubyte*) image->Data)[pixel*4+0];
+                  green = ((GLubyte*) image->Data)[pixel*4+1];
+                  blue  = ((GLubyte*) image->Data)[pixel*4+2];
+                  alpha = ((GLubyte*) image->Data)[pixel*4+3];
+                  break;
+               case GL_RED:
+                  red   = ((GLubyte*) image->Data)[pixel];
+                  green = 0;
+                  blue  = 0;
+                  alpha = 255;
+                  break;
+               case GL_GREEN:
+                  red   = 0;
+                  green = ((GLubyte*) image->Data)[pixel];
+                  blue  = 0;
+                  alpha = 255;
+                  break;
+               case GL_BLUE:
+                  red   = 0;
+                  green = 0;
+                  blue  = ((GLubyte*) image->Data)[pixel];
+                  alpha = 255;
+                  break;
+               case GL_ALPHA:
+                  red   = 0;
+                  green = 0;
+                  blue  = 0;
+                  alpha = ((GLubyte*) image->Data)[pixel];
+                  break;
+               case GL_LUMINANCE: 
+                  red   = ((GLubyte*) image->Data)[pixel];
+                  green = red;
+                  blue  = red;
+                  alpha = 255;
+                  break;
+              case GL_LUMINANCE_ALPHA:
+                  red   = ((GLubyte*) image->Data)[pixel*2+0];
+                  green = red;
+                  blue  = red;
+                  alpha = ((GLubyte*) image->Data)[pixel*2+1];
+                  break;
+              default:
+                 gl_problem(ctx,"Bad format (2) in image_to_texture");
+                 return NULL;
+            }
+            
+            if (scaleOrBias || ctx->Pixel.MapColorFlag) {
+               /* Apply RGBA scale and bias */
+               GLfloat r = UBYTE_COLOR_TO_FLOAT_COLOR(red);
+               GLfloat g = UBYTE_COLOR_TO_FLOAT_COLOR(green);
+               GLfloat b = UBYTE_COLOR_TO_FLOAT_COLOR(blue);
+               GLfloat a = UBYTE_COLOR_TO_FLOAT_COLOR(alpha);
+               if (scaleOrBias) {
+                  /* r,g,b,a now in [0,1] */
+                  r = r * ctx->Pixel.RedScale   + ctx->Pixel.RedBias;
+                  g = g * ctx->Pixel.GreenScale + ctx->Pixel.GreenBias;
+                  b = b * ctx->Pixel.BlueScale  + ctx->Pixel.BlueBias;
+                  a = a * ctx->Pixel.AlphaScale + ctx->Pixel.AlphaBias;
+                  r = CLAMP( r, 0.0F, 1.0F );
+                  g = CLAMP( g, 0.0F, 1.0F );
+                  b = CLAMP( b, 0.0F, 1.0F );
+                  a = CLAMP( a, 0.0F, 1.0F );
+               }
+               /* Apply pixel maps */
+               if (ctx->Pixel.MapColorFlag) {
+                  GLint ir = (GLint) (r*ctx->Pixel.MapRtoRsize);
+                  GLint ig = (GLint) (g*ctx->Pixel.MapGtoGsize);
+                  GLint ib = (GLint) (b*ctx->Pixel.MapBtoBsize);
+                  GLint ia = (GLint) (a*ctx->Pixel.MapAtoAsize);
+                  r = ctx->Pixel.MapRtoR[ir];
+                  g = ctx->Pixel.MapGtoG[ig];
+                  b = ctx->Pixel.MapBtoB[ib];
+                  a = ctx->Pixel.MapAtoA[ia];
+               }
+               red   = (GLint) (r * 255.0F);
+               green = (GLint) (g * 255.0F);
+               blue  = (GLint) (b * 255.0F);
+               alpha = (GLint) (a * 255.0F);
+            }
+
+            /* store texel (components are GLubytes in [0,255]) */
+            switch (texImage->Format) {
+               case GL_COLOR_INDEX:
+                  texImage->Data[pixel] = red; /* really an index */
+                  break;
+               case GL_ALPHA:
+                  texImage->Data[pixel] = alpha;
+                  break;
+               case GL_LUMINANCE:
+                  texImage->Data[pixel] = red;
+                  break;
+               case GL_LUMINANCE_ALPHA:
+                  texImage->Data[pixel*2+0] = red;
+                  texImage->Data[pixel*2+1] = alpha;
+                  break;
+               case GL_INTENSITY:
+                  texImage->Data[pixel] = red;
+                  break;
+               case GL_RGB:
+                  texImage->Data[pixel*3+0] = red;
+                  texImage->Data[pixel*3+1] = green;
+                  texImage->Data[pixel*3+2] = blue;
+                  break;
+               case GL_RGBA:
+                  texImage->Data[pixel*4+0] = red;
+                  texImage->Data[pixel*4+1] = green;
+                  texImage->Data[pixel*4+2] = blue;
+                  texImage->Data[pixel*4+3] = alpha;
+                  break;
+               default:
+                  gl_problem(ctx,"Bad format (3) in image_to_texture");
+                  return NULL;
+            }
+         }
+         break;
+
+      case GL_FLOAT:
+         for (pixel=0; pixel<numPixels; pixel++) {
+            GLfloat red, green, blue, alpha;
+            switch (image->Format) {
+               case GL_COLOR_INDEX:
+                  if (decode_internal_format(internalFormat)==GL_COLOR_INDEX) {
+                     /* a paletted texture */
+                     GLint index = (GLint) ((GLfloat*) image->Data)[pixel];
+                     red = index;
+                  }
+                  else {
+                     GLint shift = ctx->Pixel.IndexShift;
+                     GLint offset = ctx->Pixel.IndexOffset;
+                     /* MapIto[RGBA]Size must be powers of two */
+                     GLint rMask = ctx->Pixel.MapItoRsize-1;
+                     GLint gMask = ctx->Pixel.MapItoGsize-1;
+                     GLint bMask = ctx->Pixel.MapItoBsize-1;
+                     GLint aMask = ctx->Pixel.MapItoAsize-1;
+                     /* Fetch image color index */
+                     GLint index = (GLint) ((GLfloat*) image->Data)[pixel];
+                     /* apply index shift and offset */
+                     if (shift>=0) {
+                        index = (index << shift) + offset;
+                     }
+                     else {
+                        index = (index >> -shift) + offset;
+                     }
+                     /* convert index to RGBA */
+                     red   = ctx->Pixel.MapItoR[index & rMask];
+                     green = ctx->Pixel.MapItoG[index & gMask];
+                     blue  = ctx->Pixel.MapItoB[index & bMask];
+                     alpha = ctx->Pixel.MapItoA[index & aMask];
+                  }
+                  break;
+               case GL_RGB:
+                  /* Fetch image RGBA values */
+                  red   = ((GLfloat*) image->Data)[pixel*3+0];
+                  green = ((GLfloat*) image->Data)[pixel*3+1];
+                  blue  = ((GLfloat*) image->Data)[pixel*3+2];
+                  alpha = 1.0;
+                  break;
+               case GL_RGBA:
+                  red   = ((GLfloat*) image->Data)[pixel*4+0];
+                  green = ((GLfloat*) image->Data)[pixel*4+1];
+                  blue  = ((GLfloat*) image->Data)[pixel*4+2];
+                  alpha = ((GLfloat*) image->Data)[pixel*4+3];
+                  break;
+               case GL_RED:
+                  red   = ((GLfloat*) image->Data)[pixel];
+                  green = 0.0;
+                  blue  = 0.0;
+                  alpha = 1.0;
+                  break;
+               case GL_GREEN:
+                  red   = 0.0;
+                  green = ((GLfloat*) image->Data)[pixel];
+                  blue  = 0.0;
+                  alpha = 1.0;
+                  break;
+               case GL_BLUE:
+                  red   = 0.0;
+                  green = 0.0;
+                  blue  = ((GLfloat*) image->Data)[pixel];
+                  alpha = 1.0;
+                  break;
+               case GL_ALPHA:
+                  red   = 0.0;
+                  green = 0.0;
+                  blue  = 0.0;
+                  alpha = ((GLfloat*) image->Data)[pixel];
+                  break;
+               case GL_LUMINANCE: 
+                  red   = ((GLfloat*) image->Data)[pixel];
+                  green = red;
+                  blue  = red;
+                  alpha = 1.0;
+                  break;
+              case GL_LUMINANCE_ALPHA:
+                  red   = ((GLfloat*) image->Data)[pixel*2+0];
+                  green = red;
+                  blue  = red;
+                  alpha = ((GLfloat*) image->Data)[pixel*2+1];
+                  break;
+               default:
+                  gl_problem(ctx,"Bad format (4) in image_to_texture");
+                  return NULL;
+            }
+            
+            if (image->Format!=GL_COLOR_INDEX) {
+               /* Apply RGBA scale and bias */
+               if (scaleOrBias) {
+                  red   = red   * ctx->Pixel.RedScale   + ctx->Pixel.RedBias;
+                  green = green * ctx->Pixel.GreenScale + ctx->Pixel.GreenBias;
+                  blue  = blue  * ctx->Pixel.BlueScale  + ctx->Pixel.BlueBias;
+                  alpha = alpha * ctx->Pixel.AlphaScale + ctx->Pixel.AlphaBias;
+                  red   = CLAMP( red,    0.0F, 1.0F );
+                  green = CLAMP( green,  0.0F, 1.0F );
+                  blue  = CLAMP( blue,   0.0F, 1.0F );
+                  alpha = CLAMP( alpha,  0.0F, 1.0F );
+               }
+               /* Apply pixel maps */
+               if (ctx->Pixel.MapColorFlag) {
+                  GLint ir = (GLint) (red  *ctx->Pixel.MapRtoRsize);
+                  GLint ig = (GLint) (green*ctx->Pixel.MapGtoGsize);
+                  GLint ib = (GLint) (blue *ctx->Pixel.MapBtoBsize);
+                  GLint ia = (GLint) (alpha*ctx->Pixel.MapAtoAsize);
+                  red   = ctx->Pixel.MapRtoR[ir];
+                  green = ctx->Pixel.MapGtoG[ig];
+                  blue  = ctx->Pixel.MapBtoB[ib];
+                  alpha = ctx->Pixel.MapAtoA[ia];
+               }
+            }
+
+            /* store texel (components are GLubytes in [0,255]) */
+            switch (texImage->Format) {
+               case GL_COLOR_INDEX:
+                  /* a paletted texture */
+                  texImage->Data[pixel] = (GLint) (red * 255.0F);
+                  break;
+               case GL_ALPHA:
+                  texImage->Data[pixel] = (GLint) (alpha * 255.0F);
+                  break;
+               case GL_LUMINANCE:
+                  texImage->Data[pixel] = (GLint) (red * 255.0F);
+                  break;
+               case GL_LUMINANCE_ALPHA:
+                  texImage->Data[pixel*2+0] = (GLint) (red * 255.0F);
+                  texImage->Data[pixel*2+1] = (GLint) (alpha * 255.0F);
+                  break;
+               case GL_INTENSITY:
+                  texImage->Data[pixel] = (GLint) (red * 255.0F);
+                  break;
+               case GL_RGB:
+                  texImage->Data[pixel*3+0] = (GLint) (red   * 255.0F);
+                  texImage->Data[pixel*3+1] = (GLint) (green * 255.0F);
+                  texImage->Data[pixel*3+2] = (GLint) (blue  * 255.0F);
+                  break;
+               case GL_RGBA:
+                  texImage->Data[pixel*4+0] = (GLint) (red   * 255.0F);
+                  texImage->Data[pixel*4+1] = (GLint) (green * 255.0F);
+                  texImage->Data[pixel*4+2] = (GLint) (blue  * 255.0F);
+                  texImage->Data[pixel*4+3] = (GLint) (alpha * 255.0F);
+                  break;
+               default:
+                  gl_problem(ctx,"Bad format (5) in image_to_texture");
+                  return NULL;
+            }
+         }
+         break;
+
+      default:
+         gl_problem(ctx, "Bad image type in image_to_texture");
+         return NULL;
+   }
+
+   return texImage;
+}
+
+
+
+/*
+ * glTexImage[123]D can accept a NULL image pointer.  In this case we
+ * create a texture image with unspecified image contents per the OpenGL
+ * spec.
+ */
+static struct gl_texture_image *
+make_null_texture( GLcontext *ctx, GLenum internalFormat,
+                   GLsizei width, GLsizei height, GLsizei depth, GLint border )
+{
+   GLint components;
+   struct gl_texture_image *texImage;
+   GLint numPixels;
+   (void) ctx;
+
+   /*internalFormat = decode_internal_format(internalFormat);*/
+   components = components_in_intformat(internalFormat);
+   numPixels = width * height * depth;
+
+   texImage = gl_alloc_texture_image();
+   if (!texImage)
+      return NULL;
+
+   texImage->Format = (GLenum) decode_internal_format(internalFormat);
+   set_teximage_component_sizes( texImage );
+   texImage->IntFormat = internalFormat;
+   texImage->Border = border;
+   texImage->Width = width;
+   texImage->Height = height;
+   texImage->Depth = depth;
+   texImage->WidthLog2 = logbase2(width - 2*border);
+   if (height==1)  /* 1-D texture */
+      texImage->HeightLog2 = 0;
+   else
+      texImage->HeightLog2 = logbase2(height - 2*border);
+   if (depth==1)   /* 2-D texture */
+      texImage->DepthLog2 = 0;
+   else
+      texImage->DepthLog2 = logbase2(depth - 2*border);
+   texImage->Width2 = 1 << texImage->WidthLog2;
+   texImage->Height2 = 1 << texImage->HeightLog2;
+   texImage->Depth2 = 1 << texImage->DepthLog2;
+   texImage->MaxLog2 = MAX2( texImage->WidthLog2, texImage->HeightLog2 );
+
+   /* XXX should we really allocate memory for the image or let it be NULL? */
+   /*texImage->Data = NULL;*/
+
+   texImage->Data = (GLubyte *) malloc( numPixels * components + EXTRA_BYTE );
+
+   /*
+    * Let's see if anyone finds this.  If glTexImage2D() is called with
+    * a NULL image pointer then load the texture image with something
+    * interesting instead of leaving it indeterminate.
+    */
+   if (texImage->Data) {
+      char message[8][32] = {
+         "   X   X  XXXXX   XXX     X    ",
+         "   XX XX  X      X   X   X X   ",
+         "   X X X  X      X      X   X  ",
+         "   X   X  XXXX    XXX   XXXXX  ",
+         "   X   X  X          X  X   X  ",
+         "   X   X  X      X   X  X   X  ",
+         "   X   X  XXXXX   XXX   X   X  ",
+         "                               "
+      };
+
+      GLubyte *imgPtr = texImage->Data;
+      GLint i, j, k;
+      for (i=0;i<height;i++) {
+         GLint srcRow = 7 - i % 8;
+         for (j=0;j<width;j++) {
+            GLint srcCol = j % 32;
+            GLubyte texel = (message[srcRow][srcCol]=='X') ? 255 : 70;
+            for (k=0;k<components;k++) {
+               *imgPtr++ = texel;
+            }
+         }
+      }
+   }
+
+   return texImage;
+}
+
+
+
+/*
+ * Test glTexImage() parameters for errors.
+ * Input:
+ *         dimensions - must be 1 or 2 or 3
+ * Return:  GL_TRUE = an error was detected, GL_FALSE = no errors
+ */
+static GLboolean texture_error_check( GLcontext *ctx, GLenum target,
+                                      GLint level, GLint internalFormat,
+                                      GLenum format, GLenum type,
+                                      GLint dimensions,
+                                      GLint width, GLint height,
+                                      GLint depth, GLint border )
+{
+   GLboolean isProxy;
+   GLint iformat;
+
+   if (dimensions == 1) {
+      isProxy = (target == GL_PROXY_TEXTURE_1D);
+      if (target != GL_TEXTURE_1D && !isProxy) {
+         gl_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" );
+         return GL_TRUE;
+      }
+   }
+   else if (dimensions == 2) {
+      isProxy = (target == GL_PROXY_TEXTURE_2D);
+      if (target != GL_TEXTURE_2D && !isProxy) {
+          gl_error( ctx, GL_INVALID_ENUM, "glTexImage2D(target)" );
+          return GL_TRUE;
+      }
+   }
+   else if (dimensions == 3) {
+      isProxy = (target == GL_PROXY_TEXTURE_3D);
+      if (target != GL_TEXTURE_3D && !isProxy) {
+         gl_error( ctx, GL_INVALID_ENUM, "glTexImage3D(target)" );
+         return GL_TRUE;
+      }
+   }
+   else {
+      gl_problem( ctx, "bad dims in texture_error_check" );
+      return GL_TRUE;
+   }
+
+   /* Border */
+   if (border!=0 && border!=1) {
+      if (!isProxy) {
+         if (dimensions == 1)
+            gl_error( ctx, GL_INVALID_VALUE, "glTexImage1D(border)" );
+         else if (dimensions == 2)
+            gl_error( ctx, GL_INVALID_VALUE, "glTexImage2D(border)" );
+         else if (dimensions == 3)
+            gl_error( ctx, GL_INVALID_VALUE, "glTexImage3D(border)" );
+      }
+      return GL_TRUE;
+   }
+
+   /* Width */
+   if (width < 2 * border || width > 2 + ctx->Const.MaxTextureSize
+       || logbase2( width - 2 * border ) < 0) {
+      if (!isProxy) {
+         if (dimensions == 1)
+            gl_error( ctx, GL_INVALID_VALUE, "glTexImage1D(width)" );
+         else if (dimensions == 2)
+            gl_error( ctx, GL_INVALID_VALUE, "glTexImage2D(width)" );
+         else if (dimensions == 3)
+            gl_error( ctx, GL_INVALID_VALUE, "glTexImage3D(width)" );
+      }
+      return GL_TRUE;
+   }
+
+   /* Height */
+   if (dimensions >= 2) {
+      if (height < 2 * border || height > 2 + ctx->Const.MaxTextureSize
+          || logbase2( height - 2 * border ) < 0) {
+         if (!isProxy) {
+            if (dimensions == 2)
+               gl_error( ctx, GL_INVALID_VALUE, "glTexImage2D(height)" );
+            else if (dimensions == 3)
+               gl_error( ctx, GL_INVALID_VALUE, "glTexImage3D(height)" );
+            return GL_TRUE;
+         }
+      }
+   }
+
+   /* Depth */
+   if (dimensions >= 3) {
+      if (depth < 2 * border || depth > 2 + ctx->Const.MaxTextureSize
+          || logbase2( depth - 2 * border ) < 0) {
+         if (!isProxy) {
+            gl_error( ctx, GL_INVALID_VALUE, "glTexImage3D(depth)" );
+         }
+         return GL_TRUE;
+      }
+   }
+
+   /* Level */
+   if (level<0 || level>=ctx->Const.MaxTextureLevels) {
+      if (dimensions == 1)
+         gl_error( ctx, GL_INVALID_VALUE, "glTexImage1D(level)" );
+      else if (dimensions == 2)
+         gl_error( ctx, GL_INVALID_VALUE, "glTexImage2D(level)" );
+      else if (dimensions == 3)
+         gl_error( ctx, GL_INVALID_VALUE, "glTexImage3D(level)" );
+      return GL_TRUE;
+   }
+
+   iformat = decode_internal_format( internalFormat );
+   if (iformat < 0) {
+      if (dimensions == 1)
+         gl_error( ctx, GL_INVALID_VALUE, "glTexImage1D(internalFormat)" );
+      else if (dimensions == 2)
+         gl_error( ctx, GL_INVALID_VALUE, "glTexImage2D(internalFormat)" );
+      else if (dimensions == 3)
+         gl_error( ctx, GL_INVALID_VALUE, "glTexImage3D(internalFormat)" );
+      return GL_TRUE;
+   }
+
+   if (!gl_is_legal_format_and_type( format, type )) {
+      if (dimensions == 1)
+         gl_error( ctx, GL_INVALID_ENUM, "glTexImage1D(format or type)");
+      else if (dimensions == 2)
+         gl_error( ctx, GL_INVALID_ENUM, "glTexImage2D(format or type)");
+      else if (dimensions == 3)
+         gl_error( ctx, GL_INVALID_ENUM, "glTexImage3D(format or type)");
+      return GL_TRUE;
+   }
+
+   /* if we get here, the parameters are OK */
+   return GL_FALSE;
+}
+
+
+
+/*
+ * Called from the API.  Note that width includes the border.
+ */
+void gl_TexImage1D( GLcontext *ctx,
+                    GLenum target, GLint level, GLint internalformat,
+                   GLsizei width, GLint border, GLenum format,
+                   GLenum type, struct gl_image *image )
+{
+   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glTexImage1D");
+
+   if (target==GL_TEXTURE_1D) {
+      struct gl_texture_image *teximage;
+      if (texture_error_check( ctx, target, level, internalformat,
+                               format, type, 1, width, 1, 1, border )) {
+         /* error in texture image was detected */
+         return;
+      }
+
+      /* free current texture image, if any */
+      if (texUnit->CurrentD[1]->Image[level]) {
+         gl_free_texture_image( texUnit->CurrentD[1]->Image[level] );
+      }
+
+      /* make new texture from source image */
+      if (image) {
+         teximage = image_to_texture(ctx, image, internalformat, border);
+      }
+      else {
+         teximage = make_null_texture(ctx, (GLenum) internalformat,
+                                      width, 1, 1, border);
+      }
+
+      /* install new texture image */
+
+      texUnit->CurrentD[1]->Image[level] = teximage;
+      gl_put_texobj_on_dirty_list( ctx, texUnit->CurrentD[1] );
+      ctx->NewState |= NEW_TEXTURING;
+
+      /* free the source image */
+      if (image && image->RefCount==0) {
+         /* if RefCount>0 then image must be in a display list */
+         gl_free_image(image);
+      }
+
+      /* tell driver about change */
+      if (ctx->Driver.TexImage) {
+         (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_1D,
+                                  texUnit->CurrentD[1],
+                                  level, internalformat, teximage );
+      }
+   }
+   else if (target==GL_PROXY_TEXTURE_1D) {
+      /* Proxy texture: check for errors and update proxy state */
+      if (texture_error_check( ctx, target, level, internalformat,
+                               format, type, 1, width, 1, 1, border )) {
+         if (level>=0 && level<ctx->Const.MaxTextureLevels) {
+            MEMSET( ctx->Texture.Proxy1D->Image[level], 0,
+                    sizeof(struct gl_texture_image) );
+         }
+      }
+      else {
+         ctx->Texture.Proxy1D->Image[level]->Format = (GLenum) format;
+         set_teximage_component_sizes( ctx->Texture.Proxy1D->Image[level] );
+         ctx->Texture.Proxy1D->Image[level]->IntFormat = (GLenum) internalformat;
+         ctx->Texture.Proxy1D->Image[level]->Border = border;
+         ctx->Texture.Proxy1D->Image[level]->Width = width;
+         ctx->Texture.Proxy1D->Image[level]->Height = 1;
+         ctx->Texture.Proxy1D->Image[level]->Depth = 1;
+      }
+      if (image && image->RefCount==0) {
+         /* if RefCount>0 then image must be in a display list */
+         gl_free_image(image);
+      }
+   }
+   else {
+      gl_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" );
+      return;
+   }
+}
+
+
+
+
+/*
+ * Called by the API or display list executor.
+ * Note that width and height include the border.
+ */
+void gl_TexImage2D( GLcontext *ctx,
+                    GLenum target, GLint level, GLint internalformat,
+                    GLsizei width, GLsizei height, GLint border,
+                    GLenum format, GLenum type,
+                    struct gl_image *image )
+{
+   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glTexImage2D");
+
+   if (target==GL_TEXTURE_2D) {
+      struct gl_texture_image *teximage;
+      if (texture_error_check( ctx, target, level, internalformat,
+                               format, type, 2, width, height, 1, border )) {
+         /* error in texture image was detected */
+         return;
+      }
+
+      /* free current texture image, if any */
+      if (texUnit->CurrentD[2]->Image[level]) {
+         gl_free_texture_image( texUnit->CurrentD[2]->Image[level] );
+      }
+
+      /* make new texture from source image */
+      if (image) {
+         teximage = image_to_texture(ctx, image, internalformat, border);
+      }
+      else {
+         teximage = make_null_texture(ctx, (GLenum) internalformat,
+                                      width, height, 1, border);
+      }
+
+      /* install new texture image */
+      texUnit->CurrentD[2]->Image[level] = teximage;
+      gl_put_texobj_on_dirty_list( ctx, texUnit->CurrentD[2] );
+      ctx->NewState |= NEW_TEXTURING;
+
+      /* free the source image */
+      if (image && image->RefCount==0) {
+         /* if RefCount>0 then image must be in a display list */
+         gl_free_image(image);
+      }
+
+      /* tell driver about change */
+      if (ctx->Driver.TexImage) {
+         (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_2D,
+                                  texUnit->CurrentD[2],
+                                  level, internalformat, teximage );
+      }
+   }
+   else if (target==GL_PROXY_TEXTURE_2D) {
+      /* Proxy texture: check for errors and update proxy state */
+      if (texture_error_check( ctx, target, level, internalformat,
+                               format, type, 2, width, height, 1, border )) {
+         if (level>=0 && level<ctx->Const.MaxTextureLevels) {
+            MEMSET( ctx->Texture.Proxy2D->Image[level], 0,
+                    sizeof(struct gl_texture_image) );
+         }
+      }
+      else {
+         ctx->Texture.Proxy2D->Image[level]->Format = (GLenum) format;
+         set_teximage_component_sizes( ctx->Texture.Proxy2D->Image[level] );
+         ctx->Texture.Proxy2D->Image[level]->IntFormat = (GLenum) internalformat;
+         ctx->Texture.Proxy2D->Image[level]->Border = border;
+         ctx->Texture.Proxy2D->Image[level]->Width = width;
+         ctx->Texture.Proxy2D->Image[level]->Height = height;
+         ctx->Texture.Proxy2D->Image[level]->Depth = 1;
+      }
+      if (image && image->RefCount==0) {
+         /* if RefCount>0 then image must be in a display list */
+         gl_free_image(image);
+      }
+   }
+   else {
+      gl_error( ctx, GL_INVALID_ENUM, "glTexImage2D(target)" );
+      return;
+   }
+}
+
+
+
+/*
+ * Called by the API or display list executor.
+ * Note that width and height include the border.
+ */
+void gl_TexImage3DEXT( GLcontext *ctx,
+                       GLenum target, GLint level, GLint internalformat,
+                       GLsizei width, GLsizei height, GLsizei depth,
+                       GLint border, GLenum format, GLenum type,
+                       struct gl_image *image )
+{
+   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glTexImage3DEXT");
+
+   if (target==GL_TEXTURE_3D_EXT) {
+      struct gl_texture_image *teximage;
+      if (texture_error_check( ctx, target, level, internalformat,
+                               format, type, 3, width, height, depth,
+                               border )) {
+         /* error in texture image was detected */
+         return;
+      }
+
+      /* free current texture image, if any */
+      if (texUnit->CurrentD[3]->Image[level]) {
+         gl_free_texture_image( texUnit->CurrentD[3]->Image[level] );
+      }
+
+      /* make new texture from source image */
+      if (image) {
+         teximage = image_to_texture(ctx, image, internalformat, border);
+      }
+      else {
+         teximage = make_null_texture(ctx, (GLenum) internalformat,
+                                      width, height, depth, border);
+      }
+
+      /* install new texture image */
+      texUnit->CurrentD[3]->Image[level] = teximage;
+      gl_put_texobj_on_dirty_list( ctx, texUnit->CurrentD[3] );
+      ctx->NewState |= NEW_TEXTURING;
+
+      /* free the source image */
+      if (image && image->RefCount==0) {
+         /* if RefCount>0 then image must be in a display list */
+         gl_free_image(image);
+      }
+
+      /* tell driver about change */
+      if (ctx->Driver.TexImage) {
+         (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_3D_EXT,
+                                  texUnit->CurrentD[3],
+                                  level, internalformat, teximage );
+      }
+   }
+   else if (target==GL_PROXY_TEXTURE_3D_EXT) {
+      /* Proxy texture: check for errors and update proxy state */
+      if (texture_error_check( ctx, target, level, internalformat,
+                               format, type, 3, width, height, depth,
+                               border )) {
+         if (level>=0 && level<ctx->Const.MaxTextureLevels) {
+            MEMSET( ctx->Texture.Proxy3D->Image[level], 0,
+                    sizeof(struct gl_texture_image) );
+         }
+      }
+      else {
+         ctx->Texture.Proxy3D->Image[level]->Format = (GLenum) format;
+         set_teximage_component_sizes( ctx->Texture.Proxy3D->Image[level] );
+         ctx->Texture.Proxy3D->Image[level]->IntFormat = (GLenum) internalformat;
+         ctx->Texture.Proxy3D->Image[level]->Border = border;
+         ctx->Texture.Proxy3D->Image[level]->Width = width;
+         ctx->Texture.Proxy3D->Image[level]->Height = height;
+         ctx->Texture.Proxy3D->Image[level]->Depth  = depth;
+      }
+      if (image && image->RefCount==0) {
+         /* if RefCount>0 then image must be in a display list */
+         gl_free_image(image);
+      }
+   }
+   else {
+      gl_error( ctx, GL_INVALID_ENUM, "glTexImage3DEXT(target)" );
+      return;
+   }
+}
+
+
+
+void gl_GetTexImage( GLcontext *ctx, GLenum target, GLint level, GLenum format,
+                     GLenum type, GLvoid *pixels )
+{
+   const struct gl_texture_object *texObj;
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetTexImage");
+
+   if (level < 0 || level >= ctx->Const.MaxTextureLevels) {
+      gl_error( ctx, GL_INVALID_VALUE, "glGetTexImage(level)" );
+      return;
+   }
+
+   if (gl_sizeof_type(type) <= 0) {
+      gl_error( ctx, GL_INVALID_ENUM, "glGetTexImage(type)" );
+      return;
+   }
+
+   if (gl_components_in_format(format) <= 0) {
+      gl_error( ctx, GL_INVALID_ENUM, "glGetTexImage(format)" );
+      return;
+   }
+
+   if (!pixels)
+      return;  /* XXX generate an error??? */
+
+   switch (target) {
+      case GL_TEXTURE_1D:
+         texObj = ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentD[1];
+         break;
+      case GL_TEXTURE_2D:
+         texObj = ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentD[2];
+         break;
+      case GL_TEXTURE_3D:
+         texObj = ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentD[3];
+         break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glGetTexImage(target)" );
+         return;
+   }
+
+   if (texObj->Image[level] && texObj->Image[level]->Data) {
+      const struct gl_texture_image *texImage = texObj->Image[level];
+      GLint width = texImage->Width;
+      GLint height = texImage->Height;
+      GLint row;
+
+      for (row = 0; row < height; row++) {
+         /* compute destination address in client memory */
+         GLvoid *dest = gl_pixel_addr_in_image( &ctx->Unpack, pixels,
+                                                width, height,
+                                                format, type, 0, row, 0);
+
+         assert(dest);
+         if (texImage->Format == GL_RGBA) {
+            const GLubyte *src = texImage->Data + row * width * 4 * sizeof(GLubyte);
+            gl_pack_rgba_span( ctx, width, (void *) src, format, type, dest,
+                               &ctx->Pack, GL_TRUE );
+         }
+         else {
+            /* fetch RGBA row from texture image then pack it in client mem */
+            GLubyte rgba[MAX_WIDTH][4];
+            GLint i;
+            const GLubyte *src;
+            switch (texImage->Format) {
+               case GL_ALPHA:
+                  src = texImage->Data + row * width * sizeof(GLubyte);
+                  for (i = 0; i < width; i++) {
+                     rgba[i][RCOMP] = 255;
+                     rgba[i][GCOMP] = 255;
+                     rgba[i][BCOMP] = 255;
+                     rgba[i][ACOMP] = src[i];
+                  }
+                  break;
+               case GL_LUMINANCE:
+                  src = texImage->Data + row * width * sizeof(GLubyte);
+                  for (i = 0; i < width; i++) {
+                     rgba[i][RCOMP] = src[i];
+                     rgba[i][GCOMP] = src[i];
+                     rgba[i][BCOMP] = src[i];
+                     rgba[i][ACOMP] = 255;
+                   }
+                  break;
+               case GL_LUMINANCE_ALPHA:
+                  src = texImage->Data + row * 2 * width * sizeof(GLubyte);
+                  for (i = 0; i < width; i++) {
+                     rgba[i][RCOMP] = src[i*2+0];
+                     rgba[i][GCOMP] = src[i*2+0];
+                     rgba[i][BCOMP] = src[i*2+0];
+                     rgba[i][ACOMP] = src[i*2+1];
+                  }
+                  break;
+               case GL_INTENSITY:
+                  src = texImage->Data + row * width * sizeof(GLubyte);
+                  for (i = 0; i < width; i++) {
+                     rgba[i][RCOMP] = src[i];
+                     rgba[i][GCOMP] = src[i];
+                     rgba[i][BCOMP] = src[i];
+                     rgba[i][ACOMP] = 255;
+                  }
+                  break;
+               case GL_RGB:
+                  src = texImage->Data + row * 3 * width * sizeof(GLubyte);
+                  for (i = 0; i < width; i++) {
+                     rgba[i][RCOMP] = src[i*3+0];
+                     rgba[i][GCOMP] = src[i*3+1];
+                     rgba[i][BCOMP] = src[i*3+2];
+                     rgba[i][ACOMP] = 255;
+                  }
+                  break;
+               case GL_RGBA:
+                  /* this special case should have been handled above! */
+                  gl_problem( ctx, "error 1 in gl_GetTexImage" );
+                  break;
+               case GL_COLOR_INDEX:
+                  gl_problem( ctx, "GL_COLOR_INDEX not implemented in gl_GetTexImage" );
+                  break;
+               default:
+                  gl_problem( ctx, "bad format in gl_GetTexImage" );
+            }
+            gl_pack_rgba_span( ctx, width, (const GLubyte (*)[4])rgba,
+                               format, type, dest, &ctx->Pack, GL_TRUE );
+         }
+      }
+   }
+}
+
+
+
+/*
+ * Unpack the image data given to glTexSubImage[12]D.
+ * This function is just a wrapper for gl_unpack_image() but it does
+ * some extra error checking.
+ */
+struct gl_image *
+gl_unpack_texsubimage( GLcontext *ctx, GLint width, GLint height,
+                       GLenum format, GLenum type, const GLvoid *pixels )
+{
+   if (type==GL_BITMAP && format!=GL_COLOR_INDEX) {
+      return NULL;
+   }
+
+   if (format==GL_STENCIL_INDEX || format==GL_DEPTH_COMPONENT){
+      return NULL;
+   }
+
+   if (gl_sizeof_type(type)<=0) {
+      return NULL;
+   }
+
+   return gl_unpack_image3D( ctx, width, height, 1, format, type, pixels, &ctx->Unpack );
+}
+
+
+/*
+ * Unpack the image data given to glTexSubImage3D.
+ * This function is just a wrapper for gl_unpack_image() but it does
+ * some extra error checking.
+ */
+struct gl_image *
+gl_unpack_texsubimage3D( GLcontext *ctx, GLint width, GLint height,
+                         GLint depth, GLenum format, GLenum type,
+                         const GLvoid *pixels )
+{
+   if (type==GL_BITMAP && format!=GL_COLOR_INDEX) {
+      return NULL;
+   }
+
+   if (format==GL_STENCIL_INDEX || format==GL_DEPTH_COMPONENT){
+      return NULL;
+   }
+
+   if (gl_sizeof_type(type)<=0) {
+      return NULL;
+   }
+
+   return gl_unpack_image3D( ctx, width, height, depth, format, type, pixels,
+                             &ctx->Unpack );
+}
+
+
+
+void gl_TexSubImage1D( GLcontext *ctx,
+                       GLenum target, GLint level, GLint xoffset,
+                       GLsizei width, GLenum format, GLenum type,
+                       struct gl_image *image )
+{
+   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+   struct gl_texture_image *destTex;
+
+   if (target!=GL_TEXTURE_1D) {
+      gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(target)" );
+      return;
+   }
+   if (level<0 || level>=ctx->Const.MaxTextureLevels) {
+      gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(level)" );
+      return;
+   }
+
+   destTex = texUnit->CurrentD[1]->Image[level];
+   if (!destTex) {
+      gl_error( ctx, GL_INVALID_OPERATION, "glTexSubImage1D" );
+      return;
+   }
+
+   if (xoffset < -((GLint)destTex->Border)) {
+      gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage1D(xoffset)" );
+      return;
+   }
+   if (xoffset + width > (GLint) (destTex->Width + destTex->Border)) {
+      gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage1D(xoffset+width)" );
+      return;
+   }
+
+   if (image) {
+      /* unpacking must have been error-free */
+      GLint texcomponents = components_in_intformat(destTex->Format);
+
+      if (image->Type==GL_UNSIGNED_BYTE && texcomponents==image->Components) {
+         /* Simple case, just byte copy image data into texture image */
+         /* row by row. */
+         GLubyte *dst = destTex->Data + texcomponents * xoffset;
+         GLubyte *src = (GLubyte *) image->Data;
+         MEMCPY( dst, src, width * texcomponents );
+      }
+      else {
+         /* General case, convert image pixels into texels, scale, bias, etc */
+         struct gl_texture_image *subTexImg = image_to_texture(ctx, image,
+                                        destTex->IntFormat, destTex->Border);
+         GLubyte *dst = destTex->Data + texcomponents * xoffset;
+         GLubyte *src = subTexImg->Data;
+         MEMCPY( dst, src, width * texcomponents );
+         gl_free_texture_image(subTexImg);
+      }
+
+      /* if the image's reference count is zero, delete it now */
+      if (image->RefCount==0) {
+         gl_free_image(image);
+      }
+
+      gl_put_texobj_on_dirty_list( ctx, texUnit->CurrentD[1] );
+
+      /* tell driver about change */
+      if (ctx->Driver.TexSubImage) {
+       (*ctx->Driver.TexSubImage)( ctx, GL_TEXTURE_1D,
+                                   texUnit->CurrentD[1], level,
+                                   xoffset,0,width,1,
+                                   texUnit->CurrentD[1]->Image[level]->IntFormat,
+                                   destTex );
+      }
+      else {
+       if (ctx->Driver.TexImage) {
+         (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_1D, texUnit->CurrentD[1], level,
+                                  texUnit->CurrentD[1]->Image[level]->IntFormat,
+                                  destTex );
+       }
+      }
+   }
+   else {
+      /* if no image, an error must have occured, do more testing now */
+      GLint components, size;
+
+      if (width<0) {
+         gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage1D(width)" );
+         return;
+      }
+      if (type==GL_BITMAP && format!=GL_COLOR_INDEX) {
+         gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(format)" );
+         return;
+      }
+      components = components_in_intformat( format );
+      if (components<0 || format==GL_STENCIL_INDEX
+          || format==GL_DEPTH_COMPONENT){
+         gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(format)" );
+         return;
+      }
+      size = gl_sizeof_type( type );
+      if (size<=0) {
+         gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(type)" );
+         return;
+      }
+      /* if we get here, probably ran out of memory during unpacking */
+      gl_error( ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D" );
+   }
+}
+
+
+
+void gl_TexSubImage2D( GLcontext *ctx,
+                       GLenum target, GLint level,
+                       GLint xoffset, GLint yoffset,
+                       GLsizei width, GLsizei height,
+                       GLenum format, GLenum type,
+                       struct gl_image *image )
+{
+   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+   struct gl_texture_image *destTex;
+
+   if (target!=GL_TEXTURE_2D) {
+      gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" );
+      return;
+   }
+   if (level<0 || level>=ctx->Const.MaxTextureLevels) {
+      gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(level)" );
+      return;
+   }
+
+   destTex = texUnit->CurrentD[2]->Image[level];
+   if (!destTex) {
+      gl_error( ctx, GL_INVALID_OPERATION, "glTexSubImage2D" );
+      return;
+   }
+
+   if (xoffset < -((GLint)destTex->Border)) {
+      gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage2D(xoffset)" );
+      return;
+   }
+   if (yoffset < -((GLint)destTex->Border)) {
+      gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage2D(yoffset)" );
+      return;
+   }
+   if (xoffset + width > (GLint) (destTex->Width + destTex->Border)) {
+      gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage2D(xoffset+width)" );
+      return;
+   }
+   if (yoffset + height > (GLint) (destTex->Height + destTex->Border)) {
+      gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage2D(yoffset+height)" );
+      return;
+   }
+
+   if (image) {
+      /* unpacking must have been error-free */
+      GLint texcomponents = components_in_intformat(destTex->Format);
+
+      if (image->Type==GL_UNSIGNED_BYTE && texcomponents==image->Components) {
+         /* Simple case, just byte copy image data into texture image */
+         /* row by row. */
+         GLubyte *dst = destTex->Data 
+                      + (yoffset * destTex->Width + xoffset) * texcomponents;
+         GLubyte *src = (GLubyte *) image->Data;
+         GLint  j;
+         for (j=0;j<height;j++) {
+            MEMCPY( dst, src, width * texcomponents );
+            dst += destTex->Width * texcomponents * sizeof(GLubyte);
+            src += width * texcomponents * sizeof(GLubyte);
+         }
+      }
+      else {
+         /* General case, convert image pixels into texels, scale, bias, etc */
+         struct gl_texture_image *subTexImg = image_to_texture(ctx, image,
+                                        destTex->IntFormat, destTex->Border);
+         GLubyte *dst = destTex->Data
+                  + (yoffset * destTex->Width + xoffset) * texcomponents;
+         GLubyte *src = subTexImg->Data;
+         GLint j;
+         for (j=0;j<height;j++) {
+            MEMCPY( dst, src, width * texcomponents );
+            dst += destTex->Width * texcomponents * sizeof(GLubyte);
+            src += width * texcomponents * sizeof(GLubyte);
+         }
+         gl_free_texture_image(subTexImg);
+      }
+
+      /* if the image's reference count is zero, delete it now */
+      if (image->RefCount==0) {
+         gl_free_image(image);
+      }
+
+      gl_put_texobj_on_dirty_list( ctx, texUnit->CurrentD[2] );
+
+      /* tell driver about change */
+      if (ctx->Driver.TexSubImage) {
+       (*ctx->Driver.TexSubImage)( ctx, GL_TEXTURE_2D, texUnit->CurrentD[2], level,
+                                   xoffset, yoffset, width, height,
+                                   texUnit->CurrentD[2]->Image[level]->IntFormat,
+                                   destTex );
+      }
+      else {
+       if (ctx->Driver.TexImage) {
+         (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_2D, texUnit->CurrentD[2], level,
+                                  texUnit->CurrentD[2]->Image[level]->IntFormat,
+                                  destTex );
+       }
+      }
+   }
+   else {
+      /* if no image, an error must have occured, do more testing now */
+      GLint components, size;
+
+      if (width<0) {
+         gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage2D(width)" );
+         return;
+      }
+      if (height<0) {
+         gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage2D(height)" );
+         return;
+      }
+      if (type==GL_BITMAP && format!=GL_COLOR_INDEX) {
+         gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(format)" );
+         return;
+      }
+      components = gl_components_in_format( format );
+      if (components<0 || format==GL_STENCIL_INDEX
+          || format==GL_DEPTH_COMPONENT){
+         gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(format)" );
+         return;
+      }
+      size = gl_sizeof_packed_type( type );
+      if (size<=0) {
+         gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(type)" );
+         return;
+      }
+      /* if we get here, probably ran out of memory during unpacking */
+      gl_error( ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D" );
+   }
+}
+
+
+
+void gl_TexSubImage3DEXT( GLcontext *ctx,
+                          GLenum target, GLint level,
+                          GLint xoffset, GLint yoffset, GLint zoffset,
+                          GLsizei width, GLsizei height, GLsizei depth,
+                          GLenum format, GLenum type,
+                          struct gl_image *image )
+{
+   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+   struct gl_texture_image *destTex;
+
+   if (target!=GL_TEXTURE_3D_EXT) {
+      gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage3DEXT(target)" );
+      return;
+   }
+   if (level<0 || level>=ctx->Const.MaxTextureLevels) {
+      gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage3DEXT(level)" );
+      return;
+   }
+
+   destTex = texUnit->CurrentD[3]->Image[level];
+   if (!destTex) {
+      gl_error( ctx, GL_INVALID_OPERATION, "glTexSubImage3DEXT" );
+      return;
+   }
+
+   if (xoffset < -((GLint)destTex->Border)) {
+      gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(xoffset)" );
+      return;
+   }
+   if (yoffset < -((GLint)destTex->Border)) {
+      gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(yoffset)" );
+      return;
+   }
+   if (zoffset < -((GLint)destTex->Border)) {
+      gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(zoffset)" );
+      return;
+   }
+   if (xoffset + width > (GLint) (destTex->Width+destTex->Border)) {
+      gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(xoffset+width)" );
+      return;
+   }
+   if (yoffset + height > (GLint) (destTex->Height+destTex->Border)) {
+      gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(yoffset+height)" );
+      return;
+   }
+   if (zoffset + depth  > (GLint) (destTex->Depth+destTex->Border)) {
+      gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(zoffset+depth)" );
+      return;
+   }
+
+   if (image) {
+      /* unpacking must have been error-free */
+      GLint texcomponents = components_in_intformat(destTex->Format);
+      GLint dstRectArea = destTex->Width * destTex->Height;
+      GLint srcRectArea = width * height;
+
+      if (image->Type==GL_UNSIGNED_BYTE && texcomponents==image->Components) {
+         /* Simple case, just byte copy image data into texture image */
+         /* row by row. */
+         GLubyte *dst = destTex->Data 
+               + (zoffset * dstRectArea +  yoffset * destTex->Width + xoffset)
+               * texcomponents;
+         GLubyte *src = (GLubyte *) image->Data;
+         GLint j, k;
+         for(k=0;k<depth; k++) {
+           for (j=0;j<height;j++) {
+              MEMCPY( dst, src, width * texcomponents );
+              dst += destTex->Width * texcomponents;
+              src += width * texcomponents;
+           }
+           dst += dstRectArea * texcomponents * sizeof(GLubyte);
+           src += srcRectArea * texcomponents * sizeof(GLubyte);
+         }
+      }
+      else {
+         /* General case, convert image pixels into texels, scale, bias, etc */
+         struct gl_texture_image *subTexImg = image_to_texture(ctx, image,
+                                        destTex->IntFormat, destTex->Border);
+         GLubyte *dst = destTex->Data 
+               + (zoffset * dstRectArea +  yoffset * destTex->Width + xoffset)
+               * texcomponents;
+         GLubyte *src = subTexImg->Data;
+         GLint j, k;
+         for(k=0;k<depth; k++) {
+           for (j=0;j<height;j++) {
+              MEMCPY( dst, src, width * texcomponents );
+              dst += destTex->Width * texcomponents;
+              src += width * texcomponents;
+           }
+           dst += dstRectArea * texcomponents * sizeof(GLubyte);
+           src += srcRectArea * texcomponents * sizeof(GLubyte);
+         }
+         gl_free_texture_image(subTexImg);
+      }
+      /* if the image's reference count is zero, delete it now */
+      if (image->RefCount==0) {
+         gl_free_image(image);
+      }
+
+      gl_put_texobj_on_dirty_list( ctx, texUnit->CurrentD[3] );
+
+      /* tell driver about change */
+      if (ctx->Driver.TexImage) {
+         (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_3D_EXT, texUnit->CurrentD[3],
+                                  level, texUnit->CurrentD[3]->Image[level]->IntFormat,
+                                 destTex );
+      }
+   }
+   else {
+      /* if no image, an error must have occured, do more testing now */
+      GLint components, size;
+
+      if (width<0) {
+         gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(width)" );
+         return;
+      }
+      if (height<0) {
+         gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(height)" );
+         return;
+      }
+      if (depth<0) {
+         gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(depth)" );
+         return;
+      }
+      if (type==GL_BITMAP && format!=GL_COLOR_INDEX) {
+         gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage3DEXT(format)" );
+         return;
+      }
+      components = components_in_intformat( format );
+      if (components<0 || format==GL_STENCIL_INDEX
+          || format==GL_DEPTH_COMPONENT){
+         gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage3DEXT(format)" );
+         return;
+      }
+      size = gl_sizeof_type( type );
+      if (size<=0) {
+         gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage3DEXT(type)" );
+         return;
+      }
+      /* if we get here, probably ran out of memory during unpacking */
+      gl_error( ctx, GL_OUT_OF_MEMORY, "glTexSubImage3DEXT" );
+   }
+}
+
+
+
+/*
+ * Read an RGBA image from the frame buffer.
+ * Input:  ctx - the context
+ *         x, y - lower left corner
+ *         width, height - size of region to read
+ *         format - one of GL_RED, GL_RGB, GL_LUMINANCE, etc.
+ * Return: gl_image pointer or NULL if out of memory
+ */
+static struct gl_image *read_color_image( GLcontext *ctx, GLint x, GLint y,
+                                          GLsizei width, GLsizei height,
+                                          GLenum format )
+{
+   struct gl_image *image;
+   GLubyte *imgptr;
+   GLint components;
+   GLint i, j;
+
+   components = components_in_intformat( format );
+
+   /*
+    * Allocate image struct and image data buffer
+    */
+   image = (struct gl_image *) malloc( sizeof(struct gl_image) );
+   if (image) {
+      image->Width = width;
+      image->Height = height;
+      image->Depth = 1;
+      image->Components = components;
+      image->Format = format;
+      image->Type = GL_UNSIGNED_BYTE;
+      image->RefCount = 0;
+      image->Data = (GLubyte *) malloc( width * height * components );
+      if (!image->Data) {
+         free(image);
+         return NULL;
+      }
+   }
+   else {
+      return NULL;
+   }
+
+   imgptr = (GLubyte *) image->Data;
+
+   /* Select buffer to read from */
+   (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Pixel.DriverReadBuffer );
+
+   for (j=0;j<height;j++) {
+      GLubyte rgba[MAX_WIDTH][4];
+      gl_read_rgba_span( ctx, width, x, y+j, rgba );
+
+      switch (format) {
+         case GL_ALPHA:
+            for (i=0;i<width;i++) {
+               *imgptr++ = rgba[i][ACOMP];
+            }
+            break;
+         case GL_LUMINANCE:
+            for (i=0;i<width;i++) {
+               *imgptr++ = rgba[i][RCOMP];
+            }
+            break;
+         case GL_LUMINANCE_ALPHA:
+            for (i=0;i<width;i++) {
+               *imgptr++ = rgba[i][RCOMP];
+               *imgptr++ = rgba[i][ACOMP];
+            }
+            break;
+         case GL_INTENSITY:
+            for (i=0;i<width;i++) {
+               *imgptr++ = rgba[i][RCOMP];
+            }
+            break;
+         case GL_RGB:
+            for (i=0;i<width;i++) {
+               *imgptr++ = rgba[i][RCOMP];
+               *imgptr++ = rgba[i][GCOMP];
+               *imgptr++ = rgba[i][BCOMP];
+            }
+            break;
+         case GL_RGBA:
+            for (i=0;i<width;i++) {
+               *imgptr++ = rgba[i][RCOMP];
+               *imgptr++ = rgba[i][GCOMP];
+               *imgptr++ = rgba[i][BCOMP];
+               *imgptr++ = rgba[i][ACOMP];
+            }
+            break;
+         default:
+            gl_problem(ctx, "Bad format in read_color_image");
+            break;
+      } /*switch*/
+
+   } /*for*/         
+
+   /* Restore drawing buffer */
+   (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Color.DriverDrawBuffer );
+
+   return image;
+}
+
+
+
+
+void gl_CopyTexImage1D( GLcontext *ctx,
+                        GLenum target, GLint level,
+                        GLenum internalformat,
+                        GLint x, GLint y,
+                        GLsizei width, GLint border )
+{
+   GLint format;
+   struct gl_image *teximage;
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glCopyTexImage1D");
+   if (target!=GL_TEXTURE_1D) {
+      gl_error( ctx, GL_INVALID_ENUM, "glCopyTexImage1D(target)" );
+      return;
+   }
+   if (level<0 || level>=ctx->Const.MaxTextureLevels) {
+      gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage1D(level)" );
+      return;
+   }
+   if (border!=0 && border!=1) {
+      gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage1D(border)" );
+      return;
+   }
+   if (width < 2*border || width > 2 + ctx->Const.MaxTextureSize || width<0) {
+      gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage1D(width)" );
+      return;
+   }
+   format = decode_internal_format( internalformat );
+   if (format<0 || (internalformat>=1 && internalformat<=4)) {
+      gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage1D(format)" );
+      return;
+   }
+
+   teximage = read_color_image( ctx, x, y, width, 1, (GLenum) format );
+   if (!teximage) {
+      gl_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D" );
+      return;
+   }
+
+   gl_TexImage1D( ctx, target, level, internalformat, width,
+                  border, GL_RGBA, GL_UNSIGNED_BYTE, teximage );
+
+   /* teximage was freed in gl_TexImage1D */
+}
+
+
+
+void gl_CopyTexImage2D( GLcontext *ctx,
+                        GLenum target, GLint level, GLenum internalformat,
+                        GLint x, GLint y, GLsizei width, GLsizei height,
+                        GLint border )
+{
+   GLint format;
+   struct gl_image *teximage;
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glCopyTexImage2D");
+   if (target!=GL_TEXTURE_2D) {
+      gl_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" );
+      return;
+   }
+   if (level<0 || level>=ctx->Const.MaxTextureLevels) {
+      gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage2D(level)" );
+      return;
+   }
+   if (border!=0 && border!=1) {
+      gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage2D(border)" );
+      return;
+   }
+   if (width<2*border || width>2+ctx->Const.MaxTextureSize || width<0) {
+      gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage2D(width)" );
+      return;
+   }
+   if (height<2*border || height>2+ctx->Const.MaxTextureSize || height<0) {
+      gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage2D(height)" );
+      return;
+   }
+   format = decode_internal_format( internalformat );
+   if (format<0 || (internalformat>=1 && internalformat<=4)) {
+      gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage2D(format)" );
+      return;
+   }
+
+   teximage = read_color_image( ctx, x, y, width, height, (GLenum) format );
+   if (!teximage) {
+      gl_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D" );
+      return;
+   }
+
+   gl_TexImage2D( ctx, target, level, internalformat, width, height,
+                  border, GL_RGBA, GL_UNSIGNED_BYTE, teximage );
+
+   /* teximage was freed in gl_TexImage2D */
+}
+
+
+
+
+/*
+ * Do the work of glCopyTexSubImage[123]D.
+ * TODO: apply pixel bias scale and mapping.
+ */
+static void copy_tex_sub_image( GLcontext *ctx, struct gl_texture_image *dest,
+                                GLint width, GLint height,
+                                GLint srcx, GLint srcy,
+                                GLint dstx, GLint dsty, GLint zoffset )
+{
+   GLint i, j;
+   GLint format, components, rectarea;
+   GLint texwidth, texheight; 
+
+   texwidth = dest->Width;
+   texheight = dest->Height;
+   rectarea = texwidth * texheight;
+   zoffset *= rectarea; 
+   format = dest->Format;
+   components = components_in_intformat( format );
+
+   /* Select buffer to read from */
+   (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Pixel.DriverReadBuffer );
+
+   for (j=0;j<height;j++) {
+      GLubyte rgba[MAX_WIDTH][4];
+      GLubyte *texptr;
+
+      gl_read_rgba_span( ctx, width, srcx, srcy+j, rgba );
+
+      texptr = dest->Data + ( zoffset + (dsty+j) * texwidth + dstx) * components;
+
+      switch (format) {
+         case GL_ALPHA:
+            for (i=0;i<width;i++) {
+               *texptr++ = rgba[i][ACOMP];
+            }
+            break;
+         case GL_LUMINANCE:
+            for (i=0;i<width;i++) {
+               *texptr++ = rgba[i][RCOMP];
+            }
+            break;
+         case GL_LUMINANCE_ALPHA:
+            for (i=0;i<width;i++) {
+               *texptr++ = rgba[i][RCOMP];
+               *texptr++ = rgba[i][ACOMP];
+            }
+            break;
+         case GL_INTENSITY:
+            for (i=0;i<width;i++) {
+               *texptr++ = rgba[i][RCOMP];
+            }
+            break;
+         case GL_RGB:
+            for (i=0;i<width;i++) {
+               *texptr++ = rgba[i][RCOMP];
+               *texptr++ = rgba[i][GCOMP];
+               *texptr++ = rgba[i][BCOMP];
+            }
+            break;
+         case GL_RGBA:
+            for (i=0;i<width;i++) {
+               *texptr++ = rgba[i][RCOMP];
+               *texptr++ = rgba[i][GCOMP];
+               *texptr++ = rgba[i][BCOMP];
+               *texptr++ = rgba[i][ACOMP];
+            }
+            break;
+      } /*switch*/
+   } /*for*/         
+
+
+   /* Restore drawing buffer */
+   (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Color.DriverDrawBuffer );
+}
+
+
+
+
+void gl_CopyTexSubImage1D( GLcontext *ctx,
+                              GLenum target, GLint level,
+                              GLint xoffset, GLint x, GLint y, GLsizei width )
+{
+   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+   struct gl_texture_image *teximage;
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glCopyTexSubImage1D");
+   if (target!=GL_TEXTURE_1D) {
+      gl_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage1D(target)" );
+      return;
+   }
+   if (level<0 || level>=ctx->Const.MaxTextureLevels) {
+      gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage1D(level)" );
+      return;
+   }
+   if (width<0) {
+      gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage1D(width)" );
+      return;
+   }
+
+   teximage = texUnit->CurrentD[1]->Image[level];
+
+   if (teximage) {
+      if (xoffset < -((GLint)teximage->Border)) {
+         gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage1D(xoffset)" );
+         return;
+      }
+      /* NOTE: we're adding the border here, not subtracting! */
+      if (xoffset+width > (GLint) (teximage->Width+teximage->Border)) {
+         gl_error( ctx, GL_INVALID_VALUE,
+                   "glCopyTexSubImage1D(xoffset+width)" );
+         return;
+      }
+      if (teximage->Data) {
+         copy_tex_sub_image( ctx, teximage, width, 1, x, y, xoffset, 0, 0 );
+
+        /* tell driver about change */
+        if (ctx->Driver.TexSubImage) {
+          (*ctx->Driver.TexSubImage)( ctx, GL_TEXTURE_1D,
+                                      texUnit->CurrentD[1], level,
+                                      xoffset,0,width,1,
+                                      teximage->IntFormat,
+                                      teximage );
+        }
+        else {
+          if (ctx->Driver.TexImage) {
+            (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_1D, texUnit->CurrentD[1], level,
+                                     teximage->IntFormat,
+                                     teximage );
+          }
+        }
+      }
+   }
+   else {
+      gl_error( ctx, GL_INVALID_OPERATION, "glCopyTexSubImage1D" );
+   }
+}
+
+
+
+void gl_CopyTexSubImage2D( GLcontext *ctx,
+                              GLenum target, GLint level,
+                              GLint xoffset, GLint yoffset,
+                              GLint x, GLint y, GLsizei width, GLsizei height )
+{
+   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+   struct gl_texture_image *teximage;
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glCopyTexSubImage2D");
+   if (target!=GL_TEXTURE_2D) {
+      gl_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" );
+      return;
+   }
+   if (level<0 || level>=ctx->Const.MaxTextureLevels) {
+      gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage2D(level)" );
+      return;
+   }
+   if (width<0) {
+      gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage2D(width)" );
+      return;
+   }
+   if (height<0) {
+      gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage2D(height)" );
+      return;
+   }
+
+   teximage = texUnit->CurrentD[2]->Image[level];
+
+   if (teximage) {
+      if (xoffset < -((GLint)teximage->Border)) {
+         gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage2D(xoffset)" );
+         return;
+      }
+      if (yoffset < -((GLint)teximage->Border)) {
+         gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage2D(yoffset)" );
+         return;
+      }
+      /* NOTE: we're adding the border here, not subtracting! */
+      if (xoffset+width > (GLint) (teximage->Width+teximage->Border)) {
+         gl_error( ctx, GL_INVALID_VALUE,
+                   "glCopyTexSubImage2D(xoffset+width)" );
+         return;
+      }
+      if (yoffset+height > (GLint) (teximage->Height+teximage->Border)) {
+         gl_error( ctx, GL_INVALID_VALUE,
+                   "glCopyTexSubImage2D(yoffset+height)" );
+         return;
+      }
+
+      if (teximage->Data) {
+         copy_tex_sub_image( ctx, teximage, width, height,
+                             x, y, xoffset, yoffset, 0 );
+        /* tell driver about change */
+        if (ctx->Driver.TexSubImage) {
+          (*ctx->Driver.TexSubImage)( ctx, GL_TEXTURE_2D, texUnit->CurrentD[2], level,
+                                      xoffset, yoffset, width, height,
+                                      teximage->IntFormat,
+                                      teximage );
+        }
+        else {
+          if (ctx->Driver.TexImage) {
+            (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_2D, texUnit->CurrentD[2], level,
+                                     teximage->IntFormat,
+                                     teximage );
+          }
+        }
+      }
+   }
+   else {
+      gl_error( ctx, GL_INVALID_OPERATION, "glCopyTexSubImage2D" );
+   }
+}
+
+
+
+void gl_CopyTexSubImage3DEXT( GLcontext *ctx,
+                              GLenum target, GLint level,
+                              GLint xoffset, GLint yoffset, GLint zoffset,
+                              GLint x, GLint y, GLsizei width, GLsizei height )
+{
+   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+   struct gl_texture_image *teximage;
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glCopyTexSubImage3DEXT");
+   if (target!=GL_TEXTURE_2D) {
+      gl_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage3DEXT(target)" );
+      return;
+   }
+   if (level<0 || level>=ctx->Const.MaxTextureLevels) {
+      gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage3DEXT(level)" );
+      return;
+   }
+   if (width<0) {
+      gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage3DEXT(width)" );
+      return;
+   }
+   if (height<0) {
+      gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage3DEXT(height)" );
+      return;
+   }
+
+   teximage = texUnit->CurrentD[3]->Image[level];
+   if (teximage) {
+      if (xoffset < -((GLint)teximage->Border)) {
+         gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage3DEXT(xoffset)" );
+         return;
+      }
+      if (yoffset < -((GLint)teximage->Border)) {
+         gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage3DEXT(yoffset)" );
+         return;
+      }
+      if (zoffset < -((GLint)teximage->Border)) {
+         gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage3DEXT(zoffset)" );
+         return;
+      }
+      /* NOTE: we're adding the border here, not subtracting! */
+      if (xoffset+width > (GLint) (teximage->Width+teximage->Border)) {
+         gl_error( ctx, GL_INVALID_VALUE,
+                   "glCopyTexSubImage3DEXT(xoffset+width)" );
+         return;
+      }
+      if (yoffset+height > (GLint) (teximage->Height+teximage->Border)) {
+         gl_error( ctx, GL_INVALID_VALUE,
+                   "glCopyTexSubImage3DEXT(yoffset+height)" );
+         return;
+      }
+      if (zoffset > (GLint) (teximage->Depth+teximage->Border)) {
+         gl_error( ctx, GL_INVALID_VALUE,
+                   "glCopyTexSubImage3DEXT(zoffset+depth)" );
+         return;
+      }
+
+      if (teximage->Data) {
+         copy_tex_sub_image( ctx, teximage, width, height, 
+                             x, y, xoffset, yoffset, zoffset);
+
+        /* tell driver about change */
+        if (ctx->Driver.TexImage) {
+          (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_3D_EXT, texUnit->CurrentD[3],
+                                   level, teximage->IntFormat,
+                                   teximage );
+        }
+      }
+   }
+   else {
+      gl_error( ctx, GL_INVALID_OPERATION, "glCopyTexSubImage3DEXT" );
+   }
+}
+
diff --git a/src/mesa/main/teximage.h b/src/mesa/main/teximage.h
new file mode 100644 (file)
index 0000000..eb72f96
--- /dev/null
@@ -0,0 +1,186 @@
+/* $Id: teximage.h,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+#ifndef TEXIMAGE_H
+#define TEXIMAGE_H
+
+
+#include "types.h"
+
+
+/*** Internal functions ***/
+
+
+extern struct gl_texture_image *gl_alloc_texture_image( void );
+
+
+extern void gl_free_texture_image( struct gl_texture_image *teximage );
+
+
+extern struct gl_image *
+gl_unpack_texsubimage( GLcontext *ctx, GLint width, GLint height,
+                       GLenum format, GLenum type, const GLvoid *pixels );
+
+
+extern struct gl_image *
+gl_unpack_texsubimage3D( GLcontext *ctx, GLint width, GLint height,GLint depth,
+                         GLenum format, GLenum type, const GLvoid *pixels );
+
+
+extern struct gl_texture_image *
+gl_unpack_texture( GLcontext *ctx,
+                   GLint dimensions,
+                   GLenum target,
+                   GLint level,
+                   GLint internalformat,
+                   GLsizei width, GLsizei height,
+                   GLint border,
+                   GLenum format, GLenum type,
+                   const GLvoid *pixels );
+
+extern struct gl_texture_image *
+gl_unpack_texture3D( GLcontext *ctx,
+                     GLint dimensions,
+                     GLenum target,
+                     GLint level,
+                     GLint internalformat,
+                     GLsizei width, GLsizei height, GLsizei depth,
+                     GLint border,
+                     GLenum format, GLenum type,
+                     const GLvoid *pixels );
+
+
+extern void gl_tex_image_1D( GLcontext *ctx,
+                             GLenum target, GLint level, GLint internalformat,
+                             GLsizei width, GLint border, GLenum format,
+                             GLenum type, const GLvoid *pixels );
+
+
+extern void gl_tex_image_2D( GLcontext *ctx,
+                             GLenum target, GLint level, GLint internalformat,
+                             GLsizei width, GLint height, GLint border,
+                             GLenum format, GLenum type,
+                             const GLvoid *pixels );
+
+extern void gl_tex_image_3D( GLcontext *ctx,
+                             GLenum target, GLint level, GLint internalformat,
+                             GLsizei width, GLint height, GLint depth,
+                             GLint border,
+                             GLenum format, GLenum type,
+                             const GLvoid *pixels );
+
+
+/*** API entry points ***/
+
+
+extern void gl_TexImage1D( GLcontext *ctx,
+                           GLenum target, GLint level, GLint internalformat,
+                           GLsizei width, GLint border, GLenum format,
+                           GLenum type, struct gl_image *teximage );
+
+
+extern void gl_TexImage2D( GLcontext *ctx,
+                           GLenum target, GLint level, GLint internalformat,
+                           GLsizei width, GLsizei height, GLint border,
+                           GLenum format, GLenum type,
+                           struct gl_image *teximage );
+
+
+extern void gl_TexImage3DEXT( GLcontext *ctx,
+                              GLenum target, GLint level, GLint internalformat,
+                              GLsizei width, GLsizei height, GLsizei depth,
+                              GLint border,
+                              GLenum format, GLenum type,
+                              struct gl_image *teximage );
+
+
+extern void gl_GetTexImage( GLcontext *ctx, GLenum target, GLint level,
+                            GLenum format, GLenum type, GLvoid *pixels );
+
+
+
+extern void gl_TexSubImage1D( GLcontext *ctx,
+                              GLenum target, GLint level, GLint xoffset,
+                              GLsizei width, GLenum format, GLenum type,
+                              struct gl_image *image );
+
+
+extern void gl_TexSubImage2D( GLcontext *ctx,
+                              GLenum target, GLint level,
+                              GLint xoffset, GLint yoffset,
+                              GLsizei width, GLsizei height,
+                              GLenum format, GLenum type,
+                              struct gl_image *image );
+
+
+extern void gl_TexSubImage3DEXT( GLcontext *ctx,
+                                 GLenum target, GLint level,
+                                 GLint xoffset, GLint yoffset, GLint zoffset,
+                                 GLsizei width, GLsizei height, GLsizei depth,
+                                 GLenum format, GLenum type,
+                                 struct gl_image *image );
+
+
+extern void gl_CopyTexImage1D( GLcontext *ctx,
+                               GLenum target, GLint level,
+                               GLenum internalformat,
+                               GLint x, GLint y,
+                               GLsizei width, GLint border );
+
+
+extern void gl_CopyTexImage2D( GLcontext *ctx,
+                               GLenum target, GLint level,
+                               GLenum internalformat, GLint x, GLint y,
+                               GLsizei width, GLsizei height,
+                               GLint border );
+
+
+extern void gl_CopyTexSubImage1D( GLcontext *ctx,
+                                  GLenum target, GLint level,
+                                  GLint xoffset, GLint x, GLint y,
+                                  GLsizei width );
+
+
+extern void gl_CopyTexSubImage2D( GLcontext *ctx,
+                                  GLenum target, GLint level,
+                                  GLint xoffset, GLint yoffset,
+                                  GLint x, GLint y,
+                                  GLsizei width, GLsizei height );
+
+
+extern void gl_CopyTexSubImage3DEXT( GLcontext *ctx,
+                                     GLenum target, GLint level,
+                                     GLint xoffset, GLint yoffset,
+                                     GLint zoffset,
+                                     GLint x, GLint y,
+                                     GLsizei width, GLsizei height );
+
+#endif
+
diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c
new file mode 100644 (file)
index 0000000..78691d2
--- /dev/null
@@ -0,0 +1,571 @@
+/* $Id: texobj.c,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "context.h"
+#include "enums.h"
+#include "hash.h"
+#include "macros.h"
+#include "teximage.h"
+#include "texstate.h"
+#include "texobj.h"
+#include "types.h"
+#ifdef XFree86Server
+#include "GL/xf86glx.h"
+#endif
+#endif
+
+
+
+/*
+ * Allocate a new texture object and add it to the linked list of texture
+ * objects.  If name>0 then also insert the new texture object into the hash
+ * table.
+ * Input:  shared - the shared GL state structure to contain the texture object
+ *         name - integer name for the texture object
+ *         dimensions - either 1, 2 or 3
+ * Return:  pointer to new texture object
+ */
+struct gl_texture_object *
+gl_alloc_texture_object( struct gl_shared_state *shared, GLuint name,
+                         GLuint dimensions)
+{
+   struct gl_texture_object *obj;
+
+   assert(dimensions <= 3);
+
+   obj = (struct gl_texture_object *)
+                     calloc(1,sizeof(struct gl_texture_object));
+   if (obj) {
+      /* init the non-zero fields */
+      obj->Name = name;
+      obj->Dimensions = dimensions;
+      obj->WrapS = GL_REPEAT;
+      obj->WrapT = GL_REPEAT;
+      obj->MinFilter = GL_NEAREST_MIPMAP_LINEAR;
+      obj->MagFilter = GL_LINEAR;
+      obj->MinLod = -1000.0;
+      obj->MaxLod = 1000.0;
+      obj->BaseLevel = 0;
+      obj->MaxLevel = 1000;
+      obj->MinMagThresh = 0.0F;
+      obj->Palette[0] = 255;
+      obj->Palette[1] = 255;
+      obj->Palette[2] = 255;
+      obj->Palette[3] = 255;
+      obj->PaletteSize = 1;
+      obj->PaletteIntFormat = GL_RGBA;
+      obj->PaletteFormat = GL_RGBA;
+
+      /* insert into linked list */
+      if (shared) {
+         obj->Next = shared->TexObjectList;
+         shared->TexObjectList = obj;
+      }
+
+      if (name > 0) {
+         /* insert into hash table */
+         HashInsert(shared->TexObjects, name, obj);
+      }
+   }
+   return obj;
+}
+
+
+/*
+ * Deallocate a texture object struct and remove it from the given
+ * shared GL state.
+ * Input:  shared - the shared GL state to which the object belongs
+ *         t - the texture object to delete
+ */
+void gl_free_texture_object( struct gl_shared_state *shared,
+                             struct gl_texture_object *t )
+{
+   struct gl_texture_object *tprev, *tcurr;
+
+   assert(t);
+
+   /* Remove t from dirty list so we don't touch free'd memory later.
+    * Test for shared since Proxy texture aren't in global linked list.
+    */
+   if (shared)
+      gl_remove_texobj_from_dirty_list( shared, t );
+
+   /* unlink t from the linked list */
+   if (shared) {
+      tprev = NULL;
+      tcurr = shared->TexObjectList;
+      while (tcurr) {
+         if (tcurr==t) {
+            if (tprev) {
+               tprev->Next = t->Next;
+            }
+            else {
+               shared->TexObjectList = t->Next;
+            }
+            break;
+         }
+         tprev = tcurr;
+         tcurr = tcurr->Next;
+      }
+   }
+
+   if (t->Name) {
+      /* remove from hash table */
+      HashRemove(shared->TexObjects, t->Name);
+   }
+
+   /* free texture image */
+   {
+      GLuint i;
+      for (i=0;i<MAX_TEXTURE_LEVELS;i++) {
+         if (t->Image[i]) {
+            gl_free_texture_image( t->Image[i] );
+         }
+      }
+   }
+   /* free this object */
+   free( t );
+}
+
+
+
+/*
+ * Examine a texture object to determine if it is complete or not.
+ * The t->Complete flag will be set to GL_TRUE or GL_FALSE accordingly.
+ */
+void gl_test_texture_object_completeness( const GLcontext *ctx, struct gl_texture_object *t )
+{
+   t->Complete = GL_TRUE;  /* be optimistic */
+
+   /* Always need level zero image */
+   if (!t->Image[0] || !t->Image[0]->Data) {
+      t->Complete = GL_FALSE;
+      return;
+   }
+
+   /* Compute number of mipmap levels */
+   if (t->Dimensions==1) {
+      t->P = t->Image[0]->WidthLog2;
+   }
+   else if (t->Dimensions==2) {
+      t->P = MAX2(t->Image[0]->WidthLog2, t->Image[0]->HeightLog2);
+   }
+   else if (t->Dimensions==3) {
+      GLint max = MAX2(t->Image[0]->WidthLog2, t->Image[0]->HeightLog2);
+      max = MAX2(max, (GLint)(t->Image[0]->DepthLog2));
+      t->P = max;
+   }
+
+   /* Compute M (see the 1.2 spec) used during mipmapping */
+   t->M = (GLfloat) (MIN2(t->MaxLevel, t->P) - t->BaseLevel);
+
+
+   if (t->MinFilter!=GL_NEAREST && t->MinFilter!=GL_LINEAR) {
+      /*
+       * Mipmapping: determine if we have a complete set of mipmaps
+       */
+      GLint i;
+      GLint minLevel = t->BaseLevel;
+      GLint maxLevel = MIN2(t->P, ctx->Const.MaxTextureLevels-1);
+      maxLevel = MIN2(maxLevel, t->MaxLevel);
+
+      if (minLevel > maxLevel) {
+         t->Complete = GL_FALSE;
+         return;
+      }
+
+      /* Test dimension-independent attributes */
+      for (i = minLevel; i <= maxLevel; i++) {
+         if (t->Image[i]) {
+            if (!t->Image[i]->Data) {
+               t->Complete = GL_FALSE;
+               return;
+            }
+            if (t->Image[i]->Format != t->Image[0]->Format) {
+               t->Complete = GL_FALSE;
+               return;
+            }
+            if (t->Image[i]->Border != t->Image[0]->Border) {
+               t->Complete = GL_FALSE;
+               return;
+            }
+         }
+      }
+
+      /* Test things which depend on number of texture image dimensions */
+      if (t->Dimensions==1) {
+         /* Test 1-D mipmaps */
+         GLuint width = t->Image[0]->Width2;
+         for (i=1; i<ctx->Const.MaxTextureLevels; i++) {
+            if (width>1) {
+               width /= 2;
+            }
+            if (i >= minLevel && i <= maxLevel) {
+               if (!t->Image[i]) {
+                  t->Complete = GL_FALSE;
+                  return;
+               }
+               if (!t->Image[i]->Data) {
+                  t->Complete = GL_FALSE;
+                  return;
+               }
+               if (t->Image[i]->Width2 != width ) {
+                  t->Complete = GL_FALSE;
+                  return;
+               }
+            }
+            if (width==1) {
+               return;  /* found smallest needed mipmap, all done! */
+            }
+         }
+      }
+      else if (t->Dimensions==2) {
+         /* Test 2-D mipmaps */
+         GLuint width = t->Image[0]->Width2;
+         GLuint height = t->Image[0]->Height2;
+         for (i=1; i<ctx->Const.MaxTextureLevels; i++) {
+            if (width>1) {
+               width /= 2;
+            }
+            if (height>1) {
+               height /= 2;
+            }
+            if (i >= minLevel && i <= maxLevel) {
+               if (!t->Image[i]) {
+                  t->Complete = GL_FALSE;
+                  return;
+               }
+               if (t->Image[i]->Width2 != width) {
+                  t->Complete = GL_FALSE;
+                  return;
+               }
+               if (t->Image[i]->Height2 != height) {
+                  t->Complete = GL_FALSE;
+                  return;
+               }
+               if (width==1 && height==1) {
+                  return;  /* found smallest needed mipmap, all done! */
+               }
+            }
+         }
+      }
+      else if (t->Dimensions==3) {
+         /* Test 3-D mipmaps */
+         GLuint width = t->Image[0]->Width2;
+         GLuint height = t->Image[0]->Height2;
+         GLuint depth = t->Image[0]->Depth2;
+        for (i=1; i<ctx->Const.MaxTextureLevels; i++) {
+            if (width>1) {
+               width /= 2;
+            }
+            if (height>1) {
+               height /= 2;
+            }
+            if (depth>1) {
+               depth /= 2;
+            }
+            if (i >= minLevel && i <= maxLevel) {
+               if (!t->Image[i]) {
+                  t->Complete = GL_FALSE;
+                  return;
+               }
+               if (t->Image[i]->Width2 != width) {
+                  t->Complete = GL_FALSE;
+                  return;
+               }
+               if (t->Image[i]->Height2 != height) {
+                  t->Complete = GL_FALSE;
+                  return;
+               }
+               if (t->Image[i]->Depth2 != depth) {
+                  t->Complete = GL_FALSE;
+                  return;
+               }
+            }
+            if (width==1 && height==1 && depth==1) {
+               return;  /* found smallest needed mipmap, all done! */
+            }
+         }
+      }
+      else {
+         /* Dimensions = ??? */
+         gl_problem(NULL, "Bug in gl_test_texture_object_completeness\n");
+      }
+   }
+}
+
+
+
+/*
+ * Execute glGenTextures
+ */
+void gl_GenTextures( GLcontext *ctx, GLsizei n, GLuint *texName )
+{
+   GLuint first;
+   GLint i;
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGenTextures");
+   if (n<0) {
+      gl_error( ctx, GL_INVALID_VALUE, "glGenTextures" );
+      return;
+   }
+
+   first = HashFindFreeKeyBlock(ctx->Shared->TexObjects, n);
+
+   /* Return the texture names */
+   for (i=0;i<n;i++) {
+      texName[i] = first + i;
+   }
+
+   /* Allocate new, empty texture objects */
+   for (i=0;i<n;i++) {
+      GLuint name = first + i;
+      GLuint dims = 0;
+      (void) gl_alloc_texture_object(ctx->Shared, name, dims);
+   }
+}
+
+
+
+/*
+ * Execute glDeleteTextures
+ */
+void gl_DeleteTextures( GLcontext *ctx, GLsizei n, const GLuint *texName)
+{
+   GLint i;
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDeleteTextures");
+
+   for (i=0;i<n;i++) {
+      struct gl_texture_object *t;
+      if (texName[i]>0) {
+         t = (struct gl_texture_object *)
+            HashLookup(ctx->Shared->TexObjects, texName[i]);
+         if (t) {
+            GLuint u;
+            for (u=0; u<MAX_TEXTURE_UNITS; u++) {
+               struct gl_texture_unit *unit = &ctx->Texture.Unit[u];
+              GLuint d;
+              for (d = 1 ; d <= 3 ; d++) {
+                 if (unit->CurrentD[d]==t) {
+                    unit->CurrentD[d] = ctx->Shared->DefaultD[d][u];
+                    ctx->Shared->DefaultD[d][u]->RefCount++;
+                    t->RefCount--;
+                    assert( t->RefCount >= 0 );
+                 }
+              }
+            }
+
+            /* tell device driver to delete texture */
+            if (ctx->Driver.DeleteTexture) {
+               (*ctx->Driver.DeleteTexture)( ctx, t );
+            }
+
+            if (t->RefCount==0) {
+               gl_free_texture_object(ctx->Shared, t);
+            }
+         }
+      }
+   }
+}
+
+
+
+/*
+ * Execute glBindTexture
+ */
+void gl_BindTexture( GLcontext *ctx, GLenum target, GLuint texName )
+{
+   GLuint unit = ctx->Texture.CurrentUnit;
+   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+   struct gl_texture_object *oldTexObj;
+   struct gl_texture_object *newTexObj;
+   GLint dim;
+
+   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+      fprintf(stderr, "glBindTexture %s %d\n",
+             gl_lookup_enum_by_nr(target), (GLint) texName);
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glBindTexture");
+
+   dim = target - GL_TEXTURE_1D;
+
+   if (dim < 0 || dim > 2) {
+      gl_error( ctx, GL_INVALID_ENUM, "glBindTexture" );
+      return;
+   }
+
+   dim++;
+   oldTexObj = texUnit->CurrentD[dim];
+
+   if (oldTexObj->Name == texName)
+      return;
+
+   if (texName == 0) 
+      newTexObj = ctx->Shared->DefaultD[unit][dim];
+   else {
+      struct HashTable *hash = ctx->Shared->TexObjects;
+      newTexObj = (struct gl_texture_object *) HashLookup(hash, texName);
+
+      if (!newTexObj)
+        newTexObj = gl_alloc_texture_object(ctx->Shared, texName, dim);
+
+      if (newTexObj->Dimensions != dim) {
+        if (newTexObj->Dimensions) {
+           gl_error( ctx, GL_INVALID_OPERATION, "glBindTexture" );
+           return;
+        }
+        newTexObj->Dimensions = dim;
+      }
+   }
+
+   oldTexObj->RefCount--;
+   newTexObj->RefCount++;
+   texUnit->CurrentD[dim] = newTexObj;
+
+   /* If we've changed the CurrentD[123] texture object then update the
+    * ctx->Texture.Current pointer to point to the new texture object.
+    */
+   texUnit->Current = texUnit->CurrentD[texUnit->CurrentDimension];
+
+   /* Check if we may have to use a new triangle rasterizer */
+   if ((ctx->IndirectTriangles & DD_SW_RASTERIZE) &&
+       (   oldTexObj->WrapS != newTexObj->WrapS
+        || oldTexObj->WrapT != newTexObj->WrapT
+        || oldTexObj->WrapR != newTexObj->WrapR
+        || oldTexObj->MinFilter != newTexObj->MinFilter
+        || oldTexObj->MagFilter != newTexObj->MagFilter
+        || (oldTexObj->Image[0] && newTexObj->Image[0] && 
+          (oldTexObj->Image[0]->Format!=newTexObj->Image[0]->Format))))
+   {
+      ctx->NewState |= (NEW_RASTER_OPS | NEW_TEXTURING);
+   }
+
+   if (oldTexObj->Complete != newTexObj->Complete)
+      ctx->NewState |= NEW_TEXTURING;
+
+   /* Pass BindTexture call to device driver */
+   if (ctx->Driver.BindTexture) {
+      (*ctx->Driver.BindTexture)( ctx, target, newTexObj );
+   }
+}
+
+
+
+/*
+ * Execute glPrioritizeTextures
+ */
+void gl_PrioritizeTextures( GLcontext *ctx,
+                            GLsizei n, const GLuint *texName,
+                            const GLclampf *priorities )
+{
+   GLint i;
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPrioritizeTextures");
+   if (n<0) {
+      gl_error( ctx, GL_INVALID_VALUE, "glPrioritizeTextures" );
+      return;
+   }
+
+   for (i=0;i<n;i++) {
+      struct gl_texture_object *t;
+      if (texName[i]>0) {
+         t = (struct gl_texture_object *)
+            HashLookup(ctx->Shared->TexObjects, texName[i]);
+         if (t) {
+            t->Priority = CLAMP( priorities[i], 0.0F, 1.0F );
+         }
+      }
+   }
+}
+
+
+
+/*
+ * Execute glAreTexturesResident
+ */
+GLboolean gl_AreTexturesResident( GLcontext *ctx, GLsizei n,
+                                  const GLuint *texName,
+                                  GLboolean *residences )
+{
+   GLboolean resident = GL_TRUE;
+   GLint i;
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH_WITH_RETVAL(ctx, 
+                                                 "glAreTexturesResident",
+                                                 GL_FALSE);
+   if (n<0) {
+      gl_error( ctx, GL_INVALID_VALUE, "glAreTexturesResident(n)" );
+      return GL_FALSE;
+   }
+
+   for (i=0;i<n;i++) {
+      struct gl_texture_object *t;
+      if (texName[i]==0) {
+         gl_error( ctx, GL_INVALID_VALUE, "glAreTexturesResident(textures)" );
+         return GL_FALSE;
+      }
+      t = (struct gl_texture_object *)
+         HashLookup(ctx->Shared->TexObjects, texName[i]);
+      if (t) {
+         /* we consider all valid texture objects to be resident */
+         residences[i] = GL_TRUE;
+      }
+      else {
+         gl_error( ctx, GL_INVALID_VALUE, "glAreTexturesResident(textures)" );
+         return GL_FALSE;
+      }
+   }
+   return resident;
+}
+
+
+
+/*
+ * Execute glIsTexture
+ */
+GLboolean gl_IsTexture( GLcontext *ctx, GLuint texture )
+{
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH_WITH_RETVAL(ctx, "glIsTextures",
+                                                 GL_FALSE);
+   if (texture>0 && HashLookup(ctx->Shared->TexObjects, texture)) {
+      return GL_TRUE;
+   }
+   else {
+      return GL_FALSE;
+   }
+}
+
diff --git a/src/mesa/main/texobj.h b/src/mesa/main/texobj.h
new file mode 100644 (file)
index 0000000..655c823
--- /dev/null
@@ -0,0 +1,85 @@
+/* $Id: texobj.h,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+#ifndef TEXTOBJ_H
+#define TEXTOBJ_H
+
+
+#include "types.h"
+
+
+#ifdef VMS
+#define gl_test_texture_object_completeness gl_test_texture_object_complete
+#endif
+
+/*
+ * Internal functions
+ */
+
+extern struct gl_texture_object *
+gl_alloc_texture_object( struct gl_shared_state *shared, GLuint name,
+                         GLuint dimensions );
+
+
+extern void gl_free_texture_object( struct gl_shared_state *shared,
+                                    struct gl_texture_object *t );
+
+
+extern void gl_test_texture_object_completeness( const GLcontext *ctx, struct gl_texture_object *t );
+
+
+/*
+ * API functions
+ */
+
+extern void gl_GenTextures( GLcontext *ctx, GLsizei n, GLuint *textures );
+
+
+extern void gl_DeleteTextures( GLcontext *ctx,
+                               GLsizei n, const GLuint *textures);
+
+
+extern void gl_BindTexture( GLcontext *ctx, GLenum target, GLuint texture );
+
+
+extern void gl_PrioritizeTextures( GLcontext *ctx,
+                                   GLsizei n, const GLuint *textures,
+                                   const GLclampf *priorities );
+
+
+extern GLboolean gl_AreTexturesResident( GLcontext *ctx, GLsizei n,
+                                         const GLuint *textures,
+                                         GLboolean *residences );
+
+
+extern GLboolean gl_IsTexture( GLcontext *ctx, GLuint texture );
+
+
+#endif
diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c
new file mode 100644 (file)
index 0000000..eee5eaa
--- /dev/null
@@ -0,0 +1,1146 @@
+/* $Id: texstate.c,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <assert.h>
+#include <stdio.h>
+#include "context.h"
+#include "enums.h"
+#include "macros.h"
+#include "matrix.h"
+#include "texobj.h"
+#include "texstate.h"
+#include "texture.h"
+#include "types.h"
+#include "xform.h"
+#ifdef XFree86Server
+#include "GL/xf86glx.h"
+#endif
+#endif
+
+
+
+#ifdef SPECIALCAST
+/* Needed for an Amiga compiler */
+#define ENUM_TO_FLOAT(X) ((GLfloat)(GLint)(X))
+#define ENUM_TO_DOUBLE(X) ((GLdouble)(GLint)(X))
+#else
+/* all other compilers */
+#define ENUM_TO_FLOAT(X) ((GLfloat)(X))
+#define ENUM_TO_DOUBLE(X) ((GLdouble)(X))
+#endif
+
+
+
+
+/**********************************************************************/
+/*                       Texture Environment                          */
+/**********************************************************************/
+
+
+void gl_TexEnvfv( GLcontext *ctx,
+                  GLenum target, GLenum pname, const GLfloat *param )
+{
+   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glTexEnv");
+
+   if (target!=GL_TEXTURE_ENV) {
+      gl_error( ctx, GL_INVALID_ENUM, "glTexEnv(target)" );
+      return;
+   }
+
+   if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
+      fprintf(stderr, "glTexEnv %s %s %.1f(%s) ...\n",  
+             gl_lookup_enum_by_nr(target),
+             gl_lookup_enum_by_nr(pname),
+             *param,
+             gl_lookup_enum_by_nr((GLenum) (GLint) *param));
+
+
+   if (pname==GL_TEXTURE_ENV_MODE) {
+      GLenum mode = (GLenum) (GLint) *param;
+      switch (mode) {
+        case GL_MODULATE:
+        case GL_BLEND:
+        case GL_DECAL:
+        case GL_REPLACE:
+           /* A small optimization for drivers */ 
+           if (texUnit->EnvMode == mode)
+               return;
+
+           if (MESA_VERBOSE & (VERBOSE_STATE|VERBOSE_TEXTURE))
+              fprintf(stderr, "glTexEnv: old mode %s, new mode %s\n",
+                      gl_lookup_enum_by_nr(texUnit->EnvMode),
+                      gl_lookup_enum_by_nr(mode));
+
+           texUnit->EnvMode = mode;
+           ctx->NewState |= NEW_TEXTURE_ENV;
+           break;
+        default:
+           gl_error( ctx, GL_INVALID_VALUE, "glTexEnv(param)" );
+           return;
+      }
+   }
+   else if (pname==GL_TEXTURE_ENV_COLOR) {
+      texUnit->EnvColor[0] = CLAMP( param[0], 0.0, 1.0 );
+      texUnit->EnvColor[1] = CLAMP( param[1], 0.0, 1.0 );
+      texUnit->EnvColor[2] = CLAMP( param[2], 0.0, 1.0 );
+      texUnit->EnvColor[3] = CLAMP( param[3], 0.0, 1.0 );
+   }
+   else {
+      gl_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname)" );
+      return;
+   }
+
+   /* Tell device driver about the new texture environment */
+   if (ctx->Driver.TexEnv) {
+      (*ctx->Driver.TexEnv)( ctx, pname, param );
+   }
+}
+
+
+
+
+
+void gl_GetTexEnvfv( GLcontext *ctx,
+                     GLenum target, GLenum pname, GLfloat *params )
+{
+   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+   if (target!=GL_TEXTURE_ENV) {
+      gl_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" );
+      return;
+   }
+   switch (pname) {
+      case GL_TEXTURE_ENV_MODE:
+         *params = ENUM_TO_FLOAT(texUnit->EnvMode);
+        break;
+      case GL_TEXTURE_ENV_COLOR:
+        COPY_4FV( params, texUnit->EnvColor );
+        break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)" );
+   }
+}
+
+
+void gl_GetTexEnviv( GLcontext *ctx,
+                     GLenum target, GLenum pname, GLint *params )
+{
+   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+   if (target!=GL_TEXTURE_ENV) {
+      gl_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(target)" );
+      return;
+   }
+   switch (pname) {
+      case GL_TEXTURE_ENV_MODE:
+         *params = (GLint) texUnit->EnvMode;
+        break;
+      case GL_TEXTURE_ENV_COLOR:
+        params[0] = FLOAT_TO_INT( texUnit->EnvColor[0] );
+        params[1] = FLOAT_TO_INT( texUnit->EnvColor[1] );
+        params[2] = FLOAT_TO_INT( texUnit->EnvColor[2] );
+        params[3] = FLOAT_TO_INT( texUnit->EnvColor[3] );
+        break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)" );
+   }
+}
+
+
+
+
+/**********************************************************************/
+/*                       Texture Parameters                           */
+/**********************************************************************/
+
+
+void gl_TexParameterfv( GLcontext *ctx,
+                        GLenum target, GLenum pname, const GLfloat *params )
+{
+   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+   GLenum eparam = (GLenum) (GLint) params[0];
+   struct gl_texture_object *texObj;
+
+   if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
+      fprintf(stderr, "texPARAM %s %s %d...\n", 
+             gl_lookup_enum_by_nr(target),
+             gl_lookup_enum_by_nr(pname),
+             eparam);
+
+
+   switch (target) {
+      case GL_TEXTURE_1D:
+         texObj = texUnit->CurrentD[1];
+         break;
+      case GL_TEXTURE_2D:
+         texObj = texUnit->CurrentD[2];
+         break;
+      case GL_TEXTURE_3D_EXT:
+         texObj = texUnit->CurrentD[3];
+         break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glTexParameter(target)" );
+         return;
+   }
+
+   switch (pname) {
+      case GL_TEXTURE_MIN_FILTER:
+         /* A small optimization */
+         if (texObj->MinFilter == eparam)
+            return;
+
+         if (eparam==GL_NEAREST || eparam==GL_LINEAR
+             || eparam==GL_NEAREST_MIPMAP_NEAREST
+             || eparam==GL_LINEAR_MIPMAP_NEAREST
+             || eparam==GL_NEAREST_MIPMAP_LINEAR
+             || eparam==GL_LINEAR_MIPMAP_LINEAR) {
+            texObj->MinFilter = eparam;
+            ctx->NewState |= NEW_TEXTURING;
+         }
+         else {
+            gl_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
+            return;
+         }
+         break;
+      case GL_TEXTURE_MAG_FILTER:
+         /* A small optimization */
+         if (texObj->MagFilter == eparam)
+            return;
+
+         if (eparam==GL_NEAREST || eparam==GL_LINEAR) {
+            texObj->MagFilter = eparam;
+            ctx->NewState |= NEW_TEXTURING;
+         }
+         else {
+            gl_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
+            return;
+         }
+         break;
+      case GL_TEXTURE_WRAP_S:
+         if (texObj->WrapS == eparam)
+            return;
+
+         if (eparam==GL_CLAMP || eparam==GL_REPEAT || eparam==GL_CLAMP_TO_EDGE) {
+            texObj->WrapS = eparam;
+            ctx->NewState |= NEW_TEXTURING;
+         }
+         else {
+            gl_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
+            return;
+         }
+         break;
+      case GL_TEXTURE_WRAP_T:
+         if (texObj->WrapT == eparam)
+            return;
+
+         if (eparam==GL_CLAMP || eparam==GL_REPEAT || eparam==GL_CLAMP_TO_EDGE) {
+            texObj->WrapT = eparam;
+            ctx->NewState |= NEW_TEXTURING;
+         }
+         else {
+            gl_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
+            return;
+         }
+         break;
+      case GL_TEXTURE_WRAP_R_EXT:
+         if (texObj->WrapR == eparam)
+            return;
+
+         if (eparam==GL_CLAMP || eparam==GL_REPEAT || eparam==GL_CLAMP_TO_EDGE) {
+            texObj->WrapR = eparam;
+            ctx->NewState |= NEW_TEXTURING;
+         }
+         else {
+            gl_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
+         }
+         break;
+      case GL_TEXTURE_BORDER_COLOR:
+         texObj->BorderColor[0] = CLAMP((GLint)(params[0]*255.0), 0, 255);
+         texObj->BorderColor[1] = CLAMP((GLint)(params[1]*255.0), 0, 255);
+         texObj->BorderColor[2] = CLAMP((GLint)(params[2]*255.0), 0, 255);
+         texObj->BorderColor[3] = CLAMP((GLint)(params[3]*255.0), 0, 255);
+         break;
+      case GL_TEXTURE_MIN_LOD:
+         texObj->MinLod = params[0];
+         ctx->NewState |= NEW_TEXTURING;
+         break;
+      case GL_TEXTURE_MAX_LOD:
+         texObj->MaxLod = params[0];
+         ctx->NewState |= NEW_TEXTURING;
+         break;
+      case GL_TEXTURE_BASE_LEVEL:
+         if (params[0] < 0.0) {
+            gl_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
+            return;
+         }
+         texObj->BaseLevel = (GLint) params[0];
+         ctx->NewState |= NEW_TEXTURING;
+         break;
+      case GL_TEXTURE_MAX_LEVEL:
+         if (params[0] < 0.0) {
+            gl_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
+            return;
+         }
+         texObj->MaxLevel = (GLint) params[0];
+         ctx->NewState |= NEW_TEXTURING;
+         break;
+      case GL_TEXTURE_PRIORITY:
+         /* (keithh@netcomuk.co.uk) */
+         texObj->Priority = CLAMP( params[0], 0.0, 1.0 );
+         break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glTexParameter(pname)" );
+         return;
+   }
+
+   gl_put_texobj_on_dirty_list( ctx, texObj );
+
+   if (ctx->Driver.TexParameter) {
+      (*ctx->Driver.TexParameter)( ctx, target, texObj, pname, params );
+   }
+}
+
+
+
+void gl_GetTexLevelParameterfv( GLcontext *ctx, GLenum target, GLint level,
+                                GLenum pname, GLfloat *params )
+{
+   GLint iparam;
+   gl_GetTexLevelParameteriv( ctx, target, level, pname, &iparam );
+   *params = (GLfloat) iparam;
+}
+
+
+
+void gl_GetTexLevelParameteriv( GLcontext *ctx, GLenum target, GLint level,
+                                GLenum pname, GLint *params )
+{
+   const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+   const struct gl_texture_image *img = NULL;
+   GLuint dimensions;
+
+   if (level < 0 || level >= ctx->Const.MaxTextureLevels) {
+      gl_error( ctx, GL_INVALID_VALUE, "glGetTexLevelParameter[if]v" );
+      return;
+   }
+
+   switch (target) {
+      case GL_TEXTURE_1D:
+         img = texUnit->CurrentD[1]->Image[level];
+         dimensions = 1;
+         break;
+      case GL_TEXTURE_2D:
+         img = texUnit->CurrentD[2]->Image[level];
+         dimensions = 2;
+         break;
+      case GL_TEXTURE_3D:
+         img = texUnit->CurrentD[3]->Image[level];
+         dimensions = 3; 
+        break;
+      case GL_PROXY_TEXTURE_1D:
+         img = ctx->Texture.Proxy1D->Image[level];
+         dimensions = 1;
+         break;
+      case GL_PROXY_TEXTURE_2D:
+         img = ctx->Texture.Proxy2D->Image[level];
+         dimensions = 2;
+         break;
+      case GL_PROXY_TEXTURE_3D:
+         img = ctx->Texture.Proxy3D->Image[level];
+         dimensions = 3;
+         break;
+      default:
+        gl_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(target)");
+         return;
+   }
+
+   if (!img) {
+      if (pname == GL_TEXTURE_COMPONENTS)
+         *params = 1;
+      else
+         *params = 0;
+      return;
+   }
+
+   switch (pname) {
+      case GL_TEXTURE_WIDTH:
+         *params = img->Width;
+         return;
+      case GL_TEXTURE_HEIGHT:
+         if (dimensions > 1) {
+            *params = img->Height;
+         }
+         else {
+            gl_error( ctx, GL_INVALID_ENUM,
+                      "glGetTexLevelParameter[if]v(pname=GL_TEXTURE_HEIGHT)" );
+         }
+         return;
+      case GL_TEXTURE_DEPTH:
+         if (dimensions > 2) {
+            *params = img->Depth;
+         }
+         else {
+            gl_error( ctx, GL_INVALID_ENUM,
+                      "glGetTexLevelParameter[if]v(pname=GL_TEXTURE_DEPTH)" );
+         }
+         return;
+      case GL_TEXTURE_COMPONENTS:
+         *params = img->IntFormat;
+         return;
+      case GL_TEXTURE_BORDER:
+         *params = img->Border;
+         return;
+      case GL_TEXTURE_RED_SIZE:
+         *params = img->RedBits;
+         return;
+      case GL_TEXTURE_GREEN_SIZE:
+         *params = img->GreenBits;
+         return;
+      case GL_TEXTURE_BLUE_SIZE:
+         *params = img->BlueBits;
+         return;
+      case GL_TEXTURE_ALPHA_SIZE:
+         *params = img->AlphaBits;
+         return;
+      case GL_TEXTURE_INTENSITY_SIZE:
+         *params = img->IntensityBits;
+         return;
+      case GL_TEXTURE_LUMINANCE_SIZE:
+         *params = img->LuminanceBits;
+         return;
+      case GL_TEXTURE_INDEX_SIZE_EXT:
+         *params = img->IndexBits;
+         return;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM,
+                   "glGetTexLevelParameter[if]v(pname)" );
+   }
+}
+
+
+
+
+void gl_GetTexParameterfv( GLcontext *ctx,
+                           GLenum target, GLenum pname, GLfloat *params )
+{
+   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+   struct gl_texture_object *obj;
+
+   switch (target) {
+      case GL_TEXTURE_1D:
+         obj = texUnit->CurrentD[1];
+         break;
+      case GL_TEXTURE_2D:
+         obj = texUnit->CurrentD[2];
+         break;
+      case GL_TEXTURE_3D_EXT:
+         obj = texUnit->CurrentD[3];
+         break;
+      default:
+         gl_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(target)");
+         return;
+   }
+
+   switch (pname) {
+      case GL_TEXTURE_MAG_FILTER:
+        *params = ENUM_TO_FLOAT(obj->MagFilter);
+        break;
+      case GL_TEXTURE_MIN_FILTER:
+         *params = ENUM_TO_FLOAT(obj->MinFilter);
+         break;
+      case GL_TEXTURE_WRAP_S:
+         *params = ENUM_TO_FLOAT(obj->WrapS);
+         break;
+      case GL_TEXTURE_WRAP_T:
+         *params = ENUM_TO_FLOAT(obj->WrapT);
+         break;
+      case GL_TEXTURE_WRAP_R_EXT:
+         *params = ENUM_TO_FLOAT(obj->WrapR);
+         break;
+      case GL_TEXTURE_BORDER_COLOR:
+         params[0] = obj->BorderColor[0] / 255.0F;
+         params[1] = obj->BorderColor[1] / 255.0F;
+         params[2] = obj->BorderColor[2] / 255.0F;
+         params[3] = obj->BorderColor[3] / 255.0F;
+         break;
+      case GL_TEXTURE_RESIDENT:
+         *params = ENUM_TO_FLOAT(GL_TRUE);
+         break;
+      case GL_TEXTURE_PRIORITY:
+         *params = obj->Priority;
+         break;
+      case GL_TEXTURE_MIN_LOD:
+         *params = obj->MinLod;
+         break;
+      case GL_TEXTURE_MAX_LOD:
+         *params = obj->MaxLod;
+         break;
+      case GL_TEXTURE_BASE_LEVEL:
+         *params = obj->BaseLevel;
+         break;
+      case GL_TEXTURE_MAX_LEVEL:
+         *params = obj->MaxLevel;
+         break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname)" );
+   }
+}
+
+
+void gl_GetTexParameteriv( GLcontext *ctx,
+                           GLenum target, GLenum pname, GLint *params )
+{
+   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+   struct gl_texture_object *obj;
+
+   switch (target) {
+      case GL_TEXTURE_1D:
+         obj = texUnit->CurrentD[1];
+         break;
+      case GL_TEXTURE_2D:
+         obj = texUnit->CurrentD[2];
+         break;
+      case GL_TEXTURE_3D_EXT:
+         obj = texUnit->CurrentD[3];
+         break;
+      default:
+         gl_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(target)");
+         return;
+   }
+
+   switch (pname) {
+      case GL_TEXTURE_MAG_FILTER:
+         *params = (GLint) obj->MagFilter;
+         break;
+      case GL_TEXTURE_MIN_FILTER:
+         *params = (GLint) obj->MinFilter;
+         break;
+      case GL_TEXTURE_WRAP_S:
+         *params = (GLint) obj->WrapS;
+         break;
+      case GL_TEXTURE_WRAP_T:
+         *params = (GLint) obj->WrapT;
+         break;
+      case GL_TEXTURE_WRAP_R_EXT:
+         *params = (GLint) obj->WrapR;
+         break;
+      case GL_TEXTURE_BORDER_COLOR:
+         {
+            GLfloat color[4];
+            color[0] = obj->BorderColor[0]/255.0;
+            color[1] = obj->BorderColor[1]/255.0;
+            color[2] = obj->BorderColor[2]/255.0;
+            color[3] = obj->BorderColor[3]/255.0;
+            params[0] = FLOAT_TO_INT( color[0] );
+            params[1] = FLOAT_TO_INT( color[1] );
+            params[2] = FLOAT_TO_INT( color[2] );
+            params[3] = FLOAT_TO_INT( color[3] );
+         }
+         break;
+      case GL_TEXTURE_RESIDENT:
+         *params = (GLint) GL_TRUE;
+         break;
+      case GL_TEXTURE_PRIORITY:
+         *params = (GLint) obj->Priority;
+         break;
+      case GL_TEXTURE_MIN_LOD:
+         *params = (GLint) obj->MinLod;
+         break;
+      case GL_TEXTURE_MAX_LOD:
+         *params = (GLint) obj->MaxLod;
+         break;
+      case GL_TEXTURE_BASE_LEVEL:
+         *params = obj->BaseLevel;
+         break;
+      case GL_TEXTURE_MAX_LEVEL:
+         *params = obj->MaxLevel;
+         break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname)" );
+   }
+}
+
+
+
+
+/**********************************************************************/
+/*                    Texture Coord Generation                        */
+/**********************************************************************/
+
+
+void gl_TexGenfv( GLcontext *ctx,
+                  GLenum coord, GLenum pname, const GLfloat *params )
+{
+   GLuint tUnit = ctx->Texture.CurrentTransformUnit;
+   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[tUnit];
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glTexGenfv");
+
+   if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
+      fprintf(stderr, "texGEN %s %s %x...\n", 
+             gl_lookup_enum_by_nr(coord),
+             gl_lookup_enum_by_nr(pname),
+             *(int *)params);
+
+   switch( coord ) {
+      case GL_S:
+         if (pname==GL_TEXTURE_GEN_MODE) {
+           GLenum mode = (GLenum) (GLint) *params;
+           switch (mode) {
+           case GL_OBJECT_LINEAR:
+              texUnit->GenModeS = mode;
+              texUnit->GenBitS = TEXGEN_OBJ_LINEAR;
+              break;
+           case GL_EYE_LINEAR:
+              texUnit->GenModeS = mode;
+              texUnit->GenBitS = TEXGEN_EYE_LINEAR;
+              break;
+           case GL_REFLECTION_MAP_NV:
+              texUnit->GenModeS = mode;
+              texUnit->GenBitS = TEXGEN_REFLECTION_MAP_NV;
+              break;
+           case GL_NORMAL_MAP_NV:
+              texUnit->GenModeS = mode;
+              texUnit->GenBitS = TEXGEN_NORMAL_MAP_NV;
+              break;
+           case GL_SPHERE_MAP:
+              texUnit->GenModeS = mode;
+              texUnit->GenBitS = TEXGEN_SPHERE_MAP;
+              break;
+           default:
+              gl_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
+              return;
+           }
+        }
+        else if (pname==GL_OBJECT_PLANE) {
+           texUnit->ObjectPlaneS[0] = params[0];
+           texUnit->ObjectPlaneS[1] = params[1];
+           texUnit->ObjectPlaneS[2] = params[2];
+           texUnit->ObjectPlaneS[3] = params[3];
+        }
+        else if (pname==GL_EYE_PLANE) {
+            /* Transform plane equation by the inverse modelview matrix */
+            if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) {
+               gl_matrix_analyze( &ctx->ModelView );
+            }
+            gl_transform_vector( texUnit->EyePlaneS, params,
+                                 ctx->ModelView.inv );
+        }
+        else {
+           gl_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
+           return;
+        }
+        break;
+      case GL_T:
+         if (pname==GL_TEXTURE_GEN_MODE) {
+           GLenum mode = (GLenum) (GLint) *params;
+           switch(mode) {
+           case GL_OBJECT_LINEAR:
+              texUnit->GenModeT = GL_OBJECT_LINEAR;
+              texUnit->GenBitT = TEXGEN_OBJ_LINEAR;
+              break;
+           case GL_EYE_LINEAR:
+              texUnit->GenModeT = GL_EYE_LINEAR;
+              texUnit->GenBitT = TEXGEN_EYE_LINEAR;
+              break;
+           case GL_REFLECTION_MAP_NV:
+              texUnit->GenModeT = GL_REFLECTION_MAP_NV;
+              texUnit->GenBitT = TEXGEN_REFLECTION_MAP_NV;
+              break;
+           case GL_NORMAL_MAP_NV:
+              texUnit->GenModeT = GL_NORMAL_MAP_NV;
+              texUnit->GenBitT = TEXGEN_NORMAL_MAP_NV;
+              break;
+           case GL_SPHERE_MAP:
+              texUnit->GenModeT = GL_SPHERE_MAP;
+              texUnit->GenBitT = TEXGEN_SPHERE_MAP;
+              break;
+           default:
+              gl_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
+              return;
+           }
+        }
+        else if (pname==GL_OBJECT_PLANE) {
+           texUnit->ObjectPlaneT[0] = params[0];
+           texUnit->ObjectPlaneT[1] = params[1];
+           texUnit->ObjectPlaneT[2] = params[2];
+           texUnit->ObjectPlaneT[3] = params[3];
+        }
+        else if (pname==GL_EYE_PLANE) {
+            /* Transform plane equation by the inverse modelview matrix */
+            if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) {
+               gl_matrix_analyze( &ctx->ModelView );
+            }
+            gl_transform_vector( texUnit->EyePlaneT, params,
+                                 ctx->ModelView.inv );
+        }
+        else {
+           gl_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
+           return;
+        }
+        break;
+      case GL_R:
+         if (pname==GL_TEXTURE_GEN_MODE) {
+           GLenum mode = (GLenum) (GLint) *params;
+           switch (mode) {
+           case GL_OBJECT_LINEAR:
+              texUnit->GenModeR = GL_OBJECT_LINEAR;
+              texUnit->GenBitR = TEXGEN_OBJ_LINEAR;
+              break;
+           case GL_REFLECTION_MAP_NV:
+              texUnit->GenModeR = GL_REFLECTION_MAP_NV;
+              texUnit->GenBitR = TEXGEN_REFLECTION_MAP_NV;
+              break;
+           case GL_NORMAL_MAP_NV:
+              texUnit->GenModeR = GL_NORMAL_MAP_NV;
+              texUnit->GenBitR = TEXGEN_NORMAL_MAP_NV;
+              break;
+           case GL_EYE_LINEAR:
+              texUnit->GenModeR = GL_EYE_LINEAR;
+              texUnit->GenBitR = TEXGEN_EYE_LINEAR;
+              break;
+           default:
+              gl_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
+              return;
+           }
+        }
+        else if (pname==GL_OBJECT_PLANE) {
+           texUnit->ObjectPlaneR[0] = params[0];
+           texUnit->ObjectPlaneR[1] = params[1];
+           texUnit->ObjectPlaneR[2] = params[2];
+           texUnit->ObjectPlaneR[3] = params[3];
+        }
+        else if (pname==GL_EYE_PLANE) {
+            /* Transform plane equation by the inverse modelview matrix */
+            if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) {
+               gl_matrix_analyze( &ctx->ModelView );
+            }
+            gl_transform_vector( texUnit->EyePlaneR, params,
+                                 ctx->ModelView.inv );
+        }
+        else {
+           gl_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
+           return;
+        }
+        break;
+      case GL_Q:
+         if (pname==GL_TEXTURE_GEN_MODE) {
+           GLenum mode = (GLenum) (GLint) *params;
+           switch (mode) {
+           case GL_OBJECT_LINEAR: 
+              texUnit->GenModeQ = GL_OBJECT_LINEAR;
+              texUnit->GenBitQ = TEXGEN_OBJ_LINEAR;
+              break;
+           case GL_EYE_LINEAR:
+              texUnit->GenModeQ = GL_EYE_LINEAR;
+              texUnit->GenBitQ = TEXGEN_EYE_LINEAR;
+              break;
+           default:
+              gl_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
+              return;
+           }
+        }
+        else if (pname==GL_OBJECT_PLANE) {
+           texUnit->ObjectPlaneQ[0] = params[0];
+           texUnit->ObjectPlaneQ[1] = params[1];
+           texUnit->ObjectPlaneQ[2] = params[2];
+           texUnit->ObjectPlaneQ[3] = params[3];
+        }
+        else if (pname==GL_EYE_PLANE) {
+            /* Transform plane equation by the inverse modelview matrix */
+            if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) {
+               gl_matrix_analyze( &ctx->ModelView );
+            }
+            gl_transform_vector( texUnit->EyePlaneQ, params,
+                                 ctx->ModelView.inv );
+        }
+        else {
+           gl_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
+           return;
+        }
+        break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glTexGenfv(coord)" );
+        return;
+   }
+
+   ctx->NewState |= NEW_TEXTURING;
+}
+
+
+
+void gl_GetTexGendv( GLcontext *ctx,
+                     GLenum coord, GLenum pname, GLdouble *params )
+{
+   GLuint tUnit = ctx->Texture.CurrentTransformUnit;
+   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[tUnit];
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetTexGendv");
+
+   switch( coord ) {
+      case GL_S:
+         if (pname==GL_TEXTURE_GEN_MODE) {
+            params[0] = ENUM_TO_DOUBLE(texUnit->GenModeS);
+        }
+        else if (pname==GL_OBJECT_PLANE) {
+            COPY_4V( params, texUnit->ObjectPlaneS );
+        }
+        else if (pname==GL_EYE_PLANE) {
+            COPY_4V( params, texUnit->EyePlaneS );
+        }
+        else {
+           gl_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
+           return;
+        }
+        break;
+      case GL_T:
+         if (pname==GL_TEXTURE_GEN_MODE) {
+            params[0] = ENUM_TO_DOUBLE(texUnit->GenModeT);
+        }
+        else if (pname==GL_OBJECT_PLANE) {
+            COPY_4V( params, texUnit->ObjectPlaneT );
+        }
+        else if (pname==GL_EYE_PLANE) {
+            COPY_4V( params, texUnit->EyePlaneT );
+        }
+        else {
+           gl_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
+           return;
+        }
+        break;
+      case GL_R:
+         if (pname==GL_TEXTURE_GEN_MODE) {
+            params[0] = ENUM_TO_DOUBLE(texUnit->GenModeR);
+        }
+        else if (pname==GL_OBJECT_PLANE) {
+            COPY_4V( params, texUnit->ObjectPlaneR );
+        }
+        else if (pname==GL_EYE_PLANE) {
+            COPY_4V( params, texUnit->EyePlaneR );
+        }
+        else {
+           gl_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
+           return;
+        }
+        break;
+      case GL_Q:
+         if (pname==GL_TEXTURE_GEN_MODE) {
+            params[0] = ENUM_TO_DOUBLE(texUnit->GenModeQ);
+        }
+        else if (pname==GL_OBJECT_PLANE) {
+            COPY_4V( params, texUnit->ObjectPlaneQ );
+        }
+        else if (pname==GL_EYE_PLANE) {
+            COPY_4V( params, texUnit->EyePlaneQ );
+        }
+        else {
+           gl_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
+           return;
+        }
+        break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(coord)" );
+        return;
+   }
+}
+
+
+
+void gl_GetTexGenfv( GLcontext *ctx,
+                     GLenum coord, GLenum pname, GLfloat *params )
+{
+   GLuint tUnit = ctx->Texture.CurrentTransformUnit;
+   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[tUnit];
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetTexGenfv");
+
+   switch( coord ) {
+      case GL_S:
+         if (pname==GL_TEXTURE_GEN_MODE) {
+            params[0] = ENUM_TO_FLOAT(texUnit->GenModeS);
+        }
+        else if (pname==GL_OBJECT_PLANE) {
+            COPY_4V( params, texUnit->ObjectPlaneS );
+        }
+        else if (pname==GL_EYE_PLANE) {
+            COPY_4V( params, texUnit->EyePlaneS );
+        }
+        else {
+           gl_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
+           return;
+        }
+        break;
+      case GL_T:
+         if (pname==GL_TEXTURE_GEN_MODE) {
+            params[0] = ENUM_TO_FLOAT(texUnit->GenModeT);
+        }
+        else if (pname==GL_OBJECT_PLANE) {
+            COPY_4V( params, texUnit->ObjectPlaneT );
+        }
+        else if (pname==GL_EYE_PLANE) {
+            COPY_4V( params, texUnit->EyePlaneT );
+        }
+        else {
+           gl_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
+           return;
+        }
+        break;
+      case GL_R:
+         if (pname==GL_TEXTURE_GEN_MODE) {
+            params[0] = ENUM_TO_FLOAT(texUnit->GenModeR);
+        }
+        else if (pname==GL_OBJECT_PLANE) {
+            COPY_4V( params, texUnit->ObjectPlaneR );
+        }
+        else if (pname==GL_EYE_PLANE) {
+            COPY_4V( params, texUnit->EyePlaneR );
+        }
+        else {
+           gl_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
+           return;
+        }
+        break;
+      case GL_Q:
+         if (pname==GL_TEXTURE_GEN_MODE) {
+            params[0] = ENUM_TO_FLOAT(texUnit->GenModeQ);
+        }
+        else if (pname==GL_OBJECT_PLANE) {
+            COPY_4V( params, texUnit->ObjectPlaneQ );
+        }
+        else if (pname==GL_EYE_PLANE) {
+            COPY_4V( params, texUnit->EyePlaneQ );
+        }
+        else {
+           gl_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
+           return;
+        }
+        break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(coord)" );
+        return;
+   }
+}
+
+
+
+void gl_GetTexGeniv( GLcontext *ctx,
+                     GLenum coord, GLenum pname, GLint *params )
+{
+   GLuint tUnit = ctx->Texture.CurrentTransformUnit;
+   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[tUnit];
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetTexGeniv");
+
+   switch( coord ) {
+      case GL_S:
+         if (pname==GL_TEXTURE_GEN_MODE) {
+            params[0] = texUnit->GenModeS;
+        }
+        else if (pname==GL_OBJECT_PLANE) {
+            COPY_4V( params, texUnit->ObjectPlaneS );
+        }
+        else if (pname==GL_EYE_PLANE) {
+            COPY_4V( params, texUnit->EyePlaneS );
+        }
+        else {
+           gl_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
+           return;
+        }
+        break;
+      case GL_T:
+         if (pname==GL_TEXTURE_GEN_MODE) {
+            params[0] = texUnit->GenModeT;
+        }
+        else if (pname==GL_OBJECT_PLANE) {
+            COPY_4V( params, texUnit->ObjectPlaneT );
+        }
+        else if (pname==GL_EYE_PLANE) {
+            COPY_4V( params, texUnit->EyePlaneT );
+        }
+        else {
+           gl_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
+           return;
+        }
+        break;
+      case GL_R:
+         if (pname==GL_TEXTURE_GEN_MODE) {
+            params[0] = texUnit->GenModeR;
+        }
+        else if (pname==GL_OBJECT_PLANE) {
+            COPY_4V( params, texUnit->ObjectPlaneR );
+        }
+        else if (pname==GL_EYE_PLANE) {
+            COPY_4V( params, texUnit->EyePlaneR );
+        }
+        else {
+           gl_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
+           return;
+        }
+        break;
+      case GL_Q:
+         if (pname==GL_TEXTURE_GEN_MODE) {
+            params[0] = texUnit->GenModeQ;
+        }
+        else if (pname==GL_OBJECT_PLANE) {
+            COPY_4V( params, texUnit->ObjectPlaneQ );
+        }
+        else if (pname==GL_EYE_PLANE) {
+            COPY_4V( params, texUnit->EyePlaneQ );
+        }
+        else {
+           gl_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
+           return;
+        }
+        break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(coord)" );
+        return;
+   }
+}
+
+
+/* GL_ARB_multitexture */
+void gl_ActiveTexture( GLcontext *ctx, GLenum target )
+{
+   GLint maxUnits = ctx->Const.MaxTextureUnits;
+
+   ASSERT_OUTSIDE_BEGIN_END( ctx, "glActiveTextureARB" );
+
+   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+      fprintf(stderr, "glActiveTexture %s\n", 
+             gl_lookup_enum_by_nr(target));
+
+   if (target >= GL_TEXTURE0_ARB && target < GL_TEXTURE0_ARB + maxUnits) {
+      GLint texUnit = target - GL_TEXTURE0_ARB;
+      ctx->TexCoordUnit = texUnit;
+      ctx->Texture.CurrentUnit = texUnit;
+      ctx->Texture.CurrentTransformUnit = texUnit;
+      if (ctx->Driver.ActiveTexture) {
+         (*ctx->Driver.ActiveTexture)( ctx, (GLuint) texUnit );
+      }
+   }
+   else {
+      gl_error(ctx, GL_INVALID_OPERATION, "glActiveTextureARB(target)");
+   }
+}
+
+
+/* GL_ARB_multitexture */
+void gl_ClientActiveTexture( GLcontext *ctx, GLenum target )
+{
+   GLint maxUnits = ctx->Const.MaxTextureUnits;
+
+   ASSERT_OUTSIDE_BEGIN_END( ctx, "glClientActiveTextureARB" );
+
+   if (target >= GL_TEXTURE0_ARB && target < GL_TEXTURE0_ARB + maxUnits) {
+      GLint texUnit = target - GL_TEXTURE0_ARB;
+      ctx->Array.ActiveTexture = texUnit;
+   }
+   else {
+      gl_error(ctx, GL_INVALID_OPERATION, "glActiveTextureARB(target)");
+   }
+}
+
+
+
+/*
+ * Put the given texture object into the list of dirty texture objects.
+ * When a texture object is dirty we have to reexamine it for completeness
+ * and perhaps choose a different texture sampling function.
+ */
+void gl_put_texobj_on_dirty_list( GLcontext *ctx, struct gl_texture_object *t )
+{
+   ASSERT(ctx);
+   ASSERT(t);
+   /* Only insert if not already in the dirty list.
+    * The Dirty flag is only set iff the texture object is in the dirty list.
+    */
+   if (!t->Dirty) {
+      ASSERT(t->NextDirty == NULL);
+      t->Dirty = GL_TRUE;
+      t->NextDirty = ctx->Shared->DirtyTexObjList;
+      ctx->Shared->DirtyTexObjList = t;
+   }
+#ifdef DEBUG
+   else {
+      /* make sure t is in the list */
+      struct gl_texture_object *obj = ctx->Shared->DirtyTexObjList;
+      while (obj) {
+         if (obj == t) {
+            return;
+         }
+         obj = obj->NextDirty;
+      }
+      gl_problem(ctx, "Error in gl_put_texobj_on_dirty_list");
+   }
+#endif
+}
+
+
+/*
+ * Remove a texture object from the dirty texture list.
+ */
+void gl_remove_texobj_from_dirty_list( struct gl_shared_state *shared,
+                                       struct gl_texture_object *tObj )
+{
+   struct gl_texture_object *t, *prev = NULL;
+   ASSERT(shared);
+   ASSERT(tObj);
+   for (t = shared->DirtyTexObjList; t; t = t->NextDirty) {
+      if (t == tObj) {
+         if (prev) {
+            prev->NextDirty = t->NextDirty;
+         }
+         else {
+            shared->DirtyTexObjList = t->NextDirty;
+         }
+         return;
+      }
+      prev = t;
+   }
+}
+
+
+/*
+ * This is called by gl_update_state() if the NEW_TEXTURING bit in
+ * ctx->NewState is unit.
+ */
+void gl_update_dirty_texobjs( GLcontext *ctx )
+{
+   struct gl_texture_object *t, *next;
+   for (t = ctx->Shared->DirtyTexObjList; t; t = next) {
+      next = t->NextDirty;
+      gl_test_texture_object_completeness(ctx, t);
+      gl_set_texture_sampler(t);
+      t->NextDirty = NULL;
+      t->Dirty = GL_FALSE;
+   }
+   ctx->Shared->DirtyTexObjList = NULL;
+}
diff --git a/src/mesa/main/texstate.h b/src/mesa/main/texstate.h
new file mode 100644 (file)
index 0000000..870693b
--- /dev/null
@@ -0,0 +1,112 @@
+/* $Id: texstate.h,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+#ifndef TEXSTATE_H
+#define TEXSTATE_H
+
+
+#include "types.h"
+
+
+/*** Called from API ***/
+
+extern void gl_GetTexEnvfv( GLcontext *ctx,
+                            GLenum target, GLenum pname, GLfloat *params );
+
+extern void gl_GetTexEnviv( GLcontext *ctx,
+                            GLenum target, GLenum pname, GLint *params );
+
+extern void gl_GetTexGendv( GLcontext *ctx,
+                            GLenum coord, GLenum pname, GLdouble *params );
+
+extern void gl_GetTexGenfv( GLcontext *ctx,
+                            GLenum coord, GLenum pname, GLfloat *params );
+
+extern void gl_GetTexGeniv( GLcontext *ctx,
+                            GLenum coord, GLenum pname, GLint *params );
+
+extern void gl_GetTexLevelParameterfv( GLcontext *ctx,
+                                       GLenum target, GLint level,
+                                       GLenum pname, GLfloat *params );
+
+extern void gl_GetTexLevelParameteriv( GLcontext *ctx,
+                                       GLenum target, GLint level,
+                                       GLenum pname, GLint *params );
+
+extern void gl_GetTexParameterfv( GLcontext *ctx, GLenum target,
+                                  GLenum pname, GLfloat *params );
+
+extern void gl_GetTexParameteriv( GLcontext *ctx,
+                                  GLenum target, GLenum pname, GLint *params );
+
+
+extern void gl_TexEnvfv( GLcontext *ctx,
+                         GLenum target, GLenum pname, const GLfloat *param );
+
+
+extern void gl_TexParameterfv( GLcontext *ctx, GLenum target, GLenum pname,
+                               const GLfloat *params );
+
+
+extern void gl_TexGenfv( GLcontext *ctx,
+                         GLenum coord, GLenum pname, const GLfloat *params );
+
+
+
+extern void gl_SelectTextureTransform( GLcontext *ctx, GLenum target );
+
+
+/*
+ * GL_ARB_multitexture
+ */
+extern void gl_ActiveTexture( GLcontext *ctx, GLenum target );
+
+extern void gl_ClientActiveTexture( GLcontext *ctx, GLenum target );
+
+
+
+/*** Internal functions ***/
+
+extern void 
+gl_put_texobj_on_dirty_list( GLcontext *ctx, struct gl_texture_object *t );
+
+#ifdef VMS
+#define gl_remove_texobj_from_dirty_list gl_remove_texobj_from_dirty_lis
+#endif
+extern void
+gl_remove_texobj_from_dirty_list( struct gl_shared_state *shared,
+                                  struct gl_texture_object *tObj );
+
+extern void
+gl_update_dirty_texobjs( GLcontext *ctx );
+
+
+#endif
+
diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c
new file mode 100644 (file)
index 0000000..b63d6a7
--- /dev/null
@@ -0,0 +1,1259 @@
+/* $Id: varray.c,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "context.h"
+#include "api.h"
+#include "cva.h"
+#include "enable.h"
+#include "enums.h"
+#include "dlist.h"
+#include "light.h"
+#include "macros.h"
+#include "mmath.h"
+#include "pipeline.h"
+#include "texstate.h"
+#include "translate.h"
+#include "types.h"
+#include "varray.h"
+#include "vb.h"
+#include "vbfill.h"
+#include "vbrender.h"
+#include "vbindirect.h"
+#include "vbxform.h"
+#include "xform.h"
+#ifdef XFree86Server
+#include "GL/xf86glx.h"
+#endif
+#endif
+
+
+void GLAPIENTRY glVertexPointer(CTX_ARG GLint size, GLenum type, GLsizei stride,
+                                 const GLvoid *ptr )
+{
+   GLcontext *ctx;
+   GET_CONTEXT;
+   CHECK_CONTEXT;
+   ctx = CC;
+   
+   if (size<2 || size>4) {
+      gl_error( ctx, GL_INVALID_VALUE, "glVertexPointer(size)" );
+      return;
+   }
+   if (stride<0) {
+      gl_error( ctx, GL_INVALID_VALUE, "glVertexPointer(stride)" );
+      return;
+   }
+   
+   if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
+      fprintf(stderr, "glVertexPointer( sz %d type %s stride %d )\n", size, 
+             gl_lookup_enum_by_nr( type ),
+             stride);
+
+   ctx->Array.Vertex.StrideB = stride;
+   if (!stride) {
+      switch (type) {
+      case GL_SHORT:
+         ctx->Array.Vertex.StrideB =  size*sizeof(GLshort);
+         break;
+      case GL_INT:
+         ctx->Array.Vertex.StrideB =  size*sizeof(GLint);
+         break;
+      case GL_FLOAT:
+         ctx->Array.Vertex.StrideB =  size*sizeof(GLfloat);
+         break;
+      case GL_DOUBLE:
+         ctx->Array.Vertex.StrideB =  size*sizeof(GLdouble);
+         break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glVertexPointer(type)" );
+         return;
+      }
+   }
+   ctx->Array.Vertex.Size = size;
+   ctx->Array.Vertex.Type = type;
+   ctx->Array.Vertex.Stride = stride;
+   ctx->Array.Vertex.Ptr = (void *) ptr;
+   ctx->Array.VertexFunc = gl_trans_4f_tab[size][TYPE_IDX(type)];
+   ctx->Array.VertexEltFunc = gl_trans_elt_4f_tab[size][TYPE_IDX(type)];
+   ctx->Array.NewArrayState |= VERT_OBJ_ANY;
+   ctx->NewState |= NEW_CLIENT_STATE;
+}
+
+
+
+
+void GLAPIENTRY glNormalPointer(CTX_ARG GLenum type, GLsizei stride,
+                                 const GLvoid *ptr )
+{
+   GLcontext *ctx;
+   GET_CONTEXT;
+   CHECK_CONTEXT;
+   ctx = CC;
+   
+   if (stride<0) {
+      gl_error( ctx, GL_INVALID_VALUE, "glNormalPointer(stride)" );
+      return;
+   }
+
+   if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
+      fprintf(stderr, "glNormalPointer( type %s stride %d )\n", 
+             gl_lookup_enum_by_nr( type ),
+             stride);
+
+   ctx->Array.Normal.StrideB = stride;
+   if (!stride) {
+      switch (type) {
+      case GL_BYTE:
+         ctx->Array.Normal.StrideB =  3*sizeof(GLbyte);
+         break;
+      case GL_SHORT:
+         ctx->Array.Normal.StrideB =  3*sizeof(GLshort);
+         break;
+      case GL_INT:
+         ctx->Array.Normal.StrideB =  3*sizeof(GLint);
+         break;
+      case GL_FLOAT:
+         ctx->Array.Normal.StrideB =  3*sizeof(GLfloat);
+         break;
+      case GL_DOUBLE:
+         ctx->Array.Normal.StrideB =  3*sizeof(GLdouble);
+         break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glNormalPointer(type)" );
+         return;
+      }
+   }
+   ctx->Array.Normal.Type = type;
+   ctx->Array.Normal.Stride = stride;
+   ctx->Array.Normal.Ptr = (void *) ptr;
+   ctx->Array.NormalFunc = gl_trans_3f_tab[TYPE_IDX(type)];
+   ctx->Array.NormalEltFunc = gl_trans_elt_3f_tab[TYPE_IDX(type)];
+   ctx->Array.NewArrayState |= VERT_NORM;
+   ctx->NewState |= NEW_CLIENT_STATE;
+}
+
+
+
+void GLAPIENTRY glColorPointer(CTX_ARG GLint size, GLenum type, GLsizei stride,
+                                const GLvoid *ptr )
+{
+   GLcontext *ctx;
+   GET_CONTEXT;
+   CHECK_CONTEXT;
+   ctx = CC;
+   if (size<3 || size>4) {
+      gl_error( ctx, GL_INVALID_VALUE, "glColorPointer(size)" );
+      return;
+   }
+   if (stride<0) {
+      gl_error( ctx, GL_INVALID_VALUE, "glColorPointer(stride)" );
+      return;
+   }
+
+   if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
+      fprintf(stderr, "glColorPointer( sz %d type %s stride %d )\n", size, 
+         gl_lookup_enum_by_nr( type ),
+         stride);
+
+   ctx->Array.Color.StrideB = stride;
+   if (!stride) {
+      switch (type) {
+      case GL_BYTE:
+         ctx->Array.Color.StrideB =  size*sizeof(GLbyte);
+         break;
+      case GL_UNSIGNED_BYTE:
+         ctx->Array.Color.StrideB =  size*sizeof(GLubyte);
+         break;
+      case GL_SHORT:
+         ctx->Array.Color.StrideB =  size*sizeof(GLshort);
+         break;
+      case GL_UNSIGNED_SHORT:
+         ctx->Array.Color.StrideB =  size*sizeof(GLushort);
+         break;
+      case GL_INT:
+         ctx->Array.Color.StrideB =  size*sizeof(GLint);
+         break;
+      case GL_UNSIGNED_INT:
+         ctx->Array.Color.StrideB =  size*sizeof(GLuint);
+         break;
+      case GL_FLOAT:
+         ctx->Array.Color.StrideB =  size*sizeof(GLfloat);
+         break;
+      case GL_DOUBLE:
+         ctx->Array.Color.StrideB =  size*sizeof(GLdouble);
+         break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glColorPointer(type)" );
+         return;
+      }
+   }
+   ctx->Array.Color.Size = size;
+   ctx->Array.Color.Type = type;
+   ctx->Array.Color.Stride = stride;
+   ctx->Array.Color.Ptr = (void *) ptr;
+   ctx->Array.ColorFunc = gl_trans_4ub_tab[size][TYPE_IDX(type)];
+   ctx->Array.ColorEltFunc = gl_trans_elt_4ub_tab[size][TYPE_IDX(type)];
+   ctx->Array.NewArrayState |= VERT_RGBA;
+   ctx->NewState |= NEW_CLIENT_STATE;
+}
+
+
+
+void GLAPIENTRY glIndexPointer(CTX_ARG GLenum type, GLsizei stride,
+                                const GLvoid *ptr )
+{
+   GLcontext *ctx;
+   GET_CONTEXT;
+   CHECK_CONTEXT;
+   ctx = CC;
+   
+   if (stride<0) {
+      gl_error( ctx, GL_INVALID_VALUE, "glIndexPointer(stride)" );
+      return;
+   }
+
+   ctx->Array.Index.StrideB = stride;
+   if (!stride) {
+      switch (type) {
+      case GL_UNSIGNED_BYTE:
+         ctx->Array.Index.StrideB =  sizeof(GLubyte);
+         break;
+      case GL_SHORT:
+         ctx->Array.Index.StrideB =  sizeof(GLshort);
+         break;
+      case GL_INT:
+         ctx->Array.Index.StrideB =  sizeof(GLint);
+         break;
+      case GL_FLOAT:
+         ctx->Array.Index.StrideB =  sizeof(GLfloat);
+         break;
+      case GL_DOUBLE:
+         ctx->Array.Index.StrideB =  sizeof(GLdouble);
+         break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glIndexPointer(type)" );
+         return;
+      }
+   }
+   ctx->Array.Index.Type = type;
+   ctx->Array.Index.Stride = stride;
+   ctx->Array.Index.Ptr = (void *) ptr;
+   ctx->Array.IndexFunc = gl_trans_1ui_tab[TYPE_IDX(type)];
+   ctx->Array.IndexEltFunc = gl_trans_elt_1ui_tab[TYPE_IDX(type)];
+   ctx->Array.NewArrayState |= VERT_INDEX;
+   ctx->NewState |= NEW_CLIENT_STATE;
+}
+
+
+
+void GLAPIENTRY glTexCoordPointer(CTX_ARG GLint size, GLenum type,
+                                   GLsizei stride, const GLvoid *ptr )
+{
+   GLuint texUnit;
+   
+   GLcontext *ctx;
+   GET_CONTEXT;
+   CHECK_CONTEXT;
+   ctx = CC;
+   
+   texUnit = ctx->TexCoordUnit;
+
+   if (size<1 || size>4) {
+      gl_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(size)" );
+      return;
+   }
+   if (stride<0) {
+      gl_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(stride)" );
+      return;
+   }
+
+   if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
+      fprintf(stderr, "glTexCoordPointer( unit %u sz %d type %s stride %d )\n", 
+         texUnit,
+         size, 
+         gl_lookup_enum_by_nr( type ),
+         stride);
+
+   ctx->Array.TexCoord[texUnit].StrideB = stride;
+   if (!stride) {
+      switch (type) {
+      case GL_SHORT:
+         ctx->Array.TexCoord[texUnit].StrideB =  size*sizeof(GLshort);
+         break;
+      case GL_INT:
+         ctx->Array.TexCoord[texUnit].StrideB =  size*sizeof(GLint);
+         break;
+      case GL_FLOAT:
+         ctx->Array.TexCoord[texUnit].StrideB =  size*sizeof(GLfloat);
+         break;
+      case GL_DOUBLE:
+         ctx->Array.TexCoord[texUnit].StrideB =  size*sizeof(GLdouble);
+         break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glTexCoordPointer(type)" );
+         return;
+      }
+   }
+   ctx->Array.TexCoord[texUnit].Size = size;
+   ctx->Array.TexCoord[texUnit].Type = type;
+   ctx->Array.TexCoord[texUnit].Stride = stride;
+   ctx->Array.TexCoord[texUnit].Ptr = (void *) ptr;
+
+   ctx->Array.TexCoordFunc[texUnit] = gl_trans_4f_tab[size][TYPE_IDX(type)];
+   ctx->Array.TexCoordEltFunc[texUnit] = gl_trans_elt_4f_tab[size][TYPE_IDX(type)];
+   ctx->Array.NewArrayState |= PIPE_TEX(texUnit);
+   ctx->NewState |= NEW_CLIENT_STATE;
+}
+
+
+
+
+void GLAPIENTRY glEdgeFlagPointer(CTX_ARG GLsizei stride, const void *vptr )
+{
+   const GLboolean *ptr = (GLboolean *)vptr;
+   
+   GLcontext *ctx;
+   GET_CONTEXT;
+   CHECK_CONTEXT;
+   ctx = CC;
+
+   if (stride<0) {
+      gl_error( ctx, GL_INVALID_VALUE, "glEdgeFlagPointer(stride)" );
+      return;
+   }
+   ctx->Array.EdgeFlag.Stride = stride;
+   ctx->Array.EdgeFlag.StrideB = stride ? stride : sizeof(GLboolean);
+   ctx->Array.EdgeFlag.Ptr = (GLboolean *) ptr;
+   if (stride != sizeof(GLboolean)) {
+      ctx->Array.EdgeFlagFunc = gl_trans_1ub_tab[TYPE_IDX(GL_UNSIGNED_BYTE)];
+   } else {
+      ctx->Array.EdgeFlagFunc = 0;
+   }
+   ctx->Array.EdgeFlagEltFunc = gl_trans_elt_1ub_tab[TYPE_IDX(GL_UNSIGNED_BYTE)];
+   ctx->Array.NewArrayState |= VERT_EDGE;
+   ctx->NewState |= NEW_CLIENT_STATE;
+}
+
+
+/* Called only from gl_DrawElements
+ */
+void gl_CVAEltPointer( GLcontext *ctx, GLenum type, const GLvoid *ptr )
+{
+   switch (type) {
+      case GL_UNSIGNED_BYTE:
+         ctx->CVA.Elt.StrideB = sizeof(GLubyte);
+         break;
+      case GL_UNSIGNED_SHORT:
+         ctx->CVA.Elt.StrideB = sizeof(GLushort);
+         break;
+      case GL_UNSIGNED_INT:
+         ctx->CVA.Elt.StrideB = sizeof(GLuint);
+         break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glEltPointer(type)" );
+         return;
+   }
+   ctx->CVA.Elt.Type = type;
+   ctx->CVA.Elt.Stride = 0;
+   ctx->CVA.Elt.Ptr = (void *) ptr;
+   ctx->CVA.EltFunc = gl_trans_1ui_tab[TYPE_IDX(type)];
+   ctx->Array.NewArrayState |= VERT_ELT; /* ??? */
+}
+
+
+
+/* KW: Batch function to exec all the array elements in the input
+ *     buffer prior to transform.  Done only the first time a vertex
+ *     buffer is executed or compiled.
+ */
+void gl_exec_array_elements( GLcontext *ctx, struct immediate *IM )
+{
+   GLuint *flags = IM->Flag;
+   GLuint *elts = IM->Elt;
+   GLuint count = IM->Count;
+   GLuint start = IM->Start;
+   GLuint translate = ctx->Array.Flags;
+   GLuint i;
+   
+   if (translate & VERT_OBJ_ANY) 
+      (ctx->Array.VertexEltFunc)( IM->Obj, 
+                                 &ctx->Array.Vertex, 
+                                 flags, elts, VERT_ELT,
+                                 start, count);
+   
+   if (translate & VERT_NORM) 
+      (ctx->Array.NormalEltFunc)( IM->Normal, 
+                                 &ctx->Array.Normal, 
+                                 flags, elts, (VERT_ELT|VERT_NORM),
+                                 start, count);
+
+   if (translate & VERT_EDGE) 
+      (ctx->Array.EdgeFlagEltFunc)( IM->EdgeFlag, 
+                                   &ctx->Array.EdgeFlag, 
+                                   flags, elts, (VERT_ELT|VERT_EDGE),
+                                   start, count);
+   
+   if (translate & VERT_RGBA)
+      (ctx->Array.ColorEltFunc)( IM->Color, 
+                                &ctx->Array.Color, 
+                                flags, elts, (VERT_ELT|VERT_RGBA),
+                                start, count);
+
+   if (translate & VERT_INDEX)
+      (ctx->Array.IndexEltFunc)( IM->Index, 
+                                &ctx->Array.Index, 
+                                flags, elts, (VERT_ELT|VERT_INDEX),
+                                start, count);
+
+   if (translate & VERT_TEX0_ANY)
+      (ctx->Array.TexCoordEltFunc[0])( IM->TexCoord[0], 
+                                      &ctx->Array.TexCoord[0], 
+                                      flags, elts, (VERT_ELT|VERT_TEX0_ANY),
+                                      start, count);
+
+   if (translate & VERT_TEX1_ANY)
+      (ctx->Array.TexCoordEltFunc[1])( IM->TexCoord[1], 
+                                      &ctx->Array.TexCoord[1], 
+                                      flags, elts, (VERT_ELT|VERT_TEX1_ANY),
+                                      start, count);
+
+   IM->OrFlag |= translate;
+
+   /* Lighting ignores the and-flag, so still need to do this.
+    */
+   if (IM->AndFlag & VERT_ELT) {
+      for (i = 0 ; i < count ; i++) 
+        flags[i] |= translate;
+      IM->AndFlag |= translate; 
+   } else {
+      GLuint andflag = ~0;
+      for (i = 0 ; i < count ; i++) {
+        if (flags[i] & VERT_ELT) flags[i] |= translate;
+        andflag &= flags[i];
+      }
+      IM->AndFlag = andflag;
+   }
+}
+
+
+
+/* KW:  I think this is moving in the right direction, but it still feels 
+ *      like we are doing way too much work.
+ */
+void gl_DrawArrays( GLcontext *ctx, GLenum mode, GLint start, GLsizei count )
+{
+   struct vertex_buffer *VB = ctx->VB;
+   GLint i;
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDrawArrays");
+
+   if (count<0) {
+      gl_error( ctx, GL_INVALID_VALUE, "glDrawArrays(count)" );
+      return;
+   }
+
+   if (!ctx->CompileFlag && ctx->Array.Vertex.Enabled)
+   {
+      GLint remaining = count;
+      GLint i;
+      GLvector4f obj;
+      GLvector3f norm;
+      GLvector4f tc[MAX_TEXTURE_UNITS];
+      GLvector4ub col;
+      GLvector1ub edge;
+      GLvector1ui index;
+      GLuint update = 0, translate = 0;
+      struct vertex_array_pointers VSrc;
+      struct immediate *IM = VB->IM;
+      struct gl_client_array *client_data;
+      struct gl_pipeline *elt = &ctx->CVA.elt;
+      GLuint relock;
+      GLuint fallback, required;
+
+      if (ctx->NewState)
+        gl_update_state( ctx );        
+
+      /* This will die miserably with CVA...  Need more work to support this.
+       */
+      relock = ctx->CompileCVAFlag;
+      ctx->CompileCVAFlag = 0;
+
+      if (!elt->pipeline_valid || relock)
+        gl_build_immediate_pipeline( ctx );
+
+      required = elt->inputs;
+      fallback = (elt->inputs & ~ctx->Array.Summary);
+
+      VSrc.Color = &IM->v.Color;
+      VSrc.Index = &IM->v.Index;
+      VSrc.EdgeFlag = &IM->v.EdgeFlag;
+      VSrc.TexCoord[0] = &IM->v.TexCoord[0];
+      VSrc.TexCoord[1] = &IM->v.TexCoord[1];
+      VSrc.Obj = &IM->v.Obj;
+      VSrc.Normal = &IM->v.Normal;
+
+      if (required & VERT_RGBA) 
+      {
+        client_data = &ctx->Array.Color;
+        if (fallback & VERT_RGBA)
+           client_data = &ctx->Fallback.Color;
+
+        if (client_data->Type == GL_UNSIGNED_BYTE && 
+            client_data->Size == 4)
+        {
+           VSrc.Color = &col;
+           col.data = (GLubyte (*)[4]) client_data->Ptr;
+           col.stride = client_data->StrideB;
+           col.flags = VEC_NOT_WRITABLE|VEC_GOOD_STRIDE;
+           if (client_data->StrideB != 4 * sizeof(GLubyte)) 
+              col.flags ^= VEC_STRIDE_FLAGS;
+
+           update |= VERT_RGBA;
+        } else {
+           translate |= VERT_RGBA;
+        }      
+      }
+   
+      if (required & VERT_INDEX) 
+      {
+        client_data = &ctx->Array.Index;
+        if (fallback & VERT_INDEX)
+           client_data = &ctx->Fallback.Index;
+
+        if (client_data->Type == GL_UNSIGNED_INT)
+        {
+           VSrc.Index = &index;
+           index.data = (GLuint *) client_data->Ptr;
+           index.stride = client_data->StrideB;
+           index.flags = VEC_NOT_WRITABLE|VEC_GOOD_STRIDE;
+           if (client_data->StrideB != sizeof(GLuint)) 
+              index.flags ^= VEC_STRIDE_FLAGS;
+
+           update |= VERT_INDEX;
+        } else {
+           translate |= VERT_INDEX;
+        }      
+      }
+
+      for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++) 
+      {
+        GLuint flag = VERT_TEX_ANY(i);
+
+        if (required & flag) {
+
+           client_data = &ctx->Array.TexCoord[i];
+
+           if (fallback & flag) 
+           {
+              client_data = &ctx->Fallback.TexCoord[i];
+              client_data->Size = gl_texcoord_size( ctx->Current.Flag, i );
+           }
+
+           if (client_data->Type == GL_FLOAT)
+           {
+              VSrc.TexCoord[i] = &tc[i];
+              tc[i].data = (GLfloat (*)[4]) client_data->Ptr;
+              tc[i].stride = client_data->StrideB;
+              tc[i].size = client_data->Size;
+              tc[i].flags = VEC_NOT_WRITABLE|VEC_GOOD_STRIDE;
+              if (tc[i].stride |= 4 * sizeof(GLfloat))
+                 tc[i].flags ^= VEC_STRIDE_FLAGS;
+              update |= flag;
+           } else {
+              translate |= flag;
+           }
+        }
+      }
+
+      if (ctx->Array.Flags != ctx->Array.Flag[0])
+        for (i = 0 ; i < VB_MAX ; i++) 
+           ctx->Array.Flag[i] = ctx->Array.Flags;
+
+      
+      if (ctx->Array.Vertex.Type == GL_FLOAT)
+      {
+        VSrc.Obj = &obj;
+        obj.data = (GLfloat (*)[4]) ctx->Array.Vertex.Ptr;
+        obj.stride = ctx->Array.Vertex.StrideB;
+        obj.size = ctx->Array.Vertex.Size;
+        obj.flags = VEC_NOT_WRITABLE|VEC_GOOD_STRIDE;
+        if (obj.stride != 4 * sizeof(GLfloat)) 
+           obj.flags ^= VEC_STRIDE_FLAGS;
+
+        update |= VERT_OBJ_ANY;
+      }
+      else 
+      {
+        translate |= VERT_OBJ_ANY;
+      }
+
+      if (required & VERT_NORM) 
+      {
+        client_data = &ctx->Array.Normal;
+        if (fallback & VERT_NORM) 
+           client_data = &ctx->Fallback.Normal;
+
+        if (client_data->Type == GL_FLOAT) 
+        {
+           VSrc.Normal = &norm;
+           norm.flags = 0;
+           norm.data = (GLfloat (*)[3]) client_data->Ptr;
+           norm.stride = client_data->StrideB;
+           update |= VERT_NORM;            
+        } else {
+           translate |= VERT_NORM;         
+        }
+      }
+
+      if ( (required & VERT_EDGE) && 
+          (mode == GL_TRIANGLES || 
+           mode == GL_QUADS || 
+           mode == GL_POLYGON)) 
+      {
+        client_data = &ctx->Array.EdgeFlag;
+
+        if (fallback & VERT_EDGE) 
+           client_data = &ctx->Fallback.EdgeFlag;
+
+        VSrc.EdgeFlag = &edge;
+        edge.data = (GLboolean *) client_data->Ptr;
+        edge.stride = client_data->StrideB;
+        edge.flags = VEC_NOT_WRITABLE|VEC_GOOD_STRIDE;
+        if (edge.stride != sizeof(GLubyte))
+           edge.flags ^= VEC_STRIDE_FLAGS;
+        
+        update |= VERT_EDGE;
+      }
+
+      VB->Primitive = IM->Primitive; 
+      VB->NextPrimitive = IM->NextPrimitive; 
+      VB->MaterialMask = IM->MaterialMask;
+      VB->Material = IM->Material;
+      VB->BoundsPtr = 0;
+
+      while (remaining > 0) {
+         GLint vbspace = VB_MAX - VB_START;
+        GLuint count, n;
+        
+
+        if (vbspace >= remaining) {
+           n = remaining;
+           VB->LastPrimitive = VB_START + n;
+        } else {
+           n = vbspace;
+           VB->LastPrimitive = VB_START;
+        }
+        
+        VB->CullMode = 0;
+        
+
+         /* Update pointers.
+         */
+        if (update) {
+           if (update & VERT_OBJ_ANY) 
+              obj.start = VEC_ELT(&obj, GLfloat, start);
+           
+           if (update & VERT_NORM) 
+              norm.start = VEC_ELT(&norm, GLfloat, start);
+
+           if (update & VERT_EDGE) 
+              edge.start = VEC_ELT(&edge, GLubyte, start);
+
+           if (update & VERT_RGBA) 
+              col.start = VEC_ELT(&col, GLubyte, start);
+
+           if (update & VERT_INDEX) 
+              index.start = VEC_ELT(&index, GLuint, start);
+
+           if (update & VERT_TEX0_ANY) 
+              tc[0].start = VEC_ELT(&tc[0], GLfloat, start);
+
+           if (update & VERT_TEX1_ANY) 
+              tc[1].start = VEC_ELT(&tc[1], GLfloat, start);
+        }
+
+
+        /* Translate data to fix up type and stride.
+         */
+        if (translate) {
+           if (translate & VERT_OBJ_ANY) {
+              ctx->Array.VertexFunc( IM->Obj + VB_START, 
+                                     &ctx->Array.Vertex, start, n );
+           }
+
+           if (translate & VERT_NORM) {
+              ctx->Array.NormalFunc( IM->Normal + VB_START, 
+                                     &ctx->Array.Normal, start, n );
+           }
+
+           if (translate & VERT_EDGE) {
+              ctx->Array.EdgeFlagFunc( IM->EdgeFlag + VB_START, 
+                                       &ctx->Array.EdgeFlag, start, n );
+           }
+
+           if (translate & VERT_RGBA) {
+              ctx->Array.ColorFunc( IM->Color + VB_START, 
+                                    &ctx->Array.Color, start, n );
+           }
+
+           if (translate & VERT_INDEX) {
+              ctx->Array.IndexFunc( IM->Index + VB_START, 
+                                    &ctx->Array.Index, start, n );
+           }
+
+           if (translate & VERT_TEX0_ANY) {
+              IM->v.TexCoord[0].size = tc[0].size;
+              ctx->Array.TexCoordFunc[0]( IM->TexCoord[0] + VB_START, 
+                                          &ctx->Array.TexCoord[0], start, n );
+           }
+
+           if (translate & VERT_TEX1_ANY) {
+              IM->v.TexCoord[1].size = tc[1].size;
+              ctx->Array.TexCoordFunc[1]( IM->TexCoord[1] + VB_START, 
+                                          &ctx->Array.TexCoord[1], start, n );
+           }
+        }
+
+
+        VB->ObjPtr = VSrc.Obj;
+        VB->NormalPtr = VSrc.Normal;
+        VB->Color[0] = VB->Color[1] = VB->ColorPtr = VSrc.Color;
+        VB->IndexPtr = VSrc.Index;
+        VB->EdgeFlagPtr = VSrc.EdgeFlag;
+        VB->TexCoordPtr[0] = VSrc.TexCoord[0];
+        VB->TexCoordPtr[1] = VSrc.TexCoord[1];
+
+        VB->Flag = ctx->Array.Flag;
+        VB->AndFlag = ctx->Array.Flags;
+        VB->OrFlag = ctx->Array.Flags;
+
+        count = VB->Count = VB_START + n;
+
+        VB->ObjPtr->count = count;
+        VB->NormalPtr->count = count;
+        VB->ColorPtr->count = count;
+        VB->IndexPtr->count = count;
+        VB->EdgeFlagPtr->count = count;
+        VB->TexCoordPtr[0]->count = count;
+        VB->TexCoordPtr[1]->count = count;
+
+        VB->Flag[count] |= VERT_END_VB;
+        VB->Flag[VB_START] |= VERT_NORM;
+/*      VB->Flag[VB_START] |= (IM->Flag[vb_start] & VERT_MATERIAL); */
+
+        VB->NextPrimitive[VB->CopyStart] = VB->Count;
+        VB->Primitive[VB->CopyStart] = mode;
+
+         /* Transform and render.
+         */
+         gl_run_pipeline( VB );
+        gl_reset_vb( VB );
+
+        ctx->Array.Flag[count] = ctx->Array.Flags;
+        ctx->Array.Flag[VB_START] = ctx->Array.Flags;
+        IM->Flag[VB_START] = 0;
+
+         start += n;
+         remaining -= n;
+      }
+
+      ctx->CompileCVAFlag = relock;
+   }
+   else if (ctx->Array.Vertex.Enabled) 
+   {
+      /* The GL_COMPILE and GL_COMPILE_AND_EXECUTE cases.  These
+       * could be handled by the above code, but it gets a little
+       * complex.  
+       */
+      /* No need to reset - never called from inside a display list */
+      gl_Begin( ctx, mode );
+      for (i=0;i<count;i++) {
+         gl_ArrayElement( ctx, start+i );
+      }
+      gl_End( ctx );
+   }
+   else
+   {
+      /* The degenerate case where vertices are not enabled - only
+       * need to process the very final array element, as all of the
+       * preceding ones would be overwritten anyway. 
+       */
+      gl_Begin( ctx, mode );
+      gl_ArrayElement( ctx, start+count );
+      gl_End( ctx );
+   }
+}
+
+
+
+/* KW: Exactly fakes the effects of calling glArrayElement multiple times.
+ *     Compilation is handled via. the IM->maybe_transform_vb() callback.
+ */
+#define DRAW_ELT(FUNC, TYPE)                           \
+static void FUNC( GLcontext *ctx, GLenum mode,         \
+                 TYPE *indices, GLuint count )         \
+{                                                      \
+   GLuint i,j;                                         \
+                                                       \
+   if (count) gl_Begin( ctx, mode );                   \
+                                                       \
+   for (j = 0 ; j < count ; ) {                                \
+      GLuint nr = MIN2( VB_MAX, count - j + VB_START );        \
+      struct immediate *IM = ctx->input;               \
+      GLuint sf = IM->Flag[VB_START];                  \
+      GLuint flags = IM->ArrayOrFlags;                 \
+                                                       \
+      for (i = VB_START ; i < nr ; i++) {              \
+        IM->Elt[i] = (GLuint) *indices++;              \
+        IM->Flag[i] = flags;                           \
+      }                                                        \
+                                                       \
+      if (j == 0) IM->Flag[VB_START] |= sf;            \
+                                                       \
+      IM->Count = nr;                                  \
+      j += nr - VB_START;                              \
+                                                       \
+      if (j == count) gl_End( ctx );                   \
+                                                       \
+      IM->maybe_transform_vb( IM );                    \
+   }                                                   \
+}
+
+DRAW_ELT( draw_elt_ubyte, GLubyte )
+DRAW_ELT( draw_elt_ushort, GLushort )
+DRAW_ELT( draw_elt_uint, GLuint )
+
+
+static GLuint natural_stride[0x10] = 
+{
+   sizeof(GLbyte),             /* 0 */
+   sizeof(GLubyte),            /* 1 */
+   sizeof(GLshort),            /* 2 */
+   sizeof(GLushort),           /* 3 */
+   sizeof(GLint),              /* 4 */
+   sizeof(GLuint),             /* 5 */
+   sizeof(GLfloat),            /* 6 */
+   2 * sizeof(GLbyte),         /* 7 */
+   3 * sizeof(GLbyte),         /* 8 */
+   4 * sizeof(GLbyte),         /* 9 */
+   sizeof(GLdouble),           /* a */
+   0,                          /* b */
+   0,                          /* c */
+   0,                          /* d */
+   0,                          /* e */
+   0                           /* f */
+};
+
+void GLAPIENTRY glDrawElements(CTX_ARG GLenum mode, GLsizei count,
+                                GLenum type, const GLvoid *indices )
+{
+   GLcontext *ctx;
+   struct gl_cva *cva;
+      
+   GET_CONTEXT;
+   CHECK_CONTEXT;
+   ctx = CC;
+
+   cva = &ctx->CVA;
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDrawElements");
+
+   if (count<0) {
+      gl_error( ctx, GL_INVALID_VALUE, "glDrawElements(count)" );
+      return;
+   }
+
+   if (mode < 0 || mode > GL_POLYGON) {
+      gl_error( ctx, GL_INVALID_ENUM, "glDrawArrays(mode)" );
+      return;
+   }
+   
+   if (type != GL_UNSIGNED_INT && type != GL_UNSIGNED_BYTE && type != GL_UNSIGNED_SHORT)
+   {
+       gl_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" );
+       return;
+   }
+
+   if (ctx->NewState)
+      gl_update_state(ctx);
+
+   if (ctx->CompileCVAFlag) 
+   {
+#if defined(MESA_CVA_PROF)
+      force_init_prof(); 
+#endif
+
+      /* Treat VERT_ELT like a special client array.
+       */
+      ctx->Array.NewArrayState |= VERT_ELT;
+      ctx->Array.Summary |= VERT_ELT;
+      ctx->Array.Flags |= VERT_ELT;
+
+      cva->elt_mode = mode;
+      cva->elt_count = count;
+      cva->Elt.Type = type;
+      cva->Elt.Ptr = (void *) indices;
+      cva->Elt.StrideB = natural_stride[TYPE_IDX(type)];
+      cva->EltFunc = gl_trans_1ui_tab[TYPE_IDX(type)];
+
+      if (!cva->pre.pipeline_valid) 
+        gl_build_precalc_pipeline( ctx );
+      else if (MESA_VERBOSE & VERBOSE_PIPELINE)
+        fprintf(stderr, ": dont rebuild\n");
+
+      gl_cva_force_precalc( ctx );
+
+      /* Did we 'precalculate' the render op?
+       */
+      if (ctx->CVA.pre.ops & PIPE_OP_RENDER) {
+        ctx->Array.NewArrayState |= VERT_ELT;
+        ctx->Array.Summary &= ~VERT_ELT;
+        ctx->Array.Flags &= ~VERT_ELT;
+        return;
+      } 
+
+      if ( (MESA_VERBOSE&VERBOSE_VARRAY) )
+        printf("using immediate\n");
+   }
+
+
+   /* Otherwise, have to use the immediate path to render.
+    */
+   switch (type) {
+   case GL_UNSIGNED_BYTE:
+   {
+      GLubyte *ub_indices = (GLubyte *) indices;
+      if (ctx->Array.Summary & VERT_OBJ_ANY) {
+        draw_elt_ubyte( ctx, mode, ub_indices, count );
+      } else {
+        gl_ArrayElement( ctx, (GLuint) ub_indices[count-1] );
+      }
+   }
+   break;
+   case GL_UNSIGNED_SHORT:
+   {
+      GLushort *us_indices = (GLushort *) indices;
+      if (ctx->Array.Summary & VERT_OBJ_ANY) {
+        draw_elt_ushort( ctx, mode, us_indices, count );
+      } else {
+        gl_ArrayElement( ctx, (GLuint) us_indices[count-1] );
+      }
+   }
+   break;
+   case GL_UNSIGNED_INT:
+   {
+      GLuint *ui_indices = (GLuint *) indices;
+      if (ctx->Array.Summary & VERT_OBJ_ANY) {
+        draw_elt_uint( ctx, mode, ui_indices, count );
+      } else {
+        gl_ArrayElement( ctx, ui_indices[count-1] );
+      }
+   }
+   break;
+   default:
+      gl_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" );
+      break;
+   }
+
+   if (ctx->CompileCVAFlag) {
+      ctx->Array.NewArrayState |= VERT_ELT;
+      ctx->Array.Summary &= ~VERT_ELT;
+   }
+}
+
+
+
+void GLAPIENTRY glInterleavedArrays(CTX_ARG GLenum format, GLsizei stride,
+                                     const GLvoid *pointer )
+{
+   GLcontext *ctx;
+   GLboolean tflag, cflag, nflag;  /* enable/disable flags */
+   GLint tcomps, ccomps, vcomps;   /* components per texcoord, color, vertex */
+
+   GLenum ctype;                   /* color type */
+   GLint coffset, noffset, voffset;/* color, normal, vertex offsets */
+   GLint defstride;                /* default stride */
+   GLint c, f;
+   GLint coordUnitSave;
+   
+   GET_CONTEXT;
+   CHECK_CONTEXT;
+   ctx = CC;
+
+
+   f = sizeof(GLfloat);
+   c = f * ((4*sizeof(GLubyte) + (f-1)) / f);
+
+   if (stride<0) {
+      gl_error( ctx, GL_INVALID_VALUE, "glInterleavedArrays(stride)" );
+      return;
+   }
+
+   switch (format) {
+      case GL_V2F:
+         tflag = GL_FALSE;  cflag = GL_FALSE;  nflag = GL_FALSE;
+         tcomps = 0;  ccomps = 0;  vcomps = 2;
+         voffset = 0;
+         defstride = 2*f;
+         break;
+      case GL_V3F:
+         tflag = GL_FALSE;  cflag = GL_FALSE;  nflag = GL_FALSE;
+         tcomps = 0;  ccomps = 0;  vcomps = 3;
+         voffset = 0;
+         defstride = 3*f;
+         break;
+      case GL_C4UB_V2F:
+         tflag = GL_FALSE;  cflag = GL_TRUE;  nflag = GL_FALSE;
+         tcomps = 0;  ccomps = 4;  vcomps = 2;
+         ctype = GL_UNSIGNED_BYTE;
+         coffset = 0;
+         voffset = c;
+         defstride = c + 2*f;
+         break;
+      case GL_C4UB_V3F:
+         tflag = GL_FALSE;  cflag = GL_TRUE;  nflag = GL_FALSE;
+         tcomps = 0;  ccomps = 4;  vcomps = 3;
+         ctype = GL_UNSIGNED_BYTE;
+         coffset = 0;
+         voffset = c;
+         defstride = c + 3*f;
+         break;
+      case GL_C3F_V3F:
+         tflag = GL_FALSE;  cflag = GL_TRUE;  nflag = GL_FALSE;
+         tcomps = 0;  ccomps = 3;  vcomps = 3;
+         ctype = GL_FLOAT;
+         coffset = 0;
+         voffset = 3*f;
+         defstride = 6*f;
+         break;
+      case GL_N3F_V3F:
+         tflag = GL_FALSE;  cflag = GL_FALSE;  nflag = GL_TRUE;
+         tcomps = 0;  ccomps = 0;  vcomps = 3;
+         noffset = 0;
+         voffset = 3*f;
+         defstride = 6*f;
+         break;
+      case GL_C4F_N3F_V3F:
+         tflag = GL_FALSE;  cflag = GL_TRUE;  nflag = GL_TRUE;
+         tcomps = 0;  ccomps = 4;  vcomps = 3;
+         ctype = GL_FLOAT;
+         coffset = 0;
+         noffset = 4*f;
+         voffset = 7*f;
+         defstride = 10*f;
+         break;
+      case GL_T2F_V3F:
+         tflag = GL_TRUE;  cflag = GL_FALSE;  nflag = GL_FALSE;
+         tcomps = 2;  ccomps = 0;  vcomps = 3;
+         voffset = 2*f;
+         defstride = 5*f;
+         break;
+      case GL_T4F_V4F:
+         tflag = GL_TRUE;  cflag = GL_FALSE;  nflag = GL_FALSE;
+         tcomps = 4;  ccomps = 0;  vcomps = 4;
+         voffset = 4*f;
+         defstride = 8*f;
+         break;
+      case GL_T2F_C4UB_V3F:
+         tflag = GL_TRUE;  cflag = GL_TRUE;  nflag = GL_FALSE;
+         tcomps = 2;  ccomps = 4;  vcomps = 3;
+         ctype = GL_UNSIGNED_BYTE;
+         coffset = 2*f;
+         voffset = c+2*f;
+         defstride = c+5*f;
+         break;
+      case GL_T2F_C3F_V3F:
+         tflag = GL_TRUE;  cflag = GL_TRUE;  nflag = GL_FALSE;
+         tcomps = 2;  ccomps = 3;  vcomps = 3;
+         ctype = GL_FLOAT;
+         coffset = 2*f;
+         voffset = 5*f;
+         defstride = 8*f;
+         break;
+      case GL_T2F_N3F_V3F:
+         tflag = GL_TRUE;  cflag = GL_FALSE;  nflag = GL_TRUE;
+         tcomps = 2;  ccomps = 0;  vcomps = 3;
+         noffset = 2*f;
+         voffset = 5*f;
+         defstride = 8*f;
+         break;
+      case GL_T2F_C4F_N3F_V3F:
+         tflag = GL_TRUE;  cflag = GL_TRUE;  nflag = GL_TRUE;
+         tcomps = 2;  ccomps = 4;  vcomps = 3;
+         ctype = GL_FLOAT;
+         coffset = 2*f;
+         noffset = 6*f;
+         voffset = 9*f;
+         defstride = 12*f;
+         break;
+      case GL_T4F_C4F_N3F_V4F:
+         tflag = GL_TRUE;  cflag = GL_TRUE;  nflag = GL_TRUE;
+         tcomps = 4;  ccomps = 4;  vcomps = 4;
+         ctype = GL_FLOAT;
+         coffset = 4*f;
+         noffset = 8*f;
+         voffset = 11*f;
+         defstride = 15*f;
+         break;
+      default:
+         gl_error( ctx, GL_INVALID_ENUM, "glInterleavedArrays(format)" );
+         return;
+   }
+
+   if (stride==0) {
+      stride = defstride;
+   }
+
+   gl_DisableClientState( ctx, GL_EDGE_FLAG_ARRAY );
+   gl_DisableClientState( ctx, GL_INDEX_ARRAY );
+
+   /* Texcoords */
+   coordUnitSave = ctx->TexCoordUnit;
+   if (tflag) {
+      GLint i;
+      GLint factor = ctx->Array.TexCoordInterleaveFactor;
+      for (i = 0; i < factor; i++) {
+         gl_ActiveTexture( ctx, (GLenum) (GL_TEXTURE0_ARB + i) );
+         gl_EnableClientState( ctx, GL_TEXTURE_COORD_ARRAY );
+         glTexCoordPointer(CTX_PRM  tcomps, GL_FLOAT, stride,
+                             (GLubyte *) pointer + i * coffset );
+      }
+      for (i = factor; i < ctx->Const.MaxTextureUnits; i++) {
+         gl_ActiveTexture( ctx, (GLenum) (GL_TEXTURE0_ARB + i) );
+         gl_DisableClientState( ctx, GL_TEXTURE_COORD_ARRAY );
+      }
+   }
+   else {
+      GLint i;
+      for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
+         gl_ActiveTexture( ctx, (GLenum) (GL_TEXTURE0_ARB + i) );
+         gl_DisableClientState( ctx, GL_TEXTURE_COORD_ARRAY );
+      }
+   }
+   /* Restore texture coordinate unit index */
+   gl_ActiveTexture( ctx, (GLenum) (GL_TEXTURE0_ARB + coordUnitSave) );
+
+
+   /* Color */
+   if (cflag) {
+      gl_EnableClientState( ctx, GL_COLOR_ARRAY );
+      glColorPointer(CTX_PRM ccomps, ctype, stride,
+                       (GLubyte*) pointer + coffset );
+   }
+   else {
+      gl_DisableClientState( ctx, GL_COLOR_ARRAY );
+   }
+
+
+   /* Normals */
+   if (nflag) {
+      gl_EnableClientState( ctx, GL_NORMAL_ARRAY );
+      glNormalPointer(CTX_PRM GL_FLOAT, stride,
+                        (GLubyte*) pointer + noffset );
+   }
+   else {
+      gl_DisableClientState( ctx, GL_NORMAL_ARRAY );
+   }
+
+   gl_EnableClientState( ctx, GL_VERTEX_ARRAY );
+   glVertexPointer(CTX_PRM vcomps, GL_FLOAT, stride,
+                     (GLubyte *) pointer + voffset );
+}
+
+
+
+void GLAPIENTRY glDrawRangeElements(CTX_ARG GLenum mode, GLuint start,
+                                     GLuint end, GLsizei count,
+                                     GLenum type, const GLvoid *indices )
+{
+   GLcontext *ctx;
+   GET_CONTEXT;
+   CHECK_CONTEXT;
+   ctx = CC;
+
+   if (end < start) {
+      gl_error(ctx, GL_INVALID_VALUE, "glDrawRangeElements( end < start )");
+      return;
+   }
+
+   if (!ctx->Array.LockCount && 2*count > 3*(end-start)) {
+      glLockArraysEXT(CTX_PRM start, end );
+      glDrawElements(CTX_PRM mode, count, type, indices );
+      glUnlockArraysEXT(CTX_VPRM );
+   } else {
+      glDrawElements(CTX_PRM mode, count, type, indices );
+   }
+}
+
+
+
+void gl_update_client_state( GLcontext *ctx )
+{
+   static GLuint sz_flags[5] = { 0, 
+                                0,
+                                VERT_OBJ_2, 
+                                VERT_OBJ_23, 
+                                VERT_OBJ_234 };
+
+   static GLuint tc_flags[5] = { 0, 
+                                VERT_TEX0_1,
+                                VERT_TEX0_12, 
+                                VERT_TEX0_123, 
+                                VERT_TEX0_1234 };
+
+   ctx->Array.Flags = 0;
+   ctx->Array.Summary = 0;
+   ctx->input->ArrayIncr = 0;
+   
+   if (ctx->Array.Normal.Enabled)      ctx->Array.Flags |= VERT_NORM;
+   if (ctx->Array.Color.Enabled)       ctx->Array.Flags |= VERT_RGBA;
+   if (ctx->Array.Index.Enabled)       ctx->Array.Flags |= VERT_INDEX;
+   if (ctx->Array.EdgeFlag.Enabled)    ctx->Array.Flags |= VERT_EDGE;
+   if (ctx->Array.Vertex.Enabled) {
+      ctx->Array.Flags |= sz_flags[ctx->Array.Vertex.Size];
+      ctx->input->ArrayIncr = 1;
+   }
+   if (ctx->Array.TexCoord[0].Enabled) {
+      ctx->Array.Flags |= tc_flags[ctx->Array.TexCoord[0].Size];
+   }
+   if (ctx->Array.TexCoord[1].Enabled) {
+      ctx->Array.Flags |= (tc_flags[ctx->Array.TexCoord[1].Size] << NR_TEXSIZE_BITS);
+   }
+
+   /* Not really important any more:
+    */
+   ctx->Array.Summary = ctx->Array.Flags & VERT_DATA;
+
+   ctx->input->ArrayOrFlags = (ctx->Array.Flags & VERT_OBJ_234) | VERT_ELT;
+   ctx->input->ArrayAndFlags = ~ctx->Array.Flags;
+   ctx->input->ArrayEltFlush = !(ctx->CompileCVAFlag);
+}
+
diff --git a/src/mesa/main/varray.h b/src/mesa/main/varray.h
new file mode 100644 (file)
index 0000000..fc81a61
--- /dev/null
@@ -0,0 +1,113 @@
+/* $Id: varray.h,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+#ifndef VARRAY_H
+#define VARRAY_H
+
+
+#include "types.h"
+
+
+extern void gl_VertexPointer( GLcontext *ctx,
+                              GLint size, GLenum type, GLsizei stride,
+                              const GLvoid *ptr );
+
+
+extern void gl_NormalPointer( GLcontext *ctx,
+                              GLenum type, GLsizei stride, const GLvoid *ptr );
+
+
+extern void gl_ColorPointer( GLcontext *ctx,
+                             GLint size, GLenum type, GLsizei stride,
+                             const GLvoid *ptr );
+
+
+extern void gl_IndexPointer( GLcontext *ctx,
+                                GLenum type, GLsizei stride,
+                                const GLvoid *ptr );
+
+
+extern void gl_TexCoordPointer( GLcontext *ctx,
+                                GLint size, GLenum type, GLsizei stride,
+                                const GLvoid *ptr );
+
+
+extern void gl_EdgeFlagPointer( GLcontext *ctx,
+                                GLsizei stride, const GLboolean *ptr );
+
+
+extern void gl_GetPointerv( GLcontext *ctx, GLenum pname, GLvoid **params );
+
+
+
+extern void gl_DrawArrays( GLcontext *ctx,
+                           GLenum mode, GLint first, GLsizei count );
+
+extern void gl_save_DrawArrays( GLcontext *ctx,
+                                GLenum mode, GLint first, GLsizei count );
+
+
+extern void gl_DrawElements( GLcontext *ctx,
+                             GLenum mode, GLsizei count,
+                             GLenum type, const GLvoid *indices );
+
+extern void gl_save_DrawElements( GLcontext *ctx,
+                                  GLenum mode, GLsizei count,
+                                  GLenum type, const GLvoid *indices );
+
+
+extern void gl_InterleavedArrays( GLcontext *ctx,
+                                  GLenum format, GLsizei stride,
+                                  const GLvoid *pointer );
+
+extern void gl_save_InterleavedArrays( GLcontext *ctx,
+                                       GLenum format, GLsizei stride,
+                                       const GLvoid *pointer );
+
+
+extern void gl_DrawRangeElements( GLcontext *ctx, GLenum mode, GLuint start,
+                                  GLuint end, GLsizei count, GLenum type,
+                                  const GLvoid *indices );
+
+extern void gl_save_DrawRangeElements( GLcontext *ctx, GLenum mode,
+                                       GLuint start, GLuint end, GLsizei count,
+                                       GLenum type, const GLvoid *indices );
+
+
+
+extern void gl_exec_array_elements( GLcontext *ctx, 
+                                   struct immediate *IM );
+
+extern void gl_update_client_state( GLcontext *ctx );
+
+#endif
+
+
+
diff --git a/src/mesa/x86/3dnow.c b/src/mesa/x86/3dnow.c
new file mode 100644 (file)
index 0000000..f91a90b
--- /dev/null
@@ -0,0 +1,168 @@
+/* $Id: 3dnow.c,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/*
+ * 3DNow! optimizations contributed by
+ * Holger Waechtler <holger@akaflieg.extern.tu-berlin.de>
+ */
+#if defined(USE_3DNOW_ASM)
+#include "3dnow.h"
+
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include "context.h"
+#include "types.h"
+#include "xform.h"
+
+#ifdef DEBUG
+#include "debug_xform.h"
+#endif
+
+
+
+
+#define XFORM_ARGS      GLvector4f *to_vec,             \
+                        const GLmatrix *mat,            \
+                        const GLvector4f *from_vec,     \
+                        const GLubyte *mask,            \
+                        const GLubyte flag
+
+
+
+#define DECLARE_XFORM_GROUP(pfx, v, masked) \
+ extern void gl_##pfx##_transform_points##v##_general_##masked(XFORM_ARGS);    \
+ extern void gl_##pfx##_transform_points##v##_identity_##masked(XFORM_ARGS);   \
+ extern void gl_##pfx##_transform_points##v##_3d_no_rot_##masked(XFORM_ARGS);  \
+ extern void gl_##pfx##_transform_points##v##_perspective_##masked(XFORM_ARGS);\
+ extern void gl_##pfx##_transform_points##v##_2d_##masked(XFORM_ARGS);         \
+ extern void gl_##pfx##_transform_points##v##_2d_no_rot_##masked(XFORM_ARGS);  \
+ extern void gl_##pfx##_transform_points##v##_3d_##masked(XFORM_ARGS);
+
+
+
+#define ASSIGN_XFORM_GROUP( pfx, cma, vsize, masked )           \
+ gl_transform_tab[cma][vsize][MATRIX_GENERAL]                   \
+  = gl_##pfx##_transform_points##vsize##_general_##masked;      \
+ gl_transform_tab[cma][vsize][MATRIX_IDENTITY]                  \
+  = gl_##pfx##_transform_points##vsize##_identity_##masked;     \
+ gl_transform_tab[cma][vsize][MATRIX_3D_NO_ROT]                 \
+  = gl_##pfx##_transform_points##vsize##_3d_no_rot_##masked;    \
+ gl_transform_tab[cma][vsize][MATRIX_PERSPECTIVE]               \
+  = gl_##pfx##_transform_points##vsize##_perspective_##masked;  \
+ gl_transform_tab[cma][vsize][MATRIX_2D]                        \
+  = gl_##pfx##_transform_points##vsize##_2d_##masked;           \
+ gl_transform_tab[cma][vsize][MATRIX_2D_NO_ROT]                 \
+  = gl_##pfx##_transform_points##vsize##_2d_no_rot_##masked;    \
+ gl_transform_tab[cma][vsize][MATRIX_3D]                        \
+  = gl_##pfx##_transform_points##vsize##_3d_##masked;
+
+
+
+
+#define NORM_ARGS       const GLmatrix *mat,        \
+                        GLfloat scale,              \
+                        const GLvector3f *in,       \
+                        const GLfloat *lengths,     \
+                        const GLubyte mask[],       \
+                        GLvector3f *dest 
+
+
+
+#define DECLARE_NORM_GROUP(pfx, masked)                                        \
+ extern void gl_##pfx##_rescale_normals_##masked## (NORM_ARGS);                \
+ extern void gl_##pfx##_normalize_normals_##masked## (NORM_ARGS);              \
+ extern void gl_##pfx##_transform_normals_##masked## (NORM_ARGS);              \
+ extern void gl_##pfx##_transform_normals_no_rot_##masked## (NORM_ARGS);       \
+ extern void gl_##pfx##_transform_rescale_normals_##masked## (NORM_ARGS);      \
+ extern void gl_##pfx##_transform_rescale_normals_no_rot_##masked## (NORM_ARGS); \
+ extern void gl_##pfx##_transform_normalize_normals_##masked## (NORM_ARGS);    \
+ extern void gl_##pfx##_transform_normalize_normals_no_rot_##masked## (NORM_ARGS);
+
+
+
+#define ASSIGN_NORM_GROUP( pfx, cma, masked )                                 \
+   gl_normal_tab[NORM_RESCALE][cma]   =                                       \
+      gl_##pfx##_rescale_normals_##masked##;                                  \
+   gl_normal_tab[NORM_NORMALIZE][cma] =                                       \
+      gl_##pfx##_normalize_normals_##masked##;                                \
+   gl_normal_tab[NORM_TRANSFORM][cma] =                                       \
+      gl_##pfx##_transform_normals_##masked##;                                \
+   gl_normal_tab[NORM_TRANSFORM_NO_ROT][cma] =                                \
+      gl_##pfx##_transform_normals_no_rot_##masked##;                         \
+   gl_normal_tab[NORM_TRANSFORM | NORM_RESCALE][cma] =                        \
+      gl_##pfx##_transform_rescale_normals_##masked##;                        \
+   gl_normal_tab[NORM_TRANSFORM_NO_ROT | NORM_RESCALE][cma] =                 \
+      gl_##pfx##_transform_rescale_normals_no_rot_##masked##;                 \
+   gl_normal_tab[NORM_TRANSFORM | NORM_NORMALIZE][cma] =                      \
+      gl_##pfx##_transform_normalize_normals_##masked##;                      \
+   gl_normal_tab[NORM_TRANSFORM_NO_ROT | NORM_NORMALIZE][cma] =               \
+      gl_##pfx##_transform_normalize_normals_no_rot_##masked##;
+
+
+
+
+void gl_init_3dnow_asm_transforms (void)
+{
+   DECLARE_XFORM_GROUP( 3dnow, 1, raw )
+   DECLARE_XFORM_GROUP( 3dnow, 2, raw )
+   DECLARE_XFORM_GROUP( 3dnow, 3, raw )
+   DECLARE_XFORM_GROUP( 3dnow, 4, raw )
+
+   DECLARE_XFORM_GROUP( 3dnow, 1, masked )
+   DECLARE_XFORM_GROUP( 3dnow, 2, masked )
+   DECLARE_XFORM_GROUP( 3dnow, 3, masked )
+   DECLARE_XFORM_GROUP( 3dnow, 4, masked )
+
+   DECLARE_NORM_GROUP( 3dnow, raw )
+/* DECLARE_NORM_GROUP( 3dnow, masked )
+*/
+
+   ASSIGN_XFORM_GROUP( 3dnow, 0, 1, raw )
+   ASSIGN_XFORM_GROUP( 3dnow, 0, 2, raw )
+   ASSIGN_XFORM_GROUP( 3dnow, 0, 3, raw )
+   ASSIGN_XFORM_GROUP( 3dnow, 0, 4, raw )
+
+   ASSIGN_XFORM_GROUP( 3dnow, CULL_MASK_ACTIVE, 1, masked )
+   ASSIGN_XFORM_GROUP( 3dnow, CULL_MASK_ACTIVE, 2, masked )
+   ASSIGN_XFORM_GROUP( 3dnow, CULL_MASK_ACTIVE, 3, masked )
+   ASSIGN_XFORM_GROUP( 3dnow, CULL_MASK_ACTIVE, 4, masked )
+
+   ASSIGN_NORM_GROUP( 3dnow, 0, raw )
+/* ASSIGN_NORM_GROUP( 3dnow, CULL_MASK_ACTIVE, masked )
+*/
+
+#ifdef DEBUG
+   gl_test_all_transform_functions("3Dnow!");
+   gl_test_all_normal_transform_functions("3Dnow!");
+#endif
+} 
+
+#endif
+
diff --git a/src/mesa/x86/3dnow.h b/src/mesa/x86/3dnow.h
new file mode 100644 (file)
index 0000000..b06cc5b
--- /dev/null
@@ -0,0 +1,95 @@
+/* $Id: 3dnow.h,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/*
+ * 3DNow! optimizations contributed by
+ * Holger Waechtler <holger@akaflieg.extern.tu-berlin.de>
+ */
+
+
+#ifndef _3dnow_h
+#define _3dnow_h
+
+
+
+#include "xform.h"
+
+
+void gl_init_3dnow_asm_transforms (void);
+
+
+
+
+#if 0
+GLvector4f *gl_project_points( GLvector4f *proj_vec,
+                               const GLvector4f *clip_vec )
+{
+   __asm__ (
+   "   femms                                                              \n"
+   "                                                                      \n"
+   "   movq       (%0),     %%mm0      # x1             | x0              \n"
+   "   movq       8(%0),    %%mm1      # oow            | x2              \n"
+   "                                                                      \n"
+   "1: movq       %%mm1,    %%mm2      # oow            | x2              \n"
+   "   addl       %2,       %0         # next point                       \n"
+   "                                                                      \n"
+   "   punpckhdq  %%mm2,    %%mm2      # oow            | oow             \n"
+   "   addl       $16,      %1         # next point                       \n"
+   "                                                                      \n"
+   "   pfrcp      %%mm2,    %%mm3      # 1/oow          | 1/oow           \n"
+   "   decl       %3                                                      \n"
+   "                                                                      \n"
+   "   pfmul      %%mm3,    %%mm0      # x1/oow         | x0/oow          \n"
+   "   movq       %%mm0,    -16(%1)    # write r0, r1                     \n"
+   "                                                                      \n"
+   "   pfmul      %%mm3,    %%mm1      # 1              | x2/oow          \n"
+   "   movq       (%0),     %%mm0      # x1             | x0              \n"
+   "                                                                      \n"
+   "   movd       %%mm1,    8(%1)      # write r2                         \n"
+   "   movd       %%mm3,    12(%1)     # write r3                         \n"
+   "                                                                      \n"
+   "   movq       8(%0),    %%mm1      # oow            | x2              \n"
+   "   ja         1b                                                      \n"
+   "                                                                      \n"
+   "   femms                                                              \n"
+   "                                                                        "
+   ::"a" (clip_vec->start),
+   "c" (proj_vec->start),
+   "g" (clip_vec->stride),
+   "d" (clip_vec->count)
+   );
+
+   proj_vec->flags |= VEC_SIZE_4;
+   proj_vec->size = 3;
+   proj_vec->count = clip_vec->count;
+   return proj_vec;
+}
+#endif
+
+
+
+#endif
diff --git a/src/mesa/x86/assyntax.h b/src/mesa/x86/assyntax.h
new file mode 100644 (file)
index 0000000..3c92220
--- /dev/null
@@ -0,0 +1,1629 @@
+#ifndef __ASSYNTAX_H__
+#define        __ASSYNTAX_H__
+
+/*
+ * Copyright 1992 Vrije Universiteit, The Netherlands
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the Vrije Universiteit not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  The Vrije Universiteit makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ * The Vrije Universiteit DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL The Vrije Universiteit BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * assyntax.h
+ *
+ * Select the syntax appropriate to the 386 assembler being used
+ * To add support for more assemblers add more columns to the CHOICE
+ * macro.  Note that register names must also have uppercase names
+ * to avoid macro recursion. e.g., #define ah %ah recurses!
+ *
+ * NB 1.  Some of the macros for certain assemblers imply that the code is to
+ *       run in protected mode!!  Caveat emptor.
+ *
+ * NB 2.  486 specific instructions are not included.  This is to discourage
+ *       their accidental use in code that is intended to run on 386 and 486
+ *       systems.
+ *
+ * Supported assemblers:
+ *
+ * (a) AT&T SysVr4 as(1):      define ATT_ASSEMBLER
+ * (b) GNU Assembler gas:      define GNU_ASSEMBLER (default)
+ * (c) Amsterdam Compiler kit: define ACK_ASSEMBLER
+ * (d) The Netwide Assembler:  define NASM_ASSEMBLER
+ * (e) Microsoft Assembler:    define MASM_ASSEMBLER (UNTESTED!)
+ *
+ * The following naming conventions have been used to identify the various
+ * data types:
+ *             _SR = segment register version
+ *     Integer:
+ *             _Q = quadword   = 64 bits
+ *             _L = long       = 32 bits
+ *             _W = short      = 16 bits
+ *             _B = byte       =  8 bits
+ *     Floating-point:
+ *             _X = m80real    = 80 bits
+ *             _D = double     = 64 bits
+ *             _S = single     = 32 bits
+ *
+ * Author: Gregory J. Sharp, Sept 1992
+ *         Vrije Universiteit, Amsterdam, The Netherlands
+ *
+ *         [support for Intel syntax added by Josh Vanderhoof, 1999]
+ */
+
+#if !(defined(NASM_ASSEMBLER) || defined(MASM_ASSEMBLER))
+
+#if !defined(ATT_ASSEMBLER) && !defined(GNU_ASSEMBLER) && !defined(ACK_ASSEMBLER)
+#define GNU_ASSEMBLER
+#endif
+
+#if (defined(__STDC__) && !defined(UNIXCPP)) || (defined (sun) && defined (i386) \
+ && defined (SVR4) && defined (__STDC__) && !defined (__GNUC__)) 
+#define        CONCAT(x, y)    x ## y
+#else
+#define        CONCAT(x, y)    x/**/y
+#endif
+
+#ifdef ACK_ASSEMBLER
+
+/* Assume we write code for 32-bit protected mode! */
+
+/* Redefine register names for GAS & AT&T assemblers */
+#define        AL      al
+#define        AH      ah
+#define        AX      ax
+#define        EAX     ax
+#define        BL      bl
+#define        BH      bh
+#define        BX      bx
+#define        EBX     bx
+#define        CL      cl
+#define        CH      ch
+#define        CX      cx
+#define        ECX     cx
+#define        DL      dl
+#define        DH      dh
+#define        DX      dx
+#define        EDX     dx
+#define        BP      bp
+#define        EBP     bp
+#define        SI      si
+#define        ESI     si
+#define        DI      di
+#define        EDI     di
+#define        SP      sp
+#define        ESP     sp
+#define        CS      cs
+#define        SS      ss
+#define        DS      ds
+#define        ES      es
+#define        FS      fs
+#define        GS      gs
+/* Control Registers */
+#define        CR0     cr0
+#define        CR1     cr1
+#define        CR2     cr2
+#define        CR3     cr3
+/* Debug Registers */
+#define        DR0     dr0
+#define        DR1     dr1
+#define        DR2     dr2
+#define        DR3     dr3
+#define        DR4     dr4
+#define        DR5     dr5
+#define        DR6     dr6
+#define        DR7     dr7
+/* Floating-point Stack */
+#define        ST      st
+
+#define        AS_BEGIN        .sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+
+
+#define        _WTOG           o16     /* word toggle for _W instructions */
+#define        _LTOG                   /* long toggle for _L instructions */
+#define        ADDR_TOGGLE     a16
+#define        OPSZ_TOGGLE     o16
+#define        USE16           .use16
+#define        USE32           .use32
+
+#define        CHOICE(a,b,c)   c
+
+#else /* AT&T or GAS */
+
+/* Redefine register names for GAS & AT&T assemblers */
+#define        AL      %al
+#define        AH      %ah
+#define        AX      %ax
+#define        EAX     %eax
+#define        BL      %bl
+#define        BH      %bh
+#define        BX      %bx
+#define        EBX     %ebx
+#define        CL      %cl
+#define        CH      %ch
+#define        CX      %cx
+#define        ECX     %ecx
+#define        DL      %dl
+#define        DH      %dh
+#define        DX      %dx
+#define        EDX     %edx
+#define        BP      %bp
+#define        EBP     %ebp
+#define        SI      %si
+#define        ESI     %esi
+#define        DI      %di
+#define        EDI     %edi
+#define        SP      %sp
+#define        ESP     %esp
+#define        CS      %cs
+#define        SS      %ss
+#define        DS      %ds
+#define        ES      %es
+#define        FS      %fs
+#define        GS      %gs
+/* Control Registers */
+#define        CR0     %cr0
+#define        CR1     %cr1
+#define        CR2     %cr2
+#define        CR3     %cr3
+/* Debug Registers */
+#define        DR0     %db0
+#define        DR1     %db1
+#define        DR2     %db2
+#define        DR3     %db3
+#define        DR4     %db4
+#define        DR5     %db5
+#define        DR6     %db6
+#define        DR7     %db7
+/* Floating-point Stack */
+#define        ST      %st
+/* MMX Registers */
+#define MM0    %mm0
+#define MM1    %mm1
+#define MM2    %mm2
+#define MM3    %mm3
+#define MM4    %mm4
+#define MM5    %mm5
+#define MM6    %mm6
+#define MM7    %mm7
+/* SSE Registers */
+#define XMM0   %xmm0
+#define XMM1   %xmm1
+#define XMM2   %xmm2
+#define XMM3   %xmm3
+#define XMM4   %xmm4
+#define XMM5   %xmm5
+#define XMM6   %xmm6
+#define XMM7   %xmm7
+
+#define        AS_BEGIN
+#define        USE16
+#define        USE32
+
+#ifdef GNU_ASSEMBLER
+
+#define        ADDR_TOGGLE     aword
+#define        OPSZ_TOGGLE     word
+
+#define        CHOICE(a,b,c)   b
+
+#else
+/*
+ * AT&T ASSEMBLER SYNTAX
+ * *********************
+ */
+#define        CHOICE(a,b,c)   a
+
+#define        ADDR_TOGGLE     addr16
+#define        OPSZ_TOGGLE     data16
+
+#endif /* GNU_ASSEMBLER */
+#endif /* ACK_ASSEMBLER */
+
+
+#if defined(Lynx) || (defined(SYSV) || defined(SVR4)) && !defined(ACK_ASSEMBLER) \
+ || (defined(linux) || defined(__OS2ELF__)) && defined(__ELF__)
+#define GLNAME(a)       a
+#else
+#define GLNAME(a)       CONCAT(_,a)
+#endif
+
+
+       /****************************************/
+       /*                                      */
+       /*      Select the various choices      */
+       /*                                      */
+       /****************************************/
+
+
+/* Redefine assembler directives */
+/*********************************/
+#define GLOBL          CHOICE(.globl, .globl, .extern)
+/*
+#define        ALIGNTEXT32     CHOICE(.align 32, .align ARG2(5,0x90), .align 32)
+*/
+#define        ALIGNTEXT32     CHOICE(.align 32, .balign 32, .align 32)
+#define        ALIGNTEXT16     CHOICE(.align 16, .balign 16, .align 16)
+#define        ALIGNTEXT8      CHOICE(.align 8, .balign 8, .align 8)
+#define        ALIGNTEXT4      CHOICE(.align 4, .balign 4, .align 4)
+#define        ALIGNTEXT2      CHOICE(.align 2, .balign 2, .align 2)
+/* ALIGNTEXT4ifNOP is the same as ALIGNTEXT4, but only if the space is
+ * guaranteed to be filled with NOPs.  Otherwise it does nothing.
+ */
+#define        ALIGNTEXT32ifNOP        CHOICE(.align 32, .balign ARG2(32,0x90), /*can't do it*/)
+#define        ALIGNTEXT16ifNOP        CHOICE(.align 16, .balign ARG2(16,0x90), /*can't do it*/)
+#define        ALIGNTEXT8ifNOP CHOICE(.align 8, .balign ARG2(8,0x90), /*can't do it*/)
+#define        ALIGNTEXT4ifNOP CHOICE(.align 4, .balign ARG2(4,0x90), /*can't do it*/)
+#define        ALIGNDATA32     CHOICE(.align 32, .balign ARG2(32,0x0), .align 32)
+#define        ALIGNDATA16     CHOICE(.align 16, .balign ARG2(16,0x0), .align 16)
+#define        ALIGNDATA8      CHOICE(.align 8, .balign ARG2(8,0x0), .align 8)
+#define        ALIGNDATA4      CHOICE(.align 4, .balign ARG2(4,0x0), .align 4)
+#define        ALIGNDATA2      CHOICE(.align 2, .balign ARG2(2,0x0), .align 2)
+#define        FILE(s)         CHOICE(.file s, .file s, .file s)
+#define        STRING(s)       CHOICE(.string s, .asciz s, .asciz s)
+#define        D_LONG          CHOICE(.long, .long, .data4)
+#define        D_WORD          CHOICE(.value, .short, .data2)
+#define        D_BYTE          CHOICE(.byte, .byte, .data1)
+#define        SPACE           CHOICE(.comm, .space, .space)
+#define        COMM            CHOICE(.comm, .comm, .comm)
+#define        SEG_DATA        CHOICE(.data, .data, .sect .data)
+#define        SEG_TEXT        CHOICE(.text, .text, .sect .text)
+#define        SEG_BSS         CHOICE(.bss, .bss, .sect .bss)
+
+#ifdef GNU_ASSEMBLER
+#define        D_SPACE(n)      . = . + n
+#else
+#define        D_SPACE(n)      .space n
+#endif
+
+/* Addressing Modes */
+/* Immediate Mode */
+#define        ADDR(a)         CHOICE(CONCAT($,a), CONCAT($,a), a)
+#define        CONST(a)        CHOICE(CONCAT($,a), CONCAT($,a), a)
+
+/* Indirect Mode */
+#define        CONTENT(a)      CHOICE(a, a, (a))        /* take contents of variable */
+#define        REGIND(a)       CHOICE((a), (a), (a))    /* Register a indirect */
+/* Register b indirect plus displacement a */
+#define        REGOFF(a, b)    CHOICE(a(b), a(b), a(b))
+/* Reg indirect Base + Index + Displacement  - this is mainly for 16-bit mode
+ * which has no scaling
+ */
+#define        REGBID(b,i,d)   CHOICE(d(b,i), d(b,i), d(b)(i))
+/* Reg indirect Base + (Index * Scale) + Displacement */
+#define        REGBISD(b,i,s,d) CHOICE(d(b,i,s), d(b,i,s), d(b)(i*s))
+/* Displaced Scaled Index: */
+#define REGDIS(d,i,s)  CHOICE(d(,i,s), d(,i,s), d(i * s))
+/* Indexed Base: */
+#define REGBI(b,i)     CHOICE((b,i), (b,i), (b)(i))
+/* Displaced Base: */
+#define REGDB(d,b)     CHOICE(d(b), d(b), d(b))
+/* Variable indirect: */
+#define VARINDIRECT(var) CHOICE(*var, *var, (var))
+/* Use register contents as jump/call target: */
+#define CODEPTR(reg)   CHOICE(*reg, *reg, reg)
+
+/* For expressions requiring bracketing
+ * eg. (CRT0_PM | CRT_EM)
+ */
+
+#define        EXPR(a)         CHOICE([a], (a), [a])
+#define        ENOT(a)         CHOICE(0!a, ~a, ~a)
+#define        EMUL(a,b)       CHOICE(a\*b, a*b, a*b)
+#define        EDIV(a,b)       CHOICE(a\/b, a/b, a/b)
+
+/*
+ * We have to beat the problem of commas within arguments to choice.
+ * eg. choice (add a,b, add b,a) will get argument mismatch.  Luckily ANSI
+ * and other known cpp definitions evaluate arguments before substitution
+ * so the following works.
+ */
+#define        ARG2(a, b)      a,b
+#define        ARG3(a,b,c)     a,b,c
+
+/* Redefine assembler commands */
+#define        AAA             CHOICE(aaa, aaa, aaa)
+#define        AAD             CHOICE(aad, aad, aad)
+#define        AAM             CHOICE(aam, aam, aam)
+#define        AAS             CHOICE(aas, aas, aas)
+#define        ADC_L(a, b)     CHOICE(adcl ARG2(a,b), adcl ARG2(a,b), _LTOG adc ARG2(b,a))
+#define        ADC_W(a, b)     CHOICE(adcw ARG2(a,b), adcw ARG2(a,b), _WTOG adc ARG2(b,a))
+#define        ADC_B(a, b)     CHOICE(adcb ARG2(a,b), adcb ARG2(a,b), adcb ARG2(b,a))
+#define        ADD_L(a, b)     CHOICE(addl ARG2(a,b), addl ARG2(a,b), _LTOG add ARG2(b,a))
+#define        ADD_W(a, b)     CHOICE(addw ARG2(a,b), addw ARG2(a,b), _WTOG add ARG2(b,a))
+#define        ADD_B(a, b)     CHOICE(addb ARG2(a,b), addb ARG2(a,b), addb ARG2(b,a))
+#define        AND_L(a, b)     CHOICE(andl ARG2(a,b), andl ARG2(a,b), _LTOG and ARG2(b,a))
+#define        AND_W(a, b)     CHOICE(andw ARG2(a,b), andw ARG2(a,b), _WTOG and ARG2(b,a))
+#define        AND_B(a, b)     CHOICE(andb ARG2(a,b), andb ARG2(a,b), andb ARG2(b,a))
+#define        ARPL(a,b)       CHOICE(arpl ARG2(a,b), arpl ARG2(a,b), arpl ARG2(b,a))
+#define        BOUND_L(a, b)   CHOICE(boundl ARG2(a,b), boundl ARG2(b,a), _LTOG bound ARG2(b,a))
+#define        BOUND_W(a, b)   CHOICE(boundw ARG2(a,b), boundw ARG2(b,a), _WTOG bound ARG2(b,a))
+#define        BSF_L(a, b)     CHOICE(bsfl ARG2(a,b), bsfl ARG2(a,b), _LTOG bsf ARG2(b,a))
+#define        BSF_W(a, b)     CHOICE(bsfw ARG2(a,b), bsfw ARG2(a,b), _WTOG bsf ARG2(b,a))
+#define        BSR_L(a, b)     CHOICE(bsrl ARG2(a,b), bsrl ARG2(a,b), _LTOG bsr ARG2(b,a))
+#define        BSR_W(a, b)     CHOICE(bsrw ARG2(a,b), bsrw ARG2(a,b), _WTOG bsr ARG2(b,a))
+#define        BT_L(a, b)      CHOICE(btl ARG2(a,b), btl ARG2(a,b), _LTOG bt ARG2(b,a))
+#define        BT_W(a, b)      CHOICE(btw ARG2(a,b), btw ARG2(a,b), _WTOG bt ARG2(b,a))
+#define        BTC_L(a, b)     CHOICE(btcl ARG2(a,b), btcl ARG2(a,b), _LTOG btc ARG2(b,a))
+#define        BTC_W(a, b)     CHOICE(btcw ARG2(a,b), btcw ARG2(a,b), _WTOG btc ARG2(b,a))
+#define        BTR_L(a, b)     CHOICE(btrl ARG2(a,b), btrl ARG2(a,b), _LTOG btr ARG2(b,a))
+#define        BTR_W(a, b)     CHOICE(btrw ARG2(a,b), btrw ARG2(a,b), _WTOG btr ARG2(b,a))
+#define        BTS_L(a, b)     CHOICE(btsl ARG2(a,b), btsl ARG2(a,b), _LTOG bts ARG2(b,a))
+#define        BTS_W(a, b)     CHOICE(btsw ARG2(a,b), btsw ARG2(a,b), _WTOG bts ARG2(b,a))
+#define        CALL(a)         CHOICE(call a, call a, call a)
+#define        CALLF(s,a)      CHOICE(lcall ARG2(s,a), lcall ARG2(s,a), callf s:a)
+#define        CBW             CHOICE(cbtw, cbw, cbw)
+#define        CWDE            CHOICE(cwtd, cwde, cwde)
+#define        CLC             CHOICE(clc, clc, clc)
+#define        CLD             CHOICE(cld, cld, cld)
+#define        CLI             CHOICE(cli, cli, cli)
+#define        CLTS            CHOICE(clts, clts, clts)
+#define        CMC             CHOICE(cmc, cmc, cmc)
+#define        CMP_L(a, b)     CHOICE(cmpl ARG2(a,b), cmpl ARG2(a,b), _LTOG cmp ARG2(b,a))
+#define        CMP_W(a, b)     CHOICE(cmpw ARG2(a,b), cmpw ARG2(a,b), _WTOG cmp ARG2(b,a))
+#define        CMP_B(a, b)     CHOICE(cmpb ARG2(a,b), cmpb ARG2(a,b), cmpb ARG2(b,a))
+#define        CMPS_L          CHOICE(cmpsl, cmpsl, _LTOG cmps)
+#define        CMPS_W          CHOICE(cmpsw, cmpsw, _WTOG cmps)
+#define        CMPS_B          CHOICE(cmpsb, cmpsb, cmpsb)
+#define        CWD             CHOICE(cwtl, cwd, cwd)
+#define        CDQ             CHOICE(cltd, cdq, cdq)
+#define        DAA             CHOICE(daa, daa, daa)
+#define        DAS             CHOICE(das, das, das)
+#define        DEC_L(a)        CHOICE(decl a, decl a, _LTOG dec a)
+#define        DEC_W(a)        CHOICE(decw a, decw a, _WTOG dec a)
+#define        DEC_B(a)        CHOICE(decb a, decb a, decb a)
+#define        DIV_L(a)        CHOICE(divl a, divl a, div a)
+#define        DIV_W(a)        CHOICE(divw a, divw a, div a)
+#define        DIV_B(a)        CHOICE(divb a, divb a, divb a)
+#define        ENTER(a,b)      CHOICE(enter ARG2(a,b), enter ARG2(a,b), enter ARG2(b,a))
+#define        HLT             CHOICE(hlt, hlt, hlt)
+#define        IDIV_L(a)       CHOICE(idivl a, idivl a, _LTOG idiv a)
+#define        IDIV_W(a)       CHOICE(idivw a, idivw a, _WTOG idiv a)
+#define        IDIV_B(a)       CHOICE(idivb a, idivb a, idivb a)
+/* More forms than this for imul!! */
+#define        IMUL_L(a, b)    CHOICE(imull ARG2(a,b), imull ARG2(a,b), _LTOG imul ARG2(b,a))
+#define        IMUL_W(a, b)    CHOICE(imulw ARG2(a,b), imulw ARG2(a,b), _WTOG imul ARG2(b,a))
+#define        IMUL_B(a)       CHOICE(imulb a, imulb a, imulb a)
+#define        IN_L            CHOICE(inl (DX), inl ARG2(DX,EAX), _LTOG in DX)
+#define        IN_W            CHOICE(inw (DX), inw ARG2(DX,AX), _WTOG in DX)
+#define        IN_B            CHOICE(inb (DX), inb ARG2(DX,AL), inb DX)
+/* Please AS code writer: use the following ONLY, if you refer to ports<256
+ * directly, but not in IN1_W(DX), for instance, even if IN1_ looks nicer
+ */
+#if defined (sun)
+#define IN1_L(a)    CHOICE(inl (a), inl ARG2(a,EAX), _LTOG in a)
+#define IN1_W(a)    CHOICE(inw (a), inw ARG2(a,AX), _WTOG in a)
+#define IN1_B(a)    CHOICE(inb (a), inb ARG2(a,AL), inb a)
+#else
+#define        IN1_L(a)        CHOICE(inl a, inl ARG2(a,EAX), _LTOG in a)
+#define        IN1_W(a)        CHOICE(inw a, inw ARG2(a,AX), _WTOG in a)
+#define        IN1_B(a)        CHOICE(inb a, inb ARG2(a,AL), inb a)
+#endif
+#define        INC_L(a)        CHOICE(incl a, incl a, _LTOG inc a)
+#define        INC_W(a)        CHOICE(incw a, incw a, _WTOG inc a)
+#define        INC_B(a)        CHOICE(incb a, incb a, incb a)
+#define        INS_L           CHOICE(insl, insl, _LTOG ins)
+#define        INS_W           CHOICE(insw, insw, _WTOG ins)
+#define        INS_B           CHOICE(insb, insb, insb)
+#define        INT(a)          CHOICE(int a, int a, int a)
+#define        INT3            CHOICE(int CONST(3), int3, int CONST(3))
+#define        INTO            CHOICE(into, into, into)
+#define        IRET            CHOICE(iret, iret, iret)
+#define        IRETD           CHOICE(iret, iret, iretd)
+#define        JA(a)           CHOICE(ja a, ja a, ja a)
+#define        JAE(a)          CHOICE(jae a, jae a, jae a)
+#define        JB(a)           CHOICE(jb a, jb a, jb a)
+#define        JBE(a)          CHOICE(jbe a, jbe a, jbe a)
+#define        JC(a)           CHOICE(jc a, jc a, jc a)
+#define        JE(a)           CHOICE(je a, je a, je a)
+#define        JG(a)           CHOICE(jg a, jg a, jg a)
+#define        JGE(a)          CHOICE(jge a, jge a, jge a)
+#define        JL(a)           CHOICE(jl a, jl a, jl a)
+#define        JLE(a)          CHOICE(jle a, jle a, jle a)
+#define        JNA(a)          CHOICE(jna a, jna a, jna a)
+#define        JNAE(a)         CHOICE(jnae a, jnae a, jnae a)
+#define        JNB(a)          CHOICE(jnb a, jnb a, jnb a)
+#define        JNBE(a)         CHOICE(jnbe a, jnbe a, jnbe a)
+#define        JNC(a)          CHOICE(jnc a, jnc a, jnc a)
+#define        JNE(a)          CHOICE(jne a, jne a, jne a)
+#define        JNG(a)          CHOICE(jng a, jng a, jng a)
+#define        JNGE(a)         CHOICE(jnge a, jnge a, jnge a)
+#define        JNL(a)          CHOICE(jnl a, jnl a, jnl a)
+#define        JNLE(a)         CHOICE(jnle a, jnle a, jnle a)
+#define        JNO(a)          CHOICE(jno a, jno a, jno a)
+#define        JNP(a)          CHOICE(jnp a, jnp a, jnp a)
+#define        JNS(a)          CHOICE(jns a, jns a, jns a)
+#define        JNZ(a)          CHOICE(jnz a, jnz a, jnz a)
+#define        JO(a)           CHOICE(jo a, jo a, jo a)
+#define        JP(a)           CHOICE(jp a, jp a, jp a)
+#define        JPE(a)          CHOICE(jpe a, jpe a, jpe a)
+#define        JPO(a)          CHOICE(jpo a, jpo a, jpo a)
+#define        JS(a)           CHOICE(js a, js a, js a)
+#define        JZ(a)           CHOICE(jz a, jz a, jz a)
+#define        JMP(a)          CHOICE(jmp a, jmp a, jmp a)
+#define        JMPF(s,a)       CHOICE(ljmp ARG2(s,a), ljmp ARG2(s,a), jmpf s:a)
+#define        LAHF            CHOICE(lahf, lahf, lahf)
+#if !defined(_REAL_MODE) && !defined(_V86_MODE)
+#define        LAR(a, b)       CHOICE(lar ARG2(a, b), lar ARG2(a, b), lar ARG2(b, a))
+#endif
+#define        LEA_L(a, b)     CHOICE(leal ARG2(a,b), leal ARG2(a,b), _LTOG lea ARG2(b,a))
+#define        LEA_W(a, b)     CHOICE(leaw ARG2(a,b), leaw ARG2(a,b), _WTOG lea ARG2(b,a))
+#define        LEAVE           CHOICE(leave, leave, leave)
+#define        LGDT(a)         CHOICE(lgdt a, lgdt a, lgdt a)
+#define        LIDT(a)         CHOICE(lidt a, lidt a, lidt a)
+#define        LDS(a, b)       CHOICE(ldsl ARG2(a,b), lds ARG2(a,b), lds ARG2(b,a))
+#define        LES(a, b)       CHOICE(lesl ARG2(a,b), les ARG2(a,b), les ARG2(b,a))
+#define        LFS(a, b)       CHOICE(lfsl ARG2(a,b), lfs ARG2(a,b), lfs ARG2(b,a))
+#define        LGS(a, b)       CHOICE(lgsl ARG2(a,b), lgs ARG2(a,b), lgs ARG2(b,a))
+#define        LSS(a, b)       CHOICE(lssl ARG2(a,b), lss ARG2(a,b), lss ARG2(b,a))
+#define        LLDT(a)         CHOICE(lldt a, lldt a, lldt a)
+#define        LMSW(a)         CHOICE(lmsw a, lmsw a, lmsw a)
+#define LOCK           CHOICE(lock, lock, lock)
+#define        LODS_L          CHOICE(lodsl, lodsl, _LTOG lods)
+#define        LODS_W          CHOICE(lodsw, lodsw, _WTOG lods)
+#define        LODS_B          CHOICE(lodsb, lodsb, lodsb)
+#define        LOOP(a)         CHOICE(loop a, loop a, loop a)
+#define        LOOPE(a)        CHOICE(loope a, loope a, loope a)
+#define        LOOPZ(a)        CHOICE(loopz a, loopz a, loopz a)
+#define        LOOPNE(a)       CHOICE(loopne a, loopne a, loopne a)
+#define        LOOPNZ(a)       CHOICE(loopnz a, loopnz a, loopnz a)
+#if !defined(_REAL_MODE) && !defined(_V86_MODE)
+#define        LSL(a, b)       CHOICE(lsl ARG2(a,b), lsl ARG2(a,b), lsl ARG2(b,a))
+#endif
+#define        LTR(a)          CHOICE(ltr a, ltr a, ltr a)
+#define        MOV_SR(a, b)    CHOICE(movw ARG2(a,b), mov ARG2(a,b), mov ARG2(b,a))
+#define        MOV_L(a, b)     CHOICE(movl ARG2(a,b), movl ARG2(a,b), _LTOG mov ARG2(b,a))
+#define        MOV_W(a, b)     CHOICE(movw ARG2(a,b), movw ARG2(a,b), _WTOG mov ARG2(b,a))
+#define        MOV_B(a, b)     CHOICE(movb ARG2(a,b), movb ARG2(a,b), movb ARG2(b,a))
+#define        MOVS_L          CHOICE(movsl, movsl, _LTOG movs)
+#define        MOVS_W          CHOICE(movsw, movsw, _WTOG movs)
+#define        MOVS_B          CHOICE(movsb, movsb, movsb)
+#define        MOVSX_BL(a, b)  CHOICE(movsbl ARG2(a,b), movsbl ARG2(a,b), movsx ARG2(b,a))
+#define        MOVSX_BW(a, b)  CHOICE(movsbw ARG2(a,b), movsbw ARG2(a,b), movsx ARG2(b,a))
+#define        MOVSX_WL(a, b)  CHOICE(movswl ARG2(a,b), movswl ARG2(a,b), movsx ARG2(b,a))
+#define        MOVZX_BL(a, b)  CHOICE(movzbl ARG2(a,b), movzbl ARG2(a,b), movzx ARG2(b,a))
+#define        MOVZX_BW(a, b)  CHOICE(movzbw ARG2(a,b), movzbw ARG2(a,b), movzx ARG2(b,a))
+#define        MOVZX_WL(a, b)  CHOICE(movzwl ARG2(a,b), movzwl ARG2(a,b), movzx ARG2(b,a))
+#define        MUL_L(a)        CHOICE(mull a, mull a, _LTOG mul a)
+#define        MUL_W(a)        CHOICE(mulw a, mulw a, _WTOG mul a)
+#define        MUL_B(a)        CHOICE(mulb a, mulb a, mulb a)
+#define        NEG_L(a)        CHOICE(negl a, negl a, _LTOG neg a)
+#define        NEG_W(a)        CHOICE(negw a, negw a, _WTOG neg a)
+#define        NEG_B(a)        CHOICE(negb a, negb a, negb a)
+#define        NOP             CHOICE(nop, nop, nop)
+#define        NOT_L(a)        CHOICE(notl a, notl a, _LTOG not a)
+#define        NOT_W(a)        CHOICE(notw a, notw a, _WTOG not a)
+#define        NOT_B(a)        CHOICE(notb a, notb a, notb a)
+#define        OR_L(a,b)       CHOICE(orl ARG2(a,b), orl ARG2(a,b), _LTOG or ARG2(b,a))
+#define        OR_W(a,b)       CHOICE(orw ARG2(a,b), orw ARG2(a,b), _WTOG or ARG2(b,a))
+#define        OR_B(a,b)       CHOICE(orb ARG2(a,b), orb ARG2(a,b), orb ARG2(b,a))
+#define        OUT_L           CHOICE(outl (DX), outl ARG2(EAX,DX), _LTOG out DX)
+#define        OUT_W           CHOICE(outw (DX), outw ARG2(AX,DX), _WTOG out DX)
+#define        OUT_B           CHOICE(outb (DX), outb ARG2(AL,DX), outb DX)
+/* Please AS code writer: use the following ONLY, if you refer to ports<256
+ * directly, but not in OUT1_W(DX), for instance, even if OUT1_ looks nicer
+ */
+#define        OUT1_L(a)       CHOICE(outl (a), outl ARG2(EAX,a), _LTOG out a)
+#define        OUT1_W(a)       CHOICE(outw (a), outw ARG2(AX,a), _WTOG out a)
+#define        OUT1_B(a)       CHOICE(outb (a), outb ARG2(AL,a), outb a)
+#define        OUTS_L          CHOICE(outsl, outsl, _LTOG outs)
+#define        OUTS_W          CHOICE(outsw, outsw, _WTOG outs)
+#define        OUTS_B          CHOICE(outsb, outsb, outsb)
+#define        POP_SR(a)       CHOICE(pop a, pop a, pop a)
+#define        POP_L(a)        CHOICE(popl a, popl a, _LTOG pop a)
+#define        POP_W(a)        CHOICE(popw a, popw a, _WTOG pop a)
+#define        POPA_L          CHOICE(popal, popal, _LTOG popa)
+#define        POPA_W          CHOICE(popaw, popaw, _WTOG popa)
+#define        POPF_L          CHOICE(popfl, popfl, _LTOG popf)
+#define        POPF_W          CHOICE(popfw, popfw, _WTOG popf)
+#define        PUSH_SR(a)      CHOICE(push a, push a, push a)
+#define        PUSH_L(a)       CHOICE(pushl a, pushl a, _LTOG push a)
+#define        PUSH_W(a)       CHOICE(pushw a, pushw a, _WTOG push a)
+#define        PUSH_B(a)       CHOICE(push a, pushb a, push a)
+#define        PUSHA_L         CHOICE(pushal, pushal, _LTOG pusha)
+#define        PUSHA_W         CHOICE(pushaw, pushaw, _WTOG pusha)
+#define        PUSHF_L         CHOICE(pushfl, pushfl, _LTOG pushf)
+#define        PUSHF_W         CHOICE(pushfw, pushfw, _WTOG pushf)
+#define        RCL_L(a, b)     CHOICE(rcll ARG2(a,b), rcll ARG2(a,b), _LTOG rcl ARG2(b,a))
+#define        RCL_W(a, b)     CHOICE(rclw ARG2(a,b), rclw ARG2(a,b), _WTOG rcl ARG2(b,a))
+#define        RCL_B(a, b)     CHOICE(rclb ARG2(a,b), rclb ARG2(a,b), rclb ARG2(b,a))
+#define        RCR_L(a, b)     CHOICE(rcrl ARG2(a,b), rcrl ARG2(a,b), _LTOG rcr ARG2(b,a))
+#define        RCR_W(a, b)     CHOICE(rcrw ARG2(a,b), rcrw ARG2(a,b), _WTOG rcr ARG2(b,a))
+#define        RCR_B(a, b)     CHOICE(rcrb ARG2(a,b), rcrb ARG2(a,b), rcrb ARG2(b,a))
+#define        ROL_L(a, b)     CHOICE(roll ARG2(a,b), roll ARG2(a,b), _LTOG rol ARG2(b,a))
+#define        ROL_W(a, b)     CHOICE(rolw ARG2(a,b), rolw ARG2(a,b), _WTOG rol ARG2(b,a))
+#define        ROL_B(a, b)     CHOICE(rolb ARG2(a,b), rolb ARG2(a,b), rolb ARG2(b,a))
+#define        ROR_L(a, b)     CHOICE(rorl ARG2(a,b), rorl ARG2(a,b), _LTOG ror ARG2(b,a))
+#define        ROR_W(a, b)     CHOICE(rorw ARG2(a,b), rorw ARG2(a,b), _WTOG ror ARG2(b,a))
+#define        ROR_B(a, b)     CHOICE(rorb ARG2(a,b), rorb ARG2(a,b), rorb ARG2(b,a))
+#define        REP             CHOICE(rep ;, rep ;, repe)
+#define        REPE            CHOICE(repz ;, repe ;, repe)
+#define        REPNE           CHOICE(repnz ;, repne ;, repne)
+#define        REPNZ           REPNE
+#define        REPZ            REPE
+#define        RET             CHOICE(ret, ret, ret)
+#define        SAHF            CHOICE(sahf, sahf, sahf)
+#define        SAL_L(a, b)     CHOICE(sall ARG2(a,b), sall ARG2(a,b), _LTOG sal ARG2(b,a))
+#define        SAL_W(a, b)     CHOICE(salw ARG2(a,b), salw ARG2(a,b), _WTOG sal ARG2(b,a))
+#define        SAL_B(a, b)     CHOICE(salb ARG2(a,b), salb ARG2(a,b), salb ARG2(b,a))
+#define        SAR_L(a, b)     CHOICE(sarl ARG2(a,b), sarl ARG2(a,b), _LTOG sar ARG2(b,a))
+#define        SAR_W(a, b)     CHOICE(sarw ARG2(a,b), sarw ARG2(a,b), _WTOG sar ARG2(b,a))
+#define        SAR_B(a, b)     CHOICE(sarb ARG2(a,b), sarb ARG2(a,b), sarb ARG2(b,a))
+#define        SBB_L(a, b)     CHOICE(sbbl ARG2(a,b), sbbl ARG2(a,b), _LTOG sbb ARG2(b,a))
+#define        SBB_W(a, b)     CHOICE(sbbw ARG2(a,b), sbbw ARG2(a,b), _WTOG sbb ARG2(b,a))
+#define        SBB_B(a, b)     CHOICE(sbbb ARG2(a,b), sbbb ARG2(a,b), sbbb ARG2(b,a))
+#define        SCAS_L          CHOICE(scasl, scasl, _LTOG scas)
+#define        SCAS_W          CHOICE(scasw, scasw, _WTOG scas)
+#define        SCAS_B          CHOICE(scasb, scasb, scasb)
+#define        SETA(a)         CHOICE(seta a, seta a, seta a)
+#define        SETAE(a)        CHOICE(setae a, setae a, setae a)
+#define        SETB(a)         CHOICE(setb a, setb a, setb a)
+#define        SETBE(a)        CHOICE(setbe a, setbe a, setbe a)
+#define        SETC(a)         CHOICE(setc a, setb a, setb a)
+#define        SETE(a)         CHOICE(sete a, sete a, sete a)
+#define        SETG(a)         CHOICE(setg a, setg a, setg a)
+#define        SETGE(a)        CHOICE(setge a, setge a, setge a)
+#define        SETL(a)         CHOICE(setl a, setl a, setl a)
+#define        SETLE(a)        CHOICE(setle a, setle a, setle a)
+#define        SETNA(a)        CHOICE(setna a, setna a, setna a)
+#define        SETNAE(a)       CHOICE(setnae a, setnae a, setnae a)
+#define        SETNB(a)        CHOICE(setnb a, setnb a, setnb a)
+#define        SETNBE(a)       CHOICE(setnbe a, setnbe a, setnbe a)
+#define        SETNC(a)        CHOICE(setnc a, setnb a, setnb a)
+#define        SETNE(a)        CHOICE(setne a, setne a, setne a)
+#define        SETNG(a)        CHOICE(setng a, setng a, setng a)
+#define        SETNGE(a)       CHOICE(setnge a, setnge a, setnge a)
+#define        SETNL(a)        CHOICE(setnl a, setnl a, setnl a)
+#define        SETNLE(a)       CHOICE(setnle a, setnle a, setnle a)
+#define        SETNO(a)        CHOICE(setno a, setno a, setno a)
+#define        SETNP(a)        CHOICE(setnp a, setnp a, setnp a)
+#define        SETNS(a)        CHOICE(setns a, setns a, setna a)
+#define        SETNZ(a)        CHOICE(setnz a, setnz a, setnz a)
+#define        SETO(a)         CHOICE(seto a, seto a, seto a)
+#define        SETP(a)         CHOICE(setp a, setp a, setp a)
+#define        SETPE(a)        CHOICE(setpe a, setpe a, setpe a)
+#define        SETPO(a)        CHOICE(setpo a, setpo a, setpo a)
+#define        SETS(a)         CHOICE(sets a, sets a, seta a)
+#define        SETZ(a)         CHOICE(setz a, setz a, setz a)
+#define        SGDT(a)         CHOICE(sgdt a, sgdt a, sgdt a)
+#define        SIDT(a)         CHOICE(sidt a, sidt a, sidt a)
+#define        SHL_L(a, b)     CHOICE(shll ARG2(a,b), shll ARG2(a,b), _LTOG shl ARG2(b,a))
+#define        SHL_W(a, b)     CHOICE(shlw ARG2(a,b), shlw ARG2(a,b), _WTOG shl ARG2(b,a))
+#define        SHL_B(a, b)     CHOICE(shlb ARG2(a,b), shlb ARG2(a,b), shlb ARG2(b,a))
+#define        SHLD_L(a,b,c)   CHOICE(shldl ARG3(a,b,c), shldl ARG3(a,b,c), _LTOG shld ARG3(c,b,a))
+#define        SHLD2_L(a,b)    CHOICE(shldl ARG2(a,b), shldl ARG3(CL,a,b), _LTOG shld ARG3(b,a,CL))
+#define        SHLD_W(a,b,c)   CHOICE(shldw ARG3(a,b,c), shldw ARG3(a,b,c), _WTOG shld ARG3(c,b,a))
+#define        SHLD2_W(a,b)    CHOICE(shldw ARG2(a,b), shldw ARG3(CL,a,b), _WTOG shld ARG3(b,a,CL))
+#define        SHR_L(a, b)     CHOICE(shrl ARG2(a,b), shrl ARG2(a,b), _LTOG shr ARG2(b,a))
+#define        SHR_W(a, b)     CHOICE(shrw ARG2(a,b), shrw ARG2(a,b), _WTOG shr ARG2(b,a))
+#define        SHR_B(a, b)     CHOICE(shrb ARG2(a,b), shrb ARG2(a,b), shrb ARG2(b,a))
+#define        SHRD_L(a,b,c)   CHOICE(shrdl ARG3(a,b,c), shrdl ARG3(a,b,c), _LTOG shrd ARG3(c,b,a))
+#define        SHRD2_L(a,b)    CHOICE(shrdl ARG2(a,b), shrdl ARG3(CL,a,b), _LTOG shrd ARG3(b,a,CL))
+#define        SHRD_W(a,b,c)   CHOICE(shrdw ARG3(a,b,c), shrdw ARG3(a,b,c), _WTOG shrd ARG3(c,b,a))
+#define        SHRD2_W(a,b)    CHOICE(shrdw ARG2(a,b), shrdw ARG3(CL,a,b), _WTOG shrd ARG3(b,a,CL))
+#define        SLDT(a)         CHOICE(sldt a, sldt a, sldt a)
+#define        SMSW(a)         CHOICE(smsw a, smsw a, smsw a)
+#define        STC             CHOICE(stc, stc, stc)
+#define        STD             CHOICE(std, std, std)
+#define        STI             CHOICE(sti, sti, sti)
+#define        STOS_L          CHOICE(stosl, stosl, _LTOG stos)
+#define        STOS_W          CHOICE(stosw, stosw, _WTOG stos)
+#define        STOS_B          CHOICE(stosb, stosb, stosb)
+#define        STR(a)          CHOICE(str a, str a, str a)
+#define        SUB_L(a, b)     CHOICE(subl ARG2(a,b), subl ARG2(a,b), _LTOG sub ARG2(b,a))
+#define        SUB_W(a, b)     CHOICE(subw ARG2(a,b), subw ARG2(a,b), _WTOG sub ARG2(b,a))
+#define        SUB_B(a, b)     CHOICE(subb ARG2(a,b), subb ARG2(a,b), subb ARG2(b,a))
+#define        TEST_L(a, b)    CHOICE(testl ARG2(a,b), testl ARG2(a,b), _LTOG test ARG2(b,a))
+#define        TEST_W(a, b)    CHOICE(testw ARG2(a,b), testw ARG2(a,b), _WTOG test ARG2(b,a))
+#define        TEST_B(a, b)    CHOICE(testb ARG2(a,b), testb ARG2(a,b), testb ARG2(b,a))
+#define        VERR(a)         CHOICE(verr a, verr a, verr a)
+#define        VERW(a)         CHOICE(verw a, verw a, verw a)
+#define        WAIT            CHOICE(wait, wait, wait)
+#define        XCHG_L(a, b)    CHOICE(xchgl ARG2(a,b), xchgl ARG2(a,b), _LTOG xchg ARG2(b,a))
+#define        XCHG_W(a, b)    CHOICE(xchgw ARG2(a,b), xchgw ARG2(a,b), _WTOG xchg ARG2(b,a))
+#define        XCHG_B(a, b)    CHOICE(xchgb ARG2(a,b), xchgb ARG2(a,b), xchgb ARG2(b,a))
+#define        XLAT            CHOICE(xlat, xlat, xlat)
+#define        XOR_L(a, b)     CHOICE(xorl ARG2(a,b), xorl ARG2(a,b), _LTOG xor ARG2(b,a))
+#define        XOR_W(a, b)     CHOICE(xorw ARG2(a,b), xorw ARG2(a,b), _WTOG xor ARG2(b,a))
+#define        XOR_B(a, b)     CHOICE(xorb ARG2(a,b), xorb ARG2(a,b), xorb ARG2(b,a))
+
+
+/* Floating Point Instructions */
+#define        F2XM1           CHOICE(f2xm1, f2xm1, f2xm1)
+#define        FABS            CHOICE(fabs, fabs, fabs)
+#define        FADD_D(a)       CHOICE(faddl a, faddl a, faddd a)
+#define        FADD_S(a)       CHOICE(fadds a, fadds a, fadds a)
+#define        FADD2(a, b)     CHOICE(fadd ARG2(a,b), fadd ARG2(a,b), fadd ARG2(b,a))
+#define        FADDP(a, b)     CHOICE(faddp ARG2(a,b), faddp ARG2(a,b), faddp ARG2(b,a))
+#define        FIADD_L(a)      CHOICE(fiaddl a, fiaddl a, fiaddl a)
+#define        FIADD_W(a)      CHOICE(fiadd a, fiadds a, fiadds a)
+#define        FBLD(a)         CHOICE(fbld a, fbld a, fbld a)
+#define        FBSTP(a)        CHOICE(fbstp a, fbstp a, fbstp a)
+#define        FCHS            CHOICE(fchs, fchs, fchs)
+#define        FCLEX           CHOICE(fclex, wait; fnclex, wait; fclex)
+#define        FNCLEX          CHOICE(fnclex, fnclex, fclex)
+#define        FCOM(a)         CHOICE(fcom a, fcom a, fcom a)
+#define        FCOM_D(a)       CHOICE(fcoml a, fcoml a, fcomd a)
+#define        FCOM_S(a)       CHOICE(fcoms a, fcoms a, fcoms a)
+#define        FCOMP(a)        CHOICE(fcomp a, fcomp a, fcomp a)
+#define        FCOMP_D(a)      CHOICE(fcompl a, fcompl a, fcompd a)
+#define        FCOMP_S(a)      CHOICE(fcomps a, fcomps a, fcomps a)
+#define        FCOMPP          CHOICE(fcompp, fcompp, fcompp)
+#define        FCOS            CHOICE(fcos, fcos, fcos)
+#define        FDECSTP         CHOICE(fdecstp, fdecstp, fdecstp)
+#define        FDIV_D(a)       CHOICE(fdivl a, fdivl a, fdivd a)
+#define        FDIV_S(a)       CHOICE(fdivs a, fdivs a, fdivs a)
+#define        FDIV2(a, b)     CHOICE(fdiv ARG2(a,b), fdiv ARG2(a,b), fdiv ARG2(b,a))
+#define        FDIVP(a, b)     CHOICE(fdivp ARG2(a,b), fdivp ARG2(a,b), fdivp ARG2(b,a))
+#define        FIDIV_L(a)      CHOICE(fidivl a, fidivl a, fidivl a)
+#define        FIDIV_W(a)      CHOICE(fidiv a, fidivs a, fidivs a)
+#define        FDIVR_D(a)      CHOICE(fdivrl a, fdivrl a, fdivrd a)
+#define        FDIVR_S(a)      CHOICE(fdivrs a, fdivrs a, fdivrs a)
+#define        FDIVR2(a, b)    CHOICE(fdivr ARG2(a,b), fdivr ARG2(a,b), fdivr ARG2(b,a))
+#define        FDIVRP(a, b)    CHOICE(fdivrp ARG2(a,b), fdivrp ARG2(a,b), fdivrp ARG2(b,a))
+#define        FIDIVR_L(a)     CHOICE(fidivrl a, fidivrl a, fidivrl a)
+#define        FIDIVR_W(a)     CHOICE(fidivr a, fidivrs a, fidivrs a)
+#define        FFREE(a)        CHOICE(ffree a, ffree a, ffree a)
+#define        FICOM_L(a)      CHOICE(ficoml a, ficoml a, ficoml a)
+#define        FICOM_W(a)      CHOICE(ficom a, ficoms a, ficoms a)
+#define        FICOMP_L(a)     CHOICE(ficompl a, ficompl a, ficompl a)
+#define        FICOMP_W(a)     CHOICE(ficomp a, ficomps a, ficomps a)
+#define        FILD_Q(a)       CHOICE(fildll a, fildq a, fildq a)
+#define        FILD_L(a)       CHOICE(fildl a, fildl a, fildl a)
+#define        FILD_W(a)       CHOICE(fild a, filds a, filds a)
+#define        FINCSTP         CHOICE(fincstp, fincstp, fincstp)
+#define        FINIT           CHOICE(finit, wait; fninit, wait; finit)
+#define        FNINIT          CHOICE(fninit, fninit, finit)
+#define        FIST_L(a)       CHOICE(fistl a, fistl a, fistl a)
+#define        FIST_W(a)       CHOICE(fist a, fists a, fists a)
+#define        FISTP_Q(a)      CHOICE(fistpll a, fistpq a, fistpq a)
+#define        FISTP_L(a)      CHOICE(fistpl a, fistpl a, fistpl a)
+#define        FISTP_W(a)      CHOICE(fistp a, fistps a, fistps a)
+#define        FLD_X(a)        CHOICE(fldt a, fldt a, fldx a) /* 80 bit data type! */
+#define        FLD_D(a)        CHOICE(fldl a, fldl a, fldd a)
+#define        FLD_S(a)        CHOICE(flds a, flds a, flds a)
+#define        FLD1            CHOICE(fld1, fld1, fld1)
+#define        FLDL2T          CHOICE(fldl2t, fldl2t, fldl2t)
+#define        FLDL2E          CHOICE(fldl2e, fldl2e, fldl2e)
+#define        FLDPI           CHOICE(fldpi, fldpi, fldpi)
+#define        FLDLG2          CHOICE(fldlg2, fldlg2, fldlg2)
+#define        FLDLN2          CHOICE(fldln2, fldln2, fldln2)
+#define        FLDZ            CHOICE(fldz, fldz, fldz)
+#define        FLDCW(a)        CHOICE(fldcw a, fldcw a, fldcw a)
+#define        FLDENV(a)       CHOICE(fldenv a, fldenv a, fldenv a)
+#define        FMUL_S(a)       CHOICE(fmuls a, fmuls a, fmuls a)
+#define        FMUL_D(a)       CHOICE(fmull a, fmull a, fmuld a)
+#define        FMUL2(a, b)     CHOICE(fmul ARG2(a,b), fmul ARG2(a,b), fmul ARG2(b,a))
+#define        FMULP(a, b)     CHOICE(fmulp ARG2(a,b), fmulp ARG2(a,b), fmulp ARG2(b,a))
+#define        FIMUL_L(a)      CHOICE(fimull a, fimull a, fimull a)
+#define        FIMUL_W(a)      CHOICE(fimul a, fimuls a, fimuls a)
+#define        FNOP            CHOICE(fnop, fnop, fnop)
+#define        FPATAN          CHOICE(fpatan, fpatan, fpatan)
+#define        FPREM           CHOICE(fprem, fprem, fprem)
+#define        FPREM1          CHOICE(fprem1, fprem1, fprem1)
+#define        FPTAN           CHOICE(fptan, fptan, fptan)
+#define        FRNDINT         CHOICE(frndint, frndint, frndint)
+#define        FRSTOR(a)       CHOICE(frstor a, frstor a, frstor a)
+#define        FSAVE(a)        CHOICE(fsave a, wait; fnsave a, wait; fsave a)
+#define        FNSAVE(a)       CHOICE(fnsave a, fnsave a, fsave a)
+#define        FSCALE          CHOICE(fscale, fscale, fscale)
+#define        FSIN            CHOICE(fsin, fsin, fsin)
+#define        FSINCOS         CHOICE(fsincos, fsincos, fsincos)
+#define        FSQRT           CHOICE(fsqrt, fsqrt, fsqrt)
+#define        FST_D(a)        CHOICE(fstl a, fstl a, fstd a)
+#define        FST_S(a)        CHOICE(fsts a, fsts a, fsts a)
+#define        FSTP_X(a)       CHOICE(fstpt a, fstpt a, fstpx a)
+#define        FSTP_D(a)       CHOICE(fstpl a, fstpl a, fstpd a)
+#define        FSTP_S(a)       CHOICE(fstps a, fstps a, fstps a)
+#define        FSTP(a)         CHOICE(fstp a, fstp a, fstp a)
+#define        FSTCW(a)        CHOICE(fstcw a, wait; fnstcw a, wait; fstcw a)
+#define        FNSTCW(a)       CHOICE(fnstcw a, fnstcw a, fstcw a)
+#define        FSTENV(a)       CHOICE(fstenv a, wait; fnstenv a, fstenv a)
+#define        FNSTENV(a)      CHOICE(fnstenv a, fnstenv a, fstenv a)
+#define        FSTSW(a)        CHOICE(fstsw a, wait; fnstsw a, wait; fstsw a)
+#define        FNSTSW(a)       CHOICE(fnstsw a, fnstsw a, fstsw a)
+#define        FSUB_S(a)       CHOICE(fsubs a, fsubs a, fsubs a)
+#define        FSUB_D(a)       CHOICE(fsubl a, fsubl a, fsubd a)
+#define        FSUB2(a, b)     CHOICE(fsub ARG2(a,b), fsub ARG2(a,b), fsub ARG2(b,a))
+#define        FSUBP(a, b)     CHOICE(fsubp ARG2(a,b), fsubp ARG2(a,b), fsubp ARG2(b,a))
+#define        FISUB_L(a)      CHOICE(fisubl a, fisubl a, fisubl a)
+#define        FISUB_W(a)      CHOICE(fisub a, fisubs a, fisubs a)
+#define        FSUBR_S(a)      CHOICE(fsubrs a, fsubrs a, fsubrs a)
+#define        FSUBR_D(a)      CHOICE(fsubrl a, fsubrl a, fsubrd a)
+#define        FSUBR2(a, b)    CHOICE(fsubr ARG2(a,b), fsubr ARG2(a,b), fsubr ARG2(b,a))
+#define        FSUBRP(a, b)    CHOICE(fsubrp ARG2(a,b), fsubrp ARG2(a,b), fsubrp ARG2(b,a))
+#define        FISUBR_L(a)     CHOICE(fisubrl a, fisubrl a, fisubrl a)
+#define        FISUBR_W(a)     CHOICE(fisubr a, fisubrs a, fisubrs a)
+#define        FTST            CHOICE(ftst, ftst, ftst)
+#define        FUCOM(a)        CHOICE(fucom a, fucom a, fucom a)
+#define        FUCOMP(a)       CHOICE(fucomp a, fucomp a, fucomp a)
+#define        FUCOMPP         CHOICE(fucompp, fucompp, fucompp)
+#define        FWAIT           CHOICE(wait, wait, wait)
+#define        FXAM            CHOICE(fxam, fxam, fxam)
+#define        FXCH(a)         CHOICE(fxch a, fxch a, fxch a)
+#define        FXTRACT         CHOICE(fxtract, fxtract, fxtract)
+#define        FYL2X           CHOICE(fyl2x, fyl2x, fyl2x)
+#define        FYL2XP1         CHOICE(fyl2xp1, fyl2xp1, fyl2xp1)
+
+/* New instructions */
+#define        CPUID           CHOICE(D_BYTE ARG2(15, 162), cpuid, D_BYTE ARG2(15, 162))
+#define        RDTSC           CHOICE(D_BYTE ARG2(15, 49), rdtsc, D_BYTE ARG2(15, 49))
+
+#else /* NASM_ASSEMBLER || MASM_ASSEMBLER is defined */
+
+       /****************************************/
+       /*                                      */
+       /*      Intel style assemblers.         */
+       /*      (NASM and MASM)                 */
+       /*                                      */
+       /****************************************/
+
+#define P_EAX  EAX
+#define L_EAX  EAX
+#define W_AX   AX
+#define B_AH   AH
+#define B_AL   AL
+
+#define P_EBX  EBX
+#define L_EBX  EBX
+#define W_BX   BX
+#define B_BH   BH
+#define B_BL   BL
+
+#define P_ECX  ECX
+#define L_ECX  ECX
+#define W_CX   CX
+#define B_CH   CH
+#define B_CL   CL
+
+#define P_EDX  EDX
+#define L_EDX  EDX
+#define W_DX   DX
+#define B_DH   DH
+#define B_DL   DL
+
+#define P_EBP  EBP
+#define L_EBP  EBP
+#define W_BP   BP
+
+#define P_ESI  ESI
+#define L_ESI  ESI
+#define W_SI   SI
+
+#define P_EDI  EDI
+#define L_EDI  EDI
+#define W_DI   DI
+
+#define P_ESP  ESP
+#define L_ESP  ESP
+#define W_SP   SP
+
+#define W_CS   CS
+#define W_SS   SS
+#define W_DS   DS
+#define W_ES   ES
+#define W_FS   FS
+#define W_GS   GS
+
+#define X_ST   ST
+#define D_ST   ST
+#define L_ST   ST
+
+#define P_MM0  mm0
+#define P_MM1  mm1
+#define P_MM2  mm2
+#define P_MM3  mm3
+#define P_MM4  mm4
+#define P_MM5  mm5
+#define P_MM6  mm6
+#define P_MM7  mm7
+
+#define P_XMM0         xmm0
+#define P_XMM1         xmm1
+#define P_XMM2         xmm2
+#define P_XMM3         xmm3
+#define P_XMM4         xmm4
+#define P_XMM5         xmm5
+#define P_XMM6         xmm6
+#define P_XMM7         xmm7
+
+#if defined(NASM_ASSEMBLER)
+
+#define ST(n) st ## n
+
+#define TBYTE_PTR tword
+#define QWORD_PTR qword
+#define DWORD_PTR dword
+#define WORD_PTR word
+#define BYTE_PTR byte
+
+#define OFFSET
+
+#define GLOBL GLOBAL
+#define ALIGNTEXT32 ALIGN 32
+#define ALIGNTEXT16 ALIGN 16
+#define ALIGNTEXT8 ALIGN 8
+#define ALIGNTEXT4 ALIGN 4
+#define ALIGNTEXT2 ALIGN 2
+#define ALIGNTEXT32ifNOP ALIGN 32
+#define ALIGNTEXT16ifNOP ALIGN 16
+#define ALIGNTEXT8ifNOP ALIGN 8
+#define ALIGNTEXT4ifNOP ALIGN 4
+#define ALIGNDATA32 ALIGN 32
+#define ALIGNDATA16 ALIGN 16
+#define ALIGNDATA8 ALIGN 8
+#define ALIGNDATA4 ALIGN 4
+#define ALIGNDATA2 ALIGN 2
+#define FILE(s)
+#define STRING(s) db s
+#define D_LONG dd
+#define D_WORD dw
+#define D_BYTE db
+/* #define SPACE */
+/* #define COMM */
+#define SEG_DATA SECTION .data
+#define SEG_TEXT SECTION .text
+#define SEG_BSS SECTION .bss
+
+#define D_SPACE(n) db n REP 0
+
+#define AS_BEGIN
+
+#define NEAR near      /* Jcc's should be handled better than this... */
+
+#else /* MASM */
+
+#define TBYTE_PTR tbyte ptr
+#define QWORD_PTR qword ptr
+#define DWORD_PTR dword ptr
+#define WORD_PTR word ptr
+#define BYTE_PTR byte ptr
+
+#define OFFSET offset
+
+#define GLOBL GLOBAL
+#define ALIGNTEXT32 ALIGN 32
+#define ALIGNTEXT16 ALIGN 16
+#define ALIGNTEXT8 ALIGN 8
+#define ALIGNTEXT4 ALIGN 4
+#define ALIGNTEXT2 ALIGN 2
+#define ALIGNTEXT32ifNOP ALIGN 32
+#define ALIGNTEXT16ifNOP ALIGN 16
+#define ALIGNTEXT8ifNOP ALIGN 8
+#define ALIGNTEXT4ifNOP ALIGN 4
+#define ALIGNDATA32 ALIGN 32
+#define ALIGNDATA16 ALIGN 16
+#define ALIGNDATA8 ALIGN 8
+#define ALIGNDATA4 ALIGN 4
+#define ALIGNDATA2 ALIGN 2
+#define FILE(s)
+#define STRING(s) db s
+#define D_LONG dd
+#define D_WORD dw
+#define D_BYTE db
+/* #define SPACE */
+/* #define COMM */
+#define SEG_DATA .DATA
+#define SEG_TEXT .CODE
+#define SEG_BSS .DATA
+
+#define D_SPACE(n) db n REP 0
+
+#define AS_BEGIN
+
+#define NEAR
+
+#endif
+
+#if defined(Lynx) || (defined(SYSV) || defined(SVR4)) \
+|| (defined(linux) || defined(__OS2ELF__)) && defined(__ELF__)
+#define GLNAME(a) a
+#else
+#define GLNAME(a) _ ## a
+#endif
+
+/*
+ *     Addressing Modes
+ */
+
+/* Immediate Mode */
+#define P_ADDR(a)      OFFSET a
+#define X_ADDR(a)      OFFSET a
+#define D_ADDR(a)      OFFSET a
+#define L_ADDR(a)      OFFSET a
+#define W_ADDR(a)      OFFSET a
+#define B_ADDR(a)      OFFSET a
+
+#define P_CONST(a)     a
+#define X_CONST(a)     a
+#define D_CONST(a)     a
+#define L_CONST(a)     a
+#define W_CONST(a)     a
+#define B_CONST(a)     a
+
+/* Indirect Mode */
+#define P_CONTENT(a)   a
+#define X_CONTENT(a)   TBYTE_PTR a
+#define D_CONTENT(a)   QWORD_PTR a
+#define L_CONTENT(a)   DWORD_PTR a
+#define W_CONTENT(a)   WORD_PTR a
+#define B_CONTENT(a)   BYTE_PTR a
+
+/* Register a indirect */
+#define P_REGIND(a)    [a]
+#define X_REGIND(a)    TBYTE_PTR [a]
+#define D_REGIND(a)    QWORD_PTR [a]
+#define L_REGIND(a)    DWORD_PTR [a]
+#define W_REGIND(a)    WORD_PTR [a]
+#define B_REGIND(a)    BYTE_PTR [a]
+
+/* Register b indirect plus displacement a */
+#define P_REGOFF(a, b)         [a + b]
+#define X_REGOFF(a, b)         TBYTE_PTR [a + b]
+#define D_REGOFF(a, b)         QWORD_PTR [a + b]
+#define L_REGOFF(a, b)         DWORD_PTR [a + b]
+#define W_REGOFF(a, b)         WORD_PTR [a + b]
+#define B_REGOFF(a, b)         BYTE_PTR [a + b]
+
+/* Reg indirect Base + Index + Displacement  - this is mainly for 16-bit mode
+ * which has no scaling
+ */
+#define P_REGBID(b, i, d)      [b + i + d]
+#define X_REGBID(b, i, d)      TBYTE_PTR [b + i + d]
+#define D_REGBID(b, i, d)      QWORD_PTR [b + i + d]
+#define L_REGBID(b, i, d)      DWORD_PTR [b + i + d]
+#define W_REGBID(b, i, d)      WORD_PTR [b + i + d]
+#define B_REGBID(b, i, d)      BYTE_PTR [b + i + d]
+
+/* Reg indirect Base + (Index * Scale) + Displacement */
+#define P_REGBISD(b, i, s, d)  [b + i * s + d]
+#define X_REGBISD(b, i, s, d)  TBYTE_PTR [b + i * s + d]
+#define D_REGBISD(b, i, s, d)  QWORD_PTR [b + i * s + d]
+#define L_REGBISD(b, i, s, d)  DWORD_PTR [b + i * s + d]
+#define W_REGBISD(b, i, s, d)  WORD_PTR [b + i * s + d]
+#define B_REGBISD(b, i, s, d)  BYTE_PTR [b + i * s + d]
+
+/* Displaced Scaled Index: */
+#define P_REGDIS(d, i, s)      [i * s + d]
+#define X_REGDIS(d, i, s)      TBYTE_PTR [i * s + d]
+#define D_REGDIS(d, i, s)      QWORD_PTR [i * s + d]
+#define L_REGDIS(d, i, s)      DWORD_PTR [i * s + d]
+#define W_REGDIS(d, i, s)      WORD_PTR [i * s + d]
+#define B_REGDIS(d, i, s)      BYTE_PTR [i * s + d]
+
+/* Indexed Base: */
+#define P_REGBI(b, i)  [b + i]
+#define X_REGBI(b, i)  TBYTE_PTR [b + i]
+#define D_REGBI(b, i)  QWORD_PTR [b + i]
+#define L_REGBI(b, i)  DWORD_PTR [b + i]
+#define W_REGBI(b, i)  WORD_PTR [b + i]
+#define B_REGBI(b, i)  BYTE_PTR [b + i]
+
+/* Displaced Base: */
+#define P_REGDB(d, b)  [b + d]
+#define X_REGDB(d, b)  TBYTE_PTR [b + d]
+#define D_REGDB(d, b)  QWORD_PTR [b + d]
+#define L_REGDB(d, b)  DWORD_PTR [b + d]
+#define W_REGDB(d, b)  WORD_PTR [b + d]
+#define B_REGDB(d, b)  BYTE_PTR [b + d]
+
+/* Variable indirect: */
+#define VARINDIRECT(var)       [var]
+
+/* Use register contents as jump/call target: */
+#define CODEPTR(reg)   [reg]
+
+/*
+ *     Redefine assembler commands
+ */
+
+#define P_(a)  P_ ## a
+#define X_(a)  X_ ## a
+#define D_(a)  D_ ## a
+#define S_(a)  L_ ## a
+#define L_(a)  L_ ## a
+#define W_(a)  W_ ## a
+#define B_(a)  B_ ## a
+
+#define        AAA             aaa             
+#define        AAD             aad             
+#define        AAM             aam             
+#define        AAS             aas             
+#define        ADC_L(a, b)     adc L_(b), L_(a)
+#define        ADC_W(a, b)     adc W_(b), W_(a)
+#define        ADC_B(a, b)     adc B_(b), B_(a)
+#define        ADD_L(a, b)     add L_(b), L_(a)
+#define        ADD_W(a, b)     add W_(b), W_(a)
+#define        ADD_B(a, b)     add B_(b), B_(a)
+#define        AND_L(a, b)     and L_(b), L_(a)
+#define        AND_W(a, b)     and W_(b), W_(a)
+#define        AND_B(a, b)     and B_(b), B_(a)
+#define        ARPL(a,b)       arpl W_(b), a
+#define        BOUND_L(a, b)   bound L_(b), L_(a)
+#define        BOUND_W(a, b)   bound W_(b), W_(a)
+#define        BSF_L(a, b)     bsf L_(b), L_(a)
+#define        BSF_W(a, b)     bsf W_(b), W_(a)
+#define        BSR_L(a, b)     bsr L_(b), L_(a)
+#define        BSR_W(a, b)     bsr W_(b), W_(a)
+#define        BT_L(a, b)      bt L_(b), L_(a)
+#define        BT_W(a, b)      bt W_(b), W_(a)
+#define        BTC_L(a, b)     btc L_(b), L_(a)
+#define        BTC_W(a, b)     btc W_(b), W_(a)
+#define        BTR_L(a, b)     btr L_(b), L_(a)
+#define        BTR_W(a, b)     btr W_(b), W_(a)
+#define        BTS_L(a, b)     bts L_(b), L_(a)
+#define        BTS_W(a, b)     bts W_(b), W_(a)
+#define        CALL(a)         call a
+#define        CALLF(s,a)      call far s:a
+#define        CBW             cbw             
+#define        CWDE            cwde            
+#define        CLC             clc             
+#define        CLD             cld             
+#define        CLI             cli             
+#define        CLTS            clts            
+#define        CMC             cmc             
+#define        CMP_L(a, b)     cmp L_(b), L_(a)
+#define        CMP_W(a, b)     cmp W_(b), W_(a)
+#define        CMP_B(a, b)     cmp B_(b), B_(a)
+#define        CMPS_L          cmpsd
+#define        CMPS_W          cmpsw
+#define        CMPS_B          cmpsb
+#define        CWD             cwd             
+#define        CDQ             cdq             
+#define        DAA             daa             
+#define        DAS             das             
+#define        DEC_L(a)        dec L_(a)
+#define        DEC_W(a)        dec W_(a)
+#define        DEC_B(a)        dec B_(a)
+#define        DIV_L(a)        div L_(a)
+#define        DIV_W(a)        div W_(a)
+#define        DIV_B(a)        div B_(a)
+#define        ENTER(a,b)      enter b, a
+#define        HLT             hlt             
+#define        IDIV_L(a)       idiv L_(a)
+#define        IDIV_W(a)       idiv W_(a)
+#define        IDIV_B(a)       idiv B_(a)
+#define        IMUL_L(a, b)    imul L_(b), L_(a)
+#define        IMUL_W(a, b)    imul W_(b), W_(a)
+#define        IMUL_B(a)       imul B_(a)
+#define        IN_L            in EAX, DX
+#define        IN_W            in AX, DX
+#define        IN_B            in AL, DX
+#define        IN1_L(a)        in1 L_(a)
+#define        IN1_W(a)        in1 W_(a)
+#define        IN1_B(a)        in1 B_(a)
+#define        INC_L(a)        inc L_(a)
+#define        INC_W(a)        inc W_(a)
+#define        INC_B(a)        inc B_(a)
+#define        INS_L           ins
+#define        INS_W           ins
+#define        INS_B           ins
+#define        INT(a)          int B_(a)
+#define        INT3            int3            
+#define        INTO            into            
+#define        IRET            iret            
+#define        IRETD           iretd           
+#define        JA(a)           ja NEAR a
+#define        JAE(a)          jae NEAR a
+#define        JB(a)           jb NEAR a
+#define        JBE(a)          jbe NEAR a
+#define        JC(a)           jc NEAR a
+#define        JE(a)           je NEAR a
+#define        JG(a)           jg NEAR a
+#define        JGE(a)          jge NEAR a
+#define        JL(a)           jl NEAR a
+#define        JLE(a)          jle NEAR a
+#define        JNA(a)          jna NEAR a
+#define        JNAE(a)         jnae NEAR a
+#define        JNB(a)          jnb NEAR a
+#define        JNBE(a)         jnbe NEAR a
+#define        JNC(a)          jnc NEAR a
+#define        JNE(a)          jne NEAR a
+#define        JNG(a)          jng NEAR a
+#define        JNGE(a)         jnge NEAR a
+#define        JNL(a)          jnl NEAR a
+#define        JNLE(a)         jnle NEAR a
+#define        JNO(a)          jno NEAR a
+#define        JNP(a)          jnp NEAR a
+#define        JNS(a)          jns NEAR a
+#define        JNZ(a)          jnz NEAR a
+#define        JO(a)           jo NEAR a
+#define        JP(a)           jp NEAR a
+#define        JPE(a)          jpe NEAR a
+#define        JPO(a)          jpo NEAR a
+#define        JS(a)           js NEAR a
+#define        JZ(a)           jz NEAR a
+#define        JMP(a)          jmp a
+#define        JMPF(s,a)       jmpf
+#define        LAHF            lahf            
+#define        LAR(a, b)       lar b, a
+#define        LEA_L(a, b)     lea P_(b), P_(a)
+#define        LEA_W(a, b)     lea P_(b), P_(a)
+#define        LEAVE           leave           
+#define        LGDT(a)         lgdt a
+#define        LIDT(a)         lidt a
+#define        LDS(a, b)       lds b, a
+#define        LES(a, b)       les b, a
+#define        LFS(a, b)       lfs b, a
+#define        LGS(a, b)       lgs b, a
+#define        LSS(a, b)       lss b, a
+#define        LLDT(a)         lldt a
+#define        LMSW(a)         lmsw a
+#define LOCK           lock            
+#define        LODS_L          lodsd
+#define        LODS_W          lodsw
+#define        LODS_B          lodsb
+#define        LOOP(a)         loop a
+#define        LOOPE(a)        loope a
+#define        LOOPZ(a)        loopz a
+#define        LOOPNE(a)       loopne a
+#define        LOOPNZ(a)       loopnz a
+#define        LSL(a, b)       lsl b, a
+#define        LTR(a)          ltr a
+#define        MOV_SR(a, b)    mov S_(b), S_(a)
+#define        MOV_L(a, b)     mov L_(b), L_(a)
+#define        MOV_W(a, b)     mov W_(b), W_(a)
+#define        MOV_B(a, b)     mov B_(b), B_(a)
+#define        MOVS_L          movsd
+#define        MOVS_W          movsw
+#define        MOVS_B          movsb
+#define        MOVSX_BL(a, b)  movsx B_(b), B_(a)
+#define        MOVSX_BW(a, b)  movsx B_(b), B_(a)
+#define        MOVSX_WL(a, b)  movsx W_(b), W_(a)
+#define        MOVZX_BL(a, b)  movzx B_(b), B_(a)
+#define        MOVZX_BW(a, b)  movzx B_(b), B_(a)
+#define        MOVZX_WL(a, b)  movzx W_(b), W_(a)
+#define        MUL_L(a)        mul L_(a)
+#define        MUL_W(a)        mul W_(a)
+#define        MUL_B(a)        mul B_(a)
+#define        NEG_L(a)        neg L_(a)
+#define        NEG_W(a)        neg W_(a)
+#define        NEG_B(a)        neg B_(a)
+#define        NOP             nop             
+#define        NOT_L(a)        not L_(a)
+#define        NOT_W(a)        not W_(a)
+#define        NOT_B(a)        not B_(a)
+#define        OR_L(a,b)       or L_(b), L_(a)
+#define        OR_W(a,b)       or W_(b), W_(a)
+#define        OR_B(a,b)       or B_(b), B_(a)
+#define        OUT_L           out DX, EAX
+#define        OUT_W           out DX, AX
+#define        OUT_B           out DX, AL
+#define        OUT1_L(a)       out1 L_(a)
+#define        OUT1_W(a)       out1 W_(a)
+#define        OUT1_B(a)       out1 B_(a)
+#define        OUTS_L          outsd
+#define        OUTS_W          outsw
+#define        OUTS_B          outsb
+#define        POP_SR(a)       pop S_(a)
+#define        POP_L(a)        pop L_(a)
+#define        POP_W(a)        pop W_(a)
+#define        POPA_L          popad
+#define        POPA_W          popa
+#define        POPF_L          popfd
+#define        POPF_W          popf
+#define        PUSH_SR(a)      push S_(a)
+#define        PUSH_L(a)       push L_(a)
+#define        PUSH_W(a)       push W_(a)
+#define        PUSH_B(a)       push B_(a)
+#define        PUSHA_L         pushad
+#define        PUSHA_W         pusha
+#define        PUSHF_L         pushfd
+#define        PUSHF_W         pushf
+#define        RCL_L(a, b)     rcl L_(b), L_(a)
+#define        RCL_W(a, b)     rcl W_(b), W_(a)
+#define        RCL_B(a, b)     rcl B_(b), B_(a)
+#define        RCR_L(a, b)     rcr L_(b), L_(a)
+#define        RCR_W(a, b)     rcr W_(b), W_(a)
+#define        RCR_B(a, b)     rcr B_(b), B_(a)
+#define        ROL_L(a, b)     rol L_(b), L_(a)
+#define        ROL_W(a, b)     rol W_(b), W_(a)
+#define        ROL_B(a, b)     rol B_(b), B_(a)
+#define        ROR_L(a, b)     ror L_(b), L_(a)
+#define        ROR_W(a, b)     ror W_(b), W_(a)
+#define        ROR_B(a, b)     ror B_(b), B_(a)
+#define        REP             rep             
+#define        REPE            repe            
+#define        REPNE           repne           
+#define        REPNZ           REPNE
+#define        REPZ            REPE
+#define        RET             ret             
+#define        SAHF            sahf            
+#define        SAL_L(a, b)     sal L_(b), L_(a)
+#define        SAL_W(a, b)     sal W_(b), W_(a)
+#define        SAL_B(a, b)     sal B_(b), B_(a)
+#define        SAR_L(a, b)     sar L_(b), L_(a)
+#define        SAR_W(a, b)     sar W_(b), W_(a)
+#define        SAR_B(a, b)     sar B_(b), B_(a)
+#define        SBB_L(a, b)     sbb L_(b), L_(a)
+#define        SBB_W(a, b)     sbb W_(b), W_(a)
+#define        SBB_B(a, b)     sbb B_(b), B_(a)
+#define        SCAS_L          scas
+#define        SCAS_W          scas
+#define        SCAS_B          scas
+#define        SETA(a)         seta a
+#define        SETAE(a)        setae a
+#define        SETB(a)         setb a
+#define        SETBE(a)        setbe a
+#define        SETC(a)         setc a
+#define        SETE(a)         sete a
+#define        SETG(a)         setg a
+#define        SETGE(a)        setge a
+#define        SETL(a)         setl a
+#define        SETLE(a)        setle a
+#define        SETNA(a)        setna a
+#define        SETNAE(a)       setnae a
+#define        SETNB(a)        setnb a
+#define        SETNBE(a)       setnbe a
+#define        SETNC(a)        setnc a
+#define        SETNE(a)        setne a
+#define        SETNG(a)        setng a
+#define        SETNGE(a)       setnge a
+#define        SETNL(a)        setnl a
+#define        SETNLE(a)       setnle a
+#define        SETNO(a)        setno a
+#define        SETNP(a)        setnp a
+#define        SETNS(a)        setns a
+#define        SETNZ(a)        setnz a
+#define        SETO(a)         seto a
+#define        SETP(a)         setp a
+#define        SETPE(a)        setpe a
+#define        SETPO(a)        setpo a
+#define        SETS(a)         sets a
+#define        SETZ(a)         setz a
+#define        SGDT(a)         sgdt a
+#define        SIDT(a)         sidt a
+#define        SHL_L(a, b)     shl L_(b), L_(a)
+#define        SHL_W(a, b)     shl W_(b), W_(a)
+#define        SHL_B(a, b)     shl B_(b), B_(a)
+#define        SHLD_L(a,b,c)   shld
+#define        SHLD2_L(a,b)    shld L_(b), L_(a)
+#define        SHLD_W(a,b,c)   shld
+#define        SHLD2_W(a,b)    shld W_(b), W_(a)
+#define        SHR_L(a, b)     shr L_(b), L_(a)
+#define        SHR_W(a, b)     shr W_(b), W_(a)
+#define        SHR_B(a, b)     shr B_(b), B_(a)
+#define        SHRD_L(a,b,c)   shrd
+#define        SHRD2_L(a,b)    shrd L_(b), L_(a)
+#define        SHRD_W(a,b,c)   shrd
+#define        SHRD2_W(a,b)    shrd W_(b), W_(a)
+#define        SLDT(a)         sldt a
+#define        SMSW(a)         smsw a
+#define        STC             stc             
+#define        STD             std             
+#define        STI             sti             
+#define        STOS_L          stos
+#define        STOS_W          stos
+#define        STOS_B          stos
+#define        STR(a)          str a
+#define        SUB_L(a, b)     sub L_(b), L_(a)
+#define        SUB_W(a, b)     sub W_(b), W_(a)
+#define        SUB_B(a, b)     sub B_(b), B_(a)
+#define        TEST_L(a, b)    test L_(b), L_(a)
+#define        TEST_W(a, b)    test W_(b), W_(a)
+#define        TEST_B(a, b)    test B_(b), B_(a)
+#define        VERR(a)         verr a
+#define        VERW(a)         verw a
+#define        WAIT            wait            
+#define        XCHG_L(a, b)    xchg L_(b), L_(a)
+#define        XCHG_W(a, b)    xchg W_(b), W_(a)
+#define        XCHG_B(a, b)    xchg B_(b), B_(a)
+#define        XLAT            xlat            
+#define        XOR_L(a, b)     xor L_(b), L_(a)
+#define        XOR_W(a, b)     xor W_(b), W_(a)
+#define        XOR_B(a, b)     xor B_(b), B_(a)
+#define        F2XM1           f2xm1           
+#define        FABS            fabs            
+#define        FADD_D(a)       fadd D_(a)
+#define        FADD_S(a)       fadd S_(a)
+#define        FADD2(a, b)     fadd b, a
+#define        FADDP(a, b)     faddp b, a
+#define        FIADD_L(a)      fiadd L_(a)
+#define        FIADD_W(a)      fiadd W_(a)
+#define        FBLD(a)         fbld a
+#define        FBSTP(a)        fbstp a
+#define        FCHS            fchs            
+#define        FCLEX           fclex           
+#define        FNCLEX          fnclex          
+#define        FCOM(a)         fcom a
+#define        FCOM_D(a)       fcom D_(a)
+#define        FCOM_S(a)       fcom S_(a)
+#define        FCOMP(a)        fcomp a
+#define        FCOMP_D(a)      fcomp D_(a)
+#define        FCOMP_S(a)      fcomp S_(a)
+#define        FCOMPP          fcompp          
+#define        FCOS            fcos            
+#define        FDECSTP         fdecstp         
+#define        FDIV_D(a)       fdiv D_(a)
+#define        FDIV_S(a)       fdiv S_(a)
+#define        FDIV2(a, b)     fdiv b, a
+#define        FDIVP(a, b)     fdivp b, a
+#define        FIDIV_L(a)      fidiv L_(a)
+#define        FIDIV_W(a)      fidiv W_(a)
+#define        FDIVR_D(a)      fdivr D_(a)
+#define        FDIVR_S(a)      fdivr S_(a)
+#define        FDIVR2(a, b)    fdivr b, a
+#define        FDIVRP(a, b)    fdivrp b, a
+#define        FIDIVR_L(a)     fidivr L_(a)
+#define        FIDIVR_W(a)     fidivr W_(a)
+#define        FFREE(a)        ffree a
+#define        FICOM_L(a)      ficom L_(a)
+#define        FICOM_W(a)      ficom W_(a)
+#define        FICOMP_L(a)     ficomp L_(a)
+#define        FICOMP_W(a)     ficomp W_(a)
+#define        FILD_Q(a)       fild D_(a)
+#define        FILD_L(a)       fild L_(a)
+#define        FILD_W(a)       fild W_(a)
+#define        FINCSTP         fincstp         
+#define        FINIT           finit           
+#define        FNINIT          fninit          
+#define        FIST_L(a)       fist L_(a)
+#define        FIST_W(a)       fist W_(a)
+#define        FISTP_Q(a)      fistp D_(a)
+#define        FISTP_L(a)      fistp L_(a)
+#define        FISTP_W(a)      fistp W_(a)
+#define        FLD_X(a)        fld X_(a)
+#define        FLD_D(a)        fld D_(a)
+#define        FLD_S(a)        fld S_(a)
+#define        FLD1            fld1            
+#define        FLDL2T          fldl2t          
+#define        FLDL2E          fldl2e          
+#define        FLDPI           fldpi           
+#define        FLDLG2          fldlg2          
+#define        FLDLN2          fldln2          
+#define        FLDZ            fldz            
+#define        FLDCW(a)        fldcw a
+#define        FLDENV(a)       fldenv a
+#define        FMUL_S(a)       fmul S_(a)
+#define        FMUL_D(a)       fmul D_(a)
+#define        FMUL2(a, b)     fmul b, a
+#define        FMULP(a, b)     fmulp b, a
+#define        FIMUL_L(a)      fimul L_(a)
+#define        FIMUL_W(a)      fimul W_(a)
+#define        FNOP            fnop            
+#define        FPATAN          fpatan          
+#define        FPREM           fprem           
+#define        FPREM1          fprem1          
+#define        FPTAN           fptan           
+#define        FRNDINT         frndint         
+#define        FRSTOR(a)       frstor a
+#define        FSAVE(a)        fsave a
+#define        FNSAVE(a)       fnsave a
+#define        FSCALE          fscale          
+#define        FSIN            fsin            
+#define        FSINCOS         fsincos         
+#define        FSQRT           fsqrt           
+#define        FST_D(a)        fst D_(a)
+#define        FST_S(a)        fst S_(a)
+#define        FSTP_X(a)       fstp X_(a)
+#define        FSTP_D(a)       fstp D_(a)
+#define        FSTP_S(a)       fstp S_(a)
+#define        FSTP(a)         fstp a
+#define        FSTCW(a)        fstcw a
+#define        FNSTCW(a)       fnstcw a
+#define        FSTENV(a)       fstenv a
+#define        FNSTENV(a)      fnstenv a
+#define        FSTSW(a)        fstsw a
+#define        FNSTSW(a)       fnstsw a
+#define        FSUB_S(a)       fsub S_(a)
+#define        FSUB_D(a)       fsub D_(a)
+#define        FSUB2(a, b)     fsub b, a
+#define        FSUBP(a, b)     fsubp b, a
+#define        FISUB_L(a)      fisub L_(a)
+#define        FISUB_W(a)      fisub W_(a)
+#define        FSUBR_S(a)      fsubr S_(a)
+#define        FSUBR_D(a)      fsubr D_(a)
+#define        FSUBR2(a, b)    fsubr b, a
+#define        FSUBRP(a, b)    fsubrp b, a
+#define        FISUBR_L(a)     fisubr L_(a)
+#define        FISUBR_W(a)     fisubr W_(a)
+#define        FTST            ftst            
+#define        FUCOM(a)        fucom a
+#define        FUCOMP(a)       fucomp a
+#define        FUCOMPP         fucompp         
+#define        FWAIT           fwait           
+#define        FXAM            fxam            
+#define        FXCH(a)         fxch a
+#define        FXTRACT         fxtract         
+#define        FYL2X           fyl2x           
+#define        FYL2XP1         fyl2xp1         
+
+/* New instructions */
+#define        CPUID           D_BYTE 15, 162
+#define        RDTSC           D_BYTE 15, 49
+
+#endif /* NASM_ASSEMBLER, MASM_ASSEMBLER */
+
+       /****************************************/
+       /*                                      */
+       /*      Extensions to x86 insn set -    */
+       /*      MMX, 3DNow!                     */
+       /*                                      */
+       /****************************************/
+
+#if defined(NASM_ASSEMBLER) || defined(MASM_ASSEMBLER)
+#define P_ARG1(a)      P_ ## a
+#define P_ARG2(a, b)   P_ ## b, P_ ## a
+#define P_ARG3(a, b, c)        P_ ## c, P_ ## b, P_ ## a
+#else
+#define P_ARG1(a)      a
+#define P_ARG2(a, b)   a, b
+#define P_ARG3(a, b)   a, b, c
+#endif
+
+/* MMX */
+#define MOVD(a, b)     movd P_ARG2(a, b)
+#define MOVQ(a, b)     movq P_ARG2(a, b)
+
+#define PADDB(a, b)    paddb P_ARG2(a, b)
+#define PADDW(a, b)    paddw P_ARG2(a, b)
+#define PADDD(a, b)    paddd P_ARG2(a, b)
+
+#define PADDSB(a, b)   paddsb P_ARG2(a, b)
+#define PADDSW(a, b)   paddsw P_ARG2(a, b)
+
+#define PADDUSB(a, b)  paddusb P_ARG2(a, b)
+#define PADDUSW(a, b)  paddusw P_ARG2(a, b)
+
+#define PSUBB(a, b)    psubb P_ARG2(a, b)
+#define PSUBW(a, b)    psubw P_ARG2(a, b)
+#define PSUBD(a, b)    psubd P_ARG2(a, b)
+
+#define PSUBSB(a, b)   psubsb P_ARG2(a, b)
+#define PSUBSW(a, b)   psubsw P_ARG2(a, b)
+
+#define PSUBUSB(a, b)  psubusb P_ARG2(a, b)
+#define PSUBUSW(a, b)  psubusw P_ARG2(a, b)
+
+#define PCMPEQB(a, b)  pcmpeqb P_ARG2(a, b)
+#define PCMPEQW(a, b)  pcmpeqw P_ARG2(a, b)
+#define PCMPEQD(a, b)  pcmpeqd P_ARG2(a, b)
+
+#define PCMPGTB(a, b)  pcmpgtb P_ARG2(a, b)
+#define PCMPGTW(a, b)  pcmpgtw P_ARG2(a, b)
+#define PCMPGTD(a, b)  pcmpgtd P_ARG2(a, b)
+
+#define PMULHW(a, b)   pmulhw P_ARG2(a, b)
+#define PMULLW(a, b)   pmullw P_ARG2(a, b)
+
+#define PMADDWD(a, b)  pmaddwd P_ARG2(a, b)
+
+#define PAND(a, b)     pand P_ARG2(a, b)
+
+#define PANDN(a, b)    pandn P_ARG2(a, b)
+
+#define POR(a, b)      por P_ARG2(a, b)
+
+#define PXOR(a, b)     pxor P_ARG2(a, b)
+
+#define PSRAW(a, b)    psraw P_ARG2(a, b)
+#define PSRAD(a, b)    psrad P_ARG2(a, b)
+
+#define PSRLW(a, b)    psrlw P_ARG2(a, b)
+#define PSRLD(a, b)    psrld P_ARG2(a, b)
+#define PSRLQ(a, b)    psrlq P_ARG2(a, b)
+
+#define PSLLW(a, b)    psllw P_ARG2(a, b)
+#define PSLLD(a, b)    pslld P_ARG2(a, b)
+#define PSLLQ(a, b)    psllq P_ARG2(a, b)
+
+#define PACKSSWB(a, b)         packsswb P_ARG2(a, b)
+#define PACKSSDW(a, b)         packssdw P_ARG2(a, b)
+#define PACKUSWB(a, b)         packuswb P_ARG2(a, b)
+
+#define PUNPCKHBW(a, b)        punpckhbw P_ARG2(a, b)
+#define PUNPCKHWD(a, b)        punpckhwd P_ARG2(a, b)
+#define PUNPCKHDQ(a, b)        punpckhdq P_ARG2(a, b)
+#define PUNPCKLBW(a, b)        punpcklbw P_ARG2(a, b)
+#define PUNPCKLWD(a, b)        punpcklwd P_ARG2(a, b)
+#define PUNPCKLDQ(a, b)        punpckldq P_ARG2(a, b)
+
+#define EMMS   emms
+
+/* AMD 3DNow! */
+#define PAVGUSB(a, b)  pavgusb P_ARG2(a, b)
+#define PFADD(a, b)    pfadd P_ARG2(a, b)
+#define PFSUB(a, b)    pfsub P_ARG2(a, b)
+#define PFSUBR(a, b)   pfsubr P_ARG2(a, b)
+#define PFACC(a, b)    pfacc P_ARG2(a, b)
+#define PFCMPGE(a, b)  pfcmpge P_ARG2(a, b)
+#define PFCMPGT(a, b)  pfcmpgt P_ARG2(a, b)
+#define PFCMPEQ(a, b)  pfcmpeq P_ARG2(a, b)
+#define PFMIN(a, b)    pfmin P_ARG2(a, b)
+#define PFMAX(a, b)    pfmax P_ARG2(a, b)
+#define PI2FD(a, b)    pi2fd P_ARG2(a, b)
+#define PF2ID(a, b)    pf2id P_ARG2(a, b)
+#define PFRCP(a, b)    pfrcp P_ARG2(a, b)
+#define PFRSQRT(a, b)  pfrsqrt P_ARG2(a, b)
+#define PFMUL(a, b)    pfmul P_ARG2(a, b)
+#define PFRCPIT1(a, b)         pfrcpit1 P_ARG2(a, b)
+#define PFRSQIT1(a, b)         pfrsqit1 P_ARG2(a, b)
+#define PFRCPIT2(a, b)         pfrcpit2 P_ARG2(a, b)
+#define PMULHRW(a, b)  pmulhrw P_ARG2(a, b)
+
+#define FEMMS  femms
+#define PREFETCH(a)    prefetch P_ARG1(a)
+
+/* Intel SSE */
+#define ADDPS(a, b)    addps P_ARG2(a, b)
+#define ADDSS(a, b)    addss P_ARG2(a, b)
+#define ANDNPS(a, b)   andnps P_ARG2(a, b)
+#define ANDPS(a, b)    andps P_ARG2(a, b)
+/*
+ NASM only knows the pseudo ops for these.
+       #define CMPPS(a, b, c)  cmpps P_ARG3(a, b, c)
+       #define CMPSS(a, b, c)  cmpss P_ARG3(a, b, c)
+*/
+#define CMPEQPS(a, b)  cmpeqps P_ARG3(a, b)
+#define CMPLTPS(a, b)  cmpltps P_ARG3(a, b)
+#define CMPLEPS(a, b)  cmpleps P_ARG3(a, b)
+#define CMPUNORDPS(a, b)       cmpunordps P_ARG3(a, b)
+#define CMPNEQPS(a, b) cmpneqps P_ARG3(a, b)
+#define CMPNLTPS(a, b) cmpnltps P_ARG3(a, b)
+#define CMPNLEPS(a, b) cmpnleps P_ARG3(a, b)
+#define CMPORDPS(a, b) cmpordps P_ARG3(a, b)
+#define CMPEQSS(a, b)  cmpeqss P_ARG3(a, b)
+#define CMPLTSS(a, b)  cmpltss P_ARG3(a, b)
+#define CMPLESS(a, b)  cmpless P_ARG3(a, b)
+#define CMPUNORDSS(a, b)       cmpunordss P_ARG3(a, b)
+#define CMPNEQSS(a, b) cmpneqss P_ARG3(a, b)
+#define CMPNLTSS(a, b) cmpnltss P_ARG3(a, b)
+#define CMPNLESS(a, b) cmpnless P_ARG3(a, b)
+#define CMPORDSS(a, b) cmpordss P_ARG3(a, b)
+#define COMISS(a, b)   comiss P_ARG2(a, b)
+#define CVTPI2PS(a, b) cvtpi2ps P_ARG2(a, b)
+#define CVTPS2PI(a, b) cvtps2pi P_ARG2(a, b)
+#define CVTSI2SS(a, b) cvtsi2ss P_ARG2(a, b)
+#define CVTSS2SI(a, b) cvtss2si P_ARG2(a, b)
+#define CVTTPS2PI(a, b)        cvttps2pi P_ARG2(a, b)
+#define CVTTSS2SI(a, b)        cvttss2si P_ARG2(a, b)
+#define DIVPS(a, b)    divps P_ARG2(a, b)
+#define DIVSS(a, b)    divss P_ARG2(a, b)
+#define FXRSTOR(a)     fxrstor P_ARG1(a)
+#define FXSAVE(a)      fxsave P_ARG1(a)
+#define LDMXCSR(a)     ldmxcsr P_ARG1(a)
+#define MAXPS(a, b)    maxps P_ARG2(a, b)
+#define MAXSS(a, b)    maxss P_ARG2(a, b)
+#define MINPS(a, b)    minps P_ARG2(a, b)
+#define MINSS(a, b)    minss P_ARG2(a, b)
+#define MOVAPS(a, b)   movaps P_ARG2(a, b)
+#define MOVHLPS(a, b)  movhlps P_ARG2(a, b)
+#define MOVHPS(a, b)   movhps P_ARG2(a, b)
+#define MOVLHPS(a, b)  movlhps P_ARG2(a, b)
+#define MOVLPS(a, b)   movlps P_ARG2(a, b)
+#define MOVMSKPS(a, b) movmskps P_ARG2(a, b)
+#define MOVSS(a, b)    movss P_ARG2(a, b)
+#define MOVUPS(a, b)   movups P_ARG2(a, b)
+#define MULPS(a, b)    mulps P_ARG2(a, b)
+#define MULSS(a, b)    mulss P_ARG2(a, b)
+#define ORPS(a, b)     orps P_ARG2(a, b)
+#define RCPPS(a, b)    rcpps P_ARG2(a, b)
+#define RCPSS(a, b)    rcpss P_ARG2(a, b)
+#define RSQRTPS(a, b)  rsqrtps P_ARG2(a, b)
+#define RSQRTSS(a, b)  rsqrtss P_ARG2(a, b)
+#define SHUFPS(a, b, c)        shufps P_ARG3(a, b, c)
+#define SQRTPS(a, b)   sqrtps P_ARG2(a, b)
+#define SQRTSS(a, b)   sqrtss P_ARG2(a, b)
+#define STMXCSR(a)     stmxcsr P_ARG1(a)
+#define SUBPS(a, b)    subps P_ARG2(a, b)
+#define UCOMISS(a, b)  ucomiss P_ARG2(a, b)
+#define UNPCKHPS(a, b) unpckhps P_ARG2(a, b)
+#define UNPCKLPS(a, b) unpcklps P_ARG2(a, b)
+#define XORPS(a, b)    xorps P_ARG2(a, b)
+
+
+#endif /* __ASSYNTAX_H__ */
diff --git a/src/mesa/x86/common_x86.c b/src/mesa/x86/common_x86.c
new file mode 100644 (file)
index 0000000..7d30be9
--- /dev/null
@@ -0,0 +1,77 @@
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/*
+ *  Check CPU capabilities & initialize optimized funtions for this particular
+ *   processor.
+ *
+ *  Written by Holger Waechtler <holger@akaflieg.extern.tu-berlin.de>
+ */
+
+#include <stdlib.h>
+#include "common_x86asm.h"
+
+int gl_x86_cpu_features = 0;
+
+
+void gl_init_all_x86_asm (void)
+{
+#ifdef USE_X86_ASM
+   gl_x86_cpu_features = gl_identify_x86_cpu_features ();
+
+   if (gl_x86_cpu_features & GL_CPU_GenuineIntel) {
+      printf ("GenuineIntel cpu detected.\n");
+   }
+   gl_init_x86_asm_transforms ();
+
+
+#ifdef USE_MMX_ASM
+   if (gl_x86_cpu_features & GL_CPU_MMX) {
+      char *s = getenv( "MESA_NO_MMX" );
+      if (s == NULL) { 
+         printf ("MMX cpu detected.\n");
+      } else {
+         gl_x86_cpu_features &= (!GL_CPU_MMX); 
+      }
+   }
+#endif
+
+
+#ifdef USE_3DNOW_ASM
+   if (gl_x86_cpu_features & GL_CPU_3Dnow) {
+      char *s = getenv( "MESA_NO_3DNOW" );
+      if (s == NULL) {
+         printf ("3Dnow cpu detected.\n");
+         gl_init_3dnow_asm_transforms ();
+      } else {
+         gl_x86_cpu_features &= (!GL_CPU_3Dnow); 
+      }
+   }
+#endif
+
+#endif
+}
+
diff --git a/src/mesa/x86/mmx.h b/src/mesa/x86/mmx.h
new file mode 100644 (file)
index 0000000..c8c5eff
--- /dev/null
@@ -0,0 +1,77 @@
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+
+#ifndef ASM_MMX_H
+#define ASM_MMX_H
+
+
+extern void
+gl_mmx_blend_transparency( GLcontext *ctx, GLuint n, const GLubyte mask[],
+                           GLubyte rgba[][4], const GLubyte dest[][4] );
+
+
+void gl_mmx_set_blend_function( GLcontext *ctx )
+{
+   const GLenum eq = ctx->Color.BlendEquation;
+   const GLenum srcRGB = ctx->Color.BlendSrcRGB;
+   const GLenum dstRGB = ctx->Color.BlendDstRGB;
+   const GLenum srcA = ctx->Color.BlendSrcA;
+   const GLenum dstA = ctx->Color.BlendDstA;
+
+
+   if (srcRGB != srcA || dstRGB != dstA) {
+      ctx->Color.BlendFunc = blend_general;
+   }
+   else if (eq==GL_FUNC_ADD_EXT && srcRGB==GL_SRC_ALPHA
+       && dstRGB==GL_ONE_MINUS_SRC_ALPHA) {
+      ctx->Color.BlendFunc = gl_mmx_blend_transparency;
+   }
+   else if (eq==GL_FUNC_ADD_EXT && srcRGB==GL_ONE && dstRGB==GL_ONE) {
+      ctx->Color.BlendFunc = blend_add;
+   }
+   else if (((eq==GL_FUNC_ADD_EXT || eq==GL_FUNC_REVERSE_SUBTRACT_EXT)
+             && (srcRGB==GL_ZERO && dstRGB==GL_SRC_COLOR))
+            ||
+            ((eq==GL_FUNC_ADD_EXT || eq==GL_FUNC_SUBTRACT_EXT)
+             && (srcRGB==GL_DST_COLOR && dstRGB==GL_ZERO))) {
+      ctx->Color.BlendFunc = blend_modulate;
+   }
+   else if (eq==GL_MIN_EXT) {
+      ctx->Color.BlendFunc = blend_min;
+   }
+   else if (eq==GL_MAX_EXT) {
+      ctx->Color.BlendFunc = blend_max;
+   }
+   else {
+      ctx->Color.BlendFunc = blend_general;
+   }
+}
+
+
+#endif
diff --git a/src/mesa/x86/mmx_blend.S b/src/mesa/x86/mmx_blend.S
new file mode 100644 (file)
index 0000000..7bd9ec3
--- /dev/null
@@ -0,0 +1,363 @@
+#include "assyntax.h"
+
+
+#if !defined(NASM_ASSEMBLER) && !defined(MASM_ASSEMBLER)
+#define LLBL(a) .L ## a
+#else
+#define LLBL(a) a
+#endif
+
+
+SEG_TEXT
+
+
+ALIGNTEXT16
+GLOBL GLNAME(gl_mmx_blend_transparency)
+
+GLNAME( gl_mmx_blend_transparency ):
+    PUSH_L    ( EBP )
+    MOV_L     ( ESP, EBP )
+    SUB_L     ( CONST(52), ESP )
+    PUSH_L    ( EBX )
+    MOV_L     ( CONST(16711680), REGOFF(-8, EBP) )
+    MOV_L     ( CONST(16711680), REGOFF(-4, EBP) )
+    MOV_L     ( CONST(0), REGOFF(-16, EBP) )
+    MOV_L     ( CONST(-1), REGOFF(-12, EBP) )
+    MOV_L     ( CONST(-1), REGOFF(-24, EBP) )
+    MOV_L     ( CONST(0), REGOFF(-20, EBP) )
+    MOV_L     ( REGOFF(24, EBP), EAX )
+    ADD_L     ( CONST(4), EAX )
+    MOV_L     ( EAX, EDX )
+    AND_L     ( REGOFF(20, EBP), EDX )
+    MOV_L     ( EDX, EAX )
+    AND_L     ( CONST(4), EAX )
+    CMP_L     ( CONST(8), EAX )
+    JNE       ( LLBL(GMBT_2) )
+    MOV_L     ( REGOFF(20, EBP), EAX )
+    ADD_L     ( CONST(3), EAX )
+    XOR_L     ( EDX, EDX )
+    MOV_B     ( REGIND(EAX), DL )
+    MOV_L     ( EDX, REGOFF(-32, EBP) )
+    MOV_L     ( CONST(255), EAX )
+    MOV_L     ( EAX, EBX )
+    SUB_L     ( REGOFF(-32, EBP), EBX )
+    MOV_L     ( EBX, REGOFF(-36, EBP) )
+    MOV_L     ( REGOFF(20, EBP), EAX )
+    XOR_L     ( EDX, EDX )
+    MOV_B     ( REGIND(EAX), DL )
+    MOV_L     ( EDX, EAX )
+    IMUL_L    ( REGOFF(-32, EBP), EAX )
+    MOV_L     ( REGOFF(24, EBP), EDX )
+    XOR_L     ( ECX, ECX )
+    MOV_B     ( REGIND(EDX), CL )
+    MOV_L     ( ECX, EDX )
+    IMUL_L    ( REGOFF(-36, EBP), EDX )
+    ADD_L     ( EDX, EAX )
+    MOV_L     ( EAX, EBX )
+    SAR_L     ( CONST(8), EBX )
+    MOV_L     ( EBX, REGOFF(-40, EBP) )
+    MOV_L     ( REGOFF(20, EBP), EAX )
+    INC_L     ( EAX )
+    XOR_L     ( EDX, EDX )
+    MOV_B     ( REGIND(EAX), DL )
+    MOV_L     ( EDX, EAX )
+    IMUL_L    ( REGOFF(-32, EBP), EAX )
+    MOV_L     ( REGOFF(24, EBP), EDX )
+    INC_L     ( EDX )
+    XOR_L     ( ECX, ECX )
+    MOV_B     ( REGIND(EDX), CL )
+    MOV_L     ( ECX, EDX )
+    IMUL_L    ( REGOFF(-36, EBP), EDX )
+    ADD_L     ( EDX, EAX )
+    MOV_L     ( EAX, EBX )
+    SAR_L     ( CONST(8), EBX )
+    MOV_L     ( EBX, REGOFF(-44, EBP) )
+    MOV_L     ( REGOFF(20, EBP), EAX )
+    ADD_L     ( CONST(2), EAX )
+    XOR_L     ( EDX, EDX )
+    MOV_B     ( REGIND(EAX), DL )
+    MOV_L     ( EDX, EAX )
+    IMUL_L    ( REGOFF(-32, EBP), EAX )
+    MOV_L     ( REGOFF(24, EBP), EDX )
+    ADD_L     ( CONST(2), EDX )
+    XOR_L     ( ECX, ECX )
+    MOV_B     ( REGIND(EDX), CL )
+    MOV_L     ( ECX, EDX )
+    IMUL_L    ( REGOFF(-36, EBP), EDX )
+    ADD_L     ( EDX, EAX )
+    MOV_L     ( EAX, EBX )
+    SAR_L     ( CONST(8), EBX )
+    MOV_L     ( EBX, REGOFF(-48, EBP) )
+    MOV_L     ( REGOFF(20, EBP), EAX )
+    ADD_L     ( CONST(3), EAX )
+    XOR_L     ( EDX, EDX )
+    MOV_B     ( REGIND(EAX), DL )
+    MOV_L     ( EDX, EAX )
+    IMUL_L    ( REGOFF(-32, EBP), EAX )
+    MOV_L     ( REGOFF(24, EBP), EDX )
+    ADD_L     ( CONST(3), EDX )
+    XOR_L     ( ECX, ECX )
+    MOV_B     ( REGIND(EDX), CL )
+    MOV_L     ( ECX, EDX )
+    IMUL_L    ( REGOFF(-36, EBP), EDX )
+    ADD_L     ( EDX, EAX )
+    MOV_L     ( EAX, EBX )
+    SAR_L     ( CONST(8), EBX )
+    MOV_L     ( EBX, REGOFF(-52, EBP) )
+    MOV_L     ( REGOFF(20, EBP), EAX )
+    MOV_B     ( REGOFF(-40, EBP), DL )
+    MOV_B     ( DL, REGIND(EAX) )
+    MOV_L     ( REGOFF(20, EBP), EAX )
+    INC_L     ( EAX )
+    MOV_B     ( REGOFF(-44, EBP), DL )
+    MOV_B     ( DL, REGIND(EAX) )
+    MOV_L     ( REGOFF(20, EBP), EAX )
+    ADD_L     ( CONST(2), EAX )
+    MOV_B     ( REGOFF(-48, EBP), DL )
+    MOV_B     ( DL, REGIND(EAX) )
+    MOV_L     ( REGOFF(20, EBP), EAX )
+    ADD_L     ( CONST(3), EAX )
+    MOV_B     ( REGOFF(-52, EBP), DL )
+    MOV_B     ( DL, REGIND(EAX) )
+    INC_L     ( REGOFF(16, EBP) )
+    ADD_L     ( CONST(4), REGOFF(20, EBP) )
+    ADD_L     ( CONST(4), REGOFF(24, EBP) )
+    DEC_L     ( REGOFF(12, EBP) )
+LLBL( GMBT_2 ):
+
+    CMP_L     ( CONST(0), REGOFF(12, EBP) )
+    JE        ( LLBL(GMBT_3) )
+    MOV_L     ( CONST(0), REGOFF(-28, EBP) )
+ALIGNTEXT4
+LLBL( GMBT_4 ):
+
+    MOV_L     ( REGOFF(12, EBP), EDX )
+    MOV_L     ( EDX, EAX )
+    SHR_L     ( CONST(1), EAX )
+    CMP_L     ( EAX, REGOFF(-28, EBP) )
+    JB        ( LLBL(GMBT_7) )
+    JMP       ( LLBL(GMBT_5) )
+ALIGNTEXT16
+LLBL( GMBT_7 ):
+
+    MOV_L     ( REGOFF(-28, EBP), EAX )
+    LEA_L     ( REGDIS(0,EAX,2), EDX )
+    MOV_L     ( REGOFF(16, EBP), EAX )
+    CMP_B     ( CONST(0), REGBI(EAX,EDX) )
+    JE        ( LLBL(GMBT_6) )
+    MOV_L     ( REGOFF(-28, EBP), EAX )
+    MOV_L     ( EAX, EDX )
+    LEA_L     ( REGDIS(0,EDX,8), ECX )
+    MOV_L     ( ECX, EAX )
+    ADD_L     ( REGOFF(20, EBP), EAX )
+    MOV_L     ( REGOFF(-28, EBP), EDX )
+    MOV_L     ( EDX, ECX )
+    LEA_L     ( REGDIS(0,ECX,8), EDX )
+    MOV_L     ( EDX, ECX )
+    ADD_L     ( REGOFF(24, EBP), ECX )
+
+    MOVQ      ( REGIND(EAX), MM4 )
+    PXOR      ( MM5, MM5 )
+    MOVQ      ( MM4, MM1 )
+    MOVQ      ( REGIND(ECX), MM7 )
+    PUNPCKLBW ( MM5, MM1 )
+    MOVQ      ( MM7, MM6 )
+    MOVQ      ( MM1, MM0 )
+    PUNPCKLBW ( MM5, MM6 )
+    MOVQ      ( MM1, MM2 )
+    PSRLQ     ( CONST(48), MM0 )
+    PUNPCKHBW ( MM5, MM4 )
+    PACKSSDW  ( MM0, MM0 )
+    MOVQ      ( MM0, MM3 )
+    PUNPCKHBW ( MM5, MM7 )
+    PSLLQ     ( CONST(16), MM3 )
+    POR       ( REGOFF(-8, EBP), MM0 )
+    PUNPCKLWD ( MM6, MM1 )
+    PSUBW     ( MM3, MM0 )
+    PUNPCKHWD ( MM6, MM2 )
+    MOVQ      ( MM4, MM3 )
+    PSRLQ     ( CONST(48), MM3 )
+    PACKSSDW  ( MM3, MM3 )
+    MOVQ      ( MM3, MM6 )
+    POR       ( REGOFF(-8, EBP), MM3 )
+    PSLLQ     ( CONST(16), MM6 )
+    PSUBW     ( MM6, MM3 )
+    MOVQ      ( MM4, MM5 )
+    PUNPCKLWD ( MM7, MM4 )
+    PUNPCKHWD ( MM7, MM5 )
+    PMADDWD   ( MM0, MM1 )
+    PMADDWD   ( MM3, MM4 )
+    PMADDWD   ( MM0, MM2 )
+    PMADDWD   ( MM3, MM5 )
+    PSRLD     ( CONST(8), MM1 )
+    PSRLD     ( CONST(8), MM2 )
+    PSRLD     ( CONST(8), MM4 )
+    PACKSSDW  ( MM2, MM1 )
+    PSRLD     ( CONST(8), MM5 )
+    PACKUSWB  ( MM1, MM1 )
+    PACKSSDW  ( MM5, MM4 )
+    PAND      ( REGOFF(-24, EBP), MM1 )
+    PACKUSWB  ( MM4, MM4 )
+    PAND      ( REGOFF(-16, EBP), MM4 )
+    POR       ( MM1, MM4 )
+    MOVQ      ( MM4, REGIND(EAX) )
+
+
+LLBL( GMBT_8 ):
+
+LLBL( GMBT_6 ):
+
+    INC_L     ( REGOFF(-28, EBP) )
+    JMP       ( LLBL(GMBT_4) )
+ALIGNTEXT16
+LLBL( GMBT_5 ):
+
+
+    EMMS
+
+LLBL( GMBT_3 ):
+
+    MOV_L     ( REGOFF(12, EBP), EAX )
+    AND_L     ( CONST(1), EAX )
+    TEST_L    ( EAX, EAX )
+    JE        ( LLBL(GMBT_9) )
+    MOV_L     ( REGOFF(12, EBP), EAX )
+    LEA_L     ( REGDIS(0,EAX,4), EDX )
+    MOV_L     ( EDX, EAX )
+    ADD_L     ( REGOFF(20, EBP), EAX )
+    LEA_L     ( REGOFF(-1, EAX), EDX )
+    XOR_L     ( EAX, EAX )
+    MOV_B     ( REGIND(EDX), AL )
+    MOV_L     ( EAX, REGOFF(-52, EBP) )
+    MOV_L     ( CONST(255), EAX )
+    MOV_L     ( EAX, EBX )
+    SUB_L     ( REGOFF(-52, EBP), EBX )
+    MOV_L     ( EBX, REGOFF(-48, EBP) )
+    MOV_L     ( REGOFF(12, EBP), EAX )
+    LEA_L     ( REGDIS(0,EAX,4), EDX )
+    MOV_L     ( EDX, EAX )
+    ADD_L     ( REGOFF(20, EBP), EAX )
+    LEA_L     ( REGOFF(-4, EAX), EDX )
+    XOR_L     ( ECX, ECX )
+    MOV_B     ( REGIND(EDX), CL )
+    MOV_L     ( ECX, EAX )
+    IMUL_L    ( REGOFF(-52, EBP), EAX )
+    MOV_L     ( REGOFF(12, EBP), EDX )
+    LEA_L     ( REGDIS(0,EDX,4), ECX )
+    MOV_L     ( ECX, EDX )
+    ADD_L     ( REGOFF(24, EBP), EDX )
+    LEA_L     ( REGOFF(-4, EDX), ECX )
+    XOR_L     ( EDX, EDX )
+    MOV_B     ( REGIND(ECX), DL )
+    MOV_L     ( EDX, ECX )
+    IMUL_L    ( REGOFF(-48, EBP), ECX )
+    ADD_L     ( ECX, EAX )
+    MOV_L     ( EAX, EBX )
+    SAR_L     ( CONST(8), EBX )
+    MOV_L     ( EBX, REGOFF(-44, EBP) )
+    MOV_L     ( REGOFF(12, EBP), EAX )
+    LEA_L     ( REGDIS(0,EAX,4), EDX )
+    MOV_L     ( EDX, EAX )
+    ADD_L     ( REGOFF(20, EBP), EAX )
+    LEA_L     ( REGOFF(-3, EAX), EDX )
+    XOR_L     ( ECX, ECX )
+    MOV_B     ( REGIND(EDX), CL )
+    MOV_L     ( ECX, EAX )
+    IMUL_L    ( REGOFF(-52, EBP), EAX )
+    MOV_L     ( REGOFF(12, EBP), EDX )
+    LEA_L     ( REGDIS(0,EDX,4), ECX )
+    MOV_L     ( ECX, EDX )
+    ADD_L     ( REGOFF(24, EBP), EDX )
+    LEA_L     ( REGOFF(-3, EDX), ECX )
+    XOR_L     ( EDX, EDX )
+    MOV_B     ( REGIND(ECX), DL )
+    MOV_L     ( EDX, ECX )
+    IMUL_L    ( REGOFF(-48, EBP), ECX )
+    ADD_L     ( ECX, EAX )
+    MOV_L     ( EAX, EBX )
+    SAR_L     ( CONST(8), EBX )
+    MOV_L     ( EBX, REGOFF(-40, EBP) )
+    MOV_L     ( REGOFF(12, EBP), EAX )
+    LEA_L     ( REGDIS(0,EAX,4), EDX )
+    MOV_L     ( EDX, EAX )
+    ADD_L     ( REGOFF(20, EBP), EAX )
+    LEA_L     ( REGOFF(-2, EAX), EDX )
+    XOR_L     ( ECX, ECX )
+    MOV_B     ( REGIND(EDX), CL )
+    MOV_L     ( ECX, EAX )
+    IMUL_L    ( REGOFF(-52, EBP), EAX )
+    MOV_L     ( REGOFF(12, EBP), EDX )
+    LEA_L     ( REGDIS(0,EDX,4), ECX )
+    MOV_L     ( ECX, EDX )
+    ADD_L     ( REGOFF(24, EBP), EDX )
+    LEA_L     ( REGOFF(-2, EDX), ECX )
+    XOR_L     ( EDX, EDX )
+    MOV_B     ( REGIND(ECX), DL )
+    MOV_L     ( EDX, ECX )
+    IMUL_L    ( REGOFF(-48, EBP), ECX )
+    ADD_L     ( ECX, EAX )
+    MOV_L     ( EAX, EBX )
+    SAR_L     ( CONST(8), EBX )
+    MOV_L     ( EBX, REGOFF(-36, EBP) )
+    MOV_L     ( REGOFF(12, EBP), EAX )
+    LEA_L     ( REGDIS(0,EAX,4), EDX )
+    MOV_L     ( EDX, EAX )
+    ADD_L     ( REGOFF(20, EBP), EAX )
+    LEA_L     ( REGOFF(-1, EAX), EDX )
+    XOR_L     ( ECX, ECX )
+    MOV_B     ( REGIND(EDX), CL )
+    MOV_L     ( ECX, EAX )
+    IMUL_L    ( REGOFF(-52, EBP), EAX )
+    MOV_L     ( REGOFF(12, EBP), EDX )
+    LEA_L     ( REGDIS(0,EDX,4), ECX )
+    MOV_L     ( ECX, EDX )
+    ADD_L     ( REGOFF(24, EBP), EDX )
+    LEA_L     ( REGOFF(-1, EDX), ECX )
+    XOR_L     ( EDX, EDX )
+    MOV_B     ( REGIND(ECX), DL )
+    MOV_L     ( EDX, ECX )
+    IMUL_L    ( REGOFF(-48, EBP), ECX )
+    ADD_L     ( ECX, EAX )
+    MOV_L     ( EAX, EBX )
+    SAR_L     ( CONST(8), EBX )
+    MOV_L     ( EBX, REGOFF(-32, EBP) )
+    MOV_L     ( REGOFF(12, EBP), EAX )
+    LEA_L     ( REGDIS(0,EAX,4), EDX )
+    MOV_L     ( EDX, EAX )
+    ADD_L     ( REGOFF(20, EBP), EAX )
+    LEA_L     ( REGOFF(-4, EAX), EDX )
+    MOV_B     ( REGOFF(-44, EBP), AL )
+    MOV_B     ( AL, REGIND(EDX) )
+    MOV_L     ( REGOFF(12, EBP), EAX )
+    LEA_L     ( REGDIS(0,EAX,4), EDX )
+    MOV_L     ( EDX, EAX )
+    ADD_L     ( REGOFF(20, EBP), EAX )
+    LEA_L     ( REGOFF(-3, EAX), EDX )
+    MOV_B     ( REGOFF(-40, EBP), AL )
+    MOV_B     ( AL, REGIND(EDX) )
+    MOV_L     ( REGOFF(12, EBP), EAX )
+    LEA_L     ( REGDIS(0,EAX,4), EDX )
+    MOV_L     ( EDX, EAX )
+    ADD_L     ( REGOFF(20, EBP), EAX )
+    LEA_L     ( REGOFF(-2, EAX), EDX )
+    MOV_B     ( REGOFF(-36, EBP), AL )
+    MOV_B     ( AL, REGIND(EDX) )
+    MOV_L     ( REGOFF(12, EBP), EAX )
+    LEA_L     ( REGDIS(0,EAX,4), EDX )
+    MOV_L     ( EDX, EAX )
+    ADD_L     ( REGOFF(20, EBP), EAX )
+    LEA_L     ( REGOFF(-1, EAX), EDX )
+    MOV_B     ( REGOFF(-32, EBP), AL )
+    MOV_B     ( AL, REGIND(EDX) )
+LLBL( GMBT_9 ):
+
+LLBL( GMBT_1 ):
+
+    MOV_L     ( REGOFF(-56, EBP), EBX )
+    MOV_L     ( EBP, ESP )
+    POP_L     ( EBP )
+    RET
+
+
+
+
diff --git a/src/mesa/x86/x86.c b/src/mesa/x86/x86.c
new file mode 100644 (file)
index 0000000..fe3bb34
--- /dev/null
@@ -0,0 +1,107 @@
+/* $Id: x86.c,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Intel x86 assembly code by Josh Vanderhoof
+ */
+
+
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include "context.h"
+#include "types.h"
+#include "xform.h"
+#include "x86.h"
+
+
+
+#define XFORM_ARGS     GLvector4f *to_vec,             \
+                       const GLmatrix *mat,            \
+                       const GLvector4f *from_vec,     \
+                       const GLubyte *mask,            \
+                       const GLubyte flag
+
+#define DECLARE_XFORM_GROUP(pfx, vsize, masked) \
+ extern void gl_##pfx##_transform_points##vsize##_general_##masked(XFORM_ARGS);        \
+ extern void gl_##pfx##_transform_points##vsize##_identity_##masked(XFORM_ARGS);       \
+ extern void gl_##pfx##_transform_points##vsize##_3d_no_rot_##masked(XFORM_ARGS);      \
+ extern void gl_##pfx##_transform_points##vsize##_perspective_##masked(XFORM_ARGS);    \
+ extern void gl_##pfx##_transform_points##vsize##_2d_##masked(XFORM_ARGS);             \
+ extern void gl_##pfx##_transform_points##vsize##_2d_no_rot_##masked(XFORM_ARGS);      \
+ extern void gl_##pfx##_transform_points##vsize##_3d_##masked(XFORM_ARGS);
+
+#define ASSIGN_XFORM_GROUP( pfx, cma, vsize, masked )          \
+ gl_transform_tab[cma][vsize][MATRIX_GENERAL]                  \
+  = gl_##pfx##_transform_points##vsize##_general_##masked;     \
+ gl_transform_tab[cma][vsize][MATRIX_IDENTITY]                         \
+  = gl_##pfx##_transform_points##vsize##_identity_##masked;    \
+ gl_transform_tab[cma][vsize][MATRIX_3D_NO_ROT]                \
+  = gl_##pfx##_transform_points##vsize##_3d_no_rot_##masked;   \
+ gl_transform_tab[cma][vsize][MATRIX_PERSPECTIVE]              \
+  = gl_##pfx##_transform_points##vsize##_perspective_##masked;         \
+ gl_transform_tab[cma][vsize][MATRIX_2D]                       \
+  = gl_##pfx##_transform_points##vsize##_2d_##masked;          \
+ gl_transform_tab[cma][vsize][MATRIX_2D_NO_ROT]                \
+  = gl_##pfx##_transform_points##vsize##_2d_no_rot_##masked;   \
+ gl_transform_tab[cma][vsize][MATRIX_3D]                       \
+  = gl_##pfx##_transform_points##vsize##_3d_##masked;
+
+void gl_init_x86_asm_transforms( void )
+{
+#ifdef USE_X86_ASM
+   DECLARE_XFORM_GROUP( x86, 2, raw )
+   DECLARE_XFORM_GROUP( x86, 3, raw )
+   DECLARE_XFORM_GROUP( x86, 4, raw )
+   DECLARE_XFORM_GROUP( x86, 2, masked )
+   DECLARE_XFORM_GROUP( x86, 3, masked )
+   DECLARE_XFORM_GROUP( x86, 4, masked )
+
+   extern GLvector4f *gl_x86_cliptest_points4( GLvector4f *clip_vec, 
+                                               GLvector4f *proj_vec, 
+                                               GLubyte clipMask[],
+                                               GLubyte *orMask, 
+                                               GLubyte *andMask );
+
+   
+   ASSIGN_XFORM_GROUP( x86, 0, 2, raw )
+   ASSIGN_XFORM_GROUP( x86, 0, 3, raw )
+   ASSIGN_XFORM_GROUP( x86, 0, 4, raw )
+
+   ASSIGN_XFORM_GROUP( x86, CULL_MASK_ACTIVE, 2, masked )
+   ASSIGN_XFORM_GROUP( x86, CULL_MASK_ACTIVE, 3, masked )
+   ASSIGN_XFORM_GROUP( x86, CULL_MASK_ACTIVE, 4, masked )
+
+   gl_clip_tab[4] = gl_x86_cliptest_points4;
+
+#ifdef DEBUG
+   gl_test_all_transform_functions("x86");
+#endif
+
+#endif
+}
diff --git a/src/mesa/x86/x86.h b/src/mesa/x86/x86.h
new file mode 100644 (file)
index 0000000..c7aca91
--- /dev/null
@@ -0,0 +1,37 @@
+/* $Id: x86.h,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.1
+ * 
+ * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Intel x86 assembly code by Josh Vanderhoof
+ */
+
+
+#ifndef X86_H
+#define X86_H
+
+extern void gl_init_x86_asm_transforms(void);
+
+#endif